diff --git a/assets/css/frontend/pages/submit.css b/assets/css/frontend/pages/submit.css
index 50914a79..658fe34f 100644
--- a/assets/css/frontend/pages/submit.css
+++ b/assets/css/frontend/pages/submit.css
@@ -127,6 +127,10 @@
padding: 10px;
}
+.aksrt-editor-media[hidden] {
+ display: none !important;
+}
+
.aksrt-editor-media__backdrop {
position: absolute;
inset: 0;
@@ -500,7 +504,7 @@ body.aksrt-editor-media-open {
.pay-dawnload-edit .lists-item {
gap: 5px;
- padding: 6px 8px;
+ padding: 4px 12px;
word-break: break-all;
}
@@ -508,9 +512,62 @@ body.aksrt-editor-media-open {
border-top: 1px solid var(--main-border-color, rgba(50, 50, 50, 0.08));
}
-.pay-dawnload-edit .lists-item .form-control {
+.pay-dawnload-edit .name-link {
min-width: 0;
- padding: 5px 7px;
+ padding: 5px 0;
+ overflow: hidden;
+ border: 0;
+ background: transparent;
+ color: var(--focus-color, #f04494);
+ line-height: 1.5;
+ text-align: left;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ cursor: pointer;
+}
+
+.pay-dawnload-edit .name-link:focus,
+.pay-dawnload-edit .name-link:active {
+ outline: 0;
+ box-shadow: none;
+}
+
+.pay-dawnload-edit-modal .aksrt-editor-media__dialog {
+ width: min(600px, calc(100vw - 20px));
+}
+
+.pay-dawnload-edit-content {
+ padding: 20px;
+}
+
+.pay-dawnload-edit-content .pay-dawnload-edit-fields {
+ padding: 0 3px;
+}
+
+.pay-dawnload-edit-content .form-control {
+ width: 100%;
+ min-width: 0;
+}
+
+.pay-dawnload-edit-content .class-choice {
+ width: 29px;
+ height: 22px;
+ margin: 2px;
+ padding: 0;
+ border: 2px solid var(--main-bg-color, #fff);
+ cursor: pointer;
+}
+
+.pay-dawnload-edit-content .class-choice.is-active {
+ box-shadow: 0 0 0 2px var(--muted-2-color, #999);
+}
+
+.pay-dawnload-edit-content .modal-buts {
+ margin: 18px -20px -20px;
+}
+
+.pay-dawnload-edit-content .pay-upload-btn .fa {
+ margin-right: 4px;
}
.newposts-wrap [hidden] {
@@ -576,8 +633,13 @@ body.aksrt-editor-media-open {
min-height: 150px;
}
- .pay-dawnload-edit .lists-item {
- align-items: stretch;
- flex-direction: column;
+ .pay-dawnload-edit-content {
+ padding: 18px 15px;
+ }
+
+ .pay-dawnload-edit-content .modal-buts {
+ margin-right: -15px;
+ margin-bottom: -18px;
+ margin-left: -15px;
}
}
diff --git a/assets/js/front-submit-pay-download.js b/assets/js/front-submit-pay-download.js
new file mode 100644
index 00000000..e01793a8
--- /dev/null
+++ b/assets/js/front-submit-pay-download.js
@@ -0,0 +1,302 @@
+/**
+ * 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 };
+})();
diff --git a/assets/js/front-submit.js b/assets/js/front-submit.js
index ccee267c..c76e70c1 100644
--- a/assets/js/front-submit.js
+++ b/assets/js/front-submit.js
@@ -587,60 +587,16 @@
});
});
- var list = qs('[data-pay-download-list]', box);
- var tpl = qs('[data-pay-download-tpl]', box);
- var addBtn = qs('[data-pay-download-add]', box);
- if (addBtn && list && tpl) {
- addBtn.addEventListener('click', function () {
- var node = tpl.content.cloneNode(true);
- var idx = list.querySelectorAll('[data-pay-download-item]').length;
- qsa('[data-name]', node).forEach(function (input) {
- input.name = 'aksrt_pay[downloads][' + idx + '][' + input.getAttribute('data-name') + ']';
- });
- list.appendChild(node);
- });
- }
- var uploadBtn = qs('[data-pay-download-upload]', box);
- if (uploadBtn && list && tpl) {
- uploadBtn.addEventListener('click', function () {
- var toastId = 'aksrt-front-submit-resource-upload-toast';
- App.pickUpload('resource', '*/*').then(function (file) {
- if (!file) return null;
- uploadBtn.disabled = true;
- notyf(i18n.uploading || '正在上传附件…', 'load', '', toastId);
- return App.uploadFile('resource', file);
- }).then(function (file) {
- if (!file) return;
- var node = tpl.content.cloneNode(true);
- var idx = list.querySelectorAll('[data-pay-download-item]').length;
- qsa('[data-name]', node).forEach(function (input) {
- input.name = 'aksrt_pay[downloads][' + idx + '][' + input.getAttribute('data-name') + ']';
- });
- var url = qs('[data-pay-download-url]', node);
- var label = qs('[data-pay-download-label]', node);
- if (url) url.value = file.url || '';
- if (label) label.value = file.name || '';
- list.appendChild(node);
- notyf(i18n.uploaded || '附件上传成功', 'success', 5, toastId);
- }).catch(function (error) {
- notyf(error.message || i18n.error || '附件上传失败', 'danger', 5, toastId);
- }).finally(function () {
- uploadBtn.disabled = false;
- });
- });
- }
- if (list) {
- list.addEventListener('click', function (e) {
- var rm = e.target.closest('[data-pay-download-remove]');
- if (!rm) {
- return;
- }
- var item = rm.closest('[data-pay-download-item]');
- if (item) {
- item.remove();
- }
- });
- }
+ window.aksrtSubmitPayDownloads.init({
+ root: box,
+ pickUpload: this.pickUpload.bind(this),
+ uploadFile: this.uploadFile.bind(this),
+ notify: notyf,
+ markDirty: function () {
+ App.isDirty = true;
+ App.form.setAttribute('data-dirty', 'true');
+ },
+ });
},
bindAi: function () {
diff --git a/inc/helpers/aksrt-pay.php b/inc/helpers/aksrt-pay.php
index 234ece7d..8d38664a 100644
--- a/inc/helpers/aksrt-pay.php
+++ b/inc/helpers/aksrt-pay.php
@@ -1331,12 +1331,23 @@ if (!function_exists('aksrt_get_paid_download_actions_html')) {
$label = (string) ($service['name'] ?? __('本地下载', 'aksrt'));
}
$type = sanitize_key((string) ($download['type'] ?? 'direct'));
- $has_extract = trim((string) ($download['extract_code'] ?? '')) !== '';
+ $extract_code = trim((string) ($download['extract_code'] ?? ''));
+ $has_extract = $extract_code !== '';
$service_key = sanitize_html_class((string) ($service['key'] ?? 'other')) ?: 'other';
+ $button_class = trim((string) ($download['class'] ?? ''));
+ $button_class = $button_class !== '' ? $button_class : 'b-theme ' . $service_key;
+ $copy_value = trim((string) ($download['copy_val'] ?? ''));
+ $copy_key = trim((string) ($download['copy_key'] ?? ''));
+ $copy_label = $extract_code !== '' ? $extract_code : ($copy_key !== '' ? $copy_key : __('更多内容', 'aksrt'));
$buttons .= '';
- $buttons .= '
';
}
diff --git a/src/Core/DomainModel.php b/src/Core/DomainModel.php
index 7aed1f31..7c874097 100644
--- a/src/Core/DomainModel.php
+++ b/src/Core/DomainModel.php
@@ -181,6 +181,13 @@ class DomainModel {
}
$allowed_types = ['direct', 'net_disk', 'external'];
+ $allowed_classes = [
+ '',
+ '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',
+ ];
$downloads = [];
foreach ($value as $row) {
@@ -229,6 +236,11 @@ class DomainModel {
'url' => $url,
'type' => $type,
'extract_code' => $extract_code,
+ 'copy_key' => isset($row['copy_key']) ? sanitize_text_field((string) $row['copy_key']) : '',
+ 'copy_val' => isset($row['copy_val']) ? sanitize_text_field((string) $row['copy_val']) : '',
+ 'class' => isset($row['class']) && in_array($row['class'], $allowed_classes, true)
+ ? (string) $row['class']
+ : '',
];
}
diff --git a/src/Core/FrontSubmitPay.php b/src/Core/FrontSubmitPay.php
index 61091d5f..d930d392 100644
--- a/src/Core/FrontSubmitPay.php
+++ b/src/Core/FrontSubmitPay.php
@@ -229,6 +229,9 @@ trait FrontSubmitPay {
'url' => $url,
'type' => $attachment_id > 0 ? 'direct' : 'external',
'extract_code' => sanitize_text_field((string) ($row['extract_code'] ?? '')),
+ 'copy_key' => sanitize_text_field((string) ($row['copy_key'] ?? '')),
+ 'copy_val' => sanitize_text_field((string) ($row['copy_val'] ?? '')),
+ 'class' => sanitize_key((string) ($row['class'] ?? '')),
];
}
return DomainModel::sanitize_downloads($out);
diff --git a/src/Core/ResourceMetaBox.php b/src/Core/ResourceMetaBox.php
index 308fa53c..57d49d93 100644
--- a/src/Core/ResourceMetaBox.php
+++ b/src/Core/ResourceMetaBox.php
@@ -200,7 +200,7 @@ class ResourceMetaBox {
/** @param int|string $index */
private function download_row($index, array $row): void {
?>
-
+
['type' => 'string', 'format' => 'uri'],
'type' => ['type' => 'string'],
'extract_code' => ['type' => 'string'],
+ 'copy_key' => ['type' => 'string'],
+ 'copy_val' => ['type' => 'string'],
+ 'class' => ['type' => 'string'],
],
],
],
diff --git a/templates/pages/page-submit.php b/templates/pages/page-submit.php
index dccceef6..0ba6353a 100644
--- a/templates/pages/page-submit.php
+++ b/templates/pages/page-submit.php
@@ -54,10 +54,18 @@ if (file_exists($css)) {
}
$js = get_template_directory() . '/assets/js/front-submit.js';
if (file_exists($js)) {
+ $pay_download_js = get_template_directory() . '/assets/js/front-submit-pay-download.js';
+ wp_enqueue_script(
+ 'aksrt-front-submit-pay-download',
+ get_template_directory_uri() . '/assets/js/front-submit-pay-download.js',
+ [],
+ (string) filemtime($pay_download_js),
+ true
+ );
wp_enqueue_script(
'aksrt-front-submit',
get_template_directory_uri() . '/assets/js/front-submit.js',
- ['aksrt-runtime'],
+ ['aksrt-runtime', 'aksrt-front-submit-pay-download'],
(string) filemtime($js),
true
);
@@ -180,6 +188,24 @@ if (file_exists($js)) {
'loginVisible' => __('登录可见', 'aksrt'),
'vipVisible' => __('VIP 可见', 'aksrt'),
'payVisible' => __('付费可见', 'aksrt'),
+ 'addResource' => __('添加资源', 'aksrt'),
+ 'editResource' => __('编辑资源', 'aksrt'),
+ 'downloadUrl' => __('下载地址', 'aksrt'),
+ 'enterDownloadUrl' => __('请输入资源下载地址', 'aksrt'),
+ 'pasteLinkHint' => __('支持直接粘贴网盘分享链接,并自动识别提取码', 'aksrt'),
+ 'resourceNote' => __('资源备注', 'aksrt'),
+ 'enterResourceNote' => __('请输入资源备注', 'aksrt'),
+ 'resourceNoteHint' => __('例如提取码、解压密码等', 'aksrt'),
+ 'clickCopy' => __('点击复制', 'aksrt'),
+ 'copyName' => __('复制名称', 'aksrt'),
+ 'copyContent' => __('复制内容', 'aksrt'),
+ 'copyHint' => __('填写后,用户可点击资源备注复制内容', 'aksrt'),
+ 'customButton' => __('自定义按钮', 'aksrt'),
+ 'customButtonPlaceholder' => __('自定义下载按钮名称', 'aksrt'),
+ 'selectButtonStyle' => __('选择按钮样式', 'aksrt'),
+ 'extractCode' => __('提取码', 'aksrt'),
+ 'extractCodeColon' => __('提取码:', 'aksrt'),
+ 'confirm' => __('确认', 'aksrt'),
],
]);
}
diff --git a/templates/parts/submit/sidebar-pay.php b/templates/parts/submit/sidebar-pay.php
index 3df993be..7e7b3121 100644
--- a/templates/parts/submit/sidebar-pay.php
+++ b/templates/parts/submit/sidebar-pay.php
@@ -62,22 +62,21 @@ if (!function_exists('aksrt_submit_pay_line')) {
diff --git a/tests/asset-ledger/FrontSubmitPayTest.php b/tests/asset-ledger/FrontSubmitPayTest.php
index ea8cc94b..89489b2e 100644
--- a/tests/asset-ledger/FrontSubmitPayTest.php
+++ b/tests/asset-ledger/FrontSubmitPayTest.php
@@ -86,6 +86,26 @@ final class FrontSubmitPayTest extends TestCase {
self::assertSame('0.00', $meta['vip2_price']);
}
+ public function test_download_resource_modal_fields_are_sanitized_as_one_payload(): void {
+ $downloads = DomainModel::sanitize_downloads([
+ [
+ 'url' => 'https://example.com/file.zip',
+ 'label' => '镜像下载',
+ 'extract_code' => ' 提取码:1234 ',
+ 'copy_key' => '提取码',
+ 'copy_val' => ' 1234 ',
+ 'class' => 'jb-blue',
+ ],
+ ]);
+
+ self::assertCount(1, $downloads);
+ self::assertSame('镜像下载', $downloads[0]['label']);
+ self::assertSame('提取码:1234', $downloads[0]['extract_code']);
+ self::assertSame('提取码', $downloads[0]['copy_key']);
+ self::assertSame('1234', $downloads[0]['copy_val']);
+ self::assertSame('jb-blue', $downloads[0]['class']);
+ }
+
private function settings(bool $vip1_enabled, bool $vip2_enabled): array {
return [
'pay_free_s' => true,
diff --git a/tests/widget-system/post-editor-reference-contract.test.cjs b/tests/widget-system/post-editor-reference-contract.test.cjs
index bfcbf74f..42403e62 100644
--- a/tests/widget-system/post-editor-reference-contract.test.cjs
+++ b/tests/widget-system/post-editor-reference-contract.test.cjs
@@ -49,6 +49,32 @@ test('front submit follows the reference newposts shell and cards', () => {
assert.match(submit, /new-posts-submit/);
});
+test('front submit paid resources use the reference modal editor and compact list', () => {
+ const page = read('templates/pages/page-submit.php');
+ const pay = read('templates/parts/submit/sidebar-pay.php');
+ const submit = read('assets/js/front-submit.js');
+ const downloads = read('assets/js/front-submit-pay-download.js');
+ const model = read('src/Core/DomainModel.php');
+
+ assert.match(page, /aksrt-front-submit-pay-download/);
+ assert.match(submit, /aksrtSubmitPayDownloads\.init/);
+ assert.match(pay, /data-pay-download-add/);
+ assert.match(pay, /data-pay-download-edit/);
+ assert.match(pay, /data-pay-download-remove/);
+ assert.match(pay, /class="hidden-input"/);
+ assert.doesNotMatch(pay, /data-pay-download-upload|data-pay-download-tpl/);
+
+ ['url', 'extract_code', 'copy_key', 'copy_val', 'label', 'class'].forEach((field) => {
+ assert.match(downloads, new RegExp(`['"]${field}['"]`));
+ assert.match(model, new RegExp(`['"]${field}['"]`));
+ });
+ assert.match(downloads, /pay-dawnload-edit-modal/);
+ assert.match(downloads, /data-pay-resource-upload/);
+ assert.match(downloads, /data-pay-resource-classes/);
+ assert.match(downloads, /提取码\|密码/);
+ assert.doesNotMatch(downloads, /shop|forum|bbs_/i);
+});
+
test('front submit image and visibility actions live in the TinyMCE toolbar', () => {
const main = read('templates/parts/submit/editor-main.php');
const page = read('templates/pages/page-submit.php');
diff --git a/tests/widget-system/toast-contract.test.cjs b/tests/widget-system/toast-contract.test.cjs
index 85e4be79..7a42c6df 100644
--- a/tests/widget-system/toast-contract.test.cjs
+++ b/tests/widget-system/toast-contract.test.cjs
@@ -370,7 +370,8 @@ test('settings actions use rehydrated fixed-id notyf flows', () => {
test('front submit actions use direct fixed-id notyf flows', () => {
const submit = read('assets/js/front-submit.js');
const editor = read('assets/js/front-submit-editor.js');
- const source = submit + '\n' + editor;
+ const downloads = read('assets/js/front-submit-pay-download.js');
+ const source = submit + '\n' + editor + '\n' + downloads;
const page = read('templates/pages/page-submit.php');
[
@@ -399,7 +400,7 @@ test('front submit actions use direct fixed-id notyf flows', () => {
assert.match(submit, new RegExp("notyf\\([^;]+?'danger'[^;]+?" + variable + "\\);"));
});
- assert.match(submit, /aksrt-front-submit-resource-upload-toast[\s\S]*?'load'[\s\S]*?'success'[\s\S]*?'danger'/);
+ assert.match(downloads, /aksrt-front-submit-resource-upload-toast[\s\S]*?'load'[\s\S]*?'success'[\s\S]*?'danger'/);
assert.match(editor, /aksrt-front-submit-editor-media-toast[\s\S]*?'load'[\s\S]*?'success'[\s\S]*?'danger'/);
assert.match(submit, /aksrt-front-submit-ai-tags-toast[\s\S]*?aksrt-front-submit-ai-summary-toast[\s\S]*?'load'[\s\S]*?'success'[\s\S]*?'danger'/);
assert.match(submit, /needContent[^;]+?'warning'/);