(function ($) { 'use strict'; const config = window.aksrtWidgetAdmin || {}; const core = window.AKSRTWidgetAdminCore; function initForm(root) { const $root = $(root); $root.find('.aksrt-widget-color').wpColorPicker(); $root.find('.aksrt-widget-repeater__rows').sortable({ handle: '.dashicons-move', axis: 'y', update: renumberRepeaters, }); $root.find('.aksrt-widget-terms__selected').sortable({ items: '.aksrt-widget-terms__chip', update: () => $root.find('.aksrt-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); updatePlacementWarning($root); updateRepeaterControls($root); } /* terms 字段:以“已选标签”为唯一真源,同步隐藏输入(选择顺序)与复选框。 */ function syncTerms(wrap) { const $wrap = $(wrap); const ids = $wrap.find('.aksrt-widget-terms__chip').map((_i, el) => String($(el).data('term-id'))).get(); $wrap.find('.aksrt-widget-terms__value').val(ids.join(',')).trigger('change'); $wrap.find('.aksrt-widget-terms__option input').each(function () { this.checked = ids.indexOf(String(this.value)) !== -1; }); } function addTermChip(wrap, id, name) { const $selected = $(wrap).find('.aksrt-widget-terms__selected'); if ($selected.find(`.aksrt-widget-terms__chip[data-term-id="${id}"]`).length) return; const chip = $(``); chip.append(document.createTextNode(name)); chip.append(''); $selected.append(chip); } function updateWidgetTitle(root) { const $root = $(root); const title = String($root.find('.aksrt-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 updatePlacementWarning(root) { const $widget = $(root).closest('.widget'); const $hint = $widget.find('.aksrt-widget-placement-hint').first(); if (!$hint.length) return; const size = String($hint.data('widget-size') || 'any'); const area = String($widget.closest('.widgets-sortables').attr('id') || ''); const isSidebar = /sidebar/.test(area); $hint.toggleClass('is-warning', (size === 'wide' && isSidebar) || (size === 'sidebar' && !isSidebar && area !== '')); } function injectTransferToolbar($anchor, sidebarId) { if (!$anchor?.length || !sidebarId || $anchor.next('.aksrt-widget-transfer-toolbar').length) return; const $toolbar = $('
'); [ ['export', config.i18n?.export || '导出'], ['import', config.i18n?.import || '导入'], ['template', config.i18n?.template || '应用模板'], ].forEach(([action, label]) => { $('') .text(label) .attr('data-aksrt-transfer-action', action) .attr('data-sidebar-id', sidebarId) .appendTo($toolbar); }); $anchor.after($toolbar); } function scanWidgetAreas() { $('.widgets-holder-wrap:not(#available-widgets):not(.inactive-sidebar)').each(function () { const $wrap = $(this); const $sortables = $wrap.find('.widgets-sortables').first(); const sidebarId = String($sortables.attr('id') || ''); if (!sidebarId) return; const $description = $sortables.find('.sidebar-description .description').first(); const $anchor = $description.length ? $description : $sortables.find('.description').first(); if ($anchor.length) injectTransferToolbar($anchor, sidebarId); }); $('.control-section-sidebar').each(function () { const $section = $(this); const sectionId = String($section.attr('id') || ''); const prefix = 'sub-accordion-section-sidebar-widgets-'; if (!sectionId.startsWith(prefix)) return; const sidebarId = sectionId.slice(prefix.length); const $description = $section.find('.section-meta .description').first(); const $anchor = $description.length ? $description : $section.find('.accordion-section-title, .customize-section-title').first(); if ($anchor.length) injectTransferToolbar($anchor, sidebarId); }); $('.customize-control-widget_form').each(function () { const $control = $(this); const $nav = $control.find('.widget-reorder-nav').first(); if (!$nav.length || $nav.find('.aksrt-widget-customizer-remove').length) return; $('').appendTo($nav); }); } function openTransferModal(action, sidebarId) { const $modal = $('#aksrt-widget-transfer-modal'); if (!$modal.length) return; const sidebars = config.sidebars || {}; const areaName = sidebars[sidebarId] || sidebarId; $modal.find('.aksrt-widget-transfer-modal__area').text(areaName); $modal.find('input[name="sidebar"], input[name="target_sidebar"]').val(sidebarId); $modal.find('[data-transfer-tab]').removeClass('is-active'); $modal.find(`[data-transfer-tab="${action}"]`).addClass('is-active'); $modal.find('[data-transfer-panel]').prop('hidden', true); $modal.find(`[data-transfer-panel="${action}"]`).prop('hidden', false); $modal.prop('hidden', false).addClass('is-open').attr('aria-hidden', 'false'); $modal.find('[data-transfer-panel="' + action + '"] button, [data-transfer-panel="' + action + '"] input, [data-transfer-panel="' + action + '"] select').filter(':visible').first().trigger('focus'); } function closeTransferModal() { $('#aksrt-widget-transfer-modal').removeClass('is-open').attr('aria-hidden', 'true').prop('hidden', true); } 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).find('.aksrt-widget-form-lazy__status').text(config.i18n?.loading || '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).find('.aksrt-widget-form-lazy__status').text(response?.data?.message || config.i18n?.error || 'Failed to load.'); return; } const $form = $(response.data.html); $container.replaceWith($form); initForm($form); }).fail(() => { $container.data('loading', false).find('.aksrt-widget-form-lazy__status').text(config.i18n?.error || 'Failed to load.'); }); } function renumberRepeaters(_event, ui) { const $form = $(ui?.item || this).closest('.aksrt-widget-form'); $form.find('.aksrt-widget-repeater__rows').each(function () { $(this).children('.aksrt-widget-repeater__row').each(function (index) { this.dataset.rowIndex = String(index); }); }); $form.find('[name]').each(function () { const rowIndexes = $(this).parents('.aksrt-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('.aksrt-widget-repeater__rows').each(function () { $(this).children('.aksrt-widget-repeater__row').each(function (index) { const $row = $(this); const $title = $row.find('.aksrt-widget-repeater__title').first(); const prefix = String($title.data('title-prefix') || '项目'); const $firstControl = $row.children('.aksrt-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('.aksrt-widget-repeater').add($root.find('.aksrt-widget-repeater')).each(function () { const $repeater = $(this); const count = $repeater.children('.aksrt-widget-repeater__rows').children('.aksrt-widget-repeater__row').length; const min = Number($repeater.data('min-items') || 0); const max = Number($repeater.data('max-items') || 50); $repeater.children('.aksrt-widget-repeater__rows').children('.aksrt-widget-repeater__row').children('.aksrt-widget-repeater__bar').children('.aksrt-widget-repeater__remove').prop('disabled', count <= min); $repeater.children('.aksrt-widget-repeater__add').prop('disabled', count >= max); }); } function fieldValue($form, id) { const $field = $form.find(`.aksrt-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('.aksrt-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', '[data-aksrt-transfer-action]', function () { openTransferModal(String($(this).data('aksrt-transfer-action')), String($(this).data('sidebar-id'))); }) .on('click', '[data-aksrt-transfer-close]', closeTransferModal) .on('click', '[data-transfer-tab]', function () { const $modal = $(this).closest('.aksrt-widget-transfer-modal'); const panel = String($(this).data('transfer-tab')); $modal.find('[data-transfer-tab]').removeClass('is-active'); $(this).addClass('is-active'); $modal.find('[data-transfer-panel]').prop('hidden', true); $modal.find(`[data-transfer-panel="${panel}"]`).prop('hidden', false); }) .on('click', '.aksrt-widget-customizer-remove', function (event) { event.preventDefault(); $(this).closest('.customize-control-widget_form').find('.widget-control-remove').first().trigger('click'); }) .on('click', '.aksrt-widget-form-lazy__load', function () { loadForm($(this).closest('.aksrt-widget-form-lazy')); }) .on('click', '.widget.open .aksrt-widget-form-lazy, .customize-control-widget_form .aksrt-widget-form-lazy', function () { loadForm(this); }) .on('change input', '.aksrt-widget-form input, .aksrt-widget-form select, .aksrt-widget-form textarea', function () { const $form = $(this).closest('.aksrt-widget-form'); evaluateDependencies($form); updateWidgetTitle($form); updateRepeaterTitles($form); }) .on('click', '.aksrt-widget-repeater__add', function () { const $repeater = $(this).closest('.aksrt-widget-repeater'); const max = Number($repeater.data('max-items') || 50); const $rows = $repeater.children('.aksrt-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', '.aksrt-widget-repeater__remove', function (event) { event.preventDefault(); event.stopPropagation(); const $repeater = $(this).closest('.aksrt-widget-repeater'); const $rows = $repeater.children('.aksrt-widget-repeater__rows'); if ($rows.children('.aksrt-widget-repeater__row').length <= Number($repeater.data('min-items') || 0)) return; $(this).closest('.aksrt-widget-repeater__row').remove(); renumberRepeaters.call($rows[0]); updateRepeaterControls($repeater); }) .on('click', '.aksrt-widget-terms__remove', function () { $(this).closest('.aksrt-widget-terms__chip').remove(); syncTerms($(this).closest('.aksrt-widget-terms')); }) .on('change', '.aksrt-widget-terms__option input', function () { const wrap = this.closest('.aksrt-widget-terms'); const option = this.closest('.aksrt-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('.aksrt-widget-terms__chip').filter((_index, chip) => String($(chip).data('term-id')) === id).remove(); syncTerms(wrap); }) .on('input', '.aksrt-widget-terms__search', function () { const needle = this.value.trim().toLowerCase(); $(this).closest('.aksrt-widget-terms').find('.aksrt-widget-terms__option').each(function () { const name = String(this.getAttribute('data-term-name') || '').toLowerCase(); this.hidden = needle !== '' && name.indexOf(needle) === -1; }); }) .on('click', '.aksrt-widget-upload__choose', function () { const $wrap = $(this).closest('.aksrt-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 = $('正在生成预览…
'); $.post(config.ajaxUrl, { action: 'aksrt_widgets_template_preview', nonce: config.transferNonce, template: $form.find('[name="template"]').val(), }).done((response) => { if (!response?.success || !response.data) { $output.empty().append($('').text(response?.data?.message || config.i18n?.error || '预览加载失败,请重试。')); return; } $output.html(response.data.html || '模板为空。
'); }).fail((xhr) => { const message = xhr?.responseJSON?.data?.message || config.i18n?.error || '预览加载失败,请重试。'; $output.empty().append($('').text(message)); }); }); $(document).on('widget-added widget-updated', function (_event, widget) { $(widget).find('.aksrt-widget-form-lazy').each(function () { loadForm(this); }); updatePlacementWarning(widget); scanWidgetAreas(); }); 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 () { scanWidgetAreas(); $('.customize-control-widget_form .aksrt-widget-form-lazy').each(function () { loadForm(this); }); }, 100); }); }); } $(function () { scanWidgetAreas(); $(document).on('keydown', function (event) { if (event.key === 'Escape') closeTransferModal(); }); $('.aksrt-widget-form').each(function () { initForm(this); }); $('.widget.open .aksrt-widget-form-lazy').each(function () { loadForm(this); }); }); })(jQuery);