/** 优惠码:新建/批量生成弹窗、类型与范围联动、防重复提交、点击复制。仅本页入队。 */ (function () { 'use strict'; var root = document.querySelector('.jio-coupons-page'); if (!root) return; var toast = root.querySelector('[data-jio-coupon-toast]'); var toastTimer; var forms = Array.from(root.querySelectorAll('[data-jio-coupon-form]')); function notify(key) { if (!toast) return; clearTimeout(toastTimer); toast.textContent = toast.getAttribute('data-' + key); toast.classList.add('is-visible'); toastTimer = setTimeout(function () { toast.classList.remove('is-visible'); }, 3000); } /** 类型切换面值的步长/上限与单位;「全部商品」时范围 ID 禁用,否则必填。 */ function syncForm(form) { var type = form.elements.type; var value = form.elements.value; var unit = form.querySelector('[data-jio-coupon-unit]'); if (type && value) { var percent = type.value === 'percent'; value.step = percent ? '1' : '0.01'; if (percent) value.max = '100'; else value.removeAttribute('max'); if (unit) unit.textContent = unit.getAttribute(percent ? 'data-percent' : 'data-fixed'); } var scope = form.elements.scope_type; var ids = form.elements.scope_ids; if (scope && ids) { var all = scope.value === ''; ids.disabled = all; ids.required = !all; } } function lockScroll() { document.documentElement.classList.toggle('jio-coupons-modal-open', !!root.querySelector('dialog[open]')); } root.querySelectorAll('.jio-coupon-dialog').forEach(function (dialog) { if (typeof dialog.showModal !== 'function') return; var opener = null; var startedOutside = false; var form = dialog.querySelector('form'); function outside(event) { var rect = dialog.getBoundingClientRect(); return event.clientX < rect.left || event.clientX > rect.right || event.clientY < rect.top || event.clientY > rect.bottom; } function requestClose() { if (!form.dataset.submitting) dialog.close(); } root.querySelectorAll('[data-jio-dialog-open="' + dialog.id + '"]').forEach(function (button) { button.addEventListener('click', function () { opener = button; syncForm(form); dialog.showModal(); lockScroll(); }); }); dialog.querySelectorAll('[data-jio-dialog-close]').forEach(function (button) { button.addEventListener('click', requestClose); }); dialog.addEventListener('pointerdown', function (event) { startedOutside = event.target === dialog && outside(event); }); dialog.addEventListener('click', function (event) { if (startedOutside && event.target === dialog && outside(event)) requestClose(); startedOutside = false; }); dialog.addEventListener('cancel', function (event) { if (form.dataset.submitting) event.preventDefault(); }); dialog.addEventListener('close', function () { lockScroll(); if (opener && opener.isConnected) opener.focus(); opener = null; }); }); forms.forEach(function (form) { var submit = form.querySelector('[data-jio-coupon-submit]'); if (submit) submit.setAttribute('data-idle-label', submit.textContent); form.addEventListener('change', function () { syncForm(form); }); form.addEventListener('submit', function (event) { if (form.dataset.submitting) { event.preventDefault(); return; } form.dataset.submitting = '1'; if (submit) { submit.textContent = form.getAttribute('data-busy-label'); // 延后禁用:同步禁用 submit 按钮会让部分浏览器丢掉这次提交。 setTimeout(function () { submit.disabled = true; }, 0); } }); syncForm(form); }); root.addEventListener('click', async function (event) { var button = event.target.closest('[data-clipboard-text]'); if (!button) return; var value = button.getAttribute('data-clipboard-text'); try { if (navigator.clipboard && window.isSecureContext) { await navigator.clipboard.writeText(value); } else { var input = document.createElement('textarea'); input.value = value; input.className = 'screen-reader-text'; root.appendChild(input); input.select(); var copied = false; try { copied = document.execCommand('copy'); } finally { input.remove(); button.focus(); } if (!copied) throw new Error('copy'); } notify('copied'); } catch (error) { notify('copy-failed'); } }); // bfcache 返回时恢复按钮,避免表单停在提交中状态。 window.addEventListener('pageshow', function () { forms.forEach(function (form) { var submit = form.querySelector('[data-jio-coupon-submit]'); delete form.dataset.submitting; if (submit) { submit.disabled = false; submit.textContent = submit.getAttribute('data-idle-label'); } syncForm(form); }); lockScroll(); }); })();