Greasemonkey: WebExt: выполнять сценарии при всех трех запусках

Созданный на 27 февр. 2017  ·  6Комментарии  ·  Источник: greasemonkey/greasemonkey

Придумайте рабочий план того, как выполнять пользовательские сценарии, разумеется, неизвестный до времени выполнения. Совместим со всеми тремя режимами runAt times - критически document_start .

См. Https://github.com/arantius/greasemonkey/tree/8a255bde1aa6312715740fd0157d582a2d6cb183 для моих исследований, где подход:

  • Используйте один фоновый сценарий. (У него будет доступ к хранилищу / любым API, где хранятся скрипты, поэтому он может знать содержимое скриптов для выполнения.)
  • Наблюдайте что-нибудь ( что? ), Чтобы вызвать ...
  • .. вызовите tabs.executeScript() чтобы запустить каждый пользовательский сценарий.

Это «работает», за исключением того, что я еще не обнаружил ни одного события, которое работало бы для всех трех времен выполнения. Там webNavigation onBeforeNavigate что на самом деле слишком рано , оно (как следует из названия) срабатывает перед навигацией, когда текущий документ все еще активен. Но следующая точка - это onCommitted , и в этот момент уже слишком поздно для запуска, встроенные скрипты уже выполнены.

Все 6 Комментарий

Исследовать:

  • Обратите внимание на webRequest вместо webNavigation . Дает ли это нам подсказку во время начала?
  • Вставьте один сценарий содержимого webext в document_start для каждой страницы. Он должен каким-то образом знать, какие сценарии выполнять синхронно. (Потому что все, что асинхронно, подтолкнет нас к истечению времени начала.)

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);
}

Как написано, это слишком широкий круг вопросов. Я разделяю это на отдельные проблемы, чтобы их было легче отслеживать:

2525, №2526

Была ли эта страница полезной?
0 / 5 - 0 рейтинги