Aus einem UC Script heraus auf das innerHTML oder auch outerHTML zugreifen

  • Firefox-Version
    Firefox 96.0
    Betriebssystem
    Windows 10

    wisst ihr, (ob) wie man aus einem UC Script heraus auf das innerHTML oder auch outerHTML zugreifen kann und das spezifisch wenn die URL geändert wird, so dass man z.B. bestimmte Teile ausblendet etc.?

    Ich würde mich über einen Tipp freuen.

    Axel

    Hallo,

    also zunächst muss ich sagen, dass ich mich noch nie mit Browser Technologien beschäftigt habe. Ich bin absoluter Anfänger und komme nur zu diesem Thema, weil ich mir einen privaten Werbeblocker für mein Zeitunglesen basteln will. Über die userContent.css konnte ich Einiges weg blocken, aber die nachgeladenen - per Zufallsgenerator erzeugten - IDs, css Klassennamen und Scripte bekommt man damit ja nicht weg. Deshalb der Versuch über uc.js.

    0.

    Ich wurde von 'Boersenfeger' darauf hingewiesen, dass die aktuelle Versíon des FF 96.0.2 ist und nicht 96.0. Ja - das stimmt natürlich. Diese Fragen beziehen sich auf die Version 96.0.2 :)

    1.

    Wisst ihr, (ob) wie man aus einem UC Script heraus auf das innerHTML oder auch outerHTML zugreifen kann/darf und das spezifisch wenn die URL geändert wird, so dass man z.B. bestimmte Teile im laufenden HTML ausblendet etc.?

    1a.

    zuerst ein Script in den inner Browser (xhtml) nachladen (vgl. unten Bild Console (0) - das meldet im Inner-Browser und Outer Browser die Version. Da wird allerdings ein Sicherheitsfehler 'moz-nullprincipal': geworfen

    function() {
      const script = document.createElement("script");
    script.src = 'https://ajax.googleapis.com/ajax/libs/jque…0/jquery.min.js';
    script.type = 'text/javascript';
    script.addEventListener('load', () => {
    console.log('(0.) jQuery: ' + jQuery.fn.jquery + ' - has been loaded successfully!');
    });
    document.head.appendChild(script);
    })();

    1b.

    dann in der Reihenfolge (1-6) console (vgl. unten Bild Console) - das klappt:

    var {classes:Cc,interfaces:Ci,utils:Cu} = Components;
    try {
    Cu.import("resource:///modules/AboutNewTab.jsm");
    Cu.import("resource:///modules/PlacesUIUtils.jsm");
    Cu.import("resource://gre/modules/Services.jsm");
      //Cu.import("chrome://browser/content/browser.js");
      var b = Services.wm.getMostRecentWindow("navigator:browser");
      var foundW = null;
      var en = Services.wm.getEnumerator("navigator:browser");
      while (en.hasMoreElements()) {
      var w = en.getNext();
    console.log('01. Enumerator: ' + w);
    }
      var newTabURL = "https:///www.google.de"; //file:///C:/inetpub/wwwroot/index.html
    AboutNewTab.newTabURL = newTabURL;
      /*tab = AboutNewTab.newTabURL;
    this._gBrowser.tabs.getCurrent((tab) => {
    const tabId = tab.id;
    this._gBrowser.tabs.create({ url : "https:///www.google.de", cookieStoreId : tab.cookieStoreId }, () => {
    this._gBrowser.tabs.remove(tabId);
    });
    });*/
    console.log("02. this._gBrowser: " + this._gBrowser);
      //browser.loadURI("https:///www.mozilla.com")
      //browser.runtime.getURL("https:///www.mozilla.com");
      this._contentWindow =

      this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindow);
    console.log("03. this._contentWindow: " + this._contentWindow);
    console.log("04. gBrowser.tabContainer: " + this._gBrowser.tabContainer);
      //console.log(gBrowser.getBrowserIndexForDocument(gBrowser.contentDocument));// !!!!! Error -> this.selectedBrowser is undefined

    in chrome://userchromejs/content/userChrome.jsm:117
    console.log("05. document.getElementById('Browser:Back'): " + document.getElementById("Browser:Back"));
      //browser.openURI("https:///www.mozilla.com");
      //window.openDialog(AppConstants.BROWSER_CHROME_URL, "_blank", "chrome,all,dialog=no", BROWSER_NEW_TAB_URL);

    //chrome://browser/content/browser.js
      //window.openDialog("resource://gre/modules/", "_blank",

    "location=1,status=1,scrollbars=1,menubar=1,top=100,left=300,width=1550,height=900"); //AppConstants.BROWSER_CHROME_URL

    = chrome://browser/content/browser.xhtml
    } catch(e){Cu.reportError(e);}
       var absatzNeu = document.createElement("p");
       var verweis = document.createElement("a");
    verweis.setAttribute("href", "http://www.trallala.de");
      var verweisText = document.createTextNode(" XXXX trallala XXX");
    verweis.appendChild(verweisText);
    absatzNeu.appendChild(verweis);
      //document.documentElement.appendChild(absatzNeu);
    document.getElementsByTagName('html:div')[10].appendChild(absatzNeu);
      //console.log('XXX' + document.documentElement.innerHTML);
    console.log('06. XXX' + document.getElementsByTagName('html:div')[10].outerHTML + 'XXX');
      //console.log('XXX' + document.documentElement instanceof HTMLHtmlElement);
      //console.log('XXX' + document.documentElement === document.querySelector('html'));

    1c.

    Noch ein Test über einen Command nach dem Laden der Seite aus dem Tab heraus, um darüber an das HTML des outerBrowser zu kommen, aber auch ohne Erfolg:

    console.log("01. gBrowser: " + gBrowser);
    console.log(gBrowser);
    console.log('02. gBrowser._isBusy: ' + gBrowser._isBusy);
    console.log('03. Services.wm: ' + Services.wm);
    console.log(Services.wm);
    //console.log('04. gBrowser.selectedTab: ' + gBrowser.tabs[0]);

    (function() {
        if (location != 'chrome://browser/content/browser.xhtml')
          return;
        let menuitem = document.createXULElement('menuitem');
    menuitem.id = 'context_closeLeftTabs';
    menuitem.setAttribute('label', 'Linke Tabs schließen');
    menuitem.setAttribute('oncommand',
          'for (let i = TabContextMenu.contextTab._tPos - 1; i >= 0; i--) \
    gBrowser.removeTab(gBrowser.tabs[i], {animate: true})');
        let tabContextMenu = document.getElementById('tabContextMenu');
        let refItem = document.getElementById('context_undoCloseTab');
    tabContextMenu.insertBefore(menuitem, refItem);
    tabContextMenu.insertBefore(document.getElementById('context_closeTabsToTheEnd'), refItem);
    tabContextMenu.insertBefore(document.getElementById('context_closeOtherTabs'), refItem);
    tabContextMenu.removeChild(document.getElementById('context_closeTabOptions'));
    })();
     
    (function() {
         if (location != 'chrome://browser/content/browser.xhtml')
           return;
         var closeAllTabsItem = document.createXULElement('menuitem');
    closeAllTabsItem.id = 'context_closeAllTabs';
    closeAllTabsItem.setAttribute('label', 'XXXXXX ---- ConsoleLog ---- XXXXXX');
    closeAllTabsItem.setAttribute('oncommand',
            "for (let tab of gBrowser.visibleTabs) console.log('04. gBrowser.tabs[0]: '); " + // warum ist hier gBrowser.tabs[0] initialisiert und sonst null oder undefined??????
            "console.log(gBrowser.tabs[0]); console.log('05. gBrowser.selectedTab.linkedBrowser.ownerDocument: ');" +
            "console.log(gBrowser.selectedTab.linkedBrowser.ownerDocument);");
        var refItem = document.getElementById('context_closeOtherTabs');
    refItem.parentNode.insertBefore(closeAllTabsItem, refItem);
    })();

    Das wird von der Konsole ausgegeben Bilder Console Bild Console zu 1b. ---- Bild Console zu 1.c

    1d.

    aber es ist dann im 'real' laufenden Outer-Browser html auch im neuen Tab (oben) nicht drin

    this._gBrowser wird gefunden. Allerdings werfen die Funktionsaufrufe leider immer einen triggeringPrincipal Fehler. Ich habe es als Parameter1 eingefügt und auch als Patameter4. Der Fehler wird in beiden Fällen geworfen. Das scheint ein wichtiges Problem zu sein, das auch in den Bug-Meldungen immer wieder auftaucht:

    this._gBrowser.loadOneTab('https:///www.google.de',{triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}), inBackground: false, forceNotRemote: true, skipAnimation: true, });

    // triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()


    2.

    Und dann natürlich wird das Script ja nur beim ersten laden des chrome objektes ausgeführt, aber danach müsste ja jeweils bei aktualisierter URL wieder eine Funktion aus dem Script ausgeführt werden?


    3.

    Bild Dom IPC - da sieht es für mich als Anfänger so aus, als wäre die Sicherheitsarchitektur der Interprozess-Kommunikation Bild Processes Threads IPC - Firefox Process Hierarchy so angelegt, dass der Inner-Browser (browser.xhtml) mit seinem Content nicht auf den Content des Outer-Browser (Web-Isolated $SITE) zugreifen darf, ausser in klar geregelten Ausnahmen wie Tabs, Bookmarks etc., aber nicht auf inner- outerHTML des Outer-Browser? Ist das richtig?


    4.

    könnt ihr mir einen Tip geben, wo es ein aktuelles gutes Buch, Tutorial oder pdf dazu gib (die alten 2006 Bücher von OReilly wurden scheinbar nie mehr aktualisiert neu aufgelegt (vermutlich wegen der völlig veränderten Browser-Nutzer Statistik)?

    Bei Stackoverflow scheint jemand mit einem injection code im Chrome Browser an den outerBrowser WebContent heran gekommen zu sein, aber der benutzt die chrome.runtime ... es scheint auch Ansätze zu geben über das wrappedJSObject zu kommunizieren ... aber ...

    ich habe keine Ahnung ... :)

    5.

    https://extensionworkshop.com/documentation/…com-extensions/ ... XUL/XPCOM extensions (innerBrowser) can still interact with web content [outerBrowser] in multiprocess Firefox ...

    Man kann so vorgehen, wie hier beschriebenLoading content_scripts ... Dabei muss im besonderen Falle von uc.js die ... let manifestData = await pkg.readString('install.rdf'); ... modifiziert werden ... weil uc.js eine XUL/XPCOM Erweiterung ist, die nicht mit einer manifest.json arbeitet sondern mit einer install.rdf (contains metadata about the extension such as its name, icons, and so on) und einer chrome.manifest (that tells Firefox where it can find the components of the extension, including XUL overlays for the extension's interface, scripts for its behavior, and files containing localized strings) .

    Das Ganze (also das Hinzufügen der Content-Scripts in diese alte RDF Methodik) ist scheinbar in RDFManifestConverter.jsm und in RDFDataSource.jsm möglich, aber das ist mir im Moment viel zu aufwendig, mich da hindurch zu wühlen, weil ich von dieser Technologie absolut keine Ahnung habe. Das ist ja extrem zeitaufwändig. Schöne Erklärungen zu der COM.IPC und Fisson JsActors sind in verschiedenen, meiner unmaßgeblichen Meinung nach, prima Blogs hier z.B. von Mozilla selbst (Frederik Braun) gegeben worden https://blog.mozilla.org/attack-and-def…ion-in-firefox/

    Für mich klappt das jetzt mit dem dynamischen Löschen der Ad-Werbung in den Zeitungen einfach über eine kleine Erweiterung. Das reicht mir so.

    Vielen Dank für ihre nette und freundliche Hilfe. Die Frage hat sich durch ihre Hilfe erledigt. Sie können die Frage löschen, wenn Sie das möchten, oder es auch so stehen lassen. Das überlasse ich selbstverständlich dem Moderator. Noch einmal vielen Dank.

    Beste Grüße

    Axel

    87 Mal editiert, zuletzt von AxBa (8. Februar 2022 um 13:40)

  • Hallo Andreas,

    ja gerne mache ich das, habe aber keine Ahnung unter welcher Rubrik und Thema? Soll ich es einfach unter userChrome.js UC machen?

    Beste Grüße

    Axel

  • mache ich das

    Ich habe das schon für dich gemacht:

    AxBa
    21. Januar 2022 um 17:48
  • habe aber keine Ahnung unter welcher Rubrik und Thema?

    Benutzerskripte gehören in das Menü Individuelle Anpassungen, denn du möchtest ja mit Hilfe eines solchen Skripts etwas deinen Wünschen anpassen. Im Zweifelsfall eröffnest du aber auf jeden Fall deinen eigenen Thread, dann können Helfer sich speziell mit deinem Problem befassen und der Themenersteller eines Threads, an den du dich dranhängst, wird nicht irritiert. Falls dein Thread im falschen Unterforum ist, ist das kein Drama, ein Moderator kann den an die richtige Stelle verschieben.

    Übersetzer für Obersorbisch und Niedersorbisch auf pontoon.mozilla.org u.a. für Firefox, Firefox für Android, Firefox für iOS, Firefox Klar/Focus für iOS und Android, Thunderbird, Pootle, Django, LibreOffice, LibreOffice Onlinehilfe, WordPress

  • Hallo,

    ich glaube, dass deine Fragen einfacher zu beantworten wären, wenn du einen konkreten Anwendungsfall nennen könntest. Mir ist noch nicht so richtig klar, was genau du eigentlich bezweckst. Daher nur ein paar sehr allgemeine Hinweise und Fragen:

    Wieso möchest du überhaupt jQuery laden? Ich sehe dafür keinen Grund. Vor allem verwendet kein des von dir gezeigten Codes jQuery. Und selbst wenn, dann ist eine Remote-Einbettung im Browser-Kontext aus Sicherheitsgründen Tabu, was vermutlich auch den von dir genannten Fehler erklärt.

    könnt ihr mir einen Tip geben, wo es ein aktuelles gutes Buch, Tutorial oder pdf dazu gib (die alten 2006 Bücher von OReilly wurden scheinbar nie mehr aktualisiert neu aufgelegt (vermutlich wegen der völlig veränderten Browser-Nutzer Statistik)?

    Zum Thema Manipulation der Firefox-Oberfläche? Ich bezweifle stark, dass ein solches Tutorial oder gar Buch in den letzten Jahren erschienen ist.

    aber der benutzt die chrome.runtime

    Das würde die Verwendung einer WebExtension-Schnittstelle nahelegen. Aber das würde bedeuten, dass es um Websites und nicht um den Browser geht. Da sind wir wieder bei dem, was ich eingangs erwähnte: Es ist leider völlig unklar, was du eigentlich erreichen möchtest.

    5.

    https://extensionworkshop.com/documentation/…com-extensions/ ... XUL/XPCOM extensions (innerBrowser) can still interact with web content [outerBrowser] in multiprocess Firefox ...

    Das ist insofern irrelevant als dass XUL/XPCOM-Erweiterungen in Firefox seit Jahren nicht mehr installiert werden können. Aber es ist ehrlich gesagt auch unnötig. Das steht unter der Überschrift "Interacting with web content". Dafür muss man überhaupt nicht mit Browser-Interna arbeiten oder eine Erweiterung schreiben. Einfach eine Erweiterung wie GreaseMonkey, TamperMonkey oder wie sie alle heißen, installieren und dann hast du alle Möglichkeiten, die JavaScript bietet, um auf das DOM einer Website zuzugreifen.

    Man kann so vorgehen, wie hier beschrieben: Loading content_scripts ... Dabei muss im besonderen Falle von uc.js die ... let manifestData = await pkg.readString('install.rdf'); ... modifiziert werden ...

    Das verstehe ich nicht. Da geht es um WebExtensions. Wieso brauchst du zwingend eine Erweiterung in einer nicht mehr unterstützten Architektur oder wieso musst du überhaupt selbst eine Erweiterung schreiben, wenn es dir nur darum geht, eine Website zu manipulieren? Dafür gibt es fertige WebExtensions.