/** * Reference-style paid download resource editor for the front submit page. * * @package AKSRT */ (function () { 'use strict'; var fields = ['url', 'extract_code', 'copy_key', 'copy_val', 'label', 'class']; var buttonClasses = [ '', 'c-red', 'c-yellow', 'c-cyan', 'c-blue', 'c-green', 'c-purple', 'b-red', 'b-yellow', 'b-cyan', 'b-blue', 'b-green', 'b-purple', 'jb-red', 'jb-pink', 'jb-yellow', 'jb-cyan', 'jb-blue', 'jb-green', 'jb-purple', 'jb-vip1', 'jb-vip2', ]; function escapeHtml(value) { return String(value || '') .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } function validHttpUrl(value) { try { var url = new URL(String(value || '').trim(), window.location.href); return /^(https?:)$/i.test(url.protocol) ? url.href : ''; } catch (error) { return ''; } } function createItem() { var item = document.createElement('div'); item.className = 'flex ac jsb lists-item'; item.setAttribute('data-pay-download-item', ''); var edit = document.createElement('button'); edit.type = 'button'; edit.className = 'flex1 name-link pay-dawnload-add-edit'; edit.setAttribute('data-pay-download-edit', ''); item.appendChild(edit); var remove = document.createElement('button'); remove.type = 'button'; remove.className = 'pay-dawnload-add-delete em12 ml10 hollow but cir c-red'; remove.setAttribute('data-pay-download-remove', ''); remove.setAttribute('aria-label', '删除资源'); remove.innerHTML = ''; item.appendChild(remove); var hidden = document.createElement('div'); hidden.className = 'hidden-input'; fields.forEach(function (field) { var input = document.createElement('input'); input.type = 'hidden'; input.setAttribute('data-pay-download-field', field); hidden.appendChild(input); }); item.appendChild(hidden); return item; } function init(options) { var root = options && options.root; if (!root || root.getAttribute('data-pay-download-ready') === '1') { return; } var list = root.querySelector('[data-pay-download-list]'); var addButton = root.querySelector('[data-pay-download-add]'); if (!list || !addButton) { return; } root.setAttribute('data-pay-download-ready', '1'); var cfg = window.aksrtSubmitData || {}; var i18n = cfg.i18n || {}; var activeItem = null; var previousFocus = null; var modal = document.createElement('div'); modal.className = 'aksrt-editor-media pay-dawnload-edit-modal'; modal.hidden = true; modal.innerHTML = '' + ''; document.body.appendChild(modal); var dialog = modal.querySelector('.aksrt-editor-media__dialog'); var title = modal.querySelector('[data-pay-download-title]'); var actions = modal.querySelector('[data-pay-download-actions]'); var uploadButton = modal.querySelector('[data-pay-resource-upload]'); var inputMap = {}; fields.forEach(function (field) { inputMap[field] = modal.querySelector('[data-pay-resource-field="' + field + '"]'); }); var classBox = modal.querySelector('[data-pay-resource-classes]'); buttonClasses.forEach(function (buttonClass) { var button = document.createElement('button'); button.type = 'button'; button.className = 'class-choice badg ' + (buttonClass || 'b-theme'); button.setAttribute('data-pay-resource-class', buttonClass); button.setAttribute('aria-label', i18n.selectButtonStyle || '选择按钮样式'); classBox.appendChild(button); }); function markDirty() { if (typeof options.markDirty === 'function') { options.markDirty(); } } function notify(message, type, time, id) { if (typeof options.notify === 'function') { options.notify(message, type, time, id); } } function reindex() { list.querySelectorAll('[data-pay-download-item]').forEach(function (item, index) { item.querySelectorAll('[data-pay-download-field]').forEach(function (input) { var field = input.getAttribute('data-pay-download-field'); input.name = 'aksrt_pay[downloads][' + index + '][' + field + ']'; }); }); } function setButtonClass(value) { inputMap.class.value = buttonClasses.indexOf(value) === -1 ? '' : value; classBox.querySelectorAll('[data-pay-resource-class]').forEach(function (button) { button.classList.toggle('is-active', button.getAttribute('data-pay-resource-class') === inputMap.class.value); }); } function syncActions() { actions.hidden = inputMap.url.value.trim() === ''; } function closeModal() { modal.hidden = true; document.body.classList.remove('aksrt-editor-media-open'); if (previousFocus && typeof previousFocus.focus === 'function') { previousFocus.focus(); } } function openModal(item) { activeItem = item || null; previousFocus = document.activeElement; fields.forEach(function (field) { var stored = activeItem && activeItem.querySelector('[data-pay-download-field="' + field + '"]'); inputMap[field].value = stored ? stored.value : ''; }); title.textContent = activeItem ? (i18n.editResource || '编辑资源') : (i18n.addResource || '添加资源'); setButtonClass(inputMap.class.value); syncActions(); modal.hidden = false; document.body.classList.add('aksrt-editor-media-open'); dialog.focus(); } function saveResource() { var url = validHttpUrl(inputMap.url.value); if (!url) { notify(i18n.invalidMediaUrl || '请填写有效地址', 'warning'); return; } var item = activeItem || createItem(); fields.forEach(function (field) { var input = item.querySelector('[data-pay-download-field="' + field + '"]'); input.value = field === 'url' ? url : inputMap[field].value.trim(); }); item.querySelector('[data-pay-download-edit]').textContent = url; if (!activeItem) { list.appendChild(item); } reindex(); markDirty(); closeModal(); } addButton.addEventListener('click', function () { openModal(null); }); list.addEventListener('click', function (event) { var remove = event.target.closest('[data-pay-download-remove]'); if (remove) { var removeItem = remove.closest('[data-pay-download-item]'); if (removeItem) { removeItem.remove(); reindex(); markDirty(); } return; } var edit = event.target.closest('[data-pay-download-edit]'); if (edit) { openModal(edit.closest('[data-pay-download-item]')); } }); modal.addEventListener('click', function (event) { if (event.target.closest('[data-pay-download-close]')) { closeModal(); return; } var classButton = event.target.closest('[data-pay-resource-class]'); if (classButton) { setButtonClass(classButton.getAttribute('data-pay-resource-class')); } }); modal.querySelector('[data-pay-download-submit]').addEventListener('click', saveResource); inputMap.url.addEventListener('input', syncActions); inputMap.url.addEventListener('paste', function (event) { var text = event.clipboardData ? event.clipboardData.getData('text') : ''; if (!text) { return; } var urlMatch = text.match(/https?:\/\/.*?(?=[\r\n\s]|提取码|密码|$)/i); if (urlMatch && urlMatch[0]) { event.preventDefault(); inputMap.url.value = urlMatch[0]; } var codeMatch = text.match(/(?:提取码|密码)[::]\s*([a-zA-Z0-9]{4,6})/); if (codeMatch && codeMatch[1]) { inputMap.extract_code.value = (i18n.extractCodeColon || '提取码:') + codeMatch[1]; inputMap.copy_key.value = i18n.extractCode || '提取码'; inputMap.copy_val.value = codeMatch[1]; } syncActions(); }); var canUpload = !!((cfg.uploads || {}).resource && typeof options.pickUpload === 'function' && typeof options.uploadFile === 'function'); uploadButton.hidden = !canUpload; if (canUpload) { uploadButton.addEventListener('click', function () { var toastId = 'aksrt-front-submit-resource-upload-toast'; options.pickUpload('resource', '*/*').then(function (file) { if (!file) { return null; } uploadButton.disabled = true; notify(i18n.uploading || '正在上传附件…', 'load', '', toastId); return options.uploadFile('resource', file); }).then(function (file) { if (!file) { return; } inputMap.url.value = file.url || ''; syncActions(); notify(i18n.uploaded || '附件上传成功', 'success', 5, toastId); }).catch(function (error) { notify(error.message || i18n.error || '附件上传失败', 'danger', 5, toastId); }).finally(function () { uploadButton.disabled = false; }); }); } document.addEventListener('keydown', function (event) { if (!modal.hidden && event.key === 'Escape') { closeModal(); } }); reindex(); } window.aksrtSubmitPayDownloads = { init: init }; })();