Merge pull request 'Worktree/lightbox sitewide' (#16) from worktree/lightbox-sitewide into main
Reviewed-on: #16
This commit was merged in pull request #16.
This commit is contained in:
@@ -45,6 +45,10 @@
|
|||||||
!/tests/widget-system/front-submit-editor-contract.test.cjs
|
!/tests/widget-system/front-submit-editor-contract.test.cjs
|
||||||
!/tests/widget-system/comment-smilies-removal-contract.test.cjs
|
!/tests/widget-system/comment-smilies-removal-contract.test.cjs
|
||||||
!/tests/widget-system/lightbox-contract.test.cjs
|
!/tests/widget-system/lightbox-contract.test.cjs
|
||||||
|
!/tests/widget-system/homepage-dom-contract.test.cjs
|
||||||
|
!/tests/widget-system/rehydrate-runtime-contract.test.cjs
|
||||||
|
!/tests/widget-system/global-dom-init-contract.test.cjs
|
||||||
|
!/tests/widget-system/public-bundle-parity-contract.test.cjs
|
||||||
!/tests/widget-system/comment-children-list-reset-contract.test.cjs
|
!/tests/widget-system/comment-children-list-reset-contract.test.cjs
|
||||||
!/tests/widget-system/pay-card-contract.test.cjs
|
!/tests/widget-system/pay-card-contract.test.cjs
|
||||||
!/tests/widget-system/circular-button-icon-margin-contract.test.cjs
|
!/tests/widget-system/circular-button-icon-margin-contract.test.cjs
|
||||||
|
|||||||
+19
-67
@@ -269,64 +269,7 @@
|
|||||||
});
|
});
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
// ══════════════════════════════════════════════════════════════
|
// Vendor modules are no longer dynamically loaded by the canonical frontend path.
|
||||||
// §10.10a — 拦截 vendor 评论脚本 & 解绑 vendor ajax 委托
|
|
||||||
// ══════════════════════════════════════════════════════════════
|
|
||||||
// vendor 链路:loader.js(tbquire,改造版 RequireJS)→ main.min.js 检测到
|
|
||||||
// #commentform/#postcomments 即 tbquire(["comment"]) 懒加载 comment.min.js;
|
|
||||||
// 检测到 .dropdown-code/.dropdown-image 即 tbquire(["input-expand"])。
|
|
||||||
// AKSRT 自有评论脚本(comments/comment-tools/comment-fixed-input/
|
|
||||||
// comment-move-form/comment-ajax)已承担全部行为,vendor comment.min.js 的
|
|
||||||
// 7 条 body 委托会双路触发(提交 legacy action=submit_comment 无处理器,
|
|
||||||
// 即控制台「ajax请求错误」400 "0" 的来源;回复/排序/分页同理);
|
|
||||||
// vendor input-expand.min.js(表情/快捷回复旧链路,源文件已删除)同理不再下载。
|
|
||||||
//
|
|
||||||
// 双层防御:
|
|
||||||
// 1) tbfine 预注册空 'comment'/'input-expand' 模块 → tbquire 不再下载;
|
|
||||||
// 2) 若模块抢在注册前加载,退化为对 7 条委托做幂等 .off。
|
|
||||||
function stubVendorCommentModule() {
|
|
||||||
if (!(window.tbfine && window.tbquire && window.tbquire.defined)) return false;
|
|
||||||
try {
|
|
||||||
['comment', 'input-expand'].forEach(function (name) {
|
|
||||||
if (!window.tbquire.defined(name)) {
|
|
||||||
window.tbfine(name, [], function () { return {}; });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
} catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// main.min.js 的 body 级 legacy 委托同理摘除(vendor 只保留 UI 行为)。
|
|
||||||
function unbindVendorAjaxDelegates() {
|
|
||||||
stubVendorCommentModule();
|
|
||||||
if (!window.jQuery) return;
|
|
||||||
try {
|
|
||||||
var $body = jQuery('body');
|
|
||||||
$body.off('click', '[data-action]');
|
|
||||||
$body.off('click', '[ajax-action]');
|
|
||||||
$body.off('click', '.wp-ajax-submit,[zibajax="submit"]');
|
|
||||||
$body.off('click', '.initiate-checkin');
|
|
||||||
$body.off('click', '.oauth-untying');
|
|
||||||
// comment.min.js 的 7 条委托(legacy/js/comment.js 原始选择器)
|
|
||||||
$body.off('click', '[fixed-input]');
|
|
||||||
$body.off('click', '.commentlist .pagenav a,.comment-orderby');
|
|
||||||
$body.off('click', '.comment-edit-link,.comment-reply-link');
|
|
||||||
$body.off('keydown', '#comment');
|
|
||||||
$body.off('click', '.comment-trash-link');
|
|
||||||
$body.off('click', '.comment-approve-link');
|
|
||||||
$body.off('click', '#commentform #submit');
|
|
||||||
} catch (e) { /* vendor 运行时未就绪时忽略 */ }
|
|
||||||
}
|
|
||||||
var unbindVendorAjaxLoop = function () {
|
|
||||||
unbindVendorAjaxDelegates();
|
|
||||||
if (++unbindVendorAjaxLoop.tries >= 50) return; // ~10s @200ms 覆盖异步加载窗口
|
|
||||||
setTimeout(unbindVendorAjaxLoop, 200);
|
|
||||||
};
|
|
||||||
unbindVendorAjaxLoop.tries = 0;
|
|
||||||
unbindVendorAjaxLoop();
|
|
||||||
|
|
||||||
// ══════════════════════════════════════════════════════════════
|
// ══════════════════════════════════════════════════════════════
|
||||||
// §10.11 — [data-action] / [ajax-action] universal buttons
|
// §10.11 — [data-action] / [ajax-action] universal buttons
|
||||||
// ══════════════════════════════════════════════════════════════
|
// ══════════════════════════════════════════════════════════════
|
||||||
@@ -533,13 +476,7 @@
|
|||||||
// §10.11 — auto_fun: extended rehydration coverage
|
// §10.11 — auto_fun: extended rehydration coverage
|
||||||
// ══════════════════════════════════════════════════════════════
|
// ══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
aksrt.autoFun = function (root) {
|
function initTooltips(root) {
|
||||||
root = root || document;
|
|
||||||
if (window.AksrtFrontend) {
|
|
||||||
AksrtFrontend.rehydrate(root, 'ajax');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tooltips
|
|
||||||
root.querySelectorAll('[data-tooltip]').forEach(function (el) {
|
root.querySelectorAll('[data-tooltip]').forEach(function (el) {
|
||||||
if (el.dataset.tooltipBound) return;
|
if (el.dataset.tooltipBound) return;
|
||||||
el.dataset.tooltipBound = '1';
|
el.dataset.tooltipBound = '1';
|
||||||
@@ -557,8 +494,9 @@
|
|||||||
if (el._aksrtTooltip) { el._aksrtTooltip.remove(); el._aksrtTooltip = null; }
|
if (el._aksrtTooltip) { el._aksrtTooltip.remove(); el._aksrtTooltip = null; }
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Countdowns
|
function initCountdowns(root) {
|
||||||
root.querySelectorAll('[data-countdown]').forEach(function (el) {
|
root.querySelectorAll('[data-countdown]').forEach(function (el) {
|
||||||
if (el.dataset.countdownBound) return;
|
if (el.dataset.countdownBound) return;
|
||||||
el.dataset.countdownBound = '1';
|
el.dataset.countdownBound = '1';
|
||||||
@@ -572,6 +510,20 @@
|
|||||||
el.textContent = (m < 10 ? '0' : '') + m + ':' + (s < 10 ? '0' : '') + s;
|
el.textContent = (m < 10 ? '0' : '') + m + ':' + (s < 10 ? '0' : '') + s;
|
||||||
}, 1000);
|
}, 1000);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
AksrtFrontend.register('aksrt-tooltips', initTooltips);
|
||||||
|
AksrtFrontend.register('aksrt-countdowns', initCountdowns);
|
||||||
|
|
||||||
|
aksrt.autoFun = function (root, reason) {
|
||||||
|
root = root || document;
|
||||||
|
reason = reason || 'ajax';
|
||||||
|
if (!window.AksrtFrontend) return;
|
||||||
|
if (reason === 'init' && typeof AksrtFrontend.boot === 'function') {
|
||||||
|
AksrtFrontend.boot(root);
|
||||||
|
} else {
|
||||||
|
AksrtFrontend.rehydrate(root, reason);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ══════════════════════════════════════════════════════════════
|
// ══════════════════════════════════════════════════════════════
|
||||||
@@ -590,7 +542,7 @@
|
|||||||
// ── DOMContentLoaded ──
|
// ── DOMContentLoaded ──
|
||||||
|
|
||||||
function initRuntime() {
|
function initRuntime() {
|
||||||
aksrt.autoFun(document);
|
aksrt.autoFun(document, 'init');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
if (document.readyState === 'loading') {
|
||||||
|
|||||||
+42
-16
@@ -8,6 +8,8 @@
|
|||||||
var modal = null;
|
var modal = null;
|
||||||
var lastModalTrigger = null;
|
var lastModalTrigger = null;
|
||||||
var qrStates = [];
|
var qrStates = [];
|
||||||
|
var globalEventsBound = false;
|
||||||
|
var oauthResultChecked = false;
|
||||||
var oauthErrorMessages = {
|
var oauthErrorMessages = {
|
||||||
access_denied: '已取消第三方授权',
|
access_denied: '已取消第三方授权',
|
||||||
cancelled: '已取消第三方授权',
|
cancelled: '已取消第三方授权',
|
||||||
@@ -507,6 +509,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function initRoot(root) {
|
function initRoot(root) {
|
||||||
|
root = root || document;
|
||||||
|
if (root.nodeType === 1 && root.matches('[data-aksrt-auth]')) {
|
||||||
|
initAuthRoot(root);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (root.querySelectorAll) root.querySelectorAll('[data-aksrt-auth]').forEach(initAuthRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initAuthRoot(root) {
|
||||||
|
if (root.dataset.aksrtAuthInitialized === '1') return;
|
||||||
|
root.dataset.aksrtAuthInitialized = '1';
|
||||||
root.querySelectorAll('input').forEach(function (input) {
|
root.querySelectorAll('input').forEach(function (input) {
|
||||||
if (!input.hasAttribute('placeholder')) input.setAttribute('placeholder', ' ');
|
if (!input.hasAttribute('placeholder')) input.setAttribute('placeholder', ' ');
|
||||||
});
|
});
|
||||||
@@ -662,10 +675,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function initGlobal() {
|
||||||
showOAuthResultToast();
|
|
||||||
document.querySelectorAll('[data-aksrt-auth]').forEach(initRoot);
|
|
||||||
modal = document.querySelector('[data-auth-modal]');
|
modal = document.querySelector('[data-auth-modal]');
|
||||||
|
if (!oauthResultChecked) {
|
||||||
|
oauthResultChecked = true;
|
||||||
|
showOAuthResultToast();
|
||||||
|
}
|
||||||
|
if (globalEventsBound) return;
|
||||||
|
globalEventsBound = true;
|
||||||
document.addEventListener('click', function (event) {
|
document.addEventListener('click', function (event) {
|
||||||
var trigger = event.target.closest('[data-aksrt-auth-required], .aksrt-login-trigger, #nav-login-btn, .signin-loader, .signup-loader, .qrcode-signin');
|
var trigger = event.target.closest('[data-aksrt-auth-required], .aksrt-login-trigger, #nav-login-btn, .signin-loader, .signup-loader, .qrcode-signin');
|
||||||
if (!trigger) return;
|
if (!trigger) return;
|
||||||
@@ -673,17 +690,7 @@
|
|||||||
var tab = trigger.classList.contains('signup-loader') ? 'signup' : (trigger.classList.contains('qrcode-signin') ? 'oauth' : 'signin');
|
var tab = trigger.classList.contains('signup-loader') ? 'signup' : (trigger.classList.contains('qrcode-signin') ? 'oauth' : 'signin');
|
||||||
openModal(tab, trigger.dataset.authRedirect || window.location.href, trigger);
|
openModal(tab, trigger.dataset.authRedirect || window.location.href, trigger);
|
||||||
});
|
});
|
||||||
if (modal) {
|
document.addEventListener('keydown', handleModalKeydown);
|
||||||
modal.addEventListener('click', function (event) {
|
|
||||||
if (event.target.closest('[data-auth-close]')) closeModal(true);
|
|
||||||
});
|
|
||||||
document.addEventListener('keydown', handleModalKeydown);
|
|
||||||
if (modal.dataset.auto === '1' && Number(window.localStorage.getItem('aksrtAuthAutoUntil') || 0) < Date.now()) {
|
|
||||||
window.setTimeout(function () {
|
|
||||||
openModal(modal.querySelector('[data-aksrt-auth]').dataset.initialTab || 'signin', window.location.href, null);
|
|
||||||
}, Math.max(1, Number(modal.dataset.autoWait) || 5) * 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
document.addEventListener('visibilitychange', function () {
|
document.addEventListener('visibilitychange', function () {
|
||||||
qrStates.forEach(function (state) {
|
qrStates.forEach(function (state) {
|
||||||
if (document.visibilityState !== 'visible') stopQr(state.root);
|
if (document.visibilityState !== 'visible') stopQr(state.root);
|
||||||
@@ -692,6 +699,25 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
|
function initModal() {
|
||||||
else init();
|
if (!modal || modal.dataset.aksrtAuthModalInitialized === '1') return;
|
||||||
|
modal.dataset.aksrtAuthModalInitialized = '1';
|
||||||
|
modal.addEventListener('click', function (event) {
|
||||||
|
if (event.target.closest('[data-auth-close]')) closeModal(true);
|
||||||
|
});
|
||||||
|
if (modal.dataset.auto === '1' && Number(window.localStorage.getItem('aksrtAuthAutoUntil') || 0) < Date.now()) {
|
||||||
|
window.setTimeout(function () {
|
||||||
|
var root = modal.querySelector('[data-aksrt-auth]');
|
||||||
|
if (root) openModal(root.dataset.initialTab || 'signin', window.location.href, null);
|
||||||
|
}, Math.max(1, Number(modal.dataset.autoWait) || 5) * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
|
||||||
|
window.AksrtFrontend.register('aksrt-auth', function (root) {
|
||||||
|
initGlobal();
|
||||||
|
initRoot(root);
|
||||||
|
initModal();
|
||||||
|
});
|
||||||
|
}
|
||||||
}());
|
}());
|
||||||
|
|||||||
+63
-27
@@ -13,14 +13,30 @@
|
|||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
var globalEventsBound = false;
|
||||||
|
|
||||||
|
function elementsIn(root, selector) {
|
||||||
|
var elements = [];
|
||||||
|
root = root || document;
|
||||||
|
if (root.nodeType === 1 && root.matches(selector)) elements.push(root);
|
||||||
|
if (root.querySelectorAll) root.querySelectorAll(selector).forEach(function (element) { elements.push(element); });
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
function elementById(root, id) {
|
||||||
|
root = root || document;
|
||||||
|
if (root.nodeType === 1 && root.id === id) return root;
|
||||||
|
return root.querySelector ? root.querySelector('#' + id) : null;
|
||||||
|
}
|
||||||
|
|
||||||
function notifyLoadError() {
|
function notifyLoadError() {
|
||||||
if (typeof notyf === 'function') {
|
if (typeof notyf === 'function') {
|
||||||
notyf('加载失败,请重试', 'danger');
|
notyf('加载失败,请重试', 'danger');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function initPublicDashboards() {
|
function initPublicDashboards(scope) {
|
||||||
document.querySelectorAll('.dashboard--public').forEach(function (root) {
|
elementsIn(scope, '.dashboard--public').forEach(function (root) {
|
||||||
if (root.dataset.aksrtAuthorBound === '1') return;
|
if (root.dataset.aksrtAuthorBound === '1') return;
|
||||||
root.dataset.aksrtAuthorBound = '1';
|
root.dataset.aksrtAuthorBound = '1';
|
||||||
|
|
||||||
@@ -138,13 +154,13 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initCoverUpload() {
|
function initCoverUpload(root) {
|
||||||
var cfg = window.aksrtAuthorPage || {};
|
var cfg = window.aksrtAuthorPage || {};
|
||||||
var upload = cfg.coverUpload || null;
|
var upload = cfg.coverUpload || null;
|
||||||
if (!upload || !upload.enabled || !upload.restUrl) return;
|
if (!upload || !upload.enabled || !upload.restUrl) return;
|
||||||
|
|
||||||
var btn = document.getElementById(upload.buttonId || 'aksrt-upload-bg-btn');
|
var btn = elementById(root, upload.buttonId || 'aksrt-upload-bg-btn');
|
||||||
var input = document.getElementById(upload.inputId || 'aksrt-bg-file-input');
|
var input = elementById(root, upload.inputId || 'aksrt-bg-file-input');
|
||||||
if (!btn || !input || btn.dataset.aksrtCoverBound === '1') return;
|
if (!btn || !input || btn.dataset.aksrtCoverBound === '1') return;
|
||||||
|
|
||||||
btn.dataset.aksrtCoverBound = '1';
|
btn.dataset.aksrtCoverBound = '1';
|
||||||
@@ -238,13 +254,13 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initAvatarUpload() {
|
function initAvatarUpload(root) {
|
||||||
var upload = (window.aksrtUserCenter || {}).avatarUpload;
|
var upload = (window.aksrtUserCenter || {}).avatarUpload;
|
||||||
if (!upload || !upload.enabled || !upload.restUrl) return;
|
if (!upload || !upload.enabled || !upload.restUrl) return;
|
||||||
|
|
||||||
var button = document.getElementById(upload.buttonId || 'aksrt-upload-avatar-btn');
|
var button = elementById(root, upload.buttonId || 'aksrt-upload-avatar-btn');
|
||||||
var input = document.getElementById(upload.inputId || 'aksrt-avatar-file-input');
|
var input = elementById(root, upload.inputId || 'aksrt-avatar-file-input');
|
||||||
var image = document.getElementById(upload.imageId || 'aksrt-user-avatar-image');
|
var image = elementById(root, upload.imageId || 'aksrt-user-avatar-image');
|
||||||
if (!button || !input || button.dataset.aksrtAvatarBound === '1') return;
|
if (!button || !input || button.dataset.aksrtAvatarBound === '1') return;
|
||||||
button.dataset.aksrtAvatarBound = '1';
|
button.dataset.aksrtAvatarBound = '1';
|
||||||
|
|
||||||
@@ -297,8 +313,8 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initCoverMenus() {
|
function initCoverMenus(root) {
|
||||||
document.querySelectorAll('[data-aksrt-menu]').forEach(function (menu) {
|
elementsIn(root, '[data-aksrt-menu]').forEach(function (menu) {
|
||||||
if (menu.dataset.aksrtMenuBound === '1') return;
|
if (menu.dataset.aksrtMenuBound === '1') return;
|
||||||
menu.dataset.aksrtMenuBound = '1';
|
menu.dataset.aksrtMenuBound = '1';
|
||||||
var trigger = menu.querySelector('.aksrt-cover-menu__trigger');
|
var trigger = menu.querySelector('.aksrt-cover-menu__trigger');
|
||||||
@@ -320,34 +336,54 @@
|
|||||||
}
|
}
|
||||||
trigger.addEventListener('click', function () { panel.hidden ? open() : close(); });
|
trigger.addEventListener('click', function () { panel.hidden ? open() : close(); });
|
||||||
menu.addEventListener('keydown', function (event) { if (event.key === 'Escape') { close(); trigger.focus(); } });
|
menu.addEventListener('keydown', function (event) { if (event.key === 'Escape') { close(); trigger.focus(); } });
|
||||||
document.addEventListener('pointerdown', function (event) { if (!menu.contains(event.target)) close(); });
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initProfileDetailsModal() {
|
function initProfileDetailsModal(root) {
|
||||||
var modal = document.getElementById('aksrt-profile-details-modal');
|
var modal = elementById(root, 'aksrt-profile-details-modal');
|
||||||
if (!modal) return;
|
if (!modal || modal.dataset.aksrtProfileModalBound === '1') return;
|
||||||
|
modal.dataset.aksrtProfileModalBound = '1';
|
||||||
var dialog = modal.querySelector('.aksrt-profile-details-modal__dialog');
|
var dialog = modal.querySelector('.aksrt-profile-details-modal__dialog');
|
||||||
var returnFocus = null;
|
var returnFocus = null;
|
||||||
function close() { modal.hidden = true; if (returnFocus) returnFocus.focus(); }
|
function close() { modal.hidden = true; if (returnFocus) returnFocus.focus(); }
|
||||||
document.querySelectorAll('[data-aksrt-profile-details]').forEach(function (button) {
|
elementsIn(root, '[data-aksrt-profile-details]').forEach(function (button) {
|
||||||
button.addEventListener('click', function () { returnFocus = button; modal.hidden = false; if (dialog) dialog.focus(); });
|
button.addEventListener('click', function () { returnFocus = button; modal.hidden = false; if (dialog) dialog.focus(); });
|
||||||
});
|
});
|
||||||
modal.querySelectorAll('[data-aksrt-modal-close]').forEach(function (button) { button.addEventListener('click', close); });
|
modal.querySelectorAll('[data-aksrt-modal-close]').forEach(function (button) { button.addEventListener('click', close); });
|
||||||
document.addEventListener('keydown', function (event) { if (event.key === 'Escape' && !modal.hidden) close(); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function initGlobalEvents() {
|
||||||
initPublicDashboards();
|
if (globalEventsBound) return;
|
||||||
initCoverMenus();
|
globalEventsBound = true;
|
||||||
initProfileDetailsModal();
|
document.addEventListener('pointerdown', function (event) {
|
||||||
initCoverUpload();
|
document.querySelectorAll('[data-aksrt-menu]').forEach(function (menu) {
|
||||||
initAvatarUpload();
|
if (menu.contains(event.target)) return;
|
||||||
|
var panel = menu.querySelector('.aksrt-cover-menu__panel');
|
||||||
|
var trigger = menu.querySelector('.aksrt-cover-menu__trigger');
|
||||||
|
if (panel) panel.hidden = true;
|
||||||
|
if (trigger) trigger.setAttribute('aria-expanded', 'false');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
document.addEventListener('keydown', function (event) {
|
||||||
|
if (event.key !== 'Escape') return;
|
||||||
|
var modal = document.getElementById('aksrt-profile-details-modal');
|
||||||
|
if (modal && !modal.hidden) {
|
||||||
|
var close = modal.querySelector('[data-aksrt-modal-close]');
|
||||||
|
if (close) close.click();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
function init(root) {
|
||||||
document.addEventListener('DOMContentLoaded', init);
|
initGlobalEvents();
|
||||||
} else {
|
initPublicDashboards(root);
|
||||||
init();
|
initCoverMenus(root);
|
||||||
|
initProfileDetailsModal(root);
|
||||||
|
initCoverUpload(root);
|
||||||
|
initAvatarUpload(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
|
||||||
|
window.AksrtFrontend.register('aksrt-author', init);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -9,9 +9,12 @@
|
|||||||
if (window._win && window._win.ajax_url) return window._win.ajax_url;
|
if (window._win && window._win.ajax_url) return window._win.ajax_url;
|
||||||
return '/wp-admin/admin-ajax.php';
|
return '/wp-admin/admin-ajax.php';
|
||||||
}
|
}
|
||||||
function init() {
|
function init(root) {
|
||||||
var form = document.querySelector('.aksrt-ban-appeal-form');
|
root = root || document;
|
||||||
if (!form) return;
|
var form = root.nodeType === 1 && root.matches('.aksrt-ban-appeal-form')
|
||||||
|
? root : root.querySelector('.aksrt-ban-appeal-form');
|
||||||
|
if (!form || form.dataset.aksrtBanAppealBound === '1') return;
|
||||||
|
form.dataset.aksrtBanAppealBound = '1';
|
||||||
form.addEventListener('submit', function (e) {
|
form.addEventListener('submit', function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var btn = form.querySelector('button[type="submit"]');
|
var btn = form.querySelector('button[type="submit"]');
|
||||||
@@ -32,6 +35,5 @@
|
|||||||
.finally(function () { if (btn) btn.disabled = false; });
|
.finally(function () { if (btn) btn.disabled = false; });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
|
window.AksrtFrontend.register('aksrt-ban-appeal-page', init);
|
||||||
else init();
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
+436
-517
File diff suppressed because one or more lines are too long
@@ -121,8 +121,11 @@
|
|||||||
TOKEN_FIELDS: TOKEN_FIELDS
|
TOKEN_FIELDS: TOKEN_FIELDS
|
||||||
});
|
});
|
||||||
|
|
||||||
function scan() {
|
function scan(root, reason) {
|
||||||
var mounts = document.querySelectorAll('[data-aksrt-captcha-config]');
|
var scope = root && root.querySelectorAll ? root : document;
|
||||||
|
var mounts = [];
|
||||||
|
if (scope.nodeType === 1 && scope.matches('[data-aksrt-captcha-config]')) mounts.push(scope);
|
||||||
|
Array.prototype.push.apply(mounts, scope.querySelectorAll('[data-aksrt-captcha-config]'));
|
||||||
Array.prototype.forEach.call(mounts, function (mount) {
|
Array.prototype.forEach.call(mounts, function (mount) {
|
||||||
if (mount.dataset.aksrtCaptchaBound) return;
|
if (mount.dataset.aksrtCaptchaBound) return;
|
||||||
var config;
|
var config;
|
||||||
@@ -545,13 +548,5 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', scan);
|
window.AksrtFrontend.register('aksrt-captcha-front', scan);
|
||||||
else setTimeout(scan, 0);
|
|
||||||
|
|
||||||
if (window.MutationObserver) {
|
|
||||||
new MutationObserver(function (mutations) {
|
|
||||||
var shouldScan = mutations.some(function (mutation) { return mutation.addedNodes && mutation.addedNodes.length; });
|
|
||||||
if (shouldScan) scan();
|
|
||||||
}).observe(document.documentElement, { childList: true, subtree: true });
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -698,7 +698,7 @@
|
|||||||
if (preview.balance_enough === false) {
|
if (preview.balance_enough === false) {
|
||||||
if (preview.credits_url) {
|
if (preview.credits_url) {
|
||||||
body += '<a class="but c-red block mt6 aksrt-cashier__recharge" href="' + escapeAttr(preview.credits_url) + '">' +
|
body += '<a class="but c-red block mt6 aksrt-cashier__recharge" href="' + escapeAttr(preview.credits_url) + '">' +
|
||||||
'抱歉!余额不足,请先充值 <i class="ml6 fa fa-angle-right em12" aria-hidden="true"></i></a>';
|
'抱歉!余额不足,请先充值 <i class="ml6 fa fas fa-angle-right em12" aria-hidden="true"></i></a>';
|
||||||
} else {
|
} else {
|
||||||
body += '<div class="c-red mt6 aksrt-cashier__recharge">抱歉!余额不足,请先充值</div>';
|
body += '<div class="c-red mt6 aksrt-cashier__recharge">抱歉!余额不足,请先充值</div>';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function processImage(img) {
|
function processImage(img) {
|
||||||
if (img.dataset.aksrtColorDone) return;
|
if (img.dataset.aksrtColorDone || img.dataset.aksrtColorBound) return;
|
||||||
|
img.dataset.aksrtColorBound = '1';
|
||||||
|
|
||||||
// Need crossOrigin for canvas access
|
// Need crossOrigin for canvas access
|
||||||
if (!img.crossOrigin && img.src.indexOf(window.location.origin) !== 0) {
|
if (!img.crossOrigin && img.src.indexOf(window.location.origin) !== 0) {
|
||||||
@@ -127,8 +128,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init(root, reason) {
|
||||||
document.querySelectorAll('[data-aksrt-color-extract]').forEach(processImage);
|
var scope = root && root.querySelectorAll ? root : document;
|
||||||
|
if (scope.nodeType === 1 && scope.matches('[data-aksrt-color-extract]')) processImage(scope);
|
||||||
|
scope.querySelectorAll('[data-aksrt-color-extract]').forEach(processImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Public API
|
// Public API
|
||||||
@@ -139,9 +142,5 @@
|
|||||||
init: init
|
init: init
|
||||||
};
|
};
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
window.AksrtFrontend.register('aksrt-color-extract', init);
|
||||||
document.addEventListener('DOMContentLoaded', init);
|
|
||||||
} else {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -133,7 +133,7 @@
|
|||||||
if (!result.success) { notyf((result.data && result.data.message) || result.message || '操作失败', 'danger'); return; }
|
if (!result.success) { notyf((result.data && result.data.message) || result.message || '操作失败', 'danger'); return; }
|
||||||
var pinned = !!(result.data && result.data.pinned);
|
var pinned = !!(result.data && result.data.pinned);
|
||||||
btn.setAttribute('data-pinned', pinned ? '1' : '0');
|
btn.setAttribute('data-pinned', pinned ? '1' : '0');
|
||||||
btn.innerHTML = '<i class="fa fa-thumbtack mr10 fa-fw" aria-hidden="true"></i>' + (pinned ? '取消置顶' : '设置置顶');
|
btn.innerHTML = '<i class="fa fas fa-thumbtack mr10 fa-fw" aria-hidden="true"></i>' + (pinned ? '取消置顶' : '设置置顶');
|
||||||
syncPinnedBadge(commentEl, pinned);
|
syncPinnedBadge(commentEl, pinned);
|
||||||
notyf(result.message || (pinned ? '评论已置顶。' : '已取消置顶。'), 'success');
|
notyf(result.message || (pinned ? '评论已置顶。' : '已取消置顶。'), 'success');
|
||||||
})
|
})
|
||||||
@@ -148,7 +148,7 @@
|
|||||||
badge = document.createElement('badge');
|
badge = document.createElement('badge');
|
||||||
badge.className = 'badge-topping jb-blue mr6 flex0';
|
badge.className = 'badge-topping jb-blue mr6 flex0';
|
||||||
badge.title = '置顶评论';
|
badge.title = '置顶评论';
|
||||||
badge.innerHTML = '<i class="fa fa-thumbtack" aria-hidden="true"></i>';
|
badge.innerHTML = '<i class="fa fas fa-thumbtack" aria-hidden="true"></i>';
|
||||||
name.insertBefore(badge, name.firstChild);
|
name.insertBefore(badge, name.firstChild);
|
||||||
} else if (!pinned && badge) {
|
} else if (!pinned && badge) {
|
||||||
badge.remove();
|
badge.remove();
|
||||||
|
|||||||
@@ -39,19 +39,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('click', function (e) {
|
|
||||||
var trigger = e.target && e.target.closest ? e.target.closest('[fixed-input]') : null;
|
|
||||||
if (!trigger) return;
|
|
||||||
e.preventDefault();
|
|
||||||
var targetSel = trigger.getAttribute('fixed-input') || '#respond';
|
|
||||||
var panel = document.querySelector(targetSel);
|
|
||||||
var comments = document.getElementById('comments');
|
|
||||||
if (comments && comments.scrollIntoView) {
|
|
||||||
comments.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
||||||
}
|
|
||||||
FixedInput(panel, 'show');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Autoheight textareas.
|
// Autoheight textareas.
|
||||||
function bindAutoheight(ta) {
|
function bindAutoheight(ta) {
|
||||||
if (!ta || ta.dataset.autoheightBound) return;
|
if (!ta || ta.dataset.autoheightBound) return;
|
||||||
@@ -67,24 +54,49 @@
|
|||||||
resize();
|
resize();
|
||||||
}
|
}
|
||||||
|
|
||||||
function scan() {
|
function scopeFor(root) {
|
||||||
document.querySelectorAll('textarea[autoheight], textarea.grin').forEach(bindAutoheight);
|
return root && root.querySelectorAll ? root : document;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', scan);
|
function scan(root) {
|
||||||
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
|
var scope = scopeFor(root);
|
||||||
window.AksrtFrontend.register('aksrt-comment-fixed-input', function (root) {
|
if (scope.nodeType === 1 && scope.matches('textarea[autoheight], textarea.grin')) {
|
||||||
scan();
|
bindAutoheight(scope);
|
||||||
// Expose for submit hide.
|
}
|
||||||
root = root || document;
|
scope.querySelectorAll('textarea[autoheight], textarea.grin').forEach(bindAutoheight);
|
||||||
var respond = root.querySelector ? root.querySelector('#respond') : document.getElementById('respond');
|
}
|
||||||
if (respond) {
|
|
||||||
respond.aksrtFixedInput = function (action) {
|
var globalsBound = false;
|
||||||
FixedInput(respond, action);
|
function bindGlobals() {
|
||||||
};
|
if (globalsBound) return;
|
||||||
|
globalsBound = true;
|
||||||
|
document.addEventListener('click', function (e) {
|
||||||
|
var trigger = e.target && e.target.closest ? e.target.closest('[fixed-input]') : null;
|
||||||
|
if (!trigger) return;
|
||||||
|
e.preventDefault();
|
||||||
|
var targetSel = trigger.getAttribute('fixed-input') || '#respond';
|
||||||
|
var panel = document.querySelector(targetSel);
|
||||||
|
var comments = document.getElementById('comments');
|
||||||
|
if (comments && comments.scrollIntoView) {
|
||||||
|
comments.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||||
}
|
}
|
||||||
|
FixedInput(panel, 'show');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.AksrtFrontend.register('aksrt-comment-fixed-input', function (root, reason) {
|
||||||
|
bindGlobals();
|
||||||
|
scan(root);
|
||||||
|
root = root || document;
|
||||||
|
var respond = root.nodeType === 1 && root.matches && root.matches('#respond')
|
||||||
|
? root
|
||||||
|
: (root.querySelector ? root.querySelector('#respond') : document.getElementById('respond'));
|
||||||
|
if (respond) {
|
||||||
|
respond.aksrtFixedInput = function (action) {
|
||||||
|
FixedInput(respond, action);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
window.AksrtFixedInput = FixedInput;
|
window.AksrtFixedInput = FixedInput;
|
||||||
})();
|
})();
|
||||||
|
|||||||
+48
-59
@@ -4,6 +4,18 @@
|
|||||||
(function () {
|
(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var globalsBound = false;
|
||||||
|
|
||||||
|
function scopeFor(root) {
|
||||||
|
return root && root.querySelectorAll ? root : document;
|
||||||
|
}
|
||||||
|
|
||||||
|
function eachMatch(root, selector, callback) {
|
||||||
|
var scope = scopeFor(root);
|
||||||
|
if (scope.nodeType === 1 && scope.matches(selector)) callback(scope);
|
||||||
|
scope.querySelectorAll(selector).forEach(callback);
|
||||||
|
}
|
||||||
|
|
||||||
function renderGradientBackground(container) {
|
function renderGradientBackground(container) {
|
||||||
if (!container || container.dataset.aksrtGradientState || typeof window.Grade !== "function") return;
|
if (!container || container.dataset.aksrtGradientState || typeof window.Grade !== "function") return;
|
||||||
|
|
||||||
@@ -32,26 +44,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function initGradientBackgrounds(root) {
|
function initGradientBackgrounds(root) {
|
||||||
var scope = root || document;
|
eachMatch(root, ".gradient-bg", renderGradientBackground);
|
||||||
if (scope.nodeType === 1 && scope.matches(".gradient-bg")) {
|
|
||||||
renderGradientBackground(scope);
|
|
||||||
}
|
|
||||||
scope.querySelectorAll(".gradient-bg").forEach(renderGradientBackground);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener("lazyloaded", function (event) {
|
|
||||||
if (!(event.target instanceof Element) || !event.target.matches(".gradient-bg img")) return;
|
|
||||||
renderGradientBackground(event.target.closest(".gradient-bg"));
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
function initPostThumbMedia(root) {
|
function initPostThumbMedia(root) {
|
||||||
var scope = root || document;
|
eachMatch(root, "[data-post-thumb-video]", function (box) {
|
||||||
|
|
||||||
scope.querySelectorAll("[data-post-thumb-video]").forEach(function (box) {
|
|
||||||
if (box.dataset.aksrtThumbVideoBound === "1") return;
|
if (box.dataset.aksrtThumbVideoBound === "1") return;
|
||||||
box.dataset.aksrtThumbVideoBound = "1";
|
|
||||||
var video = box.querySelector("video");
|
var video = box.querySelector("video");
|
||||||
if (!video) return;
|
if (!video) return;
|
||||||
|
box.dataset.aksrtThumbVideoBound = "1";
|
||||||
|
|
||||||
function loadVideo() {
|
function loadVideo() {
|
||||||
if (!video.getAttribute("src") && video.dataset.src) {
|
if (!video.getAttribute("src") && video.dataset.src) {
|
||||||
@@ -82,25 +83,17 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
window.AksrtFrontend.register("aksrt-post-thumb-media", function (root) {
|
function initSlideCovers(root) {
|
||||||
initPostThumbMedia(root);
|
eachMatch(root, ".single-cover--slide", function (cover) {
|
||||||
initGradientBackgrounds(root);
|
if (cover.dataset.aksrtSlideCoverBound === "1") return;
|
||||||
});
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function () {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
function initSlideCovers() {
|
|
||||||
var covers = document.querySelectorAll(".single-cover--slide");
|
|
||||||
covers.forEach(function (cover) {
|
|
||||||
var slides = cover.querySelectorAll(".single-cover__slide");
|
var slides = cover.querySelectorAll(".single-cover__slide");
|
||||||
var dots = cover.querySelectorAll(".single-cover__dot");
|
var dots = cover.querySelectorAll(".single-cover__dot");
|
||||||
if (slides.length < 2) return;
|
if (slides.length < 2) return;
|
||||||
|
cover.dataset.aksrtSlideCoverBound = "1";
|
||||||
|
|
||||||
var current = 0;
|
var current = 0;
|
||||||
var interval = 5000;
|
var interval = 5000;
|
||||||
|
var timer = null;
|
||||||
|
|
||||||
function goTo(idx) {
|
function goTo(idx) {
|
||||||
slides[current].classList.remove("is-active");
|
slides[current].classList.remove("is-active");
|
||||||
@@ -110,33 +103,32 @@
|
|||||||
if (dots[current]) dots[current].classList.add("is-active");
|
if (dots[current]) dots[current].classList.add("is-active");
|
||||||
}
|
}
|
||||||
|
|
||||||
var timer = setInterval(function () {
|
function startTimer() {
|
||||||
goTo((current + 1) % slides.length);
|
timer = window.setInterval(function () {
|
||||||
}, interval);
|
goTo((current + 1) % slides.length);
|
||||||
|
}, interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
startTimer();
|
||||||
dots.forEach(function (dot, i) {
|
dots.forEach(function (dot, i) {
|
||||||
dot.addEventListener("click", function () {
|
dot.addEventListener("click", function () {
|
||||||
clearInterval(timer);
|
window.clearInterval(timer);
|
||||||
goTo(i);
|
goTo(i);
|
||||||
timer = setInterval(function () {
|
startTimer();
|
||||||
goTo((current + 1) % slides.length);
|
|
||||||
}, interval);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === "loading") {
|
function bindGlobals() {
|
||||||
document.addEventListener("DOMContentLoaded", initSlideCovers);
|
if (globalsBound) return;
|
||||||
} else {
|
globalsBound = true;
|
||||||
initSlideCovers();
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function () {
|
document.addEventListener("lazyloaded", function (event) {
|
||||||
"use strict";
|
if (!(event.target instanceof Element) || !event.target.matches(".gradient-bg img")) return;
|
||||||
|
renderGradientBackground(event.target.closest(".gradient-bg"));
|
||||||
|
}, true);
|
||||||
|
|
||||||
function initHiddenContent() {
|
|
||||||
document.addEventListener("click", function (e) {
|
document.addEventListener("click", function (e) {
|
||||||
var btn = e.target.closest(".aksrt-hidden-content__submit-btn");
|
var btn = e.target.closest(".aksrt-hidden-content__submit-btn");
|
||||||
if (!btn) return;
|
if (!btn) return;
|
||||||
@@ -157,7 +149,7 @@
|
|||||||
|
|
||||||
var formData = new FormData();
|
var formData = new FormData();
|
||||||
formData.append("action", "aksrt_check_visibility");
|
formData.append("action", "aksrt_check_visibility");
|
||||||
formData.append("_nonce", (window.aksrtData && aksrtData.visibilityNonce) || "");
|
formData.append("_nonce", (window.aksrtData && window.aksrtData.visibilityNonce) || "");
|
||||||
formData.append("mode", mode);
|
formData.append("mode", mode);
|
||||||
formData.append("pid", pid);
|
formData.append("pid", pid);
|
||||||
if (password) formData.append("password", password);
|
if (password) formData.append("password", password);
|
||||||
@@ -165,7 +157,7 @@
|
|||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
btn.textContent = "...";
|
btn.textContent = "...";
|
||||||
|
|
||||||
fetch((window.aksrtData && aksrtData.ajaxUrl) || "/wp-admin/admin-ajax.php", {
|
fetch((window.aksrtData && window.aksrtData.ajaxUrl) || "/wp-admin/admin-ajax.php", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: formData,
|
body: formData,
|
||||||
credentials: "same-origin",
|
credentials: "same-origin",
|
||||||
@@ -188,22 +180,19 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle Enter key on password input
|
|
||||||
document.addEventListener("keydown", function (e) {
|
document.addEventListener("keydown", function (e) {
|
||||||
if (e.key === "Enter" && e.target.classList.contains("aksrt-hidden-content__password-input")) {
|
if (e.key !== "Enter" || !e.target.classList.contains("aksrt-hidden-content__password-input")) return;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var wrapper = e.target.closest(".aksrt-hidden-content--locked");
|
var wrapper = e.target.closest(".aksrt-hidden-content--locked");
|
||||||
if (wrapper) {
|
var btn = wrapper ? wrapper.querySelector(".aksrt-hidden-content__submit-btn") : null;
|
||||||
var btn = wrapper.querySelector(".aksrt-hidden-content__submit-btn");
|
if (btn) btn.click();
|
||||||
if (btn) btn.click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === "loading") {
|
window.AksrtFrontend.register("aksrt-misc", function (root, reason) {
|
||||||
document.addEventListener("DOMContentLoaded", initHiddenContent);
|
bindGlobals();
|
||||||
} else {
|
initPostThumbMedia(root);
|
||||||
initHiddenContent();
|
initGradientBackgrounds(root);
|
||||||
}
|
initSlideCovers(root);
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
|
|||||||
+68
-55
@@ -15,6 +15,21 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var activePoll = null;
|
var activePoll = null;
|
||||||
|
var balancesRefreshed = false;
|
||||||
|
|
||||||
|
function elementsIn(root, selector) {
|
||||||
|
var elements = [];
|
||||||
|
root = root || document;
|
||||||
|
if (root.nodeType === 1 && root.matches(selector)) elements.push(root);
|
||||||
|
if (root.querySelectorAll) root.querySelectorAll(selector).forEach(function (element) { elements.push(element); });
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
function firstIn(root, selector) {
|
||||||
|
root = root || document;
|
||||||
|
if (root.nodeType === 1 && root.matches(selector)) return root;
|
||||||
|
return root.querySelector ? root.querySelector(selector) : null;
|
||||||
|
}
|
||||||
|
|
||||||
function operationKey(owner) {
|
function operationKey(owner) {
|
||||||
if (!owner.dataset.aksrtOperationKey) {
|
if (!owner.dataset.aksrtOperationKey) {
|
||||||
@@ -89,8 +104,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Task-list "去签到" → scroll + click the real asset-card sign-in button.
|
// Task-list "去签到" → scroll + click the real asset-card sign-in button.
|
||||||
function initSigninGoto() {
|
function initSigninGoto(root) {
|
||||||
document.querySelectorAll('[data-aksrt-signin-goto]').forEach(function (el) {
|
root = root || document;
|
||||||
|
var items = [];
|
||||||
|
if (root.nodeType === 1 && root.matches('[data-aksrt-signin-goto]')) items.push(root);
|
||||||
|
if (root.querySelectorAll) root.querySelectorAll('[data-aksrt-signin-goto]').forEach(function (el) { items.push(el); });
|
||||||
|
items.forEach(function (el) {
|
||||||
if (el.dataset.aksrtSigninGotoInitialized === '1') return;
|
if (el.dataset.aksrtSigninGotoInitialized === '1') return;
|
||||||
el.dataset.aksrtSigninGotoInitialized = '1';
|
el.dataset.aksrtSigninGotoInitialized = '1';
|
||||||
el.addEventListener('click', function (e) {
|
el.addEventListener('click', function (e) {
|
||||||
@@ -113,8 +132,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ===== Forward-only affiliate revenue center =====
|
// ===== Forward-only affiliate revenue center =====
|
||||||
function initAffiliateRevenue() {
|
function initAffiliateRevenue(scope) {
|
||||||
var root = document.querySelector('[data-aksrt-revenue-page]');
|
var root = firstIn(scope, '[data-aksrt-revenue-page]');
|
||||||
if (!root || root.dataset.affiliateBound) return;
|
if (!root || root.dataset.affiliateBound) return;
|
||||||
root.dataset.affiliateBound = '1';
|
root.dataset.affiliateBound = '1';
|
||||||
var input = root.querySelector('[data-affiliate-link]');
|
var input = root.querySelector('[data-affiliate-link]');
|
||||||
@@ -149,9 +168,10 @@
|
|||||||
|
|
||||||
|
|
||||||
// ===== VIP 积分兑换 =====
|
// ===== VIP 积分兑换 =====
|
||||||
function initVipPointsExchange() {
|
function initVipPointsExchange(scope) {
|
||||||
var root = document.querySelector('[data-aksrt-vip-points]');
|
var root = firstIn(scope, '[data-aksrt-vip-points]');
|
||||||
if (!root) return;
|
if (!root || root.dataset.aksrtVipPointsBound === '1') return;
|
||||||
|
root.dataset.aksrtVipPointsBound = '1';
|
||||||
var tip = root.querySelector('[data-aksrt-vip-points-tip]');
|
var tip = root.querySelector('[data-aksrt-vip-points-tip]');
|
||||||
var busy = false;
|
var busy = false;
|
||||||
var coordinator = window.AksrtVipPurchaseCoordinator;
|
var coordinator = window.AksrtVipPurchaseCoordinator;
|
||||||
@@ -191,9 +211,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ===== VIP 开通 =====
|
// ===== VIP 开通 =====
|
||||||
function initVipShop() {
|
function initVipShop(scope) {
|
||||||
var root = document.querySelector('[data-aksrt-vip-shop]');
|
var root = firstIn(scope, '[data-aksrt-vip-shop]');
|
||||||
if (!root) return;
|
if (!root || root.dataset.aksrtVipShopBound === '1') return;
|
||||||
|
root.dataset.aksrtVipShopBound = '1';
|
||||||
var tip = root.querySelector('[data-aksrt-vip-tip]');
|
var tip = root.querySelector('[data-aksrt-vip-tip]');
|
||||||
var busy = false;
|
var busy = false;
|
||||||
var coordinator = window.AksrtVipPurchaseCoordinator;
|
var coordinator = window.AksrtVipPurchaseCoordinator;
|
||||||
@@ -265,11 +286,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ===== 卡密兑换(余额 / 会员) =====
|
// ===== 卡密兑换(余额 / 会员) =====
|
||||||
function initCardPass() {
|
function initCardPass(scope) {
|
||||||
var roots = document.querySelectorAll('[data-aksrt-card-pass]');
|
var roots = elementsIn(scope, '[data-aksrt-card-pass]');
|
||||||
if (!roots || !roots.length) return;
|
if (!roots || !roots.length) return;
|
||||||
|
|
||||||
Array.prototype.forEach.call(roots, function (root) {
|
Array.prototype.forEach.call(roots, function (root) {
|
||||||
|
if (root.dataset.aksrtCardPassBound === '1') return;
|
||||||
|
root.dataset.aksrtCardPassBound = '1';
|
||||||
var tip = root.querySelector('[data-aksrt-card-tip]');
|
var tip = root.querySelector('[data-aksrt-card-tip]');
|
||||||
var busy = false;
|
var busy = false;
|
||||||
resetOperationKeyOnChange(root);
|
resetOperationKeyOnChange(root);
|
||||||
@@ -380,8 +403,8 @@
|
|||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
function initBalanceCharge() {
|
function initBalanceCharge(scope) {
|
||||||
var modal = document.querySelector('[data-aksrt-charge-modal]');
|
var modal = firstIn(scope, '[data-aksrt-charge-modal]');
|
||||||
if (!modal || modal.dataset.aksrtChargeInitialized === '1') return;
|
if (!modal || modal.dataset.aksrtChargeInitialized === '1') return;
|
||||||
modal.dataset.aksrtChargeInitialized = '1';
|
modal.dataset.aksrtChargeInitialized = '1';
|
||||||
var form = modal.querySelector('[data-aksrt-charge-form]');
|
var form = modal.querySelector('[data-aksrt-charge-form]');
|
||||||
@@ -458,8 +481,8 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initTransfer() {
|
function initTransfer(scope) {
|
||||||
var modal = document.querySelector('[data-aksrt-transfer-modal]');
|
var modal = firstIn(scope, '[data-aksrt-transfer-modal]');
|
||||||
if (!modal || modal.dataset.aksrtTransferInitialized === '1') return;
|
if (!modal || modal.dataset.aksrtTransferInitialized === '1') return;
|
||||||
modal.dataset.aksrtTransferInitialized = '1';
|
modal.dataset.aksrtTransferInitialized = '1';
|
||||||
var form = modal.querySelector('[data-aksrt-transfer-form]');
|
var form = modal.querySelector('[data-aksrt-transfer-form]');
|
||||||
@@ -590,8 +613,8 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initPointsExchange() {
|
function initPointsExchange(scope) {
|
||||||
var modal = document.querySelector('[data-aksrt-points-exchange-modal]');
|
var modal = firstIn(scope, '[data-aksrt-points-exchange-modal]');
|
||||||
if (!modal || modal.dataset.aksrtPointsExchangeInitialized === '1') return;
|
if (!modal || modal.dataset.aksrtPointsExchangeInitialized === '1') return;
|
||||||
modal.dataset.aksrtPointsExchangeInitialized = '1';
|
modal.dataset.aksrtPointsExchangeInitialized = '1';
|
||||||
var form = modal.querySelector('[data-aksrt-points-exchange-form]');
|
var form = modal.querySelector('[data-aksrt-points-exchange-form]');
|
||||||
@@ -650,8 +673,8 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initWithdraw() {
|
function initWithdraw(scope) {
|
||||||
var modal = document.querySelector('[data-aksrt-withdraw-modal]');
|
var modal = firstIn(scope, '[data-aksrt-withdraw-modal]');
|
||||||
if (!modal || modal.dataset.aksrtWithdrawInitialized === '1') return;
|
if (!modal || modal.dataset.aksrtWithdrawInitialized === '1') return;
|
||||||
modal.dataset.aksrtWithdrawInitialized = '1';
|
modal.dataset.aksrtWithdrawInitialized = '1';
|
||||||
var form = modal.querySelector('[data-aksrt-withdraw-form]');
|
var form = modal.querySelector('[data-aksrt-withdraw-form]');
|
||||||
@@ -735,27 +758,28 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initAssetTabs() {
|
function initAssetTabs(root) {
|
||||||
var nav = document.querySelectorAll('[data-aksrt-asset-tab]');
|
var nav = elementsIn(root, '[data-aksrt-asset-tab]');
|
||||||
if (!nav.length) return;
|
if (!nav.length) return;
|
||||||
|
var scope = root || document;
|
||||||
nav.forEach(function (link) {
|
nav.forEach(function (link) {
|
||||||
if (link.dataset.aksrtAssetTabBound === 'true') return;
|
if (link.dataset.aksrtAssetTabBound === 'true') return;
|
||||||
link.dataset.aksrtAssetTabBound = 'true';
|
link.dataset.aksrtAssetTabBound = 'true';
|
||||||
link.addEventListener('click', function (e) {
|
link.addEventListener('click', function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var key = link.getAttribute('data-aksrt-asset-tab');
|
var key = link.getAttribute('data-aksrt-asset-tab');
|
||||||
document.querySelectorAll('.uc-asset-tabs__nav [data-aksrt-asset-tab]').forEach(function (a) {
|
elementsIn(scope, '[data-aksrt-asset-tab]').forEach(function (a) {
|
||||||
var li = a.closest('li');
|
var li = a.closest('li');
|
||||||
if (!li) return;
|
if (!li) return;
|
||||||
var aKey = a.getAttribute('data-aksrt-asset-tab');
|
var aKey = a.getAttribute('data-aksrt-asset-tab');
|
||||||
var on = aKey === key || (key === 'points_date' && aKey === 'points_free');
|
var on = aKey === key || (key === 'points_date' && aKey === 'points_free');
|
||||||
li.classList.toggle('active', on);
|
li.classList.toggle('active', on);
|
||||||
});
|
});
|
||||||
var tabs = document.querySelector('.uc-asset-tabs');
|
var tabs = firstIn(scope, '.uc-asset-tabs');
|
||||||
if (tabs && typeof tabs.scrollIntoView === 'function') {
|
if (tabs && typeof tabs.scrollIntoView === 'function') {
|
||||||
tabs.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
tabs.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||||
}
|
}
|
||||||
document.querySelectorAll('[data-aksrt-asset-pane]').forEach(function (pane) {
|
elementsIn(scope, '[data-aksrt-asset-pane]').forEach(function (pane) {
|
||||||
var on = pane.getAttribute('data-aksrt-asset-pane') === key;
|
var on = pane.getAttribute('data-aksrt-asset-pane') === key;
|
||||||
pane.classList.toggle('is-active', on);
|
pane.classList.toggle('is-active', on);
|
||||||
pane.hidden = !on;
|
pane.hidden = !on;
|
||||||
@@ -765,8 +789,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function initWithdrawHistory() {
|
function initWithdrawHistory(scope) {
|
||||||
var modal = document.querySelector('[data-aksrt-withdraw-history-modal]');
|
var modal = firstIn(scope, '[data-aksrt-withdraw-history-modal]');
|
||||||
if (!modal || modal.dataset.aksrtWithdrawHistoryInitialized === '1') return;
|
if (!modal || modal.dataset.aksrtWithdrawHistoryInitialized === '1') return;
|
||||||
modal.dataset.aksrtWithdrawHistoryInitialized = '1';
|
modal.dataset.aksrtWithdrawHistoryInitialized = '1';
|
||||||
function open() { modal.hidden = false; document.body.classList.add('uc-modal-open'); }
|
function open() { modal.hidden = false; document.body.classList.add('uc-modal-open'); }
|
||||||
@@ -785,36 +809,25 @@
|
|||||||
refresh: refreshAssetBalances
|
refresh: refreshAssetBalances
|
||||||
};
|
};
|
||||||
|
|
||||||
function bootAssets() {
|
function bootAssets(root, reason) {
|
||||||
refreshAssetBalances();
|
if (!balancesRefreshed && reason === 'init') {
|
||||||
initSigninGoto();
|
balancesRefreshed = true;
|
||||||
initAffiliateRevenue();
|
refreshAssetBalances();
|
||||||
initVipShop();
|
}
|
||||||
initVipPointsExchange();
|
initSigninGoto(root);
|
||||||
initCardPass();
|
initAffiliateRevenue(root);
|
||||||
initBalanceCharge();
|
initVipShop(root);
|
||||||
initTransfer();
|
initVipPointsExchange(root);
|
||||||
initPointsExchange();
|
initCardPass(root);
|
||||||
initWithdraw();
|
initBalanceCharge(root);
|
||||||
initWithdrawHistory();
|
initTransfer(root);
|
||||||
initAssetTabs();
|
initPointsExchange(root);
|
||||||
}
|
initWithdraw(root);
|
||||||
|
initWithdrawHistory(root);
|
||||||
if (document.readyState === 'loading') {
|
initAssetTabs(root);
|
||||||
document.addEventListener('DOMContentLoaded', bootAssets);
|
|
||||||
} else {
|
|
||||||
bootAssets();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
|
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
|
||||||
window.AksrtFrontend.register('credits', function () {
|
window.AksrtFrontend.register('credits', bootAssets);
|
||||||
initSigninGoto();
|
|
||||||
initBalanceCharge();
|
|
||||||
initTransfer();
|
|
||||||
initPointsExchange();
|
|
||||||
initWithdraw();
|
|
||||||
initWithdrawHistory();
|
|
||||||
initAssetTabs();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -18,9 +18,12 @@
|
|||||||
searchInput: null,
|
searchInput: null,
|
||||||
items: [],
|
items: [],
|
||||||
|
|
||||||
init: function () {
|
init: function (root) {
|
||||||
this.sidebar = document.querySelector('.aksrt-doc-sidebar');
|
root = root || document;
|
||||||
if (!this.sidebar) return;
|
this.sidebar = root.nodeType === 1 && root.matches('.aksrt-doc-sidebar')
|
||||||
|
? root : root.querySelector('.aksrt-doc-sidebar');
|
||||||
|
if (!this.sidebar || this.sidebar.dataset.aksrtDocsNavBound === '1') return;
|
||||||
|
this.sidebar.dataset.aksrtDocsNavBound = '1';
|
||||||
|
|
||||||
this.items = Array.from(this.sidebar.querySelectorAll('.aksrt-doc-sidebar__item'));
|
this.items = Array.from(this.sidebar.querySelectorAll('.aksrt-doc-sidebar__item'));
|
||||||
this.searchInput = this.sidebar.querySelector('.aksrt-doc-sidebar__search-input');
|
this.searchInput = this.sidebar.querySelector('.aksrt-doc-sidebar__search-input');
|
||||||
@@ -129,9 +132,7 @@
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
window.AksrtFrontend.register('aksrt-docs-navigation', function (root) {
|
||||||
document.addEventListener('DOMContentLoaded', function () { DocsNav.init(); });
|
DocsNav.init(root);
|
||||||
} else {
|
});
|
||||||
DocsNav.init();
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var DownloadStatus = {
|
var DownloadStatus = {
|
||||||
init: function () {
|
init: function (root) {
|
||||||
|
this.root = root || document;
|
||||||
this.initFilterHighlight();
|
this.initFilterHighlight();
|
||||||
this.initCardHover();
|
this.initCardHover();
|
||||||
},
|
},
|
||||||
@@ -22,10 +23,13 @@
|
|||||||
* Animate filter button active state
|
* Animate filter button active state
|
||||||
*/
|
*/
|
||||||
initFilterHighlight: function () {
|
initFilterHighlight: function () {
|
||||||
var filters = document.querySelectorAll('.aksrt-download-hero__filter');
|
var filters = this.root.nodeType === 1 && this.root.matches('.aksrt-download-hero__filter')
|
||||||
|
? [this.root] : this.root.querySelectorAll('.aksrt-download-hero__filter');
|
||||||
if (filters.length === 0) return;
|
if (filters.length === 0) return;
|
||||||
|
|
||||||
filters.forEach(function (btn) {
|
filters.forEach(function (btn) {
|
||||||
|
if (btn.dataset.aksrtDownloadHoverBound === '1') return;
|
||||||
|
btn.dataset.aksrtDownloadHoverBound = '1';
|
||||||
btn.addEventListener('mouseenter', function () {
|
btn.addEventListener('mouseenter', function () {
|
||||||
btn.style.transform = 'translateY(-1px)';
|
btn.style.transform = 'translateY(-1px)';
|
||||||
});
|
});
|
||||||
@@ -39,10 +43,13 @@
|
|||||||
* Card hover depth effect
|
* Card hover depth effect
|
||||||
*/
|
*/
|
||||||
initCardHover: function () {
|
initCardHover: function () {
|
||||||
var cards = document.querySelectorAll('.aksrt-download-card');
|
var cards = this.root.nodeType === 1 && this.root.matches('.aksrt-download-card')
|
||||||
|
? [this.root] : this.root.querySelectorAll('.aksrt-download-card');
|
||||||
if (cards.length === 0) return;
|
if (cards.length === 0) return;
|
||||||
|
|
||||||
cards.forEach(function (card) {
|
cards.forEach(function (card) {
|
||||||
|
if (card.dataset.aksrtDownloadHoverBound === '1') return;
|
||||||
|
card.dataset.aksrtDownloadHoverBound = '1';
|
||||||
card.addEventListener('mouseenter', function () {
|
card.addEventListener('mouseenter', function () {
|
||||||
card.style.transform = 'translateY(-2px)';
|
card.style.transform = 'translateY(-2px)';
|
||||||
});
|
});
|
||||||
@@ -53,9 +60,7 @@
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
window.AksrtFrontend.register('aksrt-download-status', function (root) {
|
||||||
document.addEventListener('DOMContentLoaded', function () { DownloadStatus.init(); });
|
DownloadStatus.init(root);
|
||||||
} else {
|
});
|
||||||
DownloadStatus.init();
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
Vendored
+91
-114
@@ -10,108 +10,101 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var reducedMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
var reducedMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||||
|
var countUpObserver = null;
|
||||||
|
var countdownElements = [];
|
||||||
|
var countdownTimer = null;
|
||||||
|
var fpsDetectionStarted = false;
|
||||||
|
|
||||||
/* ============================================================
|
function scopeFor(root) {
|
||||||
* 1. 数字递增 (count-up) — IntersectionObserver 触发
|
return root && root.querySelectorAll ? root : document;
|
||||||
* 用法:<span data-aksrt-countup data-target="1234" data-duration="2000">0</span>
|
}
|
||||||
* ============================================================ */
|
|
||||||
function initCountUp() {
|
|
||||||
if (reducedMotion) return;
|
|
||||||
if (!('IntersectionObserver' in window)) return;
|
|
||||||
|
|
||||||
var els = document.querySelectorAll('[data-aksrt-countup]');
|
function eachMatch(root, selector, callback) {
|
||||||
if (!els.length) return;
|
var scope = scopeFor(root);
|
||||||
|
if (scope.nodeType === 1 && scope.matches(selector)) callback(scope);
|
||||||
|
scope.querySelectorAll(selector).forEach(callback);
|
||||||
|
}
|
||||||
|
|
||||||
var observer = new IntersectionObserver(function (entries) {
|
function animateCountUp(el) {
|
||||||
entries.forEach(function (entry) {
|
if (el.dataset.aksrtCountupBound === '1') return;
|
||||||
if (!entry.isIntersecting) return;
|
el.dataset.aksrtCountupBound = '1';
|
||||||
var el = entry.target;
|
countUpObserver.observe(el);
|
||||||
observer.unobserve(el);
|
}
|
||||||
|
|
||||||
var target = parseFloat(el.dataset.target || '0');
|
function initCountUp(root) {
|
||||||
var duration = parseInt(el.dataset.duration || '2000', 10);
|
if (reducedMotion || !('IntersectionObserver' in window)) return;
|
||||||
var decimals = (el.dataset.decimals || '0|').split('|');
|
if (!countUpObserver) {
|
||||||
var prefix = decimals[1] || '';
|
countUpObserver = new IntersectionObserver(function (entries) {
|
||||||
var dec = parseInt(decimals[0], 10) || 0;
|
entries.forEach(function (entry) {
|
||||||
var start = 0;
|
if (!entry.isIntersecting) return;
|
||||||
var startTime = null;
|
var el = entry.target;
|
||||||
|
countUpObserver.unobserve(el);
|
||||||
|
var target = parseFloat(el.dataset.target || '0');
|
||||||
|
var duration = parseInt(el.dataset.duration || '2000', 10);
|
||||||
|
var decimals = (el.dataset.decimals || '0|').split('|');
|
||||||
|
var prefix = decimals[1] || '';
|
||||||
|
var dec = parseInt(decimals[0], 10) || 0;
|
||||||
|
var startTime = null;
|
||||||
|
|
||||||
function step(timestamp) {
|
function step(timestamp) {
|
||||||
if (!startTime) startTime = timestamp;
|
if (!startTime) startTime = timestamp;
|
||||||
var progress = Math.min((timestamp - startTime) / duration, 1);
|
var progress = Math.min((timestamp - startTime) / duration, 1);
|
||||||
// ease-out cubic
|
var current = target * (1 - Math.pow(1 - progress, 3));
|
||||||
var eased = 1 - Math.pow(1 - progress, 3);
|
el.textContent = prefix + current.toFixed(dec).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||||
var current = start + (target - start) * eased;
|
if (progress < 1) requestAnimationFrame(step);
|
||||||
el.textContent = prefix + current.toFixed(dec).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
else el.textContent = prefix + target.toFixed(dec).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||||
if (progress < 1) {
|
|
||||||
requestAnimationFrame(step);
|
|
||||||
} else {
|
|
||||||
el.textContent = prefix + target.toFixed(dec).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
requestAnimationFrame(step);
|
requestAnimationFrame(step);
|
||||||
});
|
});
|
||||||
}, { threshold: 0.3 });
|
}, { threshold: 0.3 });
|
||||||
|
|
||||||
els.forEach(function (el) { observer.observe(el); });
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================
|
|
||||||
* 2. 倒计时组件
|
|
||||||
* 用法:<span data-aksrt-countdown data-end="2026-12-31T23:59:59">--:--:--</span>
|
|
||||||
* ============================================================ */
|
|
||||||
function initCountdown() {
|
|
||||||
var els = document.querySelectorAll('[data-aksrt-countdown]');
|
|
||||||
if (!els.length) return;
|
|
||||||
|
|
||||||
function pad(n) { return n < 10 ? '0' + n : '' + n; }
|
|
||||||
|
|
||||||
function update() {
|
|
||||||
var now = Date.now();
|
|
||||||
els.forEach(function (el) {
|
|
||||||
var end = new Date(el.dataset.end).getTime();
|
|
||||||
var diff = end - now;
|
|
||||||
if (diff <= 0) {
|
|
||||||
el.textContent = el.dataset.expired || '已结束';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var d = Math.floor(diff / 86400000);
|
|
||||||
var h = Math.floor((diff % 86400000) / 3600000);
|
|
||||||
var m = Math.floor((diff % 3600000) / 60000);
|
|
||||||
var s = Math.floor((diff % 60000) / 1000);
|
|
||||||
var format = el.dataset.format || 'dhms';
|
|
||||||
if (format === 'dhms') {
|
|
||||||
el.textContent = (d > 0 ? d + '天 ' : '') + pad(h) + ':' + pad(m) + ':' + pad(s);
|
|
||||||
} else if (format === 'hms') {
|
|
||||||
el.textContent = pad(h + d * 24) + ':' + pad(m) + ':' + pad(s);
|
|
||||||
} else {
|
|
||||||
el.textContent = (d > 0 ? d + '天 ' : '') + pad(h) + '时' + pad(m) + '分' + pad(s) + '秒';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
eachMatch(root, '[data-aksrt-countup]', animateCountUp);
|
||||||
update();
|
|
||||||
setInterval(update, 1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================
|
function pad(n) { return n < 10 ? '0' + n : '' + n; }
|
||||||
* 4. 3D 悬停倾斜 (vanilla tilt)
|
|
||||||
* 用法:<div data-aksrt-tilt data-tilt-max="15">...</div>
|
|
||||||
* ============================================================ */
|
|
||||||
function initTilt() {
|
|
||||||
if (reducedMotion) return;
|
|
||||||
|
|
||||||
document.querySelectorAll('[data-aksrt-tilt]').forEach(function (el) {
|
function updateCountdowns() {
|
||||||
|
var now = Date.now();
|
||||||
|
countdownElements = countdownElements.filter(function (el) { return document.documentElement.contains(el); });
|
||||||
|
countdownElements.forEach(function (el) {
|
||||||
|
var end = new Date(el.dataset.end).getTime();
|
||||||
|
var diff = end - now;
|
||||||
|
if (diff <= 0) {
|
||||||
|
el.textContent = el.dataset.expired || '已结束';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var d = Math.floor(diff / 86400000);
|
||||||
|
var h = Math.floor((diff % 86400000) / 3600000);
|
||||||
|
var m = Math.floor((diff % 3600000) / 60000);
|
||||||
|
var s = Math.floor((diff % 60000) / 1000);
|
||||||
|
var format = el.dataset.format || 'dhms';
|
||||||
|
if (format === 'dhms') el.textContent = (d > 0 ? d + '天 ' : '') + pad(h) + ':' + pad(m) + ':' + pad(s);
|
||||||
|
else if (format === 'hms') el.textContent = pad(h + d * 24) + ':' + pad(m) + ':' + pad(s);
|
||||||
|
else el.textContent = (d > 0 ? d + '天 ' : '') + pad(h) + '时' + pad(m) + '分' + pad(s) + '秒';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function initCountdown(root) {
|
||||||
|
eachMatch(root, '[data-aksrt-countdown]', function (el) {
|
||||||
|
if (el.dataset.aksrtCountdownBound === '1') return;
|
||||||
|
el.dataset.aksrtCountdownBound = '1';
|
||||||
|
countdownElements.push(el);
|
||||||
|
});
|
||||||
|
updateCountdowns();
|
||||||
|
if (!countdownTimer && countdownElements.length) countdownTimer = window.setInterval(updateCountdowns, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initTilt(root) {
|
||||||
|
if (reducedMotion) return;
|
||||||
|
eachMatch(root, '[data-aksrt-tilt]', function (el) {
|
||||||
if (el.dataset.tiltBound) return;
|
if (el.dataset.tiltBound) return;
|
||||||
el.dataset.tiltBound = '1';
|
el.dataset.tiltBound = '1';
|
||||||
|
|
||||||
var maxDeg = parseFloat(el.dataset.tiltMax || '10');
|
var maxDeg = parseFloat(el.dataset.tiltMax || '10');
|
||||||
var perspective = parseFloat(el.dataset.tiltPerspective || '800');
|
var perspective = parseFloat(el.dataset.tiltPerspective || '800');
|
||||||
var scale = parseFloat(el.dataset.tiltScale || '1.03');
|
var scale = parseFloat(el.dataset.tiltScale || '1.03');
|
||||||
var glare = el.dataset.tiltGlare === '1';
|
var glare = el.dataset.tiltGlare === '1';
|
||||||
var glareEl = null;
|
var glareEl = null;
|
||||||
|
|
||||||
if (glare) {
|
if (glare) {
|
||||||
glareEl = document.createElement('div');
|
glareEl = document.createElement('div');
|
||||||
glareEl.style.cssText = 'position:absolute;inset:0;border-radius:inherit;pointer-events:none;background:linear-gradient(135deg,rgba(255,255,255,0) 0%,rgba(255,255,255,0.25) 100%);opacity:0;transition:opacity 0.2s;';
|
glareEl.style.cssText = 'position:absolute;inset:0;border-radius:inherit;pointer-events:none;background:linear-gradient(135deg,rgba(255,255,255,0) 0%,rgba(255,255,255,0.25) 100%);opacity:0;transition:opacity 0.2s;';
|
||||||
@@ -119,17 +112,13 @@
|
|||||||
el.style.overflow = 'hidden';
|
el.style.overflow = 'hidden';
|
||||||
el.appendChild(glareEl);
|
el.appendChild(glareEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
el.addEventListener('mousemove', function (e) {
|
el.addEventListener('mousemove', function (e) {
|
||||||
var rect = el.getBoundingClientRect();
|
var rect = el.getBoundingClientRect();
|
||||||
var x = (e.clientX - rect.left) / rect.width;
|
var x = (e.clientX - rect.left) / rect.width;
|
||||||
var y = (e.clientY - rect.top) / rect.height;
|
var y = (e.clientY - rect.top) / rect.height;
|
||||||
var rotateX = (0.5 - y) * maxDeg;
|
el.style.transform = 'perspective(' + perspective + 'px) rotateX(' + ((0.5 - y) * maxDeg) + 'deg) rotateY(' + ((x - 0.5) * maxDeg) + 'deg) scale3d(' + scale + ',' + scale + ',' + scale + ')';
|
||||||
var rotateY = (x - 0.5) * maxDeg;
|
|
||||||
el.style.transform = 'perspective(' + perspective + 'px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg) scale3d(' + scale + ',' + scale + ',' + scale + ')';
|
|
||||||
if (glareEl) glareEl.style.opacity = '1';
|
if (glareEl) glareEl.style.opacity = '1';
|
||||||
});
|
});
|
||||||
|
|
||||||
el.addEventListener('mouseleave', function () {
|
el.addEventListener('mouseleave', function () {
|
||||||
el.style.transform = 'perspective(' + perspective + 'px) rotateX(0deg) rotateY(0deg) scale3d(1,1,1)';
|
el.style.transform = 'perspective(' + perspective + 'px) rotateX(0deg) rotateY(0deg) scale3d(1,1,1)';
|
||||||
if (glareEl) glareEl.style.opacity = '0';
|
if (glareEl) glareEl.style.opacity = '0';
|
||||||
@@ -137,42 +126,30 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================
|
function initFpsDetection(root, reason) {
|
||||||
* 5. FPS 检测 + 低端设备降级
|
if (fpsDetectionStarted || !('requestAnimationFrame' in window)) return;
|
||||||
* ============================================================ */
|
fpsDetectionStarted = true;
|
||||||
function initFpsDetection() {
|
|
||||||
if (!('requestAnimationFrame' in window)) return;
|
|
||||||
|
|
||||||
var frames = 0;
|
var frames = 0;
|
||||||
var startTime = performance.now();
|
var startTime = performance.now();
|
||||||
|
|
||||||
function countFrames() {
|
function countFrames() {
|
||||||
frames++;
|
frames++;
|
||||||
var elapsed = performance.now() - startTime;
|
var elapsed = performance.now() - startTime;
|
||||||
if (elapsed >= 1000) {
|
if (elapsed >= 1000) {
|
||||||
var fps = Math.round(frames * 1000 / elapsed);
|
if (Math.round(frames * 1000 / elapsed) < 24 && document.body) document.body.classList.add('fps-accelerat');
|
||||||
if (fps < 24) {
|
return;
|
||||||
document.body.classList.add('fps-accelerat');
|
|
||||||
}
|
|
||||||
return; // 只检测一次
|
|
||||||
}
|
}
|
||||||
requestAnimationFrame(countFrames);
|
requestAnimationFrame(countFrames);
|
||||||
}
|
}
|
||||||
|
|
||||||
requestAnimationFrame(countFrames);
|
requestAnimationFrame(countFrames);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================
|
function init(root, reason) {
|
||||||
* 初始化入口
|
initCountUp(root);
|
||||||
* ============================================================ */
|
initCountdown(root);
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
if (typeof initMarquee === 'function') initMarquee(root, reason);
|
||||||
initCountUp();
|
initTilt(root);
|
||||||
initCountdown();
|
initFpsDetection(root, reason);
|
||||||
if (typeof initMarquee === 'function') {
|
}
|
||||||
initMarquee();
|
|
||||||
}
|
|
||||||
initTilt();
|
|
||||||
initFpsDetection();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
window.AksrtFrontend.register('aksrt-effects', init);
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
var isAutoplay = false;
|
var isAutoplay = false;
|
||||||
var lastTrigger = null;
|
var lastTrigger = null;
|
||||||
var previousBodyOverflow = '';
|
var previousBodyOverflow = '';
|
||||||
|
var globalsBound = false;
|
||||||
|
var scrollDirectionBound = false;
|
||||||
var EXCLUDE_SEL = '.no-imgbox,.no-lightbox,.avatar,.img-icon,.avatar-badge,.aksrt-avatar,[data-no-lightbox],[data-aksrt-lightbox="0"]';
|
var EXCLUDE_SEL = '.no-imgbox,.no-lightbox,.avatar,.img-icon,.avatar-badge,.aksrt-avatar,[data-no-lightbox],[data-aksrt-lightbox="0"]';
|
||||||
var TRIGGER_SEL = '[data-aksrt-lightbox="1"] img,.aksrt-lightbox-trigger img,.imgbox-container img,.comment-content .box-img';
|
var TRIGGER_SEL = '[data-aksrt-lightbox="1"] img,.aksrt-lightbox-trigger img,.imgbox-container img,.comment-content .box-img';
|
||||||
var ANCHOR_TRIGGER_SEL = 'a[data-aksrt-lightbox-trigger]';
|
var ANCHOR_TRIGGER_SEL = 'a[data-aksrt-lightbox-trigger]';
|
||||||
@@ -496,7 +498,9 @@
|
|||||||
return openLightbox(item.fullSrc, item.caption, gallery.items, gallery.index, img);
|
return openLightbox(item.fullSrc, item.caption, gallery.items, gallery.index, img);
|
||||||
}
|
}
|
||||||
|
|
||||||
function initLightbox() {
|
function initLightbox(root, reason) {
|
||||||
|
if (globalsBound) return;
|
||||||
|
globalsBound = true;
|
||||||
document.addEventListener('click', function (event) {
|
document.addEventListener('click', function (event) {
|
||||||
if (!lightboxEnabled() || !(event.target instanceof Element)) return;
|
if (!lightboxEnabled() || !(event.target instanceof Element)) return;
|
||||||
|
|
||||||
@@ -527,7 +531,9 @@
|
|||||||
|
|
||||||
// Scroll direction is handled by aksrt-runtime.js. Keep the prefixed
|
// Scroll direction is handled by aksrt-runtime.js. Keep the prefixed
|
||||||
// classes in sync for the remaining CSS consumers.
|
// classes in sync for the remaining CSS consumers.
|
||||||
function initScrollDirection() {
|
function initScrollDirection(root, reason) {
|
||||||
|
if (scrollDirectionBound || !document.body) return;
|
||||||
|
scrollDirectionBound = true;
|
||||||
var body = document.body;
|
var body = document.body;
|
||||||
|
|
||||||
function sync() {
|
function sync() {
|
||||||
@@ -547,8 +553,8 @@
|
|||||||
}, { passive: true });
|
}, { passive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
window.AksrtFrontend.register('aksrt-enhancements', function (root, reason) {
|
||||||
initLightbox();
|
initLightbox(root, reason);
|
||||||
initScrollDirection();
|
initScrollDirection(root, reason);
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|||||||
+164
-194
@@ -9,11 +9,27 @@
|
|||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/* ============================================================
|
var animateObserver = null;
|
||||||
* 1. 3D 悬停倾斜效果 (vanilla-tilt 轻量版)
|
var rippleBound = false;
|
||||||
* ============================================================ */
|
var stickyScrollBound = false;
|
||||||
function initTilt() {
|
var parallaxScrollBound = false;
|
||||||
document.querySelectorAll('[data-aksrt-tilt]').forEach(function (el) {
|
var modalBound = false;
|
||||||
|
var stickyElements = [];
|
||||||
|
var parallaxElements = [];
|
||||||
|
var parallaxTicking = false;
|
||||||
|
|
||||||
|
function scopeFor(root) {
|
||||||
|
return root && root.querySelectorAll ? root : document;
|
||||||
|
}
|
||||||
|
|
||||||
|
function eachMatch(root, selector, callback) {
|
||||||
|
var scope = scopeFor(root);
|
||||||
|
if (scope.nodeType === 1 && scope.matches(selector)) callback(scope);
|
||||||
|
scope.querySelectorAll(selector).forEach(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initTilt(root) {
|
||||||
|
eachMatch(root, '[data-aksrt-tilt]', function (el) {
|
||||||
if (el.dataset.tiltInit) return;
|
if (el.dataset.tiltInit) return;
|
||||||
el.dataset.tiltInit = '1';
|
el.dataset.tiltInit = '1';
|
||||||
|
|
||||||
@@ -58,230 +74,184 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================
|
function prepareAnimation(el) {
|
||||||
* 2. 滚动触发动画 (IntersectionObserver)
|
if (el.dataset.aksrtAnimateBound === '1') return;
|
||||||
* ============================================================ */
|
el.dataset.aksrtAnimateBound = '1';
|
||||||
function initScrollAnimations() {
|
var animation = el.dataset.aksrtAnimate || 'fadeInUp';
|
||||||
|
el.style.opacity = '0';
|
||||||
|
switch (animation) {
|
||||||
|
case 'fadeIn': el.style.transform = 'none'; break;
|
||||||
|
case 'fadeInUp': el.style.transform = 'translateY(30px)'; break;
|
||||||
|
case 'fadeInDown': el.style.transform = 'translateY(-30px)'; break;
|
||||||
|
case 'fadeInLeft': el.style.transform = 'translateX(-30px)'; break;
|
||||||
|
case 'fadeInRight': el.style.transform = 'translateX(30px)'; break;
|
||||||
|
case 'zoomIn': el.style.transform = 'scale(0.9)'; break;
|
||||||
|
default: el.style.transform = 'translateY(30px)';
|
||||||
|
}
|
||||||
|
animateObserver.observe(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initScrollAnimations(root) {
|
||||||
if (!('IntersectionObserver' in window)) {
|
if (!('IntersectionObserver' in window)) {
|
||||||
// 不支持时直接显示所有元素
|
eachMatch(root, '[data-aksrt-animate]', function (el) {
|
||||||
document.querySelectorAll('[data-aksrt-animate]').forEach(function (el) {
|
|
||||||
el.style.opacity = '1';
|
el.style.opacity = '1';
|
||||||
el.style.transform = 'none';
|
el.style.transform = 'none';
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var observer = new IntersectionObserver(function (entries) {
|
if (!animateObserver) {
|
||||||
entries.forEach(function (entry) {
|
animateObserver = new IntersectionObserver(function (entries) {
|
||||||
if (!entry.isIntersecting) return;
|
entries.forEach(function (entry) {
|
||||||
|
if (!entry.isIntersecting) return;
|
||||||
var el = entry.target;
|
var el = entry.target;
|
||||||
var animation = el.dataset.aksrtAnimate || 'fadeInUp';
|
var delay = parseInt(el.dataset.aksrtAnimateDelay || '0', 10);
|
||||||
var delay = parseInt(el.dataset.aksrtAnimateDelay || '0', 10);
|
var duration = parseInt(el.dataset.aksrtAnimateDuration || '600', 10);
|
||||||
var duration = parseInt(el.dataset.aksrtAnimateDuration || '600', 10);
|
animateObserver.unobserve(el);
|
||||||
|
window.setTimeout(function () {
|
||||||
setTimeout(function () {
|
el.style.transition = 'opacity ' + duration + 'ms ease, transform ' + duration + 'ms ease';
|
||||||
el.style.transition = 'opacity ' + duration + 'ms ease, transform ' + duration + 'ms ease';
|
el.style.opacity = '1';
|
||||||
el.style.opacity = '1';
|
el.style.transform = 'translateY(0) translateX(0) scale(1)';
|
||||||
el.style.transform = 'translateY(0) translateX(0) scale(1)';
|
el.classList.add('aksrt-animated');
|
||||||
el.classList.add('aksrt-animated');
|
}, delay);
|
||||||
}, delay);
|
});
|
||||||
|
}, { threshold: 0.1, rootMargin: '0px 0px -50px 0px' });
|
||||||
observer.unobserve(el);
|
|
||||||
});
|
|
||||||
}, {
|
|
||||||
threshold: 0.1,
|
|
||||||
rootMargin: '0px 0px -50px 0px',
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelectorAll('[data-aksrt-animate]').forEach(function (el) {
|
|
||||||
var animation = el.dataset.aksrtAnimate || 'fadeInUp';
|
|
||||||
|
|
||||||
// 设置初始状态
|
|
||||||
el.style.opacity = '0';
|
|
||||||
switch (animation) {
|
|
||||||
case 'fadeIn':
|
|
||||||
el.style.transform = 'none';
|
|
||||||
break;
|
|
||||||
case 'fadeInUp':
|
|
||||||
el.style.transform = 'translateY(30px)';
|
|
||||||
break;
|
|
||||||
case 'fadeInDown':
|
|
||||||
el.style.transform = 'translateY(-30px)';
|
|
||||||
break;
|
|
||||||
case 'fadeInLeft':
|
|
||||||
el.style.transform = 'translateX(-30px)';
|
|
||||||
break;
|
|
||||||
case 'fadeInRight':
|
|
||||||
el.style.transform = 'translateX(30px)';
|
|
||||||
break;
|
|
||||||
case 'zoomIn':
|
|
||||||
el.style.transform = 'scale(0.9)';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
el.style.transform = 'translateY(30px)';
|
|
||||||
}
|
|
||||||
|
|
||||||
observer.observe(el);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================
|
|
||||||
* 5. 粘性元素 (Sticky)
|
|
||||||
* ============================================================ */
|
|
||||||
function initSticky() {
|
|
||||||
document.querySelectorAll('[data-aksrt-sticky]').forEach(function (el) {
|
|
||||||
var top = parseInt(el.dataset.aksrtStickyTop || '80', 10);
|
|
||||||
var offset = parseInt(el.dataset.aksrtStickyOffset || '0', 10);
|
|
||||||
|
|
||||||
function update() {
|
|
||||||
var rect = el.getBoundingClientRect();
|
|
||||||
var parentRect = el.parentElement.getBoundingClientRect();
|
|
||||||
|
|
||||||
if (parentRect.top < top && parentRect.bottom > el.offsetHeight + top) {
|
|
||||||
el.style.position = 'sticky';
|
|
||||||
el.style.top = top + 'px';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('scroll', update, { passive: true });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================
|
|
||||||
* 6. 视差滚动
|
|
||||||
* ============================================================ */
|
|
||||||
function initParallax() {
|
|
||||||
var elements = document.querySelectorAll('[data-aksrt-parallax]');
|
|
||||||
if (elements.length === 0) return;
|
|
||||||
|
|
||||||
var ticking = false;
|
|
||||||
|
|
||||||
function update() {
|
|
||||||
var scrollTop = window.pageYOffset;
|
|
||||||
elements.forEach(function (el) {
|
|
||||||
var speed = parseFloat(el.dataset.aksrtParallax || '0.3');
|
|
||||||
var rect = el.getBoundingClientRect();
|
|
||||||
var center = rect.top + rect.height / 2;
|
|
||||||
var windowCenter = window.innerHeight / 2;
|
|
||||||
var offset = (center - windowCenter) * speed;
|
|
||||||
|
|
||||||
el.style.transform = 'translateY(' + offset + 'px)';
|
|
||||||
});
|
|
||||||
ticking = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener('scroll', function () {
|
eachMatch(root, '[data-aksrt-animate]', prepareAnimation);
|
||||||
if (!ticking) {
|
|
||||||
requestAnimationFrame(update);
|
|
||||||
ticking = true;
|
|
||||||
}
|
|
||||||
}, { passive: true });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================
|
function updateSticky() {
|
||||||
* 7. 涟漪点击效果
|
stickyElements = stickyElements.filter(function (el) { return document.documentElement.contains(el); });
|
||||||
* ============================================================ */
|
stickyElements.forEach(function (el) {
|
||||||
function initRipple() {
|
var top = parseInt(el.dataset.aksrtStickyTop || '80', 10);
|
||||||
|
var parent = el.parentElement;
|
||||||
|
if (!parent) return;
|
||||||
|
var parentRect = parent.getBoundingClientRect();
|
||||||
|
if (parentRect.top < top && parentRect.bottom > el.offsetHeight + top) {
|
||||||
|
el.style.position = 'sticky';
|
||||||
|
el.style.top = top + 'px';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function initSticky(root) {
|
||||||
|
eachMatch(root, '[data-aksrt-sticky]', function (el) {
|
||||||
|
if (el.dataset.aksrtStickyBound === '1') return;
|
||||||
|
el.dataset.aksrtStickyBound = '1';
|
||||||
|
stickyElements.push(el);
|
||||||
|
});
|
||||||
|
if (!stickyScrollBound) {
|
||||||
|
stickyScrollBound = true;
|
||||||
|
window.addEventListener('scroll', updateSticky, { passive: true });
|
||||||
|
}
|
||||||
|
updateSticky();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateParallax() {
|
||||||
|
parallaxElements = parallaxElements.filter(function (el) { return document.documentElement.contains(el); });
|
||||||
|
parallaxElements.forEach(function (el) {
|
||||||
|
var speed = parseFloat(el.dataset.aksrtParallax || '0.3');
|
||||||
|
var rect = el.getBoundingClientRect();
|
||||||
|
var center = rect.top + rect.height / 2;
|
||||||
|
var offset = (center - window.innerHeight / 2) * speed;
|
||||||
|
el.style.transform = 'translateY(' + offset + 'px)';
|
||||||
|
});
|
||||||
|
parallaxTicking = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function initParallax(root) {
|
||||||
|
eachMatch(root, '[data-aksrt-parallax]', function (el) {
|
||||||
|
if (el.dataset.aksrtParallaxBound === '1') return;
|
||||||
|
el.dataset.aksrtParallaxBound = '1';
|
||||||
|
parallaxElements.push(el);
|
||||||
|
});
|
||||||
|
if (!parallaxScrollBound) {
|
||||||
|
parallaxScrollBound = true;
|
||||||
|
window.addEventListener('scroll', function () {
|
||||||
|
if (parallaxTicking) return;
|
||||||
|
parallaxTicking = true;
|
||||||
|
requestAnimationFrame(updateParallax);
|
||||||
|
}, { passive: true });
|
||||||
|
}
|
||||||
|
updateParallax();
|
||||||
|
}
|
||||||
|
|
||||||
|
function initRipple(root, reason) {
|
||||||
|
if (rippleBound) return;
|
||||||
|
rippleBound = true;
|
||||||
document.addEventListener('click', function (e) {
|
document.addEventListener('click', function (e) {
|
||||||
var el = e.target.closest('.aksrt-ripple');
|
var el = e.target.closest('.aksrt-ripple');
|
||||||
if (!el) return;
|
if (!el) return;
|
||||||
|
|
||||||
var rect = el.getBoundingClientRect();
|
var rect = el.getBoundingClientRect();
|
||||||
var x = e.clientX - rect.left;
|
|
||||||
var y = e.clientY - rect.top;
|
|
||||||
var size = Math.max(rect.width, rect.height) * 2;
|
var size = Math.max(rect.width, rect.height) * 2;
|
||||||
|
|
||||||
var wave = document.createElement('span');
|
var wave = document.createElement('span');
|
||||||
wave.className = 'aksrt-ripple__wave';
|
wave.className = 'aksrt-ripple__wave';
|
||||||
wave.style.width = wave.style.height = size + 'px';
|
wave.style.width = wave.style.height = size + 'px';
|
||||||
wave.style.left = (x - size / 2) + 'px';
|
wave.style.left = (e.clientX - rect.left - size / 2) + 'px';
|
||||||
wave.style.top = (y - size / 2) + 'px';
|
wave.style.top = (e.clientY - rect.top - size / 2) + 'px';
|
||||||
|
|
||||||
el.appendChild(wave);
|
el.appendChild(wave);
|
||||||
|
wave.addEventListener('animationend', function () { wave.remove(); });
|
||||||
wave.addEventListener('animationend', function () {
|
|
||||||
wave.remove();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================
|
function initFloatLabels(root) {
|
||||||
* 8. 表单浮动标签自动初始化
|
eachMatch(root, '.aksrt-float-label__input', function (input) {
|
||||||
* ============================================================ */
|
if (input.value) input.setAttribute('data-has-value', '1');
|
||||||
function initFloatLabels() {
|
if (input.dataset.aksrtFloatLabelBound === '1') return;
|
||||||
document.querySelectorAll('.aksrt-float-label__input').forEach(function (input) {
|
input.dataset.aksrtFloatLabelBound = '1';
|
||||||
// 检查初始值
|
|
||||||
if (input.value) {
|
|
||||||
input.setAttribute('data-has-value', '1');
|
|
||||||
}
|
|
||||||
input.addEventListener('input', function () {
|
input.addEventListener('input', function () {
|
||||||
if (this.value) {
|
if (this.value) this.setAttribute('data-has-value', '1');
|
||||||
this.setAttribute('data-has-value', '1');
|
else this.removeAttribute('data-has-value');
|
||||||
} else {
|
|
||||||
this.removeAttribute('data-has-value');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================
|
function initSigninCalendar(root) {
|
||||||
* 8. 签到日历可视化
|
eachMatch(root, '[data-aksrt-signin-calendar]', function (calendar) {
|
||||||
* ============================================================ */
|
if (calendar.dataset.aksrtSigninCalendarBound === '1') return;
|
||||||
function initSigninCalendar() {
|
calendar.dataset.aksrtSigninCalendarBound = '1';
|
||||||
var calendar = document.querySelector('[data-aksrt-signin-calendar]');
|
var data = [];
|
||||||
if (!calendar) return;
|
try { data = JSON.parse(calendar.dataset.aksrtSigninCalendar || '[]'); } catch (e) {}
|
||||||
|
var today = new Date();
|
||||||
var data = [];
|
var html = '<div class="aksrt-signin-calendar__grid">';
|
||||||
try {
|
for (var i = 29; i >= 0; i--) {
|
||||||
data = JSON.parse(calendar.dataset.aksrtSigninCalendar || '[]');
|
var d = new Date(today);
|
||||||
} catch (e) {}
|
d.setDate(d.getDate() - i);
|
||||||
|
var dateStr = d.toISOString().split('T')[0];
|
||||||
// 生成最近 30 天的格子
|
var isSigned = data.indexOf(dateStr) !== -1;
|
||||||
var today = new Date();
|
html += '<div class="aksrt-signin-calendar__day' + (isSigned ? ' is-signed' : '') + (i === 0 ? ' is-today' : '') +
|
||||||
var html = '<div class="aksrt-signin-calendar__grid">';
|
'" title="' + dateStr + (isSigned ? ' ✓' : '') + '"><span>' + d.getDate() + '</span></div>';
|
||||||
|
}
|
||||||
for (var i = 29; i >= 0; i--) {
|
calendar.innerHTML = html + '</div>';
|
||||||
var d = new Date(today);
|
});
|
||||||
d.setDate(d.getDate() - i);
|
|
||||||
var dateStr = d.toISOString().split('T')[0];
|
|
||||||
var isSigned = data.indexOf(dateStr) !== -1;
|
|
||||||
var isToday = i === 0;
|
|
||||||
|
|
||||||
html += '<div class="aksrt-signin-calendar__day' +
|
|
||||||
(isSigned ? ' is-signed' : '') +
|
|
||||||
(isToday ? ' is-today' : '') +
|
|
||||||
'" title="' + dateStr + (isSigned ? ' ✓' : '') + '">' +
|
|
||||||
'<span>' + d.getDate() + '</span>' +
|
|
||||||
'</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
html += '</div>';
|
|
||||||
calendar.innerHTML = html;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================
|
function bindModalLifecycle() {
|
||||||
* 初始化入口
|
if (modalBound) return;
|
||||||
* ============================================================ */
|
modalBound = true;
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('aksrt:modal:open', function (event) {
|
||||||
initTilt();
|
var root = event.target && event.target.querySelectorAll ? event.target : document;
|
||||||
initScrollAnimations();
|
window.setTimeout(function () { initSigninCalendar(root); }, 30);
|
||||||
initRipple();
|
|
||||||
initSticky();
|
|
||||||
initParallax();
|
|
||||||
initFloatLabels();
|
|
||||||
initSigninCalendar();
|
|
||||||
document.addEventListener('aksrt:modal:open', function () {
|
|
||||||
// Remote modal may inject calendar markup after open.
|
|
||||||
window.setTimeout(initSigninCalendar, 30);
|
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
function init(root, reason) {
|
||||||
|
initTilt(root);
|
||||||
|
initScrollAnimations(root);
|
||||||
|
initRipple(root, reason);
|
||||||
|
initSticky(root);
|
||||||
|
initParallax(root);
|
||||||
|
initFloatLabels(root);
|
||||||
|
initSigninCalendar(root);
|
||||||
|
bindModalLifecycle();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.AksrtFrontend.register('aksrt-enhancements-advanced', init);
|
||||||
|
|
||||||
// 暴露到全局供动态内容使用
|
|
||||||
window.AksrtEnhancements = {
|
window.AksrtEnhancements = {
|
||||||
initTilt: initTilt,
|
initTilt: initTilt,
|
||||||
initScrollAnimations: initScrollAnimations,
|
initScrollAnimations: initScrollAnimations,
|
||||||
initRipple: initRipple,
|
initRipple: initRipple,
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
+6
-6
@@ -44,7 +44,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function initFollowButtons() {
|
var globalsBound = false;
|
||||||
|
|
||||||
|
function initFollowButtons(root, reason) {
|
||||||
|
if (globalsBound) return;
|
||||||
|
globalsBound = true;
|
||||||
document.addEventListener('click', function (event) {
|
document.addEventListener('click', function (event) {
|
||||||
var button = event.target.closest('[data-aksrt-follow]');
|
var button = event.target.closest('[data-aksrt-follow]');
|
||||||
if (!button) return;
|
if (!button) return;
|
||||||
@@ -92,9 +96,5 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
window.AksrtFrontend.register('aksrt-follow', initFollowButtons);
|
||||||
document.addEventListener('DOMContentLoaded', initFollowButtons);
|
|
||||||
} else {
|
|
||||||
initFollowButtons();
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
+11
-10
@@ -80,11 +80,14 @@
|
|||||||
isSubmitting: false,
|
isSubmitting: false,
|
||||||
featured: { type: '', data: {} },
|
featured: { type: '', data: {} },
|
||||||
|
|
||||||
init: function () {
|
init: function (root) {
|
||||||
this.form = document.getElementById('aksrt-submit-form');
|
this.root = root || document;
|
||||||
if (!this.form) {
|
this.form = this.root.nodeType === 1 && this.root.matches('#aksrt-submit-form')
|
||||||
|
? this.root : this.root.querySelector('#aksrt-submit-form');
|
||||||
|
if (!this.form || this.form.dataset.aksrtFrontSubmitBound === '1') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.form.dataset.aksrtFrontSubmitBound = '1';
|
||||||
this.bindDirty();
|
this.bindDirty();
|
||||||
this.bindAutoHeight();
|
this.bindAutoHeight();
|
||||||
this.bindSubmitButtons();
|
this.bindSubmitButtons();
|
||||||
@@ -311,6 +314,8 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
bindDraftDelete: function () {
|
bindDraftDelete: function () {
|
||||||
|
if (document.__aksrtFrontSubmitDraftDeleteBound) return;
|
||||||
|
document.__aksrtFrontSubmitDraftDeleteBound = true;
|
||||||
document.addEventListener('click', function (e) {
|
document.addEventListener('click', function (e) {
|
||||||
var btn = e.target.closest('.aksrt-submit-drafts__delete');
|
var btn = e.target.closest('.aksrt-submit-drafts__delete');
|
||||||
if (!btn) {
|
if (!btn) {
|
||||||
@@ -645,11 +650,7 @@
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
window.AksrtFrontend.register('aksrt-front-submit', function (root) {
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
App.init(root);
|
||||||
App.init();
|
});
|
||||||
});
|
|
||||||
} else {
|
|
||||||
App.init();
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
+21
-17
@@ -424,6 +424,7 @@
|
|||||||
var tablists = (scope || document).querySelectorAll('[data-aksrt-home-tabs]');
|
var tablists = (scope || document).querySelectorAll('[data-aksrt-home-tabs]');
|
||||||
|
|
||||||
tablists.forEach(function (list, listIndex) {
|
tablists.forEach(function (list, listIndex) {
|
||||||
|
if (list.dataset.aksrtHomeTabsBound === '1') return;
|
||||||
var stream = list.closest('.aksrt-homepage__stream');
|
var stream = list.closest('.aksrt-homepage__stream');
|
||||||
if (!stream) return;
|
if (!stream) return;
|
||||||
|
|
||||||
@@ -431,6 +432,7 @@
|
|||||||
var panels = Array.from(stream.querySelectorAll('[data-home-tab-panel]'));
|
var panels = Array.from(stream.querySelectorAll('[data-home-tab-panel]'));
|
||||||
|
|
||||||
if (buttons.length < 2 || !panels.length) return;
|
if (buttons.length < 2 || !panels.length) return;
|
||||||
|
list.dataset.aksrtHomeTabsBound = '1';
|
||||||
|
|
||||||
function getPanel(button) {
|
function getPanel(button) {
|
||||||
var target = button.getAttribute('data-home-tab-target');
|
var target = button.getAttribute('data-home-tab-target');
|
||||||
@@ -539,12 +541,14 @@
|
|||||||
* Sortbar Dropdown Toggle
|
* Sortbar Dropdown Toggle
|
||||||
* ============================================================ */
|
* ============================================================ */
|
||||||
|
|
||||||
function initSortbarDropdown() {
|
function initSortbarDropdown(scope) {
|
||||||
document.querySelectorAll('[data-sort-dropdown-trigger]').forEach(function (trigger) {
|
(scope || document).querySelectorAll('[data-sort-dropdown-trigger]').forEach(function (trigger) {
|
||||||
|
if (trigger.dataset.aksrtSortDropdownBound === '1') return;
|
||||||
var wrapper = trigger.closest('.aksrt-homepage__sortbar-dropdown');
|
var wrapper = trigger.closest('.aksrt-homepage__sortbar-dropdown');
|
||||||
if (!wrapper) return;
|
if (!wrapper) return;
|
||||||
var menu = wrapper.querySelector('.aksrt-homepage__sortbar-dropdown-menu');
|
var menu = wrapper.querySelector('.aksrt-homepage__sortbar-dropdown-menu');
|
||||||
if (!menu) return;
|
if (!menu) return;
|
||||||
|
trigger.dataset.aksrtSortDropdownBound = '1';
|
||||||
|
|
||||||
function close() {
|
function close() {
|
||||||
menu.setAttribute('hidden', '');
|
menu.setAttribute('hidden', '');
|
||||||
@@ -599,10 +603,11 @@
|
|||||||
* Sortbar AJAX
|
* Sortbar AJAX
|
||||||
* ============================================================ */
|
* ============================================================ */
|
||||||
|
|
||||||
function initSortbar() {
|
function initSortbar(scope) {
|
||||||
document.querySelectorAll('.aksrt-homepage__stream').forEach(function (stream) {
|
(scope || document).querySelectorAll('.aksrt-homepage__stream').forEach(function (stream) {
|
||||||
var sortbar = stream.querySelector('.aksrt-homepage__sortbar');
|
var sortbar = stream.querySelector('.aksrt-homepage__sortbar');
|
||||||
if (!sortbar || !isSortAjaxEnabled(sortbar)) return;
|
if (!sortbar || !isSortAjaxEnabled(sortbar) || sortbar.dataset.aksrtSortbarBound === '1') return;
|
||||||
|
sortbar.dataset.aksrtSortbarBound = '1';
|
||||||
|
|
||||||
sortbar.addEventListener('click', function (event) {
|
sortbar.addEventListener('click', function (event) {
|
||||||
var link = event.target.closest('.aksrt-homepage__sortbar-link, .aksrt-homepage__sortbar-dropdown-item');
|
var link = event.target.closest('.aksrt-homepage__sortbar-link, .aksrt-homepage__sortbar-dropdown-item');
|
||||||
@@ -649,10 +654,11 @@
|
|||||||
return isNaN(offset) ? 60 : offset;
|
return isNaN(offset) ? 60 : offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
function initStickyTabs() {
|
function initStickyTabs(scope) {
|
||||||
if (!isStickyTabsEnabled()) return;
|
if (!isStickyTabsEnabled()) return;
|
||||||
|
|
||||||
document.querySelectorAll('.aksrt-homepage__tabs.home-tab-nav-box').forEach(function (tabs) {
|
(scope || document).querySelectorAll('.aksrt-homepage__tabs.home-tab-nav-box').forEach(function (tabs) {
|
||||||
|
if (tabs.dataset.aksrtStickyTabsBound === '1') return;
|
||||||
var parent = tabs.parentNode;
|
var parent = tabs.parentNode;
|
||||||
var sentinel = tabs.previousElementSibling;
|
var sentinel = tabs.previousElementSibling;
|
||||||
var canUseSticky = supportsStickyPosition();
|
var canUseSticky = supportsStickyPosition();
|
||||||
@@ -660,6 +666,7 @@
|
|||||||
var observer = null;
|
var observer = null;
|
||||||
|
|
||||||
if (!parent || tabs.getAttribute('data-sticky-tabs') === 'false') return;
|
if (!parent || tabs.getAttribute('data-sticky-tabs') === 'false') return;
|
||||||
|
tabs.dataset.aksrtStickyTabsBound = '1';
|
||||||
|
|
||||||
if (!sentinel || !sentinel.classList.contains('aksrt-homepage__tabs-sentinel')) {
|
if (!sentinel || !sentinel.classList.contains('aksrt-homepage__tabs-sentinel')) {
|
||||||
sentinel = document.createElement('div');
|
sentinel = document.createElement('div');
|
||||||
@@ -718,16 +725,13 @@
|
|||||||
* Init
|
* Init
|
||||||
* ============================================================ */
|
* ============================================================ */
|
||||||
|
|
||||||
function init() {
|
function init(root) {
|
||||||
initHomeTabs();
|
var scope = root || document;
|
||||||
initSortbarDropdown();
|
initHomeTabs(scope);
|
||||||
initSortbar();
|
initSortbarDropdown(scope);
|
||||||
initStickyTabs();
|
initSortbar(scope);
|
||||||
|
initStickyTabs(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
window.AksrtFrontend.register('aksrt-homepage', init);
|
||||||
document.addEventListener('DOMContentLoaded', init);
|
|
||||||
} else {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
+24
-15
@@ -37,9 +37,17 @@
|
|||||||
|
|
||||||
// ── Auto-resize Textarea ──
|
// ── Auto-resize Textarea ──
|
||||||
|
|
||||||
function initAutoResize() {
|
function queryAll(root, selector) {
|
||||||
var textareas = document.querySelectorAll('textarea[data-aksrt-autoresize]');
|
var nodes = Array.prototype.slice.call(root.querySelectorAll(selector));
|
||||||
|
if (root.nodeType === 1 && root.matches(selector)) nodes.unshift(root);
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
function initAutoResize(root) {
|
||||||
|
var textareas = queryAll(root, 'textarea[data-aksrt-autoresize]');
|
||||||
textareas.forEach(function (ta) {
|
textareas.forEach(function (ta) {
|
||||||
|
if (ta.dataset.aksrtAutoresizeBound === '1') return;
|
||||||
|
ta.dataset.aksrtAutoresizeBound = '1';
|
||||||
function resize() {
|
function resize() {
|
||||||
ta.style.height = 'auto';
|
ta.style.height = 'auto';
|
||||||
ta.style.height = ta.scrollHeight + 'px';
|
ta.style.height = ta.scrollHeight + 'px';
|
||||||
@@ -52,9 +60,11 @@
|
|||||||
|
|
||||||
// ── Character Counter ──
|
// ── Character Counter ──
|
||||||
|
|
||||||
function initCounters() {
|
function initCounters(root) {
|
||||||
var fields = document.querySelectorAll('[data-aksrt-counter]');
|
var fields = queryAll(root, '[data-aksrt-counter]');
|
||||||
fields.forEach(function (field) {
|
fields.forEach(function (field) {
|
||||||
|
if (field.dataset.aksrtCounterBound === '1') return;
|
||||||
|
field.dataset.aksrtCounterBound = '1';
|
||||||
var max = parseInt(field.getAttribute('data-aksrt-maxlength') || field.getAttribute('maxlength') || '0', 10);
|
var max = parseInt(field.getAttribute('data-aksrt-maxlength') || field.getAttribute('maxlength') || '0', 10);
|
||||||
var counter = document.createElement('span');
|
var counter = document.createElement('span');
|
||||||
counter.className = 'aksrt-counter';
|
counter.className = 'aksrt-counter';
|
||||||
@@ -79,9 +89,11 @@
|
|||||||
|
|
||||||
// ── Validation Feedback ──
|
// ── Validation Feedback ──
|
||||||
|
|
||||||
function initValidation() {
|
function initValidation(root) {
|
||||||
var fields = document.querySelectorAll('[data-aksrt-validate]');
|
var fields = queryAll(root, '[data-aksrt-validate]');
|
||||||
fields.forEach(function (field) {
|
fields.forEach(function (field) {
|
||||||
|
if (field.dataset.aksrtValidateBound === '1') return;
|
||||||
|
field.dataset.aksrtValidateBound = '1';
|
||||||
var minLen = parseInt(field.getAttribute('data-aksrt-minlength') || field.getAttribute('minlength') || '0', 10);
|
var minLen = parseInt(field.getAttribute('data-aksrt-minlength') || field.getAttribute('minlength') || '0', 10);
|
||||||
var maxLen = parseInt(field.getAttribute('data-aksrt-maxlength') || field.getAttribute('maxlength') || '0', 10);
|
var maxLen = parseInt(field.getAttribute('data-aksrt-maxlength') || field.getAttribute('maxlength') || '0', 10);
|
||||||
var required = field.hasAttribute('required');
|
var required = field.hasAttribute('required');
|
||||||
@@ -115,16 +127,13 @@
|
|||||||
|
|
||||||
// ── Main Init ──
|
// ── Main Init ──
|
||||||
|
|
||||||
function init() {
|
function init(root) {
|
||||||
|
root = root || document;
|
||||||
injectStyle();
|
injectStyle();
|
||||||
initAutoResize();
|
initAutoResize(root);
|
||||||
initCounters();
|
initCounters(root);
|
||||||
initValidation();
|
initValidation(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
window.AksrtFrontend.register('aksrt-input-expand', init);
|
||||||
document.addEventListener('DOMContentLoaded', init);
|
|
||||||
} else {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,172 +0,0 @@
|
|||||||
/**
|
|
||||||
* AKSRT Page Loader
|
|
||||||
*
|
|
||||||
* Lightweight top progress bar for page transitions and AJAX requests.
|
|
||||||
* No external dependencies — pure vanilla JS.
|
|
||||||
*
|
|
||||||
* @package AKSRT
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function () {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var STYLE_ID = 'aksrt-loader-style';
|
|
||||||
var BAR_ID = 'aksrt-loader-bar';
|
|
||||||
var CSS =
|
|
||||||
'#' + BAR_ID + '{' +
|
|
||||||
'position:fixed;top:0;left:0;width:0;height:3px;z-index:99999;' +
|
|
||||||
'background:linear-gradient(90deg,#1890ff,#36cfc9);' +
|
|
||||||
'transition:width 0.3s ease,opacity 0.3s ease;' +
|
|
||||||
'pointer-events:none;opacity:0;' +
|
|
||||||
'}' +
|
|
||||||
'#' + BAR_ID + '.is-active{opacity:1;}' +
|
|
||||||
'#' + BAR_ID + '.is-done{' +
|
|
||||||
'width:100%!important;opacity:0;' +
|
|
||||||
'}';
|
|
||||||
|
|
||||||
var bar = null;
|
|
||||||
var timer = null;
|
|
||||||
var progress = 0;
|
|
||||||
|
|
||||||
function injectStyle() {
|
|
||||||
if (document.getElementById(STYLE_ID)) return;
|
|
||||||
var style = document.createElement('style');
|
|
||||||
style.id = STYLE_ID;
|
|
||||||
style.textContent = CSS;
|
|
||||||
document.head.appendChild(style);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createBar() {
|
|
||||||
if (bar) return;
|
|
||||||
bar = document.createElement('div');
|
|
||||||
bar.id = BAR_ID;
|
|
||||||
document.body.appendChild(bar);
|
|
||||||
}
|
|
||||||
|
|
||||||
function start() {
|
|
||||||
if (!bar) createBar();
|
|
||||||
clearTimeout(timer);
|
|
||||||
bar.classList.remove('is-done');
|
|
||||||
bar.classList.add('is-active');
|
|
||||||
progress = 0;
|
|
||||||
bar.style.width = '0%';
|
|
||||||
trickle();
|
|
||||||
}
|
|
||||||
|
|
||||||
function trickle() {
|
|
||||||
if (progress >= 90) return;
|
|
||||||
var increment = progress < 30 ? 8 : progress < 60 ? 4 : 2;
|
|
||||||
progress = Math.min(90, progress + increment * (0.8 + Math.random() * 0.4));
|
|
||||||
bar.style.width = progress + '%';
|
|
||||||
timer = setTimeout(trickle, 200 + Math.random() * 300);
|
|
||||||
}
|
|
||||||
|
|
||||||
function done() {
|
|
||||||
if (!bar) return;
|
|
||||||
clearTimeout(timer);
|
|
||||||
bar.style.width = '100%';
|
|
||||||
bar.classList.add('is-done');
|
|
||||||
setTimeout(function () {
|
|
||||||
bar.classList.remove('is-active', 'is-done');
|
|
||||||
bar.style.width = '0%';
|
|
||||||
progress = 0;
|
|
||||||
}, 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Intercept link clicks for same-origin page transitions
|
|
||||||
function onLinkClick(e) {
|
|
||||||
if (e.defaultPrevented) return;
|
|
||||||
if (e.button !== 0) return; // left click only
|
|
||||||
if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
|
|
||||||
|
|
||||||
var link = e.target.closest('a');
|
|
||||||
if (!link || !link.href) return;
|
|
||||||
if (link.target === '_blank') return;
|
|
||||||
if (link.hasAttribute('download')) return;
|
|
||||||
if (link.href.indexOf('#') === 0) return;
|
|
||||||
|
|
||||||
// Same-origin only
|
|
||||||
try {
|
|
||||||
var url = new URL(link.href);
|
|
||||||
if (url.origin !== window.location.origin) return;
|
|
||||||
if (url.protocol !== "http:" && url.protocol !== "https:") return;
|
|
||||||
if (url.pathname === window.location.pathname && url.search === window.location.search) return;
|
|
||||||
} catch (ex) { return; }
|
|
||||||
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Intercept form submissions
|
|
||||||
function onFormSubmit(e) {
|
|
||||||
var form = e.target;
|
|
||||||
if (!form || form.tagName !== 'FORM') return;
|
|
||||||
if (form.target === '_blank') return;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hook into AJAX (fetch) if available
|
|
||||||
function hookFetch() {
|
|
||||||
if (!window.fetch) return;
|
|
||||||
var origFetch = window.fetch;
|
|
||||||
window.fetch = function () {
|
|
||||||
start();
|
|
||||||
return origFetch.apply(this, arguments).then(function (response) {
|
|
||||||
done();
|
|
||||||
return response;
|
|
||||||
}).catch(function (err) {
|
|
||||||
done();
|
|
||||||
throw err;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hook into XMLHttpRequest
|
|
||||||
function hookXHR() {
|
|
||||||
if (!window.XMLHttpRequest) return;
|
|
||||||
var origOpen = XMLHttpRequest.prototype.open;
|
|
||||||
var origSend = XMLHttpRequest.prototype.send;
|
|
||||||
|
|
||||||
XMLHttpRequest.prototype.open = function () {
|
|
||||||
this._aksrtLoader = true;
|
|
||||||
return origOpen.apply(this, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
XMLHttpRequest.prototype.send = function () {
|
|
||||||
if (this._aksrtLoader) {
|
|
||||||
start();
|
|
||||||
var self = this;
|
|
||||||
this.addEventListener('loadend', function () { done(); });
|
|
||||||
}
|
|
||||||
return origSend.apply(this, arguments);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
injectStyle();
|
|
||||||
createBar();
|
|
||||||
|
|
||||||
document.addEventListener('click', onLinkClick, true);
|
|
||||||
document.addEventListener('submit', onFormSubmit, true);
|
|
||||||
|
|
||||||
// Done on page load (handles bfcache)
|
|
||||||
window.addEventListener('pageshow', function (e) {
|
|
||||||
if (e.persisted) done();
|
|
||||||
});
|
|
||||||
window.addEventListener('load', done);
|
|
||||||
|
|
||||||
hookFetch();
|
|
||||||
hookXHR();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public API
|
|
||||||
window.AksrtLoader = {
|
|
||||||
start: start,
|
|
||||||
done: done
|
|
||||||
};
|
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
|
||||||
document.addEventListener('DOMContentLoaded', init);
|
|
||||||
} else {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/**
|
|
||||||
* AKSRT Frontend Shell
|
|
||||||
*
|
|
||||||
* All init modules have been extracted to assets/js/core/*.js.
|
|
||||||
* This file remains as the enqueue anchor (handle: aksrt-script) that
|
|
||||||
* other scripts depend on, and provides the AksrtFrontend fallback
|
|
||||||
* for edge cases where rehydrate.js is not loaded first.
|
|
||||||
*
|
|
||||||
* @package AKSRT
|
|
||||||
* @since 5.0.0
|
|
||||||
*/
|
|
||||||
(function () {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
if (!window.AksrtFrontend) {
|
|
||||||
window.AksrtFrontend = {
|
|
||||||
register: function (name, fn) {
|
|
||||||
if (document.readyState === "loading") {
|
|
||||||
document.addEventListener("DOMContentLoaded", function () { fn(document, "init"); });
|
|
||||||
} else {
|
|
||||||
fn(document, "init");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
rehydrate: function () {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
@@ -6,8 +6,11 @@
|
|||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var root = document.querySelector('[data-message-center]');
|
function init(scope) {
|
||||||
if (!root) return;
|
scope = scope || document;
|
||||||
|
var root = scope.nodeType === 1 && scope.matches('[data-message-center]') ? scope : scope.querySelector('[data-message-center]');
|
||||||
|
if (!root || root.dataset.aksrtMessagesBound === '1') return;
|
||||||
|
root.dataset.aksrtMessagesBound = '1';
|
||||||
|
|
||||||
var nonce = typeof aksrtData !== 'undefined' ? aksrtData.nonce : '';
|
var nonce = typeof aksrtData !== 'undefined' ? aksrtData.nonce : '';
|
||||||
var ajaxUrl = typeof aksrtData !== 'undefined' ? aksrtData.ajaxUrl : '/wp-admin/admin-ajax.php';
|
var ajaxUrl = typeof aksrtData !== 'undefined' ? aksrtData.ajaxUrl : '/wp-admin/admin-ajax.php';
|
||||||
@@ -225,4 +228,7 @@
|
|||||||
if (result.success && result.data) updateHeaderBadge(result.data.unread);
|
if (result.success && result.data) updateHeaderBadge(result.data.unread);
|
||||||
}).catch(function () {});
|
}).catch(function () {});
|
||||||
}, pollInterval);
|
}, pollInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.AksrtFrontend.register('aksrt-messages', init);
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -307,8 +307,11 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 自动初始化
|
// 自动初始化
|
||||||
function autoInit() {
|
function autoInit(root) {
|
||||||
document.querySelectorAll('[data-aksrt-mini-upload]').forEach(function (el) {
|
var containers = [];
|
||||||
|
if (root && root.nodeType === 1 && root.matches('[data-aksrt-mini-upload]')) containers.push(root);
|
||||||
|
Array.prototype.push.apply(containers, (root || document).querySelectorAll('[data-aksrt-mini-upload]'));
|
||||||
|
containers.forEach(function (el) {
|
||||||
if (el.dataset.miniUploadInit) return;
|
if (el.dataset.miniUploadInit) return;
|
||||||
el.dataset.miniUploadInit = '1';
|
el.dataset.miniUploadInit = '1';
|
||||||
|
|
||||||
@@ -321,11 +324,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
window.AksrtFrontend.register('aksrt-mini-upload', autoInit);
|
||||||
document.addEventListener('DOMContentLoaded', autoInit);
|
|
||||||
} else {
|
|
||||||
autoInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 暴露到全局
|
// 暴露到全局
|
||||||
window.AksrtMiniUpload = MiniUpload;
|
window.AksrtMiniUpload = MiniUpload;
|
||||||
|
|||||||
@@ -473,5 +473,4 @@
|
|||||||
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === "function") {
|
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === "function") {
|
||||||
window.AksrtFrontend.register("aksrt-order-center", init);
|
window.AksrtFrontend.register("aksrt-order-center", init);
|
||||||
}
|
}
|
||||||
init(document);
|
|
||||||
}());
|
}());
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
function PageEdit(options) {
|
function PageEdit(options) {
|
||||||
this.options = Object.assign({
|
this.options = Object.assign({
|
||||||
|
form: null,
|
||||||
formSelector: 'form[data-aksrt-edit]',
|
formSelector: 'form[data-aksrt-edit]',
|
||||||
titleSelector: 'input[name="title"], input[name="topic_title"]',
|
titleSelector: 'input[name="title"], input[name="topic_title"]',
|
||||||
contentSelector: 'textarea[name="content"], textarea[name="topic_content"]',
|
contentSelector: 'textarea[name="content"], textarea[name="topic_content"]',
|
||||||
@@ -29,7 +30,7 @@
|
|||||||
draftKey: '',
|
draftKey: '',
|
||||||
}, options || {});
|
}, options || {});
|
||||||
|
|
||||||
this.form = document.querySelector(this.options.formSelector);
|
this.form = this.options.form || document.querySelector(this.options.formSelector);
|
||||||
if (!this.form) return;
|
if (!this.form) return;
|
||||||
|
|
||||||
this.autoSaveTimer = null;
|
this.autoSaveTimer = null;
|
||||||
@@ -189,18 +190,15 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 自动初始化
|
// 自动初始化
|
||||||
function autoInit() {
|
function autoInit(root) {
|
||||||
var form = document.querySelector('form[data-aksrt-edit]');
|
var form = root && root.nodeType === 1 && root.matches('form[data-aksrt-edit]')
|
||||||
|
? root : (root || document).querySelector('form[data-aksrt-edit]');
|
||||||
if (form) {
|
if (form) {
|
||||||
new PageEdit();
|
new PageEdit({ form: form });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
window.AksrtFrontend.register('aksrt-page-edit', autoInit);
|
||||||
document.addEventListener('DOMContentLoaded', autoInit);
|
|
||||||
} else {
|
|
||||||
autoInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
window.AksrtPageEdit = PageEdit;
|
window.AksrtPageEdit = PageEdit;
|
||||||
})();
|
})();
|
||||||
|
|||||||
+24
-20
@@ -28,7 +28,10 @@
|
|||||||
searchQuery: '',
|
searchQuery: '',
|
||||||
ajaxInFlight: null,
|
ajaxInFlight: null,
|
||||||
|
|
||||||
init: function () {
|
init: function (root) {
|
||||||
|
this.root = root || document;
|
||||||
|
if (this.root.__aksrtPageNavInitialized) return;
|
||||||
|
this.root.__aksrtPageNavInitialized = true;
|
||||||
this.initTocHighlight();
|
this.initTocHighlight();
|
||||||
this.initSmoothScroll();
|
this.initSmoothScroll();
|
||||||
this.initDocSearch();
|
this.initDocSearch();
|
||||||
@@ -40,7 +43,8 @@
|
|||||||
* TOC 高亮(文档阅读页)
|
* TOC 高亮(文档阅读页)
|
||||||
* ============================================================ */
|
* ============================================================ */
|
||||||
initTocHighlight: function () {
|
initTocHighlight: function () {
|
||||||
var toc = document.querySelector('.aksrt-doc-toc');
|
var toc = this.root.querySelector('.aksrt-doc-toc');
|
||||||
|
if (this.root.nodeType === 1 && this.root.matches('.aksrt-doc-toc')) toc = this.root;
|
||||||
if (!toc) return;
|
if (!toc) return;
|
||||||
|
|
||||||
this.tocItems = Array.from(toc.querySelectorAll('.aksrt-doc-toc__item a'));
|
this.tocItems = Array.from(toc.querySelectorAll('.aksrt-doc-toc__item a'));
|
||||||
@@ -92,7 +96,9 @@
|
|||||||
* 平滑滚动
|
* 平滑滚动
|
||||||
* ============================================================ */
|
* ============================================================ */
|
||||||
initSmoothScroll: function () {
|
initSmoothScroll: function () {
|
||||||
document.addEventListener('click', function (e) {
|
if (this.root.__aksrtPageNavSmoothBound) return;
|
||||||
|
this.root.__aksrtPageNavSmoothBound = true;
|
||||||
|
this.root.addEventListener('click', function (e) {
|
||||||
var link = e.target.closest('a[href^="#"]');
|
var link = e.target.closest('a[href^="#"]');
|
||||||
if (!link) return;
|
if (!link) return;
|
||||||
|
|
||||||
@@ -113,11 +119,11 @@
|
|||||||
* 文档搜索(AJAX 接管)
|
* 文档搜索(AJAX 接管)
|
||||||
* ============================================================ */
|
* ============================================================ */
|
||||||
initDocSearch: function () {
|
initDocSearch: function () {
|
||||||
var searchInput = document.querySelector('.aksrt-doc-search__input');
|
var searchInput = this.root.querySelector('.aksrt-doc-search__input');
|
||||||
if (!searchInput) return;
|
if (!searchInput) return;
|
||||||
|
|
||||||
var resultsContainer = document.querySelector('.aksrt-doc-search__results');
|
var resultsContainer = this.root.querySelector('.aksrt-doc-search__results');
|
||||||
var takeover = document.querySelector('.aksrt-doc-takeover');
|
var takeover = this.root.querySelector('.aksrt-doc-takeover');
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var debounceTimer = null;
|
var debounceTimer = null;
|
||||||
@@ -206,7 +212,7 @@
|
|||||||
resultsContainer.innerHTML = '';
|
resultsContainer.innerHTML = '';
|
||||||
}
|
}
|
||||||
// 显示所有卡片
|
// 显示所有卡片
|
||||||
var cards = document.querySelectorAll('.aksrt-doc-index-card');
|
var cards = this.root.querySelectorAll('.aksrt-doc-index-card');
|
||||||
cards.forEach(function (card) { card.style.display = ''; });
|
cards.forEach(function (card) { card.style.display = ''; });
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -231,7 +237,7 @@
|
|||||||
* 分类切换 — AJAX 加载 + 分页
|
* 分类切换 — AJAX 加载 + 分页
|
||||||
* ============================================================ */
|
* ============================================================ */
|
||||||
initCategoryChips: function () {
|
initCategoryChips: function () {
|
||||||
var toolbar = document.querySelector('.aksrt-doc-toolbar');
|
var toolbar = this.root.querySelector('.aksrt-doc-toolbar');
|
||||||
if (!toolbar) return;
|
if (!toolbar) return;
|
||||||
|
|
||||||
var chips = toolbar.querySelectorAll('.aksrt-doc-toolbar__chip[data-cat-id]');
|
var chips = toolbar.querySelectorAll('.aksrt-doc-toolbar__chip[data-cat-id]');
|
||||||
@@ -260,7 +266,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var grid = document.querySelector('.aksrt-doc-grid');
|
var grid = this.root.querySelector('.aksrt-doc-grid');
|
||||||
if (!grid) return;
|
if (!grid) return;
|
||||||
|
|
||||||
// 显示加载状态
|
// 显示加载状态
|
||||||
@@ -305,7 +311,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
updateMetaCount: function (total) {
|
updateMetaCount: function (total) {
|
||||||
var meta = document.querySelector('.aksrt-doc-toolbar__meta');
|
var meta = this.root.querySelector('.aksrt-doc-toolbar__meta');
|
||||||
if (meta) {
|
if (meta) {
|
||||||
meta.textContent = total + ' 篇文档';
|
meta.textContent = total + ' 篇文档';
|
||||||
}
|
}
|
||||||
@@ -316,7 +322,7 @@
|
|||||||
* ============================================================ */
|
* ============================================================ */
|
||||||
initPagination: function () {
|
initPagination: function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
var paginationContainer = document.querySelector('.aksrt-doc-pagination');
|
var paginationContainer = this.root.querySelector('.aksrt-doc-pagination');
|
||||||
if (!paginationContainer) return;
|
if (!paginationContainer) return;
|
||||||
|
|
||||||
paginationContainer.addEventListener('click', function (e) {
|
paginationContainer.addEventListener('click', function (e) {
|
||||||
@@ -331,7 +337,7 @@
|
|||||||
self.loadCategoryDocs(self.activeCategory, page);
|
self.loadCategoryDocs(self.activeCategory, page);
|
||||||
|
|
||||||
// 滚动到顶部
|
// 滚动到顶部
|
||||||
var grid = document.querySelector('.aksrt-doc-grid');
|
var grid = self.root.querySelector('.aksrt-doc-grid');
|
||||||
if (grid) {
|
if (grid) {
|
||||||
grid.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
grid.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||||
}
|
}
|
||||||
@@ -342,7 +348,7 @@
|
|||||||
this.totalPages = totalPages;
|
this.totalPages = totalPages;
|
||||||
this.currentPage = currentPage;
|
this.currentPage = currentPage;
|
||||||
|
|
||||||
var container = document.querySelector('.aksrt-doc-pagination');
|
var container = this.root.querySelector('.aksrt-doc-pagination');
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
|
|
||||||
if (totalPages <= 1) {
|
if (totalPages <= 1) {
|
||||||
@@ -394,7 +400,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
filterDocItems: function (query) {
|
filterDocItems: function (query) {
|
||||||
var cards = document.querySelectorAll('.aksrt-doc-index-card');
|
var cards = this.root.querySelectorAll('.aksrt-doc-index-card');
|
||||||
if (cards.length > 0) {
|
if (cards.length > 0) {
|
||||||
cards.forEach(function (card) {
|
cards.forEach(function (card) {
|
||||||
var title = card.querySelector('.aksrt-doc-index-card__title');
|
var title = card.querySelector('.aksrt-doc-index-card__title');
|
||||||
@@ -408,7 +414,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var sidebarItems = document.querySelectorAll('.aksrt-doc-sidebar__item');
|
var sidebarItems = this.root.querySelectorAll('.aksrt-doc-sidebar__item');
|
||||||
if (sidebarItems.length > 0) {
|
if (sidebarItems.length > 0) {
|
||||||
sidebarItems.forEach(function (item) {
|
sidebarItems.forEach(function (item) {
|
||||||
var link = item.querySelector('.aksrt-doc-sidebar__link');
|
var link = item.querySelector('.aksrt-doc-sidebar__link');
|
||||||
@@ -446,9 +452,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
window.AksrtFrontend.register('aksrt-page-navs', function (root) {
|
||||||
document.addEventListener('DOMContentLoaded', function () { PAGE_NAVS.init(); });
|
PAGE_NAVS.init(root);
|
||||||
} else {
|
});
|
||||||
PAGE_NAVS.init();
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
+22
-13
@@ -10,9 +10,15 @@
|
|||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function initContentExpand() {
|
function queryAll(root, selector) {
|
||||||
|
var nodes = Array.prototype.slice.call((root || document).querySelectorAll(selector));
|
||||||
|
if (root && root.nodeType === 1 && root.matches(selector)) nodes.unshift(root);
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
function initContentExpand(root) {
|
||||||
// legacy-style: inject .read-more inside .limit-height and expand on click.
|
// legacy-style: inject .read-more inside .limit-height and expand on click.
|
||||||
document.querySelectorAll('.wp-posts-content.limit-height, .limit-height[data-nav]').forEach(function (content) {
|
queryAll(root, '.wp-posts-content.limit-height, .limit-height[data-nav]').forEach(function (content) {
|
||||||
if (content.dataset.aksrtExpandBound === '1') return;
|
if (content.dataset.aksrtExpandBound === '1') return;
|
||||||
content.dataset.aksrtExpandBound = '1';
|
content.dataset.aksrtExpandBound = '1';
|
||||||
|
|
||||||
@@ -58,8 +64,13 @@
|
|||||||
wrap.remove();
|
wrap.remove();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Compatibility: old external expand buttons.
|
var expandDelegateBound = false;
|
||||||
|
|
||||||
|
function bindExpandDelegate() {
|
||||||
|
if (expandDelegateBound) return;
|
||||||
|
expandDelegateBound = true;
|
||||||
document.addEventListener('click', function (event) {
|
document.addEventListener('click', function (event) {
|
||||||
var open = event.target.closest && event.target.closest('.read-more-open');
|
var open = event.target.closest && event.target.closest('.read-more-open');
|
||||||
if (!open) return;
|
if (!open) return;
|
||||||
@@ -73,8 +84,8 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initFlashQueryCleanup() {
|
function initFlashQueryCleanup(root) {
|
||||||
document.querySelectorAll('[data-aksrt-flash-query]').forEach(function (node) {
|
queryAll(root, '[data-aksrt-flash-query]').forEach(function (node) {
|
||||||
var queryKey = node.getAttribute('data-aksrt-flash-query');
|
var queryKey = node.getAttribute('data-aksrt-flash-query');
|
||||||
if (!queryKey || !window.history || typeof window.history.replaceState !== 'function') return;
|
if (!queryKey || !window.history || typeof window.history.replaceState !== 'function') return;
|
||||||
|
|
||||||
@@ -86,14 +97,12 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init(root) {
|
||||||
initContentExpand();
|
root = root || document;
|
||||||
initFlashQueryCleanup();
|
bindExpandDelegate();
|
||||||
|
initContentExpand(root);
|
||||||
|
initFlashQueryCleanup(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
window.AksrtFrontend.register('aksrt-page-template', init);
|
||||||
document.addEventListener('DOMContentLoaded', init);
|
|
||||||
} else {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -567,9 +567,5 @@
|
|||||||
document.addEventListener("click", onDocClick, true);
|
document.addEventListener("click", onDocClick, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === "loading") {
|
window.AksrtFrontend.register("aksrt-pay-vip", bindOnce);
|
||||||
document.addEventListener("DOMContentLoaded", bindOnce, { once: true });
|
|
||||||
} else {
|
|
||||||
bindOnce();
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -271,7 +271,11 @@
|
|||||||
return Promise.resolve({ mode: 'window' });
|
return Promise.resolve({ mode: 'window' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var genericShareBound = false;
|
||||||
|
|
||||||
function bindGenericShareButtons() {
|
function bindGenericShareButtons() {
|
||||||
|
if (genericShareBound) return;
|
||||||
|
genericShareBound = true;
|
||||||
document.addEventListener('click', function (event) {
|
document.addEventListener('click', function (event) {
|
||||||
var node = event.target.closest('[data-share-platform]');
|
var node = event.target.closest('[data-share-platform]');
|
||||||
if (!node || node.closest('#share-dropdown')) return;
|
if (!node || node.closest('#share-dropdown')) return;
|
||||||
@@ -299,9 +303,7 @@
|
|||||||
bindGenericShareButtons();
|
bindGenericShareButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
window.AksrtFrontend.register('aksrt-post-share', function () {
|
||||||
document.addEventListener('DOMContentLoaded', init);
|
|
||||||
} else {
|
|
||||||
init();
|
init();
|
||||||
}
|
});
|
||||||
})();
|
})();
|
||||||
|
|||||||
+16
-16
@@ -37,7 +37,11 @@
|
|||||||
PosterShare.prototype.init = function () {
|
PosterShare.prototype.init = function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
document.querySelectorAll(this.options.triggerSelector).forEach(function (btn) {
|
var scope = this.options.root || document;
|
||||||
|
var triggers = [];
|
||||||
|
if (scope.nodeType === 1 && scope.matches(this.options.triggerSelector)) triggers.push(scope);
|
||||||
|
Array.prototype.push.apply(triggers, scope.querySelectorAll(this.options.triggerSelector));
|
||||||
|
triggers.forEach(function (btn) {
|
||||||
btn.addEventListener('click', function (e) {
|
btn.addEventListener('click', function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
@@ -360,25 +364,21 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 自动初始化
|
// 自动初始化
|
||||||
function autoInit() {
|
function autoInit(root) {
|
||||||
document.querySelectorAll('[data-aksrt-poster]').forEach(function (el) {
|
var triggers = [];
|
||||||
if (el.dataset.posterInit) return;
|
if (root && root.nodeType === 1 && root.matches('[data-aksrt-poster]')) triggers.push(root);
|
||||||
|
Array.prototype.push.apply(triggers, (root || document).querySelectorAll('[data-aksrt-poster]'));
|
||||||
|
if (!triggers.length) return;
|
||||||
|
var pending = triggers.filter(function (el) { return el.dataset.posterInit !== '1'; });
|
||||||
|
if (!pending.length) return;
|
||||||
|
var instance = new PosterShare({ root: root || document, triggerSelector: '[data-aksrt-poster]' });
|
||||||
|
pending.forEach(function (el) {
|
||||||
el.dataset.posterInit = '1';
|
el.dataset.posterInit = '1';
|
||||||
|
el._aksrtPosterShare = instance;
|
||||||
var config = {};
|
|
||||||
try {
|
|
||||||
config = JSON.parse(el.dataset.aksrtPoster || '{}');
|
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
new PosterShare({ triggerSelector: '[data-aksrt-poster]' });
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
window.AksrtFrontend.register('aksrt-poster-share', autoInit);
|
||||||
document.addEventListener('DOMContentLoaded', autoInit);
|
|
||||||
} else {
|
|
||||||
autoInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a poster directly from a unified share payload, without binding
|
* Generate a poster directly from a unified share payload, without binding
|
||||||
|
|||||||
@@ -8,11 +8,14 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function qs(sel, root) {
|
function qs(sel, root) {
|
||||||
|
if (root && root.nodeType === 1 && root.matches(sel)) return root;
|
||||||
return (root || document).querySelector(sel);
|
return (root || document).querySelector(sel);
|
||||||
}
|
}
|
||||||
|
|
||||||
function qsa(sel, root) {
|
function qsa(sel, root) {
|
||||||
return Array.prototype.slice.call((root || document).querySelectorAll(sel));
|
var nodes = Array.prototype.slice.call((root || document).querySelectorAll(sel));
|
||||||
|
if (root && root.nodeType === 1 && root.matches(sel)) nodes.unshift(root);
|
||||||
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ajaxUrl() {
|
function ajaxUrl() {
|
||||||
@@ -21,10 +24,13 @@
|
|||||||
return '/wp-admin/admin-ajax.php';
|
return '/wp-admin/admin-ajax.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
function initModal() {
|
function initModal(root) {
|
||||||
var modal = qs('#post-navs-sz');
|
var modal = qs('#post-navs-sz', root);
|
||||||
if (!modal) return;
|
if (!modal) return;
|
||||||
|
|
||||||
|
if (modal.dataset.aksrtPostsNavModalBound === '1') return;
|
||||||
|
modal.dataset.aksrtPostsNavModalBound = '1';
|
||||||
|
|
||||||
function openModal(e) {
|
function openModal(e) {
|
||||||
if (e) e.preventDefault();
|
if (e) e.preventDefault();
|
||||||
modal.classList.add('is-open', 'show');
|
modal.classList.add('is-open', 'show');
|
||||||
@@ -37,11 +43,11 @@
|
|||||||
modal.setAttribute('aria-hidden', 'true');
|
modal.setAttribute('aria-hidden', 'true');
|
||||||
}
|
}
|
||||||
|
|
||||||
qsa('[data-toggle="modal"][data-target="#post-navs-sz"], a[href="#post-navs-sz"]').forEach(function (el) {
|
qsa('[data-toggle="modal"][data-target="#post-navs-sz"], a[href="#post-navs-sz"]', root).forEach(function (el) {
|
||||||
el.addEventListener('click', openModal);
|
el.addEventListener('click', openModal);
|
||||||
});
|
});
|
||||||
// Title [设置] uses data-target.
|
// Title [设置] uses data-target.
|
||||||
qsa('[data-target="#post-navs-sz"]').forEach(function (el) {
|
qsa('[data-target="#post-navs-sz"]', root).forEach(function (el) {
|
||||||
el.addEventListener('click', openModal);
|
el.addEventListener('click', openModal);
|
||||||
});
|
});
|
||||||
qsa('[data-dismiss="modal"]', modal).forEach(function (btn) {
|
qsa('[data-dismiss="modal"]', modal).forEach(function (btn) {
|
||||||
@@ -55,9 +61,9 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initDragSort() {
|
function initDragSort(root) {
|
||||||
var left = qs('#cat-sortable');
|
var left = qs('#cat-sortable', root);
|
||||||
var right = qs('#cat-sortable-ok');
|
var right = qs('#cat-sortable-ok', root);
|
||||||
if (!left || !right) return;
|
if (!left || !right) return;
|
||||||
|
|
||||||
var dragEl = null;
|
var dragEl = null;
|
||||||
@@ -123,8 +129,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function initSave() {
|
function initSave(root) {
|
||||||
var form = qs('#aksrt-posts-navs-settings');
|
var form = qs('#aksrt-posts-navs-settings', root);
|
||||||
if (!form) return;
|
if (!form) return;
|
||||||
|
|
||||||
form.addEventListener('submit', function (e) {
|
form.addEventListener('submit', function (e) {
|
||||||
@@ -179,9 +185,9 @@
|
|||||||
* Build simple TOC into .posts-nav-box if section-navs hasn't already.
|
* Build simple TOC into .posts-nav-box if section-navs hasn't already.
|
||||||
* Uses category h2 headings inside .posts-navs.
|
* Uses category h2 headings inside .posts-navs.
|
||||||
*/
|
*/
|
||||||
function initFallbackToc() {
|
function initFallbackToc(scope) {
|
||||||
var box = qs('.posts-nav-box');
|
var box = qs('.posts-nav-box', scope);
|
||||||
var root = qs('.posts-navs[data-nav]');
|
var root = qs('.posts-navs[data-nav]', scope);
|
||||||
if (!box || !root) return;
|
if (!box || !root) return;
|
||||||
if (box.querySelector('.posts-nav-lists, .aksrt-section-nav, .toc-list')) return;
|
if (box.querySelector('.posts-nav-lists, .aksrt-section-nav, .toc-list')) return;
|
||||||
|
|
||||||
@@ -230,17 +236,14 @@
|
|||||||
highlight();
|
highlight();
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init(root) {
|
||||||
initModal();
|
root = root || document;
|
||||||
initDragSort();
|
initModal(root);
|
||||||
initSave();
|
initDragSort(root);
|
||||||
|
initSave(root);
|
||||||
// Defer so section-navs.js can own TOC first.
|
// Defer so section-navs.js can own TOC first.
|
||||||
window.setTimeout(initFallbackToc, 50);
|
window.setTimeout(function () { initFallbackToc(root); }, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
window.AksrtFrontend.register('aksrt-posts-navs-page', init);
|
||||||
document.addEventListener('DOMContentLoaded', init);
|
|
||||||
} else {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -218,9 +218,7 @@
|
|||||||
loadEnlighterJS(initEnlighter);
|
loadEnlighterJS(initEnlighter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
window.AksrtFrontend.register('aksrt-precode', function () {
|
||||||
document.addEventListener('DOMContentLoaded', init);
|
|
||||||
} else {
|
|
||||||
init();
|
init();
|
||||||
}
|
});
|
||||||
})();
|
})();
|
||||||
|
|||||||
+45
-17
@@ -6,8 +6,9 @@
|
|||||||
* to initialize or re-initialize them on a given root element.
|
* to initialize or re-initialize them on a given root element.
|
||||||
*
|
*
|
||||||
* Usage:
|
* Usage:
|
||||||
* AksrtFrontend.register('name', initFn); // Register a component
|
* AksrtFrontend.register('name', initFn); // Register a component
|
||||||
* AksrtFrontend.rehydrate(root, 'init'); // Initialize all components
|
* AksrtFrontend.boot(document); // One-time initial page load
|
||||||
|
* AksrtFrontend.rehydrate(root, 'ajax'); // Initialize dynamic content
|
||||||
*
|
*
|
||||||
* @package AKSRT
|
* @package AKSRT
|
||||||
* @since 5.0.0
|
* @since 5.0.0
|
||||||
@@ -16,7 +17,25 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var _registry = [];
|
var _registry = [];
|
||||||
var _initialized = [];
|
var _booted = false;
|
||||||
|
var _bootRoot = null;
|
||||||
|
|
||||||
|
function invoke(entry, root, reason) {
|
||||||
|
try {
|
||||||
|
entry.initFn(root, reason);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('[AKSRT Rehydrate] Error initializing "' + entry.name + '":', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch(root, reason, eventName) {
|
||||||
|
try {
|
||||||
|
root.dispatchEvent(new CustomEvent(eventName, {
|
||||||
|
bubbles: true,
|
||||||
|
detail: { reason: reason }
|
||||||
|
}));
|
||||||
|
} catch (e) { /* IE fallback */ }
|
||||||
|
}
|
||||||
|
|
||||||
window.AksrtFrontend = {
|
window.AksrtFrontend = {
|
||||||
|
|
||||||
@@ -32,10 +51,26 @@
|
|||||||
for (var i = 0; i < _registry.length; i++) {
|
for (var i = 0; i < _registry.length; i++) {
|
||||||
if (_registry[i].name === name) {
|
if (_registry[i].name === name) {
|
||||||
_registry[i].initFn = initFn;
|
_registry[i].initFn = initFn;
|
||||||
|
if (_booted) invoke(_registry[i], _bootRoot || document, 'init');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_registry.push({ name: name, initFn: initFn });
|
var entry = { name: name, initFn: initFn };
|
||||||
|
_registry.push(entry);
|
||||||
|
if (_booted) invoke(entry, _bootRoot || document, 'init');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the one-time initial page boot.
|
||||||
|
*
|
||||||
|
* @param {Element|Document} root The document root to initialize
|
||||||
|
*/
|
||||||
|
boot: function (root) {
|
||||||
|
if (_booted) return;
|
||||||
|
_booted = true;
|
||||||
|
_bootRoot = root || document;
|
||||||
|
this.rehydrate(_bootRoot, 'init');
|
||||||
|
dispatch(_bootRoot, 'init', 'aksrt:ready');
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,21 +88,10 @@
|
|||||||
reason = reason || 'init';
|
reason = reason || 'init';
|
||||||
|
|
||||||
for (var i = 0; i < _registry.length; i++) {
|
for (var i = 0; i < _registry.length; i++) {
|
||||||
var entry = _registry[i];
|
invoke(_registry[i], root, reason);
|
||||||
try {
|
|
||||||
entry.initFn(root, reason);
|
|
||||||
} catch (err) {
|
|
||||||
console.error('[AKSRT Rehydrate] Error initializing "' + entry.name + '":', err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dispatch event so external scripts can hook in
|
dispatch(root, reason, 'aksrt:rehydrated');
|
||||||
try {
|
|
||||||
root.dispatchEvent(new CustomEvent('aksrt:rehydrated', {
|
|
||||||
bubbles: true,
|
|
||||||
detail: { reason: reason }
|
|
||||||
}));
|
|
||||||
} catch (e) { /* IE fallback */ }
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,6 +99,10 @@
|
|||||||
*/
|
*/
|
||||||
getRegistered: function () {
|
getRegistered: function () {
|
||||||
return _registry.map(function (r) { return r.name; });
|
return _registry.map(function (r) { return r.name; });
|
||||||
|
},
|
||||||
|
|
||||||
|
isBooted: function () {
|
||||||
|
return _booted;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+4
-5
@@ -141,6 +141,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function initReportButtons() {
|
function initReportButtons() {
|
||||||
|
if (document.documentElement.dataset.aksrtReportInitialized === '1') return;
|
||||||
|
document.documentElement.dataset.aksrtReportInitialized = '1';
|
||||||
document.addEventListener('click', function (e) {
|
document.addEventListener('click', function (e) {
|
||||||
var btn = e.target.closest('[data-aksrt-report]');
|
var btn = e.target.closest('[data-aksrt-report]');
|
||||||
if (!btn) return;
|
if (!btn) return;
|
||||||
@@ -157,10 +159,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-init on DOMContentLoaded
|
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
|
||||||
if (document.readyState === 'loading') {
|
window.AksrtFrontend.register('aksrt-report', initReportButtons);
|
||||||
document.addEventListener('DOMContentLoaded', initReportButtons);
|
|
||||||
} else {
|
|
||||||
initReportButtons();
|
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
+4
-5
@@ -8,7 +8,10 @@
|
|||||||
|
|
||||||
var cfg = window.aksrtData || {};
|
var cfg = window.aksrtData || {};
|
||||||
|
|
||||||
function initReward() {
|
function initReward(root) {
|
||||||
|
if (root && root.nodeType === 1 && !root.matches('[data-aksrt-reward-root], body, html')) return;
|
||||||
|
if (document.documentElement.dataset.aksrtRewardInitialized === '1') return;
|
||||||
|
document.documentElement.dataset.aksrtRewardInitialized = '1';
|
||||||
var activeTrigger = null;
|
var activeTrigger = null;
|
||||||
|
|
||||||
function operationKey(modal) {
|
function operationKey(modal) {
|
||||||
@@ -125,9 +128,5 @@
|
|||||||
|
|
||||||
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
|
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
|
||||||
window.AksrtFrontend.register('aksrt-reward', initReward);
|
window.AksrtFrontend.register('aksrt-reward', initReward);
|
||||||
} else if (document.readyState === 'loading') {
|
|
||||||
document.addEventListener('DOMContentLoaded', initReward);
|
|
||||||
} else {
|
|
||||||
initReward();
|
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -41,9 +41,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ==================== Dashboard 导航 ==================== */
|
/* ==================== Dashboard 导航 ==================== */
|
||||||
function initDashboardNavigation() {
|
function initDashboardNavigation() {
|
||||||
var tabContainer = document.querySelector('.uc-mobile-tabs');
|
if (document.documentElement.dataset.aksrtUserCenterNavigationInitialized === 'true') return;
|
||||||
if (!tabContainer) return;
|
var tabContainer = document.querySelector('.uc-mobile-tabs');
|
||||||
|
if (!tabContainer) return;
|
||||||
|
document.documentElement.dataset.aksrtUserCenterNavigationInitialized = 'true';
|
||||||
|
|
||||||
var tabs = tabContainer.querySelectorAll('[data-tab]');
|
var tabs = tabContainer.querySelectorAll('[data-tab]');
|
||||||
var sidebarBtns = document.querySelectorAll('.uc-sidebar [data-tab]');
|
var sidebarBtns = document.querySelectorAll('.uc-sidebar [data-tab]');
|
||||||
@@ -322,22 +324,18 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
|
function initAuthForm(root) {
|
||||||
window.AksrtFrontend.register('aksrt-profile-form', function(root) {
|
root = root || document;
|
||||||
initProfileForm(root);
|
var identityRoot = root.matches && root.matches('[data-identity-root]') ? root : root.querySelector('[data-identity-root]');
|
||||||
});
|
if (identityRoot && window.AKSRTUserCenterAuth && typeof window.AKSRTUserCenterAuth.init === 'function') {
|
||||||
}
|
window.AKSRTUserCenterAuth.init(identityRoot);
|
||||||
|
}
|
||||||
function initAuthForm() {
|
|
||||||
var root = document.querySelector('[data-identity-root]');
|
|
||||||
if (root && window.AKSRTUserCenterAuth && typeof window.AKSRTUserCenterAuth.init === 'function') {
|
|
||||||
window.AKSRTUserCenterAuth.init(root);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* ==================== 列表内取消收藏 ==================== */
|
/* ==================== 列表内取消收藏 ==================== */
|
||||||
function initUnfavorite() {
|
function initUnfavorite(root) {
|
||||||
var list = document.querySelector('.profile-list[data-list="favorites"]');
|
root = root || document;
|
||||||
|
var list = root.matches && root.matches('.profile-list[data-list="favorites"]') ? root : root.querySelector('.profile-list[data-list="favorites"]');
|
||||||
if (!list) return;
|
if (!list) return;
|
||||||
|
|
||||||
list.addEventListener('click', function(e) {
|
list.addEventListener('click', function(e) {
|
||||||
@@ -395,9 +393,9 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initPostDeletion() {
|
function initPostDeletion(root) {
|
||||||
if (document.documentElement.dataset.aksrtPostDeletionBound === 'true') return;
|
if (document.documentElement.dataset.aksrtPostDeletionBound === 'true') return;
|
||||||
document.documentElement.dataset.aksrtPostDeletionBound = 'true';
|
document.documentElement.dataset.aksrtPostDeletionBound = 'true';
|
||||||
document.addEventListener('click', function(e) {
|
document.addEventListener('click', function(e) {
|
||||||
var btn = e.target && e.target.closest ? e.target.closest('[data-action="delete-post"]') : null;
|
var btn = e.target && e.target.closest ? e.target.closest('[data-action="delete-post"]') : null;
|
||||||
if (!btn || btn.disabled || !confirm('确定删除这篇文章?')) return;
|
if (!btn || btn.disabled || !confirm('确定删除这篇文章?')) return;
|
||||||
@@ -423,12 +421,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ==================== 通知中心 ==================== */
|
/* ==================== 通知中心 ==================== */
|
||||||
function initNotifications() {
|
function initNotifications(root) {
|
||||||
var list = document.getElementById('aksrt-notification-list');
|
root = root || document;
|
||||||
var markAllBtn = document.getElementById('aksrt-mark-all-notifications-read');
|
var list = root.matches && root.matches('#aksrt-notification-list') ? root : root.querySelector('#aksrt-notification-list');
|
||||||
var markSelectedBtn = document.getElementById('aksrt-mark-selected-notifications-read');
|
var markAllBtn = list && list.ownerDocument.getElementById('aksrt-mark-all-notifications-read');
|
||||||
var deleteSelectedBtn = document.getElementById('aksrt-delete-selected-notifications');
|
var markSelectedBtn = list && list.ownerDocument.getElementById('aksrt-mark-selected-notifications-read');
|
||||||
if (!list) return;
|
var deleteSelectedBtn = list && list.ownerDocument.getElementById('aksrt-delete-selected-notifications');
|
||||||
|
if (!list || list.dataset.aksrtNotificationsInitialized === 'true') return;
|
||||||
|
list.dataset.aksrtNotificationsInitialized = 'true';
|
||||||
|
|
||||||
function markRead(notificationId, markAll) {
|
function markRead(notificationId, markAll) {
|
||||||
var body = new URLSearchParams();
|
var body = new URLSearchParams();
|
||||||
@@ -1033,42 +1033,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
|
|
||||||
window.AksrtFrontend.register('aksrt-settings', function(root) {
|
|
||||||
initSettings(root);
|
|
||||||
initBindPhone(root);
|
|
||||||
});
|
|
||||||
window.AksrtFrontend.register('aksrt-notification-preferences', function(root) {
|
|
||||||
initNotificationPreferences(root);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
function initNavigationOnce() {
|
||||||
if (document.readyState === 'loading') {
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
initDashboardNavigation();
|
initDashboardNavigation();
|
||||||
initProfileForm();
|
|
||||||
initAuthForm();
|
|
||||||
initUnfavorite();
|
|
||||||
initPostDeletion();
|
initPostDeletion();
|
||||||
initNotifications();
|
}
|
||||||
initNotificationPreferences();
|
|
||||||
initSettings();
|
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
|
||||||
initBindPhone();
|
window.AksrtFrontend.register('aksrt-user-center', function(root) {
|
||||||
initSettingsCallbackToast();
|
initNavigationOnce();
|
||||||
});
|
initProfileForm(root);
|
||||||
} else {
|
initAuthForm(root);
|
||||||
initDashboardNavigation();
|
initUnfavorite(root);
|
||||||
initProfileForm();
|
initNotifications(root);
|
||||||
initAuthForm();
|
initNotificationPreferences(root);
|
||||||
initUnfavorite();
|
initSettings(root);
|
||||||
initPostDeletion();
|
initBindPhone(root);
|
||||||
initNotifications();
|
initSettingsCallbackToast();
|
||||||
initNotificationPreferences();
|
});
|
||||||
initSettings();
|
}
|
||||||
initBindPhone();
|
|
||||||
initSettingsCallbackToast();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 绑定手机
|
// 绑定手机
|
||||||
function initBindPhone(root) {
|
function initBindPhone(root) {
|
||||||
|
|||||||
@@ -59,17 +59,8 @@ tbquire.config({
|
|||||||
'translate' : 'libs/translate.min',
|
'translate' : 'libs/translate.min',
|
||||||
'waterfall' : 'waterfall.min',
|
'waterfall' : 'waterfall.min',
|
||||||
'enlighterjs' : 'enlighter/enlighterjs.min',
|
'enlighterjs' : 'enlighter/enlighterjs.min',
|
||||||
'section-navs' : 'section-navs.min',
|
|
||||||
|
|
||||||
'poster-share' : 'poster-share.min',
|
|
||||||
'comment' : 'comment.min',
|
|
||||||
'page-template' : 'page-template.min',
|
|
||||||
'page-edit' : 'page-edit.min',
|
|
||||||
'author' : 'author.min',
|
|
||||||
'page-navs' : 'page-navs.min',
|
|
||||||
'input-expand' : 'input-expand.min',
|
|
||||||
'mini-touch' : 'mini-touch.min',
|
'mini-touch' : 'mini-touch.min',
|
||||||
'mini-upload' : 'mini-upload.min',
|
|
||||||
'editextend' : 'editextend.min',
|
'editextend' : 'editextend.min',
|
||||||
'petite-vue' : 'libs/petite-vue.iife',
|
'petite-vue' : 'libs/petite-vue.iife',
|
||||||
'svg-icon' : 'svg-icon',
|
'svg-icon' : 'svg-icon',
|
||||||
|
|||||||
+16
-39
@@ -1872,7 +1872,7 @@ function post_ajax(_this, con, jcon, item, loader, pag, next, trigger, replace,
|
|||||||
}
|
}
|
||||||
|
|
||||||
swiper_tab_AutoHeight($con);
|
swiper_tab_AutoHeight($con);
|
||||||
auto_fun();
|
window.AksrtFrontend.rehydrate($con[0], 'ajax');
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return !1;
|
return !1;
|
||||||
@@ -1884,7 +1884,7 @@ _win.bd.on('click', '[remote-box]', function () {
|
|||||||
if (remote) {
|
if (remote) {
|
||||||
jQuery.post(remote, null, function (data) {
|
jQuery.post(remote, null, function (data) {
|
||||||
_this.html(data).removeAttr('remote-box');
|
_this.html(data).removeAttr('remote-box');
|
||||||
auto_fun();
|
window.AksrtFrontend.rehydrate(_this[0], 'ajax');
|
||||||
_this.trigger('aksrt:remote-loaded');
|
_this.trigger('aksrt:remote-loaded');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2176,7 +2176,7 @@ _win.bd.on('show.bs.modal loaded.bs.modal', '.modal:not(.flex)', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
_win.bd.on('show.bs.modal loaded.bs.modal', '.modal', function () {
|
_win.bd.on('show.bs.modal loaded.bs.modal', '.modal', function () {
|
||||||
auto_fun();
|
window.AksrtFrontend.rehydrate(this, 'modal');
|
||||||
});
|
});
|
||||||
|
|
||||||
_win.modal_z_index = 1050;
|
_win.modal_z_index = 1050;
|
||||||
@@ -2420,7 +2420,9 @@ function z_auto() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.auto_fun = debounce(z_auto_fun, 100);
|
window.auto_fun = debounce(function (root) {
|
||||||
|
window.AksrtFrontend.rehydrate(root && root.nodeType ? root : document, 'ajax');
|
||||||
|
}, 100);
|
||||||
function z_auto_fun() {
|
function z_auto_fun() {
|
||||||
jQuery(document).trigger('auto_fun');
|
jQuery(document).trigger('auto_fun');
|
||||||
|
|
||||||
@@ -2433,9 +2435,6 @@ function z_auto_fun() {
|
|||||||
//可复制
|
//可复制
|
||||||
jQuery('.cloneable').cloneable();
|
jQuery('.cloneable').cloneable();
|
||||||
|
|
||||||
//倒计时
|
|
||||||
jQuery('[data-countdown]').countdown();
|
|
||||||
|
|
||||||
auto_maxHeight();
|
auto_maxHeight();
|
||||||
//兼容性图片懒加载
|
//兼容性图片懒加载
|
||||||
jQuery('img[data-src]:not(.lazyload,.lazyloaded,.lazyloading,.swiper-lazy)').addClass('lazyload');
|
jQuery('img[data-src]:not(.lazyload,.lazyloaded,.lazyloading,.swiper-lazy)').addClass('lazyload');
|
||||||
@@ -2446,13 +2445,6 @@ function z_auto_fun() {
|
|||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
|
|
||||||
jQuery('.dropdown-code,.dropdown-image,.dropdown-quick-often').length && tbquire(['input-expand']);
|
|
||||||
/**上传图片 */
|
|
||||||
jQuery('[aksrtupload]').length && tbquire(['mini-upload']);
|
|
||||||
|
|
||||||
//海报分享
|
|
||||||
jQuery('[poster-share]').length && tbquire(['poster-share']); //海报分享
|
|
||||||
|
|
||||||
/* 提示工具*/
|
/* 提示工具*/
|
||||||
jQuery("[data-toggle='tooltip']").tooltip({
|
jQuery("[data-toggle='tooltip']").tooltip({
|
||||||
container: 'body',
|
container: 'body',
|
||||||
@@ -3095,21 +3087,6 @@ _win.bd.on('input focus', 'textarea[autoHeight]', function () {
|
|||||||
_win.bd.on('click', '.rewards', function () {
|
_win.bd.on('click', '.rewards', function () {
|
||||||
jQuery('#rewards-popover').modal('show');
|
jQuery('#rewards-popover').modal('show');
|
||||||
});
|
});
|
||||||
//用户中心
|
|
||||||
_win.bd.hasClass('author') && tbquire(['author']);
|
|
||||||
|
|
||||||
//文章导航
|
|
||||||
_win.bd.hasClass('page-template-postsnavs') && _win.bd.hasClass('logged-admin') && tbquire(['page-navs']);
|
|
||||||
//前台编辑
|
|
||||||
jQuery('#modal_admin_set').length && tbquire(['page-edit']);
|
|
||||||
//评论
|
|
||||||
jQuery('#commentform,#postcomments').length && tbquire(['comment']);
|
|
||||||
//通用模板js文件
|
|
||||||
_win.bd.hasClass('page-template') && tbquire(['page-template']);
|
|
||||||
|
|
||||||
//微信分享
|
|
||||||
window.WeChatShareDate && tbquire(['weixin-share']);
|
|
||||||
|
|
||||||
//搜索关键词高亮
|
//搜索关键词高亮
|
||||||
if (_win.bd.hasClass('search')) {
|
if (_win.bd.hasClass('search')) {
|
||||||
var val = jQuery('.search-desc-text .search-key').text();
|
var val = jQuery('.search-desc-text .search-key').text();
|
||||||
@@ -3520,7 +3497,7 @@ jQuery.fn.AutoSearch = function () {
|
|||||||
_this.removeClass(loading);
|
_this.removeClass(loading);
|
||||||
_remind.html(result.remind || '');
|
_remind.html(result.remind || '');
|
||||||
_icon.html(_icon_html);
|
_icon.html(_icon_html);
|
||||||
auto_fun();
|
window.AksrtFrontend.rehydrate(_container[0], 'ajax');
|
||||||
},
|
},
|
||||||
'json'
|
'json'
|
||||||
);
|
);
|
||||||
@@ -3969,12 +3946,6 @@ function posts_limit_height() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto_fun();
|
|
||||||
thumb_dplayer(_wid > 640 ? '.posts-item .item-thumbnail,.forum-lists-cover' : '.posts-item,.forum-posts', '.video-thumb-box[video-url]');
|
|
||||||
|
|
||||||
//页面加载之后自动点击
|
|
||||||
jQuery('[load-click]').attr('no-scroll', true).click();
|
|
||||||
|
|
||||||
//图片延迟懒加载-ias自动加载
|
//图片延迟懒加载-ias自动加载
|
||||||
jQuery(document).on('lazybeforeunveil', function (e) {
|
jQuery(document).on('lazybeforeunveil', function (e) {
|
||||||
var _this = jQuery(e.target);
|
var _this = jQuery(e.target);
|
||||||
@@ -4553,7 +4524,7 @@ _win.bd.on('click', '.customize-preview-widget-edit', function (e) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//页面加载完毕之后加载的函数
|
//页面加载完毕之后加载的函数
|
||||||
jQuery(document).ready(function () {
|
function initLegacyDocumentReady() {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
//页面加载完毕之后再延迟两秒加载的函数
|
//页面加载完毕之后再延迟两秒加载的函数
|
||||||
|
|
||||||
@@ -4700,8 +4671,6 @@ jQuery(document).ready(function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/*文章目录*/
|
/*文章目录*/
|
||||||
jQuery('[data-nav] h1,[data-nav] h2,[data-nav] h3,[data-nav] h4').length > 2 && tbquire(['section-navs']);
|
|
||||||
|
|
||||||
//手势控制
|
//手势控制
|
||||||
jQuery('[mini-touch]').each(function () {
|
jQuery('[mini-touch]').each(function () {
|
||||||
var _this = jQuery(this);
|
var _this = jQuery(this);
|
||||||
@@ -4718,4 +4687,12 @@ jQuery(document).ready(function () {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
window.AksrtFrontend.register('aksrt-legacy-main', function (root, reason) {
|
||||||
|
z_auto_fun();
|
||||||
|
if (reason !== 'init') return;
|
||||||
|
initLegacyDocumentReady();
|
||||||
|
thumb_dplayer(_wid > 640 ? '.posts-item .item-thumbnail,.forum-lists-cover' : '.posts-item,.forum-posts', '.video-thumb-box[video-url]');
|
||||||
|
jQuery('[load-click]').attr('no-scroll', true).click();
|
||||||
});
|
});
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -1,46 +0,0 @@
|
|||||||
//文章导航
|
|
||||||
jQuery("button[evt='action']").on("click", function (t) {
|
|
||||||
t = t || window.event;
|
|
||||||
var a = t.target || t.srcElement,
|
|
||||||
e = jQuery(a),
|
|
||||||
n = e.parents("form"),
|
|
||||||
r = n.serializeObject(),
|
|
||||||
c = [];
|
|
||||||
return jQuery("#cat-sortable-ok .sortable-cat-item").each(function () {
|
|
||||||
c.push(jQuery(this).attr("data-id"));
|
|
||||||
}), r.navs_show_cat_id = c, save_userdata(r, aksrt__("save_success"), "reload"), !1;
|
|
||||||
});
|
|
||||||
|
|
||||||
function save_userdata(b, c, d) {
|
|
||||||
notyf(aksrt__("processing_wait"), "load", "", "user_ajax"),
|
|
||||||
c = c || aksrt__("done");
|
|
||||||
jQuery.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: _win.uri + '/action/post_navs.php',
|
|
||||||
data: b,
|
|
||||||
dataType: "json",
|
|
||||||
success: function (n) {
|
|
||||||
if (n.error) {
|
|
||||||
n.msg && notyf(n.msg, (n.error ? 'danger' : ""), "", "user_ajax");
|
|
||||||
} else {
|
|
||||||
notyf(n.msg || c, "", "", "user_ajax");
|
|
||||||
"reload" == d && location.reload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
jQuery(document).ready(function () {
|
|
||||||
jQuery("#cat-sortable").length && tbquire(["sortablejs"], function () {
|
|
||||||
var e = document.getElementById("cat-sortable"),
|
|
||||||
t = document.getElementById("cat-sortable-ok"),
|
|
||||||
a = {
|
|
||||||
group: "cat_shared",
|
|
||||||
multiDrag: !0,
|
|
||||||
chosenClass: "chosen",
|
|
||||||
fallbackClass: !0,
|
|
||||||
animation: 400
|
|
||||||
};
|
|
||||||
Sortable.create(e, a), Sortable.create(t, a);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Vendored
-1
@@ -1 +0,0 @@
|
|||||||
function save_userdata(a,t,e){notyf(aksrt__("processing_wait"),"load","","user_ajax"),t=t||aksrt__("done"),jQuery.ajax({type:"POST",url:_win.uri+"/action/post_navs.php",data:a,dataType:"json",success:function(a){a.error?a.msg&¬yf(a.msg,a.error?"danger":"","","user_ajax"):(notyf(a.msg||t,"","","user_ajax"),"reload"==e&&location.reload())}})}jQuery("button[evt='action']").on("click",function(a){a=a||window.event;var t=a.target||a.srcElement,e=jQuery(t),o=e.parents("form"),r=o.serializeObject(),s=[];return jQuery("#cat-sortable-ok .sortable-cat-item").each(function(){s.push(jQuery(this).attr("data-id"))}),r.navs_show_cat_id=s,save_userdata(r,aksrt__("save_success"),"reload"),!1}),jQuery(document).ready(function(){jQuery("#cat-sortable").length&&tbquire(["sortablejs"],function(){var a=document.getElementById("cat-sortable"),t=document.getElementById("cat-sortable-ok"),e={group:"cat_shared",multiDrag:!0,chosenClass:"chosen",fallbackClass:!0,animation:400};Sortable.create(a,e),Sortable.create(t,e)})});
|
|
||||||
+27
-22
@@ -40,8 +40,10 @@
|
|||||||
return count >= MIN_HEADINGS ? html : '';
|
return count >= MIN_HEADINGS ? html : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
function fillBoxes(listsHtml) {
|
function fillBoxes(listsHtml, scope) {
|
||||||
document.querySelectorAll(NAVBOX).forEach(function (box) {
|
var boxes = Array.prototype.slice.call(scope.querySelectorAll(NAVBOX));
|
||||||
|
if (scope.nodeType === 1 && scope.matches(NAVBOX)) boxes.unshift(scope);
|
||||||
|
boxes.forEach(function (box) {
|
||||||
var existing = box.querySelector('.' + NAV_CLASS);
|
var existing = box.querySelector('.' + NAV_CLASS);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
existing.innerHTML = listsHtml;
|
existing.innerHTML = listsHtml;
|
||||||
@@ -75,7 +77,13 @@
|
|||||||
window.scrollTo({ top: top, behavior: 'smooth' });
|
window.scrollTo({ top: top, behavior: 'smooth' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var clicksBound = false;
|
||||||
|
var scrollspyBound = false;
|
||||||
|
var autoHashHandled = false;
|
||||||
|
|
||||||
function bindClicks() {
|
function bindClicks() {
|
||||||
|
if (clicksBound) return;
|
||||||
|
clicksBound = true;
|
||||||
document.addEventListener('click', function (e) {
|
document.addEventListener('click', function (e) {
|
||||||
var a = e.target && e.target.closest ? e.target.closest('.' + NAV_CLASS + ' a[href^="#"]') : null;
|
var a = e.target && e.target.closest ? e.target.closest('.' + NAV_CLASS + ' a[href^="#"]') : null;
|
||||||
if (!a) return;
|
if (!a) return;
|
||||||
@@ -87,9 +95,11 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function scrollspy() {
|
function scrollspy(scope) {
|
||||||
var links = document.querySelectorAll('.' + NAV_CLASS + ' a[href^="#"]');
|
if (scrollspyBound) return;
|
||||||
|
var links = scope.querySelectorAll('.' + NAV_CLASS + ' a[href^="#"]');
|
||||||
if (!links.length) return;
|
if (!links.length) return;
|
||||||
|
scrollspyBound = true;
|
||||||
var map = [];
|
var map = [];
|
||||||
links.forEach(function (a) {
|
links.forEach(function (a) {
|
||||||
var id = a.getAttribute('href').slice(1);
|
var id = a.getAttribute('href').slice(1);
|
||||||
@@ -111,37 +121,32 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function autoHash() {
|
function autoHash() {
|
||||||
if (window.location.hash) {
|
if (autoHashHandled || !window.location.hash) return;
|
||||||
setTimeout(function () {
|
autoHashHandled = true;
|
||||||
smoothTo(window.location.hash);
|
setTimeout(function () {
|
||||||
}, 40);
|
smoothTo(window.location.hash);
|
||||||
}
|
}, 40);
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init(scope) {
|
||||||
|
scope = scope || document;
|
||||||
if (document.querySelector('.posts-nav-box .toc-list, .posts-nav-box.toc-widget .toc-list')) {
|
if (document.querySelector('.posts-nav-box .toc-list, .posts-nav-box.toc-widget .toc-list')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var root = document.querySelector('[data-nav], .article-content, .entry-content, main.article');
|
var root = scope.nodeType === 1 && scope.matches('[data-nav], .article-content, .entry-content, main.article')
|
||||||
|
? scope
|
||||||
|
: scope.querySelector('[data-nav], .article-content, .entry-content, main.article');
|
||||||
if (!root) return;
|
if (!root) return;
|
||||||
var listsHtml = buildLists(root);
|
var listsHtml = buildLists(root);
|
||||||
if (!listsHtml) return;
|
if (!listsHtml) return;
|
||||||
if (!document.querySelector(NAVBOX) && !document.querySelector('.' + NAV_CLASS)) {
|
if (!document.querySelector(NAVBOX) && !document.querySelector('.' + NAV_CLASS)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fillBoxes(listsHtml);
|
fillBoxes(listsHtml, document);
|
||||||
bindClicks();
|
bindClicks();
|
||||||
scrollspy();
|
scrollspy(document);
|
||||||
autoHash();
|
autoHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
|
window.AksrtFrontend.register('aksrt-section-navs', init);
|
||||||
window.AksrtFrontend.register('aksrt-section-navs', function () {
|
|
||||||
init();
|
|
||||||
});
|
|
||||||
} else if (document.readyState === 'loading') {
|
|
||||||
document.addEventListener('DOMContentLoaded', init);
|
|
||||||
} else {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
+17
-12
@@ -29,8 +29,11 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initSignin() {
|
function initSignin(scope) {
|
||||||
var buttons = Array.prototype.slice.call(document.querySelectorAll('[data-signin-btn]'));
|
scope = scope || document;
|
||||||
|
var buttons = [];
|
||||||
|
if (scope.nodeType === 1 && scope.matches('[data-signin-btn]')) buttons.push(scope);
|
||||||
|
if (scope.querySelectorAll) scope.querySelectorAll('[data-signin-btn]').forEach(function (button) { buttons.push(button); });
|
||||||
var freshButtons = buttons.filter(function (button) {
|
var freshButtons = buttons.filter(function (button) {
|
||||||
return button.dataset.aksrtSigninInitialized !== '1';
|
return button.dataset.aksrtSigninInitialized !== '1';
|
||||||
});
|
});
|
||||||
@@ -40,12 +43,19 @@
|
|||||||
button.dataset.aksrtSigninInitialized = '1';
|
button.dataset.aksrtSigninInitialized = '1';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function elements(selector) {
|
||||||
|
var items = [];
|
||||||
|
if (scope.nodeType === 1 && scope.matches(selector)) items.push(scope);
|
||||||
|
if (scope.querySelectorAll) scope.querySelectorAll(selector).forEach(function (item) { items.push(item); });
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
function statuses() {
|
function statuses() {
|
||||||
return document.querySelectorAll('[data-signin-status]');
|
return elements('[data-signin-status]');
|
||||||
}
|
}
|
||||||
|
|
||||||
function currentButtons() {
|
function currentButtons() {
|
||||||
return document.querySelectorAll('[data-signin-btn]');
|
return elements('[data-signin-btn]');
|
||||||
}
|
}
|
||||||
|
|
||||||
function setStatus(text) {
|
function setStatus(text) {
|
||||||
@@ -98,7 +108,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function captchaMount() {
|
function captchaMount() {
|
||||||
return document.querySelector('[data-signin-captcha]');
|
if (scope.nodeType === 1 && scope.matches('[data-signin-captcha]')) return scope;
|
||||||
|
return scope.querySelector ? scope.querySelector('[data-signin-captcha]') : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function doSignin(captchaPayload) {
|
function doSignin(captchaPayload) {
|
||||||
@@ -115,7 +126,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
notyf(result.json.message || '签到成功', 'success', 5, 'aksrt-balance-signin-toast');
|
notyf(result.json.message || '签到成功', 'success', 5, 'aksrt-balance-signin-toast');
|
||||||
document.querySelectorAll('[data-credits-value]').forEach(function (element) {
|
elements('[data-credits-value]').forEach(function (element) {
|
||||||
element.textContent = Number(result.json.balance || 0).toLocaleString();
|
element.textContent = Number(result.json.balance || 0).toLocaleString();
|
||||||
});
|
});
|
||||||
setButtonState('done');
|
setButtonState('done');
|
||||||
@@ -149,12 +160,6 @@
|
|||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
|
||||||
document.addEventListener('DOMContentLoaded', initSignin);
|
|
||||||
} else {
|
|
||||||
initSignin();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
|
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
|
||||||
window.AksrtFrontend.register('signin', initSignin);
|
window.AksrtFrontend.register('signin', initSignin);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,11 @@
|
|||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var el = document.getElementById('aksrt-site-notice');
|
window.AksrtFrontend.register('aksrt-site-notice', function (root) {
|
||||||
if (!el) return;
|
root = root || document;
|
||||||
|
var el = root.nodeType === 1 && root.matches('#aksrt-site-notice') ? root : root.querySelector('#aksrt-site-notice');
|
||||||
|
if (!el || el.dataset.aksrtNoticeBound === '1') return;
|
||||||
|
el.dataset.aksrtNoticeBound = '1';
|
||||||
|
|
||||||
// 弹窗周期(小时),0=永不过期
|
// 弹窗周期(小时),0=永不过期
|
||||||
var expiresHours = parseInt(el.dataset.expires || '24', 10) || 0;
|
var expiresHours = parseInt(el.dataset.expires || '24', 10) || 0;
|
||||||
@@ -88,4 +91,5 @@
|
|||||||
// Delay slightly so it doesn't flash on fast navigations
|
// Delay slightly so it doesn't flash on fast navigations
|
||||||
setTimeout(show, 500);
|
setTimeout(show, 500);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -19,7 +19,10 @@
|
|||||||
if (typeof window.notyf === 'function') window.notyf(message, type);
|
if (typeof window.notyf === 'function') window.notyf(message, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('click', function (event) {
|
function bindOnce() {
|
||||||
|
if (document.__aksrtUserBadgeActionsBound) return;
|
||||||
|
document.__aksrtUserBadgeActionsBound = true;
|
||||||
|
document.addEventListener('click', function (event) {
|
||||||
var button = event.target.closest('[data-aksrt-badge-action]');
|
var button = event.target.closest('[data-aksrt-badge-action]');
|
||||||
if (!button || button.classList.contains('is-loading')) return;
|
if (!button || button.classList.contains('is-loading')) return;
|
||||||
|
|
||||||
@@ -56,5 +59,8 @@
|
|||||||
button.removeAttribute('aria-busy');
|
button.removeAttribute('aria-busy');
|
||||||
notice(error.message || '网络错误', 'danger');
|
notice(error.message || '网络错误', 'danger');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
window.AksrtFrontend.register('aksrt-user-badge-actions', bindOnce);
|
||||||
})(window, document);
|
})(window, document);
|
||||||
|
|||||||
+14
-11
@@ -219,7 +219,10 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ── 剧集切换按钮事件委托 ──
|
// ── 剧集切换按钮事件委托 ──
|
||||||
document.addEventListener('click', function (e) {
|
function bindEpisodeSwitch() {
|
||||||
|
if (document.__aksrtVideoEpisodeBound) return;
|
||||||
|
document.__aksrtVideoEpisodeBound = true;
|
||||||
|
document.addEventListener('click', function (e) {
|
||||||
var switchBtn = e.target.closest('.switch-video, .switch-iframe');
|
var switchBtn = e.target.closest('.switch-video, .switch-iframe');
|
||||||
if (!switchBtn) return;
|
if (!switchBtn) return;
|
||||||
|
|
||||||
@@ -256,24 +259,24 @@
|
|||||||
});
|
});
|
||||||
switchBtn.classList.add('is-active');
|
switchBtn.classList.add('is-active');
|
||||||
switchBtn.classList.add('active');
|
switchBtn.classList.add('active');
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ── Public API ──
|
// ── Public API ──
|
||||||
|
|
||||||
window.AksrtVideoPlayer = AksrtVideoPlayer;
|
window.AksrtVideoPlayer = AksrtVideoPlayer;
|
||||||
|
|
||||||
// ── Auto-init ──
|
function init(root) {
|
||||||
|
root = root || document;
|
||||||
function init() {
|
|
||||||
injectStyle();
|
injectStyle();
|
||||||
document.querySelectorAll('[data-aksrt-video]').forEach(function (el) {
|
bindEpisodeSwitch();
|
||||||
|
var elements = [];
|
||||||
|
if (root && root.nodeType === 1 && root.matches('[data-aksrt-video]')) elements.push(root);
|
||||||
|
Array.prototype.push.apply(elements, root.querySelectorAll('[data-aksrt-video]'));
|
||||||
|
elements.forEach(function (el) {
|
||||||
new AksrtVideoPlayer(el);
|
new AksrtVideoPlayer(el);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
window.AksrtFrontend.register('aksrt-video-player', init);
|
||||||
document.addEventListener('DOMContentLoaded', init);
|
|
||||||
} else {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
+19
-11
@@ -154,24 +154,32 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function autoInit() {
|
function autoInit(root) {
|
||||||
document.querySelectorAll('[data-aksrt-waterfall]').forEach(function (el) {
|
var elements = [];
|
||||||
|
if (root && root.nodeType === 1 && root.matches('[data-aksrt-waterfall]')) elements.push(root);
|
||||||
|
Array.prototype.push.apply(elements, (root || document).querySelectorAll('[data-aksrt-waterfall]'));
|
||||||
|
elements.forEach(function (el) {
|
||||||
|
if (el._aksrtWaterfall) return;
|
||||||
var cols = parseInt(el.dataset.aksrtWaterfallColumns) || 0;
|
var cols = parseInt(el.dataset.aksrtWaterfallColumns) || 0;
|
||||||
var gap = parseInt(el.dataset.aksrtWaterfallGap) || 16;
|
var gap = parseInt(el.dataset.aksrtWaterfallGap) || 16;
|
||||||
waterfallInstances.push(new Waterfall(el, { columns: cols, gap: gap }));
|
el._aksrtWaterfall = new Waterfall(el, { columns: cols, gap: gap });
|
||||||
|
waterfallInstances.push(el._aksrtWaterfall);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('post_ajax.ed', relayoutAll);
|
function bindGlobalEvents() {
|
||||||
document.addEventListener('aksrt:posts:rendered', relayoutAll);
|
if (document.__aksrtWaterfallEventsBound) return;
|
||||||
document.addEventListener('lazyloaded', relayoutAll, true);
|
document.__aksrtWaterfallEventsBound = true;
|
||||||
|
document.addEventListener('post_ajax.ed', relayoutAll);
|
||||||
if (document.readyState === 'loading') {
|
document.addEventListener('aksrt:posts:rendered', relayoutAll);
|
||||||
document.addEventListener('DOMContentLoaded', autoInit);
|
document.addEventListener('lazyloaded', relayoutAll, true);
|
||||||
} else {
|
|
||||||
autoInit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.AksrtFrontend.register('aksrt-waterfall', function (root) {
|
||||||
|
bindGlobalEvents();
|
||||||
|
autoInit(root);
|
||||||
|
});
|
||||||
|
|
||||||
// Export to global
|
// Export to global
|
||||||
window.AksrtWaterfall = Waterfall;
|
window.AksrtWaterfall = Waterfall;
|
||||||
window.AksrtInfiniteScroll = InfiniteScroll;
|
window.AksrtInfiniteScroll = InfiniteScroll;
|
||||||
|
|||||||
+5
-2
@@ -249,7 +249,10 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
window.AksrtFrontend.register('aksrt-yiyan', function (root) {
|
||||||
document.querySelectorAll('[data-aksrt-yiyan]').forEach(initYiyan);
|
var elements = [];
|
||||||
|
if (root && root.nodeType === 1 && root.matches('[data-aksrt-yiyan]')) elements.push(root);
|
||||||
|
Array.prototype.push.apply(elements, (root || document).querySelectorAll('[data-aksrt-yiyan]'));
|
||||||
|
elements.forEach(initYiyan);
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|||||||
+21
-21
@@ -166,7 +166,7 @@
|
|||||||
}
|
}
|
||||||
if (data.paginate_html) container.insertAdjacentHTML('beforeend', data.paginate_html);
|
if (data.paginate_html) container.insertAdjacentHTML('beforeend', data.paginate_html);
|
||||||
container.dataset.page = String(data.page || page);
|
container.dataset.page = String(data.page || page);
|
||||||
scan(container);
|
window.AksrtFrontend.rehydrate(container, 'ajax');
|
||||||
})
|
})
|
||||||
.catch(function () { container.innerHTML = errorMarkup(); })
|
.catch(function () { container.innerHTML = errorMarkup(); })
|
||||||
.finally(function () {
|
.finally(function () {
|
||||||
@@ -262,28 +262,28 @@
|
|||||||
requestAnimationFrame(frame);
|
requestAnimationFrame(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function elementsIn(root, selector) {
|
||||||
|
var scope = root || document;
|
||||||
|
var elements = [];
|
||||||
|
if (scope.matches && scope.matches(selector)) elements.push(scope);
|
||||||
|
if (scope.querySelectorAll) {
|
||||||
|
scope.querySelectorAll(selector).forEach(function (element) { elements.push(element); });
|
||||||
|
}
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
function scan(root) {
|
function scan(root) {
|
||||||
var scope = root || document;
|
var scope = root || document;
|
||||||
scope.querySelectorAll('.aksrt-widget-video[data-video-url]').forEach(initVideo);
|
elementsIn(scope, '.aksrt-widget-video[data-video-url]').forEach(initVideo);
|
||||||
scope.querySelectorAll('.aksrt-widget-toc').forEach(initToc);
|
elementsIn(scope, '.aksrt-widget-toc').forEach(initToc);
|
||||||
scope.querySelectorAll('.aksrt-widget-quote').forEach(initQuote);
|
elementsIn(scope, '.aksrt-widget-quote').forEach(initQuote);
|
||||||
scope.querySelectorAll('[data-widget-items]').forEach(initItems);
|
elementsIn(scope, '[data-widget-items]').forEach(initItems);
|
||||||
scope.querySelectorAll('.aksrt-widget-tabs, .widget-tab-post').forEach(initTabs);
|
elementsIn(scope, '.aksrt-widget-tabs, .widget-tab-post').forEach(initTabs);
|
||||||
scope.querySelectorAll('.aksrt-faq').forEach(initFaq);
|
elementsIn(scope, '.aksrt-faq').forEach(initFaq);
|
||||||
scope.querySelectorAll('.aksrt-feature-intro').forEach(initFeatures);
|
elementsIn(scope, '.aksrt-feature-intro').forEach(initFeatures);
|
||||||
scope.querySelectorAll('[data-count-up]').forEach(initCount);
|
elementsIn(scope, '[data-count-up]').forEach(initCount);
|
||||||
if (typeof window.VanillaTilt !== 'undefined') scope.querySelectorAll('[data-aksrt-tilt]').forEach(function (el) { if (once(el, 'Tilt')) window.VanillaTilt.init(el); });
|
if (typeof window.VanillaTilt !== 'undefined') elementsIn(scope, '[data-aksrt-tilt]').forEach(function (el) { if (once(el, 'Tilt')) window.VanillaTilt.init(el); });
|
||||||
}
|
}
|
||||||
|
|
||||||
function ready() {
|
window.AksrtFrontend.register('aksrt-widgets', scan);
|
||||||
scan(document);
|
|
||||||
if ('MutationObserver' in window) {
|
|
||||||
new MutationObserver(function (mutations) {
|
|
||||||
mutations.forEach(function (mutation) { mutation.addedNodes.forEach(function (node) { if (node.nodeType === 1) scan(node); }); });
|
|
||||||
}).observe(document.body, { childList: true, subtree: true });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', ready);
|
|
||||||
else ready();
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -403,7 +403,7 @@ if (!function_exists('aksrt_comments_render_signarea')) :
|
|||||||
<div class="comment-signarea text-center box-body radius8">
|
<div class="comment-signarea text-center box-body radius8">
|
||||||
<h3 class="text-muted em12 theme-box muted-3-color"><?php esc_html_e('请登录后发表评论', 'aksrt'); ?></h3>
|
<h3 class="text-muted em12 theme-box muted-3-color"><?php esc_html_e('请登录后发表评论', 'aksrt'); ?></h3>
|
||||||
<p>
|
<p>
|
||||||
<a href="javascript:;" data-login-url="<?php echo esc_url($login_url); ?>" class="signin-loader but c-blue padding-lg"><i class="fa fa-fw fa-sign-in mr10" aria-hidden="true"></i><?php esc_html_e('登录', 'aksrt'); ?></a>
|
<a href="javascript:;" data-login-url="<?php echo esc_url($login_url); ?>" class="signin-loader but c-blue padding-lg"><i class="fa fas fa-fw fa-sign-in-alt mr10" aria-hidden="true"></i><?php esc_html_e('登录', 'aksrt'); ?></a>
|
||||||
<?php if (get_option('users_can_register')) :
|
<?php if (get_option('users_can_register')) :
|
||||||
$register_url = function_exists('aksrt_get_register_url') ? aksrt_get_register_url() : wp_registration_url();
|
$register_url = function_exists('aksrt_get_register_url') ? aksrt_get_register_url() : wp_registration_url();
|
||||||
?>
|
?>
|
||||||
@@ -508,7 +508,7 @@ if (!function_exists('aksrt_comments_render_form')) :
|
|||||||
$req_mark = $require_name_email ? '(' . __('必填', 'aksrt') . ')' : '';
|
$req_mark = $require_name_email ? '(' . __('必填', 'aksrt') . ')' : '';
|
||||||
?>
|
?>
|
||||||
<span class="dropup relative" id="comment-user-info"<?php echo $require_name_email ? ' require_name_email="true"' : ''; ?>>
|
<span class="dropup relative" id="comment-user-info"<?php echo $require_name_email ? ' require_name_email="true"' : ''; ?>>
|
||||||
<a class="but mr6" data-toggle-class="open" data-target="#comment-user-info" href="javascript:;"><i class="fa fa-fw fa-user" aria-hidden="true"></i><span class="hide-sm"><?php esc_html_e('昵称', 'aksrt'); ?></span></a>
|
<a class="but mr6" data-toggle-class="open" data-target="#comment-user-info" href="javascript:;"><i class="fa fas fa-fw fa-user" aria-hidden="true"></i><span class="hide-sm"><?php esc_html_e('昵称', 'aksrt'); ?></span></a>
|
||||||
<div class="dropdown-menu box-body" style="width:250px;">
|
<div class="dropdown-menu box-body" style="width:250px;">
|
||||||
<div class="mb20">
|
<div class="mb20">
|
||||||
<p><?php esc_html_e('请填写用户信息:', 'aksrt'); ?></p>
|
<p><?php esc_html_e('请填写用户信息:', 'aksrt'); ?></p>
|
||||||
@@ -516,20 +516,20 @@ if (!function_exists('aksrt_comments_render_form')) :
|
|||||||
<li class="line-form mb10">
|
<li class="line-form mb10">
|
||||||
<input type="text" name="author" class="line-form-input" tabindex="1" value="<?php echo esc_attr($comment_author); ?>" placeholder="">
|
<input type="text" name="author" class="line-form-input" tabindex="1" value="<?php echo esc_attr($comment_author); ?>" placeholder="">
|
||||||
<div class="scale-placeholder"><?php echo esc_html__('昵称', 'aksrt') . esc_html($req_mark); ?></div>
|
<div class="scale-placeholder"><?php echo esc_html__('昵称', 'aksrt') . esc_html($req_mark); ?></div>
|
||||||
<div class="abs-right muted-color"><i class="fa fa-fw fa-user" aria-hidden="true"></i></div>
|
<div class="abs-right muted-color"><i class="fa fas fa-fw fa-user" aria-hidden="true"></i></div>
|
||||||
<i class="line-form-line"></i>
|
<i class="line-form-line"></i>
|
||||||
</li>
|
</li>
|
||||||
<li class="line-form">
|
<li class="line-form">
|
||||||
<input type="text" name="email" class="line-form-input" tabindex="2" value="<?php echo esc_attr($comment_email); ?>" placeholder="">
|
<input type="text" name="email" class="line-form-input" tabindex="2" value="<?php echo esc_attr($comment_email); ?>" placeholder="">
|
||||||
<div class="scale-placeholder"><?php echo esc_html__('邮箱', 'aksrt') . esc_html($req_mark); ?></div>
|
<div class="scale-placeholder"><?php echo esc_html__('邮箱', 'aksrt') . esc_html($req_mark); ?></div>
|
||||||
<div class="abs-right muted-color"><i class="fa fa-fw fa-envelope-o" aria-hidden="true"></i></div>
|
<div class="abs-right muted-color"><i class="fa far fa-fw fa-envelope" aria-hidden="true"></i></div>
|
||||||
<i class="line-form-line"></i>
|
<i class="line-form-line"></i>
|
||||||
</li>
|
</li>
|
||||||
<?php if (!empty($ctx['user_url_enabled'])) : ?>
|
<?php if (!empty($ctx['user_url_enabled'])) : ?>
|
||||||
<li class="line-form">
|
<li class="line-form">
|
||||||
<input type="text" name="url" class="line-form-input" tabindex="3" value="<?php echo esc_attr($comment_author_url); ?>" placeholder="">
|
<input type="text" name="url" class="line-form-input" tabindex="3" value="<?php echo esc_attr($comment_author_url); ?>" placeholder="">
|
||||||
<div class="scale-placeholder"><?php esc_html_e('博客地址', 'aksrt'); ?></div>
|
<div class="scale-placeholder"><?php esc_html_e('博客地址', 'aksrt'); ?></div>
|
||||||
<div class="abs-right muted-color"><i class="fa fa-fw fa-link" aria-hidden="true"></i></div>
|
<div class="abs-right muted-color"><i class="fa fas fa-fw fa-link" aria-hidden="true"></i></div>
|
||||||
<i class="line-form-line"></i>
|
<i class="line-form-line"></i>
|
||||||
</li>
|
</li>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ if (!function_exists('aksrt_get_user_badges')) {
|
|||||||
$html .= '<a class="but c-blue tag-posts" data-toggle="tooltip" title="' . esc_attr(sprintf(__('共%s篇文章', 'aksrt'), $post_n)) . '" href="' . esc_url($home) . '">' . aksrt_renderer_svg_icon('post') . $post_n . '</a>';
|
$html .= '<a class="but c-blue tag-posts" data-toggle="tooltip" title="' . esc_attr(sprintf(__('共%s篇文章', 'aksrt'), $post_n)) . '" href="' . esc_url($home) . '">' . aksrt_renderer_svg_icon('post') . $post_n . '</a>';
|
||||||
$html .= '<a class="but c-green tag-comment" data-toggle="tooltip" title="' . esc_attr(sprintf(__('共%s条评论', 'aksrt'), $com_n)) . '" href="' . esc_url($home) . '">' . aksrt_renderer_svg_icon('comment') . $com_n . '</a>';
|
$html .= '<a class="but c-green tag-comment" data-toggle="tooltip" title="' . esc_attr(sprintf(__('共%s条评论', 'aksrt'), $com_n)) . '" href="' . esc_url($home) . '">' . aksrt_renderer_svg_icon('comment') . $com_n . '</a>';
|
||||||
if ($followed_n) {
|
if ($followed_n) {
|
||||||
$html .= '<a class="but c-yellow tag-follow" data-toggle="tooltip" title="' . esc_attr(sprintf(__('共%s个粉丝', 'aksrt'), $followed_n)) . '" href="' . esc_url($home) . '"><i class="fa fa-heart em09" aria-hidden="true"></i>' . $followed_n . '</a>';
|
$html .= '<a class="but c-yellow tag-follow" data-toggle="tooltip" title="' . esc_attr(sprintf(__('共%s个粉丝', 'aksrt'), $followed_n)) . '" href="' . esc_url($home) . '"><i class="fa fas fa-heart em09" aria-hidden="true"></i>' . $followed_n . '</a>';
|
||||||
} elseif ($like_n) {
|
} elseif ($like_n) {
|
||||||
$html .= '<span class="badg c-yellow tag-like" data-toggle="tooltip" title="' . esc_attr(sprintf(__('获得%s个点赞', 'aksrt'), $like_n)) . '">' . aksrt_renderer_svg_icon('like') . $like_n . '</span>';
|
$html .= '<span class="badg c-yellow tag-like" data-toggle="tooltip" title="' . esc_attr(sprintf(__('获得%s个点赞', 'aksrt'), $like_n)) . '">' . aksrt_renderer_svg_icon('like') . $like_n . '</span>';
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-17
@@ -1344,18 +1344,18 @@ if (!function_exists('aksrt_get_paywall_html')) {
|
|||||||
: __('开通会员', 'aksrt');
|
: __('开通会员', 'aksrt');
|
||||||
$action_class = is_user_logged_in() ? 'pay-vip' : 'signin-loader';
|
$action_class = is_user_logged_in() ? 'pay-vip' : 'signin-loader';
|
||||||
$icon = aksrt_get_pay_vip_icon_html($level_settings);
|
$icon = aksrt_get_pay_vip_icon_html($level_settings);
|
||||||
$button = '<div class="badg c-yellow em09 mb6"><i class="fa fa-fw fa-info-circle mr6" aria-hidden="true"></i>' . esc_html(sprintf(__('您暂无购买权限,请先%s', 'aksrt'), $vip_action)) . '</div>';
|
$button = '<div class="badg c-yellow em09 mb6"><i class="fa fas fa-fw fa-info-circle mr6" aria-hidden="true"></i>' . esc_html(sprintf(__('您暂无购买权限,请先%s', 'aksrt'), $vip_action)) . '</div>';
|
||||||
$button .= '<a href="javascript:;" vip-level="' . esc_attr((string) $pay_limit) . '" data-vip-level="' . esc_attr((string) $pay_limit) . '" class="but btn-block jb-vip' . esc_attr((string) $pay_limit) . ' ' . esc_attr($action_class) . ' padding-lg">' . $icon . esc_html($vip_action) . '</a>';
|
$button .= '<a href="javascript:;" vip-level="' . esc_attr((string) $pay_limit) . '" data-vip-level="' . esc_attr((string) $pay_limit) . '" class="but btn-block jb-vip' . esc_attr((string) $pay_limit) . ' ' . esc_attr($action_class) . ' padding-lg">' . $icon . esc_html($vip_action) . '</a>';
|
||||||
} elseif (!is_user_logged_in()) {
|
} elseif (!is_user_logged_in()) {
|
||||||
if ($amount_minor > 0 && $modo === '0' && aksrt_allow_guest_content_pay($post)) {
|
if ($amount_minor > 0 && $modo === '0' && aksrt_allow_guest_content_pay($post)) {
|
||||||
$button = '<button type="button" class="but jb-red padding-lg cashier-link' . $block_class . '" data-aksrt-pay-content="' . esc_attr((string) $post->ID) . '"><i class="fa fa-shopping-cart" aria-hidden="true"></i> ' . esc_html__('立即购买', 'aksrt') . '</button>';
|
$button = '<button type="button" class="but jb-red padding-lg cashier-link' . $block_class . '" data-aksrt-pay-content="' . esc_attr((string) $post->ID) . '"><i class="fa fas fa-shopping-cart" aria-hidden="true"></i> ' . esc_html__('立即购买', 'aksrt') . '</button>';
|
||||||
} else {
|
} else {
|
||||||
$button = '<a href="javascript:;" class="but jb-blue signin-loader padding-lg' . $block_class . '"><i class="fa fa-sign-in mr10" aria-hidden="true"></i>' . esc_html__('登录购买', 'aksrt') . '</a>';
|
$button = '<a href="javascript:;" class="but jb-blue signin-loader padding-lg' . $block_class . '"><i class="fa fas fa-sign-in-alt mr10" aria-hidden="true"></i>' . esc_html__('登录购买', 'aksrt') . '</a>';
|
||||||
}
|
}
|
||||||
} elseif ($amount_minor > 0) {
|
} elseif ($amount_minor > 0) {
|
||||||
$button = '<button type="button" class="but ' . ($modo === 'points' ? 'jb-yellow' : 'jb-red') . ' padding-lg cashier-link' . $block_class . '" data-aksrt-pay-content="' . esc_attr((string) $post->ID) . '"><i class="fa fa-shopping-cart" aria-hidden="true"></i> ' . esc_html__('立即购买', 'aksrt') . '</button>';
|
$button = '<button type="button" class="but ' . ($modo === 'points' ? 'jb-yellow' : 'jb-red') . ' padding-lg cashier-link' . $block_class . '" data-aksrt-pay-content="' . esc_attr((string) $post->ID) . '"><i class="fa fas fa-shopping-cart" aria-hidden="true"></i> ' . esc_html__('立即购买', 'aksrt') . '</button>';
|
||||||
} else {
|
} else {
|
||||||
$button = '<button type="button" class="but jb-blue padding-lg cashier-link' . $block_class . '" data-aksrt-pay-content="' . esc_attr((string) $post->ID) . '"><i class="fa fa-eye" aria-hidden="true"></i> ' . esc_html__('查看内容', 'aksrt') . '</button>';
|
$button = '<button type="button" class="but jb-blue padding-lg cashier-link' . $block_class . '" data-aksrt-pay-content="' . esc_attr((string) $post->ID) . '"><i class="fa fas fa-eye" aria-hidden="true"></i> ' . esc_html__('查看内容', 'aksrt') . '</button>';
|
||||||
}
|
}
|
||||||
$price = aksrt_get_show_pay_price_html($meta, $priced);
|
$price = aksrt_get_show_pay_price_html($meta, $priced);
|
||||||
$vip = aksrt_get_posts_vip_price($meta);
|
$vip = aksrt_get_posts_vip_price($meta);
|
||||||
@@ -1374,12 +1374,12 @@ if (!function_exists('aksrt_get_paywall_html')) {
|
|||||||
|
|
||||||
if ($is_widget && aksrt_has_paid_access($post)) {
|
if ($is_widget && aksrt_has_paid_access($post)) {
|
||||||
$view_labels = [
|
$view_labels = [
|
||||||
AKSRT_PAY_TYPE_DOWNLOAD => '<i class="fa fa-download fa-fw" aria-hidden="true"></i>' . esc_html__('获取下载地址', 'aksrt'),
|
AKSRT_PAY_TYPE_DOWNLOAD => '<i class="fa fas fa-download fa-fw" aria-hidden="true"></i>' . esc_html__('获取下载地址', 'aksrt'),
|
||||||
AKSRT_PAY_TYPE_GALLERY => '<i class="fa fa-file-image-o fa-fw" aria-hidden="true"></i>' . esc_html__('查看图片', 'aksrt'),
|
AKSRT_PAY_TYPE_GALLERY => '<i class="fa far fa-file-image fa-fw" aria-hidden="true"></i>' . esc_html__('查看图片', 'aksrt'),
|
||||||
AKSRT_PAY_TYPE_VIDEO => '<i class="fa fa-play-circle fa-fw" aria-hidden="true"></i>' . esc_html__('查看视频', 'aksrt'),
|
AKSRT_PAY_TYPE_VIDEO => '<i class="fa fas fa-play-circle fa-fw" aria-hidden="true"></i>' . esc_html__('查看视频', 'aksrt'),
|
||||||
];
|
];
|
||||||
$view_label = $view_labels[$pay_type] ?? '<i class="fa fa-dot-circle-o fa-fw" aria-hidden="true"></i>' . esc_html__('查看内容', 'aksrt');
|
$view_label = $view_labels[$pay_type] ?? '<i class="fa far fa-dot-circle fa-fw" aria-hidden="true"></i>' . esc_html__('查看内容', 'aksrt');
|
||||||
return '<div class="zib-widget pay-box pay-widget paid-box order-type-' . $order_type . '" style="padding:0">' . $tag . '<div class="relative-h ' . esc_attr($theme) . '" style="background-size:120%"><div class="pay-widget__orb pay-widget__orb--right ' . esc_attr($theme) . '"></div><div class="pay-widget__orb pay-widget__orb--left ' . esc_attr($theme) . '"></div><div class="relative box-body"><div class="text-center mt10 box-body"><p><i class="fa fa-shopping-bag fa-3x" aria-hidden="true"></i></p><b class="em14">' . esc_html__('已购买', 'aksrt') . '</b></div></div></div><div class="box-body">' . $widget_service . '<div class="mt10"><a href="#posts-pay" class="but padding-lg btn-block ' . esc_attr($theme) . '">' . $view_label . '</a></div>' . $demo_row . $attrs . '</div>' . $count . '</div>';
|
return '<div class="zib-widget pay-box pay-widget paid-box order-type-' . $order_type . '" style="padding:0">' . $tag . '<div class="relative-h ' . esc_attr($theme) . '" style="background-size:120%"><div class="pay-widget__orb pay-widget__orb--right ' . esc_attr($theme) . '"></div><div class="pay-widget__orb pay-widget__orb--left ' . esc_attr($theme) . '"></div><div class="relative box-body"><div class="text-center mt10 box-body"><p><i class="fa fas fa-shopping-bag fa-3x" aria-hidden="true"></i></p><b class="em14">' . esc_html__('已购买', 'aksrt') . '</b></div></div></div><div class="box-body">' . $widget_service . '<div class="mt10"><a href="#posts-pay" class="but padding-lg btn-block ' . esc_attr($theme) . '">' . $view_label . '</a></div>' . $demo_row . $attrs . '</div>' . $count . '</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($is_widget) {
|
if ($is_widget) {
|
||||||
@@ -1388,7 +1388,7 @@ if (!function_exists('aksrt_get_paywall_html')) {
|
|||||||
|
|
||||||
$thumb = get_the_post_thumbnail($post, 'medium', ['class' => 'fit-cover', 'alt' => '']);
|
$thumb = get_the_post_thumbnail($post, 'medium', ['class' => 'fit-cover', 'alt' => '']);
|
||||||
if ($thumb === '') {
|
if ($thumb === '') {
|
||||||
$thumb = '<div class="pay-thumb-placeholder"><i class="fa fa-lock" aria-hidden="true"></i></div>';
|
$thumb = '<div class="pay-thumb-placeholder"><i class="fa fas fa-lock" aria-hidden="true"></i></div>';
|
||||||
}
|
}
|
||||||
$graphic_actions = '';
|
$graphic_actions = '';
|
||||||
if ($demo !== '' || $discount_text !== '') {
|
if ($demo !== '' || $discount_text !== '') {
|
||||||
@@ -1402,7 +1402,7 @@ if (!function_exists('aksrt_get_paywall_html')) {
|
|||||||
$gallery_count = count((array) ($meta['gallery'] ?? []));
|
$gallery_count = count((array) ($meta['gallery'] ?? []));
|
||||||
$graphic = '<div class="flex0 relative mr20 hide-sm pay-thumb"><div class="graphic"><div class="blur-10 absolute">' . $thumb . '</div><div class="absolute graphic-mask" style="opacity:.3"></div><div class="abs-center text-center">' . esc_html(sprintf(__('共%s张图片', 'aksrt'), $gallery_count)) . '<br>' . esc_html__('请付费后查看', 'aksrt') . '</div>' . $graphic_actions . '</div></div>';
|
$graphic = '<div class="flex0 relative mr20 hide-sm pay-thumb"><div class="graphic"><div class="blur-10 absolute">' . $thumb . '</div><div class="absolute graphic-mask" style="opacity:.3"></div><div class="abs-center text-center">' . esc_html(sprintf(__('共%s张图片', 'aksrt'), $gallery_count)) . '<br>' . esc_html__('请付费后查看', 'aksrt') . '</div>' . $graphic_actions . '</div></div>';
|
||||||
} elseif ($pay_type === AKSRT_PAY_TYPE_VIDEO) {
|
} elseif ($pay_type === AKSRT_PAY_TYPE_VIDEO) {
|
||||||
$graphic = '<div class="flex0 relative mr20 hide-sm pay-thumb"><div class="graphic">' . $thumb . '<div class="absolute graphic-mask" style="opacity:.2"></div><div class="abs-center text-center"><i class="fa fa-play-circle-o fa-4x opacity8" aria-hidden="true"></i></div>' . $graphic_actions . '</div></div>';
|
$graphic = '<div class="flex0 relative mr20 hide-sm pay-thumb"><div class="graphic">' . $thumb . '<div class="absolute graphic-mask" style="opacity:.2"></div><div class="abs-center text-center"><i class="fa far fa-play-circle fa-4x opacity8" aria-hidden="true"></i></div>' . $graphic_actions . '</div></div>';
|
||||||
} else {
|
} else {
|
||||||
$graphic = '<div class="flex0 relative mr20 hide-sm pay-thumb"><div class="graphic">' . $thumb . $graphic_actions . '</div></div>';
|
$graphic = '<div class="flex0 relative mr20 hide-sm pay-thumb"><div class="graphic">' . $thumb . $graphic_actions . '</div></div>';
|
||||||
}
|
}
|
||||||
@@ -1471,10 +1471,10 @@ if (!function_exists('aksrt_get_paid_download_actions_html')) {
|
|||||||
$buttons .= '<div class="but-download flex ac">';
|
$buttons .= '<div class="but-download flex ac">';
|
||||||
if ($direct_download) {
|
if ($direct_download) {
|
||||||
$buttons .= '<a class="mr10 but ' . esc_attr($button_class) . '" href="' . esc_url($url) . '" target="_blank" rel="nofollow noopener">';
|
$buttons .= '<a class="mr10 but ' . esc_attr($button_class) . '" href="' . esc_url($url) . '" target="_blank" rel="nofollow noopener">';
|
||||||
$buttons .= '<i class="fa fa-download" aria-hidden="true"></i>' . esc_html($label) . '</a>';
|
$buttons .= '<i class="fa fas fa-download" aria-hidden="true"></i>' . esc_html($label) . '</a>';
|
||||||
} else {
|
} else {
|
||||||
$buttons .= '<button type="button" class="mr10 but ' . esc_attr($button_class) . '" data-action="aksrt-download" data-source-index="' . esc_attr((string) $index) . '" data-source-type="' . esc_attr($type) . '" data-has-extract="' . ($has_extract ? '1' : '0') . '">';
|
$buttons .= '<button type="button" class="mr10 but ' . esc_attr($button_class) . '" data-action="aksrt-download" data-source-index="' . esc_attr((string) $index) . '" data-source-type="' . esc_attr($type) . '" data-has-extract="' . ($has_extract ? '1' : '0') . '">';
|
||||||
$buttons .= '<i class="fa fa-download" aria-hidden="true"></i>' . esc_html($label) . '</button>';
|
$buttons .= '<i class="fa fas fa-download" aria-hidden="true"></i>' . esc_html($label) . '</button>';
|
||||||
}
|
}
|
||||||
if ($copy_value !== '') {
|
if ($copy_value !== '') {
|
||||||
$buttons .= '<button type="button" class="but" data-clipboard-tag="' . esc_attr($copy_key !== '' ? $copy_key : __('内容', 'aksrt')) . '" data-clipboard-text="' . esc_attr($copy_value) . '">' . esc_html($copy_label) . '</button>';
|
$buttons .= '<button type="button" class="but" data-clipboard-tag="' . esc_attr($copy_key !== '' ? $copy_key : __('内容', 'aksrt')) . '" data-clipboard-text="' . esc_attr($copy_value) . '">' . esc_html($copy_label) . '</button>';
|
||||||
@@ -1552,12 +1552,12 @@ if (!function_exists('aksrt_get_paid_box_html')) {
|
|||||||
$paid_info .= '<div class="flex jsb"><span>' . esc_html__('支付时间', 'aksrt') . '</span><span>' . esc_html($paid_at) . '</span></div>';
|
$paid_info .= '<div class="flex jsb"><span>' . esc_html__('支付时间', 'aksrt') . '</span><span>' . esc_html($paid_at) . '</span></div>';
|
||||||
}
|
}
|
||||||
$paid_info .= '<div class="flex jsb"><span>' . esc_html__('支付金额', 'aksrt') . '</span><span>' . esc_html($amount_text) . '</span></div>';
|
$paid_info .= '<div class="flex jsb"><span>' . esc_html__('支付金额', 'aksrt') . '</span><span>' . esc_html($amount_text) . '</span></div>';
|
||||||
$paid_box = '<div class="flex ac jb-green padding-10 em09"><div class="text-center flex-auto"><div class="mb6"><i class="fa fa-shopping-bag fa-2x" aria-hidden="true"></i></div><b class="em12">' . esc_html__('已购买', 'aksrt') . '</b></div><div class="em09 paid-info flex-auto">' . $paid_info . '</div></div>';
|
$paid_box = '<div class="flex ac jb-green padding-10 em09"><div class="text-center flex-auto"><div class="mb6"><i class="fa fas fa-shopping-bag fa-2x" aria-hidden="true"></i></div><b class="em12">' . esc_html__('已购买', 'aksrt') . '</b></div><div class="em09 paid-info flex-auto">' . $paid_info . '</div></div>';
|
||||||
} elseif ($vip_level > 0 || $pay_type === AKSRT_PAY_TYPE_VIP) {
|
} elseif ($vip_level > 0 || $pay_type === AKSRT_PAY_TYPE_VIP) {
|
||||||
$level = max(1, $vip_level);
|
$level = max(1, $vip_level);
|
||||||
$price_label = aksrt_get_pay_price_label($post);
|
$price_label = aksrt_get_pay_price_label($post);
|
||||||
$price = '<div class="price-box"><div class="text-center"><b class="em3x">' . esc_html((string) ($price_label['text'] ?? '')) . '</b></div></div>';
|
$price = '<div class="price-box"><div class="text-center"><b class="em3x">' . esc_html((string) ($price_label['text'] ?? '')) . '</b></div></div>';
|
||||||
$paid_box = '<div class="flex jsb ac payvip-icon box-body vipbg-v' . esc_attr((string) $level) . '">' . $price . '<div class="flex0"><b class="em12"><i class="fa fa-certificate mr10 em12" aria-hidden="true"></i>' . esc_html(sprintf(__('VIP%d 会员免费', 'aksrt'), $level)) . '</b></div></div>';
|
$paid_box = '<div class="flex jsb ac payvip-icon box-body vipbg-v' . esc_attr((string) $level) . '">' . $price . '<div class="flex0"><b class="em12"><i class="fa fas fa-certificate mr10 em12" aria-hidden="true"></i>' . esc_html(sprintf(__('VIP%d 会员免费', 'aksrt'), $level)) . '</b></div></div>';
|
||||||
} else {
|
} else {
|
||||||
$type_label = str_replace(__('付费', 'aksrt'), __('免费', 'aksrt'), $type_label);
|
$type_label = str_replace(__('付费', 'aksrt'), __('免费', 'aksrt'), $type_label);
|
||||||
}
|
}
|
||||||
@@ -1574,7 +1574,7 @@ if (!function_exists('aksrt_get_paid_box_html')) {
|
|||||||
if ($pay_type === AKSRT_PAY_TYPE_DOWNLOAD) {
|
if ($pay_type === AKSRT_PAY_TYPE_DOWNLOAD) {
|
||||||
$captcha_active = function_exists('aksrt_is_captcha_enabled_for') && aksrt_is_captcha_enabled_for('download');
|
$captcha_active = function_exists('aksrt_is_captcha_enabled_for') && aksrt_is_captcha_enabled_for('download');
|
||||||
$root_data = ' data-aksrt-download-box data-post-id="' . esc_attr((string) $post->ID) . '" data-captcha="' . ($captcha_active ? '1' : '0') . '"';
|
$root_data = ' data-aksrt-download-box data-post-id="' . esc_attr((string) $post->ID) . '" data-captcha="' . ($captcha_active ? '1' : '0') . '"';
|
||||||
$download_box = '<div class="hidden-box show"><div class="hidden-text"><i class="fa fa-download mr6" aria-hidden="true"></i>' . esc_html__('资源下载', 'aksrt') . '</div>' . aksrt_get_paid_download_actions_html($meta) . '</div>';
|
$download_box = '<div class="hidden-box show"><div class="hidden-text"><i class="fa fas fa-download mr6" aria-hidden="true"></i>' . esc_html__('资源下载', 'aksrt') . '</div>' . aksrt_get_paid_download_actions_html($meta) . '</div>';
|
||||||
$demo = aksrt_get_demo_link_html($post, 'but jb-yellow padding-lg');
|
$demo = aksrt_get_demo_link_html($post, 'but jb-yellow padding-lg');
|
||||||
if ($demo !== '') {
|
if ($demo !== '') {
|
||||||
$download_box .= '<div class="mt10">' . $demo . '</div>';
|
$download_box .= '<div class="mt10">' . $demo . '</div>';
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ if (!function_exists('aksrt_get_input_expand_but')) :
|
|||||||
|
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case 'link':
|
case 'link':
|
||||||
$but = '<a class="but btn-input-expand input-link mr6" href="javascript:;"><i class="fa fa-fw fa-link" aria-hidden="true"></i><span class="hide-sm">' . esc_html__('链接', 'aksrt') . '</span></a>';
|
$but = '<a class="but btn-input-expand input-link mr6" href="javascript:;"><i class="fa fas fa-fw fa-link" aria-hidden="true"></i><span class="hide-sm">' . esc_html__('链接', 'aksrt') . '</span></a>';
|
||||||
$dropdown = '<div class="dropdown-link">';
|
$dropdown = '<div class="dropdown-link">';
|
||||||
$dropdown .= '<p>' . esc_html__('请输入链接:', 'aksrt') . '</p>';
|
$dropdown .= '<p>' . esc_html__('请输入链接:', 'aksrt') . '</p>';
|
||||||
$dropdown .= '<p><textarea rows="2" tabindex="1" class="form-control input-textarea link-textarea" style="height:55px;" placeholder="https://..."></textarea></p>';
|
$dropdown .= '<p><textarea rows="2" tabindex="1" class="form-control input-textarea link-textarea" style="height:55px;" placeholder="https://..."></textarea></p>';
|
||||||
@@ -60,7 +60,7 @@ if (!function_exists('aksrt_get_input_expand_but')) :
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'code':
|
case 'code':
|
||||||
$but = '<a class="but btn-input-expand input-code mr6" href="javascript:;"><i class="fa fa-fw fa-code" aria-hidden="true"></i><span class="hide-sm">' . esc_html__('代码', 'aksrt') . '</span></a>';
|
$but = '<a class="but btn-input-expand input-code mr6" href="javascript:;"><i class="fa fas fa-fw fa-code" aria-hidden="true"></i><span class="hide-sm">' . esc_html__('代码', 'aksrt') . '</span></a>';
|
||||||
$dropdown = '<div class="dropdown-code">';
|
$dropdown = '<div class="dropdown-code">';
|
||||||
$dropdown .= '<p>' . esc_html__('请输入代码:', 'aksrt') . '</p>';
|
$dropdown .= '<p>' . esc_html__('请输入代码:', 'aksrt') . '</p>';
|
||||||
$dropdown .= '<p><textarea rows="6" tabindex="1" class="form-control input-textarea" placeholder="' . esc_attr__('在此处粘贴或输入代码', 'aksrt') . '"></textarea></p>';
|
$dropdown .= '<p><textarea rows="6" tabindex="1" class="form-control input-textarea" placeholder="' . esc_attr__('在此处粘贴或输入代码', 'aksrt') . '"></textarea></p>';
|
||||||
@@ -70,7 +70,7 @@ if (!function_exists('aksrt_get_input_expand_but')) :
|
|||||||
|
|
||||||
case 'image':
|
case 'image':
|
||||||
$upload = !empty($arg1) || !empty($ctx['upload']);
|
$upload = !empty($arg1) || !empty($ctx['upload']);
|
||||||
$but = '<a class="but btn-input-expand input-image mr6" href="javascript:;"><i class="fa fa-fw fa-image" aria-hidden="true"></i><span class="hide-sm">' . esc_html__('图片', 'aksrt') . '</span></a>';
|
$but = '<a class="but btn-input-expand input-image mr6" href="javascript:;"><i class="fa fas fa-fw fa-image" aria-hidden="true"></i><span class="hide-sm">' . esc_html__('图片', 'aksrt') . '</span></a>';
|
||||||
|
|
||||||
$dropdown = '<div class="dropdown-image">';
|
$dropdown = '<div class="dropdown-image">';
|
||||||
$dropdown .= '<p>' . esc_html__('请填写图片地址:', 'aksrt') . '</p>';
|
$dropdown .= '<p>' . esc_html__('请填写图片地址:', 'aksrt') . '</p>';
|
||||||
|
|||||||
@@ -163,10 +163,10 @@ if (!function_exists('aksrt_get_comments_action_dropdown_html')) :
|
|||||||
$label = $is_pinned ? __('取消置顶', 'aksrt') : __('设置置顶', 'aksrt');
|
$label = $is_pinned ? __('取消置顶', 'aksrt') : __('设置置顶', 'aksrt');
|
||||||
// 不带 legacy 的 wp-ajax-submit 类:vendor main.min.js 会全局代理该类并向
|
// 不带 legacy 的 wp-ajax-submit 类:vendor main.min.js 会全局代理该类并向
|
||||||
// admin-ajax 发空 action 请求(400 "0"),置顶走 data-comment-action REST。
|
// admin-ajax 发空 action 请求(400 "0"),置顶走 data-comment-action REST。
|
||||||
$lists .= '<li><a class="comment-topping" data-comment-action="pin" data-pinned="' . ($is_pinned ? '1' : '0') . '" href="javascript:;"><i class="fa fa-thumbtack mr10 fa-fw" aria-hidden="true"></i>' . esc_html($label) . '</a></li>';
|
$lists .= '<li><a class="comment-topping" data-comment-action="pin" data-pinned="' . ($is_pinned ? '1' : '0') . '" href="javascript:;"><i class="fa fas fa-thumbtack mr10 fa-fw" aria-hidden="true"></i>' . esc_html($label) . '</a></li>';
|
||||||
}
|
}
|
||||||
if (!empty($perms['can_edit'])) {
|
if (!empty($perms['can_edit'])) {
|
||||||
$lists .= '<li><a class="comment-edit-link" data-commentid="' . (int) $comment->comment_ID . '" data-postid="' . (int) $comment->comment_post_ID . '" href="javascript:;"><i class="fa fa-edit mr10 fa-fw" aria-hidden="true"></i>' . esc_html__('编辑', 'aksrt') . '</a></li>';
|
$lists .= '<li><a class="comment-edit-link" data-commentid="' . (int) $comment->comment_ID . '" data-postid="' . (int) $comment->comment_post_ID . '" href="javascript:;"><i class="fa fas fa-edit mr10 fa-fw" aria-hidden="true"></i>' . esc_html__('编辑', 'aksrt') . '</a></li>';
|
||||||
}
|
}
|
||||||
if (!empty($perms['can_moderate'])) {
|
if (!empty($perms['can_moderate'])) {
|
||||||
$text = $is_pending ? __('批准', 'aksrt') : __('驳回', 'aksrt');
|
$text = $is_pending ? __('批准', 'aksrt') : __('驳回', 'aksrt');
|
||||||
@@ -176,7 +176,7 @@ if (!function_exists('aksrt_get_comments_action_dropdown_html')) :
|
|||||||
$lists .= '<li><a class="comment-approve-link ' . $class . '" data-comment-action="' . $action . '" data-commentid="' . (int) $comment->comment_ID . '" data-postid="' . (int) $comment->comment_post_ID . '" href="javascript:;">' . $approve_icon . '<text>' . esc_html($text) . '</text></a></li>';
|
$lists .= '<li><a class="comment-approve-link ' . $class . '" data-comment-action="' . $action . '" data-commentid="' . (int) $comment->comment_ID . '" data-postid="' . (int) $comment->comment_post_ID . '" href="javascript:;">' . $approve_icon . '<text>' . esc_html($text) . '</text></a></li>';
|
||||||
}
|
}
|
||||||
if (!empty($perms['can_delete'])) {
|
if (!empty($perms['can_delete'])) {
|
||||||
$lists .= '<li><a class="comment-trash-link c-red" data-comment-action="delete" data-commentid="' . (int) $comment->comment_ID . '" data-postid="' . (int) $comment->comment_post_ID . '" href="javascript:;"><i class="fa fa-trash-o mr10 fa-fw" aria-hidden="true"></i>' . esc_html__('删除', 'aksrt') . '</a></li>';
|
$lists .= '<li><a class="comment-trash-link c-red" data-comment-action="delete" data-commentid="' . (int) $comment->comment_ID . '" data-postid="' . (int) $comment->comment_post_ID . '" href="javascript:;"><i class="fa far fa-trash-alt mr10 fa-fw" aria-hidden="true"></i>' . esc_html__('删除', 'aksrt') . '</a></li>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($lists === '') {
|
if ($lists === '') {
|
||||||
|
|||||||
@@ -588,8 +588,8 @@ if (!function_exists('aksrt_render_comment_pagination')) {
|
|||||||
'base' => $base,
|
'base' => $base,
|
||||||
'type' => 'array',
|
'type' => 'array',
|
||||||
'mid_size' => $is_mobile ? 1 : 2,
|
'mid_size' => $is_mobile ? 1 : 2,
|
||||||
'prev_text' => '<i class="fa fa-angle-left em12"></i><span class="hide-sm ml6">' . __('上一页', 'aksrt') . '</span>',
|
'prev_text' => '<i class="fa fas fa-angle-left em12"></i><span class="hide-sm ml6">' . __('上一页', 'aksrt') . '</span>',
|
||||||
'next_text' => '<span class="hide-sm mr6">' . __('下一页', 'aksrt') . '</span><i class="fa fa-angle-right em12"></i>',
|
'next_text' => '<span class="hide-sm mr6">' . __('下一页', 'aksrt') . '</span><i class="fa fas fa-angle-right em12"></i>',
|
||||||
'total' => $max_pages,
|
'total' => $max_pages,
|
||||||
'current' => $paged,
|
'current' => $paged,
|
||||||
'add_fragment' => '#comments',
|
'add_fragment' => '#comments',
|
||||||
@@ -601,7 +601,7 @@ if (!function_exists('aksrt_render_comment_pagination')) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($max_pages > 8) {
|
if ($max_pages > 8) {
|
||||||
$array[] = '<a class="pag-jump page-numbers" href="javascript:;" no-scroll="true" data-jump-comments="1"><input autocomplete="off" max="' . esc_attr((string) $max_pages) . '" current="' . esc_attr((string) $paged) . '" type="' . ($is_mobile ? 'number' : 'text') . '" class="form-control jump-input" name="pag-go"><span class="hide-sm mr6 jump-text">' . __('跳转', 'aksrt') . '</span><i class="jump-icon fa fa-angle-double-right em12"></i></a>';
|
$array[] = '<a class="pag-jump page-numbers" href="javascript:;" no-scroll="true" data-jump-comments="1"><input autocomplete="off" max="' . esc_attr((string) $max_pages) . '" current="' . esc_attr((string) $paged) . '" type="' . ($is_mobile ? 'number' : 'text') . '" class="form-control jump-input" name="pag-go"><span class="hide-sm mr6 jump-text">' . __('跳转', 'aksrt') . '</span><i class="jump-icon fa fas fa-angle-double-right em12"></i></a>';
|
||||||
}
|
}
|
||||||
|
|
||||||
echo '<div class="pagenav" data-current-page="' . esc_attr((string) $paged) . '" data-max-pages="' . esc_attr((string) $max_pages) . '">';
|
echo '<div class="pagenav" data-current-page="' . esc_attr((string) $paged) . '" data-max-pages="' . esc_attr((string) $max_pages) . '">';
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class SchemaPageDisplay {
|
|||||||
self::field('nav_newposts', 'Add发布按钮', 'switcher', true, ['description' => '顶部导航显示文章投稿按钮。']),
|
self::field('nav_newposts', 'Add发布按钮', 'switcher', true, ['description' => '顶部导航显示文章投稿按钮。']),
|
||||||
self::field('nav_newposts_radius', '按钮圆角', 'switcher', true, ['dependsOn' => self::enabled('nav_newposts')]),
|
self::field('nav_newposts_radius', '按钮圆角', 'switcher', true, ['dependsOn' => self::enabled('nav_newposts')]),
|
||||||
self::field('nav_newposts_class', '按钮颜色', 'palette', 'jb-blue', ['dependsOn' => self::enabled('nav_newposts'), 'options' => self::aksrt_palette()]),
|
self::field('nav_newposts_class', '按钮颜色', 'palette', 'jb-blue', ['dependsOn' => self::enabled('nav_newposts'), 'options' => self::aksrt_palette()]),
|
||||||
self::field('nav_newposts_text', '按钮文案', 'textarea', '<i class="fa fa-fw fa-pencil"></i>发布', ['dependsOn' => self::enabled('nav_newposts'), 'sanitize_type' => 'html', 'rows' => 1]),
|
self::field('nav_newposts_text', '按钮文案', 'textarea', '<i class="fa fas fa-fw fas fa-pencil-alt"></i>发布', ['dependsOn' => self::enabled('nav_newposts'), 'sanitize_type' => 'html', 'rows' => 1]),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ class SchemaPageDisplay {
|
|||||||
self::field('footer_contact_weibo', '微博链接', 'url', 'https://weibo.com/'),
|
self::field('footer_contact_weibo', '微博链接', 'url', 'https://weibo.com/'),
|
||||||
self::field('footer_contact_email', '邮箱', 'text', '1234567788@QQ.COM'),
|
self::field('footer_contact_email', '邮箱', 'text', '1234567788@QQ.COM'),
|
||||||
self::field('footer_contact_more', '更多图标联系方式', 'group', [], ['button_title' => '添加图标联系方式', 'fields' => [
|
self::field('footer_contact_more', '更多图标联系方式', 'group', [], ['button_title' => '添加图标联系方式', 'fields' => [
|
||||||
self::field('desc', '按钮名称', 'text', ''), self::field('icon', '按钮图标', 'icon', 'fa fa-heart'), self::field('link', '按钮链接', 'url', '', ['dependsOn' => ['key' => 'img', 'operator' => 'empty']]), self::field('img', '二维码图片', 'upload', ''),
|
self::field('desc', '按钮名称', 'text', ''), self::field('icon', '按钮图标', 'icon', 'fa fas fa-heart'), self::field('link', '按钮链接', 'url', '', ['dependsOn' => ['key' => 'img', 'operator' => 'empty']]), self::field('img', '二维码图片', 'upload', ''),
|
||||||
]]),
|
]]),
|
||||||
self::field('footer_mini_img_m_s', '版块三移动端显示', 'switcher', true),
|
self::field('footer_mini_img_m_s', '版块三移动端显示', 'switcher', true),
|
||||||
self::field('footer_mini_img', '版块三大图片', 'group', [['image' => $img . 'qrcode.png', 'text' => '扫码加QQ群'], ['image' => $img . 'qrcode.png', 'text' => '扫码加微信']], ['max' => 4, 'button_title' => '添加图片', 'fields' => self::footer_image_fields()]),
|
self::field('footer_mini_img', '版块三大图片', 'group', [['image' => $img . 'qrcode.png', 'text' => '扫码加QQ群'], ['image' => $img . 'qrcode.png', 'text' => '扫码加微信']], ['max' => 4, 'button_title' => '添加图片', 'fields' => self::footer_image_fields()]),
|
||||||
@@ -181,7 +181,7 @@ class SchemaPageDisplay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static function card_fields(): array {
|
private static function card_fields(): array {
|
||||||
return [self::field('icon_radius4', '方形图标', 'switcher', false), self::field('cards', '添加卡片', 'group', [], ['button_title' => '添加内容', 'fields' => [self::field('title', '文案标题', 'textarea', '', ['sanitize_type' => 'html']), self::field('desc', '文案简介', 'textarea', '', ['sanitize_type' => 'html']), self::field('icon', '选择图标', 'icon', 'fa fa-magic'), self::field('customize_icon', '自定义图标', 'textarea', '', ['sanitize_type' => 'html']), self::field('icon_class', '图标颜色', 'palette', 'c-yellow', ['options' => self::aksrt_palette(true)]), self::field('link', '跳转链接', 'link', [])]])];
|
return [self::field('icon_radius4', '方形图标', 'switcher', false), self::field('cards', '添加卡片', 'group', [], ['button_title' => '添加内容', 'fields' => [self::field('title', '文案标题', 'textarea', '', ['sanitize_type' => 'html']), self::field('desc', '文案简介', 'textarea', '', ['sanitize_type' => 'html']), self::field('icon', '选择图标', 'icon', 'fa fas fa-magic'), self::field('customize_icon', '自定义图标', 'textarea', '', ['sanitize_type' => 'html']), self::field('icon_class', '图标颜色', 'palette', 'c-yellow', ['options' => self::aksrt_palette(true)]), self::field('link', '跳转链接', 'link', [])]])];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function orderby_fields(): array { return [self::field('lists', '显示排序方式', 'select', ['modified', 'views', 'like', 'comment_count'], ['multiple' => true, 'sortable' => true, 'options' => self::post_order_options(false)]), self::field('dropdown', '更多排序方式', 'switcher', false)]; }
|
private static function orderby_fields(): array { return [self::field('lists', '显示排序方式', 'select', ['modified', 'views', 'like', 'comment_count'], ['multiple' => true, 'sortable' => true, 'options' => self::post_order_options(false)]), self::field('dropdown', '更多排序方式', 'switcher', false)]; }
|
||||||
@@ -190,7 +190,7 @@ class SchemaPageDisplay {
|
|||||||
private static function header_slider_defaults(): array { $img = self::asset('assets/img/'); return [['background' => $img . 'slider-bg.jpg', 'link' => ['url' => home_url('/'), 'target' => '_blank'], 'text' => ['title' => '', 'desc' => ''], 'text_align' => 'left-bottom', 'text_parallax' => 30, 'text_size_m' => 20, 'text_size_pc' => 30], ['background' => $img . 'user_t.jpg', 'link' => ['url' => home_url('/'), 'target' => '_blank'], 'text' => ['title' => '', 'desc' => ''], 'text_align' => 'left-bottom', 'text_parallax' => 30, 'text_size_m' => 20, 'text_size_pc' => 30]]; }
|
private static function header_slider_defaults(): array { $img = self::asset('assets/img/'); return [['background' => $img . 'slider-bg.jpg', 'link' => ['url' => home_url('/'), 'target' => '_blank'], 'text' => ['title' => '', 'desc' => ''], 'text_align' => 'left-bottom', 'text_parallax' => 30, 'text_size_m' => 20, 'text_size_pc' => 30], ['background' => $img . 'user_t.jpg', 'link' => ['url' => home_url('/'), 'target' => '_blank'], 'text' => ['title' => '', 'desc' => ''], 'text_align' => 'left-bottom', 'text_parallax' => 30, 'text_size_m' => 20, 'text_size_pc' => 30]]; }
|
||||||
private static function slider_options_defaults(): array { return ['direction' => 'horizontal', 'loop' => true, 'button' => true, 'pagination' => true, 'effect' => 'slide', 'scale_height' => false, 'auto_height' => false, 'pc_height' => 550, 'm_height' => 280, 'spacebetween' => 0, 'speed' => 0, 'autoplay' => true, 'interval' => 6]; }
|
private static function slider_options_defaults(): array { return ['direction' => 'horizontal', 'loop' => true, 'button' => true, 'pagination' => true, 'effect' => 'slide', 'scale_height' => false, 'auto_height' => false, 'pc_height' => 550, 'm_height' => 280, 'spacebetween' => 0, 'speed' => 0, 'autoplay' => true, 'interval' => 6]; }
|
||||||
private static function search_defaults(): array { return ['show_keywords' => true, 'popular_limit' => 6, 'show_input_cat' => false, 'in_cat' => '', 'more_cats' => '', 'show_type' => false, 'in_type' => 'post', 'before_html' => '<div class="em16 font-bold mb10">更优雅的Wordpress主题</div>' . "\n" . '<div>这是导航栏幻灯片多功能组件,可在后台进行配置</div>', 'after_html' => '']; }
|
private static function search_defaults(): array { return ['show_keywords' => true, 'popular_limit' => 6, 'show_input_cat' => false, 'in_cat' => '', 'more_cats' => '', 'show_type' => false, 'in_type' => 'post', 'before_html' => '<div class="em16 font-bold mb10">更优雅的Wordpress主题</div>' . "\n" . '<div>这是导航栏幻灯片多功能组件,可在后台进行配置</div>', 'after_html' => '']; }
|
||||||
private static function card_defaults(): array { return ['icon_radius4' => false, 'cards' => [['icon' => 'fa fas fa-gem', 'customize_icon' => '', 'icon_class' => 'c-yellow', 'link' => [], 'title' => '图标卡片', 'desc' => '这是一个图标卡片示例'], ['icon' => 'fa fas fa-star', 'customize_icon' => '', 'icon_class' => 'c-blue-2', 'link' => [], 'title' => '原创作品', 'desc' => '这是一个图标卡片示例'], ['icon' => 'fa fas fa-fire', 'customize_icon' => '', 'icon_class' => 'jb-pink', 'link' => [], 'title' => '灵感来源<badge class="ml6 jb-yellow">NEW</badge>', 'desc' => '这是一个图标卡片示例'], ['icon' => 'fa fas fa-wrench', 'customize_icon' => '', 'icon_class' => 'jb-cyan', 'link' => [], 'title' => '系统工具 <badge class="ml6 jb-blue">GO <span class="fa fa-angle-right em12"></span></badge>', 'desc' => '这是一个图标卡片示例']]]; }
|
private static function card_defaults(): array { return ['icon_radius4' => false, 'cards' => [['icon' => 'fa fas fa-gem', 'customize_icon' => '', 'icon_class' => 'c-yellow', 'link' => [], 'title' => '图标卡片', 'desc' => '这是一个图标卡片示例'], ['icon' => 'fa fas fa-star', 'customize_icon' => '', 'icon_class' => 'c-blue-2', 'link' => [], 'title' => '原创作品', 'desc' => '这是一个图标卡片示例'], ['icon' => 'fa fas fa-fire', 'customize_icon' => '', 'icon_class' => 'jb-pink', 'link' => [], 'title' => '灵感来源<badge class="ml6 jb-yellow">NEW</badge>', 'desc' => '这是一个图标卡片示例'], ['icon' => 'fa fas fa-wrench', 'customize_icon' => '', 'icon_class' => 'jb-cyan', 'link' => [], 'title' => '系统工具 <badge class="ml6 jb-blue">GO <span class="fa fas fa-angle-right em12"></span></badge>', 'desc' => '这是一个图标卡片示例']]]; }
|
||||||
|
|
||||||
private static function field(string $key, string $label, string $type, $default = null, array $extra = []): array { return array_merge(['key' => $key, 'label' => $label, 'type' => $type, 'default' => $default], $extra); }
|
private static function field(string $key, string $label, string $type, $default = null, array $extra = []): array { return array_merge(['key' => $key, 'label' => $label, 'type' => $type, 'default' => $default], $extra); }
|
||||||
private static function notice(string $content): array { return ['key' => '_notice_' . md5($content), 'type' => 'notice', 'content' => $content, 'tone' => 'warning']; }
|
private static function notice(string $content): array { return ['key' => '_notice_' . md5($content), 'type' => 'notice', 'content' => $content, 'tone' => 'warning']; }
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ trait VipServiceModal {
|
|||||||
$html .= $equity_html;
|
$html .= $equity_html;
|
||||||
$html .= '<a class="but jb-blue radius payvip-button" href="javascript:;">'
|
$html .= '<a class="but jb-blue radius payvip-button" href="javascript:;">'
|
||||||
. esc_html(sprintf(__('开通%s', 'aksrt'), $name))
|
. esc_html(sprintf(__('开通%s', 'aksrt'), $name))
|
||||||
. '<span class="ml6"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i></span></a>';
|
. '<span class="ml6"><i class="fa fas fa-chevron-circle-right" aria-hidden="true"></i></span></a>';
|
||||||
$html .= '</div></div>';
|
$html .= '</div></div>';
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -469,7 +469,7 @@ trait ScriptsPart1b {
|
|||||||
wp_enqueue_script(
|
wp_enqueue_script(
|
||||||
'aksrt-section-navs',
|
'aksrt-section-navs',
|
||||||
$base_uri . '/assets/js/section-navs.js',
|
$base_uri . '/assets/js/section-navs.js',
|
||||||
['jquery'],
|
['aksrt-runtime'],
|
||||||
(string) filemtime($section_navs),
|
(string) filemtime($section_navs),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ final class UserRenderer {
|
|||||||
if ($url === '') {
|
if ($url === '') {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
return '<a rel="nofollow" class="newadd-btns ' . esc_attr($class) . '" href="' . esc_url($url) . '"><icon class="jb-green"><i class="fa fas fa-pencil-square" aria-hidden="true"></i></icon><text>' . esc_html($text) . '</text></a>';
|
return '<a rel="nofollow" class="newadd-btns ' . esc_attr($class) . '" href="' . esc_url($url) . '"><icon class="jb-green"><i class="fa fas fa-edit" aria-hidden="true"></i></icon><text>' . esc_html($text) . '</text></a>';
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function card_link(string $url, string $class, string $text, bool $nofollow = false): string {
|
private static function card_link(string $url, string $class, string $text, bool $nofollow = false): string {
|
||||||
|
|||||||
@@ -392,7 +392,7 @@ final class WidgetSchemas {
|
|||||||
['id' => 'm_row', 'type' => 'button_set', 'label' => '移动端单行排列数量', 'default' => 2, 'options' => [1 => '1个', 2 => '2个', 3 => '3个', 4 => '4个', 6 => '6个', 12 => '12个']],
|
['id' => 'm_row', 'type' => 'button_set', 'label' => '移动端单行排列数量', 'default' => 2, 'options' => [1 => '1个', 2 => '2个', 3 => '3个', 4 => '4个', 6 => '6个', 12 => '12个']],
|
||||||
['id' => 'size', 'type' => 'slider', 'label' => '图标尺寸微调', 'default' => 0, 'min' => -10, 'max' => 10, 'step' => 1],
|
['id' => 'size', 'type' => 'slider', 'label' => '图标尺寸微调', 'default' => 0, 'min' => -10, 'max' => 10, 'step' => 1],
|
||||||
['id' => 'cards', 'type' => 'group', 'label' => '添加图标', 'max_items' => 40, 'default' => [], 'fields' => [
|
['id' => 'cards', 'type' => 'group', 'label' => '添加图标', 'max_items' => 40, 'default' => [], 'fields' => [
|
||||||
['id' => 'icon', 'type' => 'icon', 'label' => '选择图标', 'default' => 'fa fa-magic'],
|
['id' => 'icon', 'type' => 'icon', 'label' => '选择图标', 'default' => 'fa fas fa-magic'],
|
||||||
['id' => 'customize_icon', 'type' => 'textarea', 'label' => '自定义图标', 'default' => '', 'allow_html' => true, 'attributes' => ['rows' => 1]],
|
['id' => 'customize_icon', 'type' => 'textarea', 'label' => '自定义图标', 'default' => '', 'allow_html' => true, 'attributes' => ['rows' => 1]],
|
||||||
['id' => 'link', 'type' => 'link', 'label' => '跳转链接', 'default' => []],
|
['id' => 'link', 'type' => 'link', 'label' => '跳转链接', 'default' => []],
|
||||||
['id' => 'icon_radius', 'type' => 'switcher', 'label' => '显示图标背景', 'default' => false],
|
['id' => 'icon_radius', 'type' => 'switcher', 'label' => '显示图标背景', 'default' => false],
|
||||||
@@ -414,7 +414,7 @@ final class WidgetSchemas {
|
|||||||
['id' => 'cards', 'type' => 'group', 'label' => '添加卡片', 'max_items' => 40, 'default' => [], 'fields' => [
|
['id' => 'cards', 'type' => 'group', 'label' => '添加卡片', 'max_items' => 40, 'default' => [], 'fields' => [
|
||||||
['id' => 'title', 'type' => 'textarea', 'label' => '文案标题', 'default' => '', 'allow_html' => true, 'attributes' => ['rows' => 1]],
|
['id' => 'title', 'type' => 'textarea', 'label' => '文案标题', 'default' => '', 'allow_html' => true, 'attributes' => ['rows' => 1]],
|
||||||
['id' => 'desc', 'type' => 'textarea', 'label' => '文案简介', 'default' => '', 'allow_html' => true, 'attributes' => ['rows' => 2]],
|
['id' => 'desc', 'type' => 'textarea', 'label' => '文案简介', 'default' => '', 'allow_html' => true, 'attributes' => ['rows' => 2]],
|
||||||
['id' => 'icon', 'type' => 'icon', 'label' => '选择图标', 'default' => 'fa fa-magic'],
|
['id' => 'icon', 'type' => 'icon', 'label' => '选择图标', 'default' => 'fa fas fa-magic'],
|
||||||
['id' => 'customize_icon', 'type' => 'textarea', 'label' => '自定义图标', 'default' => '', 'allow_html' => true, 'attributes' => ['rows' => 1]],
|
['id' => 'customize_icon', 'type' => 'textarea', 'label' => '自定义图标', 'default' => '', 'allow_html' => true, 'attributes' => ['rows' => 1]],
|
||||||
['id' => 'icon_class', 'type' => 'palette', 'label' => '图标颜色', 'default' => 'c-yellow', 'options' => self::icon_background_palette()],
|
['id' => 'icon_class', 'type' => 'palette', 'label' => '图标颜色', 'default' => 'c-yellow', 'options' => self::icon_background_palette()],
|
||||||
['id' => 'link', 'type' => 'link', 'label' => '跳转链接', 'default' => []],
|
['id' => 'link', 'type' => 'link', 'label' => '跳转链接', 'default' => []],
|
||||||
|
|||||||
@@ -58,8 +58,8 @@ if (file_exists($js)) {
|
|||||||
wp_enqueue_script(
|
wp_enqueue_script(
|
||||||
'aksrt-front-submit-pay-download',
|
'aksrt-front-submit-pay-download',
|
||||||
get_template_directory_uri() . '/assets/js/front-submit-pay-download.js',
|
get_template_directory_uri() . '/assets/js/front-submit-pay-download.js',
|
||||||
[],
|
['aksrt-runtime'],
|
||||||
(string) filemtime($pay_download_js),
|
(string) filemtime($pay_download_js),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
wp_enqueue_script(
|
wp_enqueue_script(
|
||||||
@@ -74,7 +74,7 @@ if (file_exists($js)) {
|
|||||||
wp_enqueue_script(
|
wp_enqueue_script(
|
||||||
'aksrt-mini-upload',
|
'aksrt-mini-upload',
|
||||||
get_template_directory_uri() . '/assets/js/mini-upload.js',
|
get_template_directory_uri() . '/assets/js/mini-upload.js',
|
||||||
[],
|
['aksrt-runtime'],
|
||||||
(string) filemtime($mini),
|
(string) filemtime($mini),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -38,13 +38,19 @@ const header = join([
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
test('the public dependency graph is the single local runtime stack', () => {
|
test('the public dependency graph is the single local runtime stack', () => {
|
||||||
assert.match(scripts, /wp_deregister_script\('jquery'\)/);
|
const buildTool = read('tools/build-public-assets.mjs');
|
||||||
assert.match(scripts, /jquery\.min\.js'[\s\S]*?'1\.9\.1'/);
|
|
||||||
assert.match(scripts, /bootstrap\.min\.css'[\s\S]*?'3\.4\.1'/);
|
assert.match(scripts, /registered\['jquery'\]->deps = \['jquery-core'\]/);
|
||||||
assert.match(scripts, /fontawesome5'[\s\S]*?all\.min\.css'[\s\S]*?'5\.15\.4'/);
|
assert.match(scripts, /wp_enqueue_script\('jquery'\)/);
|
||||||
assert.match(scripts, /main\.min\.css/);
|
assert.doesNotMatch(scripts, /wp_deregister_script\('jquery'\)/);
|
||||||
assert.match(scripts, /loader\.js'[\s\S]*?\['jquery', 'bootstrap'\]/);
|
assert.match(scripts, /'aksrt-runtime'/);
|
||||||
assert.match(read('assets/js/runtime/loader.js'), /tbquire\(\['main'\]\)/);
|
assert.match(scripts, /assets\/js\/build\/public\.js/);
|
||||||
|
assert.match(buildTool, /assets\/css\/bootstrap\.min\.css/);
|
||||||
|
assert.match(buildTool, /assets\/fontawesome5\/css\/all\.min\.css/);
|
||||||
|
assert.match(buildTool, /assets\/css\/main\.min\.css/);
|
||||||
|
assert.match(buildTool, /assets\/js\/runtime\/libs\/bootstrap\.min\.js/);
|
||||||
|
assert.match(buildTool, /assets\/js\/runtime\/loader\.js/);
|
||||||
|
assert.match(buildTool, /assets\/js\/runtime\/main\.min\.js/);
|
||||||
for (const file of [
|
for (const file of [
|
||||||
'assets/js/runtime/libs/jquery.min.js',
|
'assets/js/runtime/libs/jquery.min.js',
|
||||||
'assets/js/runtime/libs/bootstrap.min.js',
|
'assets/js/runtime/libs/bootstrap.min.js',
|
||||||
@@ -146,16 +152,17 @@ test('mobile navigation is one setting-driven left right or top drawer', () => {
|
|||||||
|
|
||||||
test('guest account member VIP and publish contracts share reference header DOM', () => {
|
test('guest account member VIP and publish contracts share reference header DOM', () => {
|
||||||
const userboxCss = read('assets/css/frontend/header-userbox.css');
|
const userboxCss = read('assets/css/frontend/header-userbox.css');
|
||||||
|
const buildTool = read('tools/build-public-assets.mjs');
|
||||||
|
|
||||||
assert.match(header, /is_user_logged_in\(\)/);
|
assert.match(header, /is_user_logged_in\(\)/);
|
||||||
assert.match(header, /sub-user-box aksrt-header-userbox/);
|
assert.match(header, /sub-user-box aksrt-header-userbox/);
|
||||||
assert.match(header, /signin-loader|signin/);
|
assert.match(header, /signin-loader|signin/);
|
||||||
assert.match(header, /get_payment_vip_settings/);
|
assert.match(header, /get_payment_vip_settings/);
|
||||||
assert.match(header, /nav_user_newposts_btn/);
|
assert.match(header, /navbar-newposts/);
|
||||||
assert.match(header, /nav_newposts/);
|
assert.match(header, /nav_newposts/);
|
||||||
assert.match(header, /navbar-form navbar-right navbar-but/);
|
assert.match(header, /navbar-form navbar-right/);
|
||||||
assert.match(header, /pay-vip/);
|
assert.match(header, /pay-vip/);
|
||||||
assert.match(scripts, /\$enqueue_module\('header-userbox'\)/);
|
assert.match(buildTool, /assets\/css\/frontend\/header-userbox\.css/);
|
||||||
assert.match(userboxCss, /\.aksrt-header-userbox \.user-info > \.avatar/);
|
assert.match(userboxCss, /\.aksrt-header-userbox \.user-info > \.avatar/);
|
||||||
assert.match(userboxCss, /\.aksrt-header-wallet/);
|
assert.match(userboxCss, /\.aksrt-header-wallet/);
|
||||||
assert.match(userboxCss, /\.aksrt-header-checkin/);
|
assert.match(userboxCss, /\.aksrt-header-checkin/);
|
||||||
|
|||||||
@@ -72,7 +72,11 @@ function createHarness() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let providerCallback;
|
let providerCallback;
|
||||||
|
let captchaInit = null;
|
||||||
const window = {
|
const window = {
|
||||||
|
AksrtFrontend: {
|
||||||
|
register(_name, init) { captchaInit = init; },
|
||||||
|
},
|
||||||
fetch(url) {
|
fetch(url) {
|
||||||
if (url === '/challenge') return Promise.resolve({ ok: true, json: () => Promise.resolve({ success: true, data: { challenge: 'challenge-token' } }) });
|
if (url === '/challenge') return Promise.resolve({ ok: true, json: () => Promise.resolve({ success: true, data: { challenge: 'challenge-token' } }) });
|
||||||
if (url === '/exchange') return Promise.resolve({ ok: true, json: () => Promise.resolve({ success: true, data: { proof: 'proof-token' } }) });
|
if (url === '/exchange') return Promise.resolve({ ok: true, json: () => Promise.resolve({ success: true, data: { proof: 'proof-token' } }) });
|
||||||
@@ -87,6 +91,7 @@ function createHarness() {
|
|||||||
Promise,
|
Promise,
|
||||||
};
|
};
|
||||||
vm.runInNewContext(runtime, { window, document, Promise, MutationObserver: undefined, setTimeout, clearTimeout, console });
|
vm.runInNewContext(runtime, { window, document, Promise, MutationObserver: undefined, setTimeout, clearTimeout, console });
|
||||||
|
if (captchaInit) captchaInit(document, 'init');
|
||||||
return { api: window.AKSRTCaptcha, container };
|
return { api: window.AKSRTCaptcha, container };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const assert = require('node:assert/strict');
|
||||||
|
const fs = require('node:fs');
|
||||||
|
const path = require('node:path');
|
||||||
|
const test = require('node:test');
|
||||||
|
|
||||||
|
const root = path.resolve(__dirname, '..', '..');
|
||||||
|
const read = (file) => fs.readFileSync(path.join(root, file), 'utf8');
|
||||||
|
|
||||||
|
const publicSources = [
|
||||||
|
'assets/js/core/comment-fixed-input.js',
|
||||||
|
'assets/js/core/misc.js',
|
||||||
|
'assets/js/follow.js',
|
||||||
|
'assets/js/enhancements.js',
|
||||||
|
'assets/js/enhancements2.js',
|
||||||
|
'assets/js/color-extract.js',
|
||||||
|
'assets/js/effects.js',
|
||||||
|
'assets/js/captcha-front.js',
|
||||||
|
'assets/widgets/frontend.js',
|
||||||
|
];
|
||||||
|
|
||||||
|
const routedSources = [
|
||||||
|
'assets/js/auth.js',
|
||||||
|
'assets/js/author.js',
|
||||||
|
'assets/js/routes/user-center.js',
|
||||||
|
'assets/js/order-center.js',
|
||||||
|
'assets/js/credits.js',
|
||||||
|
'assets/js/signin.js',
|
||||||
|
'assets/js/reward.js',
|
||||||
|
'assets/js/report.js',
|
||||||
|
'assets/js/page-navs.js',
|
||||||
|
'assets/js/section-navs.js',
|
||||||
|
'assets/js/posts-navs-page.js',
|
||||||
|
'assets/js/front-submit.js',
|
||||||
|
'assets/js/mini-upload.js',
|
||||||
|
'assets/js/page-template.js',
|
||||||
|
'assets/js/page-edit.js',
|
||||||
|
'assets/js/precode.js',
|
||||||
|
'assets/js/post-share.js',
|
||||||
|
'assets/js/poster-share.js',
|
||||||
|
'assets/js/pay-vip.js',
|
||||||
|
'assets/js/video-player.js',
|
||||||
|
'assets/js/download-status.js',
|
||||||
|
'assets/js/ban-appeal-page.js',
|
||||||
|
'assets/js/docs-navigation.js',
|
||||||
|
'assets/js/input-expand.js',
|
||||||
|
'assets/js/waterfall.js',
|
||||||
|
'assets/js/yiyan.js',
|
||||||
|
'assets/js/messages.js',
|
||||||
|
'assets/js/site-notice.js',
|
||||||
|
'assets/js/user-badge-actions.js',
|
||||||
|
];
|
||||||
|
|
||||||
|
const readyPattern = /(?:document\.addEventListener\(\s*['"]DOMContentLoaded['"]|document\.readyState\s*===|jQuery\(document\)\.ready\s*\()/;
|
||||||
|
|
||||||
|
test('global DOM boot is the only initial page lifecycle owner', () => {
|
||||||
|
const runtime = read('assets/js/aksrt-runtime.js');
|
||||||
|
const registry = read('assets/js/rehydrate.js');
|
||||||
|
assert.match(registry, /boot:\s*function/);
|
||||||
|
assert.match(registry, /register:[\s\S]*?_booted/);
|
||||||
|
assert.match(runtime, /AksrtFrontend\.boot\(root\)/);
|
||||||
|
assert.match(runtime, /aksrt\.autoFun\(document, 'init'\)/);
|
||||||
|
assert.match(runtime, /reason === 'init'[\s\S]*?AksrtFrontend\.boot\(root\)[\s\S]*?else[\s\S]*?AksrtFrontend\.rehydrate\(root, reason\)/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('public bundle components register instead of owning DOM ready', () => {
|
||||||
|
for (const file of publicSources) {
|
||||||
|
const source = read(file);
|
||||||
|
assert.doesNotMatch(source, readyPattern, `${file} still owns a DOM-ready boot`);
|
||||||
|
assert.match(source, /AksrtFrontend\.register\(/, `${file} must register with the global lifecycle`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('active routed UI scripts register with the global lifecycle', () => {
|
||||||
|
for (const file of routedSources) {
|
||||||
|
const source = read(file);
|
||||||
|
if (/API|coordinator|runtime/i.test(source.slice(0, 500)) && !/querySelector|addEventListener/.test(source)) continue;
|
||||||
|
assert.doesNotMatch(source, readyPattern, `${file} still owns a DOM-ready boot`);
|
||||||
|
assert.match(source, /AksrtFrontend\.register\(/, `${file} must register with the global lifecycle`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('high-risk routed components remain idempotent under global rehydrate', () => {
|
||||||
|
const pageNavs = read('assets/js/page-navs.js');
|
||||||
|
const sectionNavs = read('assets/js/section-navs.js');
|
||||||
|
const poster = read('assets/js/poster-share.js');
|
||||||
|
|
||||||
|
assert.match(pageNavs, /__aksrtPageNavInitialized/);
|
||||||
|
assert.match(pageNavs, /var grid = self\.root\.querySelector\('\.aksrt-doc-grid'\)/);
|
||||||
|
assert.match(sectionNavs, /if \(scrollspyBound\) return/);
|
||||||
|
assert.match(sectionNavs, /if \(autoHashHandled \|\| !window\.location\.hash\) return/);
|
||||||
|
assert.match(poster, /triggers\.filter\(function \(el\) \{ return el\.dataset\.posterInit !== '1'; \}\)/);
|
||||||
|
assert.doesNotMatch(poster, /triggers\.some\(function \(el\) \{ return el\.dataset\.posterInit === '1'; \}\)/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('resource and SDK load listeners are not mistaken for page boot', () => {
|
||||||
|
const captcha = read('assets/js/captcha-front.js');
|
||||||
|
const color = read('assets/js/color-extract.js');
|
||||||
|
assert.match(captcha, /\.onload\s*=|addEventListener\(['"]load['"]/);
|
||||||
|
assert.match(color, /addEventListener\(['"]load['"]/);
|
||||||
|
assert.doesNotMatch(captcha, /DOMContentLoaded/);
|
||||||
|
assert.doesNotMatch(color, /DOMContentLoaded/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('route scripts that use the registry load after the public runtime', () => {
|
||||||
|
const scripts = read('src/Core/ScriptsPart1b.php') + read('src/Core/ScriptsPart1c.php');
|
||||||
|
const files = ['section-navs.js', 'page-navs.js', 'posts-navs-page.js', 'author.js', 'auth.js'];
|
||||||
|
for (const file of files) {
|
||||||
|
const uri = scripts.indexOf("/assets/js/" + file);
|
||||||
|
assert.notEqual(uri, -1, `${file} must be enqueued`);
|
||||||
|
const blockStart = scripts.lastIndexOf('wp_enqueue_script(', uri);
|
||||||
|
const blockEnd = scripts.indexOf(');', uri);
|
||||||
|
const block = scripts.slice(blockStart, blockEnd + 2);
|
||||||
|
assert.match(block, /aksrt-runtime/, `${file} must depend on aksrt-runtime`);
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const assert = require('node:assert/strict');
|
||||||
|
const fs = require('node:fs');
|
||||||
|
const path = require('node:path');
|
||||||
|
const vm = require('node:vm');
|
||||||
|
const test = require('node:test');
|
||||||
|
|
||||||
|
const root = path.resolve(__dirname, '..', '..');
|
||||||
|
const read = (file) => fs.readFileSync(path.join(root, file), 'utf8');
|
||||||
|
|
||||||
|
test('homepage uses the global DOM lifecycle without a second ready path', () => {
|
||||||
|
const runtime = read('assets/js/aksrt-runtime.js');
|
||||||
|
const homepage = read('assets/js/homepage-fixed.js');
|
||||||
|
|
||||||
|
assert.match(runtime, /aksrt\.autoFun\s*=\s*function\s*\(root, reason\)/);
|
||||||
|
assert.match(runtime, /function initRuntime\(\)\s*\{\s*aksrt\.autoFun\(document, 'init'\);/s);
|
||||||
|
assert.doesNotMatch(runtime, /function initRuntime\(\)\s*\{\s*aksrt\.autoFun\(document\);/s);
|
||||||
|
|
||||||
|
assert.match(homepage, /window\.AksrtFrontend\.register\('aksrt-homepage', init\)/);
|
||||||
|
assert.doesNotMatch(homepage, /DOMContentLoaded/);
|
||||||
|
assert.doesNotMatch(homepage, /document\.querySelectorAll\('\[data-sort-dropdown-trigger\]'\)/);
|
||||||
|
assert.doesNotMatch(homepage, /document\.querySelectorAll\('\.aksrt-homepage__stream'\)/);
|
||||||
|
assert.doesNotMatch(homepage, /document\.querySelectorAll\('\.aksrt-homepage__tabs\.home-tab-nav-box'\)/);
|
||||||
|
assert.match(homepage, /dataset\.aksrtHomeTabsBound === '1'/);
|
||||||
|
assert.match(homepage, /dataset\.aksrtSortDropdownBound === '1'/);
|
||||||
|
assert.match(homepage, /dataset\.aksrtSortbarBound === '1'/);
|
||||||
|
assert.match(homepage, /dataset\.aksrtStickyTabsBound === '1'/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('homepage initializer is registered once and remains idempotent across rehydrate calls', () => {
|
||||||
|
const source = read('assets/js/homepage-fixed.js');
|
||||||
|
const registrations = [];
|
||||||
|
let sortbarClickBindings = 0;
|
||||||
|
const sortbar = {
|
||||||
|
dataset: {},
|
||||||
|
getAttribute() {
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
addEventListener(type) {
|
||||||
|
if (type === 'click') sortbarClickBindings++;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const stream = {
|
||||||
|
querySelector(selector) {
|
||||||
|
return selector === '.aksrt-homepage__sortbar' ? sortbar : null;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const scope = {
|
||||||
|
querySelectorAll(selector) {
|
||||||
|
return selector === '.aksrt-homepage__stream' ? [stream] : [];
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const context = {
|
||||||
|
window: {
|
||||||
|
AksrtFrontend: {
|
||||||
|
register(name, init) {
|
||||||
|
registrations.push({ name, init });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
document: scope,
|
||||||
|
console,
|
||||||
|
URLSearchParams,
|
||||||
|
URL,
|
||||||
|
setTimeout,
|
||||||
|
clearTimeout,
|
||||||
|
};
|
||||||
|
context.window.window = context.window;
|
||||||
|
context.window.document = scope;
|
||||||
|
vm.runInNewContext(source, context, { filename: 'homepage-fixed.js' });
|
||||||
|
|
||||||
|
assert.equal(registrations.length, 1);
|
||||||
|
assert.equal(registrations[0].name, 'aksrt-homepage');
|
||||||
|
assert.equal(typeof registrations[0].init, 'function');
|
||||||
|
registrations[0].init(scope, 'init');
|
||||||
|
registrations[0].init(scope, 'ajax');
|
||||||
|
assert.equal(sortbarClickBindings, 1);
|
||||||
|
assert.equal(sortbar.dataset.aksrtSortbarBound, '1');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('homepage AJAX content continues to use the shared ajax rehydrate contract', () => {
|
||||||
|
const homepage = read('assets/js/homepage-fixed.js');
|
||||||
|
assert.match(homepage, /window\.AksrtFrontend\.rehydrate\(panel, 'ajax'\)/);
|
||||||
|
});
|
||||||
@@ -149,7 +149,9 @@ test('OAuth result handler maps safe errors and preserves unrelated URL state',
|
|||||||
activeElement: null,
|
activeElement: null,
|
||||||
body: { classList: { add() {}, remove() {} } },
|
body: { classList: { add() {}, remove() {} } },
|
||||||
}
|
}
|
||||||
|
let authInit = null
|
||||||
const window = {
|
const window = {
|
||||||
|
AksrtFrontend: { register: (_name, init) => { authInit = init } },
|
||||||
aksrtData: {},
|
aksrtData: {},
|
||||||
URL,
|
URL,
|
||||||
location,
|
location,
|
||||||
@@ -175,6 +177,7 @@ test('OAuth result handler maps safe errors and preserves unrelated URL state',
|
|||||||
Math,
|
Math,
|
||||||
Promise,
|
Promise,
|
||||||
})
|
})
|
||||||
|
authInit(document, 'init')
|
||||||
assert.deepEqual(notices, [{ message: '第三方授权失败,请重试', type: 'danger' }])
|
assert.deepEqual(notices, [{ message: '第三方授权失败,请重试', type: 'danger' }])
|
||||||
assert.equal(replaced, '/sign/?keep=1#section')
|
assert.equal(replaced, '/sign/?keep=1#section')
|
||||||
assert.equal(replaced.includes('script'), false)
|
assert.equal(replaced.includes('script'), false)
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const assert = require('node:assert/strict');
|
||||||
|
const fs = require('node:fs');
|
||||||
|
const path = require('node:path');
|
||||||
|
const test = require('node:test');
|
||||||
|
|
||||||
|
const root = path.resolve(__dirname, '..', '..');
|
||||||
|
const read = (file) => fs.readFileSync(path.join(root, file), 'utf8');
|
||||||
|
|
||||||
|
test('public bundle has one source list and one generated legacy main artifact', () => {
|
||||||
|
const build = read('tools/build-public-assets.mjs');
|
||||||
|
assert.match(build, /'assets\/js\/rehydrate\.js'[\s\S]*?'assets\/js\/aksrt-runtime\.js'/);
|
||||||
|
assert.match(build, /'assets\/js\/runtime\/main\.min\.js'/);
|
||||||
|
assert.match(build, /async function buildRuntimeMainMin\(\)/);
|
||||||
|
assert.match(build, /assets\/js\/runtime\/main\.js/);
|
||||||
|
assert.match(build, /await buildRuntimeMainMin\(\)/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('global lifecycle source precedes every registered public component', () => {
|
||||||
|
const build = read('tools/build-public-assets.mjs');
|
||||||
|
const registry = build.indexOf("'assets/js/rehydrate.js'");
|
||||||
|
const runtime = build.indexOf("'assets/js/aksrt-runtime.js'");
|
||||||
|
const legacy = build.indexOf("'assets/js/runtime/main.min.js'");
|
||||||
|
assert.ok(registry >= 0 && registry < runtime && runtime < legacy);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('deleted orphan entry files do not return to enqueue or build graphs', () => {
|
||||||
|
const graph = [
|
||||||
|
read('tools/build-public-assets.mjs'),
|
||||||
|
read('src/Core/ScriptsPart1b.php'),
|
||||||
|
read('src/Core/ScriptsPart1c.php'),
|
||||||
|
].join('\n');
|
||||||
|
assert.equal(fs.existsSync(path.join(root, 'assets/js/main.js')), false);
|
||||||
|
assert.equal(fs.existsSync(path.join(root, 'assets/js/loader.js')), false);
|
||||||
|
assert.doesNotMatch(graph, /assets\/js\/(?:main|loader)\.js/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('built public JavaScript contains the canonical global boot', () => {
|
||||||
|
const bundle = read('assets/js/build/public.js');
|
||||||
|
assert.match(bundle, /AksrtFrontend\.boot\(root\)/);
|
||||||
|
assert.match(bundle, /aksrt\.autoFun\(document, 'init'\)/);
|
||||||
|
assert.match(bundle, /aksrt:ready/);
|
||||||
|
});
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const assert = require('node:assert/strict');
|
||||||
|
const fs = require('node:fs');
|
||||||
|
const path = require('node:path');
|
||||||
|
const vm = require('node:vm');
|
||||||
|
const test = require('node:test');
|
||||||
|
|
||||||
|
const root = path.resolve(__dirname, '..', '..');
|
||||||
|
const source = fs.readFileSync(path.join(root, 'assets/js/rehydrate.js'), 'utf8');
|
||||||
|
|
||||||
|
function createRuntime() {
|
||||||
|
const events = [];
|
||||||
|
const document = {
|
||||||
|
dispatchEvent(event) {
|
||||||
|
events.push(event);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
function CustomEvent(type, options) {
|
||||||
|
this.type = type;
|
||||||
|
this.bubbles = Boolean(options && options.bubbles);
|
||||||
|
this.detail = options && options.detail;
|
||||||
|
}
|
||||||
|
const errors = [];
|
||||||
|
const context = {
|
||||||
|
window: {},
|
||||||
|
document,
|
||||||
|
CustomEvent,
|
||||||
|
console: {
|
||||||
|
error(...args) {
|
||||||
|
errors.push(args);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
context.window.window = context.window;
|
||||||
|
context.window.document = document;
|
||||||
|
vm.runInNewContext(source, context, { filename: 'rehydrate.js' });
|
||||||
|
return { api: context.window.AksrtFrontend, document, events, errors };
|
||||||
|
}
|
||||||
|
|
||||||
|
test('global DOM boot runs registered components once with init reason', () => {
|
||||||
|
const runtime = createRuntime();
|
||||||
|
const calls = [];
|
||||||
|
runtime.api.register('first', (rootNode, reason) => calls.push([rootNode, reason]));
|
||||||
|
|
||||||
|
runtime.api.boot(runtime.document);
|
||||||
|
runtime.api.boot(runtime.document);
|
||||||
|
|
||||||
|
assert.equal(runtime.api.isBooted(), true);
|
||||||
|
assert.deepEqual(calls, [[runtime.document, 'init']]);
|
||||||
|
assert.deepEqual(runtime.events.map((event) => event.type), ['aksrt:rehydrated', 'aksrt:ready']);
|
||||||
|
assert.equal(runtime.events[0].detail.reason, 'init');
|
||||||
|
assert.equal(runtime.events[1].detail.reason, 'init');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('late registrations initialize immediately after global boot', () => {
|
||||||
|
const runtime = createRuntime();
|
||||||
|
const calls = [];
|
||||||
|
runtime.api.boot(runtime.document);
|
||||||
|
runtime.api.register('late', (rootNode, reason) => calls.push([rootNode, reason]));
|
||||||
|
|
||||||
|
assert.deepEqual(calls, [[runtime.document, 'init']]);
|
||||||
|
assert.deepEqual(Array.from(runtime.api.getRegistered()), ['late']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('same-name registration replaces the owner without duplicating it', () => {
|
||||||
|
const runtime = createRuntime();
|
||||||
|
const calls = [];
|
||||||
|
runtime.api.register('owner', () => calls.push('old'));
|
||||||
|
runtime.api.register('owner', () => calls.push('new'));
|
||||||
|
runtime.api.boot(runtime.document);
|
||||||
|
|
||||||
|
assert.deepEqual(Array.from(runtime.api.getRegistered()), ['owner']);
|
||||||
|
assert.deepEqual(calls, ['new']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('rehydrate preserves root and reason while isolating component failures', () => {
|
||||||
|
const runtime = createRuntime();
|
||||||
|
const fragment = {
|
||||||
|
dispatchEvent(event) {
|
||||||
|
runtime.events.push(event);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const calls = [];
|
||||||
|
runtime.api.register('broken', () => { throw new Error('broken'); });
|
||||||
|
runtime.api.register('healthy', (rootNode, reason) => calls.push([rootNode, reason]));
|
||||||
|
|
||||||
|
runtime.api.rehydrate(fragment, 'modal');
|
||||||
|
|
||||||
|
assert.deepEqual(calls, [[fragment, 'modal']]);
|
||||||
|
assert.equal(runtime.errors.length, 1);
|
||||||
|
assert.equal(runtime.events.at(-1).type, 'aksrt:rehydrated');
|
||||||
|
assert.equal(runtime.events.at(-1).detail.reason, 'modal');
|
||||||
|
assert.equal(runtime.events.at(-1).bubbles, true);
|
||||||
|
});
|
||||||
@@ -240,7 +240,8 @@ test('balance center actions use direct fixed-id notyf flows', () => {
|
|||||||
assert.match(signinController, /querySelectorAll\('\[data-signin-btn\]'\)/);
|
assert.match(signinController, /querySelectorAll\('\[data-signin-btn\]'\)/);
|
||||||
assert.match(signinController, /freshButtons\.forEach[\s\S]*?addEventListener\('click'/);
|
assert.match(signinController, /freshButtons\.forEach[\s\S]*?addEventListener\('click'/);
|
||||||
assert.match(credits, /onTimeout:[\s\S]*?notyf\([^;]+?'danger'[^;]+?'aksrt-balance-charge-payment-toast'\)/);
|
assert.match(credits, /onTimeout:[\s\S]*?notyf\([^;]+?'danger'[^;]+?'aksrt-balance-charge-payment-toast'\)/);
|
||||||
assert.match(credits, /register\('credits',[\s\S]*?initSigninGoto\(\);[\s\S]*?initBalanceCharge\(\);[\s\S]*?initTransfer\(\);[\s\S]*?initPointsExchange\(\);[\s\S]*?initWithdraw\(\);/);
|
assert.match(credits, /function bootAssets\(root, reason\)[\s\S]*?initSigninGoto\(root\);[\s\S]*?initBalanceCharge\(root\);[\s\S]*?initTransfer\(root\);[\s\S]*?initPointsExchange\(root\);[\s\S]*?initWithdraw\(root\);/);
|
||||||
|
assert.match(credits, /register\('credits', bootAssets\)/);
|
||||||
assert.doesNotMatch(credits, /function initSignin\(|\/signin\/today|POST \/signin/);
|
assert.doesNotMatch(credits, /function initSignin\(|\/signin\/today|POST \/signin/);
|
||||||
assert.match(signinController, /aksrtSigninInitialized/);
|
assert.match(signinController, /aksrtSigninInitialized/);
|
||||||
assert.match(credits, /aksrtPointsExchangeInitialized[\s\S]*?aksrtWithdrawInitialized/);
|
assert.match(credits, /aksrtPointsExchangeInitialized[\s\S]*?aksrtWithdrawInitialized/);
|
||||||
@@ -321,7 +322,7 @@ test('profile save uses AJAX rehydrate and a fixed-id notyf flow without query f
|
|||||||
const scripts = read('src/Core/ScriptsPart1b.php');
|
const scripts = read('src/Core/ScriptsPart1b.php');
|
||||||
|
|
||||||
assert.match(profile, /function initProfileForm\(root\)[\s\S]*?aksrtProfileInitialized[\s\S]*?addEventListener\('submit'/);
|
assert.match(profile, /function initProfileForm\(root\)[\s\S]*?aksrtProfileInitialized[\s\S]*?addEventListener\('submit'/);
|
||||||
assert.match(profile, /register\('aksrt-profile-form',[\s\S]*?initProfileForm\(root\)/);
|
assert.match(profile, /register\('aksrt-user-center',[\s\S]*?initProfileForm\(root\)/);
|
||||||
assert.match(profile, /notyf\([^;]+?'load'[^;]+?'aksrt-profile-save-toast'\);/);
|
assert.match(profile, /notyf\([^;]+?'load'[^;]+?'aksrt-profile-save-toast'\);/);
|
||||||
assert.match(profile, /notyf\([^;]+?'success'[^;]+?'aksrt-profile-save-toast'\);/);
|
assert.match(profile, /notyf\([^;]+?'success'[^;]+?'aksrt-profile-save-toast'\);/);
|
||||||
assert.match(profile, /notyf\([^;]+?'danger'[^;]+?'aksrt-profile-save-toast'\);/);
|
assert.match(profile, /notyf\([^;]+?'danger'[^;]+?'aksrt-profile-save-toast'\);/);
|
||||||
@@ -350,7 +351,7 @@ test('settings actions use rehydrated fixed-id notyf flows', () => {
|
|||||||
assert.match(userCenter, /notyf\([^;]+?'load'[^;]+?toastId\);/);
|
assert.match(userCenter, /notyf\([^;]+?'load'[^;]+?toastId\);/);
|
||||||
assert.match(userCenter, /notyf\([^;]+?'success'[^;]+?toastId\);/);
|
assert.match(userCenter, /notyf\([^;]+?'success'[^;]+?toastId\);/);
|
||||||
assert.match(userCenter, /notyf\([^;]+?'danger'[^;]+?toastId\);/);
|
assert.match(userCenter, /notyf\([^;]+?'danger'[^;]+?toastId\);/);
|
||||||
assert.match(userCenter, /register\('aksrt-settings',[\s\S]*?initSettings\(root\);[\s\S]*?initBindPhone\(root\);/);
|
assert.match(userCenter, /register\('aksrt-user-center',[\s\S]*?initSettings\(root\);[\s\S]*?initBindPhone\(root\);/);
|
||||||
assert.match(userCenter, /aksrtSettingsInitialized/);
|
assert.match(userCenter, /aksrtSettingsInitialized/);
|
||||||
assert.match(userCenter, /oauth_action[\s\S]*?notyf\(message, type\)[\s\S]*?history\.replaceState/);
|
assert.match(userCenter, /oauth_action[\s\S]*?notyf\(message, type\)[\s\S]*?history\.replaceState/);
|
||||||
assert.doesNotMatch(userCenter, /oauth_unbound/);
|
assert.doesNotMatch(userCenter, /oauth_unbound/);
|
||||||
|
|||||||
@@ -173,6 +173,22 @@ async function buildScriptBundle() {
|
|||||||
await writeFile(path.join(jsBuildDir, 'public.js'), `${sections.join('\n\n')}\n`, 'utf8');
|
await writeFile(path.join(jsBuildDir, 'public.js'), `${sections.join('\n\n')}\n`, 'utf8');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function buildRuntimeMainMin() {
|
||||||
|
const sourcePath = path.join(repoRoot, 'assets/js/runtime/main.js');
|
||||||
|
const outputPath = path.join(repoRoot, 'assets/js/runtime/main.min.js');
|
||||||
|
const source = await readFile(sourcePath, 'utf8');
|
||||||
|
const minified = await transform(source, {
|
||||||
|
charset: 'utf8',
|
||||||
|
legalComments: 'inline',
|
||||||
|
loader: 'js',
|
||||||
|
minifyIdentifiers: false,
|
||||||
|
minifySyntax: true,
|
||||||
|
minifyWhitespace: true,
|
||||||
|
sourcefile: 'runtime/main.js',
|
||||||
|
});
|
||||||
|
await writeFile(outputPath, minified.code, 'utf8');
|
||||||
|
}
|
||||||
|
|
||||||
// 评论区硬切换后 main.min.css 由 main.css 重新生成,保持两者同步。
|
// 评论区硬切换后 main.min.css 由 main.css 重新生成,保持两者同步。
|
||||||
async function buildMainMin() {
|
async function buildMainMin() {
|
||||||
const sourcePath = path.join(repoRoot, 'assets/css/main.css');
|
const sourcePath = path.join(repoRoot, 'assets/css/main.css');
|
||||||
@@ -190,6 +206,7 @@ async function buildMainMin() {
|
|||||||
|
|
||||||
await mkdir(cssBuildDir, { recursive: true });
|
await mkdir(cssBuildDir, { recursive: true });
|
||||||
await mkdir(jsBuildDir, { recursive: true });
|
await mkdir(jsBuildDir, { recursive: true });
|
||||||
|
await buildRuntimeMainMin();
|
||||||
// 先刷新 main.min.css,public.css 打包时才能读到最新内容。
|
// 先刷新 main.min.css,public.css 打包时才能读到最新内容。
|
||||||
await buildMainMin();
|
await buildMainMin();
|
||||||
for (const [outputName, sources] of Object.entries(cssBundles)) {
|
for (const [outputName, sources] of Object.entries(cssBundles)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user