Greasemonkey: document.head é nulo quando @run-at document-start

Criado em 15 jun. 2017  ·  9Comentários  ·  Fonte: greasemonkey/greasemonkey

Ambiente

Chave | Valor
-- | --
Plataforma do Sistema | AMD64, Windows-10-10.0.14393
Navegador | Firefox Developer Edition (55.0 Beta 1, 64 bits)
Agente do usuário | Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0
Configuração de compilação | https://hg.mozilla.org/releases/mozilla-beta/rev/6872377277a618b2b9e0d2b4c2b9e51765ac199e
Macaco de graxa | 3.11

Teste o script do usuário:

// ==UserScript==
// <strong i="15">@name</strong>        HeadTest
// <strong i="16">@namespace</strong>   HeadTest
// <strong i="17">@include</strong>     *
// @run-at      document-start
// <strong i="18">@version</strong>     1
// <strong i="19">@grant</strong>       none
// ==/UserScript==
AddGlobalStyle('body{background-color:red;}');

function AddGlobalStyle(css) {
    var head, style;
    head = document.getElementsByTagName("head")[0];
    console.log("[Test]: Head: %o", head); //DEBUG
    console.log("[Test]: document.head: %o", document.head); //DEBUG
}

Resultado esperado:

[Test]: Head:  <head> 
[Test]: document.head:  <head>

Resultado atual:

[Test]: Head:  undefined
[Test]: document.head:  null

Este problema também se aplica a GM_addStyle

Comentários muito úteis

@the8472 Se o comportamento do document-start atual estiver correto e intencionalmente, precisamos usar um observador toda vez que você precisar adicionar estilo
Algo como

function addGlobalStyle(css){
  let headHunter = new MutationObserver(
    records => {
    ; check mutation records
    ; is added node's tag name 'head'?
    ; create a style node then throw it in
    ; then disconnect us
   }
  );
  headhunter.observer(document, {childlist : true});
}

é necessário para cada script que adiciona um estilo antes document-end . Isto é chato.

Espero que GM_addstyle possa fazer isso por mim, ou escrever algum aviso útil no wiki ("GM_addstyle não está disponível para scripts com @run-at document-start, não o use, encontre uma solução você mesmo ", etc.)

Todos 9 comentários

@janekptacijarabaci Encontrou uma solução alternativa:

setTimeout(()=>{
    AddGlobalStyle('body{background-color:red;}');
});

Parece instável e não confiável, mas essa é a maneira mais simples que posso encontrar atualmente para fazer as coisas funcionarem.

Não acho que isso seja um bug. document-start acontece muito cedo. Isso permite que os scripts de usuário manipulem a página antes que qualquer javascript de conteúdo seja executado.

Se você quiser executar mais tarde, use document-end ou use observadores de mutação para esperar que um determinado elemento seja inserido.

@the8472
Talvez você esteja certo.
De acordo com o MDN:

elemento-documento-inserido
Enviado imediatamente após a criação do elemento raiz de um documento, mas antes de executar qualquer script nele.

document-start (baseado em document-element-inserted ) é disparado imediatamente após <html></html> ser criado, neste momento, <head> é nulo.

Mas isso quebra muitos scripts que tentam adicionar estilo antes da página ser renderizada (se você usar GM_addstyle com document-end você notará que a página está piscando) como funciona antes

Não tenho certeza se isso é intencional

GM_addStyle é bobo de qualquer maneira, ele apenas insere uma tag <style> em <head> , você pode fazer isso sozinho, com um observador de mutação, se necessário.

Mas se essa é a preocupação real, ela pode ser corrigida para verificar a presença de observadores de uso <head> , se não for.

@the8472 Se o comportamento do document-start atual estiver correto e intencionalmente, precisamos usar um observador toda vez que você precisar adicionar estilo
Algo como

function addGlobalStyle(css){
  let headHunter = new MutationObserver(
    records => {
    ; check mutation records
    ; is added node's tag name 'head'?
    ; create a style node then throw it in
    ; then disconnect us
   }
  );
  headhunter.observer(document, {childlist : true});
}

é necessário para cada script que adiciona um estilo antes document-end . Isto é chato.

Espero que GM_addstyle possa fazer isso por mim, ou escrever algum aviso útil no wiki ("GM_addstyle não está disponível para scripts com @run-at document-start, não o use, encontre uma solução você mesmo ", etc.)

Sim, gm_addstyle deve ser corrigido.

Mas tudo o mais que um script pode fazer também precisa passar pelos mesmos obstáculos no início do documento, adicionando estilos não especiais a esse respeito. Nada do DOM está disponível, então você tem que esperar o que precisar. Ou seja, você precisa usar observadores de qualquer maneira se executar as coisas no início do documento.

Obrigado pelo relatório detalhado, mas este é o WAI, e o branch 3.x está morto de qualquer maneira. (Eu, por exemplo, dou as boas-vindas aos nossos novos senhores da extensão da web.) Coisas como GM_addStyle serão corrigidas por nunca existirem no 4.x.

Existem scripts como https://arantius.com/misc/greasemonkey/amazon-url-cleaner.user.js que não precisam de um DOM e devem ser executados o mais rápido possível.

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