ESJZone编辑器中保留事件函数

该脚本用于在ESJZone编辑器中保留文章元素的事件函数。

// ==UserScript==
// @name         ESJZone编辑器中保留事件函数
// @namespace    http://tampermonkey.net/
// @description  该脚本用于在ESJZone编辑器中保留文章元素的事件函数。
// @version      1.01
// @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
// ==/UserScript==

(function() {
    'use strict';
    // 指定缓存的页面上限
    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);
            });
            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) {
                                    // 恢复指定事件类型的事件处理器
                                    element.setAttribute(eventType, item.eventHandler);
                                }
                            });
                        }
                    });
                }
            }
        }
    }

    if (window.location.href.includes('/forum/')) {
        cacheForumContent();
    } else if (window.location.href.includes('/my/post/')) {
        loadPostContent();
    }
})();