Colorpeek, Teil 2: Erstellen Sie Ihre erste Chrome-Erweiterung

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Der folgende Beitrag ist ein Gastbeitrag von Tyler Sticka. Tyler hat ein Tool namens Colorpeek entwickelt. Gestern haben wir uns das Was und Warum angesehen. Heute schauen wir uns an, wie er die Chrome-Erweiterung erstellt hat, was als großartiges Tutorial dienen wird, wie Sie mit der Erstellung Ihrer eigenen Chrome-Erweiterungen beginnen können.

In Teil Eins habe ich Colorpeek vorgestellt, eine Web-App, die ich zum schnellen Teilen von CSS-Farben erstellt habe, und seine Chrome-Erweiterung, die das *Empfangen* von Farben genauso einfach machte. Wie hat es ein Mann, der sich selbst als Designer und erst dann als Entwickler beschreibt, geschafft, eine schicke Erweiterung ganz allein zu bauen?

(Entschuldigung an IKEA.)

Ziemlich einfach, wie sich herausstellt. Chrome-Erweiterungen sind größtenteils JavaScript, und zwar relativ einfaches JavaScript. Das Durchforsten dieser gesamten Dokumentation mag anfangs beängstigend sein, aber sobald Sie die Grundlagen gemeistert haben, werden Sie feststellen, dass die Chrome-Entwicklung einfach *Webentwicklung* mit ein paar einzigartigen Wendungen ist.

In diesem Beitrag erstellen wir unsere eigene Miniaturversion der Colorpeek-Erweiterung: background-colorpeek, ein Tool zum Finden und Vorabsehen aller background-color-Werte, die eine Webseite verwendet. Sie werden überrascht sein, wie *wenig* Raketenwissenschaft dahinter steckt.

Was Sie brauchen werden

  • Google Chrome.
  • Ihr bevorzugter Texteditor.
  • Ein Ordner, in dem die Erweiterungsdateien gespeichert werden.
  • Ein Symbol für die *Browser-Aktion*, was im Chrome-Jargon ein Button in der Browser-Symbolleiste ist. Dies sollte ein 19x19 Pixel großes PNG sein. Sie können dieses hier verwenden, wenn Sie möchten:

Sie können alle benötigten Dateien jetzt oder im Laufe der Zeit erstellen... es liegt wirklich an Ihnen. Bis wir fertig sind, wird unser Ordner ungefähr so aussehen:

  • event.js
  • icon19.png
  • inject.js
  • manifest.json

Bereit? Legen wir los!

Die Manifest-Datei

Erstellen Sie eine neue Datei im Stammverzeichnis Ihres Ordners und nennen Sie sie manifest.json. Das Manifest ist das Herzstück jeder Chrome-Erweiterung. Es sagt Chrome: "Hier bin ich, und hier ist, was ich brauche, um zu funktionieren."

Fügen wir der Datei einige Details mit JSON hinzu.

{
  "manifest_version": 2,

  "name": "background-colorpeek",
  "version": "1.0",
  "description": "Get every background-color from the current tab.",

  "browser_action": {
    "default_icon": "icon19.png"
  },

  "background": {
    "scripts": ["event.js"],
    "persistent": false
  },
  
  "permissions": ["<all_urls>"]
}

Die meisten dieser Eigenschaften sind selbsterklärend, mit einigen Ausnahmen:

  • manifest_version: Dies teilt Chrome mit, welche Version des Manifest-Dateiformats wir verwenden. Version 1 wurde ab Chrome 18 als veraltet eingestuft, daher sollten Sie immer 2 verwenden.
  • background: Informationen zu den Skripten, die unsere Erweiterung benötigt, um auf Dinge wie einen Klick auf die *Browser-Aktion* zu reagieren. Mehr dazu später.
  • permissions: Da unsere Erweiterung die background-color-Werte von jeder URL abrufen soll, benötigen wir die Berechtigung, mit &lt;all_urls&gt; zu interagieren. Wenn unsere Erweiterung nur auf https://css-tricks.de/ funktionieren sollte, könnten wir stattdessen dies angeben.

Es gibt noch viel mehr, was Sie mit der Manifest-Datei tun können, aber das ist alles, was unsere Erweiterung benötigt.

Das Skript wird ernst

Sie werden feststellen, dass unser Manifest eine JavaScript-Datei referenziert, die wir noch nicht erstellt haben: event.js. Erstellen Sie sie jetzt und fügen wir etwas Code hinzu.

