1

I want to make a chrome extension that will connect to a localhost server to receive instructions to play songs in Grooveshark using the Grooveshark Javascript API. (http://grooveshark.com/GroovesharkAPI.html)

For example, if I type window.Grooveshark.addSongsByID([13963],true) in the javascript console, it'll add the song and start playing like it should I need to be able to do this from the extension. So to start, I just wanted to make an extension with a background page and just this single script to execute the command:

background.html

<!doctype html>
<html>
    <head>
        <script src="background.js"></script>
    </head>
    <body>
    </body>
</html>

background.js

chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(
    null, {code:"window.Grooveshark.addSongsByID([13963],true)"});
});

manifest.json

{
  "name": "Play song in Grooveshark",
  "version": "0.1.0",
  "background_page": "background.html",
  "permissions": [
    "tabs", "http://*/*"
  ],
  "browser_action": {
    "name": "Play song",
    "default_icon": "icon.png"
  }
}

Could anyone tell me why it doesn't work?

Thank you very much!!

Trevor
  • 716
  • 6
  • 9
  • 1
    I'm not 100% certain but it could be the trailing comma in your manifest – JaredMcAteer Nov 03 '11 at 17:27
  • Oops, that's actually not there. Thanks for pointing it out though. – Trevor Nov 03 '11 at 17:33
  • You can right-click the extension button and select the bottom option "show popup" or similar. It will have console that prints the errors from your extension. – Lycha Nov 03 '11 at 17:33
  • Actually, when I click the button it does create an error in the console "Uncaught TypeError: Cannot call method 'addSongsByID' of undefined (anonymous function)" – Trevor Nov 03 '11 at 17:46

2 Answers2

1

Content scripts cannot access parent page's window object. You would need to inject <script> tag into a page with your code.

//bg page
chrome.tabs.executeScript(null, {
    code: "injectJs('window.Grooveshark.addSongsByID([13963],true)')"
});

//content script
function injectJs(code) {
        var scr = document.createElement("script");
        scr.type = "text/javascript";
        scr.text = code;
        (document.head || document.body || document.documentElement).appendChild(scr);
}

You can inject injectJs function through manifest to all pages, and then call it when needed.

serg
  • 109,619
  • 77
  • 317
  • 330
  • Nice! Thank you. So I have the function in a file called contentScript.js and I've added `"content_scripts": [ { "js": ["contentScript.js"], "matches": ["http://*.groovshark.com/*"] } ],` to the manifest but it says "Uncaught ReferenceError: injectJs is not defined." What am I missing? – Trevor Nov 03 '11 at 18:33
  • Actually, when I add that script to the background.html, it doesn't give me any error but it doesn't work either ... =( – Trevor Nov 03 '11 at 19:06
  • @Trevor Maybe when you are calling it from bg page that script wasn't loaded yet? You need to call it after page with content script is fully loaded. – serg Nov 03 '11 at 19:38
  • It's because when you call chrome.tabs.executeScript with a null tabid, it sends it to the background page. That first parameter needs to be a tab id. Or just use the proxy in my answer and don't worry about all this message passing. – msfeldstein Feb 10 '12 at 18:24
0

I wrote a wrapper to make this almost transparent. The script injection solution also doesn't let you get any return values from the functions, while this proxy does.

Include this in your content script and call methods on GroovesharkProxy instead of window.Grooveshark.

https://github.com/msfeldstein/Grooveshark-Chrome-Extension-Proxy

http://www.macromeez.com/use-groovesharks-js-api-from-a-chrome-extension/

msfeldstein
  • 1,080
  • 1
  • 9
  • 18