Greasemonkey: document.head ist null, wenn @run-at document-start

Erstellt am 15. Juni 2017  ·  9Kommentare  ·  Quelle: greasemonkey/greasemonkey

Umfeld

Schlüssel | Wert
-- | --
Systemplattform | AMD64, Windows-10-10.0.14393
Browser | Firefox Developer Edition (55.0 Beta 1, 64-Bit)
Benutzeragent | Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0
Build-Konfiguration | https://hg.mozilla.org/releases/mozilla-beta/rev/6872377277a618b2b9e0d2b4c2b9e51765ac199e
Grease-Affe | 3.11

Benutzerskript testen:

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

Ergebnis erwarten:

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

Tatsächliche Ergebnis:

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

Dieses Problem gilt auch für GM_addStyle

Hilfreichster Kommentar

@the8472 Wenn das Verhalten des aktuellen document-start korrekt und absichtlich ist, müssen wir jedes Mal einen Beobachter verwenden, wenn Sie Stil hinzufügen müssen
Etwas wie

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

wird für jedes Skript benötigt, das einen Stil vor document-end hinzufügt. Das ist langweilig.

Ich hoffe, GM_addstyle könnte das für mich tun oder eine nützliche Warnung ins Wiki schreiben ("GM_addstyle ist für Skripte mit @run-at document-start nicht verfügbar, verwenden Sie es nicht, finden Sie selbst eine Lösung ", etc)

Alle 9 Kommentare

@janekptacijarabaci Habe eine Problemumgehung gefunden:

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

Es sieht instabil und unzuverlässig aus, aber das ist der einfachste Weg, den ich derzeit finden kann, um die Dinge zum Laufen zu bringen.

Ich glaube nicht, dass das ein Bug ist. document-start passiert sehr früh. Dadurch können Benutzerskripte die Seite manipulieren, bevor irgendein Inhalts-Javascript ausgeführt wurde.

Wenn Sie später ausführen möchten, verwenden Sie einfach document-end oder verwenden Sie Mutationsbeobachter, um auf das Einfügen eines bestimmten Elements zu warten.

@the8472
Vielleicht hast du Recht.
Laut MDN:

Dokumentelement eingefügt
Wird sofort gesendet, nachdem das Stammelement eines Dokuments erstellt wurde, aber bevor ein Skript darauf ausgeführt wird.

document-start (basierend auf document-element-inserted ) wird unmittelbar nach der <html></html> ausgelöst, zu diesem Zeitpunkt ist <head> null.

Aber das bricht viele Skripte, die versuchen, Stil hinzuzufügen, bevor die Seite gerendert wird (wenn Sie GM_addstyle mit document-end verwenden, werden Sie bemerken, dass die Seite blinkt), wie es vorher funktioniert hat

Ich bin mir nicht sicher, ob dies beabsichtigt ist

GM_addStyle ist sowieso albern, es fügt einfach ein <style> -Tag in <head> ein, das können Sie selbst tun, notfalls mit einem Mutationsbeobachter.

Aber wenn dies das eigentliche Problem ist, könnte es gepatcht werden, um das Vorhandensein von <head> Use Observern zu überprüfen, wenn dies nicht der Fall ist.

@the8472 Wenn das Verhalten des aktuellen document-start korrekt und absichtlich ist, müssen wir jedes Mal einen Beobachter verwenden, wenn Sie Stil hinzufügen müssen
Etwas wie

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

wird für jedes Skript benötigt, das einen Stil vor document-end hinzufügt. Das ist langweilig.

Ich hoffe, GM_addstyle könnte das für mich tun oder eine nützliche Warnung ins Wiki schreiben ("GM_addstyle ist für Skripte mit @run-at document-start nicht verfügbar, verwenden Sie es nicht, finden Sie selbst eine Lösung ", etc)

Ja, gm_addstyle sollte behoben werden.

Aber auch alles andere, was ein Skript tun könnte, muss beim Dokumentstart durch die gleichen Hürden springen und in dieser Hinsicht nicht besondere Stile hinzufügen. Nichts vom DOM ist verfügbar, also müssen Sie auf alles warten, was Sie brauchen. Das heißt, Sie müssen sowieso Beobachter verwenden, wenn Sie Dinge beim Dokumentstart ausführen.

Danke für den ausführlichen Bericht, aber das ist WAI, und der 3.x-Zweig ist sowieso tot. (Ich für meinen Teil begrüße unsere neuen Web-Extension-Overlords.) Dinge wie GM_addStyle werden behoben, indem sie in 4.x nie existieren.

Es gibt Skripte wie https://arantius.com/misc/greasemonkey/amazon-url-cleaner.user.js , die überhaupt kein DOM benötigen und so schnell wie möglich ausgeführt werden sollten.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen