From a89edfe5e8960132fb415a2c697234d943a5e409 Mon Sep 17 00:00:00 2001 From: Vaica <94612053+zqlit@users.noreply.github.com> Date: Thu, 25 Jun 2026 18:49:06 +0800 Subject: [PATCH] Update artalk.js --- themes/Ying/assets/js/modules/artalk.js | 217 ++++++++++++++++++++++++ 1 file changed, 217 insertions(+) diff --git a/themes/Ying/assets/js/modules/artalk.js b/themes/Ying/assets/js/modules/artalk.js index fac76dc0..36b73ff1 100644 --- a/themes/Ying/assets/js/modules/artalk.js +++ b/themes/Ying/assets/js/modules/artalk.js @@ -1,4 +1,144 @@ // Global Artalk Initialization Function (Supports PJAX) + +// ── 持久化 artalkInitCount (跨 PJAX 切换保留) ── +// PJAX 切换时 artalk.js 会被重新加载,普通变量会重置。 +// 使用 sessionStorage 持久化,让缓存机制在 PJAX 切换时继续生效。 +if (typeof window.artalkInitCount === 'undefined') { + try { + var stored = sessionStorage.getItem('artalk_init_count'); + window.artalkInitCount = stored ? parseInt(stored, 10) : 0; + } catch(e) { + window.artalkInitCount = 0; + } +} +var saveInitCount = function() { + try { + sessionStorage.setItem('artalk_init_count', String(window.artalkInitCount)); + } catch(e) {} +}; + +// ── 增强评论框字段 (PJAX 适配版本) ── +// 在 Artalk 完全加载前就开始监控,确保油猴脚本能识别到字段 +window.__artalkEnhancer = window.__artalkEnhancer || { + observers: [], + doneEditors: new WeakSet(), + + enhance: function() { + var editors = document.querySelectorAll('.atk-editor'); + var self = this; + + editors.forEach(function(editor) { + if (self.doneEditors.has(editor)) return; + self.doneEditors.add(editor); + + // 昵称输入框 + var nickInput = editor.querySelector('input[name="nick"]'); + if (nickInput && !nickInput.getAttribute('data-autofill-done')) { + nickInput.setAttribute('autocomplete', 'name'); + nickInput.setAttribute('aria-label', '昵称 author nick name user'); + nickInput.classList.add('comment-author', 'user-nick', 'user-name', 'user-displayname'); + nickInput.setAttribute('data-autofill-done', '1'); + } + + // 邮箱输入框 + var emailInput = editor.querySelector('input[name="email"]'); + if (emailInput && !emailInput.getAttribute('data-autofill-done')) { + emailInput.setAttribute('autocomplete', 'email'); + emailInput.setAttribute('aria-label', '邮箱 email mail'); + emailInput.classList.add('comment-email', 'user-email', 'user-mail'); + emailInput.setAttribute('data-autofill-done', '1'); + } + + // 网址输入框 + var linkInput = editor.querySelector('input[name="link"]'); + if (linkInput && !linkInput.getAttribute('data-autofill-done')) { + linkInput.setAttribute('autocomplete', 'url'); + linkInput.setAttribute('aria-label', '网址 website url link homepage site web'); + linkInput.classList.add('comment-url', 'user-link', 'user-website', 'user-site', 'user-web'); + linkInput.setAttribute('data-autofill-done', '1'); + } + + // 内容输入框(避免被误识别为昵称) + var contentInput = editor.querySelector('textarea[name="content"]'); + if (contentInput && !contentInput.getAttribute('data-autofill-done')) { + contentInput.setAttribute('autocomplete', 'off'); + contentInput.setAttribute('aria-label', '评论内容 content comment message'); + contentInput.setAttribute('data-autofill-done', '1'); + } + }); + }, + + // 监控 DOM 变化(PJAX 切换、动态加载) + observe: function() { + var self = this; + if (typeof MutationObserver === 'undefined') return; + + // 清理旧 observer + this.observers.forEach(function(o) { o.disconnect(); }); + this.observers = []; + + var observer = new MutationObserver(function(mutations) { + for (var i = 0; i < mutations.length; i++) { + var added = mutations[i].addedNodes; + for (var j = 0; j < added.length; j++) { + var node = added[j]; + if (node.nodeType === 1) { + if (node.classList && node.classList.contains('atk-editor')) { + self.enhance(); + } + if (node.querySelectorAll) { + var nestedEditors = node.querySelectorAll('.atk-editor'); + if (nestedEditors.length > 0) { + self.enhance(); + } + } + } + } + } + }); + + observer.observe(document.body, { childList: true, subtree: true }); + this.observers.push(observer); + }, + + // 启动全局监控(在脚本加载时执行一次) + start: function() { + this.enhance(); + this.observe(); + } +}; + +// 页面加载时启动全局监控 +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', function() { + window.__artalkEnhancer.start(); + }); +} else { + window.__artalkEnhancer.start(); +} + +// 监听 PJAX 切换:立即增强(Artalk 实例被销毁后,新实例加载前的过渡期) +document.addEventListener('pjax:send', function() { + // 重置已处理记录(让新页面的评论框能重新增强) + if (window.__artalkEnhancer) { + window.__artalkEnhancer.doneEditors = new WeakSet(); + } +}); + +document.addEventListener('pjax:success', function() { + // 立即增强新页面的评论框 + if (window.__artalkEnhancer) { + window.__artalkEnhancer.enhance(); + } +}); + +document.addEventListener('pjax:complete', function() { + // 完整加载后再增强一次 + if (window.__artalkEnhancer) { + setTimeout(function() { window.__artalkEnhancer.enhance(); }, 100); + setTimeout(function() { window.__artalkEnhancer.enhance(); }, 500); + } +}); window.loadScriptOnce = window.loadScriptOnce || function(src, globalName, callback) { if (globalName && window[globalName]) { callback(); @@ -41,10 +181,12 @@ window.initArtalk = function() { // 2. PJAX: Load from localStorage if available // Initialize initialization count to track PJAX usage + // (从 sessionStorage 加载,由文件顶部的逻辑处理) if (typeof window.artalkInitCount === 'undefined') { window.artalkInitCount = 0; } window.artalkInitCount++; + saveInitCount(); // 持久化到 sessionStorage var config = Object.assign({}, window.artalkConfig); // Clone config var server = config.server.replace(/\/$/, ''); @@ -94,6 +236,81 @@ window.initArtalk = function() { artalk.setDarkMode(currentTheme === 'dark'); } + // ── 增强评论框字段属性 (兼容油猴自动填充脚本) ── + // 为 Artalk 输入框添加额外属性,确保第三方脚本(如博客网站留言评论信息自动填充) + // 能够通过 type/id/name/placeholder/class/aria-label 准确匹配 + var enhanceEditorInputs = function() { + var editor = document.querySelector('.atk-editor'); + if (!editor) return; + + // 昵称输入框 + var nickInput = editor.querySelector('input[name="nick"]'); + if (nickInput && !nickInput.getAttribute('data-autofill-done')) { + nickInput.setAttribute('autocomplete', 'name'); + nickInput.setAttribute('aria-label', '昵称 author nick name'); + nickInput.classList.add('comment-author', 'user-nick'); + nickInput.setAttribute('data-autofill-done', '1'); + } + + // 邮箱输入框 + var emailInput = editor.querySelector('input[name="email"]'); + if (emailInput && !emailInput.getAttribute('data-autofill-done')) { + emailInput.setAttribute('autocomplete', 'email'); + emailInput.setAttribute('aria-label', '邮箱 email mail'); + emailInput.classList.add('comment-email', 'user-email'); + emailInput.setAttribute('data-autofill-done', '1'); + } + + // 网址输入框 + var linkInput = editor.querySelector('input[name="link"]'); + if (linkInput && !linkInput.getAttribute('data-autofill-done')) { + linkInput.setAttribute('autocomplete', 'url'); + linkInput.setAttribute('aria-label', '网址 website url link homepage site web'); + linkInput.classList.add('comment-url', 'user-link', 'user-website'); + linkInput.setAttribute('data-autofill-done', '1'); + } + + // 内容输入框(避免被误识别为昵称) + var contentInput = editor.querySelector('textarea[name="content"]'); + if (contentInput && !contentInput.getAttribute('data-autofill-done')) { + contentInput.setAttribute('autocomplete', 'off'); + contentInput.setAttribute('aria-label', '评论内容 content comment'); + contentInput.setAttribute('data-autofill-done', '1'); + } + }; + + // 立即执行一次 + enhanceEditorInputs(); + + // 监听评论框加载完成 + artalk.on('mounted', function() { + setTimeout(enhanceEditorInputs, 100); + }); + + // 监听评论列表加载(PJAX 切换后) + artalk.on('list-loaded', function() { + setTimeout(enhanceEditorInputs, 200); + }); + + // 兜底:定时检查(防止某些情况下事件未触发) + var enhanceInterval = setInterval(function() { + enhanceEditorInputs(); + // 找到所有字段都已增强后停止 + var editor = document.querySelector('.atk-editor'); + if (editor) { + var inputs = editor.querySelectorAll('input[name="nick"], input[name="email"], input[name="link"], textarea[name="content"]'); + var allDone = true; + inputs.forEach(function(input) { + if (!input.getAttribute('data-autofill-done')) allDone = false; + }); + if (allDone && inputs.length > 0) { + clearInterval(enhanceInterval); + } + } + }, 1000); + // 30秒后停止轮询 + setTimeout(function() { clearInterval(enhanceInterval); }, 30000); + // Aggressive Config Saving Strategy var saveConf = function() { try {