Analyzing 2 more Chrome plugins

Girish Venkatachalam
6 min readSep 27, 2023

--

Learning from two more Chrome plugins today

Let us analyze two Chrome plugins

Here is a list of Chrome plugins I have in my github projects I downloaded. The list is huge. You can learn a lot just by browsing the code.

allowThirdPartyCookies
analytics
app
app_1
app_2
app_launcher
archive
background-simple
basic
basic_1
basic_2
basic_3
basic_4
basic_5
basic_6
basic_7
basic_8
blank_ntp
broken_background_color
buildbot
calendar
capturevisibleregion
catblock
catifier
chrome-firephp
chrome-query
chrome_search
cld
commands
comm_demo_app
comm_demo_ext
console_tts_engine
constant_context
contentSettings
cookies
default_command_override
desktopCapture
detectLanguage
document_scan
download_filename_controller
download_images
download_links
download_manager
download_open
downloads_overwrite
email_this_page
enableReferrer
event_page
extension-questions
fontSettings
fx
gdocs
getMessage
global_context_search
gmail
historyOverride
idle_simple
inspector
isAllowedAccess
live-headers
localizedHostedApp
magic8ball
make_page_red
managed_bookmarks
mappy
maps_app
merge_windows
news
news_a11y
news_i18n
newtab_search
no_cookies
notifications
oauth_contacts
optional_permissions
override_igoogle
pageaction_by_content
pageaction_by_url
pause-resume
pin
plugin_settings
power
print
printingMetrics
process_monitor
proxy_configuration
README.md
sandbox
screenshot
set_icon
set_icon_path
set_page_color
showHistory
show_tabs
simple-example
speak_selection
stylizr
tabCapture
tabCast
tab_shortcuts
talking_alarm_clock
timer
ttsdebug
ttsdemo
water_alarm_notification
zoom

This is just one project. There are lots by official and unofficial sources. Truth be told, if you are carping about not finding adequate help online for some software project you are an idiot.

This is because if you learn to look at the right places you always find help.

I am not so much telling of stackoverflow and google. Those are programmer’s bosom buddies.

But you have numerous projects on github, bitbucket, gitlab and several other places. You need the background knowledge to be able to go through several thousand lines of source. The depth of knowledge you can quickly soak up is enormous.

Event Page

This is a rather simple context menu plugin. It is ridiculous and meant to be a starter project. Not like the live headers we saw yesterday. That was a real project with practical use for which someone will open their wallet and pay you.

This one is just a demo of the possibilities afforded by context menu. Note we used only vanilla HTML form elements. Nothing fancy here.

Omnibox

The magic of this plugin is that you type omnix in the search or address bar.

First screen appears magically. The Omnibox plugin shows the triggering in blue.

Then whatever you type is shown in a very annoying popup.

It is illustrative of how powerful Chrome plugins can be. Again a very dumbed down example to teach us extension development. Nothing fancy.

What are the ideas learnt?

What I find in all this is that the manifest.json file is the starting poing of a Chrome extension. Kind of like the main() method in C.

You specify the name of the js or html file and then the execution path can be traced by going thro’ the source.

By looking at source below we can work our way into the execution path.

The idea here is that any serious plugin work can be learnt from the freely available code samples. You call them SDK if you want.

Source code of EventPage

manifest.json

{
"name": "Context Menus Sample (with Event Page)",
"description": "Shows some of the features of the Context Menus API using an event page",
"version": "0.7",
"permissions": ["contextMenus"],
"background": {
"persistent": false,
"scripts": ["sample.js"]
},
"manifest_version": 2
}

