سؤال

I'm writing a simple content script for chrome that reads text on webpages using google's tts api. The script works fine on domains under google.co.uk but not working on other pages.

(help for usage: it plays selected text after '0' key pressed)

manifest.json:

{
    "manifest_version": 2,
    "name": "text reader",
    "description": "text reader using google's text to speech api",
    "version": "0.1",
    "content_scripts": [{
        "matches": ["<all_urls>"],
        "js": ["tts.js"]
    }],
    "permissions": [
        "http://*/",
        "https://*/"
    ]
}

tts.js:

function Tts() {
    var ttsurl = "https://translate.google.co.uk/translate_tts";
    var audio = new Audio();
    audio.onloadeddata = function() {
        audio.play();
    };

    this.read = function(text) {
        var url =  ttsurl + "?q=" + escape(text) + "&tl=en";
        audio.src = url;
        alert(url);
    }
}

var tts = new Tts();

document.onkeypress = function() {
    if(event.keyCode == 48) { //key '0' pressed
        var text = getSelection();
        tts.read(getSelection().toString());
    }
}

Is there a nice way to make cross domain requests from a content script? I am happy to change settings of my browser too. What I tried: setting permission for all URLs (see manifest.json permissions)

هل كانت مفيدة؟

المحلول

The solution I found is fairly straight forward. As you already know you can't use the TTS API in the content scripts. What you have to do is use a background page, or an event page for our purpose since it should be sparsely used.

manifest.json:

...
"permissions": [
    "http://*/",
    "https://*/",
    "tts"
],
"background": {
    "scripts": ["background.js"],
    "persistent": false
}


tts.js:

document.onkeypress = function() {
    if(event.keyCode == 48) { //key '0' pressed
        var text = getSelection().toString();
        chrome.runtime.sendMessage({type:"tts", text:text});
    }
}


background.js:

chrome.runtime.onMessage.addListener(function (request) {
    switch(request.type) {
        case "tts":
            tts(request.text);
        break;
    }
});

function tts(text) {
    chrome.tts.speak(text);
}

or

chrome.runtime.onMessage.addListener(function (request) {
    if (request.type == "tts") {
        tts(request.text);
    }
});

function tts(text) {
    chrome.tts.speak(text);
}


Note that type:"tts" is only being used as a key and could be anything else. Also, the tts function doesn't have to match the key. I know this isn't exactly the way you were looking to solve it, but this should handle your problem.


Good luck!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top