Browser Extension, Firefox, Google-Music-Search, Google-Open-Storage-Search, Javascript

Firefox Extension – Google-Music-Search v0.2

Firefox Google-Music-Search


Firefox Google-Music-Search running on Crunchbang Linux


Google Music Search provides a simple way to search for music and files on google.com. There are two different types of queries to run: one to search for music files, and one to search for anything else stored in open indexed storage. Both open a tab in the browser and display search results from google.com. Firefox Google Music Search extension is based the Chrome Google Music Search and Chrome Open Storage Search extensions.

package.json

{
  "name": "google-music-search",
  "fullName": "Google-Music-Search",
  "id": "jid1-mIB68YB7TCOYZg",
  "description": "Makes searching for music and files on Google simple",
  "author": "Timothy Tocci - timothytocci.com",
  "homepage":"https://timothytocci.com/",
  "license": "MPL 2.0",
  "version": "0.2"
}

main.js


var widgets = require("sdk/widget");
var tabs = require("sdk/tabs");
var data = require("sdk/self").data;
var widget = widgets.Widget({
  id: "google-music-search",
  label: "Google Music Search",
  contentURL: data.url("google.png"),
  onClick: function() {
	searchdialog.show();
  }
});
var searchdialog = require("sdk/panel").Panel({
  width:480,
  height:272,
  contentURL: data.url("searchdialog.html")
});
var helpdialog = require("sdk/panel").Panel({
  width:640,
  height:480,
  contentURL: data.url("helpdialog.html")
});
searchdialog.port.on("doquery", function(url) {
  console.log(url);
  hidedialog();
  tabs.open(url);
});
function hidedialog(){
	searchdialog.hide();
}
searchdialog.port.on("helpclicked", function() {
    showhelp();
});
function showhelp(){
	helpdialog.show();
}
function closehelp(){
	helpdialog.hide();
}
helpdialog.port.on("gohome", function() {
	console.log("gohome");
    tabs.open("https://timothytocci.com/");
});
helpdialog.port.on("gocmusic", function() {
	console.log("gocmusic");
    tabs.open("https://timothytocci.com/2013/02/01/google-chrome-extension-google-music-search-an-omnibox-extension/");
});
helpdialog.port.on("gocoss", function() {
	console.log("gocoss");
    tabs.open("https://timothytocci.com/2013/02/03/google-chrome-extension-google-open-storage-search-an-omnibox-extension/");
});

helpdialog.html


<html>
    <head>
        <style>
            body {
                background-color: white;
            }
            
            input {
                height: 30px;
                width: 450px;
            }
			#home{
				color:blue;
				text-decoration:underline;
				cursor:hand;
			}
			#cmusic{
				color:blue;
                text-decoration:underline;
                cursor:hand;
			}
			#coss{
				color:blue;
                text-decoration:underline;
                cursor:hand;
			}
            #intro{
            	font-size: large;
            }
			.queries{
				font-size:large;
				font-weight:bold;
			}
			.qlist li{
				list-style: url(google.png);
			}
            .blue {
                color: blue;
            }
            
            .red {
                color: red;
            }
            
            .orange {
                color: orange;
            }
            
            .green {
                color: green;
            }
        </style>
    </head>
    <body>
        <center>
            <h1><span class="blue">G</span><span class="red">o</span><span class="orange">o</span><span class="blue">g</span><span class="green">l</span><span class="red">e</span>-<span class="blue">M</span><span class="red">u</span><span class="orange">s</span><span class="blue">i</span><span class="green">c</span>-<span class="blue">S</span><span class="red">e</span><span class="orange">a</span><span class="blue">r</span><span class="green">c</span><span class="red">h</span></h1>
            <p id="intro">
                Google Music Search provides a simple way to search for music and files on google.com. 
				There are two different types of queries to run: one to search for music files, and one to search for anything stored in open indexed storage. 
				Both open a tab in the browser and display search results from google.com. 
				Firefox Google Music Search extension is based the <a id="cmusic">Chrome Google Music Search</a> and <a id="coss">Chrome Open Storage Search</a> extensions. 
				Google Music Search was written by <a id="home">Timothy Tocci</a>.
            </p>
        </center>
        <p>
            To search for music files simply provide a band or artist name press the Music Search Button. To search for other filetypes; you must first specify the filetypes you are looking for. Filetypes can be ORed together using the pipe (|) character. After the filetypes you must enter a space. Anything before the first space in the query is considered the filetype(s). Then enter the query term for the file(s) you are searching for and press the Open Storage Search button.
        </p>
		<h4>Examples</h4>
		<ul class="qlist"><li><span class="queries">gif|jpg|png homecoming queen</span></li>
		<li><span class="queries">flv|mov|mp4 first steps</span></li>
		<li><span class="queries">torrent sometorrentfile</span> <-- May also act as a torrent weasel (depends on seed host)</li></ul>
    </body>
    <script type="text/javascript">
        window.onload = function(){
            var homelink = document.getElementById("home");
            homelink.addEventListener("click", function(){
                addon.port.emit("gohome","");
            }, false);
			
			var cmusiclink = document.getElementById("cmusic");
            cmusiclink.addEventListener("click", function(){
                addon.port.emit("gocmusic","");
            }, false);
			
			var cosslink = document.getElementById("coss");
            cosslink.addEventListener("click", function(){
                addon.port.emit("gocoss","");
            }, false);
        }
    </script>
</html>


searchdialog.html


<html>
    <head>
        <style>
            body {
                background-color: white;
            }
           
            input {
                height: 30px;
                width: 450px;
            }
            
            #goo {
                padding-top: 20px;
            }
			.blabels{
				font-size:large;
			}
        </style>
        
    </head>
    <body>
        <center>
            <div id="goo">
                <img src="google_logo_front.png"/>
            </div>
            <br/>
            <div>
                <input name="query" id="query" type="text" align="center" placeholder="enter a bandname or filetype and query"/>
                <br/>
                <button id="music">
                	<span class="blabels">Music Search</span>
                </button>
                <button id="storage">
                	<span class="blabels">Open Storage Search</span>
                </button>
				<button id="help">
                    <span class="blabels">Help/About</span>
                </button>
            </div>
        </center>
    </body>
	<script type="text/javascript">
           window.onload = function () {
                var btnmusic = document.getElementById("music");
                btnmusic.addEventListener("click", function(){
                    var input = document.getElementById("query");
                    var text = input.value;
					if(input.value == ""){return}
                    var query = 'intitle:index.of +?last modified? +?parent directory? +(mp3|wma|ogg|wav) +"' + text + '" -htm -html -php -asp -jsp -"Passwords"';
                    doquery(query);
                }, false);
                var btnstorage = document.getElementById("storage");
                btnstorage.addEventListener("click", function(){
                    var input = document.getElementById("query");
					if(input.value == ""){return}
                    var temp = input.value.split(" ", 2);
                    var filetype = temp[0];
                    text = temp[1];
                    var query = 'intitle:index.of +?last modified? +?parent directory? +(' + filetype + ') +"' + text + '" -htm -html -php -asp -jsp -"Passwords"';
                    doquery(query);
                }, false);
				
				var btnhelp = document.getElementById("help");
                btnhelp.addEventListener("click", function(){
					addon.port.emit("helpclicked");
				},true);
					
            }
            function doquery(query){
                url = "https://www.google.com/search?q=" + encodeURIComponent(query);
                addon.port.emit("doquery", url);
            }
        </script>
</html>

Click to Install Most Recent Version

Standard
Browser Extension, Firefox, Javascript, Share-It

Firefox Extension – Share-it 0.6 Context Menu

Share-it provides a context menu that allows the user to share the current page with a number of different websites that allow for link submissions. Share-it currently shares a web page on: facebook, twitter, google plus, linkedin, digg, stumbleupon, tumblr, friendfeed, fark, blinklist, and plurk. There is an options page that will allow the user to turn on or off the menu items they choose to use. Very simple and minimalistic design.

Share-it Context Menu Opened Up In Firefox

Share it Options Dialog Opened Up In Firefox

package.json

{
  "name": "share-it",
  "fullName": "Share-it",
  "id": "jid1-Kl2M45Ix2rhGtA",
  "description": "Adds context menu items to share the current page on a number of websites ",
  "author": "Timothy Tocci - timothytocci.com",
  "homepage": "https://timothytocci.com/",
  "license": "MPL 2.0",
  "version": "0.5"
}

main.js


var cm = require("sdk/context-menu");
var data = require("sdk/self").data;
var tabs = require("sdk/tabs");
var SS = require("simple-storage");

popupPanel = require("panel").Panel({
        height: 500,
        contentURL: data.url("options.html")
    });
popupPanel.port.on("optionsstarted", function () {
	console.log("optionsstarted received");
    popupPanel.port.emit("entrylist", entries);
});
popupPanel.port.on("setActive", function (menu) {
    setActive(menu);
});
popupPanel.port.on("setInactive", function (menu) {
    setInactive(menu);
});
var defaultentries = [
	{
	"menu":"facebook.com",
	"active":1,
	"ustr":"http://www.facebook.com/sharer.php?u={{URL}}&src={{TITLE}}"
	},{
	"menu":"twitter.com",
	"active":1,
	"ustr":"https://twitter.com/share?url={{URL}}&text={{TITLE}}"
	},{
	"menu":"plus.google.com",
	"active":1,
	"ustr":"https://plusone.google.com/_/+1/confirm?hl=en&url={{URL}}"
	},{
	"menu":"linkedin.com",
	"active":1,
	"ustr":"http://www.linkedin.com/cws/share?url={{URL}}"
	},{
	"menu":"digg.com",
	"active":1,
	"ustr":"http://digg.com/submit?url={{URL}}&title={{TITLE}}"
	},{
	"menu":"stumbleupon.com",
	"active":1,
	"ustr":"http://www.stumbleupon.com/submit?url={{URL}}"
	},{
	"menu":"tumblr.com",
	"active":1,
	"ustr":"http://www.tumblr.com/share?v=3&u={{URL}}&t={{TITLE}}"
	},{
	"menu":"friendfeed.com",
	"active":1,
	"ustr":"http://www.friendfeed.com/share?url={{URL}}&title={{TITLE}}"
	},{
	"menu":"fark.com",
	"active":1,
	"ustr":"http://cgi.fark.com/cgi/fark/farkit.pl?u={{URL}}&h={{TITLE}}"
	},{
	"menu":"blinklist.com",
	"active":1,
	"ustr":"http://www.blinklist.com/index.php?Action=Blink/Addblink.php&Url={{URL}}&Title={{TITLE}}"
	},{
	"menu":"plurk.com",
	"active":1,
	"ustr":"http://plurk.com/?qualifier=shares&status={{TITLE}}%20%2D%20{{URL}}"
	},
];
var entries = {};
if (!SS.storage["entries"]) {
	SS.storage["entries"] = JSON.stringify(defaultentries);
}
entries = JSON.parse(SS.storage["entries"]);
function setActive(menu){
	console.log("setActive");
	var elen = entries.length;
	console.log(menu);
	for(i=0;i<elen;i++){
		if(entries[i]["menu"] == menu){
			entries[i]["active"] = 1;
		}
	}
	SS.storage["entries"] = JSON.stringify(entries);
}
function setInactive(menu){
	console.log("setInactive");
	var elen = entries.length;
	console.log(menu);
	for(i=0;i<elen;i++){
		if(entries[i]["menu"] == menu){
			entries[i]["active"] = 0;
		}
	}
	SS.storage["entries"] = JSON.stringify(entries);
}
var mitems = [];
var entlen = entries.length;
for (i=0;i<entlen;i++){ 	if(entries[i]["active"] == 1){ 		mitems.push(cm.Item({ label: entries[i]["menu"], data: entries[i]["ustr"] })); 	} } mitems.push(cm.Separator()); mitems.push(cm.Item({ label: "Options", data: "{{OPTIONS}}" })); cm.Menu({   label: "Share-it",   contentScriptFile: data.url("menuscript.js"),   items: mitems,   onMessage: function(data) {sendit(data);} }); function sendit(data){ 	if(data.lastIndexOf("{{OPTIONS}}")!==-1){ 		popupPanel.show(); 	}else{ 		var url = data; 		url = url.replace("{{URL}}", encodeURI(tabs.activeTab.url)); 		if(data.lastIndexOf("{{TITLE}}")>0){
			url = url.replace("{{TITLE}}", encodeURIComponent(tabs.activeTab.title));
		}
		tabs.open({
			url: url,
			onReady: function onReady(tab) {
				console.log(tab.title);
			}
		});
	}
}

options.html


<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Share-it Options</title>
</head>
<style>
.green{color:green;}
.red{color:red;}
li{list-style-type: none;}
</style>
<body>
<h3>Share-it Context Menu Options</h3>
<ul id="menu">
</ul>
<div class="summary">Changes will take place the next time you start your browser. 
Or if you don't want to close the browser you could disable and reenable the Extension on the Plug-ins page.</div>
<p>Click anywhere outside this window to close it.</p>
</body>
<script type="text/javascript">
window.onload = function () {
	addon.port.emit("optionsstarted");
	var list = document.getElementById("menu");
	addon.port.on("entrylist", function (ckb) {
		for(i = 0; i < ckb.length; i++){
			if(ckb[i]["active"] == 1){
				var li = document.createElement("li");
				cbox = document.createElement("input");
				cbox.type = "checkbox";
				cbox.setAttribute("class","butt");
				cbox.checked = true;
				cbox.value = ckb[i]["menu"];
				var txtspan = document.createElement("span");
				txtspan.setAttribute("class","green");
				var mtxt = document.createTextNode(ckb[i]["menu"]);
				txtspan.appendChild(mtxt);
				li.appendChild(cbox);
				li.appendChild(txtspan);
				list.appendChild(li);
			}else{
				var li = document.createElement("li");
				cbox = document.createElement("input");
				cbox.type = "checkbox";
				cbox.setAttribute("class","butt");
				cbox.checked = false;
				cbox.value = ckb[i]["menu"];
				var txtspan = document.createElement("span");
				txtspan.setAttribute("class","red");
				var mtxt = document.createTextNode(ckb[i]["menu"]);
				txtspan.appendChild(mtxt);
				li.appendChild(cbox);
				li.appendChild(txtspan);
				list.appendChild(li);
			}
		}	
		as = document.getElementsByClassName("butt");
		for(i=0;i<as.length;i++){
			as[i].addEventListener("click",function(evt){
				if(evt.target.checked == true){
					addon.port.emit("setActive",evt.target.value);
				}else{
					addon.port.emit("setInactive",evt.target.value);
				}
			},false)
		}
	});
}
</script>
</html>