sample.js

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// The onClicked callback function.
function onClickHandler(info, tab) {
if (info.menuItemId == "radio1" || info.menuItemId == "radio2") {
console.log("radio item " + info.menuItemId +
" was clicked (previous checked state was " +
info.wasChecked + ")");
} else if (info.menuItemId == "checkbox1" || info.menuItemId == "checkbox2") {
console.log(JSON.stringify(info));
console.log("checkbox item " + info.menuItemId +
" was clicked, state is now: " + info.checked +
" (previous state was " + info.wasChecked + ")");
} else {
console.log("item " + info.menuItemId + " was clicked");
console.log("info: " + JSON.stringify(info));
console.log("tab: " + JSON.stringify(tab));
}
};
chrome.contextMenus.onClicked.addListener(onClickHandler);
// Set up context menu tree at install time.
chrome.runtime.onInstalled.addListener(function() {
// Create one test item for each context type.
var contexts = ["page","selection","link","editable","image","video",
"audio"];
for (var i = 0; i < contexts.length; i++) {
var context = contexts[i];
var title = "Test '" + context + "' menu item";
var id = chrome.contextMenus.create({"title": title, "contexts":[context],
"id": "context" + context});
console.log("'" + context + "' item:" + id);
}
// Create a parent item and two children.
chrome.contextMenus.create({"title": "Test parent item", "id": "parent"});
chrome.contextMenus.create(
{"title": "Child 1", "parentId": "parent", "id": "child1"});
chrome.contextMenus.create(
{"title": "Child 2", "parentId": "parent", "id": "child2"});
console.log("parent child1 child2");
// Create some radio items.
chrome.contextMenus.create({"title": "Radio 1", "type": "radio",
"id": "radio1"});
chrome.contextMenus.create({"title": "Radio 2", "type": "radio",
"id": "radio2"});
console.log("radio1 radio2");
// Create some checkbox items.
chrome.contextMenus.create(
{"title": "Checkbox1", "type": "checkbox", "id": "checkbox1"});
chrome.contextMenus.create(
{"title": "Checkbox2", "type": "checkbox", "id": "checkbox2"});
console.log("checkbox1 checkbox2");
// Intentionally create an invalid item, to show off error checking in the
// create callback.
console.log("About to try creating an invalid item - an error about " +
"duplicate item child1 should show up");
chrome.contextMenus.create({"title": "Oops", "id": "child1"}, function() {
if (chrome.extension.lastError) {
console.log("Got expected error: " + chrome.extension.lastError.message);
}
});
});

The sample.js file tells you how the context menu is built using the chrome.contextMenu object.

Most plugins use the chrome object. Most of your work might happen outside the chrome object but you have to tie into it to sit inside a tab or plug into Chrome at some level.

Source code of Omnix

manifest.json

{
"name": "Omnibox Example",
"description" : "To use, type 'omnix' plus a search term into the Omnibox.",
"version": "1.1",
"background": {
"scripts": ["background.js"],
"persistent": false
},
"omnibox": { "keyword" : "omnix" },
"manifest_version": 2
}

background.js

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';
// This event is fired each time the user updates the text in the omnibox,
// as long as the extension's keyword mode is still active.
chrome.omnibox.onInputChanged.addListener(
function(text, suggest) {
console.log('inputChanged: ' + text);
suggest([
{content: text + " one", description: "the first one"},
{content: text + " number two", description: "the second entry"}
]);
});
// This event is fired with the user accepts the input in the omnibox.
chrome.omnibox.onInputEntered.addListener(
function(text) {
console.log('inputEntered: ' + text);
alert('You just typed "' + text + '"');
});

This is really short. Gets to the point succinctly.

The Chrome address bar is called as omnibar. You have an event listener for

  • Input changed
  • Input entered

Could not get any simpler. Also the total lines of code within plugin is just 20.

Conclusion

We find Google extension coding is not very hard after all. All it takes is faith and some practice. We will look at some bigger code bases later.

--

--

Girish Venkatachalam

Author of Photoveda image editor Chrome plugin, SDK, API. Vim fanatic. Solopreneur for 19 years. Love coding in Python(Jupyter notebook). Linux fanatic.