Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Text selection and display in context menu chrome extension

I have been working on a small Chrome extension with a problem I cant seem to get my head around and would appreciate someone to look at it with a fresh perspective.

The goal is to create a chrome extension which enables you to select text on any given website and displays an option to send the selection to another website using a contextmenu item.

My manifest.json looks like this:

{
"name": "Context Menu Search",
"description": "Opens the selected text as keyword in a new window",
"version": "0.1",
"permissions": ["contextMenus"],
"background_page": "background.html"
}

Then background.html:

<script src="rightclick.js"></script>

And rightclick.js:

var selection_callbacks = []; 
 function getSelection(callback) { 
 selection_callbacks.push(callback); 
    chrome.tabs.executeScript(null, { file:"selection.js" }); 
  }; 
  chrome.extension.onRequest.addListener(function (request) { 
    var callback = selection_callbacks.shift(); 
    callback(request); 
  });

function sendSearch(selectedText) {
var serviceCall = 'http://www.google.com/search?q=' + selectedText;
chrome.tabs.create({url: serviceCall});
}
var tx = getSelection();
var title = "Test '" + tx + "' menu item";
var id = chrome.contextMenus.create({"title": title, "contexts":[selection],
                                   "onclick": sendSearch(tx)});
console.log("selection item:" + id);

Plus selection.js:

chrome.extension.sendResponse(window.getSelection().toString());

So far the context menu creation works fine, but the selected text is not displayed at all. If anyone has any suggestions on how to solve this problem as well as simplify the script, I would appreciate your input.

Thank you very much.

like image 862
baik Avatar asked Dec 07 '10 11:12

baik


1 Answers

UPDATE

I just looked at the docs and all this can be done much more simpler without any content scripts and callbacks:

chrome.contextMenus.create({
    title: "Test %s menu item", 
    contexts:["selection"], 
    onclick: function(info, tab) {
        sendSearch(info.selectionText);
    }
});

That's all you need, because you can use %s in menu title to get selected text.

(everything below is not needed anymore)


Your getSelection() method doesn't return selected text, it just injects a content script to a page. Selected text is received sometime later in onRequest and then passed to a callback function from your callback array as a parameter.

So this part:

var tx = getSelection();
var title = "Test '" + tx + "' menu item";
var id = chrome.contextMenus.create({"title": title, "contexts":[selection],
                                   "onclick": sendSearch(tx)});
console.log("selection item:" + id);

needs to be changed to something like this:

getSelection(function(tx) { 
    var title = "Test '" + tx + "' menu item";
    var id = chrome.contextMenus.create({"title": title, "contexts":["selection"],
                                       "onclick": sendSearch(tx)});
    console.log("selection item:" + id);
})

But I would get rid of that selection_callbacks array altogether as I think it is not needed:

chrome.extension.onRequest.addListener(function (request) { 
    var tx = request;
    var title = "Test '" + tx + "' menu item";
    var id = chrome.contextMenus.create({"title": title, "contexts":["selection"],
                                       "onclick": sendSearch(tx)});
    console.log("selection item:" + id);
});

Also note that "contexts":[selection] needs to be "contexts":["selection"], and "onclick": sendSearch(tx) needs to be something like this instead:

"onclick": function(info, tab) {
    sendSearch(info.selectionText);
}
like image 54
serg Avatar answered Oct 07 '22 01:10

serg