0

I'm developing a Chrome extension which sends the highlighted selection to a speech engine API. I want to implement both context menu and on icon click. Here's the problem:

This works perfectly:

chrome.contextMenus.create({
    "title" : "Speak Me",
    "contexts" : ["selection"],
    onclick: function (info, tab) {
        speakMe(info.selectionText);
    }
});

Directly underneath it I have:

chrome.browserAction.onClicked.addListener(function() {
  speakMe(info.selectionText);
});

Which doesn't work.

If I leave the parameter empty it returns an audio saying "Undefined". So I guess the speech engine is telling me it got no text. What am I doing wrong?

This is the function in question, placed above:

var speakMe = function (text) {
        var key, lang, url, audio;
        key = "key=12345678910";
        lang = "sv_se";
        url = "http://tts.engine.com/api/speak?" + key + "&lang=en_us&voice=male1&speed=100&audioformat=ogg&oggbitrate=100&text=" + text; 
        audio = new Audio(url);
        audio.play();
    };

The selection text comes from another JS file:

function getSelectedText() {
  var text = "";
  if (typeof window.getSelection != "undefined") {
    text = window.getSelection().toString();
  } else if (typeof document.selection != "undefined" && document.selection.type == "Text") {
    text = document.selection.createRange().text;
  }
  return text;
}

But since the context menu works perfectly, I don't think there's a problem with that. It's just the browserAction that I don't get how to use properly.

user19882
  • 113
  • 7

1 Answers1

1

Because the browser action's onClicked event doesn't have any information about the selected text. You need to figure it out yourself. You can inject a content script into the current page and get the selected text with window.getSelection().toString(). Then send the message back to the extension and speak the text.

Here's an example:

chrome.browserAction.onClicked.addListener(function(tab) {
  chrome.tabs.executeScript(tab.id,
      {code: 'window.getSelection().toString()'}, function(results) {
    alert(results[0]);
  });
});

It just shows an alert, but it's very easy to change it to call speakMe.

方 觉
  • 4,042
  • 1
  • 24
  • 28
  • Hi. I tried using this method by adding it to the popup.js but still nothing. I'm not sure where the problem is. The console shows nothing, maybe I'm doing it wrong. How do I go around seeing where it fails, step by step so I can inform you better of the problem. – user19882 Jul 15 '13 at 10:53
  • First, where did you put the code? It should be in the background page. – 方 觉 Jul 15 '13 at 11:18
  • It's it the background page. Everything in the background page works fine, except this. When I click the popup icon, the alert doesn't fire. – user19882 Jul 15 '13 at 11:48
  • Do you have "default_popup" defined in your manifest.json? (oops, from your first comment, it's obvious that you have.) If you only want the selected text to be spoken, omit "default_popup" in the manifest. Otherwise, you need to move it to popup.js and change it to: `chrome.tabs.executeScript(null, {code: 'window.getSelection().toString()'}, function(results) { alert(results[0]); });` – 方 觉 Jul 15 '13 at 12:28