Greasemonkey: document.head es nulo cuando @run-at document-start

Creado en 15 jun. 2017  ·  9Comentarios  ·  Fuente: greasemonkey/greasemonkey

Ambiente

Clave | Valor
-- | --
Plataforma del sistema | AMD64, Windows-10-10.0.14393
navegador | Firefox Developer Edition (55.0 Beta 1, 64 bits)
Agente de usuario | Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0
Configuración de compilación | https://hg.mozilla.org/releases/mozilla-beta/rev/6872377277a618b2b9e0d2b4c2b9e51765ac199e
Mono de grasa | 3.11

Guión de usuario de prueba:

// ==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
}

Esperar resultado:

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

Resultado actual:

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

Este problema también se aplica a GM_addStyle

Comentario más útil

@the8472 Si el comportamiento del document-start actual es correcto e intencional, entonces debemos usar un observador cada vez que necesite agregar 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});
}

es necesario para cada secuencia de comandos que agregue un estilo antes document-end . Eso es aburrido.

Espero que GM_addstyle pueda hacer eso por mí, o escribir alguna advertencia útil en el wiki ("GM_addstyle no está disponible para scripts con @run-at-document-start, no lo use, encuentre una solución usted mismo ", etc.)

Todos 9 comentarios

@janekptacijarabaci Encontró una solución alternativa:

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

Parece inestable y poco confiable, pero esa es la forma más simple que puedo encontrar actualmente para hacer que las cosas funcionen.

No creo que esto sea un error. document-start sucede muy temprano. Esto permite que los scripts de usuario manipulen la página antes de que se haya ejecutado cualquier javascript de contenido.

Si desea ejecutar más tarde, simplemente use document-end o use observadores de mutación para esperar a que se inserte un elemento en particular.

@the8472
Quizás tengas razón.
Según MDN:

documento-elemento-insertado
Enviado inmediatamente después de que se haya creado el elemento raíz de un documento, pero antes de ejecutar cualquier script en él.

document-start (basado en document-element-inserted ) se activa inmediatamente después de que se crea <html></html> , en este momento, <head> es nulo.

Pero esto rompe muchas secuencias de comandos que intentan agregar estilo antes de que se represente la página (si usa GM_addstyle con document-end notará que la página parpadea) como funciona antes

No estoy seguro de que esto sea intencional

GM_addStyle es una tontería de todos modos, solo inserta una etiqueta <style> en <head> , puede hacerlo usted mismo, con un observador de mutaciones si es necesario.

Pero si esa es la preocupación real, se podría parchear para verificar la presencia de <head> use observadores si no lo es.

@the8472 Si el comportamiento del document-start actual es correcto e intencional, entonces debemos usar un observador cada vez que necesite agregar 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});
}

es necesario para cada secuencia de comandos que agregue un estilo antes document-end . Eso es aburrido.

Espero que GM_addstyle pueda hacer eso por mí, o escribir alguna advertencia útil en el wiki ("GM_addstyle no está disponible para scripts con @run-at-document-start, no lo use, encuentre una solución usted mismo ", etc.)

Sí, gm_addstyle debería arreglarse.

Pero todo lo demás que puede hacer un script también tiene que pasar por los mismos aros al inicio del documento, agregando estilos que no son especiales en ese sentido. Nada del DOM está disponible, por lo que debe esperar lo que necesite. Es decir, necesita usar observadores de todos modos si ejecuta cosas al inicio del documento.

Gracias por el informe detallado, pero esto es WAI, y la rama 3.x está ~muerta de todos modos. (Yo, por mi parte, doy la bienvenida a nuestros nuevos señores de la extensión web). Cosas como GM_addStyle se solucionarán al no existir nunca en 4.x.

Existen secuencias de comandos como https://arantius.com/misc/greasemonkey/amazon-url-cleaner.user.js que no necesitan un DOM en absoluto y deberían ejecutarse lo antes posible.

¿Fue útil esta página
0 / 5 - 0 calificaciones