chore(branding): remove leftover upstream theme identifiers

The theme was renamed Zibll/子比 → AKSRT → Jio, but upstream branding
survived the sweeps in CSS classes, the SVG sprite prefix, a persisted
widget field ID, JS events, admin Vue class names, test infrastructure
and docblocks.

Renames:
- zib-widget / zib-widget-wrap / zib-slider → jio-widget-box /
  jio-widget-box-wrap / jio-slider-box (jio-widget is taken by the modern
  widget shell, jio-box-* by the card primitives)
- zib-partners-scroll + zps-* → jio-partners-scroll + jps-*
- zib-combo-info-card + zci-* → jio-combo-info-card + jci-*
- zibsvg- → jiosvg-, including the exported picker helpers and the
  fa-zibsvg- family-prefix guard
- zibpay_type → pay_type; the dual-read fallback in PostQuery collapses
  to a single key
- [zibajax="submit"] dropped (no PHP emitter); zib_ajax.success →
  jio_ajax.success
- aks-* admin Vue classes → jio-*
- zib_palette() → palette()

User-facing vendor traces are gone: the floating "more" button default no
longer ships a zibll.com link or 子比主题 marketing copy, the notice
widget ships no preset promo entries, and the four 官网教程 links are
removed from the post-list admin schema.

Test infrastructure renamed to neutral names (docker-compose.reference.yml,
Caddyfile, article-baseline.json, modern-widgets-contract.test.cjs) with
their DB/volume/env/slug identifiers following.

Kept intentionally, documented in tests/fixtures/README.md: the golden
fixture reference fingerprint (a SHA-256 record of an external directory,
read by validate-widget-golden / generate-widget-golden-fixture /
audit-widget-system), the doesNotMatch guards that prove the old tokens are
gone, and the reference theme's own meta key in the visual fixtures.

No backward-compat or data migration: saved widget configs holding old
icon keys or the old field ID silently lose them, per the project's
rewrite-over-compatibility rule.

Verified: 132/132 node contract tests, php tests/widget-system/run.php
(146 assertions), audit-admin-contracts, audit-psr4-paths and
validate-widget-golden all green; tracked bundles regenerated and in sync.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kate522andClaude Opus 5 committed 2026-11-02 00:06:54 +08:00
1 parent 42cc64106d
commit 427968a721
188 files changed
+915 -967

No files matched your search

