Eine lange, langwierige Einführung mit einem Anspruch auf Größenwahn
Als ich entdeckte, dass wie immer etwas auf dieser Welt nicht sehr zu mir passte. Wenn ich nämlich eine lange Abfrage in eine Suchmaschine auf einem Desktop-Computer eingebe und dann zu einem Tablet wechsle, kann ich mich nicht wörtlich an den Text der Abfrage erinnern, um genau die gleichen Ergebnisse zu erzielen. Alles begann so gut. Ich sah in der Suchmaschine einen Link zur Antwort auf meine Frage und stellte fest, dass dies eine lange Lektüre verspricht. Dann schaltete ich den Computer aus und ließ mich mit dem Tablet auf das Sofa fallen, mit dem Gedanken, dass ich jetzt einfach alles wieder in die Suchmaschine tippe. Ich öffne diesen Link jetzt auf dem Tablet und lege mich ruhig in eine bequemere Position. Ich lese ihn ... Aber nicht hier war. Einige kleinere Abweichungen im Text - und mein Link befindet sich nicht mehr in der Suchmaschine. Das Abspielen des Links selbst ist ebenfalls keine Option: Es ist zu lang. Ich rätselte über die Optionen für den Abfragetext und war fast wütend darüber, das Tablet zu zerbrechen. Verdammt, ich musste aufstehen, den Computer wieder einschalten, den Browser starten und in den Verlauf eintauchen, um den genauen Text meiner Anfrage zu finden.

Erweiterung in Chrome und Firefox installiertIdee
Ich dachte, aber es wäre schön, eine solche Erweiterung für den Browser zu schreiben, mit der Sie alle geöffneten Registerkarten über den Server auf einen anderen Computer übertragen und dort weiter mit ihnen arbeiten können. Ja, einige Browser verfügen bereits über eine Cloud-Funktion. Sie müssen sich lediglich bei beiden Geräten anmelden und ... Aber das ist der Haken. Aber was ist, wenn ich Chrome auf meinem Computer und Firefox auf meinem Tablet habe? Und dann ... Loggen Sie sich einfach ein, ja. Wenn ich mich noch an mein Passwort aus dem Google-Konto erinnere. Und ich habe einfach kein Konto in Firefox. Ich weiß nicht einmal, ob es dort Konten gibt. Es gibt natürlich Cloud-Dienste von Drittanbietern, bei denen Sie sich registrieren und wahrscheinlich den gewünschten Link zu sich selbst werfen können. Es ist jedoch weiterhin erforderlich, sich dort zu registrieren und sich ein anderes Passwort zu merken ... Nein, das ist völlig unrealistisch. Am Ende können Sie sich einen Link durch die Mail werfen. All dies dauert jedoch lange und das Kopieren und Einfügen von und dann in die Adressleiste, was beispielsweise auf einem Tablet äußerst unpraktisch ist. Nein, das alles ist eine Art Unsinn ...
Als ich auf der Couch lag, wurde mir langsam klar, dass all diese Aktionen zu viel Bewegung erfordern ... Nein, Leute, das geht nicht. Und wenn ich verstehe, dass etwas auf dieser Welt nicht zu mir passt, setze ich mich hin, um Code zu schreiben und alles auf meine eigene Weise zu tun. Ich dachte, dass ich in sozialen Netzwerken sowohl auf dem Tablet als auch auf dem Desktop-Computer autorisiert war. Und das in verschiedenen Browsern, zum Beispiel auch auf demselben Computer. Im Allgemeinen war die Lösung für mich offensichtlich - den Benutzer über soziale Netzwerke zu authentifizieren.
Lyrischer Exkurs
Übrigens, wenn ich etwas Eigenes schreibe, dann mache ich es auch auf meine eigene Weise. Ich schreibe in reinem JavaScript in einem erweiterten Notizbuch, verwende kein Github, verwende keine Bibliotheken von Drittanbietern und verwende nicht einmal JQuery. Daher wird es kein Tutorial zum Schreiben einer Browsererweiterung geben. Ich werde dir das nicht beibringen. Tu nicht so wie ich. Ich warne Sie - das ist ein schlechtes Beispiel. Ich möchte auch allen potenziellen Kritikern davon erzählen und ihre Reaktion vorwegnehmen - ja, ich stimme voll und ganz Ihrer gerechten Wut zu. Ja, Sie können nicht das gesamte Skript in eine oder zwei Dateien verschieben, aber Sie müssen alles wie einen Salat in viele kleine Stücke schneiden, damit es dann 3 Stunden lang auf einem langen, intelligenten Befehl über die Befehlszeile zusammengesetzt werden kann. Ja, Sie können Javascript-Code und HTML-Code nicht in einer Datei kombinieren. Es ist besser, eine andere Abstraktionsebene zu vermasseln, die sie kombiniert. Ja, Sie können kein Tabellenlayout verwenden, aber verdammt, es ist Eisen! Und noch mehr - jetzt werden sie mich verbrennen - können Sie innerHtml nicht verwenden und eine komplexe HTML-Struktur auf einen Schlag erstellen, aber Sie müssen alle Kinder in einer Schleife anhängen und trennen und jeden Handler sorgfältig anhängen und dann löschen ... Ja, ich mache alles falsch. Sündig, ich bereue. Aber ich mache es bewusst, weil es einfacher ist. Und wer wird mir verbieten? Am Ende ist es nicht illegal, oder? Ich weiß nicht, wie man als moderner Mod programmiert, und ich möchte es nicht einmal versuchen, weil ich glaube, dass das Entwicklungsprozessdiagramm unnötig kompliziert ist. Ich bin dafür, Code mit meinen Händen zu schreiben und ihn nicht aus den Stücken eines anderen zu konstruieren, ohne eine einzige Zeile zu schreiben. Mein Code ist jedoch leichtgewichtig, muss nicht von einem speziellen Team zusammengestellt werden und funktioniert schnell. Ich schreibe Code mit F5-Technologie. In diesem Fall klicken Sie einfach auf den F5-Browser, um zu sehen, wie die aktuelle Version zu jedem Zeitpunkt des Entwicklungsprozesses funktioniert.

