gal007
gal007

Reputation: 7192

Sharing addon objects (content scripts) with Web content (page objects) in Firefox

I spent days trying to share one of my Firefox for Android extension objects with the webpages I also open from my extension (declared as resources). The thing is I have read a lot about the last year's changes about unsafewindow, so I tryed a very small example with the new functions but didn't work. I copied the examples and I also tryed my owns, but there is no way to copy existing objects with functionality. See, I have a VERY big object to clone in the content window, but I decided to test with a small one:

//From addon
var dog = {
    name: 'Spike',
    woof: function(){alert('woof woof!')}
};

And after that I tryed to copy this object into the active window:

//From addon
var contentWindow = window.BrowserApp.selectedBrowser.contentWindow;
contentWindow.dog = Components.utils.cloneInto(
    dog, 
    contentWindow, 
    {cloneFunctions: true}
);

And after that, I tryed to check what was really copied:

alert(contentWindow.dog); //Shows: [object Object]
alert(contentWindow.dog.name); //Shows: Spike
alert(contentWindow.dog.woof); //Shows: undefined

So, I can clone the objects but no the functions, even when I declared "cloneFunctions: true".

I also tryed to create an empty object and then assign the functions (a lot of work thinking in my so big original object), and didn't work:

function greetme(user) {
    return "cheers " + user;
}
var foo = Components.utils.createObjectIn(contentWindow,{defineAs: "foo"});
Components.utils.exportFunction(greetme, foo, {defineAs: "greetme"}); 
//foo is not an object in current window

So... Any idea is welcome, I really don't know what to do because theory and given examples doesn't work anymore.

Thanks (A LOT) in advance!!

https://blog.mozilla.org/addons/2014/04/10/changes-to-unsafewindow-for-the-add-on-sdk/

Upvotes: 4

Views: 492

Answers (1)

nmaier
nmaier

Reputation: 33192

Your code is more or less correct already, however, you're running into trouble with XRay wrappers. And, in order for the content window (website) to actually see you dog, you need to waive the XRay wrapper on the content window as well.

I tested the following with the current Firefox for Android Nightly (sorry, my release Firefox is not configured for remote debugging).

Ran this in the Main Process (using the WebIDE):

var dog = {
  name: 'Spike',
  woof: function () {
    alert(contentWindow.document.title + "\n" + this.name + ': woof woof!');
  }
};

var contentWindow = BrowserApp.selectedBrowser.contentWindow;

// Need to unwrap this, so that we can actually set properties on the
// object itself and not just the wrapper. Aka. make "dog" visible to
// the actual script.
var unsafeWindow = Components.utils.waiveXrays(contentWindow);

// Define Window.dog (on the unsafe window, so that the website code
// can actually see it).
unsafeWindow.dog = Components.utils.cloneInto(dog, contentWindow, {
  cloneFunctions: true
});

Then I switched over to the actual tab and tested:

dog.woof();

And it worked.

Upvotes: 2

Related Questions