@@ -1,7 +1,7 @@
'use strict';
/**
* 「百度推送」后台设置页契约(对齐参考主题 zibll):
* 「百度推送」后台设置页契约:
* 1) PHP schema(SchemaExtensionsPush.php)与 JS schema(push.js)字段键、顺序、默认值一致;
* 2) 参考主题字段全集存在:自动推送 JS、普通收录、快速收录、准入 Token、发布/更新触发;
* 3) 双路/迁移字段(SEO 页 seo_baidu_*、熊掌号 xzh_*、批量推送 batch_*)已彻底移除,无双路兼容;
@@ -27,7 +27,7 @@ const displayGroups = fs.readFileSync(path.join(root, 'src/Settings/DisplayPageG
const metaBox = fs.readFileSync(path.join(root, 'src/Extensions/SearchPushMetaBox.php'), 'utf8');
const functions = fs.readFileSync(path.join(root, 'functions.php'), 'utf8');
// 参考主题(zibll)百度推送字段全集,Jio 单一 canonical 配置面(扩展&增强 → 百度推送)。
// 百度推送字段全集,Jio 单一 canonical 配置面(扩展&增强 → 百度推送)。
const REFERENCE_KEYS = [
'baidu_push_enabled',
'baidu_push_token',
@@ -160,10 +160,8 @@ test('JS schema 与 PHP 字段键一致(ui_only 教程行除外)', () => {
for (const legacy of LEGACY_KEYS) {
assert.ok(!keys.includes(legacy), `JS schema 残留旧字段: ${legacy}`);
}
// 参考主题 desc 中的官网教程链接以 ui_only content 行承载。
assert.match(js, /ui_only:\s*true/);
assert.match(js, /https:\/\/www\.zibll\.com\/1717\.html/);
assert.match(js, /https:\/\/www\.zibll\.com\/683\.html/);
// 说明内置于字段 description,且不得再指向第三方站点。
assert.doesNotMatch(js, /https?:\/\/www\.zibll\.com/);
});
test('JS schema 默认值与选项对齐参考主题', () => {
@@ -1,9 +1,8 @@
/**
* 高级筛选设置页参考主题 1:1 契约。
*
* 参考:zibll inc/options/admin-options.php「高级筛选」区块(5251-5424 行)与
* 前台链路(zib-category.php zib_get_ajax_option_menu / zib_get_option_custom_filter_but、
* zib-post.php zib_sift_posts_per_page)。
* 参考实现「高级筛选」区块与前台链路(分类/标签归档的 AJAX 选项菜单、自定义
* 筛选按钮、每页筛选条数)。
*/
const test = require('node:test');
const assert = require('node:assert');
@@ -92,10 +91,10 @@ test('JS schema 默认值、选项与依赖对齐参考主题', () => {
assert.match(js, /key: 'orderby_lists',[\s\S]{0,220}?dependsOn:\s*\{\s*key:\s*'orderby_s',\s*value:\s*true\s*\}/);
// custom_filters 为动态选项 checkbox(引用 custom_filter 维度定义)。
assert.match(js, /key: 'custom_filters',[\s\S]{0,400}?options:\s*'custom_filter'/);
// 提示行承载参考主题 submessage 与官网教程链接。
// 提示行承载筛选说明,且不得再指向第三方站点。
assert.match(js, /type:\s*'content'/);
assert.match(js, /ui_only:\s*true/);
assert.match(js, /zibll\.com\/15886\.html/);
assert.doesNotMatch(js, /zibll\.com/);
assert.match(js, /避免与其他mate_key重复/);
});
@@ -127,11 +126,11 @@ test('JS schema 与 PHP schema 一致性', () => {
assert.match(php, /'addText'\s*=>\s*'添加筛选类别'/);
assert.match(php, /'addText'\s*=>\s*'添加值'/);
assert.match(php, /'addText'\s*=>\s*'添加自定义分类筛选'/);
// 排序选项不含 zibpay 系列与销量(本项目无对应运行时)。
// 排序选项不含付费商品价格系列与销量(本项目无对应运行时)。
assert.ok(!js.includes('zibpay_price') && !js.includes('sales_volume'));
});
test('前台链路:覆盖与门禁(参考主题 zib-category.php 语义)', () => {
test('前台链路:覆盖与门禁', () => {
// cat 页按 cat_custom_filter 覆盖,回退 custom_filter_show 门禁。
assert.match(postDisplay, /function get_archive_custom_filter_config\(int \$term_id, string \$page\)/);
assert.match(postDisplay, /if \(\$page === 'cat'\)/);
@@ -1,7 +1,7 @@
'use strict';
/**
* 「文章页面」后台设置页契约(对齐参考主题 zibll 1:1):
* 「文章页面」后台设置页契约:
* 1) PHP schema(SchemaPostList.php page section 2.0.0)字段键、顺序、默认值与
* JS schema(assets/admin/src/schema/sections/post-list/page.js)一致;
* 2) 参考主题字段全集存在:三类封面(article_image_cover / article_slide_cover /
@@ -67,14 +67,14 @@ function phpSection(src, sectionKey) {
const pagePhp = phpSection(php, 'page');
// 参考主题 admin-options.php 4934–5249 的字段顺序(含 fieldset 父字段与子字段)。
// page section 字段顺序(含 fieldset 父字段与子字段)。
const PAGE_FIELD_SEQUENCE = [
'article_image_cover',
'article_image_cover_option',
'scale', // article_image_cover_option.scale
'article_slide_cover',
'article_slide_cover_option',
// article_slide_cover_option(CFS_Module::slide 全字段)
// article_slide_cover_option(幻灯片封面全字段)
'direction', 'loop', 'button', 'pagination', 'effect', 'scale_height', 'scale',
'auto_height', 'max_height', 'min_height', 'pc_height', 'm_height',
'spacebetween', 'speed', 'autoplay', 'interval',
@@ -159,7 +159,7 @@ test('PHP page section 默认值对齐参考主题', () => {
assert.match(pagePhp, /'post_related_orderby',\s*'label'\s*=>\s*'排序方式',\s*'type'\s*=>\s*'select',\s*'default'\s*=>\s*'views'/);
});
test('PHP slide fieldset 全字段及嵌套依赖对齐 CFS_Module::slide', () => {
test('PHP slide fieldset 全字段及嵌套依赖齐全', () => {
// 幻灯片默认值(pagination: true, pc_height: 380, m_height: 180 为参考主题默认)。
assert.match(pagePhp, /'direction'\s*=>\s*'horizontal',\s*'loop'\s*=>\s*true,\s*'button'\s*=>\s*false,\s*'pagination'\s*=>\s*true,\s*'effect'\s*=>\s*'slide'/);
assert.match(pagePhp, /'pc_height'\s*=>\s*380,\s*'m_height'\s*=>\s*180,\s*'spacebetween'\s*=>\s*15,\s*'speed'\s*=>\s*0,\s*'autoplay'\s*=>\s*true,\s*'interval'\s*=>\s*4/);
@@ -199,9 +199,10 @@ test('JS schema 与 PHP 字段键一致(ui_only 一言行除外)', () => {
}
assert.ok(!js.includes(`key: 'share_s'`), 'JS page schema 残留 share_s');
assert.ok(!/key:\s*'post_rewards_/.test(js), 'JS page schema 残留 post_rewards_*');
// 参考主题视频封面配置教程链接以 ui_only description 承载。
// 视频封面配置说明以 ui_only description 承载,且不得再指向第三方站点。
assert.match(js, /ui_only:\s*true/);
assert.match(js, /https:\/\/www\.zibll\.com\/1900\.html/);
assert.match(js, /视频封面配置/);
assert.doesNotMatch(js, /zibll\.com/);
});
test('JS schema 默认值与依赖对齐参考主题', () => {
@@ -251,7 +252,7 @@ test('社交分享位于全局功能并使用参考主题唯一键集', () => {
assert.doesNotMatch(shareJs, /share_wechat_s|share_wechat_appid|share_wechat_app_secret|share_only_logo/);
});
test('post_rewards_* 迁移至用户功能页 rewards 组(对齐参考主题 8977 行)', () => {
test('post_rewards_* 迁移至用户功能页 rewards 组', () => {
assert.match(usersPhp, /\['key' => 'rewards', 'title' => '打赏', 'fields' => \[/);
assert.match(usersPhp, /'post_rewards_s', 'label' => '用户打赏功能', 'type' => 'switcher', 'default' => true/);
assert.match(usersPhp, /'post_rewards_text', 'label' => '打赏按钮文案', 'type' => 'input', 'default' => '赞赏'/);
@@ -287,7 +288,7 @@ test('运行时只读取新键并接线封面/缩进/版权/一言', () => {
assert.match(runtime, /max\(20, min\(200, \(int\) \(\$image_cover_option\['scale'\] \?\? 35\)\)\)/);
// 视频封面比例 clamp 0-200(0 = 不固定长宽比例)。
assert.match(runtime, /max\(0, min\(200, \(int\) \(\$video_cover_option\['scale'\] \?\? 0\)\)\)/);
// 幻灯片配置归一化(CFS_Module::slide 全字段)。
// 幻灯片配置归一化(幻灯片封面全字段)。
assert.match(runtime, /normalize_slide_cover_option\(\$slide_option_raw\)/);
for (const key of ['direction', 'loop', 'button', 'pagination', 'effect', 'scale_height', 'scale', 'auto_height', 'max_height', 'min_height', 'pc_height', 'm_height', 'spacebetween', 'speed', 'autoplay', 'interval']) {
assert.ok(runtime.includes(`'${key}'`), `normalize_slide_cover_option 缺少 ${key}`);