Elabore um plano de trabalho sobre como executar scripts de usuário, obviamente não conhecido até o tempo de execução. Compatível com todos os três tempos de execução - criticamente document_start
.
Veja https://github.com/arantius/greasemonkey/tree/8a255bde1aa6312715740fd0157d582a2d6cb183 para minha pesquisa até agora, onde a abordagem é:
tabs.executeScript()
para disparar cada script de usuário.Isso "funciona", exceto por nenhum evento que ainda encontrei para observar que funcione para todos os três tempos de execução. Há webNavigation
's onBeforeNavigate
que na verdade é muito cedo , ele (como o nome indica) dispara antes da navegação, quando o documento atual ainda está ativo. Mas o próximo ponto é onCommitted
, e nesse ponto é tarde demais para iniciar, os scripts embutidos já foram executados.
Pesquisar:
webRequest
vez de webNavigation
. Isso nos dá um controle sobre o tempo de início?Re: https://bugzilla.mozilla.org/show_bug.cgi?id=1332273#c8
Gostaria de poder armazenar (em segundo plano) um blob, depois obter (apenas) sua URL e passar essa URL (de forma síncrona) para o (s) script (s) de conteúdo, mas não conheço nenhuma maneira de fazer qualquer uma dessas coisas.
Não resolvi todos os detalhes sozinho, mas acho que a página de plano de fundo poderia armazenar blobs em IndexedDB, convertê-los em URIs de blob via URL.createObjectURL () no momento da inicialização e passá-los para a API de configuração síncrona hipotética e então talvez carregue-os via
O IndexedDB não está desabilitado no modo de
Não acho que isso afete o (s) script (s) de fundo?
Isso é possível usando um script de conteúdo que é executado em document_start
e se parece com isto: (possivelmente não funcionará para guias já carregadas, use jQuery para isso)
// execute `document_start` scripts here...
document.addEventListener("DOMContentLoaded", event => {
// execute `document_end` scripts here...
});
window.addEventListener("load", event => {
// execute `document_idle` scripts here...
});
ou algo assim: (pode ser mais sujeito a erros)
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...
}
Outra maneira é usar três scripts de conteúdo separados, onde cada um deles é executado em um momento diferente.
Para isso, o manifest.json
contém o seguinte: (provavelmente funcionará provavelmente (pode haver uma condição de corrida))
"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"]
}
]
Também é possível usar jQuery, que pode ser a maneira menos propensa a erros, mas tudo isso precisa de testes extensivos: (novamente, é executado em document_start
mas precisa ser empacotado com 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);
}
Conforme está escrito, este problema é muito amplo. Estou dividindo isso em problemas separados para serem rastreados com mais facilidade: