This function provides a safe way to take an object defined in a privileged scope and create a structured clone of it in a less-privileged scope. It returns a reference to the clone:
var clonedObject = cloneInto(myObject, targetWindow);
You can then assign the clone to an object in the target scope as an expando property, and scripts running in that scope can access it:
targetWindow.foo = clonedObject;
In this way privileged code, such as an add-on, can share an object with less-privileged code like a normal web page script.
Syntax
Components.utils.cloneInto(obj, targetScope[, options]);
Parameters
-
obj : object - The object to clone.
-
targetScope : object - The object to attach the object to.
-
options : object - This optional parameter is an object with the following optional properties:
cloneFunctions: a Boolean value that determines if functions should be cloned. If omitted the default value isfalse. Cloned functions have the same semantics as functions exported usingComponents.utils.exportFunction. See Cloning objects that have functions below.wrapReflectors: a Boolean value that determines if objects reflected from C++, such as DOM objects, should be cloned. If omitted the default value isfalse. See Cloning objects that contain DOM elements below.
Returns
A reference to the cloned object.
Example
This add-on script creates an object, clones it into the content window and makes it a property of the content window global:
// add-on script
var addonScriptObject = {"greeting" : "hello from add-on"};
contentWindow.addonScriptObject = cloneInto(addonScriptObject, contentWindow);
Scripts running in the page can now access the object:
// page script
button.addEventListener("click", function() {
console.log(window.addonScriptObject.greeting); // "hello from add-on"
}, false);
Of course, you don't have to assign the clone to the window itself: you can assign it to some other object in the target scope:
contentWindow.foo.addonScriptObject = cloneInto(addonScriptObject, contentWindow);
You can also pass it into a function defined in the page script. Suppose the page script defines a function like this:
// page script
function foo(greeting) {
console.log("they said: " + greeting.message);
}
The add-on script can define an object, clone it, and pass it into this function:
// add-on script
var addonScriptObject = {"message" : "hello from add-on"};
contentWindow.foo(cloneInto(addonScriptObject, contentWindow)); // "they said: hello from add-on"
Cloning objects that have functions
If the object to be cloned contains functions, you must pass the {cloneFunctions:true} flag or you'll get an error. If you do pass this flag, then functions in the object are cloned using the same mechanism as that used in Components.utils.exportFunction:
// add-on script
var addonScriptObject = {
greetme: function() {
alert("hello from add-on");
}
};
contentWindow.addonScriptObject = cloneInto(addonScriptObject,
contentWindow,
{cloneFunctions: true});
// page script
var test = document.getElementById("test");
test.addEventListener("click", function() {
window.addonScriptObject.greetme();
}, false);
Cloning objects that contain DOM elements
By default, if the object you clone contains objects that are reflected from C++, such as DOM elements, the cloning operation will fail with an error. If you pass the {wrapReflectors:true} flag, then the object you clone is allowed to contain these objects:
// add-on script
var addonScriptObject = {
body: contentWindow.document.body
};
contentWindow.addonScriptObject = cloneInto(addonScriptObject,
contentWindow,
{wrapReflectors: true});
// page script
var test = document.getElementById("test");
test.addEventListener("click", function() {
console.log(window.addonScriptObject.body.innerHTML);
}, false);
Access to these objects in the target scope is subject to the normal security checks.
