/* Sidebar toolbar: per-area export / import / template import. */ (function ($) { 'use strict'; const config = window.jioWidgetAdmin || {}; const t = (key) => (config.i18n && config.i18n[key]) || key; function post(action, data) { return $.ajax({ url: config.ajaxUrl, type: 'POST', dataType: 'json', data: $.extend({ action, nonce: config.transferNonce }, data || {}), }); } function failMessage(res, xhr, fallbackKey) { return res?.data?.message || xhr?.responseJSON?.data?.message || t(fallbackKey); } function clearResult($result) { return $result.removeClass('is-ok is-warn is-err').empty(); } function showError($result, message) { clearResult($result).addClass('is-err').text(message); } function reloadButton() { return $('

').append( $('').text(t('reloadPage')) ); } function renderImportResult($result, res, autoReload) { clearResult($result); if (!res?.success || !res.data) { showError($result, failMessage(res, null, 'importFailed')); return; } const warnings = Array.isArray(res.data.warnings) ? res.data.warnings : []; $result.addClass(warnings.length ? 'is-warn' : 'is-ok'); [res.data.message || t('importSuccess')].concat(warnings).forEach((line, index) => { if (index) $result.append('
'); $result.append(document.createTextNode(String(line))); }); $result.append(reloadButton()); if (autoReload) window.setTimeout(() => window.location.reload(), 200); } function withButtonLoading($button, loadingText, idleText, request) { $button.prop('disabled', true).text(loadingText); return request().always(() => $button.prop('disabled', false).text(idleText)); } function importModeHtml(name) { return `
`; } function createModal(opts) { let $modal = null; function ensure() { if ($modal) return $modal; $modal = $(``).appendTo('body'); $modal.find('.jio-wie-modal__import-mode-title').text(t('importModeLabel')); $modal.find('[data-mode-label="replace"]').text(t('importModeReplace')); $modal.find('[data-mode-label="append"]').text(t('importModeAppend')); $modal.find('.jio-wie-modal__cancel').text(t('close')); $modal.on('click', '[data-jio-wie-close], .jio-wie-modal__cancel', close); if (opts.onInit) opts.onInit($modal); return $modal; } function open() { ensure().find('input[name$="-import-mode"][value="append"]').prop('checked', true); clearResult($modal.find('.jio-wie-modal__result')); $modal.addClass('is-open').attr('aria-hidden', 'false'); } function close() { if ($modal) $modal.removeClass('is-open').attr('aria-hidden', 'true'); } return { ensure, open, close, $result: () => ensure().find('.jio-wie-modal__result') }; } const state = { mode: 'export', sidebarId: '', templateSidebarId: '' }; const ioModal = createModal({ id: 'jio-wie-modal', bodyHtml: `

${importModeHtml('jio-wie-import-mode')}`, actionsHtml: `

`, onInit($modal) { $modal.find('.jio-wie-modal__copy').on('click', function () { const textarea = $modal.find('.jio-wie-modal__textarea')[0]; textarea.select(); textarea.setSelectionRange(0, textarea.value.length); try { document.execCommand('copy'); $(this).text(t('copyDone')); } catch (_error) { window.alert(t('copyFail')); } }); $modal.find('.jio-wie-modal__submit').on('click', submitImport); }, }); const templateModal = createModal({ id: 'jio-wie-template-modal', extraClass: 'jio-wie-template-layer', bodyHtml: `

${importModeHtml('jio-wie-template-import-mode')}`, actionsHtml: `

`, onInit($modal) { $modal.find('.jio-wie-modal__title').text(t('templateModalTitle')); // templateHint is server-built, escaped translation markup. $modal.find('.jio-wie-modal__hint').html(t('templateHint')); $modal.find('.jio-wie-template-submit').text(t('templateSubmit')).on('click', submitTemplate); }, }); function openIoModal(mode, sidebarId) { state.mode = mode; state.sidebarId = sidebarId; const $modal = ioModal.ensure(); const isExport = mode === 'export'; $modal.find('.jio-wie-modal__title').text(t(isExport ? 'exportTitle' : 'importTitle')); $modal.find('.jio-wie-modal__hint').text(t(isExport ? 'exportHint' : 'importHint')); $modal.find('.jio-wie-modal__textarea').prop('readonly', isExport).val(''); $modal.find('.jio-wie-modal__copy').toggle(isExport).text(t('copy')); $modal.find('.jio-wie-modal__submit').toggle(!isExport).text(t('submitImport')).prop('disabled', false); $modal.find('.jio-wie-modal__import-mode').toggle(!isExport); ioModal.open(); if (isExport) fetchExport(); } function fetchExport() { const $textarea = ioModal.ensure().find('.jio-wie-modal__textarea').val(t('loadingExport')); post('jio_widgets_export_sidebar', { sidebar_id: state.sidebarId }) .done((res) => { if (res?.success && res.data?.json_text) { $textarea.val(res.data.json_text); return; } $textarea.val(''); showError(ioModal.$result(), failMessage(res, null, 'exportFailed')); }) .fail((xhr) => { $textarea.val(''); showError(ioModal.$result(), failMessage(null, xhr, 'networkError')); }); } function submitImport() { const $modal = ioModal.ensure(); const mode = $modal.find('input[name="jio-wie-import-mode"]:checked').val() || 'append'; if (!window.confirm(t(mode === 'append' ? 'confirmImportAppend' : 'confirmImportReplace'))) return; const raw = String($modal.find('.jio-wie-modal__textarea').val() || '').trim(); if (!raw) { showError(ioModal.$result(), t('pasteJsonFirst')); return; } withButtonLoading($modal.find('.jio-wie-modal__submit'), t('loadingImport'), t('submitImport'), () => post('jio_widgets_import_sidebar', { sidebar_id: state.sidebarId, json: raw, import_mode: mode }) .done((res) => { if (res?.success) $modal.find('.jio-wie-modal__textarea').val(''); renderImportResult(ioModal.$result(), res, false); }) .fail((xhr) => showError(ioModal.$result(), failMessage(null, xhr, 'networkError'))) ); } function templateItem(template) { const $meta = $('') .append($('').text(template.title || template.id)); if (template.desc) $meta.append($('').text(template.desc)); if (template.remind) { $meta.append($('') .append('') .append(document.createTextNode(template.remind))); } if (Array.isArray(template.modules) && template.modules.length) { $meta.append($('').text(template.modules.map((module) => module.title).join(' / '))); } const $label = $('') .append($('').val(template.id)) .append($meta); return $('
').append($('
').append($label)); } function openTemplateModal(sidebarId) { state.templateSidebarId = sidebarId; const $modal = templateModal.ensure(); const $list = $modal.find('.jio-wie-template-list').empty(); const $status = $modal.find('.jio-wie-template-list-status').text(t('templateLoadingList')); templateModal.open(); post('jio_widgets_list_templates') .done((res) => { const templates = res?.success ? res.data?.templates : null; $status.text(Array.isArray(templates) && templates.length ? '' : t('templateEmpty')); (templates || []).forEach((template) => $list.append(templateItem(template))); }) .fail((xhr) => $status.text(failMessage(null, xhr, 'networkError'))); } function submitTemplate() { const $modal = templateModal.ensure(); const $picked = $modal.find('input[name="jio-wie-template-id"]:checked'); if (!$picked.length) { window.alert(t('templatePick')); return; } const templateId = String($picked.val()); const mode = $modal.find('input[name="jio-wie-template-import-mode"]:checked').val() || 'append'; const title = $picked.closest('.jio-wie-template-item').find('.jio-wie-template-item-title').text().trim() || templateId; const message = t('confirmTemplate').replace('{title}', title).replace('{mode}', t(mode === 'append' ? 'importModeAppend' : 'importModeReplace')); if (!window.confirm(message)) return; withButtonLoading($modal.find('.jio-wie-template-submit'), t('loadingImport'), t('templateSubmit'), () => post('jio_widgets_import_template', { sidebar_id: state.templateSidebarId, template_id: templateId, import_mode: mode }) .done((res) => renderImportResult(templateModal.$result(), res, true)) .fail((xhr) => showError(templateModal.$result(), failMessage(null, xhr, 'networkError'))) ); } function injectToolbar($anchor, sidebarId) { if (!$anchor?.length || !sidebarId || $anchor.next('.jio-wie-toolbar').length) return; const $toolbar = $('
'); [['export', 'exportModules'], ['import', 'importModules'], ['template', 'importTemplate']].forEach(([action, label]) => { $('') .text(t(label)) .attr('data-jio-wie-action', action) .attr('data-sidebar-id', sidebarId) .appendTo($toolbar); }); $anchor.after($toolbar); } function scanWidgetsScreen() { $('.widgets-holder-wrap:not(#available-widgets):not(.inactive-sidebar):not(.is-jio-wie)').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(); $wrap.addClass('is-jio-wie'); injectToolbar($description.length ? $description : $sortables.find('.description').first(), sidebarId); }); } function scanCustomizer() { const prefix = 'sub-accordion-section-sidebar-widgets-'; $('.control-section-sidebar:not(.is-jio-wie)').each(function () { const $section = $(this); const sectionId = String($section.attr('id') || ''); if (!sectionId.startsWith(prefix) || sectionId.length === prefix.length) return; $section.addClass('is-jio-wie'); const $description = $section.find('.section-meta .description').first(); injectToolbar($description.length ? $description : $section.find('.accordion-section-title, .customize-section-title').first(), sectionId.slice(prefix.length)); }); $('.customize-control-widget_form:not(.is-jio-wie)').each(function () { const $nav = $(this).find('.widget-reorder-nav').first(); if (!$nav.length) return; $('').text(t('removeModule')).appendTo($nav); $(this).addClass('is-jio-wie'); }); } $(document) .on('click', '[data-jio-wie-action]', function () { const action = String($(this).data('jio-wie-action')); const sidebarId = String($(this).data('sidebar-id') || ''); if (!sidebarId) return; if (action === 'template') openTemplateModal(sidebarId); else openIoModal(action, sidebarId); }) .on('click keydown', '.jio-wie-btn-delete', function (event) { if (event.type === 'keydown' && event.key !== 'Enter' && event.key !== ' ') return; event.preventDefault(); $(this).closest('.customize-control-widget_form').find('.widget-control-remove').first().trigger('click'); }) .on('click', '.jio-wie-modal__reload', () => window.location.reload()) .on('keydown', (event) => { if (event.key !== 'Escape') return; ioModal.close(); templateModal.close(); }) .on('widget-added', () => { if (document.body.classList.contains('wp-customizer')) scanCustomizer(); }); $(function () { if (!config.ajaxUrl) return; if (document.body.classList.contains('widgets-php')) scanWidgetsScreen(); if (document.body.classList.contains('wp-customizer')) { window.wp?.customize?.bind?.('ready', () => window.setTimeout(scanCustomizer, 300)); $(document).on('click', '.control-panel-widgets .control-section-sidebar', () => window.setTimeout(scanCustomizer, 100)); } }); })(jQuery);