refactor: rename the theme brand and every identifier from AKSRT to Jio

Full-project rename. `git grep -i aksrt` is now empty apart from the
DBMigrator 3.3.0 changelog note that documents the rename itself.

Code identifiers
- PHP namespace AKSRT\ -> Jio\ (composer PSR-4 + 378 declarations)
- global constants AKSRT_* -> JIO_* (VERSION/DIR/URI, PAY_TYPE_*, CAPTCHA_*)
- procedural functions, hooks, options, meta keys, table names,
  cookies, query vars, ajax actions and nonces: aksrt_ -> jio_
- text domain aksrt -> jio; Theme Name -> Jio
- JS globals: aksrtData/aksrtAdminData/... -> jioData/jioAdminData/...,
  window.AKSRTCaptcha & friends -> window.JioCaptcha, Aksrt* -> Jio*
- Vue components Aks*.vue -> Jio*.vue (15 files renamed + imports)
- CSS classes/data-attrs/custom properties: aksrt- -> jio-
- REST namespace aksrt/v1 -> jio/v1 (incl. payment gateway callbacks)

Storage layer
- DB tables {prefix}aksrt_* -> {prefix}jio_*; SCHEMA_VERSION 3.2.0 -> 3.3.0
  so dbDelta creates the new names on install
- widget id_base aksrt_widget_* -> jio_widget_*
- uninstall.php drop list rebuilt from the actual migrator tables
  (dropped 3 stale entries, added the 17 missing ones)

Removed
- hardcoded https://api.aksrt.com/version.json default update endpoint;
  get_endpoint() now reads the 「更新端点」 setting and do_check() no-ops
  when it is empty

Files renamed: inc/helpers/aksrt-*.php -> jio-*.php (54),
assets/admin/src/components/form/Aks*.vue -> Jio*.vue (15).
Build artifacts regenerated: assets/css/build, assets/js/runtime,
assets/admin/build.

Verified: audit-psr4-paths errors=0, audit-admin-contracts errors=0
(warnings=56, unchanged baseline), 813/813 widget-system tests,
44/44 phpunit, php -l clean across all PHP.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kate522andClaude Opus 5 committed 2026-11-01 20:05:04 +08:00
1 parent 5b16bc6e15
commit 35bb96e82f
997 files changed
+28216 -28188

No files matched your search

