Пользовательский скрипт Tampermonkey предотвращает загрузку страниц

В настоящее время я делаю пользовательский скрипт для интерпретации языка программирования APL в окне чата Stackexchange. Это код, который я придумал:

// ==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/[email protected]/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.info(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.info(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, и она импортируется из инструкции @require с использованием интерпретатора ngn javascript APL. После подтверждения ngn могу сказать, что никакие глобалы не мешают.

Он отлично работает в Firefox (Greasemonkey), но в Chrome Tampermonkey любая chat.stackexchange.com страница, которую я посещаю, никогда не перестает загружаться. Он застревает в этом месте:

Пользовательский скрипт Tampermonkey предотвращает загрузку страниц

И это ошибки консоли:

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, но я не уверен, что именно вызывает эту проблему. Это может быть что-то еще.

Каково правильное решение этой проблемы?

Я не могу воспроизвести проблему. Пробовали ли вы запускать скрипт позже, когда чат полностью загрузится. Например, window.setTimeout для всего скрипта, чтобы подождать несколько секунд перед выполнением.

cuzi 29.12.2020 21:12

@cuzi конечно, попробую.

Razetime 30.12.2020 02:47

@cuzi, похоже, та же проблема с 10-секундным тайм-аутом. Я также пробовал очищать куки и кеш.

Razetime 30.12.2020 03:06

@cuzi хорошо, кажется, это работает, когда я встраиваю минимизированный js вместо того, чтобы требовать его.

Razetime 30.12.2020 03:22
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
4
1 103
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Проблема здесь была решена путем перемещения скрипта @require внутрь слушателя DOMContentLoaded, как в этой ссылке .

Я думаю, что основная проблема заключалась в том, что интерпретатор вызывал конфликты, поскольку он загружался до загрузки страницы. Я был бы признателен, если бы кто-нибудь нашел способ заставить это работать с @require в нем.

Цитата

Вы устанавливаете @ run-at document-start в своем пользовательском скрипте, это заставляет скрипт запускаться до загрузки страницы, если вы удалите его, скрипт внедряется после запуска DOMContentLoaded. Если это не поможет, вы можете попробовать использовать исходный код из gitlab @require gitlab.com/n9n/apl/-/raw/master/apl.js вам нужно будет изменить вызов apl на result = apl .fmt(apl(elem.innerText)).toString()

cuzi 31.12.2020 21:08

@cuzi Это работает отлично. Не стесняйтесь добавлять ответ, чтобы я мог присудить награду.

Razetime 01.01.2021 10:35
Ответ принят как подходящий

Вы устанавливаете @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/[email protected]/lib/apl.js ) имеет некоторые вспомогательные функции сценария кофе, включенные в верхнюю часть файла. , в частности, есть некоторые объявленные методы Array.prototype.*, которые также будут доступны на странице. Это может сломать страницу, см. этот вопрос для получения дополнительной информации: Почему расширение нативных объектов является плохой практикой?

Другие вопросы по теме