WebExtension.Fragen()

  • Wie ich schon in Sörens thread [PREVIEW] Enterprise Policy Generator geschrieben habe, beschäftige ich mich gerade mit meiner allerersten Extension.
    Kurzer Umriss:
    Die Extension erstellt eine Liste der Tabs und den kürzlich geschlossenen Tabs und zwar sowohl in der Sidebar als auch als PopUp (per Button-Aufruf).
    Die erstellten Listeneinträge - also entsprechend den Tabs - können
    - per linker Maustaste angewählt,
    - per mittlerer Maustaste gelöscht,
    - und per rechten Maustaste entladen und (in der Tabs-Leiste) verborgen werden.

    Ich hänge die Extension mal gezippt an, damit man meine Problemchen nachvollziehen kann.
    (Oder mir Tipps geben kann... :P )
    [attachment=0]extension.zip[/attachment]

    Kleiner Screenshot für alle, die sich das ZIP-File nicht herunterladen oder die Extension nicht installieren möchten:
    [attachment=1]extension.PNG[/attachment]

    Soweit funktioniert das jedenfalls schon ganz gut.


    Um die Liste zu aktualisieren, benutze ich entsprechende addListener, also

    Code
    browser.tabs.onRemoved.addListener( updateList );

    und so weiter.
    Aber genau der onRemoved.addListener macht mir bissel Probleme. Und eigentlich nur der.
    Solange ich in der Liste selbst ein Tab entferne (mittlere Maustaste), ist alles schick.
    Aber sobald ich ein Tab in der Tab-Leiste selbst lösche, wird der entsprechende Eintrag nicht sofort aus der Liste entfernt.
    Erst nachdem sich die Liste durch eine andere Aktion wieder aktualisiert, ist auch der Eintrag verschwunden.
    Ich könnte mir mit einer leichten Verzögerung durch setTimeout behelfen - das funktioniert. Aber ich denke, das kann es nicht sein und irgendwo mache ich einen Fehler.
    Nur welchen? Lösungsvorschläge?


    Banal, aber nervig: Ich habe in meiner popup.js vier Constanten jeweils Elemente aus popup.html zugewiesen.

    Code
    const createTab = document.getElementById( 'create-tab' );

    Allerdings bekomme ich in der Konsole für genau diese eine Constante immer wieder diesen Fehler angezeigt:

    Zitat

    TypeError: createTab is null

    Was für mich völlig unverständlich und irritierend ist, denn das Element ist ja vorhanden und unterscheidet sich nicht von den anderen. Vor allem, weil es dann ja doch funktioniert, wie es soll. openOptions ist ebenfalls eine Constante und auch ein target eines addEventListener. Funktioniert ohne Fehleranzeige.
    Auch ein Umbenennen von createTab hat nicht geholfen. Frage: Woran könnte dies liegen?


    Ferner wird mir in der Konsole dieser Fehler vorgeworfen:

    Zitat

    Sicherheitsfehler: Inhalt auf moz-extension://74cf95bb-dfe2-4c98-b098-9d37543c7c18/popup/popup.html darf chrome://mozapps/skin/extensions/extensionGeneric-16.svg nicht laden oder verlinken.


    Direkt über meine Extension wird keine chrome-Grafik geladen. Ich könnte mir aber vorstellen, das diese Fehlermeldung mit dem Auslesen der Favicons-Adresse zu tun haben könnte.
    Irgendjemand Ideen dazu?


    Was als nächstes ansteht, sind Optionen. Fände ich nett. :)
    Eine Optionsseite habe ich auch bereits angelegt und ich kann sie auch aufrufen.
    Was mich nun interessiert: Welche Funktionen benötige ich bzw. sollte ich mir anschauen, um das zu realisieren.
    Wie werden Optionen gespeichert? Wie rufe ich diese wieder ab? Usw.
    Ich erwarte keine Komplett-Lösung, nur ein paar Anhaltspunkte, damit ich nicht völlig im Dunkel des MDN herumirre... :P

  • Die erstellten Listeneinträge - also entsprechend den Tabs - können
    - per linker Maustaste angewählt,
    - per mittlerer Maustaste gelöscht,
    - und per rechten Maustaste entladen und (in der Tabs-Leiste) verborgen werden.

    Eine alternative Bedienung wäre hilfreich - so etwas wie eine mittlere Maustaste existiert bei mir nicht. ;)

    Ein weiteres Problem, welches mir aufgefallen ist: Unter "Kürzlich geschlossene Tabs" sind erwartungsgemäß die kürzlich geschlossenen Tabs zu finden. Schließe ich aber einen Tab und drücke dann Cmd + Shift + T, um den Tab wiederherzustellen, ist die Liste unter "Kürzlich geschlossene Tabs" plötzlich komplett leer.

    Das könnte https://bugzilla.mozilla.org/show_bug.cgi?id=1396758 sein - das Event wird abgefeuert, *bevor* die Aktion passiert. Insofern schätze ich, dass der Workaround mit dem Timeout das beste ist, was du momentan machen kannst.

    Banal, aber nervig: Ich habe in meiner popup.js vier Constanten jeweils Elemente aus popup.html zugewiesen.

    Code
    const createTab = document.getElementById( 'create-tab' );

    Allerdings bekomme ich in der Konsole für genau diese eine Constante immer wieder diesen Fehler angezeigt:


    Was für mich völlig unverständlich und irritierend ist, denn das Element ist ja vorhanden und unterscheidet sich nicht von den anderen. Vor allem, weil es dann ja doch funktioniert, wie es soll. openOptions ist ebenfalls eine Constante und auch ein target eines addEventListener. Funktioniert ohne Fehleranzeige.
    Auch ein Umbenennen von createTab hat nicht geholfen. Frage: Woran könnte dies liegen?

    Wann erhältst du den Fehler? Mir ist das jetzt noch nicht aufgefallen.

    Ferner wird mir in der Konsole dieser Fehler vorgeworfen:


    Direkt über meine Extension wird keine chrome-Grafik geladen. Ich könnte mir aber vorstellen, das diese Fehlermeldung mit dem Auslesen der Favicons-Adresse zu tun haben könnte.
    Irgendjemand Ideen dazu?

    Das lässt sich einfach prüfen: Erscheint der Fehler noch, wenn du den Teil mit den Favicons weglässt? ;)

    Was als nächstes ansteht, sind Optionen. Fände ich nett. :)
    Eine Optionsseite habe ich auch bereits angelegt und ich kann sie auch aufrufen.
    Was mich nun interessiert: Welche Funktionen benötige ich bzw. sollte ich mir anschauen, um das zu realisieren.
    Wie werden Optionen gespeichert? Wie rufe ich diese wieder ab? Usw.
    Ich erwarte keine Komplett-Lösung, nur ein paar Anhaltspunkte, damit ich nicht völlig im Dunkel des MDN herumirre... :P

    Üblicherweise verwendet man die browser.storage.local-API zum Speichern und Lesen von Optionen. Hier der Code für meine Erweiterung Bookmarks Organizer:

    https://github.com/cadeyrn/bookma…core/options.js

    Hier werden im Script die Optionen genutzt:

    https://github.com/cadeyrn/bookma…nd.js#L384-L387

  • Hi EffPeh,

    auch wenn ich Dir leider nicht helfen kann... so möchte ich Dich doch voll unterstützen Deine "TabsListe" weiterzuentwickeln und asap dann auch zu veröffentlichen - nach Fehlerbereinigung!!

    Ich suche immer nach guten Tabs-WebExtensions - Deine kann echt ein Favorit von mir werden (Tab-PopUpliste sollte schließen beim Öffnen des ausgesuchten Tabs).

    Weiter so!!

    Gruß,
    Migo

  • Ich danke euch für das Feedback. :)


    Eine alternative Bedienung wäre hilfreich - so etwas wie eine mittlere Maustaste existiert bei mir nicht. ;)


    Ja, ich habe gehört, das es solche Mäuschen geben soll. :P
    Gut, dass da oben in der Leiste noch Platz für weitere Funktionen ist. ;)
    Oder vielleicht doch so ein kleines PopUp-Menü mit Funktionsicons? Hm...


    Ein weiteres Problem, welches mir aufgefallen ist: Unter "Kürzlich geschlossene Tabs" sind erwartungsgemäß die kürzlich geschlossenen Tabs zu finden. Schließe ich aber einen Tab und drücke dann Cmd + Shift + T, um den Tab wiederherzustellen, ist die Liste unter "Kürzlich geschlossene Tabs" plötzlich komplett leer.


    Kann ich hier jetzt nicht nachvollziehen, alles gut. Habe ich bisher nicht beobachtet. Aber ich sitze hier vor einem Windows.
    Ich werde es auf jeden im Auge behalten.


    Das könnte https://bugzilla.mozilla.org/show_bug.cgi?id=1396758 sein - das Event wird abgefeuert, *bevor* die Aktion passiert. Insofern schätze ich, dass der Workaround mit dem Timeout das beste ist, was du momentan machen kannst.


    Ja, das klingt genau nach dem, was mich stört.
    Okay, dann doch mit dem Workaround. In der Praxis merkt man die Verzögerung eh kaum.


    Wann erhältst du den Fehler? Mir ist das jetzt noch nicht aufgefallen.


    Direkt nach dem Laden. Es ist auch immer nur diese eine Constante. :-??


    Das lässt sich einfach prüfen: Erscheint der Fehler noch, wenn du den Teil mit den Favicons weglässt?


    Öhm, ja, hätte ich auch selbst drauf kommen können, nüch... :roll:
    Auf jeden auch ein Dankeschön für die Links. Das gibt mir wieder einiges zu denken... :P
    async? What is it goody for? I'll think about... :D


    [...]Tab-PopUpliste sollte schließen beim Öffnen des ausgesuchten Tabs)[...]


    Ja, schauen wir mal... ;)
    Ist zwar mein Erstlingswerk, aber ich denke schon, das ich es dann veröffentliche.
    Das kann aber noch bissel dauern, weil ich noch ein paar Ideen habe und auch viel ausprobiere.
    Dein Post hat mir übrigens schon geholfen, denn die Anmerkung mit dem Schliessen des PopUps ist eine weitere Frage, - die mir aber wieder entfallen war - , auf die ich noch keine Antwort habe.
    Das nervt nämlich schon ein wenig, wenn es nicht von selbst schliesst bzw. erst, wenn es den Fokus verliert.

    Windows 10 | FF 62.0 (64-Bit) / FF 61.0 (64-Bit) / FF 63.0 (64-Bit)

  • Ja, ich habe gehört, das es solche Mäuschen geben soll. :P

    Ich besitze überhaupt keine Maus. ;)

    async? What is it goody for? I'll think about... :D

    Das "async" ist die Voraussetzung dafür, dass "await" in der Methode zur Verfügung steht. Das ist der moderne Weg, asynchrones JavaScript zu schreiben. Die Art, wie man JavaScript entwickelt, hat sich in den letzten Jahren verändert. Früher war alles sehr Callback-lastig. Dann wurden Promises eingeführt und damit das sogenannte Method Chaining mit den ganzen .then() und .catch()-Blöcken. Der aktuelle Stand ist die Verwendung von async/await, was uns EcmaScript 2017 gebracht hat. Das spart einem die blöde Verschachtelung von Code.

    Mal ein gekürztes und vereinfachtes Beispiel aus dem Bookmarks Organizer. Alter Code:

    Code
    function handleResponse (response) {
      browser.bookmarks.update(response.bookmarkId, { }).then(() => {
        // irgendwelcher Code, der ausgeführt wird, wenn browser.bookmarks.update() ein Ergebnis geliefert hat
      });
    }

    Neuer Code:

    Code
    async function handleResponse (response) {
      await browser.bookmarks.update(response.bookmarkId, { });
      // irgendwelcher Code, der ausgeführt wird, wenn browser.bookmarks.update() ein Ergebnis geliefert hat
    }
  • Dankeschön für die Erklärung, Sören. :)
    Ich merke schon: ich bin so was von oldskool... :P

    Windows 10 | FF 62.0 (64-Bit) / FF 61.0 (64-Bit) / FF 63.0 (64-Bit)


  • Gibt es eigentlich ein GitHub-Repository, um sich Fortschritte am Code ansehen zu können? ;)


    Öööhm - Nö. :P
    Ich hatte da zwar mal vor vielen Jahren einen Account - ich glaube, wegen einem jQuery-Plugin, das ich gescriptet hatte - aber da kenne ich die Zugangsdaten nicht mehr. Ich kenne mich aber eh mit GitHub nicht aus.
    Ich will ja auch keine Wissenschaft aus der Sache machen. :)

    Gestern habe ich mir die async/await-Sache angeschaut. So richtig verstanden habe ich das immer noch nicht. Glaube ich. Aber ich habe mich stark an deinem Script orientiert und erfolgreich meine options.js (mit momentan nur einer Einstellung zum Testen) angelegt. :P

    Ausserdem habe ich mein popup.js nochmal komplett überarbeitet und das so angelegt wie ich es bei dir gesehen habe.
    Und ich habe chrome-Seiten beim Ermitteln der Favicons ausgeschlossen. Bisher kam diese Fehlermeldung auch nicht mehr. ;)

    Ich hänge die aktuelle Version mal an. :)

    [attachment=0]extension.zip[/attachment]

  • Testen kann ich erst zuhause.

    Gestern habe ich mir die async/await-Sache angeschaut. So richtig verstanden habe ich das immer noch nicht.

    Ist eigentlich ganz einfach, wenn man die ganze Theorie weglässt und direkt mit einem Beispiel arbeitet. ;)

    Code
    function foo() {
      method1();
      method2();
    }

    Angenommen, method1() braucht fünf Sekunden, bis sie ein Ergebnis liefert. Die Funktion method2() wird direkt nach dem Start von method()1 ausgeführt, bevor das Ergebnis von method1() da ist. Wenn method2() nun vom Ergebnis von method1() abhängt, hast du ein Problem, weil das Ergebnis noch nicht da ist.

    Nun bauen wir den Code so um:

    Code
    async function foo() {
      await method1();
      method2();
    }

    Jetzt stoppt das Script bei method1(), bis das Ergebnis da ist. Erst nach diesen fünf Sekunden, die method1() benötigt, geht es mit der Ausführung von method2() weiter. Damit ist garantiert, dass method2() mit dem Ergebnis von method1() arbeiten kann.

  • Na, dann bin ich ja doch noch lernfähig. Zumindest halbwegs. :P
    So habe ich mir gestern dann - nach der async-Lektüre bei MDN - auch die entsprechende Funktion in der option.js erklärt.
    Wobei ich da auch erst einmal kapieren musste, dass du dort für storage Defaultwerte vorgibst. Ist natürlich echt praktisch. So findet man das aber nicht in den storage-Beispielen auf MDN.
    Das ist mein grosses Problem mit MDN. Es gibt zwar Beispiele, aber die sind oft abstrakt und theoretisch. Die Beispiele funktionieren. Aber in der Praxis und in der Anwendung stellen sich dann oft Fragen, zumindest für mich als Autodidakten. Das ging mir mit async dort auch so. Zumal Promise auch Neuland für mich ist. :)

    Windows 10 | FF 62.0 (64-Bit) / FF 61.0 (64-Bit) / FF 63.0 (64-Bit)

  • Die maximale Anzahl der kürzliche geschlossenen Tabs wird von browser.sessionstore.max_tabs_undo bestimmt.
    Das lässt sich durch eine Webextension wohl nicht überschreiben?
    Lässt sich der Wert des Schalters per Script ermitteln? :)

    Windows 10 | FF 62.0 (64-Bit) / FF 61.0 (64-Bit) / FF 63.0 (64-Bit)

  • Danke Sören, das ist doch mal eine klare und sofort verständliche Antwort. :lol:
    Dann kommen wir gleich zur nächsten Frage. :P
    Ich habe da diese eher experimentelle Funktion, mit der ich alle Tabs - ausser dem aktiven und den angepinnten - verberge. Das ist aber natürlich unpraktisch, wenn man z.B. in einem Tab Medien-Inhalte (Videos, Musik, etc.) laufen hat. Jetzt habe ich mal einen Blick in die Extension Auto Tab Discard geworfen. Wenn ich es richtig verstanden habe, wird hier mit Hilfe von Javascript Injection ermittelt, ob Inhalte der beschriebenen Art existieren. Gehe ich Recht in der Annahme, dass es da keinen anderen/einfacheren Weg gibt? Wenn ja, lasse ich diese Funktion nämlich weg.

    Windows 10 | FF 62.0 (64-Bit) / FF 61.0 (64-Bit) / FF 63.0 (64-Bit)

  • So, hier noch ein Update.
    [attachment=0]extension.zip[/attachment]
    Ich habe wieder ein wenig umgebaut. Im Original-Beispiel war die Liste eigentlich eine Anreihung von Links. Jetzt ist es tatsächlich eine Liste. Die Ansicht der Tab- und Chronik-Liste wurde geteilt und die Listung wird jetzt anders sortiert. Für jeden Tab/Listeneintrag gibt es nun ein Popup mit verschiedene Funktionen bei Mouseover. Die kürzlich geschlossene Tabs kann man nun auch einzeln oder insgesamt löschen.
    Auch diesen Type-Fehler habe ich bereinigt - ich denke, es lag daran, dass in der manifest das popup.html auch unter background.scripts eingetragen war. Fragt mich nicht, wie es dahin kam, aber ich habe viel experimentiert. :P
    Soweit bin ich jedenfalls ganz zufrieden mit meiner ersten Extension.

    Jetzt würde ich in den Optionen gerne eine Farbanpassung (Hintergrund, Tab-Farbe, etc.) zulassen.
    Aber wie bekomme ich diese Werte in Form von CSS dann in meine Popup.html hinein? Ich weiss - theoretisch - wie ich das bei einem Tab machen kann, aber dazu, wie ich das Popup bzw. die Sidebar manipulieren kann, finde ich bei MDN so gar nichts... :-??