refactor(assets): vendor 资产迁入标准目录并全仓去除 zibll 标识

- assets/vendor 全量迁移: fontawesome5→assets/fontawesome5, css→assets/css,
  js→assets/js/runtime(避开 14 个同名自有文件), img 合并去重→assets/img,
  fonts→assets/fonts; 删除 assets/vendor
- libs 五个与 widgets/third-party 字节相同的库不重复入库, loader paths 改指向
- 运行时切换: _win.uri=assets 根, loader baseUrl=/js/runtime, enlighter 注入
  路径同步; PHP 7 个引用文件切换并改名 $zibll_*→$runtime_*
- 去品牌: Qinver 头注释/品牌 console.log/演示链接清除, 默认文案中性化
- 功能标识符改名: zib__→aksrt__, zib_ajax→aksrt_ajax, window.zib→
  window.aksrtLegacy, zibllblock/*→aksrtblock/*, .zib-widget→.aksrt-panel,
  .zib-slider→.aksrt-slider, zib_menu_options meta 键等
- 自有 CSS 改名: legacy-utilities/compat-vars/footer shell
- admin SPA 重建; 契约测试同步(路径/断言/文件更名)
- 例外保留: tests/visual 对照环境与 fixtures 前缀(外部 Zibll 产品引用)

验证: php -l 133 个改动文件通过; runtime 86 个 JS node --check 通过;
契约测试 68/70(2 个失败经 stash 对照确认为存量问题)
This commit is contained in:
2026-08-22 16:16:30 +08:00
parent 4f2391fb64
commit 9375b1c30c
591 changed files with 1690 additions and 11041 deletions
@@ -8,7 +8,7 @@ const test = require('node:test');
const root = path.resolve(__dirname, '..', '..');
const read = (file) => fs.readFileSync(path.join(root, file), 'utf8');
test('icon card renderers keep vertical and horizontal Zibll DOM contracts separate', () => {
test('icon card renderers keep vertical and horizontal legacy DOM contracts separate', () => {
const helper = read('inc/helpers/aksrt-icon-cards.php');
const widgets = read('src/WidgetSystem/Renderers/GeneralRenderer.php');
const header = read('inc/helpers/homepage/header-components.php');
@@ -24,7 +24,7 @@ test('icon card renderers keep vertical and horizontal Zibll DOM contracts separ
assert.match(header, /empty\(\$card\['custom_icon'\]\)/);
});
test('homepage horizontal cards render fully from Zibll CSS with no dedicated stylesheet', () => {
test('homepage horizontal cards render fully from legacy CSS with no dedicated stylesheet', () => {
const baseCss = read('assets/css/frontend/base.css');
const widgetCss = read('assets/widgets/frontend.css');
const scripts = read('src/Core/ScriptsPart1b.php');
@@ -68,7 +68,7 @@ ${body}
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 (entry.name === '.git' || entry.name === '.claude' || entry.name === 'build' || entry.name === 'vendor' || entry.name === 'runtime' || 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));
@@ -77,7 +77,7 @@ function sourceFiles(directory) {
return output;
}
test('admin schemas expose the ten Zibll lazy fields and defaults', () => {
test('admin schemas expose the ten legacy 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)) {
@@ -122,8 +122,8 @@ echo aksrt_lazy_content_images($html);
assert.doesNotMatch(avatar, /loading=/);
});
test('Zibll owns lazySizes while AKSRT consumers share one image-attribute bridge', () => {
const runtime = read('assets/vendor/zibll/js/main.js');
test('the legacy runtime owns lazySizes while AKSRT consumers share one image-attribute bridge', () => {
const runtime = read('assets/js/runtime/main.js');
const bridge = read('assets/js/lazy-image-attr.js');
const scripts = read('src/Core/ScriptsPart1c.php');
const routeScripts = read('src/Core/ScriptsPart1b.php');
@@ -150,7 +150,7 @@ test('Zibll owns lazySizes while AKSRT consumers share one image-attribute bridg
assert.doesNotMatch(widgets, /IntersectionObserver/);
});
test('post lists have no second lazy switch and keep Zibll fallback thumbnails', () => {
test('post lists have no second lazy switch and keep legacy fallback thumbnails', () => {
const config = read('inc/helpers/posts-renderer/config.php');
const postData = read('inc/helpers/posts-renderer/post-data.php');
const markup = read('inc/helpers/posts-renderer/markup.php');
@@ -16,7 +16,7 @@ const controllerBase = read('src/Admin/ControllerBase.php')
const provider = read('src/Admin/SchemaProvider.php')
const settingsFacade = read('src/Settings/Settings.php')
const scriptsPart1c = read('src/Core/ScriptsPart1c.php')
const footerCss = read('assets/css/frontend/footer/zibll-shell.css')
const footerCss = read('assets/css/frontend/footer/shell.css')
const frontendBaseCss = read('assets/css/frontend/base.css')
const headerMenuButtons = read('inc/helpers/aksrt-header-menu-buttons.php')
const frontendRenderer = read('src/WidgetSystem/FrontendRenderer.php')
@@ -29,7 +29,7 @@ const vipCardRenderer = read('src/Content/VipServiceModal.php')
const vipModalCss = read('assets/css/frontend/vip-modal.css')
const payVipJs = read('assets/js/pay-vip.js')
const modalRuntimeJs = read('assets/js/core/modal-runtime.js')
const zibllMainCss = read('assets/vendor/zibll/css/main.css')
const legacyMainCss = read('assets/css/main.css')
function activeRepositorySource() {
const roots = ['assets/admin/src', 'assets/js', 'inc', 'src', 'templates']
@@ -66,7 +66,7 @@ test('page display exposes exactly eight ordered routes', () => {
assert.deepEqual(routeOrder, expected)
})
test('top-level field IDs match the Zibll V9.0 eight-page contract', () => {
test('top-level field IDs match the legacy V9.0 eight-page contract', () => {
assert.deepEqual(topLevelFieldIds('header_nav'), [
'header_theme_custom', 'header_theme_bg_custom', 'header_theme_bg', 'header_theme_color_custom',
'header_layout', 'mobile_header_layout', 'mobile_navbar_align', 'nav_fixed', 'nav_scroll_down_hide',
@@ -131,7 +131,7 @@ 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', () => {
test('header VIP hover cards match the legacy markup and style contract', () => {
assert.match(headerMenuButtons, /<span class="hover-show inline-block navbar-vip-hover">/)
assert.match(headerMenuButtons, /<div class="hover-show-con sub-menu sub-vip-card">/)
assert.match(vipCardRenderer, /aksrt_get_lazy_attr\('lazy_other', \$icon_url, 'img-icon'\)/)
@@ -146,15 +146,15 @@ test('header VIP hover cards match the Zibll markup and style contract', () => {
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)
assert.match(legacyMainCss, /\.sub-vip-card\s*\{[^}]*font-size:\s*12px;[^}]*padding:\s*0\s*!important;/s)
assert.match(legacyMainCss, /\.sub-vip-card \.vip-card\s*\{[^}]*display:\s*inline-block;[^}]*width:\s*240px;[^}]*margin:\s*5px;/s)
assert.match(legacyMainCss, /\.sub-vip-card \.vip-baicon\.abs-center\s*\{[^}]*font-size:\s*10em;[^}]*left:\s*55%;/s)
assert.match(legacyMainCss, /\.sub-vip-card \.vip-img\s*\{[^}]*display:\s*none;/s)
assert.match(headerCss, /\.navbar-top \.aksrt-navbar-actions \.navbar-vip-hover\s*\{[^}]*align-self:\s*stretch;[^}]*overflow:\s*visible;/s)
assert.match(headerCss, /\.navbar-top \.aksrt-navbar-actions \.navbar-vip-hover > \.sub-vip-card\s*\{[^}]*top:\s*100%;[^}]*right:\s*0;[^}]*left:\s*auto;[^}]*max-width:\s*calc\(100vw - 24px\);/s)
})
test('VIP purchase modal matches Zibll desktop-center and mobile-bottom positioning', () => {
test('VIP purchase modal matches legacy desktop-center and mobile-bottom positioning', () => {
const purchaseModal = payVipJs.slice(payVipJs.indexOf('function vipPay('), payVipJs.indexOf('function onDocClick('))
assert.doesNotMatch(purchaseModal, /mobileBottom:\s*false/)
@@ -45,7 +45,7 @@ test('the article stream exposes only the new typed renderer contract', () => {
assert.doesNotMatch(consumers, /content-post-card|aksrt_homepage_render_post_card/);
});
test('settings use Zibll list modes, grouped options, and destructive related keys', () => {
test('settings use legacy list modes, grouped options, and destructive related keys', () => {
const source = join(articleFiles);
const listSchema = read('assets/admin/src/schema/sections/post-list/list.js');
const pageSchema = read('assets/admin/src/schema/sections/post-list/page.js');
@@ -123,7 +123,7 @@ test('image resolution counts only content images and applies the configured Wor
assert.match(phpSchema, /'spare_thumbnail'.*'default' => \[\['img' => get_template_directory_uri\(\) \. '\/assets\/img\/thumbnail\.svg'\]\]/);
});
test('list, card, media, badge and Mini DOM follow dedicated Zibll structures', () => {
test('list, card, media, badge and Mini DOM follow dedicated legacy structures', () => {
const markup = read('inc/helpers/posts-renderer/markup.php');
const data = read('inc/helpers/posts-renderer/post-data.php');
const card = markup.slice(markup.indexOf('function aksrt_renderer_card'), markup.indexOf('function aksrt_renderer_mini'));
@@ -136,7 +136,7 @@ test('list, card, media, badge and Mini DOM follow dedicated Zibll structures',
assert.match(markup, /<div class="item-body flex xx flex1 jsb/);
assert.doesNotMatch(card, /item-excerpt|renderer_excerpt_markup|thumb-items/);
assert.match(data, /<div class="item-thumbnail/);
assert.match(data, /relative zib-slider.*new-swiper item-thumbnail/s);
assert.match(data, /relative aksrt-slider.*new-swiper item-thumbnail/s);
assert.match(data, /swiper-slide.*gradient-bg.*data-opacity="0\.2"/s);
assert.match(data, /\$fit = \$is_contain && !\$has_slides \? ' contain gradient-bg' : ''/);
assert.match(data, /video-thumb-box.*data-post-thumb-video/s);
@@ -180,13 +180,13 @@ test('post-card CSS owns the exact desktop and 767/640 responsive matrix', () =>
assert.doesNotMatch(mobile767, /\.posts-mini\s*\{[^}]*width:\s*100%/s);
assert.match(mobile640, /\.posts-mini\s*\{[^}]*width:\s*100%/s);
assert.match(mobile640, /\.posts-item:not\(\.no-thumb\) \.meta-right item\s*\{[^}]*display:\s*none/s);
assert.doesNotMatch(css, /\.aksrt-|post-card-cms|grid-cms/);
assert.doesNotMatch(css, /\.aksrt-(?!panel|slider)|post-card-cms|grid-cms/);
});
test('article metadata owns its flex and SVG contracts on every list route', () => {
const css = read('assets/css/frontend/post-card.css');
const scripts = read('src/Core/ScriptsPart1c.php');
const loader = read('assets/vendor/zibll/js/loader.js');
const loader = read('assets/js/runtime/loader.js');
assert.doesNotMatch(scripts, /aksrt-svg-icon|svg-icon-helper/);
assert.match(loader, /'svg-icon'\s*:\s*'svg-icon'/);
@@ -252,7 +252,7 @@ test('AJAX pagination can recover, caps auto loading and rehydrates appended med
assert.match(ajaxList, /if \(link\.closest\("\[data-aksrt-pagination\], \.aksrt-comment-pagination"\)\) return;/);
assert.match(media, /thumb-dplayer-playing/);
assert.doesNotMatch(media, /new Swiper|data-post-thumb-slider/);
assert.match(read('assets/vendor/zibll/js/main.min.js'), /new-swiper/);
assert.match(read('assets/js/runtime/main.min.js'), /new-swiper/);
assert.match(media, /data-post-thumb-video/);
assert.match(media, /window\.Grade\(container/);
assert.match(media, /linear-gradient\(135deg/);
@@ -260,7 +260,7 @@ test('AJAX pagination can recover, caps auto loading and rehydrates appended med
assert.match(read('src/Core/ScriptsPart1c.php'), /'aksrt-grade'/);
});
test('the pinned Zibll baseline records all source checksums', () => {
test('the pinned visual baseline records all source checksums', () => {
const baseline = JSON.parse(read('tests/visual/zibll-9.0-article-baseline.json'));
assert.equal(baseline.theme, 'Zibll');
assert.equal(baseline.version, '9.0');
+13 -13
View File
@@ -98,7 +98,7 @@ function createRuntime() {
function parseNotification(html) {
const id = (html.match(/ id="([^"]+)"/) || [])[1] || '';
const content = html.match(/<div class="notyf ([^"]+)">([\s\S]*)<\/div><\/div>$/);
assert.ok(content, 'notification markup should follow the Zibll contract');
assert.ok(content, 'notification markup should follow the legacy runtime contract');
const wrapper = new FakeElement(['noty1'], id);
const message = new FakeElement(['notyf', content[1]]);
message.innerHTML = content[2];
@@ -121,7 +121,7 @@ function createRuntime() {
return { body, timers, window };
}
test('notyf follows Zibll defaults, type normalization, and timing', () => {
test('notyf follows legacy-runtime defaults, type normalization, and timing', () => {
const runtime = createRuntime();
runtime.window.notyf('完成');
@@ -156,7 +156,7 @@ test('fixed-id notifications stay open until an in-place update', () => {
assert.equal(runtime.timers[0].delay, 3000);
});
test('clicking a notification uses the Zibll exit class and removal delay', () => {
test('clicking a notification uses the legacy exit class and removal delay', () => {
const runtime = createRuntime();
runtime.window.notyf('可关闭');
const notification = runtime.body.children[0].children[0];
@@ -285,11 +285,11 @@ test('VIP purchase and points exchange use direct fixed-id notyf flows', () => {
assert.match(scripts, /'aksrt-pay-vip',[\s\S]*?\/assets\/js\/pay-vip\.js',[\s\S]*?\[[^\]]*'aksrt-notyf'[^\]]*\]/);
});
test('payment entry points never load the removed Zibll pay runtime', () => {
const loader = read('assets/vendor/zibll/js/loader.js');
const zibllMain = [
read('assets/vendor/zibll/js/main.js'),
read('assets/vendor/zibll/js/main.min.js'),
test('payment entry points never load the removed legacy pay runtime', () => {
const loader = read('assets/js/runtime/loader.js');
const legacyMain = [
read('assets/js/runtime/main.js'),
read('assets/js/runtime/main.min.js'),
].join('\n');
const vip = read('assets/js/pay-vip.js');
const content = read('assets/js/cms-download.js');
@@ -299,15 +299,15 @@ test('payment entry points never load the removed Zibll pay runtime', () => {
].join('\n');
assert.doesNotMatch(loader, /['"]pay['"]\s*:/);
assert.doesNotMatch(zibllMain, /tbquire\(\[['"]pay['"]\]\)/);
assert.doesNotMatch(zibllMain, /indexOf\(['"]zippay['"]\)/);
assert.doesNotMatch(legacyMain, /tbquire\(\[['"]pay['"]\]\)/);
assert.doesNotMatch(legacyMain, /indexOf\(['"]zippay['"]\)/);
assert.match(vip, /\.pay-vip/);
assert.match(content, /data-aksrt-pay-content/);
assert.match(scripts, /'aksrt-pay-vip'/);
assert.match(scripts, /'aksrt-cms-download'/);
assert.match(scripts, /\$zibll_loader_version = file_exists\(\$zibll_loader_path\)/);
assert.match(scripts, /\$zibll_runtime_version = file_exists\(\$zibll_main_path\)/);
assert.match(scripts, /'ver'\s*=> \$zibll_runtime_version/);
assert.match(scripts, /\$runtime_loader_version = file_exists\(\$runtime_loader_path\)/);
assert.match(scripts, /\$runtime_version = file_exists\(\$runtime_main_path\)/);
assert.match(scripts, /'ver'\s*=> \$runtime_version/);
});
test('profile save uses AJAX rehydrate and a fixed-id notyf flow without query feedback', () => {