Click to Install Most Recent Version

Standard
Browser Extension, Google Chrome, Javascript, Opera, Share-It

Google Chrome Extension Share-it New Feature Update – An Options Page

The Google Chrome extension Share-it now has an Options page that enables you to choose which menu items are visible. Users simply can check which menu items to use and which to hide on the options page instead of navigating a menu of irrelevant menu items that they do not use. Preferences in an add-on are stored within the localstorage object in the browser in order to persist across start ups and closings. Developing an options page for your add-on isn’t a very difficult task, however, there are a couple of coding issues  to be aware of.

Share-it context menu running in Google Chrome

Share-it Context Menu

Share-it context menu options page running in Google Chrome

Share-it Options Page

Opera Next Is In The Loop

Something else to note is that I now also test Share-it on Opera Next where it runs superbly. I plan on eventually submitting this to the Opera store for consumption . For now, however, there is a link to download the .nex file at the bottom of this post if you want to use in now. Opera Next is based on the open source Chromium browser which Google Chrome is also based on. The context menu API is basically the same throughout as it allows for a shared code-base for context menu add-on development.

Share-it Context Menu running on Opera Next

Share-it Context Menu running on Opera Next

Caveats Developing an Options page or Popup page

There are a couple of tricky issues you should keep in mind if you are developing an options page for your add-on. First relates to scripting in pages inside of your add-on. There can be no inline script in your pages. Just keep your JavaScript in a separate file and make sure you are careful with your scripting not to create any inline script. Usually this means listening for click events and handling them using the event itself (similar to the way you would do it with Actionscript and Flex if you’ve ever done any Flash coding). The second issue relates to message and object passing. The JavaScript executing in your page isn’t in global scope for security reasons. There’s a special function to call, chrome.extension.getBackgroundPage(), that you have to call in order to gain access to the background page (app.js in this add-on). If you run into problems developing your page you should inspect the running page itself. The generated background page inspector will not show errors for secondary parts of the add-on (remember, not in global scope). Check out the source code below if you’re curious.

Source Code:

manifest.json

{
  "name": "Share-it",
  "description": "Adds context menu items to share the current page on a number of websites",
  "version": "0.4",
  "permissions": ["contextMenus"],
  "background": {
    "scripts": ["app.js"]
  },
  "options_page": "options.html",
  "icons" : {
		"16" : "favicon.ico",
		"32" : "peopleicon32.png",
		"48" : "peopleicon48.png",
		"128" : "peopleicon128.png"
	},
  "manifest_version": 2
}

app.js

/** app.js */
var defaultentries = [
	{
	"menu":"facebook.com",
	"active":1
	},{
	"menu":"twitter.com",
	"active":1
	},{
	"menu":"plus.google.com",
	"active":1
	},{
	"menu":"linkedin.com",
	"active":1
	},{
	"menu":"digg.com",
	"active":1
	},{
	"menu":"stumbleupon.com",
	"active":1
	},{
	"menu":"tumblr.com",
	"active":1
	},{
	"menu":"friendfeed.com",
	"active":1
	},{
	"menu":"fark.com",
	"active":1
	},{
	"menu":"blinklist.com",
	"active":1
	},{
	"menu":"plurk.com",
	"active":1
	},
];
var entries = {};
if (!localStorage.getItem("entries")) {
	localStorage.setItem("entries", JSON.stringify(defaultentries));
}
entries = JSON.parse(localStorage.getItem("entries"));
function isActive(menu){
	console.log("isActive");
	var elen = entries.length;
	console.assert(!elen == 0);
	for(i=0;i<elen;i++){
		if(entries[i]["menu"] == menu){
			console.log(entries[i]["menu"]);
			if(entries[i]["active"] == 1){
				return true;
			}else{
				return false;
			}
		}
	}
}
function setActive(menu){
	console.log("setActive");
	var elen = entries.length;
	console.log(menu);
	console.assert(!elen == 0);
	for(i=0;i<elen;i++){
		if(entries[i]["menu"] == menu){
			entries[i]["active"] = 1;
		}
	}
	localStorage.setItem("entries", JSON.stringify(entries));
}
function setInactive(menu){
	console.log("setInactive");
	var elen = entries.length;
	console.log(menu);
	console.assert(!elen == 0);
	for(i=0;i<elen;i++){
		if(entries[i]["menu"] == menu){
			entries[i]["active"] = 0;
		}
	}
	localStorage.setItem("entries", JSON.stringify(entries));
}
/* Create the context menu */
var hp = chrome.contextMenus.create({"title": "Share-it"});

if(isActive("facebook.com")){
	chrome.contextMenus.create({"title": "facebook.com", "contexts":["page"], "parentId": hp, "onclick": facebookIt});
}
function facebookIt(i, t){
	var createProperties = {url: "http://www.facebook.com/sharer.php?u="+ encodeURI(t.url) + "&src=" + encodeURIComponent("Share-it")};
	chrome.tabs.create(createProperties);
}