// This function will eventually contain some logic
// for receiving background-color values from the
// current tab.
function getBgColors (tab) {
  // But for now, let's just make sure what we have so
  // far is working as expected.
  alert('The browser action was clicked! Yay!');
}

// When the browser action is clicked, call the
// getBgColors function.
chrome.browserAction.onClicked.addListener(getBgColors);

Dieses Skript ist das, was von Chrome (etwas verwirrend) als *Ereignisseite* bezeichnet wird. Das bedeutet, dass es nur ausgeführt wird, wenn ein *Ereignis* eintritt, um das sich die Erweiterung kümmert... in diesem Fall das Klicken auf die Browser-Aktion.

Bevor wir fortfahren, sollten wir unsere Erweiterung in Chrome laden.

  1. Öffnen Sie chrome://extensions/ (oder klicken Sie auf die ganz rechte Menüschaltfläche, dann auf "Tools", dann auf "Erweiterungen").
  2. Stellen Sie sicher, dass das Feld "Entwicklermodus" in der oberen rechten Ecke aktiviert ist.
  3. Klicken Sie auf "Entpackte Erweiterung laden..." und wählen Sie den Ordner aus, den Sie zuvor erstellt haben.

Wenn alles gut geht, sollte die Erweiterung wie jede andere installiert werden. Klicken Sie auf die Browser-Aktion (unser Symbol), um einen wundersamen Alarm zu sehen.

Alert: The browser action was clicked! Yay!

Schön, oder?

Tab-Kommunikation

Nun, da unsere Browser-Aktion bereit ist, unseren Befehlen zu folgen, müssen wir CSS-Informationen aus dem aktuellen Tab abrufen. Dazu sollten wir ein wenig darüber verstehen, wie Chrome-Erweiterungen relativ zu geladenen Webseiten in Tabs funktionieren und wie die beiden kommunizieren können.

Chrome war der erste Browser, der etwas populär machte, das wir in Desktop-Browsern heute als selbstverständlich ansehen: Die *Mehrprozessarchitektur*. In Chrome hat jede Webseite, jedes Add-on und jede Erweiterung ihren eigenen Prozess. Dies macht es *wirklich* schwierig für eine einzelne Webseite oder Erweiterung, Ihren gesamten Browser zum Absturz zu bringen. Aber es macht unsere Ereignisseite auch zu einer kleinen Insel... wie können wir Inhalte eines Tabs bearbeiten, wenn der Prozess dieses Tabs vollständig von event.js getrennt ist?

Schlechte Nachrichten: Das können wir nicht.

Gute Nachrichten: Wir müssen es nicht, denn Chrome unterstützt das *Übergeben von Nachrichten* zwischen Skripten. Wir haben bereits unsere *Ereignisseite*, die wir zum *Senden* von Nachrichten verwenden können. Alles, was wir jetzt brauchen, ist ein Skript im aktuellen Tab, das sie empfangen kann!

Darstellung des Autors von sendMessage in Aktion.

So wird unsere ausgeklügelte Nachrichtenübermittlung funktionieren:

  1. Wenn ein Benutzer auf die Browser-Aktion klickt, wird event.js ein neues Skript in den aktuellen Tab *injizieren* mit Anweisungen, was als Nächstes zu tun ist.
  2. Das injizierte Skript wird tun, was es tun muss, und mit den von uns angeforderten Daten antworten.

Das bedeutet, unsere Erweiterung wird noch eine Datei benötigen: inject.js.

// This helps avoid conflicts in case we inject 
// this script on the same page multiple times
// without reloading.
var injected = injected || (function(){

  // An object that will contain the "methods"
  // we can use from our event script.
  var methods = {};

  // This method will eventually return
  // background colors from the current page.
  methods.getBgColors = function(){
    var nodes = document.querySelectorAll('*');
    return nodes.length;
  };

  // This tells the script to listen for
  // messages from our extension.
  chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
    var data = {};
    // If the method the extension has requested
    // exists, call it and assign its response
    // to data.
    if (methods.hasOwnProperty(request.method))
      data = methods[request.method]();
    // Send the response back to our extension.
    sendResponse({ data: data });
    return true;
  });

  return true;
})();

Jetzt haben wir ein Skript, das bereit ist, Befehle zu empfangen und Daten zurückzugeben. Aktualisieren wir event.js, um dies zu nutzen.

