Saturday, 27 February 2016

Steps To Make Your Own Working Google Chrome extension

What You’ll Need

  • Google Chrome.
  • Your favorite text editor.
  • A folder where the extension files will live.
  • An icon for the browser action, which is Chrome-speak for a button in the browser toolbar. This should be a 19 square pixel PNG. You can use this one if you’d like:
You can create all the files we’ll need now or as we move along... it’s really up to you. By the time we finish, our folder will look something like this:
  • event.js
  • icon19.png
  • inject.js
  • manifest.json
Ready? Let’s get started!

The Manifest File

Create a new file at the root of your folder and name it manifest.json. The manifest is the heart of any Chrome extension. It tells Chrome “here’s what I am, and here’s what I need to work.”
Let’s add some details to the file using JSON:
{
"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>"]
}
Most of these properties are self-explanatory, with a few exceptions:
  • manifest_version: This lets Chrome know what version of the manifest file format we are using. Version 1 was deprecated as of Chrome 18, so you should always use 2.
  • background: Information about the scripts our extension requires to respond to things like a click of the browser action. More on this later.
  • permissions: Because we want our extension to grab the background-color values from any URL, we need permission to interact with&lt;all_urls&gt;. If we wanted our extension to only work onhttp://www.tricksglobal.org, we could specify that instead.
There’s a lot more you can do with the manifest file, but that’s all our extension will need.

Script Gets Real

You’ll notice our manifest references a JavaScript file we haven’t created yet,event.js. Create it now, and let’s add some code to it:
// 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);
This script is what’s known by Chrome (somewhat confusingly) as an event page. This means it will only run when an event the extension cares about occurs... in this case, the browser action being clicked.
Before we continue, we should load our extension in Chrome:
  1. Open up chrome://extensions/ (or click the rightmost menu button, then “Tools,” then “Extensions”).
  2. Make sure the “Developer mode” box in the upper-right is checked.
  3. Click “Load unpacked extension...” and select the folder you created earlier.
If all goes well, the extension should install like any other. Give the browser action (our icon) a click to see a wondrous alert:
Alert: The browser action was clicked! Yay!
Neat, huh?

Tab Talkin’

Now that our browser action is prepared to do our bidding, we need to retrieve CSS information from the current tab. To do that, we should understand a little about how Chrome extensions work relative to webpages loaded in tabs, and how the two can communicate.
Chrome was the first browser to popularize something we take for granted in desktop browsers today: The multi-process architecture. In Chrome, every webpage, add-on and extension gets its own process. This makes it really difficult for a single webpage or extension to crash your entire browser. But it also makes our event page a bit of an island... how do we act on the contents of a tab when that tab’s process is completely separate from event.js?
Bad news: We can’t.
Good news: We don’t need to, because Chrome supports passing messagesbetween scripts. We already have our event page, which we can use to sendmessages. All we need now is a script in the current tab that can receive them!
Author’s rendition of sendMessage in action.
Here’s how our nifty message-passing will work:
  1. When a user clicks the browser action, event.js will inject a new script into the current tab with instructions on what to do next.
  2. The injected script will do whatever it needs to, responding with the data we requested.
This means our extension will need one more file, 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;
})();
Now we have a script that’s ready to receive commands and return data. Let’s update event.js  to take advantage of that:
// 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);
Reload the extension from chrome://extensions/ and try the browser action on any webpage. You should see a message with the number of HTML nodes therein, which means we’ve successfully interacted with the tab! Woo-hoo!

Finally Doing Something Cool

All the pieces are in place. It’s time to actually do what we set out to do:
  1. When the browser action is clicked, determine all the background-colorvalues of the current tab.
  2. Build a Colorpeek URL based on those values.
  3. Open that URL in a new tab.
There’s very little magic from this point forward... it’s really just JavaScript (and not even fancy jQuery). Here we go...
Open inject.js again and update the getBgColors method:
// 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];
});
}
We’re almost done! Now update the getBgColors function 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;
})
}
Reload the extension and give it a try. If it works, go get yourself a beverage to celebrate your new-found ability to make Chrome extensions!

Share this

0 Comment to "Steps To Make Your Own Working Google Chrome extension"

Post a Comment