diff --git a/inc/helpers/aksrt-graphic-card.php b/inc/helpers/aksrt-graphic-card.php
index 93952de6..ee37f97c 100644
--- a/inc/helpers/aksrt-graphic-card.php
+++ b/inc/helpers/aksrt-graphic-card.php
@@ -24,7 +24,7 @@ if (!function_exists('aksrt_graphic_card')) :
* @type string $text2 Secondary text.
* @type string $text3 Tertiary / badge text (HTML allowed for icon+count).
* @type string $more Extra absolute HTML (badge etc).
- * @type bool $lazy Use aksrt-lazy data-src.
+ * @type bool $lazy Use the Zibll lazySizes contract.
* @type int|float $height_scale Padding-bottom % (0 = default CSS).
* @type int|float $mask_opacity 0–100 overlay opacity.
* @type string $hide pc|m|'' hide on device.
@@ -89,21 +89,21 @@ if (!function_exists('aksrt_graphic_card')) :
$link_target = sanitize_text_field((string) ($link['target'] ?? ''));
$lazy = !empty($args['lazy']);
- $placeholder = get_template_directory_uri() . '/assets/img/placeholder.svg';
$media = '';
if ($video_url !== '' && !(function_exists('wp_is_mobile') && wp_is_mobile())) {
- $poster = $img_url !== '' ? ' poster="' . esc_url($img_url) . '"' : '';
- if ($lazy) {
- $media = '';
+ if ($lazy && aksrt_is_lazy('lazy_other')) {
+ $poster = $img_url !== '' ? ' data-poster="' . esc_url($img_url) . '"' : '';
+ $media = '';
} else {
+ $poster = $img_url !== '' ? ' poster="' . esc_url($img_url) . '"' : '';
$media = '';
}
} elseif ($img_url !== '') {
$alt = (string) ($args['alt'] !== '' ? $args['alt'] : __('图片', 'aksrt'));
if ($lazy) {
- $media = '
';
+ $media = '
';
} else {
- $media = '
';
+ $media = '
';
}
}
if ($media === '') {
@@ -228,7 +228,7 @@ if (!function_exists('aksrt_author_minicard')) :
? aksrt_get_user_home_url($user_id)
: get_author_posts_url($user_id);
- $avatar_box = '';
+ $avatar_box = '';
$name = function_exists('aksrt_get_user_name')
? aksrt_get_user_name([
@@ -260,7 +260,7 @@ if (!function_exists('aksrt_author_minicard')) :
$blur = '';
if ($blur_bg) {
- $blur = '
';
+ $blur = '
';
}
return ''
diff --git a/inc/helpers/aksrt-icon-cards.php b/inc/helpers/aksrt-icon-cards.php
index 3d72fadd..ae7b4dd7 100644
--- a/inc/helpers/aksrt-icon-cards.php
+++ b/inc/helpers/aksrt-icon-cards.php
@@ -42,7 +42,7 @@ if (!function_exists('aksrt_icon_card')) :
if ($icon_img === '' && is_string($args['customize_icon']) && str_contains((string) $args['customize_icon'], '<')) {
$custom_html = wp_kses((string) $args['customize_icon'], [
'i' => ['class' => true, 'aria-hidden' => true],
- 'img' => ['src' => true, 'alt' => true, 'class' => true, 'width' => true, 'height' => true, 'loading' => true],
+ 'img' => ['src' => true, 'data-src' => true, 'alt' => true, 'class' => true, 'width' => true, 'height' => true],
'span'=> ['class' => true],
]);
}
@@ -80,7 +80,7 @@ if (!function_exists('aksrt_icon_card')) :
if ($custom_html !== '') {
$icon_inner = $custom_html;
} elseif ($icon_img !== '') {
- $icon_inner = '
';
+ $icon_inner = '
';
} else {
if ($icon_fa !== '' && !str_contains($icon_fa, 'fa-') && !str_contains($icon_fa, ' ')) {
$icon_fa = 'fa fa-' . $icon_fa;
@@ -181,7 +181,7 @@ if (!function_exists('aksrt_icon_cover_card')) :
if ($icon_img === '' && $custom_src !== '' && str_contains($custom_src, '<')) {
$custom_html = wp_kses($custom_src, [
'i' => ['class' => true, 'aria-hidden' => true],
- 'img' => ['src' => true, 'alt' => true, 'class' => true, 'loading' => true, 'width' => true, 'height' => true],
+ 'img' => ['src' => true, 'data-src' => true, 'alt' => true, 'class' => true, 'width' => true, 'height' => true],
'span' => ['class' => true],
'svg' => ['class' => true, 'viewbox' => true, 'viewBox' => true, 'width' => true, 'height' => true, 'fill' => true, 'xmlns' => true, 'aria-hidden' => true],
'path' => ['d' => true, 'fill' => true, 'stroke' => true, 'stroke-width' => true],
@@ -235,7 +235,7 @@ if (!function_exists('aksrt_icon_cover_card')) :
if ($custom_html !== '') {
$icon_inner = $custom_html;
} elseif ($icon_img !== '') {
- $icon_inner = '
';
+ $icon_inner = '
';
} else {
// zibll: zib_get_cfs_icon($args['icon'], 'em09') — keep FA class + em09.
if ($icon_fa !== '' && !str_contains($icon_fa, 'fa-') && !str_contains($icon_fa, ' ') && !str_starts_with($icon_fa, 'zibsvg-')) {
diff --git a/inc/helpers/aksrt-identity.php b/inc/helpers/aksrt-identity.php
index 634d3fe4..f39a14ab 100644
--- a/inc/helpers/aksrt-identity.php
+++ b/inc/helpers/aksrt-identity.php
@@ -99,7 +99,7 @@ if (!function_exists('aksrt_render_user_identity_chips')) {
if ($type !== '') {
$classes .= ' aksrt-identity-medal--' . $type;
}
- $html .= '
';
+ $html .= '
';
$n++;
continue;
}
@@ -180,20 +180,20 @@ if (!function_exists('aksrt_get_user_name')) {
$auth_html = $icon_url !== ''
- ? '
'
+ ? '
'
: ' ' . esc_html($label) . '';
} elseif ($type === 'level' && !empty($args['level']) && $level_html === '') {
if ($icon_url !== '') {
- $level_html = '
';
+ $level_html = '
';
} else {
// Text fallback mirrors zibll LV badge: small pill, never oversized.
$level_html = '' . esc_html($label) . '';
}
} elseif ($type === 'badge' && !empty($args['medal']) && $medal_html === '' && !empty($signal['wear'])) {
if ($icon_url !== '') {
- $medal_html = '
';
+ $medal_html = '
';
} else {
$medal_html = ' ' . esc_html($label) . '';
}
@@ -212,7 +212,7 @@ if (!function_exists('aksrt_get_user_name')) {
continue;
}
if ($icon_url !== '') {
- $medal_html = '
';
+ $medal_html = '
';
} else {
$medal_html = ' ' . esc_html($label) . '';
}
@@ -282,7 +282,7 @@ if (!function_exists('aksrt_render_user_medal_entry')) {
continue;
}
$label = sanitize_text_field((string) ($item['label'] ?? __('徽章', 'aksrt')));
- $icons[] = '
';
+ $icons[] = '
';
if (count($icons) >= $limit) {
break 2;
}
@@ -409,7 +409,7 @@ if (!function_exists('aksrt_get_worn_medal_icon')) {
if ($icon !== '') {
$extra = $class !== '' ? ' ' . esc_attr($class) : '';
- return '
';
+ return '
';
}
// Text fallback (rare): small pill labelled with badge text.
diff --git a/inc/helpers/aksrt-links.php b/inc/helpers/aksrt-links.php
index 737c398a..897d308d 100644
--- a/inc/helpers/aksrt-links.php
+++ b/inc/helpers/aksrt-links.php
@@ -152,7 +152,7 @@ if (!function_exists('aksrt_links_box')) :
$dec = !empty($link['desc']) ? (string) $link['desc'] : '';
$rel = $nofollow ? ' rel="nofollow noopener noreferrer"' : ' rel="noopener noreferrer"';
$img_src = $src !== '' ? $src : $placeholder;
- $img = '
';
+ $img = '
';
$data_dec = $dec !== ''
? ' title="' . esc_attr($title) . '" data-content="' . esc_attr($dec) . '"'
: ' data-content="' . esc_attr($title) . '"';
@@ -385,7 +385,7 @@ if (!function_exists('aksrt_link_get_search_cover')) :
. '' . $type_con . '
' . $type_con . '
'
- . '
'
+ . '
'
. $search . '
';
}
endif;
diff --git a/inc/helpers/aksrt-null.php b/inc/helpers/aksrt-null.php
index 60d67a07..60efc570 100644
--- a/inc/helpers/aksrt-null.php
+++ b/inc/helpers/aksrt-null.php
@@ -59,7 +59,7 @@ if (!function_exists('aksrt_get_null')) {
$style .= 'opacity:.7;';
$src = aksrt_null_image_url($img);
return ''
- . '
'
+ . '
'
. $caption
. '
';
}
diff --git a/inc/helpers/aksrt-pay.php b/inc/helpers/aksrt-pay.php
index 967e097b..de90ff24 100644
--- a/inc/helpers/aksrt-pay.php
+++ b/inc/helpers/aksrt-pay.php
@@ -1243,7 +1243,7 @@ if (!function_exists('aksrt_render_paid_gallery')) {
-
+
alt="">
-
+
alt="">
@@ -1316,16 +1316,15 @@ if (!function_exists('aksrt_render_paid_video')) {
-
-
-
-
-
-
-
+
+
+
+
+
diff --git a/inc/helpers/aksrt-single-components.php b/inc/helpers/aksrt-single-components.php
index 66d27e63..5166a11f 100644
--- a/inc/helpers/aksrt-single-components.php
+++ b/inc/helpers/aksrt-single-components.php
@@ -494,15 +494,13 @@ if (!function_exists('aksrt_render_related_graphic_card')) :
$views = function_exists('aksrt_get_post_views') ? (int) aksrt_get_post_views($post->ID) : 0;
$views_label = function_exists('aksrt_format_number') ? aksrt_format_number($views) : number_format_i18n($views);
- $img_attrs = function_exists('aksrt_lazy_img_attrs')
- ? aksrt_lazy_img_attrs($thumb, 'cover', 'fit-cover')
- : 'class="fit-cover" src="' . esc_url($thumb) . '" loading="lazy"';
+ $img_attrs = aksrt_get_lazy_attr('lazy_cover', (string) $thumb, 'fit-cover', aksrt_get_lazy_thumb('lg'));
$html = '
+
+
';
$html .= '
';
$html .= '';
$html .= '
';
- $html .= '
';
+ $html .= '
';
$html .= '
';
$html .= '
' . esc_html($title) . '
';
$html .= '' . esc_html($time) . '';
diff --git a/inc/helpers/aksrt-single-render.php b/inc/helpers/aksrt-single-render.php
index 385aef73..0d74f20c 100644
--- a/inc/helpers/aksrt-single-render.php
+++ b/inc/helpers/aksrt-single-render.php
@@ -119,7 +119,7 @@ if (!function_exists('aksrt_single_render_cover')) :
$slide_url) : ?>
-
+
alt="" style="">
@@ -130,13 +130,11 @@ if (!function_exists('aksrt_single_render_cover')) :
endif;
// Image cover (default).
- $img_attrs = function_exists('aksrt_lazy_img_attrs')
- ? aksrt_lazy_img_attrs((string) $ctx['cover_url'], 'cover', 'fit-cover')
- : 'class="fit-cover" src="' . esc_url((string) $ctx['cover_url']) . '" loading="eager"';
+ $img_attrs = aksrt_get_lazy_attr('lazy_cover', (string) $ctx['cover_url'], 'fit-cover', aksrt_get_lazy_thumb('lg'));
?>
-
alt="">
+
alt="">
@@ -480,7 +478,7 @@ if (!function_exists('aksrt_single_render_author_card')) :
?>
-
+
alt="" decoding="async" style="width:100%;aspect-ratio:16/10;object-fit:cover;">
diff --git a/inc/helpers/aksrt-slider.php b/inc/helpers/aksrt-slider.php
index edfad5b8..e89d683d 100644
--- a/inc/helpers/aksrt-slider.php
+++ b/inc/helpers/aksrt-slider.php
@@ -137,8 +137,7 @@ function aksrt_render_slider(array $args = []): string {
}
if ($image) {
- $html .= '
';
- $html .= '';
+ $html .= '
';
}
if ($link) {
diff --git a/inc/helpers/aksrt-user-card.php b/inc/helpers/aksrt-user-card.php
index 687dbd5b..d1ea1d9b 100644
--- a/inc/helpers/aksrt-user-card.php
+++ b/inc/helpers/aksrt-user-card.php
@@ -125,7 +125,7 @@ if (!function_exists('aksrt_render_user_card_posts')) :
echo '
';
echo '';
if ($thumb) {
- echo '
';
+ echo '
';
}
echo '';
echo '' . esc_html($title) . '';
diff --git a/inc/helpers/aksrt-vip.php b/inc/helpers/aksrt-vip.php
index 5a875c56..31456df9 100644
--- a/inc/helpers/aksrt-vip.php
+++ b/inc/helpers/aksrt-vip.php
@@ -364,7 +364,7 @@ function aksrt_render_vip_badge(int $user_id = 0, string $size = 'sm'): string {
$icon_url = esc_url((string) ($vip_settings['levels'][$level]['img_icon'] ?? ''));
}
$icon = $icon_url !== ''
- ? '
'
+ ? '
'
: '';
return '' . $icon . '';
diff --git a/inc/helpers/comments/content.php b/inc/helpers/comments/content.php
index e54a7aae..c4755851 100644
--- a/inc/helpers/comments/content.php
+++ b/inc/helpers/comments/content.php
@@ -88,12 +88,9 @@ if (!function_exists('aksrt_render_comment_smilie')) :
if (!isset($map[$lookup])) {
return '[g=' . esc_html($raw) . ']';
}
- return sprintf(
- '
',
- esc_url($map[$lookup]),
- esc_attr('[' . $lookup . ']'),
- esc_attr($lookup)
- );
+ $label = esc_attr('[' . $lookup . ']');
+ return '
';
}
endif;
@@ -103,9 +100,12 @@ if (!function_exists('aksrt_render_comment_content')) :
*/
function aksrt_render_comment_content(string $content): string {
// [img=url]
- $rendered = preg_replace(
+ $rendered = preg_replace_callback(
'/\[img=(https?:\/\/[^\s\[\]]+)\]/i',
- '
',
+ static function (array $matches): string {
+ return '
';
+ },
$content
);
// [code]...[/code]
@@ -134,7 +134,7 @@ if (!function_exists('aksrt_render_comment_content')) :
'title' => true,
'width' => true,
'height' => true,
- 'loading' => true,
+ 'data-src' => true,
'decoding' => true,
'data-smilie' => true,
'data-src' => true,
diff --git a/inc/helpers/comments/form-parts.php b/inc/helpers/comments/form-parts.php
index eab7c895..4cb2845e 100644
--- a/inc/helpers/comments/form-parts.php
+++ b/inc/helpers/comments/form-parts.php
@@ -45,7 +45,7 @@ if (!function_exists('aksrt_get_input_expand_but')) :
$map = function_exists('aksrt_comment_smilie_map') ? aksrt_comment_smilie_map() : [];
$icons = '';
foreach ($map as $key => $url) {
- $icons .= '
';
+ $icons .= '
';
}
$but = '' . esc_html__('表情', 'aksrt') . '';
$drop = '';
diff --git a/inc/helpers/header/aksrt-header-navbar.php b/inc/helpers/header/aksrt-header-navbar.php
index ea1a5976..cb72b4a2 100644
--- a/inc/helpers/header/aksrt-header-navbar.php
+++ b/inc/helpers/header/aksrt-header-navbar.php
@@ -148,7 +148,7 @@ if (!function_exists('aksrt_header_user_box_html')) :
if ($user_id > 0) {
$user = $ctx['current_user'] instanceof WP_User ? $ctx['current_user'] : wp_get_current_user();
$display_name = $user->display_name ?: $user->user_login;
- $avatar = get_avatar($user_id, 44, '', esc_attr($display_name), ['loading' => 'lazy']);
+ $avatar = aksrt_get_avatar_html($user_id, 44, ['alt' => $display_name]);
$desc = (string) ($ctx['user_desc'] ?? '');
$vip_badge = function_exists('aksrt_render_vip_badge') ? aksrt_render_vip_badge($user_id, 'sm') : '';
// Level and certification icons ride inline to the right of the display name.
@@ -167,7 +167,7 @@ if (!function_exists('aksrt_header_user_box_html')) :
$icon_url = esc_url((string) ($signal['icon_url'] ?? ''));
$title = (string) ($signal['title'] ?? $signal['label'] ?? '');
if ($icon_url !== '' && $title !== '') {
- $certification_badge = '
';
+ $certification_badge = '
';
}
break;
}
@@ -329,7 +329,7 @@ if (!function_exists('aksrt_menu_button')) :
$user_sub = '' . $avatar . ' ';
} else {
@@ -340,7 +340,7 @@ if (!function_exists('aksrt_menu_button')) :
}
} else {
$trigger = $user_id > 0
- ? get_avatar($user_id, 36, '', '', ['loading' => 'lazy'])
+ ? aksrt_get_avatar_html($user_id, 36)
: '';
$cls = $user_id > 0 ? 'navbar-avatar' : 'btn signin-loader';
$dot = ($user_id > 0 && (int) ($ctx['unread_count'] ?? 0) > 0)
diff --git a/inc/helpers/posts-renderer/config.php b/inc/helpers/posts-renderer/config.php
index a39ea34a..0677edfc 100644
--- a/inc/helpers/posts-renderer/config.php
+++ b/inc/helpers/posts-renderer/config.php
@@ -342,30 +342,6 @@ if (!function_exists('aksrt_renderer_resolve_images')) {
}
}
-if (!function_exists('aksrt_renderer_lazyload_config')) {
- /**
- * Small lazyload config subset for post cards.
- *
- * @return array
- */
- function aksrt_renderer_lazyload_config(): array {
- if (class_exists('\AKSRT\Settings\Settings')) {
- $lazy = \AKSRT\Settings\Settings::get_lazyload_config();
- return [
- 'enabled' => !empty($lazy['enabled']) && !empty($lazy['posts_thumb_enabled']),
- 'placeholder_url' => (string) ($lazy['placeholder_url'] ?? ''),
- 'blur' => !empty($lazy['blur']),
- ];
- }
-
- return [
- 'enabled' => false,
- 'placeholder_url' => '',
- 'blur' => false,
- ];
- }
-}
-
if (!function_exists('aksrt_renderer_thumb_ratio_value')) {
/**
* Convert ratio tokens like 4:3 to CSS aspect ratio values.
diff --git a/inc/helpers/posts-renderer/markup.php b/inc/helpers/posts-renderer/markup.php
index 2f18ede6..940f72ae 100644
--- a/inc/helpers/posts-renderer/markup.php
+++ b/inc/helpers/posts-renderer/markup.php
@@ -169,10 +169,11 @@ if (!function_exists('aksrt_renderer_mini')) {
$thumb_html = '';
$target_attr = !empty($cfg['target_blank']) ? ' target="_blank"' : '';
if ($cfg['show_thumb'] && !empty($data['has_img'])) {
- $lazy = $data['lazy'];
- $thumb_img = !empty($lazy['enabled']) && !empty($data['has_real_img'])
- ? '
'
- : '
';
+ $fit_class = !empty($cfg['thumb_fit']) && $cfg['thumb_fit'] === 'contain' ? 'fit-contain' : 'fit-cover';
+ $thumb_attr = !empty($cfg['thumb_lazy'])
+ ? aksrt_get_lazy_attr('lazy_posts_thumb', (string) $data['img_url'], $fit_class)
+ : ' class="' . esc_attr($fit_class) . '" src="' . esc_url($data['img_url']) . '"';
+ $thumb_img = '
';
$thumb_html = '' . $thumb_img . '';
}
diff --git a/inc/helpers/posts-renderer/post-data.php b/inc/helpers/posts-renderer/post-data.php
index 91689817..60535c00 100644
--- a/inc/helpers/posts-renderer/post-data.php
+++ b/inc/helpers/posts-renderer/post-data.php
@@ -20,9 +20,6 @@ if (!function_exists('aksrt_renderer_collect_post_data')) {
return [];
}
- $lazy = aksrt_renderer_lazyload_config();
- $lazy['enabled'] = !empty($lazy['enabled']) && !empty($cfg['thumb_lazy']);
-
$images = aksrt_renderer_resolve_images($post_id, $cfg);
$gallery_images = array_slice($images['gallery'], 0, $cfg['multi_thumb_limit']);
$is_mult_thumb = !empty($cfg['multi_thumb_enabled'])
@@ -71,7 +68,6 @@ if (!function_exists('aksrt_renderer_collect_post_data')) {
'resource_strip' => $resource_strip,
'is_resource' => function_exists('aksrt_is_resource_post') ? aksrt_is_resource_post($post_id) : false,
'is_sticky' => is_sticky($post_id),
- 'lazy' => $lazy,
'thumb_ratio_css' => aksrt_renderer_thumb_ratio_value((string) $cfg['thumb_ratio']),
'thumb_ratio_key' => (string) $cfg['thumb_ratio'],
];
@@ -110,19 +106,17 @@ if (!function_exists('aksrt_renderer_thumb')) {
return '';
}
- $lazy = $data['lazy'];
$img = (string) $data['img_url'];
$title = (string) $data['title'];
$href = (string) $data['permalink'];
$is_sticky = !empty($data['is_sticky']);
$has_real_img = !empty($data['has_real_img']);
- if ($has_real_img && !empty($lazy['enabled'])) {
- $img_html = ''
- . '
';
- } else {
- $img_html = '
';
- }
+ $fit_class = !empty($cfg['thumb_fit']) && $cfg['thumb_fit'] === 'contain' ? 'fit-contain' : 'fit-cover';
+ $img_attr = !empty($cfg['thumb_lazy'])
+ ? aksrt_get_lazy_attr('lazy_posts_thumb', $img, $fit_class)
+ : ' class="' . esc_attr($fit_class) . '" src="' . esc_url($img) . '"';
+ $img_html = '
';
$sticky_html = ($is_sticky && !empty($cfg['badge_show']))
? '' . esc_html__('置顶', 'aksrt') . ' '
@@ -164,17 +158,11 @@ if (!function_exists('aksrt_renderer_mult_thumb')) {
return '';
}
- $lazy = $data['lazy'];
$html = '';
foreach (array_slice($data['gallery_images'], 0, 4) as $image) {
$html .= '';
- if (!empty($lazy['enabled'])) {
- $html .= ''
- . '
';
- } else {
- $html .= '
';
- }
+ $html .= '
';
$html .= '';
}
@@ -277,7 +265,7 @@ if (!function_exists('aksrt_renderer_meta')) {
$left = [];
if (!empty($cfg['show_author'])) {
- $left[] = ' . ')
' . esc_html($data['author_name']) . ' ';
+ $left[] = '![]()
' . esc_html($data['author_name']) . ' ';
}
if (!empty($cfg['show_date'])) {
$left[] = '- ' . esc_html($data['time_ago']) . '
';
diff --git a/inc/helpers/template-tags/media-brand.php b/inc/helpers/template-tags/media-brand.php
index ce7b98ba..7cb1a89a 100644
--- a/inc/helpers/template-tags/media-brand.php
+++ b/inc/helpers/template-tags/media-brand.php
@@ -187,10 +187,8 @@ function aksrt_render_slider_markup(array $slides, array $args = array()) {
' . $icons . '
' . aksrt_header_user_box_html($ctx) . '
';
if ('2' === $layout) {
if ($user_id > 0) {
- $avatar = get_avatar($user_id, 36, '', '', ['loading' => 'lazy', 'class' => 'avatar']);
+ $avatar = aksrt_get_avatar_html($user_id, 36, ['class' => 'avatar']);
$sign_but = '- '
. $user_sub . '
data-link="">
-
alt=""
- loading=""
decoding="async"
>
@@ -451,6 +449,6 @@ function aksrt_get_adaptive_theme_img(string $white_src = '', string $dark_src =
}
$this_src = $is_dark ? $dark_src : $white_src;
- return '
';
+ return '
';
}
endif;
diff --git a/inc/helpers/template-tags/pagination-permissions.php b/inc/helpers/template-tags/pagination-permissions.php
index 2ae7ac3e..9a6a4ad4 100644
--- a/inc/helpers/template-tags/pagination-permissions.php
+++ b/inc/helpers/template-tags/pagination-permissions.php
@@ -109,9 +109,8 @@ if (!function_exists('aksrt_render_pagination')) {
data-max-pages=""
data-query-context=""
data-query-vars=""
- data-render-config=""
- data-lazyload-action="ias">
-
+ data-render-config="">
+
role="button" tabindex="0">
@@ -175,66 +174,176 @@ function aksrt_auto_image_alt(string $content): string {
add_filter('the_content', 'aksrt_auto_image_alt', 999);
/**
- * 懒加载 per-scope 开关判断
+ * Detect search-engine crawlers that must receive real image URLs.
*
- * 检查总开关 + 指定 scope 开关。
- *
- * @param string $scope avatar|content|comment|private|slider|cover|other|widget
- * @return bool
+ * @return string|false Matched crawler name, or false.
*/
-function aksrt_is_lazyload_enabled(string $scope = 'other'): bool {
- if (!class_exists('\AKSRT\Settings\Settings')) return true; // 默认开
- $cfg = \AKSRT\Settings\Settings::get_lazyload_config();
- if (!$cfg['enabled']) return false;
- return !empty($cfg[$scope] ?? true);
+function aksrt_is_crawler() {
+ static $crawler = null;
+ if ($crawler !== null) {
+ return $crawler;
+ }
+
+ $bots = [
+ 'Baidu' => 'baiduspider', 'Google Bot' => 'google', '360spider' => '360spider',
+ 'Sogou' => 'spider', 'soso.com' => 'sosospider', 'MSN' => 'msnbot',
+ 'Alex' => 'ia_archiver', 'Lycos' => 'lycos', 'Ask Jeeves' => 'jeeves',
+ 'Altavista' => 'scooter', 'AllTheWeb' => 'fast-webcrawler', 'Inktomi' => 'slurp@inktomi',
+ 'Turnitin.com' => 'turnitinbot', 'Technorati' => 'technorati', 'Yahoo' => 'yahoo',
+ 'Findexa' => 'findexa', 'NextLinks' => 'findlinks', 'Gais' => 'gaisbo',
+ 'WiseNut' => 'zyborg', 'WhoisSource' => 'surveybot', 'Bloglines' => 'bloglines',
+ 'BlogSearch' => 'blogsearch', 'PubSub' => 'pubsub', 'Syndic8' => 'syndic8',
+ 'RadioUserland' => 'userland', 'Gigabot' => 'gigabot', 'Become.com' => 'become.com',
+ 'Yandex' => 'yandex',
+ ];
+ $user_agent = strtolower((string) ($_SERVER['HTTP_USER_AGENT'] ?? ''));
+ $crawler = false;
+ foreach ($bots as $name => $needle) {
+ if ($user_agent !== '' && stripos($user_agent, $needle) !== false) {
+ $crawler = $name;
+ break;
+ }
+ }
+ return $crawler;
}
/**
- * 返回 img 标签的 lazy-loading 属性字符串
- *
- * 当 scope 启用懒加载时:class="aksrt-lazy" + data-src(需配合 skeleton 使用)
- * 当 scope 禁用时:loading="lazy"(浏览器原生)
- *
- * @param string $url 图片 URL
- * @param string $scope 场景名
- * @param string $extra_class 额外 CSS 类
- * @return string HTML 属性字符串
+ * Determine whether one Zibll-style lazy-loading scope is enabled.
*/
-function aksrt_lazy_img_attrs(string $url, string $scope = 'other', string $extra_class = ''): string {
- if (empty($url)) return '';
-
- if (aksrt_is_lazyload_enabled($scope)) {
- $cfg = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_lazyload_config() : [];
- $placeholder = $cfg['placeholder_url'] ?? '';
- $animation = $cfg['animation'] ?? 'blur';
- $cls = trim('fit-cover aksrt-lazy ' . $extra_class);
- $attrs = sprintf('class="%s" data-src="%s" data-lazy-animation="%s"', esc_attr($cls), esc_url($url), esc_attr($animation));
- if ($placeholder) {
- $attrs .= sprintf(' src="%s"', esc_url($placeholder));
- }
- return $attrs;
- }
-
- // 原生 lazy
- $cls = trim('fit-cover ' . $extra_class);
- return sprintf('class="%s" src="%s" loading="lazy"', esc_attr($cls), esc_url($url));
+function aksrt_is_lazy(string $key, bool $default = false): bool {
+ if (aksrt_is_crawler()) {
+ return false;
+ }
+ $defaults = [
+ 'lazy_posts_thumb' => true,
+ 'lazy_avatar' => true,
+ 'lazy_posts_content' => false,
+ 'lazy_comment' => true,
+ 'lazy_private' => true,
+ 'lazy_sider' => true,
+ 'lazy_cover' => true,
+ 'lazy_other' => true,
+ ];
+ $default = array_key_exists($key, $defaults) ? $defaults[$key] : $default;
+ if (!class_exists('\AKSRT\Settings\Settings')) {
+ return $default;
+ }
+ return (bool) \AKSRT\Settings\Settings::get_value($key, $default);
}
/**
- * 返回条件懒加载 loading 属性字符串
- *
- * 当指定 scope 启用懒加载时返回 loading="lazy",否则返回空字符串。
- *
- * @param string $scope 场景名 (cover|other 等)
- * @return string HTML 属性字符串
+ * Return the configured lazy placeholder or a bundled size variant.
*/
-function aksrt_lazy_loading(string $scope = 'other'): string {
- if (function_exists('aksrt_is_lazyload_enabled') && aksrt_is_lazyload_enabled($scope)) {
- return ' loading="lazy"';
- }
- return '';
+function aksrt_get_lazy_thumb(string $size = ''): string {
+ $configured = $size === '' && class_exists('\AKSRT\Settings\Settings')
+ ? (string) \AKSRT\Settings\Settings::get_value('thumbnail', '')
+ : '';
+ if ($configured !== '') {
+ return $configured;
+ }
+ $suffix = $size !== '' ? '-' . sanitize_key($size) : '';
+ return get_template_directory_uri() . '/assets/img/thumbnail' . $suffix . '.svg';
}
+/**
+ * Build the only supported lazy-media attribute set.
+ */
+function aksrt_get_lazy_attr(string $key, string $src, string $class = '', string $lazy_src = ''): string {
+ $class = trim($class);
+ if ($src === '') {
+ return ' class="' . esc_attr($class) . '" src=""';
+ }
+ if (!aksrt_is_lazy($key)) {
+ return ' class="' . esc_attr($class) . '" src="' . esc_url($src) . '"';
+ }
+ $lazy_src = $lazy_src !== '' ? $lazy_src : aksrt_get_lazy_thumb();
+ return ' class="lazyload ' . esc_attr($class) . '" src="' . esc_url($lazy_src) . '" data-src="' . esc_url($src) . '"';
+}
+
+/**
+ * Remove Zibll-style lazy attributes from a rendered image string.
+ */
+function aksrt_str_remove_lazy(string $html = ''): string {
+ $pattern = "/
/i";
+ $replacement = '
';
+ return (string) preg_replace($pattern, $replacement, str_replace('lazyload', '', $html));
+}
+
+/**
+ * Convert post-content images to the same lazySizes contract as Zibll.
+ */
+function aksrt_lazy_content_images(string $content): string {
+ if ((is_admin() && !wp_doing_ajax()) || !aksrt_is_lazy('lazy_posts_content')) {
+ return $content;
+ }
+ $placeholder = esc_url(aksrt_get_lazy_thumb('lg'));
+ $content = (string) preg_replace(
+ "/
]*).(bmp|gif|jpeg|jpg|png|ico|tiff|svg|webp)('|\")(.*?)>/i",
+ '
',
+ $content
+ );
+ return (string) preg_replace(
+ "/
]*)('|\")(.*?)>/i",
+ '
',
+ $content
+ );
+}
+add_filter('the_content', 'aksrt_lazy_content_images', 10);
+
+/**
+ * Route WordPress-generated attachment images through the same lazySizes path.
+ *
+ * @param array $attr Image attributes.
+ * @param WP_Post $attachment Attachment post.
+ * @return array
+ */
+function aksrt_lazy_attachment_attributes(array $attr, $attachment): array {
+ unset($attr['loading'], $attr['fetchpriority']);
+ if ((is_admin() && !wp_doing_ajax()) || empty($attr['src']) || !empty($attr['data-src'])) {
+ return $attr;
+ }
+
+ $key = 'lazy_other';
+ $placeholder_size = '';
+ $attachment_id = is_object($attachment) ? (int) $attachment->ID : 0;
+ if ($attachment_id > 0 && $attachment_id === (int) get_post_thumbnail_id()) {
+ $key = is_singular() ? 'lazy_cover' : 'lazy_posts_thumb';
+ $placeholder_size = is_singular() ? 'lg' : '';
+ }
+ if (!aksrt_is_lazy($key)) {
+ return $attr;
+ }
+
+ $attr['data-src'] = (string) $attr['src'];
+ $attr['src'] = aksrt_get_lazy_thumb($placeholder_size);
+ if (!empty($attr['srcset'])) {
+ $attr['data-srcset'] = (string) $attr['srcset'];
+ unset($attr['srcset']);
+ }
+ $attr['class'] = trim('lazyload ' . (string) ($attr['class'] ?? ''));
+ return $attr;
+}
+add_filter('wp_get_attachment_image_attributes', 'aksrt_lazy_attachment_attributes', 10, 2);
+
+/**
+ * Convert avatars produced directly by WordPress into the avatar lazy scope.
+ */
+function aksrt_lazy_avatar_html(string $avatar): string {
+ $avatar = (string) preg_replace('/\sloading=("|\')[^"\']*("|\')/i', '', $avatar);
+ if ((is_admin() && !wp_doing_ajax()) || !aksrt_is_lazy('lazy_avatar') || str_contains($avatar, 'data-src=')) {
+ return $avatar;
+ }
+ $avatar = preg_replace('/\ssrc=("|\')([^"\']+)("|\')/i', ' src="' . esc_url(aksrt_get_default_avatar_url()) . '" data-src="$2"', $avatar, 1);
+ if (str_contains($avatar, 'class="')) {
+ return str_replace('class="', 'class="lazyload ', (string) $avatar);
+ }
+ return str_replace('
= 1 && !empty($vip_settings['levels'][$vip_level]['name'])) {
$level_icon_url = esc_url((string) ($vip_settings['levels'][$vip_level]['img_icon'] ?? ''));
$level_icon = $level_icon_url !== ''
- ? '
'
+ ? '
'
: '';
if (class_exists('\AKSRT\Settings\Settings')) {
$paid_display = \AKSRT\Settings\Settings::get_paid_content_settings();
diff --git a/inc/helpers/user-center-renderers/profile-level.php b/inc/helpers/user-center-renderers/profile-level.php
index 20a136c9..7e266c7b 100644
--- a/inc/helpers/user-center-renderers/profile-level.php
+++ b/inc/helpers/user-center-renderers/profile-level.php
@@ -63,7 +63,7 @@ $day_max = \AKSRT\User\Level::day_max();
'
+ ? '
'
: '';
?>
diff --git a/inc/helpers/user-center-renderers/vip-tab.php b/inc/helpers/user-center-renderers/vip-tab.php
index dd52d354..cee0cebf 100644
--- a/inc/helpers/user-center-renderers/vip-tab.php
+++ b/inc/helpers/user-center-renderers/vip-tab.php
@@ -92,7 +92,7 @@ if ($level > 0) {
$status_icon_url = esc_url((string) ($levels[$vip_level_number]['img_icon'] ?? ''));
$status_icon = $status_icon_url !== ''
- ? '
'
+ ? '
'
: '';
$status_html = '
-
LV
+
alt="">LV
EXP
diff --git a/inc/helpers/user-center-renderers/sidebar-vip.php b/inc/helpers/user-center-renderers/sidebar-vip.php
index 0c2e9c57..26b15b42 100644
--- a/inc/helpers/user-center-renderers/sidebar-vip.php
+++ b/inc/helpers/user-center-renderers/sidebar-vip.php
@@ -48,7 +48,7 @@ if ($vip_level > 0) {
$sidebar_level = $vip_level > 0 ? $vip_level : $expired_level;
$sidebar_icon_url = esc_url((string) ($vip_levels[$sidebar_level]['img_icon'] ?? ''));
$sidebar_icon = $sidebar_icon_url !== ''
- ? ''
. '
'
@@ -124,7 +124,7 @@ foreach ([1, 2] as $lv) {
$vip_attr = $lv;
$lv_icon_url = esc_url((string) ($levels[$lv]['img_icon'] ?? ''));
$lv_icon = $lv_icon_url !== ''
- ? '
'
+ ? '
'
: '';
if (str_starts_with($btn_type, 'renew_')) {
$renew_lv = (int) substr($btn_type, 6);
diff --git a/src/Admin/Schema/GlobalSchema.php b/src/Admin/Schema/GlobalSchema.php
index 98d0b8c6..6d136249 100644
--- a/src/Admin/Schema/GlobalSchema.php
+++ b/src/Admin/Schema/GlobalSchema.php
@@ -20,8 +20,21 @@ class GlobalSchema {
'version' => '1.0.0',
'option_key' => 'aksrt_settings',
'groups' => [
- ['key' => 'performance', 'title' => '性能优化', 'fields' => [
- ['key' => 'lazyload_enabled', 'label' => '图片懒加载', 'type' => 'switch', 'default' => true],
+ ['key' => 'performance', 'title' => '图像异步懒加载', 'fields' => [
+ ['key' => 'lazy_posts_thumb', 'label' => '文章缩略图懒加载', 'type' => 'switch', 'default' => true],
+ ['key' => 'lazy_avatar', 'label' => '头像懒加载', 'type' => 'switch', 'default' => true],
+ ['key' => 'lazy_posts_content', 'label' => '文章内容图片懒加载', 'type' => 'switch', 'default' => false],
+ ['key' => 'lazy_comment', 'label' => '评论内容图片懒加载', 'type' => 'switch', 'default' => true],
+ ['key' => 'lazy_private', 'label' => '私信聊天图片懒加载', 'type' => 'switch', 'default' => true],
+ ['key' => 'lazy_sider', 'label' => '幻灯片图片懒加载', 'type' => 'switch', 'default' => true],
+ ['key' => 'lazy_cover', 'label' => '封面图片懒加载', 'type' => 'switch', 'default' => true],
+ ['key' => 'lazy_other', 'label' => '其它图片懒加载', 'type' => 'switch', 'default' => true],
+ ['key' => 'lazy_animation', 'label' => '懒加载动画效果', 'type' => 'select', 'default' => 'blur', 'options' => [
+ ['label' => '淡出淡入', 'value' => 'fade'],
+ ['label' => '高斯模糊', 'value' => 'blur'],
+ ['label' => '放大缩小', 'value' => 'scale'],
+ ]],
+ ['key' => 'thumbnail', 'label' => '懒加载预载图', 'type' => 'media', 'default' => get_template_directory_uri() . '/assets/img/thumbnail.svg'],
]],
['key' => 'filing', 'title' => '备案信息', 'fields' => [
['key' => 'icp_filing', 'label' => 'ICP 备案号', 'type' => 'input', 'default' => ''],
@@ -93,34 +106,6 @@ class GlobalSchema {
]],
],
],
- 'lazyload' => [
- 'key' => 'lazyload',
- 'title' => '懒加载设置',
- 'version' => '1.0.0',
- 'option_key' => 'aksrt_settings',
- 'groups' => [
- ['key' => 'basic', 'title' => '懒加载开关', 'fields' => [
- ['key' => 'lazyload_enabled', 'label' => '图像异步懒加载', 'type' => 'switch', 'default' => true],
- ['key' => 'lazyload_animation', 'label' => '懒加载动画效果', 'type' => 'select', 'default' => 'blur', 'options' => [
- ['label' => '淡出淡入', 'value' => 'fade'],
- ['label' => '高斯模糊', 'value' => 'blur'],
- ['label' => '放大缩小', 'value' => 'scale'],
- ]],
- ['key' => 'lazyload_placeholder', 'label' => '懒加载预载图', 'type' => 'media', 'default' => ''],
- ['key' => 'lazyload_blur', 'label' => '模糊预览', 'type' => 'switch', 'default' => true],
- ]],
- ['key' => 'scope', 'title' => '懒加载范围', 'fields' => [
- ['key' => 'lazyload_avatar', 'label' => '头像懒加载', 'type' => 'switch', 'default' => true],
- ['key' => 'lazyload_content', 'label' => '文章内容图片懒加载', 'type' => 'switch', 'default' => false],
- ['key' => 'lazyload_comment', 'label' => '评论内容图片懒加载', 'type' => 'switch', 'default' => true],
- ['key' => 'lazyload_private', 'label' => '私信聊天图片懒加载', 'type' => 'switch', 'default' => true],
- ['key' => 'lazyload_slider', 'label' => '幻灯片图片懒加载', 'type' => 'switch', 'default' => true],
- ['key' => 'lazyload_cover', 'label' => '封面图片懒加载', 'type' => 'switch', 'default' => true],
- ['key' => 'lazyload_other', 'label' => '其它图片懒加载', 'type' => 'switch', 'default' => true],
- ['key' => 'lazyload_widget', 'label' => '小工具图片懒加载', 'type' => 'switch', 'default' => true],
- ]],
- ],
- ],
'layout' => [
'key' => 'layout',
'title' => '显示&布局',
diff --git a/src/Content/VipServiceModal.php b/src/Content/VipServiceModal.php
index 7308a189..04f7216e 100644
--- a/src/Content/VipServiceModal.php
+++ b/src/Content/VipServiceModal.php
@@ -164,7 +164,7 @@ trait VipServiceModal {
$icon_url = esc_url((string) ($levels[$level]['img_icon'] ?? ''));
$icon = $icon_url !== ''
- ? '
'
+ ? '
'
: '';
$html = '
';
$html .= '
' . $badge . '';
+ $img_html = '
' . $badge . '';
$title_html = $title !== '' ? '
';
+ $icon = '
';
}
$title_html = $icon . $title;
$class = trim(($class ? $class . ' ' : '') . 'link-item');
diff --git a/src/Settings/FacadeBulk.php b/src/Settings/FacadeBulk.php
index b389625f..1eb91063 100644
--- a/src/Settings/FacadeBulk.php
+++ b/src/Settings/FacadeBulk.php
@@ -271,43 +271,6 @@ trait FacadeBulk {
- /**
- * 获取懒加载配置
- *
- * 返回 schema 定义的全部字段:全局开关、动画、占位图、模糊预览、
- * 以及 8 项粒度范围开关。
- *
- * @return array {enabled, animation, placeholder_url, blur, avatar, content, comment, private, slider, cover, other, widget}
- */
- public static function get_lazyload_config(): array {
- $s = self::get_all();
-
- // placeholder 兼容:schema 存 lazyload_placeholder,REST/Vue 存 lazyload_placeholder_url
- $placeholder = '';
- if (!empty($s['lazyload_placeholder'])) {
- $placeholder = $s['lazyload_placeholder'];
- } elseif (!empty($s['lazyload_placeholder_url'])) {
- $placeholder = $s['lazyload_placeholder_url'];
- }
-
- return [
- 'enabled' => !isset($s['lazyload_enabled']) || !empty($s['lazyload_enabled']),
- 'animation' => $s['lazyload_animation'] ?? 'blur',
- 'placeholder_url' => (string) $placeholder,
- 'blur' => !isset($s['lazyload_blur']) || !empty($s['lazyload_blur']),
- 'avatar' => !isset($s['lazyload_avatar']) || !empty($s['lazyload_avatar']),
- 'content' => !empty($s['lazyload_content']),
- 'comment' => !isset($s['lazyload_comment']) || !empty($s['lazyload_comment']),
- 'private' => !isset($s['lazyload_private']) || !empty($s['lazyload_private']),
- 'slider' => !isset($s['lazyload_slider']) || !empty($s['lazyload_slider']),
- 'cover' => !isset($s['lazyload_cover']) || !empty($s['lazyload_cover']),
- 'other' => !isset($s['lazyload_other']) || !empty($s['lazyload_other']),
- 'widget' => !isset($s['lazyload_widget']) || !empty($s['lazyload_widget']),
- ];
- }
-
-
-
/**
* 获取备案配置。
* @return array {icp_enabled, icp_filing, police_enabled, police_filing}
diff --git a/src/User/Level.php b/src/User/Level.php
index b5702db7..ef4e52ca 100644
--- a/src/User/Level.php
+++ b/src/User/Level.php
@@ -156,7 +156,7 @@ class Level {
$name = self::get_level_name($level);
$icon = self::get_level_icon_url($level);
if ($icon !== '') {
- return '
';
+ return '
';
}
return 'LV' . esc_html((string) $level) . '';
}
diff --git a/src/WidgetSystem/FormRenderer.php b/src/WidgetSystem/FormRenderer.php
index 7174f321..cdad87a8 100644
--- a/src/WidgetSystem/FormRenderer.php
+++ b/src/WidgetSystem/FormRenderer.php
@@ -151,7 +151,7 @@ final class FormRenderer {
private static function upload(string $id, string $name, string $value): void {
echo '
';
+ return '
';
}
public static function lines(string $value): array {
@@ -49,7 +48,11 @@ final class RendererHelpers {
}
$media .= self::image((string) ($item['image'] ?? ''), $title, 'aksrt-media-card__image');
if (!empty($item['video'])) {
- $media .= '';
+ $video = esc_url((string) $item['video']);
+ $video_attr = aksrt_is_lazy('lazy_other')
+ ? ' class="aksrt-media-card__video lazyload" src="" data-src="' . $video . '"'
+ : ' class="aksrt-media-card__video" src="' . $video . '"';
+ $media .= '';
}
$body = '' . esc_html($title) . '';
if (!empty($item['description'])) {
diff --git a/src/WidgetSystem/Renderers/GeneralRenderer.php b/src/WidgetSystem/Renderers/GeneralRenderer.php
index b1e8020d..4179f370 100644
--- a/src/WidgetSystem/Renderers/GeneralRenderer.php
+++ b/src/WidgetSystem/Renderers/GeneralRenderer.php
@@ -67,14 +67,24 @@ final class GeneralRenderer {
return RendererHelpers::empty_state(__('请配置视频地址', 'aksrt'));
}
$ratio = (string) $i['ratio'];
- return '';
+ if (aksrt_is_lazy('lazy_other')) {
+ $video_attr = ' class="lazyload" src="" data-src="' . $url . '"';
+ $poster_attr = !empty($i['poster']) ? ' data-poster="' . esc_url((string) $i['poster']) . '"' : '';
+ } else {
+ $video_attr = ' src="' . $url . '"';
+ $poster_attr = !empty($i['poster']) ? ' poster="' . esc_url((string) $i['poster']) . '"' : '';
+ }
+ return '';
}
private static function render_embed(array $i): string {
if (empty($i['url'])) {
return RendererHelpers::empty_state(__('请配置嵌入地址', 'aksrt'));
}
- return '';
+ $src_attr = aksrt_is_lazy('lazy_other')
+ ? ' class="lazyload" src="" data-src="' . esc_url((string) $i['url']) . '"'
+ : ' src="' . esc_url((string) $i['url']) . '"';
+ return '';
}
private static function render_media_cards(array $i): string {
diff --git a/src/WidgetSystem/Renderers/SliderRenderer.php b/src/WidgetSystem/Renderers/SliderRenderer.php
index e9aaf0a5..91b319ff 100644
--- a/src/WidgetSystem/Renderers/SliderRenderer.php
+++ b/src/WidgetSystem/Renderers/SliderRenderer.php
@@ -16,13 +16,19 @@ final class SliderRenderer {
continue;
}
$link = RendererHelpers::link((array) ($slide['link'] ?? []));
- $media = !empty($slide['background_video'])
- ? ''
- : RendererHelpers::image((string) $slide['background'], (string) ($slide['title'] ?? ''), 'swiper-lazy');
+ if (!empty($slide['background_video'])) {
+ $video = esc_url((string) $slide['background_video']);
+ $video_attr = aksrt_is_lazy('lazy_sider')
+ ? ' class="lazyload" src="" data-src="' . $video . '"'
+ : ' src="' . $video . '"';
+ $media = '';
+ } else {
+ $media = RendererHelpers::image((string) $slide['background'], (string) ($slide['title'] ?? ''), '', 'lazy_sider', aksrt_get_lazy_thumb('lg'));
+ }
$layers = '';
foreach ((array) ($slide['layers'] ?? []) as $layer) {
if (!empty($layer['image'])) {
- $layers .= '
';
+ $layers .= '
';
}
}
$copy = '';
diff --git a/templates/pages/page-messages.php b/templates/pages/page-messages.php
index 5fd0a1a0..f01e3edf 100644
--- a/templates/pages/page-messages.php
+++ b/templates/pages/page-messages.php
@@ -237,7 +237,7 @@ if (!$messages_base) {
' . $icon . '
';
diff --git a/src/Core/ScriptsPart1b.php b/src/Core/ScriptsPart1b.php
index 3f3df401..a622bed5 100644
--- a/src/Core/ScriptsPart1b.php
+++ b/src/Core/ScriptsPart1b.php
@@ -39,6 +39,14 @@ trait ScriptsPart1b {
);
wp_enqueue_style('aksrt-style', get_stylesheet_uri(), ['bootstrap5'], $version);
+ $lazy_animation = class_exists('\AKSRT\Settings\Settings')
+ ? (string) \AKSRT\Settings\Settings::get_value('lazy_animation', 'blur')
+ : 'blur';
+ if ($lazy_animation === 'fade') {
+ wp_add_inline_style('aksrt-style', '.lazyloaded{--lazy-animation:lazy_fade!important;}');
+ } elseif ($lazy_animation === 'scale') {
+ wp_add_inline_style('aksrt-style', '.lazyloaded{--lazy-animation:lazy_scale!important;}');
+ }
$core_bundle = get_template_directory() . '/assets/css/build/core.min.css';
if (file_exists($core_bundle)) {
diff --git a/src/Core/ScriptsPart1c.php b/src/Core/ScriptsPart1c.php
index fae16923..fb3aeb3c 100644
--- a/src/Core/ScriptsPart1c.php
+++ b/src/Core/ScriptsPart1c.php
@@ -90,11 +90,21 @@ trait ScriptsPart1c {
true
);
+ // Zibll lazySizes is the only media lazy-loading runtime.
+ $lazysizes_js = get_template_directory() . '/assets/js/lazysizes.js';
+ wp_enqueue_script(
+ 'aksrt-lazysizes',
+ $base_uri . '/assets/js/lazysizes.js',
+ [],
+ file_exists($lazysizes_js) ? (string) filemtime($lazysizes_js) : $version,
+ true
+ );
+
// Rehydrate system — must load before aksrt-script so AksrtFrontend is available
wp_enqueue_script(
'aksrt-rehydrate',
$base_uri . '/assets/js/rehydrate.js',
- [],
+ ['aksrt-lazysizes'],
file_exists(get_template_directory() . '/assets/js/rehydrate.js')
? (string) filemtime(get_template_directory() . '/assets/js/rehydrate.js')
: $version,
@@ -597,13 +607,26 @@ trait ScriptsPart1c {
'floatActionsId' => 'float-right-btns',
'tabbarId' => 'footer-tabbar',
],
- 'themeUri' => get_template_directory_uri(),
- 'codeHighlight' => class_exists('\AKSRT\Settings\Settings')
+ 'themeUri' => get_template_directory_uri(),
+ 'lazyScopes' => [
+ 'lazy_posts_thumb' => aksrt_is_lazy('lazy_posts_thumb'),
+ 'lazy_avatar' => aksrt_is_lazy('lazy_avatar'),
+ 'lazy_posts_content' => aksrt_is_lazy('lazy_posts_content'),
+ 'lazy_comment' => aksrt_is_lazy('lazy_comment'),
+ 'lazy_private' => aksrt_is_lazy('lazy_private'),
+ 'lazy_sider' => aksrt_is_lazy('lazy_sider'),
+ 'lazy_cover' => aksrt_is_lazy('lazy_cover'),
+ 'lazy_other' => aksrt_is_lazy('lazy_other'),
+ ],
+ 'lazyThumbs' => [
+ 'default' => aksrt_get_lazy_thumb(),
+ 'sm' => aksrt_get_lazy_thumb('sm'),
+ 'lg' => aksrt_get_lazy_thumb('lg'),
+ ],
+ 'lazyAvatar' => aksrt_get_default_avatar_url(),
+ 'codeHighlight' => class_exists('\AKSRT\Settings\Settings')
? \AKSRT\Settings\Settings::get_code_highlight_config()
: ['enabled' => true, 'lightTheme' => 'enlighter', 'darkTheme' => 'monokai', 'lineNumbers' => false, 'showButtons' => true, 'maxHeight' => 500],
- 'lazyload' => class_exists('\AKSRT\Settings\Settings')
- ? \AKSRT\Settings\Settings::get_lazyload_config()
- : ['enabled' => true, 'animation' => 'blur', 'placeholder_url' => '', 'blur' => true],
'systemNotice' => class_exists('\AKSRT\Settings\Settings')
? \AKSRT\Settings\Settings::get_system_notice_config()
: ['enabled' => false],
diff --git a/src/Frontend/NavWalker.php b/src/Frontend/NavWalker.php
index e5ceb991..af8b7820 100644
--- a/src/Frontend/NavWalker.php
+++ b/src/Frontend/NavWalker.php
@@ -143,7 +143,7 @@ class NavWalker extends \Walker_Nav_Menu {
? ''
. esc_html((string) $args['badge']) . '
'
: '';
- $img_html = '' . esc_html($title) . '
' : '';
return '';
@@ -201,7 +201,7 @@ class NavWalker extends \Walker_Nav_Menu {
$icon = aksrt_render_menu_icon((string) $args['icon'], true);
}
if (!empty($args['img_icon'])) {
- $icon = '';
if ($value !== '') {
- echo '
';
+ echo '
';
}
echo '';
echo '
';
diff --git a/src/WidgetSystem/PostRenderer.php b/src/WidgetSystem/PostRenderer.php
index 514aa29d..a1ed9ba1 100644
--- a/src/WidgetSystem/PostRenderer.php
+++ b/src/WidgetSystem/PostRenderer.php
@@ -90,6 +90,8 @@ final class PostRenderer {
return $html . '';
}
$label = $mode === 'infinite' ? __('继续加载', 'aksrt') : __('加载更多', 'aksrt');
- return '';
+ $class = $mode === 'infinite' ? 'aksrt-widget-load-more ias-btn lazyload' : 'aksrt-widget-load-more';
+ $action = $mode === 'infinite' ? ' lazyload-action="ias"' : '';
+ return '';
}
}
diff --git a/src/WidgetSystem/RendererHelpers.php b/src/WidgetSystem/RendererHelpers.php
index d51b3623..ec0d444f 100644
--- a/src/WidgetSystem/RendererHelpers.php
+++ b/src/WidgetSystem/RendererHelpers.php
@@ -20,12 +20,11 @@ final class RendererHelpers {
return $link['target'] === '_blank' ? ' target="_blank" rel="noopener noreferrer"' : '';
}
- public static function image(string $url, string $alt = '', string $class = ''): string {
+ public static function image(string $url, string $alt = '', string $class = '', string $key = 'lazy_other', string $lazy_src = ''): string {
if ($url === '') {
return '';
}
- return '' . esc_html__('视频加载失败,请稍后重试。', 'aksrt') . '
' . esc_html__('视频加载失败,请稍后重试。', 'aksrt') . '
' . esc_html((string) ($slide['title'] ?? '')) . '
' . esc_html((string) ($slide['description'] ?? '')) . '
-
/>
+
alt="">
diff --git a/templates/parts/content-gallery.php b/templates/parts/content-gallery.php
index 75370127..d07f3c82 100644
--- a/templates/parts/content-gallery.php
+++ b/templates/parts/content-gallery.php
@@ -35,9 +35,8 @@ if (empty($images)) return;
class="content-gallery__link"
data-caption="">
-
alt=""
- class="content-gallery__img"
width=""
height="">
diff --git a/templates/parts/content-post-card.php b/templates/parts/content-post-card.php
index 4a5a7b97..fec023b0 100644
--- a/templates/parts/content-post-card.php
+++ b/templates/parts/content-post-card.php
@@ -1,174 +1,31 @@
- $mode,
- 'context' => $context,
- ]);
-
- echo aksrt_render_post($config); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
- return;
-}
-
-// ============================================================
-// Fallback: self-contained rendering when shared renderer unavailable
-// ============================================================
-
-$args = isset($args) && is_array($args) ? $args : [];
-
-$lazy_cfg = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_lazyload_config() : ['enabled' => false, 'placeholder_url' => ''];
-$lazy_on = !empty($lazy_cfg['enabled']);
-$placeholder_url = !empty($lazy_cfg['placeholder_url']) ? (string) $lazy_cfg['placeholder_url'] : (get_template_directory_uri() . '/assets/img/placeholder.svg');
-
-$forced_layout = (string) get_query_var('aksrt_post_card_layout', '');
-$layout = 'card';
-if (is_string($forced_layout) && in_array($forced_layout, ['card', 'list', 'masonry', 'grid-cms'], true)) {
- $layout = $forced_layout;
-} elseif (function_exists('aksrt_get_post_flow') && aksrt_get_post_flow(get_the_ID()) === 'cms') {
- $layout = 'grid-cms';
-} elseif (class_exists('\AKSRT\Settings\Settings')) {
- $layout = \AKSRT\Settings\Settings::get_archive_layout();
-}
-
-$post_id = get_the_ID();
-$author_id = get_the_author_meta('ID');
-$author = get_the_author();
-$avatar_url = get_avatar_url($author_id, ['size' => 40]);
-$time_ago = human_time_diff(get_the_time('U'), current_time('timestamp')) . __('前', 'aksrt');
-$excerpt = wp_trim_words(get_the_excerpt(), 'list' === $layout ? 30 : 20, '...');
-$tags = get_the_tags() ?: [];
-$categories = get_the_category() ?: [];
-$comment_count = (int) get_comments_number();
-$views = function_exists('aksrt_get_post_views') ? aksrt_get_post_views($post_id) : 0;
-$is_sticky = is_sticky($post_id);
-$title_html = isset($args['title_html']) ? (string) $args['title_html'] : get_the_title();
-$resource_badge = function_exists('aksrt_resource_card_badge_text') ? aksrt_resource_card_badge_text($post_id) : '';
-
-$img_url = '';
-if (has_post_thumbnail()) {
- $img_url = get_the_post_thumbnail_url($post_id, 'medium_large');
-} elseif (function_exists('aksrt_get_first_content_image_url')) {
- $img_url = (string) aksrt_get_first_content_image_url($post_id);
-}
-$has_img = !empty($img_url);
-
-$scene = (string) get_query_var('aksrt_post_card_scene', '');
-$is_home_scene = $scene === 'home' || is_front_page() || (is_home() && !is_paged());
-$category_limit = $is_home_scene ? 1 : 3;
-$tag_limit = $is_home_scene ? 2 : 3;
-
-// Badges HTML
-ob_start();
-?>
-
-
->
-
-
- >
-
-
+ $mode,
+ 'context' => $context,
+])); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
diff --git a/templates/parts/docs/doc-index-card.php b/templates/parts/docs/doc-index-card.php
index bbfb0139..e17b0b74 100644
--- a/templates/parts/docs/doc-index-card.php
+++ b/templates/parts/docs/doc-index-card.php
@@ -24,7 +24,7 @@ $excerpt = wp_trim_words(get_the_excerpt(), 30, '...');
- -
-
-
-
-
-
-
-
- -
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
>
+
alt="">
diff --git a/templates/parts/home-modules/module-banner.php b/templates/parts/home-modules/module-banner.php
index 110838ce..e2cb4c95 100644
--- a/templates/parts/home-modules/module-banner.php
+++ b/templates/parts/home-modules/module-banner.php
@@ -70,12 +70,9 @@ $swiper_config = [
data-link="" data-target="">
-
alt=""
- loading=""
decoding="async"
- class="fit-cover"
>
diff --git a/templates/parts/home-modules/module-category_recommend_cards.php b/templates/parts/home-modules/module-category_recommend_cards.php
index 5d4365c8..f97bc959 100644
--- a/templates/parts/home-modules/module-category_recommend_cards.php
+++ b/templates/parts/home-modules/module-category_recommend_cards.php
@@ -23,10 +23,7 @@ $show_dates = !isset($cfg['show_dates']) || !empty($cfg['show_dates']);
if (empty($cat_ids)) return;
-// 懒加载配置
-$lazy_cfg = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_lazyload_config() : ['enabled' => false, 'placeholder_url' => ''];
-$lazy_on = !empty($lazy_cfg['enabled']);
-$placeholder = $lazy_cfg['placeholder_url'] ?: (get_template_directory_uri() . '/assets/img/placeholder.svg');
+$placeholder = aksrt_get_lazy_thumb('lg');
// 组装卡片数据
$cards = [];
@@ -84,12 +81,7 @@ if (empty($cards)) return;
0) : ?>
-
-
-
-
-
-
+
alt="name); ?>">
diff --git a/templates/parts/home-modules/module-friend_links.php b/templates/parts/home-modules/module-friend_links.php
index 8482cc80..44459705 100644
--- a/templates/parts/home-modules/module-friend_links.php
+++ b/templates/parts/home-modules/module-friend_links.php
@@ -32,7 +32,7 @@ if (empty($friend_links)) return;
-
>
+
alt="">
diff --git a/templates/parts/home-modules/module-hero.php b/templates/parts/home-modules/module-hero.php
index e530f284..12ff87c0 100644
--- a/templates/parts/home-modules/module-hero.php
+++ b/templates/parts/home-modules/module-hero.php
@@ -377,16 +377,18 @@ if (!empty($hero_banners)) :
}
// Background media (zibll order: video > image).
- $s_background = '';
- if ($use_video) {
- $poster = $image_url !== '' ? ' poster="' . esc_url($image_url) . '"' : '';
- $s_background = '';
- } elseif ($image_url !== '') {
- $s_background = '
0
- ? ' data-src="' . esc_url($image_url) . '" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"'
- : ' src="' . esc_url($image_url) . '"')
- . ' alt="' . esc_attr($img_alt) . '">';
+ $s_background = '';
+ if ($use_video) {
+ if (aksrt_is_lazy('lazy_sider')) {
+ $poster = $image_url !== '' ? ' data-poster="' . esc_url($image_url) . '"' : '';
+ $video_src = ' class="fit-cover radius8 lazyload" src="" data-src="' . esc_url($video_url) . '"';
+ } else {
+ $poster = $image_url !== '' ? ' poster="' . esc_url($image_url) . '"' : '';
+ $video_src = ' class="fit-cover radius8" src="' . esc_url($video_url) . '"';
+ }
+ $s_background = '';
+ } elseif ($image_url !== '') {
+ $s_background = '
';
} else {
continue;
}
@@ -403,7 +405,7 @@ if (!empty($hero_banners)) :
if ($layer_image === '') {
continue;
}
- $layer_img = '
';
+ $layer_img = '
';
$layer_parallax = isset($layer['parallax']) ? (int) $layer['parallax'] : 0;
$layer_attr = $layer_parallax ? ' data-swiper-parallax="' . $layer_parallax . '%"' : '';
$layer_class = !empty($layer['free_size']) ? ' slide-layer' : '';
diff --git a/templates/parts/home-modules/module-highlight_cards.php b/templates/parts/home-modules/module-highlight_cards.php
index 98c99435..bb4f99a1 100644
--- a/templates/parts/home-modules/module-highlight_cards.php
+++ b/templates/parts/home-modules/module-highlight_cards.php
@@ -38,7 +38,7 @@ if (empty($items)) return;
?>
< class="aksrt-highlight-card">
-
>
+
alt="">
diff --git a/templates/parts/home-modules/module-more.php b/templates/parts/home-modules/module-more.php
index 538355a3..9c008c12 100644
--- a/templates/parts/home-modules/module-more.php
+++ b/templates/parts/home-modules/module-more.php
@@ -57,7 +57,7 @@ if (empty($categories)) {
-
>
+
alt="">
diff --git a/templates/parts/home-modules/module-partner_marquee.php b/templates/parts/home-modules/module-partner_marquee.php
index 289807f0..816443ce 100644
--- a/templates/parts/home-modules/module-partner_marquee.php
+++ b/templates/parts/home-modules/module-partner_marquee.php
@@ -40,7 +40,7 @@ if (empty($items)) return;
?>
< class="aksrt-marquee__item">
-
>
+
alt="">
diff --git a/templates/parts/home-modules/module-product_showcase.php b/templates/parts/home-modules/module-product_showcase.php
index 473302aa..360d6cae 100644
--- a/templates/parts/home-modules/module-product_showcase.php
+++ b/templates/parts/home-modules/module-product_showcase.php
@@ -36,7 +36,7 @@ if (empty($products)) return;
-
>
+
alt="">
diff --git a/templates/parts/home-modules/module-user.php b/templates/parts/home-modules/module-user.php
index 76c75166..827f8f92 100644
--- a/templates/parts/home-modules/module-user.php
+++ b/templates/parts/home-modules/module-user.php
@@ -65,7 +65,7 @@ if (empty($users)) {
?>
-
>
+
alt="">
diff --git a/templates/parts/resource-download-box.php b/templates/parts/resource-download-box.php
index e27cacab..e47d436f 100644
--- a/templates/parts/resource-download-box.php
+++ b/templates/parts/resource-download-box.php
@@ -185,7 +185,7 @@ if ($is_need_purchase && $user_amount > 0) {
-
>
+
alt="">
diff --git a/templates/parts/user-home/panel-follow.php b/templates/parts/user-home/panel-follow.php
index d845d9e5..6925b31a 100644
--- a/templates/parts/user-home/panel-follow.php
+++ b/templates/parts/user-home/panel-follow.php
@@ -54,7 +54,7 @@ extract($args, EXTR_SKIP); // phpcs:ignore WordPress.PHP.DontExtract.extract_ext
-
+
alt="" width="48" height="48">
diff --git a/templates/parts/user/author-hero.php b/templates/parts/user/author-hero.php
index 20209009..cceecd5c 100644
--- a/templates/parts/user/author-hero.php
+++ b/templates/parts/user/author-hero.php
@@ -62,9 +62,7 @@ $pm_url = ($pm_enabled && $messages_url !== '')
-
>
+
alt="">
0) : ?>
>
+
diff --git a/templates/shortcodes/profile.php b/templates/shortcodes/profile.php
index 964d2b0d..4d877cae 100644
--- a/templates/shortcodes/profile.php
+++ b/templates/shortcodes/profile.php
@@ -41,7 +41,7 @@ $show_credits = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Setti
?>
-
>
+
alt="display_name); ?>" width="64" height="64">
display_name); ?>
diff --git a/tests/widget-system/lazyload-contract.test.cjs b/tests/widget-system/lazyload-contract.test.cjs
new file mode 100644
index 00000000..98e61788
--- /dev/null
+++ b/tests/widget-system/lazyload-contract.test.cjs
@@ -0,0 +1,138 @@
+'use strict';
+
+const assert = require('node:assert/strict');
+const { spawnSync } = require('node:child_process');
+const fs = require('node:fs');
+const path = require('node:path');
+const test = require('node:test');
+
+const root = path.resolve(__dirname, '..', '..');
+const read = (file) => fs.readFileSync(path.join(root, file), 'utf8');
+
+const lazyDefaults = {
+ lazy_posts_thumb: true,
+ lazy_avatar: true,
+ lazy_posts_content: false,
+ lazy_comment: true,
+ lazy_private: true,
+ lazy_sider: true,
+ lazy_cover: true,
+ lazy_other: true,
+ lazy_animation: 'blur',
+};
+
+function phpHarness(body, values = {}, userAgent = 'Mozilla/5.0') {
+ const helper = path.join(root, 'inc/helpers/template-tags/pagination-permissions.php');
+ const code = `
+define('ABSPATH', __DIR__);
+$_SERVER['HTTP_USER_AGENT'] = ${JSON.stringify(userAgent)};
+function add_filter() {}
+function add_action() {}
+function is_admin() { return false; }
+function wp_doing_ajax() { return false; }
+function sanitize_key($value) { return preg_replace('/[^a-z0-9_\\-]/', '', strtolower($value)); }
+function esc_attr($value) { return htmlspecialchars((string) $value, ENT_QUOTES); }
+function esc_url($value) { return (string) $value; }
+function get_template_directory_uri() { return 'https://theme.test'; }
+function aksrt_get_default_avatar_url() { return 'https://theme.test/default-avatar.png'; }
+eval('namespace AKSRT\\\\Settings; class Settings { public static $values = []; public static function get_value($key, $default = null) { return array_key_exists($key, self::$values) ? self::$values[$key] : $default; } }');
+\\AKSRT\\Settings\\Settings::$values = json_decode(${JSON.stringify(JSON.stringify(values))}, true);
+require ${JSON.stringify(helper)};
+${body}
+`;
+ const result = spawnSync('php', ['-r', code], { cwd: root, encoding: 'utf8' });
+ assert.equal(result.status, 0, result.stderr || result.stdout);
+ return result.stdout.trim();
+}
+
+function sourceFiles(directory) {
+ const output = [];
+ for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
+ if (entry.name === '.git' || entry.name === '.claude' || entry.name === 'build' || entry.name === 'vendor' || entry.name === 'node_modules' || entry.name === 'third-party') continue;
+ if (/\.min\.(?:js|css)$/.test(entry.name)) continue;
+ const full = path.join(directory, entry.name);
+ if (entry.isDirectory()) output.push(...sourceFiles(full));
+ else if (/\.(?:php|js|vue|css)$/.test(entry.name)) output.push(full);
+ }
+ return output;
+}
+
+test('admin schemas expose the ten Zibll lazy fields and defaults', () => {
+ const php = read('src/Admin/Schema/GlobalSchema.php');
+ const vue = read('assets/admin/src/schema/sections/global/common.js');
+ for (const [key, value] of Object.entries(lazyDefaults)) {
+ const literal = typeof value === 'string' ? `'${value}'` : String(value);
+ assert.match(php, new RegExp(`'key'\\s*=>\\s*'${key}'[\\s\\S]*?'default'\\s*=>\\s*${literal}`));
+ assert.match(vue, new RegExp(`${key}:\\s*${literal}`));
+ }
+ assert.match(php, /'key'\s*=>\s*'thumbnail'[\s\S]*?thumbnail\.svg/);
+ assert.match(vue, /thumbnail:\s*defaultThumbnail/);
+});
+
+test('PHP helpers emit placeholder/data-src, direct src, and crawler bypass', () => {
+ const enabled = phpHarness("echo aksrt_get_lazy_attr('lazy_posts_thumb', 'https://cdn.test/post.webp', 'fit-cover');");
+ assert.match(enabled, /class="lazyload fit-cover"/);
+ assert.match(enabled, /src="https:\/\/theme\.test\/assets\/img\/thumbnail\.svg"/);
+ assert.match(enabled, /data-src="https:\/\/cdn\.test\/post\.webp"/);
+
+ const disabled = phpHarness("echo aksrt_get_lazy_attr('lazy_posts_thumb', 'https://cdn.test/post.webp', 'fit-cover');", { lazy_posts_thumb: false });
+ assert.equal(disabled, 'class="fit-cover" src="https://cdn.test/post.webp"');
+
+ const crawler = phpHarness("echo aksrt_get_lazy_attr('lazy_posts_thumb', 'https://cdn.test/post.webp', 'fit-cover');", {}, 'Googlebot/2.1');
+ assert.equal(crawler, 'class="fit-cover" src="https://cdn.test/post.webp"');
+
+ const empty = phpHarness("echo aksrt_get_lazy_attr('lazy_other', '', 'media');");
+ assert.equal(empty, 'class="media" src=""');
+});
+
+test('content, avatar, and responsive image paths follow one contract', () => {
+ const content = phpHarness(`
+$html = '
';
+echo aksrt_lazy_content_images($html);
+`, { lazy_posts_content: true });
+ assert.match(content, /thumbnail-lg\.svg/);
+ assert.match(content, /data-src="https:\/\/cdn\.test\/photo\.jpg"/);
+ assert.match(content, /data-srcset="https:\/\/cdn\.test\/photo-2x\.jpg 2x"/);
+ assert.doesNotMatch(content, /\ssrcset=/);
+
+ const avatar = phpHarness("echo aksrt_lazy_avatar_html('
');");
+ assert.match(avatar, /class="lazyload avatar"/);
+ assert.match(avatar, /src="https:\/\/theme\.test\/default-avatar\.png"/);
+ assert.match(avatar, /data-src="https:\/\/cdn\.test\/avatar\.png"/);
+ assert.doesNotMatch(avatar, /loading=/);
+});
+
+test('one lazySizes runtime owns dynamic media, backgrounds, videos, and IAS', () => {
+ const runtime = read('assets/js/lazysizes.js');
+ const scripts = read('src/Core/ScriptsPart1c.php');
+ const pagination = read('assets/js/core/pagination.js');
+ const widgets = read('assets/widgets/frontend.js');
+
+ assert.match(scripts, /'aksrt-lazysizes'/);
+ assert.match(scripts, /'aksrt-rehydrate'[\s\S]*?\['aksrt-lazysizes'\]/);
+ assert.match(runtime, /lazybeforeunveil/);
+ assert.match(runtime, /source\[data-src\],source\[data-srcset\]/);
+ assert.match(runtime, /data-bg/);
+ assert.match(runtime, /lazyload-action/);
+ assert.match(runtime, /element\.hasAttribute\('remote-box'\)[\s\S]*?element\.click\(\)/);
+ assert.doesNotMatch(pagination, /IntersectionObserver|new Image\(/);
+ assert.doesNotMatch(widgets, /IntersectionObserver/);
+});
+
+test('legacy lazy identifiers and theme-native loading attributes are gone', () => {
+ const files = sourceFiles(root).filter((file) => !file.endsWith('lazyload-contract.test.cjs'));
+ const source = files.map((file) => fs.readFileSync(file, 'utf8')).join('\n');
+ const forbidden = [
+ 'data-' + 'lazy-animation',
+ 'lazyload_' + 'enabled',
+ 'get_' + 'lazyload_config',
+ 'aksrt_' + 'lazy_img_attrs',
+ 'aksrt_' + 'lazy_loading',
+ ];
+ for (const token of forbidden) assert.equal(source.includes(token), false, token);
+ assert.doesNotMatch(source, /aksrt-lazy(?!sizes)/);
+ assert.doesNotMatch(source, /aksrt-loaded/);
+ assert.doesNotMatch(source, /loading=["'](?:lazy|eager)["']/);
+ assert.doesNotMatch(source, /\.loading\s*=\s*["'](?:lazy|eager)["']/);
+ assert.doesNotMatch(source, /setAttribute\(\s*["']loading["']/);
+});
';
+echo aksrt_lazy_content_images($html);
+`, { lazy_posts_content: true });
+ assert.match(content, /thumbnail-lg\.svg/);
+ assert.match(content, /data-src="https:\/\/cdn\.test\/photo\.jpg"/);
+ assert.match(content, /data-srcset="https:\/\/cdn\.test\/photo-2x\.jpg 2x"/);
+ assert.doesNotMatch(content, /\ssrcset=/);
+
+ const avatar = phpHarness("echo aksrt_lazy_avatar_html('