Ich musste die Handler jedoch immer noch in einer Schleife aufhängen, da sonst die Erweiterung den Test nicht besteht. Auch in Erweiterungen, nur für den Fall, in der HTML-Indexdatei - plötzlich - sind dynamisch verbundene Skripte verboten. Also habe ich sie über das Skript-Tag verbunden.
Tab-Speicher
Daher habe ich beschlossen, die im Browser geöffneten Registerkarten in bestimmten Listen zu speichern, die als Computer bezeichnet werden - Heimcomputer, Arbeitscomputer, Lokaler Computer. Lokal ist, wenn die Liste nicht auf dem Server, sondern in der Browser-Datenbank gespeichert ist und dementsprechend nur in dem Browser verwendet werden kann, in dem sie gespeichert ist. Dies gilt für Registerkarten, die nicht zwischen verschiedenen Computern verschoben werden müssen. Nun, der Rest der Listen kann auf allen Computern und Browsern unter den von der Erweiterung unterstützten angezeigt werden.
Für jede Registerkarte kann der Benutzer einen beliebigen Textkommentar hinterlassen. Zum Beispiel ist es für mich praktisch, mich daran zu erinnern, welche Serie ich beim Ansehen der Serie angehalten habe, und für mich selbst zu markieren, was sich auf der Seite befindet, wenn dies durch Titel und Art des Links nicht klar ist.
Gemäß der Dokumentation zum Erstellen von Erweiterungen für Chrome und Firefox sollte sich der Erweiterungscode in zwei Dateien befinden - der Hauptdatei und der Hintergrunddatei. Das Hauptskript befasst sich mit der Anzeige der Benutzeroberfläche, und das Hintergrundskript kann Browser-Registerkarten steuern und Daten mit dem Server austauschen. Das Verwalten von Registerkarten in Chrome und Firefox ist sehr ähnlich. Der Ereignishandler zum Öffnen oder Schließen von Registerkarten in Chrome sieht beispielsweise folgendermaßen aus:
chrome.tabs.onUpdated.addListener( function(tabId, changeInfo) { });
Und in Firefox so:
browser.tabs.onUpdated.addListener( function(tabId, changeInfo, tabInfo) { });
Die Funktion, mit der eine Liste aller geöffneten Registerkarten angezeigt wird, ist für beide Browser genau gleich geschrieben:
chrome.tabs.query({},function(data){ });
Ja, ja, Chrome schreibt auch Chrome in Firefox ... usw. Dies ist ein bisschen seltsam, aber die Tatsache, dass Browser ihre API standardisieren, ist sehr ermutigend.
Tatsächlich wird die gesamte Funktionalität der Erweiterung durch die Verwendung mehrerer Funktionen erreicht: Öffnen Sie das Erweiterungsfenster, indem Sie auf das entsprechende Symbol klicken, geöffnete Registerkarten lesen, die Registerkarte schließen, eine neue Registerkarte erstellen, Registerkartenereignisse abhören und Daten mit dem Erweiterungsfenster austauschen. Das ist alles. Diese Methoden sind nur im Hintergrundskript verfügbar.
Nach dem Lesen werden die im Browser geöffneten Registerkarten an meinen Server gesendet und dort in einer regulären SQL-Datenbank gespeichert. Das Serverskript ist in PHP geschrieben. Es gibt eine Benutzertabelle, in der Links zu Zeilen in einer anderen Tabelle gespeichert sind - der Datentabelle. Diese Daten sind die Adressen der Seiten, ihre Namen und Textkommentare des Benutzers, die im Format von Textzeichenfolgen in einem Textfeld mit einer Länge von etwa einem Kilobyte gespeichert sind. Die Daten werden unverschlüsselt gespeichert. Pro Megabyte können ca. 1.000 Registerkarten gespeichert werden. Pro Benutzer werden maximal 25 solcher Speicher („Computer“) bereitgestellt.
Die kostenlose Version der Erweiterung beschränkt den Benutzer jedoch auf zwei Speicher - Heimcomputer und Arbeitscomputer. Jeder von ihnen kann nicht mehr als 10 Registerkarten speichern. Ich arbeite immer noch an der kostenpflichtigen Version und den Zahlungsmethoden. Es gibt bis zu 25 „Computer“ und jeweils bis zu 1000 Registerkarten sowie eine Auswahl an Hintergrundbildern, Symbolen und Namen für jeden Computer, hierarchischen Listen und vielem mehr.
Es gibt ein anderes Repository - Lokaler Computer. Hier gibt es keine Einschränkungen, da die Registerkarten in der lokalen Browser-Datenbank auf dem Computer des Benutzers gespeichert sind. Hier können Sie so viele Registerkarten speichern, wie Sie möchten, aber nicht mehr, als die Festplatte zulässt. Da die Daten nicht im lokalen Speicher, sondern in der indizierten Datenbank gespeichert sind, gibt es dort keine Begrenzung auf 5 oder einige Megabyte. Es ist nur wichtig, dieses Repository nicht versehentlich zusammen mit dem Browserverlauf zu löschen. Ich plane auch, Registerkarten in eine Textdatei zu exportieren und zu importieren.
Um mit indexedDB zu arbeiten, habe ich eine kleine Unterbibliothek geschrieben, die nur 106 Zeilen lang ist. Im Gegensatz zur Datenbank auf dem Server müssen hier nicht alle Daten in eine Textzeichenfolge destilliert werden, sondern können sofort unverändert im assoziativen Array gespeichert werden. Das Prinzip der Speicherung dort ist folgendes: Der Schlüssel ist der Wert. Und der Wert kann ein riesiges assoziatives Array sein.
Benutzerauthentifizierung
FirefoxDie Autorisierung erfolgt, wie bereits erwähnt, über soziale Netzwerke und auf dem Server mithilfe des OAuth-Protokolls. Es wird weiterhin von Facebook und VKontakte unterstützt, aber ich plane, die Anzahl der Benutzerauthentifizierungsmethoden zu erhöhen. Das OAuth-Serverautorisierungsschema wird in der Dokumentation für beide sozialen Netzwerke ausführlich beschrieben, daher ist es nicht sinnvoll, ausführlich darauf einzugehen. Ich stelle nur fest, dass mir die Tatsache nicht gefallen hat, dass während der Autorisierung eine neue Browser-Registerkarte geöffnet wird, auch wenn der Benutzer bereits im sozialen Netzwerk angemeldet ist und bereits die Erweiterungsrechte gewährt hat. Diese Registerkarte muss vom Hintergrunderweiterungsskript erfasst und dann geschlossen werden. Im Allgemeinen sieht sie nicht ästhetisch ansprechend aus, keilt sich in die anderen Registerkarten ein und blinkt, wenn sie angezeigt und zerstört wird.
Um es zu schließen, müssen Sie für VKontakte das Vorhandensein der Adresse im Tab-Ereignishandler überprüfen:
oauth.vk.com/blank.html
Und für Facebook:
https://www.facebook.com/connect/blank.html
Und nur für den Fall:
facebook.com/connect/login_success.html
Daher habe ich zunächst eine Erweiterungsassembly an den Google Web Store gesendet, in der die Autorisierung auf dem Client mit einem vorläufigen Pull-up des entsprechenden sozialen Netzwerks für Client-Javascript-API durchgeführt wurde. Da die Erweiterung auf dem Benutzer installiert ist und ich sie auf meinem Server autorisieren muss, habe ich außerdem im Erweiterungsskript im i-frame HTML von meinem Server abgerufen, aber bereits die API für soziale Netzwerke darin abgerufen ...
Und das Datenaustauschschema mit dem Server war so. Eine Erweiterungsindexseite sendet einen Befehl (z. B. Klickinformationen) an ein Hintergrunderweiterungsskript. Hintergrundskript mit postMessage sendet Daten an i-frame html. I-Frame sendet Daten an das PHP-Skript auf dem Server. Der Server antwortet im i-Frame, der i-Frame antwortet im Hintergrundskript, das Hintergrundskript antwortet im Index, der Benutzer sieht die Antwort. Puh ... und vor allem - es hat alles funktioniert!
Im Allgemeinen hat dies nicht funktioniert. Google hat meine Erweiterung mit einer Reihe von Formulierungen versehen, unter denen es etwas Unbestimmtes gab, das besagt, dass Ihre Erweiterung nicht unseren Sicherheitsrichtlinien entspricht. Durch Korrespondenz mit dem Support konnte ich Einzelheiten erreichen. Sie mochten nämlich nicht die Tatsache, dass die Erweiterung HTML und JS von Servern von Drittanbietern abruft ... Im Allgemeinen musste ich die Client-Autorisierung erhalten und zum Server zurückkehren. Ja, das Senden einer http-Post-Anfrage von einem Hintergrunderweiterungsskript direkt an Ihren Server hat sich jedoch als zulässig erwiesen. Na ja, okay. Das ist noch besser. Es stellte sich heraus, dass es kürzer war und keine JavaScript-API aus sozialen Netzwerken abgerufen werden musste - dies ist eine zusätzliche Wartezeit für den Benutzer.
Registerkarten anzeigen
Zurück zu den Erweiterungsoptionen. Die Liste der Registerkarten selbst besteht aus einer Reihe von Zeilen, in denen zuerst das Bildfavicon, dann der Seitentitel und schließlich der Link angezeigt werden. Was nicht in die angegebene Zeilengröße auf dem Bildschirm passt, wird zugeschnitten. Die Datenbank wird jedoch vollständig gespeichert. Außerdem kann jede Linie in Form einer farbigen Kachel auf dem Bildschirm nach oben verschoben werden. Dies ist für die wichtigsten Websites, die in erster Linie vor Ihren Augen sein sollten.
Chrome-Tab-ListeDie Farben für die Kacheln werden automatisch basierend auf dem Domainnamen der Site ausgewählt. Die Funktion akzeptiert die URL. Der Domänenname ist in drei ungefähr gleiche Zeichengruppen unterteilt. Die ersten Zeichen aus jeder Gruppe werden in die Werte der Farbkomponenten konvertiert: R, G, B. Diese Konvertierung wird wie folgt durchgeführt. Die Codes dieser drei Zeichen werden auf den Bereich d1 von 0 bis 25 reduziert, indem der Rest der Division um 26 genommen wird. Sogar die Zeichen des russischen Alphabets werden auf diesen Bereich reduziert. Es spielt keine Rolle, dass der 27. Buchstabe dort der erste wird: Wir brauchen nicht, dass die Farbkomponenten aller Buchstaben des Alphabets notwendigerweise unterschiedlich sind, lassen Sie sie wiederholen. Dann werden die drei aus dem Bereich d1 (0 ... 25) erhaltenen Zahlen proportional auf den Bereich d2 (150 ... 255) reduziert. Im Allgemeinen werden diese Bereiche zu Beginn der Funktion festgelegt und können in andere geändert werden. Ich habe 150 ... 255 genommen, damit die Farbkomponenten hell sind. Wenn Sie beispielsweise 0 ... 100 einstellen, werden die Kacheln dunkel. Somit werden drei Zeichen aus dem Domainnamen in 3 Zahlen aus dem Bereich 150 ... 255 konvertiert. Und dann, wie Sie wahrscheinlich vermutet haben, werden sie als Farbkomponenten der Kacheln R, G und B interpretiert. Alles ist sehr einfach.
getSiteColor=function(url) { var d1=[0,25], d2=[150,255]; var code=0, codep=0, color=0, str='', domen='', ar=[], inc=0; ar=url.split('//'); if (ar.length>1) {str=ar[1];} else {str=ar[0];}; str=str.split('www.').join(''); domen=str.split('/')[0]; str=domen.split('.').join(''); ar=[]; inc=Math.floor(str.length/3); if (str.length % 3 >0) {inc++;}; for (var i=0; i<str.length; i+=inc) { code=str.slice(i, i+1).charCodeAt(0); codep=code % (d1[1]-d1[0]+1); color=Math.round( codep * (d2[1]-d2[0]) / (d1[1]-d1[0]) ) + d2[0]; ar.push(color); }; return {r:ar[0], g:ar[1], b:ar[2], domen:domen}; }
HTML-Dokumentstruktur
Ein HTML-Dokument besteht aus mehreren Elementen der Zeichenfläche mit absoluter Positionierung, kombiniert durch Überlagerung, und einem Div-Block, in dem die Liste angezeigt wird. An der Größe des Browserfensters hängt eine Funktion, die die Größe aller dieser Elemente ändert und sie an die neue Höhe und Breite anpasst. Es gibt auch eine Mindestgröße, die das Auftreten von Bildlaufleisten verursacht. Das Hintergrundbild wird auf der unteren Leinwand angezeigt. Ich entschied, dass für verschiedene Listen (dh Computer) unterschiedliche Hintergründe festgelegt werden sollten, um dem Benutzer die Navigation zu erleichtern. Das Hintergrundbild füllt das Fenster unter Beibehaltung seiner Proportionen und wird leicht aufgehellt, um nicht auf sich aufmerksam zu machen - darüber wird ein weißes durchscheinendes Rechteck gezeichnet. Über dem Hintergrundbereich befindet sich der Bereich des Hauptmenüs, der nur den oberen Bildschirmrand ausfüllt. Gut und noch höher liegt der div-Block, in dem die Liste der Registerkarten selbst gebildet wird. Die Navigation im Canvas-Menü erfolgt über meine Minibibliothek.

Opera und Yandex BrowserLokalisierung
Auf dem Hauptbildschirm befindet sich eine Flagge, auf die durch Klicken zwischen Russisch und Englisch umgeschaltet wird. Hier wird die Seite an dieselbe Adresse umgeleitet, jedoch mit einem Parameter in der Befehlszeile. Dieser Parameter wird gelesen, bevor alle anderen Elemente geladen werden. Und basierend auf ihrem Wert wird diese oder jene js-Datei mit russischen oder englischen Phrasen in das assoziative Array für Phrasen geladen: lng_en.js oder lng_ru.js. In der Anwendung selbst werden zum Anzeigen von Schnittstellenphrasen bereits Links zu Textzeichenfolgen aus diesem assoziativen Array verwendet. Abhängig vom Wert in der Adressleiste wird außerdem eine Datei geladen, die die Elemente der grafischen Oberfläche enthält - Schaltflächen: button_en.png oder keys_ru.png. Ich habe beschlossen, dass es besser ist, Schaltflächen direkt zusammen mit den Symbolen und Beschriftungen in jeder Sprache im Grafikeditor zu erstellen, als eine leere Schaltfläche zu erstellen und Symbole und Beschriftungen darauf zu überlagern, zumal es nicht viele davon gibt und diese gesamte Sprite-Liste nur 50 wiegt Kb Ich habe vor, weiter am Design zu arbeiten und alle Schaltflächen in ihrer Form unterschiedlich zu gestalten.