// Execute the inject.js in a tab and call a method,
// passing the result to a callback function.
function injectedMethod (tab, method, callback) {
  chrome.tabs.executeScript(tab.id, { file: 'inject.js' }, function(){
    chrome.tabs.sendMessage(tab.id, { method: method }, callback);
  });
}

function getBgColors (tab) {
  // When we get a result back from the getBgColors
  // method, alert the data
  injectedMethod(tab, 'getBgColors', function (response) {
    alert('Elements in tab: ' + response.data);
    return true;
  });
}

// When the browser action is clicked, call the
// getBgColors function.
chrome.browserAction.onClicked.addListener(getBgColors);

Laden Sie die Erweiterung von chrome://extensions/ neu und probieren Sie die Browser-Aktion auf jeder Webseite aus. Sie sollten eine Nachricht mit der Anzahl der HTML-Knoten darin sehen, was bedeutet, dass wir erfolgreich mit dem Tab interagiert haben! Woo-hoo!

Endlich etwas Cooles tun

Alle Teile sind vorhanden. Es ist Zeit, *tatsächlich* zu tun, was wir uns vorgenommen haben.

  1. Wenn die Browser-Aktion geklickt wird, ermitteln Sie alle background-color-Werte des aktuellen Tabs.
  2. Erstellen Sie eine Colorpeek-URL basierend auf diesen Werten.
  3. Öffnen Sie diese URL in einem neuen Tab.

Von diesem Punkt an gibt es nur noch wenig Magie... es ist wirklich nur JavaScript (und nicht einmal ausgefallenes jQuery). Los geht's...

Öffnen Sie inject.js erneut und aktualisieren Sie die Methode getBgColors.

// Return all of the background-color values
methods.getBgColors = function(){
  // Stores the colors and the number of occurrences
  var colors = {};
  // Get all the nodes on a page
  var nodes = document.querySelectorAll('*');
  // Instantiate variables we'll use later
  var node, nodeArea, bgColor, i;

  // Loop through all the nodes
  for (i = 0; i < nodes.length; i++) {
    // The current node
    node = nodes[i];
    // The area in pixels occupied by the element
    nodeArea = node.clientWidth * node.clientHeight;
    // The computed background-color value
    bgColor = window.getComputedStyle(node)['background-color'];
    // Strip spaces from the color for succinctness
    bgColor = bgColor.replace(/ /g, '');
    // If the color is not white or fully transparent...
    if (
      bgColor != 'rgb(255,255,255)' &&
      !(bgColor.indexOf('rgba') === 0 && bgColor.substr(-3) === ',0)')
    ) {
      // ...set or override it in the colors object,
      // adding the current element area to the
      // existing value.
      colors[bgColor] = (colors[bgColor] >> 0) + nodeArea;
    }
  }

  // Sort and return the colors by
  // total area descending
  return Object.getOwnPropertyNames(colors).sort(function (a, b) {
    return colors[b] - colors[a];
  });
}

Wir sind fast fertig! Aktualisieren Sie nun die Funktion getBgColors in event.js.

// Get background-color values from the current tab
// and open them in Colorpeek.
function getBgColors (tab) {
  injectedMethod(tab, 'getBgColors', function (response) {
    var colors = response.data;
    if (colors && colors.length) {
      var url = 'http://colorpeek.com/#' + colors.join(',');
      chrome.tabs.create({ url: url });
    } else {
      alert('No background colors were found! :(');
    }
    return true;
  })
}

Laden Sie die Erweiterung neu und probieren Sie es aus. Wenn es funktioniert, gönnen Sie sich ein Getränk, um Ihre neu entdeckte Fähigkeit zur Erstellung von Chrome-Erweiterungen zu feiern!

Einige der Hintergrundfarben, die auf CSS-Tricks verwendet werden.

Zusatzpunkte

Diese Erweiterung ist nur die Spitze des Eisbergs. Mit den Plattform-APIs von Chrome können Sie eine *Menge* tun. Hier sind einige Dinge, die Sie ausprobieren können, wenn Ihr Gehirn noch nach Wissen dürstet:

Ich hoffe, dies hat einige Aspekte der Chrome-Erweiterungsentwicklung entmystifiziert. Und wenn Ihnen gefällt, was wir gemeinsam gebaut haben, probieren Sie Colorpeek für Chrome aus... ich denke, es wird Ihnen gefallen. Viel Spaß beim Basteln!