Chrome Extensions sind relativ leicht zu erstellen. Sie bieten uns die Möglichkeit, selbst erstellten JavaScript Code in eine Seite zu injezieren. So lassen sich beispielsweise Adblocker, TwitterClients oder auch dynamische Dictionaries realisieren. Besitzt man bereits JS und HTML/CSS Kenntnisse, bedarf es nicht einmal Einarbeitung in eine neue Sprache, was sehr elegant von Google gelöst wurde.
Wie man Chrome Extensions entwickelt wird hier sehr detailliert eklärt.
Jedoch stolperte ich bei der Entwicklung einer Extension im Bereich Content-Scripts im Abschnitt Execution environment über folgendes:
"Content scripts execute in a special environment called an isolated world. They have access to the DOM of the page they are injected into, but not to any JavaScript variables or functions created by the page. It looks to each content script as if there is no other JavaScript executing on the page it is running on. The same is true in reverse: JavaScript running on the page cannot call any functions or access any variables defined by content scripts."
Nun möchte ich aber mittels eines Content-Scripts, Methoden bzw. Events aufrufen, die schon auf der Seite vorhanden ist. Oder anders ausgedrückt: stellt eine Webpage, einen Code in einem script - Tag zur Verfügung, sollte dieser ebenfalls mit meinem injezierten Code aufrufbar sein.
Realisierung
Da es möglich ist, die Webpage mit dem content-script kommunizieren zu lassen, wie im Abschnitt Communication with the embedding page beschrieben ist, können wir diesen Weg verwenden, um Methodennamen bzw. Methodenobjekte zu übergeben.
z.B:
contentscript.js
Hier muss in irgendeinem Listener bzw. an irgendeiner Stelle im Code, die window.postMessage() - Methode stehen, die ein method Objekt mit dem Namen der auf zu rufenden Funktion ( bereitgestellt von der Webpage ), übergibt. Die Gegenstelle ( Webpage ) wartet mittels window.addEventListener("message",...) auf das Methodenobjekt.
webpage.html - z.B im HeaderTag
Natürlich ist es nicht elegant eine switch case Abfrage zu starten, dieser Weg ist aber anschaulicher, ersetzen könnte man dies durch eine call(event.data.method) - function, indem man den Funktionsnamen ( als Attribut des method-Objekt ) übergibt.
Alles schön und gut aber wie gestalten wir das Ganze dynamischer? Ich möchte ja jede beliebige Webpage besuchen und deren Funktionen aufrufen. Hier müsste ich ja die besuchte Page editieren was natürlich nicht funktioniert.
Nehmen wir den editierten script-Tag und speichern den beinhaltenden Code in eine separaten JS Datei (execute_method.js), können wir mittels folgenden Einträgen in der manifest.json und contentscript.js uns das manuelle editieren der Webpage sparen:
manifest.json
contentscript.js
Diese Ergänzung editiert unsere Gegenstelle als einen script-Tag mit dem Inhalt der method-execute.js.
Nun könnte die Frage auftreten: "Wofür injeziere ich meinen eigenen JS Code um anschließend Webpage-Functions aufzurufen?"
Stellt man sich als Szenario einen externen Sensor vor, der mittels Interrupts bestimmte Events abfeuern will, könnte dies mit einer Websocket Anbindung funktionieren. Hier spendiert man dem Chrome Plugin ein background - script, welches mittels Websockets die Information des Sensors annimmt und Sie dem contentscript übergibt.