Придумайте рабочий план того, как выполнять пользовательские сценарии, разумеется, неизвестный до времени выполнения. Совместим со всеми тремя режимами runAt times - критически document_start
.
См. Https://github.com/arantius/greasemonkey/tree/8a255bde1aa6312715740fd0157d582a2d6cb183 для моих исследований, где подход:
tabs.executeScript()
чтобы запустить каждый пользовательский сценарий.Это «работает», за исключением того, что я еще не обнаружил ни одного события, которое работало бы для всех трех времен выполнения. Там webNavigation
onBeforeNavigate
что на самом деле слишком рано , оно (как следует из названия) срабатывает перед навигацией, когда текущий документ все еще активен. Но следующая точка - это onCommitted
, и в этот момент уже слишком поздно для запуска, встроенные скрипты уже выполнены.
Исследовать:
webRequest
вместо webNavigation
. Дает ли это нам подсказку во время начала?Re: https://bugzilla.mozilla.org/show_bug.cgi?id=1332273#c8
Я хотел бы иметь возможность хранить (в фоновом режиме) blob-объект, позже получить (только) его URL-адрес и передать этот URL-адрес (синхронно) в скрипт (-ы) содержимого, но я не знаю способа сделать что-либо из этого.
Я сам не проработал все детали, но думаю, что фоновая страница может хранить большие двоичные объекты в IndexedDB, а затем преобразовывать их в URI больших двоичных объектов через URL.createObjectURL () во время запуска и передавать их гипотетическому синхронному API конфигурации, а затем, возможно, загрузить их через
Разве IndexedDB не отключен в режиме
Я не думаю, что это влияет на фоновые скрипты?
Это возможно с помощью сценария содержимого, который запускается по адресу document_start
и выглядит примерно так: (возможно, не будет работать для уже загруженных вкладок, используйте для этого jQuery)
// execute `document_start` scripts here...
document.addEventListener("DOMContentLoaded", event => {
// execute `document_end` scripts here...
});
window.addEventListener("load", event => {
// execute `document_idle` scripts here...
});
или что-то вроде этого: (может быть больше подвержено ошибкам)
let run = [false, false, false];
document_start();
if (document.readyState === "complete") {
document_idle();
} else if (document.readyState === "interactive") {
document_end();
}
document.onreadystatechange = () => {
switch (document.readyState) {
case "loading": break;
case "interactive": document_end();
case "complete": document_idle();
}
};
function document_start() {
if (run[0]) return;
run[0] = true;
// execute `document_start` scripts here...
}
function document_end() {
if (!run[0]) document_start();
if (run[1]) return;
run[1] = true;
// execute `document_end` scripts here...
}
function document_idle() {
if (!run[1]) document_end();
if (run[2]) return;
run[2] = true;
// execute `document_idle` scripts here...
}
Другой способ - использовать три отдельных сценария содержимого, каждый из которых запускается в разное время.
Для этого manifest.json
содержит следующее: (возможно, сработает гарантированно (может быть состояние гонки))
"content_scripts": [
{
"matches": ["<all_urls>"],
"run_at": "document_start",
"js": ["document_start_handler.js"]
},
{
"matches": ["<all_urls>"],
"run_at": "document_end",
"js": ["document_end_handler.js"]
},
{
"matches": ["<all_urls>"],
"run_at": "document_idle",
"js": ["document_idle_handler.js"]
}
]
Также можно использовать jQuery, который может быть наименее подверженным ошибкам способом, но все это требует тщательного тестирования: (опять же, работает при document_start
но должен быть связан с jQuery)
function document_start() {
// execute `document_start` scripts here...
}
function document_end() {
// execute `document_end` scripts here...
}
function document_idle() {
// execute `document_idle` scripts here...
}
// Use jQuery to execute all the functions:
document_start();
// `$(document).ready(document_end)` is deprecated since 3.0
$(document_end);
// jQuery used to have a method for this: `$(window).load(document_idle)`
if (document.readyState === "complete") {
document_idle();
} else {
$(window).on("load", document_idle);
}
Как написано, это слишком широкий круг вопросов. Я разделяю это на отдельные проблемы, чтобы их было легче отслеживать: