Tampermonkey 用户脚本阻止页面加载

Tampermonkey userscript prevents pages from loading

我目前正在制作一个用户脚本来解释 Stackexchange 聊天中的 APL 编程语言 window。这是我想出的代码:

// ==UserScript==
// @name     APL chat
// @version  2
// @grant    GM_xmlhttpRequest
// @grant    GM_listValues
// @match    https://chat.stackexchange.com/*
// @run-at   document-start
// @require  https://cdn.jsdelivr.net/npm/apl@0.1.15/lib/apl.min.js
// ==/UserScript==

// thanks to @cvzi for making it work correctly!

var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

var observer = new MutationObserver(function(mutations, observer) {
    // fired when a mutation occurs
    console.log(mutations, observer);
    let codes = document.getElementsByTagName("code");
        for (let elem of codes) {
            if(elem.innerText && !('interpreted' in elem.dataset) && elem.innerText[0] == '⋄') {
                elem.dataset.interpreted = true;  // see https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes#JavaScript_access
                let result = ''
                let color = 'red'
                // Catch apl error and show it in orange color
                try {
                    result = apl(elem.innerText).toString()
                } catch(e) {
                    result = e.toString()
                    color = 'orange'
                }
                let tmp = document.createElement("div");
                tmp.innerHTML = "<pre style=\"color:"+color+"\">"+result.replace("\n","<br>")+"</pre>";
                let parent = elem.parentElement;
                parent.appendChild(tmp.firstChild);
                //console.log(result);
            }
        }
});

window.addEventListener('DOMContentLoaded', (event) => {
    alert = function() {}; // Prevents ⎕← and ⍞← from trggering alerts
    window.alert = function(){};
      observer.observe(document, {
      subtree: true,
    ChildList:true,
      attributes: true
    });

});

当一个代码块被写入正文并包含 个字符时,它应该被执行并以红色显示在代码下方。

apl() 函数采用单个字符串,并以 APL 语言解释,并使用 ngn's javascript APL interpreter@require 语句导入。经过ngn的确认,我可以说它不干扰任何全局变量。

它在 firefox(Greasemonkey) 上完美运行,但在 Chrome 的 Tampermonkey 上,我访问的任何 chat.stackexchange.com 页面都不会停止加载。此时卡住了:

这些是控制台错误:

Uncaught TypeError: o.substr is not a function
    at HTMLLIElement.<anonymous> (master-chat-with-millinery.js?v=93a5b9100f35:1)
    at Function.each (jquery.min.js:2)
    at n.fn.init.each (jquery.min.js:2)
    at o (master-chat-with-millinery.js?v=93a5b9100f35:1)
    at Sidebar (master-chat-with-millinery.js?v=93a5b9100f35:1)
    at Vt (master-chat-with-millinery.js?v=93a5b9100f35:3)
    at StartChat (master-chat-with-millinery.js?v=93a5b9100f35:3)
    at HTMLDocument.<anonymous> (the-nineteenth-byte:182)
    at i (jquery.min.js:2)
    at Object.fireWith [as resolveWith] (jquery.min.js:2)
master-chat-with-millinery.js?v=93a5b9100f35:7 Uncaught TypeError: Cannot read property 'resolve' of undefined
    at Object.<anonymous> (master-chat-with-millinery.js?v=93a5b9100f35:7)
    at i (jquery.min.js:2)
    at Object.fireWith [as resolveWith] (jquery.min.js:2)
    at y (jquery.min.js:4)
    at XMLHttpRequest.c (jquery.min.js:4)
DevTools failed to load SourceMap: Could not load content for chrome-extension://dhdgffkkebhmkfjojejmpbldmpobfkfo/sm/66503b0e4799e2375dd4e11269326fc0fcb9a65474ff19f45c7f956fd381cea8.map: HTTP error: status code 404, net::ERR_UNKNOWN_URL_SCHEME

我怀疑 MutationObserver@grant,但我不确定究竟是什么导致了这个问题。也可能是别的东西。

这个问题的正确解决方法是什么?

这里的问题已通过在 DOMContentLoaded 侦听器中移动 @require 脚本得到解决,就像 link.

我认为主要问题是解释器导致了冲突,因为它在页面加载之前就已经加载了。不过,如果有人能找到一种方法使它与 @require 一起工作,我将不胜感激。

Citation

您在您的用户脚本中设置了 @run-at document-start,这使得脚本在页面加载之前 运行,如果您删除它,脚本将在 DOMContentLoaded 被触发后注入。

如果这没有帮助,您可以尝试使用来自 gitlab 的原始来源 @require https://gitlab.com/n9n/apl/-/raw/master/apl.js 您需要将 apl 调用更改为 result = apl.fmt(apl(elem.innerText)).toString()

我假设发生冲突是因为 apl 库 (https://cdn.jsdelivr.net/npm/apl@0.1.15/lib/apl.js) has some coffee script helper functions included at the top of the file, notably there are some Array.prototype.* methods declared which will also be available in the page. These could break the page, see this question for more information: Why is extending native objects a bad practice?