Greasy Fork is available in English.
该脚本用于在ESJZone编辑器中保留文章元素的事件函数。
当前为
// ==UserScript==
// @name ESJZone编辑器中保留事件函数
// @namespace http://tampermonkey.net/
// @description 该脚本用于在ESJZone编辑器中保留文章元素的事件函数。
// @version 1.02
// @author PipeYume
// @license MIT
// @match https://www.esjzone.cc/forum/*
// @match https://www.esjzone.cc/my/post/*
// @match https://www.esjzone.one/forum/*
// @match https://www.esjzone.one/my/post/*
// @grant GM_getValue
// @grant GM_setValue
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
const LOG_LEVELS = {
DEBUG: 0,
INFO: 1,
WARN: 2,
ERROR: 3,
};
let currentLogLevel = LOG_LEVELS.INFO; // 设置当前日志等级
const logger = {
debug: (...args) => {
if (currentLogLevel <= LOG_LEVELS.DEBUG) console.debug('[DEBUG]', ...args);
},
info: (...args) => {
if (currentLogLevel <= LOG_LEVELS.INFO) console.info('[INFO]', ...args);
},
warn: (...args) => {
if (currentLogLevel <= LOG_LEVELS.WARN) console.warn('[WARN]', ...args);
},
error: (...args) => {
if (currentLogLevel <= LOG_LEVELS.ERROR) console.error('[ERROR]', ...args);
},
};
// 指定缓存的页面上限
const maxCacheSize = 5;
// 指定需要缓存的事件类型,你可以自行添加来扩充
const eventTypesToCache = ['onclick', 'onload', 'onerror'];
const cacheKey = 'esjzone_cache';
function getCache() {
return JSON.parse(GM_getValue(cacheKey, '[]'));
}
function setCache(cache) {
GM_setValue(cacheKey, JSON.stringify(cache));
}
function addToCache(id, content) {
let cache = getCache();
cache = cache.filter(item => item.id !== id); // Remove existing entry if any
cache.push({ id, content });
if (cache.length > maxCacheSize) {
cache.shift(); // Remove the oldest entry if cache size exceeds maxCacheSize
}
setCache(cache);
}
function getFromCache(id) {
const cache = getCache();
const cachedItem = cache.find(item => item.id === id);
return cachedItem ? cachedItem.content : null;
}
function extractIdFromUrl(url) {
const match = url.match(/\/forum\/(\d+\/\d+)/) || url.match(/\/my\/post\/(\d+\/\d+)/);
return match ? match[1] : null;
}
function getElementsContent(container, eventType) {
const elements = container.querySelectorAll(`[${eventType}]`);
return Array.from(elements).map(element => {
return {
path: getElementPath(element, container),
eventHandler: element.getAttribute(eventType)
};
});
}
function getElementPath(element, container) {
const path = [];
while (element !== container && element !== document.body) {
const index = Array.from(element.parentNode.children).indexOf(element);
path.unshift(index);
element = element.parentNode;
}
return path;
}
function getElementByPath(container, path) {
let element = container;
for (const index of path) {
if (element && element.children && element.children[index]) {
element = element.children[index];
} else {
return null;
}
}
return element;
}
function cacheForumContent() {
const contentDiv = document.querySelector('div.forum-content.mt-3');
if (contentDiv) {
const cachedEvents = {};
eventTypesToCache.forEach(eventType => {
// 动态获取并缓存指定事件类型的内容
cachedEvents[eventType] = getElementsContent(contentDiv, eventType);
});
logger.info("Cached Events\n", cachedEvents);
const id = extractIdFromUrl(window.location.href);
if (id) {
// 缓存所有指定的事件类型
addToCache(id, cachedEvents);
}
}
}
function loadPostContent() {
const contentDiv = document.querySelector('div.fr-element.fr-view[contenteditable="true"]');
if (contentDiv) {
const id = extractIdFromUrl(window.location.href);
if (id) {
const cachedContent = getFromCache(id);
if (cachedContent) {
eventTypesToCache.forEach(eventType => {
if (cachedContent[eventType]) {
cachedContent[eventType].forEach(item => {
const element = getElementByPath(contentDiv, item.path);
if (element) {
logger.info("Restored Element\n", element)
// 恢复指定事件类型的事件处理器
window.addEventListener("DOMContentLoaded", (win, ev)=>{
element.setAttribute(eventType, item.eventHandler);
})
}
});
}
});
}
}
}
}
if (window.location.href.includes('/forum/')) {
cacheForumContent();
} else if (window.location.href.includes('/my/post/')) {
loadPostContent();
}
})();