修复了一些问题
This commit is contained in:
@@ -278,72 +278,6 @@
|
||||
color: #e74c3c;
|
||||
}
|
||||
|
||||
/* Header hover VIP cards
|
||||
* Markup: .navbar-vip > .navbar-vip-hover.hover-show > a + .hover-show-con.sub-vip-card
|
||||
* (hover-show is on the INNER span, not on .navbar-vip itself)
|
||||
*/
|
||||
.navbar-vip-hover.hover-show,
|
||||
.navbar-vip .hover-show {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sub-vip-card {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: calc(100% + 0px);
|
||||
right: 0;
|
||||
z-index: 60;
|
||||
width: max-content;
|
||||
max-width: min(520px, 92vw);
|
||||
padding: 10px;
|
||||
padding-top: 12px; /* hover bridge */
|
||||
border-radius: 12px;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
gap: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.navbar-vip-hover.hover-show:hover .sub-vip-card,
|
||||
.navbar-vip-hover.hover-show:focus-within .sub-vip-card,
|
||||
.navbar-vip .hover-show:hover .sub-vip-card,
|
||||
.navbar-vip .hover-show:focus-within .sub-vip-card {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.vip-card {
|
||||
position: relative;
|
||||
flex: 1 1 160px;
|
||||
min-width: 150px;
|
||||
padding: 14px 12px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(135deg, #2b2f3a, #1b1e27);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.vip-card.vip-theme1 {
|
||||
background: linear-gradient(135deg, #f6c453, #f39c12);
|
||||
color: #3b2a00;
|
||||
}
|
||||
|
||||
.vip-card.vip-theme2 {
|
||||
background: linear-gradient(135deg, #8e44ad, #3f51b5);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.vip-card .payvip-button {
|
||||
display: inline-block;
|
||||
margin-top: 6px;
|
||||
padding: 6px 12px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.92);
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.vipbg-v2 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -153,31 +153,26 @@ trait VipServiceModal {
|
||||
return '';
|
||||
}
|
||||
$name = (string) ($levels[$level]['name'] ?? ('VIP' . $level));
|
||||
$desc = (string) ($levels[$level]['desc'] ?? '');
|
||||
$equity = (string) ($levels[$level]['equity'] ?? '');
|
||||
$cls = $user_id > 0 ? ' pay-vip' : ' signin-loader';
|
||||
|
||||
// Preserve admin equity HTML as-is (sanitize/wrap only; never re-split).
|
||||
$equity_html = function_exists('aksrt_format_vip_equity_html')
|
||||
? aksrt_format_vip_equity_html($equity, 'mb10 relative')
|
||||
$equity_html = $equity !== ''
|
||||
? '<ul class="mb10 relative">' . wp_kses_post($equity) . '</ul>'
|
||||
: '';
|
||||
|
||||
$icon_url = esc_url((string) ($levels[$level]['img_icon'] ?? ''));
|
||||
$icon = $icon_url !== ''
|
||||
? '<img' . aksrt_get_lazy_attr('lazy_other', $icon_url, 'aksrt-vip-level-icon') . ' alt="" decoding="async">'
|
||||
? '<img' . aksrt_get_lazy_attr('lazy_other', $icon_url, 'img-icon') . ' title="' . esc_attr($name) . '" alt="' . esc_attr($name) . '" decoding="async">'
|
||||
: '<i class="fa fas fa-gem" aria-hidden="true"></i>';
|
||||
$html = '<div class="vip-card pointer level-' . $level . ' vip-theme' . $level . $cls . '" vip-level="' . $level . '">';
|
||||
$html .= '<div class="vip-baicon" aria-hidden="true">' . $icon . '</div>';
|
||||
$html .= '<div class="abs-center vip-baicon" aria-hidden="true">' . $icon . '</div>';
|
||||
$html .= '<div class="vip-img abs-right">' . $icon . '</div>';
|
||||
$html .= '<div class="relative">';
|
||||
$html .= '<div class="vip-name mb10"><span class="vip-name__icon">' . $icon . '</span><span class="vip-name__label">' . esc_html($name) . '</span></div>';
|
||||
if ($desc !== '') {
|
||||
$html .= '<div class="mb6 font-bold em09">' . esc_html($desc) . '</div>';
|
||||
}
|
||||
$html .= '<div class="vip-name mb10"><span class="mr6">' . $icon . '</span>' . esc_html($name) . '</div>';
|
||||
$html .= $equity_html;
|
||||
$html .= '<a class="but jb-blue radius payvip-button" href="javascript:;">'
|
||||
. esc_html(sprintf(__('开通%s', 'aksrt'), $name))
|
||||
. '<span class="ml6"><i class="fa fas fa-chevron-circle-right" aria-hidden="true"></i></span></a>';
|
||||
. '<span class="ml6"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i></span></a>';
|
||||
$html .= '</div></div>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@ const headerNavbar = read('inc/helpers/header/aksrt-header-navbar.php')
|
||||
const headerUserbox = read('inc/helpers/aksrt-header-userbox.php')
|
||||
const headerSearch = read('inc/helpers/header/aksrt-header-menu-search.php')
|
||||
const headerCss = read('assets/css/frontend/header-userbox.css')
|
||||
const vipCardRenderer = read('src/Content/VipServiceModal.php')
|
||||
const vipModalCss = read('assets/css/frontend/vip-modal.css')
|
||||
const zibllMainCss = read('assets/vendor/zibll/css/main.css')
|
||||
|
||||
function activeRepositorySource() {
|
||||
const roots = ['assets/admin/src', 'assets/js', 'inc', 'src', 'templates']
|
||||
@@ -126,6 +129,25 @@ test('VIP navigation purchase switches are saved and consumed end to end', () =>
|
||||
assert.match(headerNavbar, /!empty\(\$vs\['enabled'\]\) && !empty\(\$vs\['nav_user_pay_vip'\]\)/)
|
||||
})
|
||||
|
||||
test('header VIP hover cards match the Zibll markup and style contract', () => {
|
||||
assert.match(vipCardRenderer, /aksrt_get_lazy_attr\('lazy_other', \$icon_url, 'img-icon'\)/)
|
||||
assert.match(vipCardRenderer, /<div class=\"abs-center vip-baicon\"[^>]*>/)
|
||||
assert.match(vipCardRenderer, /<div class=\"vip-img abs-right\">/)
|
||||
assert.match(vipCardRenderer, /<div class=\"vip-name mb10\"><span class=\"mr6\">/)
|
||||
assert.match(vipCardRenderer, /<ul class=\"mb10 relative\">/)
|
||||
assert.doesNotMatch(vipCardRenderer, /vip-name__(?:icon|label)/)
|
||||
assert.doesNotMatch(vipCardRenderer, /aksrt_format_vip_equity_html\(\$equity, 'mb10 relative'\)/)
|
||||
|
||||
assert.doesNotMatch(vipModalCss, /Header hover VIP cards/)
|
||||
assert.doesNotMatch(vipModalCss, /\.navbar-vip-hover\.hover-show/)
|
||||
assert.doesNotMatch(vipModalCss, /\.sub-vip-card/)
|
||||
assert.doesNotMatch(vipModalCss, /\.vip-card\.vip-theme[12]/)
|
||||
assert.match(zibllMainCss, /\.sub-vip-card\s*\{[^}]*font-size:\s*12px;[^}]*padding:\s*0\s*!important;/s)
|
||||
assert.match(zibllMainCss, /\.sub-vip-card \.vip-card\s*\{[^}]*display:\s*inline-block;[^}]*width:\s*240px;[^}]*margin:\s*5px;/s)
|
||||
assert.match(zibllMainCss, /\.sub-vip-card \.vip-baicon\.abs-center\s*\{[^}]*font-size:\s*10em;[^}]*left:\s*55%;/s)
|
||||
assert.match(zibllMainCss, /\.sub-vip-card \.vip-img\s*\{[^}]*display:\s*none;/s)
|
||||
})
|
||||
|
||||
test('schema REST saves are privileged, section-whitelisted, and deeply sanitized', () => {
|
||||
assert.match(controllerBase, /current_user_can\('manage_options'\)/)
|
||||
assert.match(controllerBase, /sanitize_payload\(\$domain, \$payload, \$section\)/)
|
||||
|
||||
Reference in New Issue
Block a user