Files
kate522andClaude Opus 5 35bb96e82f 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>
2026-11-01 20:05:04 +08:00

243 lines
11 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
(function ($) {
'use strict';
const config = window.jioWidgetAdmin || {};
const core = window.JioWidgetAdminCore;
function initForm(root) {
const $root = $(root);
$root.find('.jio-widget-color').wpColorPicker();
$root.find('.jio-widget-repeater__rows').sortable({
handle: '.dashicons-move',
axis: 'y',
update: renumberRepeaters,
});
$root.find('.jio-widget-terms__selected').sortable({
items: '.jio-widget-terms__chip',
update: () => $root.find('.jio-widget-terms').each((_i, el) => syncTerms(el)),
});
$root.find('input[type="range"]').each(function () {
const output = this.parentElement.querySelector('output');
if (output) this.addEventListener('input', () => { output.textContent = this.value; });
});
evaluateDependencies($root);
updateWidgetTitle($root);
updateRepeaterControls($root);
}
/* terms 字段:以“已选标签”为唯一真源,同步隐藏输入(选择顺序)与复选框。 */
function syncTerms(wrap) {
const $wrap = $(wrap);
const ids = $wrap.find('.jio-widget-terms__chip').map((_i, el) => String($(el).data('term-id'))).get();
$wrap.find('.jio-widget-terms__value').val(ids.join(',')).trigger('change');
$wrap.find('.jio-widget-terms__option input').each(function () {
this.checked = ids.indexOf(String(this.value)) !== -1;
});
}
function addTermChip(wrap, id, name) {
const $selected = $(wrap).find('.jio-widget-terms__selected');
if ($selected.find(`.jio-widget-terms__chip[data-term-id="${id}"]`).length) return;
const chip = $(`<span class="jio-widget-terms__chip" data-term-id="${id}"><span class="dashicons dashicons-move" aria-hidden="true"></span></span>`);
chip.append(document.createTextNode(name));
chip.append('<button type="button" class="button-link-delete jio-widget-terms__remove" aria-label="移除">×</button>');
$selected.append(chip);
}
function updateWidgetTitle(root) {
const $root = $(root);
const title = String($root.find('.jio-widget-field[data-field-id="title"] input').first().val() || '').trim();
if (!title) return;
$root.closest('.widget').find('.widget-title h3, .widget-title-action + h3').first().contents().filter(function () {
return this.nodeType === Node.TEXT_NODE;
}).first().replaceWith(`${title} `);
}
function loadForm(container) {
const $container = $(container);
if ($container.data('loading') || $container.data('loaded')) return;
const $widget = $container.closest('.widget, .customize-control-widget_form');
const inputName = String($widget.find('input[name^="widget-"]').first().attr('name') || '');
const number = core.resolveWidgetNumber(inputName, $widget.attr('id'), $container.data('widget-number'));
// New-widget templates use __i__ until WordPress assigns a real instance number.
if (!number) return;
$container.data('loading', true);
setLazyStatus($container, 'loading', config.i18n?.loading || '正在加载模块配置…');
$.post(config.ajaxUrl, {
action: config.action,
nonce: config.nonce,
id_base: $container.data('id-base'),
widget_number: number,
}).done((response) => {
if (!response?.success || !response.data?.html) {
$container.data('loading', false);
setLazyStatus($container, 'error', response?.data?.message || config.i18n?.error || '加载失败,请刷新页面后重试');
return;
}
const $form = $(response.data.html);
$container.data('loaded', true).replaceWith($form);
initForm($form);
}).fail((xhr) => {
$container.data('loading', false);
setLazyStatus($container, 'error', xhr?.responseJSON?.data?.message || config.i18n?.error || '加载失败,请刷新页面后重试');
});
}
/* Lazy placeholder status uses the reference t-notice box (t-loading / t-error). */
function setLazyStatus($container, type, message) {
const $notice = $('<div class="t-notice"></div>').addClass(`t-${type}`).text(message);
$container.find('.jio-widget-form-lazy__status').empty().append($notice);
}
function renumberRepeaters(_event, ui) {
const $form = $(ui?.item || this).closest('.jio-widget-form');
$form.find('.jio-widget-repeater__rows').each(function () {
$(this).children('.jio-widget-repeater__row').each(function (index) {
this.dataset.rowIndex = String(index);
});
});
$form.find('[name]').each(function () {
const rowIndexes = $(this).parents('.jio-widget-repeater__row').get().reverse().map((row) => Number(row.dataset.rowIndex || 0));
if (!rowIndexes.length) return;
this.name = core.replaceRepeaterIndexes(this.name, rowIndexes);
});
updateRepeaterTitles($form);
}
function updateRepeaterTitles($form) {
$form.find('.jio-widget-repeater__rows').each(function () {
$(this).children('.jio-widget-repeater__row').each(function (index) {
const $row = $(this);
const $title = $row.find('.jio-widget-repeater__title').first();
const prefix = String($title.data('title-prefix') || '项目');
const $firstControl = $row.children('.jio-widget-repeater__fields').find('input:not([type="hidden"]), select, textarea').first();
const value = String($firstControl.val() || '').trim();
$title.text(prefix + (index + 1) + (value ? ':' + value : ''));
});
});
}
function updateRepeaterControls($root) {
$root.filter('.jio-widget-repeater').add($root.find('.jio-widget-repeater')).each(function () {
const $repeater = $(this);
const count = $repeater.children('.jio-widget-repeater__rows').children('.jio-widget-repeater__row').length;
const min = Number($repeater.data('min-items') || 0);
const max = Number($repeater.data('max-items') || 50);
$repeater.children('.jio-widget-repeater__rows').children('.jio-widget-repeater__row').children('.jio-widget-repeater__bar').children('.jio-widget-repeater__remove').prop('disabled', count <= min);
$repeater.children('.jio-widget-repeater__add').prop('disabled', count >= max);
});
}
function fieldValue($form, id) {
const $field = $form.find(`.jio-widget-field[data-field-id="${CSS.escape(id)}"]`).first();
const $checked = $field.find('input:checked').first();
if ($checked.length) return String($checked.val());
return String($field.find('input,select,textarea').first().val() ?? '');
}
function evaluateDependencies($form) {
$form.find('[data-dependency]').each(function () {
const rule = core.parseDependency(this.dataset.dependency || '[]');
const $row = $(this).closest('.jio-widget-repeater__row');
const scope = $row.length ? $row : $form;
const ids = Array.isArray(rule[0]) ? rule[0].map((part) => part[0]) : String(rule[0] || '').split('|');
const current = {};
ids.forEach((id) => { current[id] = fieldValue(scope, id); });
this.hidden = !core.dependencyVisible(rule, current);
});
}
$(document)
.on('click', '.widget-top', function () {
const $widget = $(this).closest('.widget, .customize-control-widget_form');
window.setTimeout(() => $widget.find('.jio-widget-form-lazy').each(function () { loadForm(this); }), 20);
})
.on('change input', '.jio-widget-form input, .jio-widget-form select, .jio-widget-form textarea', function () {
const $form = $(this).closest('.jio-widget-form');
evaluateDependencies($form);
updateWidgetTitle($form);
updateRepeaterTitles($form);
})
.on('click', '.jio-widget-repeater__add', function () {
const $repeater = $(this).closest('.jio-widget-repeater');
const max = Number($repeater.data('max-items') || 50);
const $rows = $repeater.children('.jio-widget-repeater__rows');
if ($rows.children().length >= max) return;
const index = $rows.children().length;
const token = String($repeater.data('index-token') || '__index__');
const html = $repeater.children('template').html().replaceAll(token, String(index));
const $row = $(html).appendTo($rows);
initForm($row);
renumberRepeaters.call($rows[0]);
updateRepeaterControls($repeater);
})
.on('click', '.jio-widget-repeater__remove', function (event) {
event.preventDefault();
event.stopPropagation();
const $repeater = $(this).closest('.jio-widget-repeater');
const $rows = $repeater.children('.jio-widget-repeater__rows');
if ($rows.children('.jio-widget-repeater__row').length <= Number($repeater.data('min-items') || 0)) return;
$(this).closest('.jio-widget-repeater__row').remove();
renumberRepeaters.call($rows[0]);
updateRepeaterControls($repeater);
})
.on('click', '.jio-widget-terms__remove', function () {
$(this).closest('.jio-widget-terms__chip').remove();
syncTerms($(this).closest('.jio-widget-terms'));
})
.on('change', '.jio-widget-terms__option input', function () {
const wrap = this.closest('.jio-widget-terms');
const option = this.closest('.jio-widget-terms__option');
const id = String(this.value);
const name = (option.querySelector('[data-term-name]') || option).getAttribute('data-term-name');
if (this.checked) addTermChip(wrap, id, name || id);
else $(wrap).find('.jio-widget-terms__chip').filter((_index, chip) => String($(chip).data('term-id')) === id).remove();
syncTerms(wrap);
})
.on('input', '.jio-widget-terms__search', function () {
const needle = this.value.trim().toLowerCase();
$(this).closest('.jio-widget-terms').find('.jio-widget-terms__option').each(function () {
const name = String(this.getAttribute('data-term-name') || '').toLowerCase();
this.hidden = needle !== '' && name.indexOf(needle) === -1;
});
})
.on('click', '.jio-widget-upload__choose', function () {
const $wrap = $(this).closest('.jio-widget-upload');
const frame = wp.media({ title: $wrap.data('media-library') === 'video' ? '选择视频' : '选择图片', library: $wrap.data('media-library') ? { type: $wrap.data('media-library') } : undefined, multiple: false });
frame.on('select', () => {
const attachment = frame.state().get('selection').first().toJSON();
$wrap.find('input[type="url"]').val(attachment.url).trigger('change');
if ($wrap.data('media-library') === 'video') return;
let $image = $wrap.find('img');
if (!$image.length) $image = $('<img alt="">').prependTo($wrap);
$image.attr('src', attachment.url);
});
frame.open();
})
.on('click', '.jio-widget-upload__remove', function () {
const $wrap = $(this).closest('.jio-widget-upload');
$wrap.find('input[type="url"]').val('').trigger('change');
$wrap.find('img').remove();
});
$(document).on('widget-added widget-updated', function (_event, widget) {
$(widget).find('.jio-widget-form-lazy').each(function () { loadForm(this); });
});
if (window.wp?.customize?.bind) {
window.wp.customize.bind('ready', function () {
$('#customize-theme-controls').on('expanded', function (_event, section) {
if (!section || !String(section.id || section).includes('sidebar-widgets')) return;
window.setTimeout(function () {
$('.customize-control-widget_form .jio-widget-form-lazy').each(function () { loadForm(this); });
}, 100);
});
});
}
$(function () {
$('.jio-widget-form').each(function () { initForm(this); });
$('.widget.open .jio-widget-form-lazy').each(function () { loadForm(this); });
});
})(jQuery);