Interacting with
Web Content

Mozilla Add-on SDK Workshop

Follow along

http://talks.canuckistani.ca/webcontent-uk-2011/#2

Content scripts

Hello, world

var pageMod = require("page-mod").PageMod({
  include: ['*'],
  contentScript: 'alert("Heellooooooo, Looondoooon!!!!")',
  contentScriptWhen: 'end',
});

Dissection:

Link

Content script security model

Example

Page script:

window.alert = function(arg) { /* evil code here */ }

Content script:

window.alert("Heellooooooo, Looondoooon!!!!");

Link

Result?

workaround: unsafeWindow

unsafeWindow: direct access to the document from content script. This is a security hole, here be dragons, this will steal your lunch, etc.

Using previous example, if you change the content script to:

Content script:

unsafeWindow.alert("Heellooooooo, Looondoooon!!!!");

Result: Hodor!!!

Exercise 1:

Expand the 'hello world' example to do something funny / evil / useful to every page.

Builder link, or

webcontent/1-hello in the github repo

page-mod

'Batteries included' example

var pageMod = require("page-mod").PageMod({
    include: ['*.canuckistani.ca'],
    contentScriptWhen: 'end',
    contentScriptFile: [data.url('lib.js')],
    onAttach: function(worker) {
      workers.push(worker);
      worker.on('detach', function () {
        detachWorker(this, workers);
      });
      worker.postMessage('42'); 
    }
  });
Link

Exercise 2:

tabs

Tabs / onAttach example

var data = require("self").data;
var tabs = require("tabs");
 
tabs.on('ready', function(tab) {
  tab.attach({
  contentScript: 'if (confirm("EXTERMINATE???")) ' + 
    '{ document.body.innerHTML = ' +
    '\'<img src="http://dailypop.files.wordpress.com/2010/04/dalek.gif">\';' + 
    'document.body.style.display="block"; ' + 
    '};',
  });
});
Link

Exercise 3.a

Exercise 3.b

Content script communications

Example: posting a message to a content script.

Example

Add-on code:

onAttach: function(worker) {
  workers.push(worker);
  worker.on('detach', function () {
    detachWorker(this, workers);
  });
  worker.postMessage('42');
}

Content script:

self.on('message', function (payload) {
    window.alert('The answer to the ultimate question of life, the universe ' + "\n" +
      'and everything is '+parseInt(payload));
});

Link

Example: posting a message from a content script to your add-on.

Example

Content script:

self.postMessage("This is from the content script!");

Add-on code:

worker.on("message", function(data) {
    console.log("Got message: " + data);
})

Link

Example: posting a message from a content script to a page.

Example

Content script:

document.defaultView.postMessage(' +
        '"this is my message...", "*");

Page code:

window.addEventListener('message', function(e) {
    console.log("Got message: " + e.data);
});

Link

Example: posting a message from a page to your content script.

Example

Page script:

$(document).ready(function() {
    $("#clicker").click(function() {
        window.postMessage("sending message from page!", "*");
        return false;
    });
});

Add-on code:

tab.attach({
  contentScript: 'window.addEventListener("message",
    function(ev) {
      alert("In content script, got "+ ev.data);',
});

Link

Exercise 4

Using this example as a starting point, implement a button in a page that sends an message through to your add-on code in main.js.

Questions?

We are all Rocketeers!

Get involved, kick the tires, let us know.