Greasemonkey: Suporte ao tempo de execução do script de início de documento

Criado em 25 jul. 2017  ·  17Comentários  ·  Fonte: greasemonkey/greasemonkey

Apoie document-start por @run-at .

Veja #2483 para mais detalhes. Isso pode ser "impossível".

Todos 17 comentários

Você pode usar a propriedade run_at da chave de manifesto content_scripts .

Eu compartilhei a pena sobre o Chrome com você 4 anos atrás. Agora novamente para o Firefox. 😭

Gostaria de reformular minha sugestão em https://bugs.chromium.org/p/chromium/issues/detail?id=257956

tabs.insertCSS/executeScript deve inserir CSS/JS até que o URL da guia seja definido como não vazio (não nulo, não indefinido, não string vazia "") e seja cancelado se a guia for removida/alterada

As APIs WebExtension devem ser aprimoradas.

@iology por que você rejeitou minha sugestão? É perfeitamente válido. Além disso, pode-se usar o script de conteúdo para inserir tags de script no documento que contém os scripts do usuário.

O seguinte deve explicar como fazer isso usando meu método: (deve funcionar de forma confiável)

/**
 * <strong i="8">@typedef</strong> UserScript
 * <strong i="9">@property</strong> {Object} header The parsed header of a script
 * <strong i="10">@property</strong> {String} script The raw script data
 * <strong i="11">@property</strong> {String} type The script media type (in case a script is WebAssembly
 *                         or something other than JavaScript)
 */

/** The load state of this script. Used by the `matches()` function */
const READY_STATE = document.readyState;

(async () => {
    (await (browser.storage.local.get({scripts: []}) // Excuse this horrible code style
        .then(ret => ret.scripts)))                  // of combining `await` and `.then()`
        .forEach(/* <strong i="12">@param</strong> {UserScript} script */ script => {
            if (matches(script.header)) {
                let scriptTag = document.createElement("script");
                scriptTag.setAttribute("type", script.type)
                scriptTag.textContent = script.script;
                document.appendChild(scriptTag);
            }
        });
})();

/**
 * Checks if this script matches this page and @run-at property.
 * 
 * <strong i="13">@param</strong> {Object} scriptHeader The parsed header of a script
 * <strong i="14">@return</strong> {boolean} `true` if this page matches, `false` otherwise
 */
function matches(scriptHeader) {
    // Uses window.location and READY_STATE.
    // TODO: Implement
}

@ExE-Boss No momento em que você recuperar os scripts do armazenamento de extensão, parte da página já estará carregada.

Estou ciente disso, mas realmente não vejo outra maneira de fazer isso devido ao fato de que as WebExtensions são inerentemente assíncronas.

@ExE-Boss, há um bugzilla, https://bugzilla.mozilla.org/show_bug.cgi?id=1332273 , que parece estar progredindo bem e deve ajudar a resolver o problema @document-start. Se vai pousar para FF57, não tenho certeza.

Estou ciente disso, mas realmente não vejo outra maneira de fazer isso devido ao fato de que as WebExtensions são inerentemente assíncronas.

@ExE-Boss Esse é literalmente o problema que estamos tentando resolver.

Estou tentando resolvê-lo também, mas minha solução realmente só funciona bem o suficiente para #2525, porque nesse ponto a página inteira foi totalmente carregada.

O Violentmonkey também tem esse problema, não tenho certeza do que a magia negra Tampermonkey usa, mas é capaz de injetar script de forma confiável no document-start real.

Tampermonkey 2.9 e anterior era GPL-3.0 e publicado no GitHub . Eu tentei investigar isso, e a princípio pensei que estava usando sync XHR , mas depois de analisar um pouco, não tenho ideia de como ele consegue isso, mas faz isso de alguma forma porque o suporte para isso foi adicionado na versão 2.6 .2767 .

Veja aqui por que o Tampermonekey foi de código fechado:

Não estou interessado em piratear coisas, não será muito difícil reverter a lógica do Tampermonkey, mas não é legal fazer isso.

@Sxderp Isso é apenas para o Firefox 57, esse bug ainda pode ser resolvido em 58+.

Para sua informação, Tampermonkey também não é confiável no início do documento. Existe uma opção de injeção "instantânea" (que é extremamente hacky) que acelera as coisas, mas em páginas simples como xkcd.com, ainda recebo um flash antes que meu CSS (que é sempre injetado no início do documento) seja carregado. Eu também ocasionalmente recebo um flash em outros sites.

Reverter o código do Tampermonkey não é uma maneira de descobrir isso. Além disso, bem, os métodos reais que eles usam podem ser encontrados em seus fóruns, sugeridos por outros usuários. Copiar um método não é copiar-vio, apenas copiar o próprio código.

Mas sabemos que é uma solução imperfeita e queremos uma perfeita.

Se um método for encontrado para fazer isso funcionar, poderia haver uma maneira de um script ler pelo menos um subconjunto de suas opções de configuração de forma síncrona? Como exemplo do tipo de problemas que isso resolveria, consulte https://github.com/ccd0/4chan-x/issues/1627. Aqui eu preciso desabilitar algum código na página, mas também quero ter uma opção para não desabilitar o código. E muitos usuários limpam localStorage no final de cada sessão do navegador.

Se um método for encontrado para fazer isso funcionar, poderia haver uma maneira de um script ler pelo menos um subconjunto de suas opções de configuração de forma síncrona?

Não em curto prazo. Não há como se comunicar com o armazenamento (get|set)Value de maneira síncrona. Talvez algum tipo de injeção por parte do GM em que variáveis ​​com valores de configuração são injetadas no escopo global do script. Isso é o melhor que consigo pensar, e isso não é muito legal.

Talvez algum tipo de injeção por parte do GM em que variáveis ​​com valores de configuração são injetadas no escopo global do script. Isso é o melhor que consigo pensar, e isso não é muito legal.

Presumivelmente, seria parte do objeto GM . Algo como GM.initValues.yourVariable .

Esta página foi útil?
0 / 5 - 0 avaliações