Chrome browser extensions are known to work in their own sandbox. For embedding into a web page, there is a content script mechanism, when javascript code is embedded into a page, and has access to the DOM tree. This mechanism allows you to work with the content of the page, change the appearance, run arbitrary JS, exchange data with the background extension process.
But one thing the content script mechanism does not allow you to do is get access to the javascript environment of a web page.
When I made an extension for scrobing listening to music from vk.com on last.fm, I first used the player’s DOM parsing to monitor the status of the player. It was awful, and after the first change in the layout, everything broke. So I had to come up with something more reliable. Searches on the Internet led to a simple and seemingly obvious mechanism for embedding your code in a web page:
')
1. From the content of the script, create a “script” element with its code in the DOM tree of the page.
2. The code patches the functions that you need to work with. For patching, we use the addCallListener method found somewhere on the Internet. It replaces the objective function with itself, and calls handlers before and after its launch:
Function.addCallListener = function(func, callbacks) { var successNumber = 0, errorNumber = 0, name = func.name; return function() { var args = [].slice.call(arguments); var result, error; var props = { args: args, self: this, name: name } callbacks.before && callbacks.before(props); try { result = func.apply(this, arguments); props.successNumber = ++successNumber; props.result = result; props.status = 'success'; callbacks.success && callbacks.success(props); } catch (e) { props.errorNumber = ++errorNumber; props.error = e; props.status = 'error'; callbacks.error && callbacks.error(props); } callbacks.after && callbacks.after(props); return result; } }
3. We patch the necessary functions. In the case of vk.com, this is the audioPlayer.onPlayProgress function, it is called every second during playback:
var ARTIST_NUM = 5; var TITLE_NUM = 6; var artistElem = document.getElementById('vkScrobblerArtist'); var titleElem = document.getElementById('vkScrobblerTrackTitle');
Now, when the player is working, the artistElem and titleElem elements will contain the actual title of the song and its performer. It remains only to periodically check their contents and do anything with it. You can get rid of periodically checking the contents of elements by using the jQuery event mechanism. This way you can arrange the exchange of any serializable data between the js of the web page and the extension.