cloneInto()
This function provides a safe way to take an object defined in a privileged scope and create astructured 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;
This enables privileged code, such as an extension, to share an object with less-privileged code, such as a web page script.
Syntax
let clonedObject = cloneInto( obj, // object targetScope, // object options // optional object);
Parameters
obj
object
. The object to clone.targetScope
object
. The object to attach the object to.options
Optionalobject
. Options for the function.cloneFunctions
Optionalboolean
. Whether the object's functions should be cloned. Default tofalse
. Cloned functions have the same semantics as functions exported usingexportFunction
. SeeCloning objects that have functions.OptionalwrapReflectors
Optionalboolean
. Whether DOM objects should be passed by reference instead of cloned. DOM objects are usually not clonable. Defaults tofalse
. SeeCloning objects that contain DOM elements.
Return value
A reference to the cloned object.
Examples
This content script creates an object, clones it into the content window and makes it a property of the content window global:
// content scriptvar addonScriptObject = { greeting: "hello from your extension" };window.addonScriptObject = cloneInto(addonScriptObject, window);
Scripts running in the page can access the object:
// page scriptbutton.addEventListener( "click", function () { console.log(window.addonScriptObject.greeting); // "hello from your extension" }, 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:
// Content scriptwindow.foo.addonScriptObject = cloneInto(addonScriptObject, window);
You can also pass it into a function defined in the page script. Suppose the page script defines a function like this:
// page scriptfunction foo(greeting) { console.log(`they said: ${greeting.message}`);}
The content script can define an object, clone it, and pass it into this function:
// content scriptvar addonScriptObject = { message: "hello from your extension" };window.foo(cloneInto(addonScriptObject, window)); // "they said: hello from your extension"
Cloning objects that have functions
If the object to clone contains functions, you must pass the{cloneFunctions:true}
flag, or you get an error. If you do pass this flag, then functions in the object are cloned using the same mechanism used inexportFunction
:
// content scriptvar addonScriptObject = { greetMe: function () { alert("hello from your extension"); },};window.addonScriptObject = cloneInto(addonScriptObject, window, { cloneFunctions: true,});
// page scriptvar 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 reflected from C++, such as DOM elements, the cloning operation fails with an error. If you pass the{wrapReflectors:true}
flag, then the object you clone contains these objects:
// content scriptvar addonScriptObject = { body: window.document.body,};window.addonScriptObject = cloneInto(addonScriptObject, window, { wrapReflectors: true,});
// page scriptvar 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 normalscript security checks.