@@ -112,24 +112,24 @@ function createRuntime({ imgEnabled = true, categories = [
if (!shell) return;
if (activeModal === shell) activeModal = null;
shell.remove();
document.dispatch('aksrt:modal:close', { detail: { shell } });
document.dispatch('jio:modal:close', { detail: { shell } });
},
};
const window = {
aksrtData: {
apiUrl: '/wp-json/aksrt/v1',
jioData: {
apiUrl: '/wp-json/jio/v1',
restNonce: 'test-nonce',
reportCategories: categories,
report: { imgEnabled },
},
AksrtModalRuntime: modalRuntime,
JioModalRuntime: modalRuntime,
fetch,
};
const jquery = () => ({
off() { return this; },
on(event, callback) {
if (event === 'auto_fun.aksrt-report') autoInit = callback;
if (event === 'auto_fun.jio-report') autoInit = callback;
return this;
},
});
@@ -157,7 +157,7 @@ function createRuntime({ imgEnabled = true, categories = [
get activeModal() { return activeModal; },
openReport(target = { target_type: 'post', target_id: 42, target_name: 'Article' }) {
const opener = document.createElement('button');
opener.setAttribute('data-aksrt-report', JSON.stringify(target));
opener.setAttribute('data-jio-report', JSON.stringify(target));
document.body.appendChild(opener);
const event = opener.dispatch('click');
return { ...modals.at(-1), opener, event };
@@ -175,7 +175,7 @@ function selectReason(modal, value) {
}
function submit(modal) {
return modal.shell.querySelector('.aksrt-report-form').dispatch('submit');
return modal.shell.querySelector('.jio-report-form').dispatch('submit');
}
function callsFor(runtime, endpoint) {
@@ -195,8 +195,8 @@ test('opens from an article button, associates the target, omits URL input, and
const runtime = createRuntime({ categories: [{ name: '<svg onload="run()">reason</svg>' }] });
const targetName = '<img src=x onerror="run()"> &';
const modal = runtime.openReport({ target_type: 'post', target_id: 73, target_name: targetName });
const target = modal.shell.querySelector('.aksrt-report-target__name');
const reason = modal.shell.querySelector('.aksrt-report-reason span');
const target = modal.shell.querySelector('.jio-report-target__name');
const reason = modal.shell.querySelector('.jio-report-reason span');
assert.equal(modal.event.defaultPrevented, true);
assert.equal(modal.options.title, '举报文章');
@@ -207,18 +207,18 @@ test('opens from an article button, associates the target, omits URL input, and
assert.equal(reason.querySelector('svg'), null);
assert.equal(modal.shell.querySelector('[name="report_url"]'), null);
assert.equal(modal.shell.querySelector('input[type="url"]'), null);
assert.ok(modal.shell.querySelector('.aksrt-report-target'));
assert.equal(modal.shell.querySelector('.aksrt-report-target__label').textContent, '关联对象:');
assert.equal(modal.shell.querySelector('.aksrt-report-target__icon'), null);
assert.ok(modal.shell.querySelector('.jio-report-target'));
assert.equal(modal.shell.querySelector('.jio-report-target__label').textContent, '关联对象:');
assert.equal(modal.shell.querySelector('.jio-report-target__icon'), null);
assert.equal(target.getAttribute('title'), target.textContent);
});
test('requires a radio reason and other text, then sends canonical fields with description', async () => {
const runtime = createRuntime();
const modal = runtime.openReport();
const form = modal.shell.querySelector('.aksrt-report-form');
const reasonError = form.querySelector('[data-aksrt-report-reason-error]');
const otherBox = form.querySelector('.aksrt-report-other');
const form = modal.shell.querySelector('.jio-report-form');
const reasonError = form.querySelector('[data-jio-report-reason-error]');
const otherBox = form.querySelector('.jio-report-other');
const otherInput = form.querySelector('[name="reason_other"]');
const description = form.querySelector('[name="report_desc"]');
@@ -265,7 +265,7 @@ test('preset reason ignores hidden custom text while including description in re
description.value = 'More context';
selectReason(modal, 1);
assert.equal(modal.shell.querySelector('.aksrt-report-other').hidden, true);
assert.equal(modal.shell.querySelector('.jio-report-other').hidden, true);
assert.equal(otherInput.disabled, true);
submit(modal);
const payload = payloadFor(callsFor(runtime, '/report/submit')[0]);
@@ -308,24 +308,24 @@ test('omits all image controls when image evidence is disabled', () => {
const runtime = createRuntime({ imgEnabled: false });
const modal = runtime.openReport();
assert.equal(modal.shell.querySelector('[data-aksrt-report-file]'), null);
assert.equal(modal.shell.querySelector('[data-aksrt-report-add]'), null);
assert.equal(modal.shell.querySelector('[data-aksrt-report-images]'), null);
assert.equal(modal.shell.querySelector('[data-aksrt-report-image-count]'), null);
assert.equal(modal.shell.querySelector('[data-jio-report-file]'), null);
assert.equal(modal.shell.querySelector('[data-jio-report-add]'), null);
assert.equal(modal.shell.querySelector('[data-jio-report-images]'), null);
assert.equal(modal.shell.querySelector('[data-jio-report-image-count]'), null);
});
test('counts in-flight images once, accepts exactly three, and blocks submit until ready', async () => {
const runtime = createRuntime();
const modal = runtime.openReport();
selectReason(modal, 0);
const fileInput = modal.shell.querySelector('[data-aksrt-report-file]');
const fileInput = modal.shell.querySelector('[data-jio-report-file]');
fileInput.files = [1, 2, 3].map((index) => ({ name: `evidence-${index}.png`, type: 'image/png' }));
fileInput.dispatch('change');
assert.equal(callsFor(runtime, '/report/upload-image').length, 3);
assert.equal(modal.shell.querySelector('[data-aksrt-report-image-count]').textContent, '3 / 3');
assert.equal(modal.shell.querySelector('[data-aksrt-report-submit]').disabled, true);
assert.equal(modal.shell.querySelector('[data-aksrt-report-status]').textContent, '图片正在上传,完成后即可提交');
assert.equal(modal.shell.querySelector('[data-jio-report-image-count]').textContent, '3 / 3');
assert.equal(modal.shell.querySelector('[data-jio-report-submit]').disabled, true);
assert.equal(modal.shell.querySelector('[data-jio-report-status]').textContent, '图片正在上传,完成后即可提交');
submit(modal);
assert.equal(callsFor(runtime, '/report/submit').length, 0);
@@ -334,9 +334,9 @@ test('counts in-flight images once, accepts exactly three, and blocks submit unt
data: { id: 800 + index, url: `https://evidence.test/${index + 1}.png` },
}));
await flushPromises();
assert.equal(modal.shell.querySelectorAll('.aksrt-report-image').length, 3);
assert.equal(modal.shell.querySelector('[data-aksrt-report-image-count]').textContent, '3 / 3');
assert.equal(modal.shell.querySelector('[data-aksrt-report-add]').disabled, true);
assert.equal(modal.shell.querySelectorAll('.jio-report-image').length, 3);
assert.equal(modal.shell.querySelector('[data-jio-report-image-count]').textContent, '3 / 3');
assert.equal(modal.shell.querySelector('[data-jio-report-add]').disabled, true);
fileInput.files = [{ name: 'fourth.png', type: 'image/png' }];
fileInput.dispatch('change');
@@ -353,39 +353,39 @@ test('counts in-flight images once, accepts exactly three, and blocks submit unt
test('retries a failed upload and deletes its pending attachment when removed', async () => {
const runtime = createRuntime();
const modal = runtime.openReport();
const fileInput = modal.shell.querySelector('[data-aksrt-report-file]');
const fileInput = modal.shell.querySelector('[data-jio-report-file]');
fileInput.files = [{ name: 'retry.png', type: 'image/png' }];
fileInput.dispatch('change');
callsFor(runtime, '/report/upload-image')[0].resolve({ success: false, message: 'Upload failed' });
await flushPromises();
const image = modal.shell.querySelector('.aksrt-report-image');
const image = modal.shell.querySelector('.jio-report-image');
assert.equal(image.getAttribute('data-upload-state'), 'error');
assert.match(modal.shell.querySelector('[data-aksrt-report-error]').textContent, /Upload failed/);
assert.match(modal.shell.querySelector('[data-jio-report-error]').textContent, /Upload failed/);
image.querySelector('[data-aksrt-report-retry]').dispatch('click');
image.querySelector('[data-jio-report-retry]').dispatch('click');
const retry = callsFor(runtime, '/report/upload-image')[1];
assert.ok(retry);
retry.resolve({ success: true, data: { id: 901, url: 'https://evidence.test/retry.png' } });
await flushPromises();
assert.equal(image.getAttribute('data-upload-state'), 'ready');
image.querySelector('[data-aksrt-report-remove]').dispatch('click');
image.querySelector('[data-jio-report-remove]').dispatch('click');
const deletion = callsFor(runtime, '/upload/pending/901')[0];
assert.ok(deletion);
assert.equal(deletion.options.method, 'DELETE');
assert.equal(modal.shell.querySelectorAll('.aksrt-report-image').length, 0);
assert.equal(modal.shell.querySelector('[data-aksrt-report-image-count]').textContent, '0 / 3');
assert.equal(modal.shell.querySelectorAll('.jio-report-image').length, 0);
assert.equal(modal.shell.querySelector('[data-jio-report-image-count]').textContent, '0 / 3');
});
test('server failure preserves values, reenables controls, and allows a retry', async () => {
const runtime = createRuntime();
const modal = runtime.openReport();
selectReason(modal, 'other');
const form = modal.shell.querySelector('.aksrt-report-form');
const form = modal.shell.querySelector('.jio-report-form');
const otherInput = form.querySelector('[name="reason_other"]');
const description = form.querySelector('[name="report_desc"]');
const submitButton = form.querySelector('[data-aksrt-report-submit]');
const submitButton = form.querySelector('[data-jio-report-submit]');
otherInput.value = 'A custom report reason';
description.value = 'Additional context';
@@ -402,7 +402,7 @@ test('server failure preserves values, reenables controls, and allows a retry',
assert.equal(otherInput.disabled, false);
assert.equal(description.disabled, false);
assert.equal(submitButton.disabled, false);
assert.equal(form.querySelector('[data-aksrt-report-error]').hidden, true);
assert.equal(form.querySelector('[data-jio-report-error]').hidden, true);
assert.deepEqual(runtime.notyfCalls.at(-1).slice(0, 3), ['Server rejected report', 'danger', 5]);
submit(modal);
@@ -416,9 +416,9 @@ test('uses a persistent shared toast per submit attempt without inline submittin
const runtime = createRuntime();
const modal = runtime.openReport();
selectReason(modal, 0);
const form = modal.shell.querySelector('.aksrt-report-form');
const button = form.querySelector('[data-aksrt-report-submit]');
const status = form.querySelector('[data-aksrt-report-status]');
const form = modal.shell.querySelector('.jio-report-form');
const button = form.querySelector('[data-jio-report-submit]');
const status = form.querySelector('[data-jio-report-status]');
submit(modal);
const firstToast = runtime.notyfCalls.at(-1);
@@ -467,7 +467,7 @@ test('blocks duplicate submits and closing an old submitting dialog cannot close
test('cleans pending attachments on close and when an upload completes after close', async () => {
const runtime = createRuntime();
const readyModal = runtime.openReport();
const readyFile = readyModal.shell.querySelector('[data-aksrt-report-file]');
const readyFile = readyModal.shell.querySelector('[data-jio-report-file]');
readyFile.files = [{ name: 'ready.png', type: 'image/png' }];
readyFile.dispatch('change');
callsFor(runtime, '/report/upload-image')[0].resolve({
@@ -482,7 +482,7 @@ test('cleans pending attachments on close and when an upload completes after clo
assert.equal(readyDeletion.options.method, 'DELETE');
const pendingModal = runtime.openReport();
const pendingFile = pendingModal.shell.querySelector('[data-aksrt-report-file]');
const pendingFile = pendingModal.shell.querySelector('[data-jio-report-file]');
pendingFile.files = [{ name: 'pending.png', type: 'image/png' }];
pendingFile.dispatch('change');
const pendingUpload = callsFor(runtime, '/report/upload-image')[1];
@@ -505,16 +505,16 @@ test('keeps a live child modal open and marks the finished report after success'
selectReason(report, 0);
submit(report);
const request = callsFor(runtime, '/report/submit')[0];
const child = runtime.modalRuntime.open({ className: 'aksrt-child-modal', html: '<p>Child dialog</p>' });
const child = runtime.modalRuntime.open({ className: 'jio-child-modal', html: '<p>Child dialog</p>' });
request.resolve({ success: true });
await flushPromises();
const form = report.shell.querySelector('.aksrt-report-form');
const form = report.shell.querySelector('.jio-report-form');
assert.equal(runtime.activeModal, child);
assert.equal(runtime.closeCalls.length, 0);
assert.equal(form.getAttribute('aria-busy'), 'false');
assert.equal(form.querySelector('[data-aksrt-report-submit]').textContent, '举报已提交');
assert.ok(report.shell.querySelector('[data-aksrt-report-status]'));
assert.equal(form.querySelector('[data-jio-report-submit]').textContent, '举报已提交');
assert.ok(report.shell.querySelector('[data-jio-report-status]'));
});
test('retains claimed evidence on post-close success and deletes it on post-close failure', async () => {
@@ -522,7 +522,7 @@ test('retains claimed evidence on post-close success and deletes it on post-clos
async function submitClosedReport(id, result) {
const modal = runtime.openReport();
selectReason(modal, 0);
const fileInput = modal.shell.querySelector('[data-aksrt-report-file]');
const fileInput = modal.shell.querySelector('[data-jio-report-file]');
fileInput.files = [{ name: `${id}.png`, type: 'image/png' }];
fileInput.dispatch('change');
callsFor(runtime, '/report/upload-image').at(-1).resolve({