if(isActive("twitter.com")){
	chrome.contextMenus.create({"title": "twitter.com", "contexts":["page"], "parentId": hp, "onclick": twitterIt});
}
function twitterIt(i, t){
	var createProperties = {url: "https://twitter.com/share?url="+ encodeURI(t.url) + "&text=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}

if(isActive("plus.google.com")){
	chrome.contextMenus.create({"title": "plus.google.com", "contexts":["page"], "parentId": hp, "onclick": googleplusIt});
}
function googleplusIt(i, t){
	var createProperties = {url: "https://plusone.google.com/_/+1/confirm?hl=en&url="+ encodeURI(t.url)};
	chrome.tabs.create(createProperties);
}

if(isActive("linkedin.com")){
	chrome.contextMenus.create({"title": "linkedin.com", "contexts":["page"], "parentId": hp, "onclick": linkedinIt});
}
function linkedinIt(i, t){
	var createProperties = {url: "http://www.linkedin.com/cws/share?url="+ encodeURI(t.url)};
	chrome.tabs.create(createProperties);
}

if(isActive("digg.com")){
	chrome.contextMenus.create({"title": "digg.com", "contexts":["page"], "parentId": hp, "onclick": diggIt});
}
function diggIt(i, t){
	var createProperties = {url: "http://digg.com/submit?url="+ encodeURI(t.url) + "&title=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}

if(isActive("stumbleupon.com")){
	chrome.contextMenus.create({"title": "stumbleupon.com", "contexts":["page"], "parentId": hp, "onclick": stumbleuponIt});
}
function stumbleuponIt(i, t){
	var createProperties = {url: "http://www.stumbleupon.com/submit?url="+ encodeURI(t.url)};
	chrome.tabs.create(createProperties);
}

if(isActive("tumblr.com")){
	chrome.contextMenus.create({"title": "tumblr.com", "contexts":["page"], "parentId": hp, "onclick": tumblrIt});
}
function tumblrIt(i, t){
	var createProperties = {url: "http://www.tumblr.com/share?v=3&u="+ encodeURI(t.url) + "&t=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}

if(isActive("friendfeed.com")){
	chrome.contextMenus.create({"title": "friendfeed.com", "contexts":["page"], "parentId": hp, "onclick": friendfeedIt});
}
function friendfeedIt(i, t){
	var createProperties = {url: "http://www.friendfeed.com/share?url="+ encodeURI(t.url) + "&title=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}

if(isActive("fark.com")){
	chrome.contextMenus.create({"title": "fark.com", "contexts":["page"], "parentId": hp, "onclick": farkIt});
}
function farkIt(i, t){
	var createProperties = {url: "http://cgi.fark.com/cgi/fark/farkit.pl?u="+ encodeURI(t.url) + "&h=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}

if(isActive("blinklist.com")){
	chrome.contextMenus.create({"title": "blinklist.com", "contexts":["page"], "parentId": hp, "onclick": blinklistIt});
}
function blinklistIt(i, t){
	var createProperties = {url: "http://www.blinklist.com/index.php?Action=Blink/Addblink.php&Url="+ encodeURI(t.url) + "&Title=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}

if(isActive("plurk.com")){
	chrome.contextMenus.create({"title": "plurk.com", "contexts":["page"], "parentId": hp, "onclick": plurkIt});
}
function plurkIt(i, t){
	var createProperties = {url: "http://plurk.com/?qualifier=shares&status=" + encodeURIComponent(t.title) + "%20%2D%20" + encodeURI(t.url)};
	chrome.tabs.create(createProperties);
}

options.html


<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Share-it Options</title>
	<script type="text/javascript" src="options.js"></script>
</head>
<body>
<ul id="menu"></ul>
<div class="summary">Changes will take place the next time you start your browser.
Or if you don't want to close the browser you could uncheck and recheck the enabled box next to this extension on the Extensions tab page.</div>
</body>
</html>

options.js


window.onload = function () {
	ckb = chrome.extension.getBackgroundPage().entries;
	var list = document.getElementById("menu");
	for(i = 0; i < ckb.length; i++){
		console.log(ckb[i]["active"]);
		if(ckb[i]["active"] == 1){
			var li = document.createElement("li");
			var temp = "<input class="\&quot;butt\&quot;" type="\&quot;checkbox\&quot;" checked="checked" value="\&quot;&quot;" />" + ckb[i]["menu"] + "";

			li.innerHTML = temp;
			list.appendChild(li);
		}else{
			var li = document.createElement("li");
			var tempp = "<input class="\&quot;butt\&quot;" type="\&quot;checkbox\&quot;" value="\&quot;&quot;" />" + ckb[i]["menu"] + "";
			li.innerHTML = tempp;
			list.appendChild(li);

		}
	}
	as = document.getElementsByClassName("butt");
	for(i=0;i<as.length;i++){
		as[i].addEventListener("click",function(evt){
			if(evt.target.checked == true){

				chrome.extension.getBackgroundPage().setActive(evt.target.value);
			}else{
				chrome.extension.getBackgroundPage().setInactive(evt.target.value);
			}
		},false)
	}
}

Version 0.5 update – fixed the graphics display in newest Chrome browser

If you downloaded an extension from somewhere other than the Google Store (or the Opera Store), Chrome will not let you install it on the fly (Opera will install it, however, you’ll have to go to the extensions page to enable it). You have to go to the browser menu and choose Tools->Extensions to open up the Extensions tab. Then drag the extension from wherever it is on the file-system to the open Extensions page. This should start the install process. If you ever feel funny about a packed extension that was downloaded you can unzip them to inspect the code (if you don’t have 7zip you’ll have to change the file extension to .zip – do it on a copy).

Related:

Chrome Browser:

Opera Next Extension Development:

References From Google Developer:

Standard
AIR, Google-Music-Search, Google-Open-Storage-Search, Javascript, Windows

Adobe AIR Application – Google Music Search

Adds Music Search functionality to Windows and Mac. Provides the functionality of the Google Music Search and Google Open Storage Search Chrome add-ons to Windows and Mac users. Opens up the Google search query in the default system browser whatever that may be.

application.xml

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<application xmlns="http://ns.adobe.com/air/application/1.5">
 <id>com.timothytocci.example.Google.Music.Search</id>
 <filename>Google.Music.Search</filename>
 <name>Google.Music.Search</name>
 <version>1.0</version>
 <description/>
 <copyright/>
 <initialWindow>
 <content>Google.Music.Search.html</content>
 <systemChrome>none</systemChrome>
 <transparent>true</transparent>
 <resizable>false</resizable>
 </initialWindow>
 <icon>
 <image16x16>icons/musicsearch_16.png</image16x16>
 <image32x32>icons/musicsearch_32.png</image32x32>
 <image48x48>icons/musicsearch_48.png</image48x48>
 <image128x128>icons/musicsearch_128.png</image128x128>
 </icon>
</application>

Google.Music.Search.html

<html>
 <head>
 <script type="text/javascript" src="lib/air/AIRAliases.js">
 </script>
 <script type="text/javascript">
 var thisVersion, currentVersion;
 var iconLoadComplete = function(event){
 air.NativeApplication.nativeApplication.icon.bitmaps = [event.target.content.bitmapData];
 }
 air.NativeApplication.nativeApplication.autoExit = false;
 var iconLoad = new air.Loader();
 var iconMenu = new air.NativeMenu();
 var showSearchCommand = iconMenu.addItem(new air.NativeMenuItem("Music Search"));
 showSearchCommand.addEventListener(air.Event.SELECT, function(event){
 showSearch();
 });
 var exitCommand = iconMenu.addItem(new air.NativeMenuItem("Exit"));
 exitCommand.addEventListener(air.Event.SELECT, function(event){
 air.NativeApplication.nativeApplication.icon.bitmaps = [];
 air.NativeApplication.nativeApplication.exit();
 });
 if (air.NativeApplication.supportsSystemTrayIcon) {
 air.NativeApplication.nativeApplication.autoExit = false;
 iconLoad.contentLoaderInfo.addEventListener(air.Event.COMPLETE, iconLoadComplete);
 iconLoad.load(new air.URLRequest("icons/musicsearch_16.png"));
 air.NativeApplication.nativeApplication.icon.tooltip = gettooltip();
 air.NativeApplication.nativeApplication.icon.menu = iconMenu;
 }
 if (air.NativeApplication.supportsDockIcon) {
 iconLoad.contentLoaderInfo.addEventListener(air.Event.COMPLETE, iconLoadComplete);
 iconLoad.load(new air.URLRequest("icons/musicsearch_128.png"));
 air.NativeApplication.nativeApplication.icon.menu = iconMenu;
 }
 checkVersion();
 showSearch();

 function checkVersion(){
 var appData = air.NativeApplication.nativeApplication.applicationDescriptor;
 var dp = new DOMParser();
 var xml = dp.parseFromString(appData, "text/xml");
 var version = xml.getElementsByTagName("version")[0].firstChild;
 thisVersion = version.nodeValue;
 var url = new air.URLRequest("http://weyou.us/apps/GoogleMusicSearch/version/");
 var loader = new air.URLLoader();
 loader.dataFormat = air.URLLoaderDataFormat.TEXT;
 loader.addEventListener(air.Event.COMPLETE, compareVersion);
 loader.load(url);
 }

 function compareVersion(e){
 currentVersion = e.currentTarget.data;
 if (currentVersion > thisVersion) {
 openInBrowser("http://weyou.us/apps/GoogleMusicSearch/");
 }
 }

 function gettooltip(){
 var temp = "";
 temp = "Google Music Search" + "\n";
 temp = temp + " Use google to find music.";
 return temp;
 }

 function showSearch(){
 var init = new air.NativeWindowInitOptions();
 var win = null;
 var height = 228;
 var width = 500;
 // adobe bug - should be centered perfectly
 var top = (air.Capabilities.screenResolutionX / 2) - (height / 2);
 var left = (air.Capabilities.screenResolutionY / 2) - (width / 2);
 var spot = new air.Rectangle(top, left, width, height);
 init.minimizable = true;
 init.maximizable = true;
 init.resizable = false;
 init.type = "lightweight";
 init.systemChrome = air.NativeWindowSystemChrome.NONE;
 win = air.HTMLLoader.createRootWindow(true, init, false, spot);
 var form = air.File.applicationDirectory.resolvePath("search.html");
 win.load(new air.URLRequest(form.url));
 }

 function openInBrowser(url){
 air.navigateToURL(new air.URLRequest(url));
 }
 </script>
 </head>
 <body>
 <!-- This page is never shown. -->
 </body>
</html>

search.html

<html>
 <head>
 <style>
 body {
 background-color: white;
 }

 input {
 height: 30px;
 width: 450px;
 }

 #goo {
 padding-top: 20px;
 }
 </style>
 <script type="text/javascript" src="lib/air/AIRAliases.js">
 </script>
 <script type="text/javascript">
 var win = window.nativeWindow;
 var stay = false;
 var staycount = 0;
 function close(){
 win.close();
 }

 function timeout(){
 if (!stay) {
 close();
 }
 else {
 staycount++;
 }
 if (staycount === 3) {
 staycount = 0;
 stay = false;
 }
 }

 function doquery(query){
 url = "https://www.google.com/search?q=" + encodeURIComponent(query);
 openInBrowser(url);
 }

 function openInBrowser(url){
 air.navigateToURL(new air.URLRequest(url));
 }

 window.onload = function(){
 var dlg = document.getElementsByTagName("body");
 dlg[0].addEventListener("mousedown", function(){
 stay = true;
 staycount = 0;
 win.startMove();
 }, false);
 dlg[0].addEventListener("mouseover", function(){
 stay = true;
 staycount = 0;
 }, false);
 var inpt = document.getElementById("query");
 inpt.addEventListener("change", function(){
 stay = true;
 staycount = 0;
 }, false);
 var btnmusic = document.getElementById("music");
 btnmusic.addEventListener("click", function(){
 var input = document.getElementById("query");
 var text = input.value;
 var query = 'intitle:index.of +?last modified? +?parent directory? +(mp3|wma|ogg|wav) +"' + text + '" -htm -html -php -asp -jsp -"Passwords"';
 doquery(query);
 win.close();
 }, false);
 var btnstorage = document.getElementById("storage");
 btnstorage.addEventListener("click", function(){
 var input = document.getElementById("query");
 var temp = input.value.split(" ", 2);
 var filetype = temp[0];
 text = temp[1];
 var query = 'intitle:index.of +?last modified? +?parent directory? +(' + filetype + ') +"' + text + '" -htm -html -php -asp -jsp -"Passwords"';
 doquery(query);
 win.close();
 }, false);
 setInterval(timeout, 5000);
 }
 </script>
 </head>
 <body>
 <center>
 <div id="goo">
 <img src="google_logo_front.png"/>
 </div>
 <br/>
 <div>
 <input name="query" id="query" type="text" align="center" placeholder="enter a bandname or filetype and query"/>
 <br/>
 <button id="music">
 <img src="google_music_search_button.png"/>
 </button>
 <button id="storage">
 <img src="google_open_storage_search_button.png"/>
 </button>
 </div>
 </center>
 </body>
</html>

Original Source

MD5: ff8765b516c027539d18693a8b0adc73

Install Music Search

MD5: d3084dfb2406a68a3957d63acffa33c1

 Adobe AIR application installers can be unzipped to inspect the code (if you don’t have 7-Zip you’ll have to change the file extension to .zip – do it on a copy).

Standard
Browser Extension, Google Chrome, Google-Open-Storage-Search, Javascript

Google Chrome Extension – Google Open Storage Search, an Omnibox extension

Adds Open Storage Search functionality to Google Chrome, Chromium, and Comodo Dragon.

manifest.json

{
"name": "Google Open Storage Search",
"description" : "To use, type 'gos' & space, a filetype & space plus a query term into the Omnibox. timothytocci.com",
"version": "0.1",
"background": {
"scripts": ["background.js"]
},
"omnibox": { "keyword" : "gos" },
"icons" : {
"16" : "google.png",
"32" : "peopleicon32.png",
"48" : "peopleicon48.png",
"128" : "peopleicon128.png"
},
"manifest_version": 2
}

background.js

chrome.omnibox.onInputEntered
.addListener(function(text) {
var temp = text.split(" ", 2);
var filetype = temp[0];
text = temp[1];
var query = 'intitle:index.of +?last modified? +?parent directory? +(' + filetype + ') +"' + text + '" -htm -html -php -asp -jsp -"Passwords"';
var createProperties = {
url : "https://www.google.com/search?q="
+ encodeURIComponent(query)
};
chrome.tabs.create(createProperties);
});
chrome.omnibox.onInputStarted
.addListener(function() {
var suggestion = {
description : "Search by filetype and query term: %s using Google Open Storage Search"
}
chrome.omnibox.setDefaultSuggestion(suggestion);
});

Install (you must trust my code)

If you downloaded an extension from somewhere other than Google, Chrome will not let you install it on the fly. You have to go to the browser menu and choose Tools->Extensions to open up the Extensions tab. Then drag the extension from wherever it is on the file-system to the open Extensions page. This should start the install process. If you ever feel funny about a packed extension you can unzip them to inspect the code (if you don’t have 7zip you’ll have to change the file extension to .zip – do it on a copy).

Standard
Browser Extension, Google Chrome, Google-Music-Search, Javascript

Google Chrome Extension – Google Music Search, an Omnibox extension

Adds Music Search functionality to Google Chrome, Chromium, and Comodo Dragon.

manifest.json

{
  "name": "Google Music Search",
  "description" : "To use, type 'music', a space plus a band or artist name into the Omnibox. timothytocci.com",
  "version": "0.3",
  "background": {
    "scripts": ["background.js"]
  },
  "omnibox": { "keyword" : "music" },
   "icons" : {
		"16" : "google.png",
		"32" : "peopleicon32.png",
		"48" : "peopleicon48.png",
		"128" : "peopleicon128.png"
	},
  "manifest_version": 2
}

background.js

chrome.omnibox.onInputChanged.addListener(function(text, suggest) {
	suggest( [ {
		content : text + " discography",
		description : "+Discography"
	}, {
		content : text + " greatest hits",
		description : "+Greatest Hits"
	}, {
		content : text + " album",
		description : "+Album"
	}, {
		content : text + " collection",
		description : "+Collection"
	}, {
		content : text + " compilation",
		description : "+Compilation"
	} ]);
});
chrome.omnibox.onInputEntered
		.addListener(function(text) {
			var query = 'intitle:index.of +?last modified? +?parent directory? +(mp3|wma|ogg|wav) +"' + text + '" -htm -html -php -asp -jsp -"Passwords"';
			var createProperties = {
				url : "https://www.google.com/search?q="
						+ encodeURIComponent(query)
			};
			chrome.tabs.create(createProperties);
		});
chrome.omnibox.onInputStarted
		.addListener(function() {
			var suggestion = {
				description : "Find Music by %s using Google Music Search"
			}
			chrome.omnibox.setDefaultSuggestion(suggestion);
		});

Install (you must trust my code)

If you downloaded an extension from somewhere other than Google, Chrome will not let you install it on the fly. You have to go to the browser menu and choose Tools->Extensions to open up the Extensions tab. Then drag the extension from wherever it is on the file-system to the open Extensions page. This should start the install process. If you ever feel funny about a packed extension you can unzip them to inspect the code (if you don’t have 7zip you’ll have to change the file extension to .zip – do it on a copy).

Standard
Analyze-It, Browser Extension, Google Chrome, Javascript

Google Chrome Extension – Developing Analyze-it, a Context Menu

Developing a Google Chrome browser extension that creates a context menu for the active tab is a simple way to add the functionality you desire to the browser using JavaScript. You can use everything the Internet has to offer inside your context menu extension to help you use your browser better. The context menu extension described in this post is simple to develop, and easy to reuse as a simple template. By reverse engineering the GET request parameters in a url, you should be able to accomplish whatever you are doing with less copy-paste, clicks – whatever. This particular extension will open up the Guess and Fetch tools from scritch.org in a new tab with the active tab url passed in for analysis. This should make it easier to research any page in the browser and discover SEO and CMS information about it.

Google Chrome Extension Context Menu Development

Google Chrome Context Menu development is simple as far as structure is concerned. If your context menu is coded to do something relatively simple the extension size will only amount to a few lines of code in a JavaScript file, the manifest, and the graphics needed (graphics are not required to run the extension).

About the objects we will be developing with

There are only two objects in the Google Chrome Extension API to be concerned with when developing extensions similar to the one covered in this post; the tabs object and the contextMenu object. The Google Chrome Extension contextMenu object is very simple, it consists of only four methods, one event and one data type. The three parts we will be developing with is the create method, the onClicked event and the onClickData type. The Google Chrome Extension tabs object is slightly more complex. However, since we will only be creating a new tab and pointing it to a url, coding its usage is trivial  The only method in the tabs object we will be using is the chrome.tabs.create method which takes one object that contains the url as a parameter, This type of extension is small in size. There’s only a few lines of code to go over and explain. Mostly, the boilerplate and the graphics for the extension is what takes up the most space.

The file structure of a Google Chrome Browser Extension

The file structure for this extension is going to be the bare minimum needed for an extension. The files involved are a JSON manifest file required by every extension, a JavaScript file referenced in the manifest containing the code that does everything, and the graphics referenced in the manifest.json file. Thats it!  Everything in a folder and run it in unpacked mode (makes sure the developer mode checkbox is selected on the extension page). When an extension gets packed, all the files needed are zipped up at the top level (cannot be in a subfolder). Your folder structure should look similar to:

  • MyChromeExtension
    • manifest.json
    • app.js
    • icon16.png
    • icon32.png
    • icon64.png

The Google Chrome Extension Context Menu Manifest File

The manifest.json file defines all of the properties and permissions associated with the extension. Manifest files can get complex in larger extensions. Important parts of manifest.json in this extension are: the name, description, version, permissions array, background script, manifest version and icons properties. These properties are the bare minimum needed to install and run the extension.

You can actually leave out the icons block if you don’t want to bother with graphics. Chrome will assign default graphics to your extension if none are provided. A good rule of thumb is if you are going to upload your extension to the Google Web Store and distribute it – you should brand it somehow with the graphics. The right graphic can set your extension apart in the end user’s memory; especially if they like it. You should only let Chrome brand your extension while you are developing it.

There’s only one permission in the permissions array, contextMenus. .The contextMenus setting is a silent permission that does not display a warning dialog on installation. See http://developer.chrome.com/extensions/permission_warnings.html for more information regarding permissions settings and warnings.

The background object’s scripts array contains the JavaScript source file name for the extension.

manifest.json

{

"name": "Analyze-it",

"description": "Adds Analyze-it context menu items for the current page. Opens up the scritch.org Guess and Fetch Tools with the active tab url passed in for analysis. Discover SEO and CMS information for any page url",

"version": "0.1",

"permissions": ["contextMenus"],

"background": {

"scripts": ["app.js"]

},

"icons" : {

"16" : "favicon.ico",

"32" : "peopleicon32.png",

"48" : "peopleicon48.png",

"128" : "peopleicon128.png"

},

"manifest_version": 2

}

The Google Chrome Extension Context Menu JavaScript

The JavaScript goes as follows: First, a reference is created to a new menu item. This menu item is the parent context item that will show up when you right click on a page. All other menu items created have to reference this parent reference. Then we start creating the two sub-menu items using the same function used to create the parent – chrome.contextMenus.create. When we created the parent menu item all we passed in was the title, which is the menu item text shown in the menu. There are additional properties we pass in when we create the sub-menu items. The contexts array contains the context settings for the menu item. In this case the setting is set to page, which means the menu item will be shown when the page is right clicked. If you leave this out, the context defaults to page anyway. Then comes the parentId property which should be set to the parent reference created on the first line. Finally, the onclick property should be set to the callback function created for the menu click (which will be created on the next line).

There are two data objects passed into the callback function automatically: the OnClickData object and the tabInformation object. We will make use of the tabInformation object in the callback to retrieve the tab URL. So when you define the callback function pass in those two objects. The callback will start off with a tabCreateProperties object that is defined on the first line of the callback. The tabCreateProperties object contains one key – url. The URL passed into the tabCreateProperties object has to be URI encoded  That object will be passed into a chrome.tabs.create function that will open up the tab and evaluate the URL passed in.

app.js

var hp = chrome.contextMenus.create({"title": "Analyze-it"});

chrome.contextMenus.create({"title": "Fetch Page Info", "contexts":["page"], "parentId": hp, "onclick": fetchIt});

function fetchIt(i, t){

var createProperties = {url: "http://fetch.scritch.org/?url="+ encodeURI(t.url)};

chrome.tabs.create(createProperties);

}

chrome.contextMenus.create({"title": "Guess CMS", "contexts":["page"], "parentId": hp, "onclick": guessIt});

function guessIt(i, t){

var createProperties = {url: "http://guess.scritch.org/?url="+ encodeURI(t.url)};

chrome.tabs.create(createProperties);

}

Running an unpacked extension

Normally, you would download and install an extension from the google site. You must go to the browser menu and choose: Tools->Extensions. There, on the extensions page in the upper right corner of the page, is a Developer mode checkbox. You have to make sure that checkbox is checked before Chrome will allow you to load an unpacked extension (in a folder on the file system). This way you can run any code you want any time you feel up to coding something.  To load something just hit the Load unpacked extension button and choose your extension’s working folder. Don’t forget to reload the extension after you make any code changes to test it.

Running a downloaded extension

If you downloaded an extension from somewhere other than Google, Chrome will not let you install it on the fly. You have to go to the browser menu and choose Tools->Extensions to open up the Extensions tab. Then drag the extension from wherever it is on the file-system to the open Extensions page. This should start the install process. CAUTION! INSTALLING EXTENSIONS IN THIS WAY CAN CAUSE DAMAGE!. You really have to trust the source of the extension if you install it this way. Google has a complete infrastructure that, believe it or not, makes installing extensions through them the safest way. Google will hold the developer account accountable if something turns out to be malicious. Downloading and installing an extension from somewhere other than Google takes that small incentive to write clean, non-malicious code away. Take it from me, its far too easy for someone to write an extension for Google Chrome that steals your passwords or banking information – across every account you visit! Just to be safe you should always install any browser extension from the Chrome Web Store.

Context Menu Extension Development on Demand

Context menu extensions are so small you’ll most likely memorize the basics quickly. If you’re a student or writer, being able to develop these on the fly is skill that could come in handy. Cutting down the number of actions needed to accomplish something can make using Chrome easier and more efficient, Having the right extension can make the difference between doing something and getting aggravated or simply doing something. I haven’t found a cheat sheet on the Internet for writing Google Chrome Browser Extensions so I recommend that you keep a sort of boilerplate file with easy to reuse functionality in it that you can turn to. Having that boilerplate code around while you’re browsing or doing your research can help. If you find yourself doing something over and over again repetitively, you should try to make that action into an extension if possible.

Let’s consider the end user who had a habit of selecting some text on one webpage and copying it, opening another page and pasting the text into that second page’s search box and then searching. There’s the chance to lighten the users load by writing an extension to automate that task flow. Ideally, what you would want is a menu item to click instead of copy that does everything. It’s not too hard to do this for any web site. The key to doing this is reverse engineering the search GET request and setting up the tab creation function to use a url that includes your parameters (the selected text) in the request. It will appear that a new tab will open up to the search for the selected text you originally selected.

Reverse Engineering a GET Request

In a GET request, everything after the question mark is an array of url encoded key value pairs denoted by ampersands. What you have to do on the site being searched is do a search. When your results page comes up look at the url. Locate where your search term is located. First, copy the url up to the question mark (include it) and paste it somewhere.  Now copy the key (include the equals sign). The key gets pasted onto the end of the url you pasted earlier – which creates the url used in the tab creation. Sometimes there will be a plethora of extra system data being passed into the search, you can ignore the rest for now.

If the tab opens up to content other than what you planned when your extension is built and runnung you should go back to the GET request and check if you are missing a parameter. Most web applications work if session information in the url is missing.

Create the extension

Basically cut and paste the code in this extension to use as a template. Next you’ll have to change all the values around to suit your needs. Name, description, version should be changed in the manifest. In app.js you’ll have to change the menu titles to something suitable and the context menu context to selection because its the selected text being passed in as a parameter instead of the page url. The callback name and reference should also be changed to something suitable. Now take the string you created earlier (web address – it should end with an equal sign) and replace the url in the tab’s createProperties object with it.

The selected text that is passed to the search query is in the OnClickData object (the other object being passed in automatically to the callback) in the selectionText property. We will use the encodeURIComponent function instead of encodeURI to encode the selected text and prepare it to be concatenated into the GET request that open up the new tab. The i.selectionText property holds the text to be encoded in the JavaScript file. The url in the code below is fictional and included for illustrative purposes only. The code is not a working extension in other words.

All things considered, its pretty easy to write an extension for a web application on the Internet. It doesn’t have to be the search box you connect your browser to, it can be any site with a form that uses GET instead of POST.

The code alterations should look something like the following:

manifest.json

{

"name": "Search Somesite",

"description": "Adds a Search menu item with the Searh Somesite submenu",

"version": "0.1",

"permissions": ["contextMenus"],

"background": {

"scripts": ["app.js"]

},

"icons" : {

"16" : "favicon.ico",

"32" : "peopleicon32.png",

"48" : "peopleicon48.png",

"128" : "peopleicon128.png"

},

"manifest_version": 2

}

app.js

var hp = chrome.contextMenus.create({"title": "Search"});

chrome.contextMenus.create({"title": "Search some site", "contexts":["selection"], "parentId": hp, "onclick": search});

function search(i, t){

var createProperties = {url: "http://somesite.com/search.php?query="+ encodeURIComponent(i.selectionText)};

chrome.tabs.create(createProperties);

}

There are many small sites on the Internet that don’t have browser extensions either because they don’t have the time or don’t have the budget to develop them. If you use one of these sites extensively maybe its time to whip up an extension to make life a bit easier.

Adding functionality to make the browser easier or simpler to use is what many an end user has often wished they could do in the past. Google made it easy to develop browser extensions in JavaScript for their popular web browser Chrome (and the open source version often used on Linux- Chromium) . Google Chrome Browser Extensions also run on Comodo Dragon a Chromium based secure version of Chrome that centers on privacy.

Related:

Chrome Browser:

Google Chrome Extension:

Google Chrome Extension Development:

References From Google Developer:

Standard
Browser Extension, Google Chrome, Javascript, Share-It

Share-it A Google Chrome Extension for Sharing a Page on Multiple Websites

manifest.json

{
  "name": "Share-it",
  "description": "Adds context menu items to share the current page on a number of websites",
  "version": "0.2",
  "permissions": ["contextMenus"],
  "background": {
    "scripts": ["app.js"]
  },
  "icons" : {
		"16" : "favicon.ico",
		"32" : "peopleicon32.png",
		"48" : "peopleicon48.png",
		"128" : "peopleicon128.png"
	},
  "manifest_version": 2
}

app.js

var hp = chrome.contextMenus.create({"title": "Share-it"});
chrome.contextMenus.create({"title": "facebook.com", "contexts":["page"], "parentId": hp, "onclick": facebookIt});
function facebookIt(i, t){
	var createProperties = {url: "http://www.facebook.com/sharer.php?u="+ encodeURI(t.url) + "&src=" + encodeURIComponent("Share-it")};
	chrome.tabs.create(createProperties);
}
chrome.contextMenus.create({"title": "twitter.com", "contexts":["page"], "parentId": hp, "onclick": twitterIt});
function twitterIt(i, t){
	var createProperties = {url: "https://twitter.com/share?url="+ encodeURI(t.url) + "&text=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}
chrome.contextMenus.create({"title": "plus.google.com", "contexts":["page"], "parentId": hp, "onclick": googleplusIt});
function googleplusIt(i, t){
	// var createProperties = {url: "https://plusone.google.com/_/+1/confirm?hl=en&url="+ encodeURI(t.url)};
	var createProperties = {url: "https://plusone.google.com/share?url="+ encodeURI(t.url)};
	chrome.tabs.create(createProperties);
}
chrome.contextMenus.create({"title": "linkedin.com", "contexts":["page"], "parentId": hp, "onclick": linkedinIt});
function linkedinIt(i, t){
	var createProperties = {url: "http://www.linkedin.com/cws/share?url="+ encodeURI(t.url)};
	chrome.tabs.create(createProperties);
}
chrome.contextMenus.create({"title": "digg.com", "contexts":["page"], "parentId": hp, "onclick": diggIt});
function diggIt(i, t){
	var createProperties = {url: "http://digg.com/submit?url="+ encodeURI(t.url) + "&title=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}
chrome.contextMenus.create({"title": "myspace.com", "contexts":["page"], "parentId": hp, "onclick": myspaceIt});
function myspaceIt(i, t){
	var createProperties = {url: "http://www.myspace.com/Modules/PostTo/Pages/?u="+ encodeURI(t.url)};
	chrome.tabs.create(createProperties);
}
chrome.contextMenus.create({"title": "stumbleupon.com", "contexts":["page"], "parentId": hp, "onclick": stumbleuponIt});
function stumbleuponIt(i, t){
	var createProperties = {url: "http://www.stumbleupon.com/submit?url="+ encodeURI(t.url)};
	chrome.tabs.create(createProperties);
}
chrome.contextMenus.create({"title": "tumblr.com", "contexts":["page"], "parentId": hp, "onclick": tumblrIt});
function tumblrIt(i, t){
	var createProperties = {url: "http://www.tumblr.com/share?v=3&u="+ encodeURI(t.url) + "&t=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}
chrome.contextMenus.create({"title": "friendfeed.com", "contexts":["page"], "parentId": hp, "onclick": friendfeedIt});
function friendfeedIt(i, t){
	var createProperties = {url: "http://www.friendfeed.com/share?url="+ encodeURI(t.url) + "&title=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}
chrome.contextMenus.create({"title": "fark.com", "contexts":["page"], "parentId": hp, "onclick": farkIt});
function farkIt(i, t){
	var createProperties = {url: "http://cgi.fark.com/cgi/fark/farkit.pl?u="+ encodeURI(t.url) + "&h=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}
chrome.contextMenus.create({"title": "blinklist.com", "contexts":["page"], "parentId": hp, "onclick": blinklistIt});
function blinklistIt(i, t){
	var createProperties = {url: "http://www.blinklist.com/index.php?Action=Blink/Addblink.php&Url="+ encodeURI(t.url) + "&Title=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}
chrome.contextMenus.create({"title": "plurk.com", "contexts":["page"], "parentId": hp, "onclick": plurkIt});
function plurkIt(i, t){
	var createProperties = {url: "http://plurk.com/?qualifier=shares&status=" + encodeURIComponent(t.title) + "%20%2D%20" + encodeURI(t.url)};
	chrome.tabs.create(createProperties);
}

This one is a little more full featured as far as sharing is concerned. I may just give this one out so I added my site graphics so it looks a bit more professional. Demonstrates using a parent ‘folder’ for (sub) context menu items. Its pretty basic: create a handle (var hp) and a parent (which is nothing more than a context menu item with just a title) and use it in each child’s creation function inside the “parentId” property. I would have liked to put the proper site icons next to each menu item, but it does not work like that in Chrome. You can, however, use check boxes and radio buttons in the menu items. Maybe that will be included in the next version of Chrome (hopefully).

If you plan to use a library when creating your extension, be sure to use one that doesn’t use dynamic loading (unbuild dojo apps will not run in other words). In my opinion you should use straight javascript targeted at Chrome. This extension assumes its user is smart enough not to share a page that’s on the hard drive without hosting it on the Internet first (otherwise you’ll be sharing a file path). I could have used a Match Pattern in the “documentUrlPatterns” property in the creation function for each menu item that could check the scheme, but I didn’t bother. Its something you could use at your own discretion in your add-on.

Standard
Browser Extension, Google Chrome, Javascript, Look-It-Up

Look-it-up A Google Chrome Extension that Looks Up Selected Text on dictionary.com

manifest.json

{
  "name": "Look-it-up",
  "description": "Adds context menu item that looks up selected text on dictionary.com",
  "version": "0.1",
  "permissions": ["contextMenus"],
  "background": {
    "scripts": ["app.js"]
  },
  "manifest_version": 2
}

app.js

chrome.contextMenus.create({"title": "Look-it-up", "contexts":["selection"],"onclick": lookItUp});
function lookItUp(i, t){
	var createProperties = {url: "http://www.dictionary.com/cgi-bin/dict.pl?term=" + encodeURIComponent(i.selectionText)};
	chrome.tabs.create(createProperties);
}

Simple Google Chrome Extension that looks up selected text on dictionary.com. Obviously you should only select one word as dictionary.com will not define more than one. Same as Google-Translate-it, demonstrates getting selected text and processing it in a GET request.

Standard