Die allgemeine Datei mit den Sprites main.png, die grafische Elemente enthält, die nicht an eine bestimmte Lokalisierung gebunden sind, wird trotzdem geladen.
Webversion
Ich dachte, es wäre schön, wenn die Links, die sorgfältig vom Heim- oder Arbeitscomputer gespeichert wurden, auf dem Weg vom Telefon aus angezeigt werden könnten. Aber nicht alle Browser für mobile Betriebssysteme unterstützen Erweiterungen. Also habe ich eine Web-Assembly erstellt. Wenn Sie die Site unter einer bestimmten Adresse besuchen, können Sie sich weiterhin über eines der sozialen Netzwerke anmelden und Ihre Registerkarten anzeigen.
Ja, es gibt keine Möglichkeit, Registerkarten zur Liste hinzuzufügen oder zu bearbeiten. Sie können jedoch zumindest Registerkarten aus der Liste öffnen und die Seiten anzeigen. Ich denke, es lohnt sich, an der mobilen Version dieser Website zu arbeiten und größere Listen mit Registerkarten darin anzuzeigen.
Webversion in IE 11Werbung
Ich habe bisher nicht wirklich daran gearbeitet, meine Expansion voranzutreiben. Er hat gerade Gruppen in sozialen Netzwerken gegründet und alle seine Freunde dort eingeladen. Ja, er hat in Yandex Direct eine Werbekampagne für 1.500 Rubel gestartet. Sie hat keine besonderen Ergebnisse geliefert, aber vielleicht habe ich die Ankündigung nicht richtig gemacht. Oder vielleicht liegt das Problem darin, dass ich einen Link zur englischen Version der Homepage der Erweiterung angegeben habe. Und vielleicht hat es sich gelohnt, einen Link nicht zur Homepage, sondern sofort zu einem der Extension Stores zu geben. Wie Sie wissen, bin ich kein Marketing-Genie. Im Allgemeinen werde ich es mit anderen Parametern erneut versuchen. Die Kampagne gab 39 Klicks. Es ist schwer zu sagen, ob ich dadurch einige neue Benutzer gewonnen habe.
Es gab eine Kuriosität mit der Version unter Firefox.
Statistiken für den 17. Oktober zeigen bis zu 227 Downloads. Ich weiß nicht, ob die Kampagne in Yandex.Direct dazu beigetragen hat oder nicht, aber aus irgendeinem Grund werden aus irgendeinem Grund wieder 1-2 Downloads pro Tag durchgeführt. Gleichzeitig gibt es für die Erweiterung von Firefox das Konzept der täglichen Benutzer:
Warum es 227 Downloads gab, aber nur 1-2 Benutzer pro Tag, ist nicht klar. Vielleicht war es eine Art Misserfolg. Im Allgemeinen verstand ich immer noch nicht, was es war und wo all diese Leute sind ...
Die Statistiken im Chrome Web Store-Erweiterungsspeicher erfreuten sich an einem ewig nicht geladenen Zeitplan - das habe ich nicht gesehen - und an 5-10 täglichen Nutzern.
Außerdem habe ich die Assembly an den Opera-Erweiterungsspeicher gesendet. Nachdem ich jedoch zwei Versionen entworfen hatte und nicht auf die Moderation einer von ihnen gewartet hatte, spuckte ich irgendwann darauf, dort neue zu verbreiten. Und warum ist dies tatsächlich erforderlich, wenn Opera Erweiterungen aus dem Chrome Store perfekt installiert?
Zusammenfassung
Ich habe drei Erweiterungs-Builds erstellt - für Chrome, Firefox und die Webversion. Tatsächlich sind alle drei Assemblys ein und dieselbe Assembly, was in der Konfiguration lediglich angibt, welche Browser-Engine derzeit verwendet wird. Die entsprechenden Funktionen zum Arbeiten mit Registerkarten werden initialisiert. Ich ändere diesen Wert, bevor ich in zip packe und das Paket an den entsprechenden Erweiterungsspeicher sende.
Die Versionen für Chrome und Firefox wurden getestet und in den jeweiligen offiziellen Erweiterungsgeschäften abgelegt. Darüber hinaus kostet die Registrierung als Erweiterungsentwickler bei Google 5 US-Dollar. Mozilla hat es kostenlos. Die Webversion der Erweiterung befindet sich auf dem Server. Die Assembly aus dem Chrome Store funktioniert in kompatiblen Browsern einwandfrei: Sie kann auch in Yandex Browser und Opera installiert werden. Ich plane, neue Versionen mit noch erweiterten Funktionen zu veröffentlichen.
Im Allgemeinen sind Browser-Erweiterungen Power. Jetzt muss ich nicht mehr von der Couch aufstehen und es besteht auch kein Grund zur Wut, um das Tablet zu zerbrechen. Das ist volles Zen. Gut zu allen.