XPCNativeWrapper

From GreaseSpot

Jump to: navigation, search

Contents

[edit] Overview

Most all objects on a target web page that a user script sees are wrapped in XPCNativeWrapper. The reason for this is so that a script can change the properties of an object (actually the wrapper) without any JavaScript on the target page being able to see it. Mostly the wrapping is "transparent" - wrapped and unwrapped objects seem to behave the same because the wrapping object passes methods to the wrapped object, though there are some some exceptions.

[edit] wrappedJSObject

For a script to access the real underlying object there is the method

var realObj = wrappedObj.wrappedJSObject;


Be very careful when using the wrappedJSObject property. It is just as dangerous as unsafeWindow is.

[edit] Security

Related to security.

[edit] Limitations / Problems

[edit] Expando Properties

Expando Properties do not work on XPCNativeWrappers. This means that, for example, this will not work:

var el = document.createElement("a");
el.onclick = "alert('Error'); return false;";


Instead, use setAttribute and addEventListener methods. Note the use of the preventDefault method to emulate the "return false" behavior above.

addEventListener example:

function showTheError(event) {
    event.preventDefault();

    /* some code */
}
var el = document.createElement("a");
el.addEventListener("click", showTheError, false);


setAttribute example:

var el = document.createElement("a");
el.setAttribute("onclick", "alert('Error'); return false;");


This applies to any element, not just new ones you create (those references from createElement and those from getElementById et al), and any event handler, not just onclick.

[edit] for ... in on HTMLCollections

DOM methods like getElementsByTagName return HTMLCollections.

var arInputs = document.getElementsByTagName("input");

for (var elmInput in arInputs) {

  /* some code */
}

Instead use this...

var arInputs = document.getElementsByTagName("input");

var elmInput;
for (var i = arInputs.length - 1; i >= 0; --i) {
  elmInput = arInputs[i];

  /* some code */
}


[edit] Named Items

Items like frames, form elements, and so on can be referenced by name in normal JavaScript. XPCNativeWrappers cannot reference items by name. Use the namedItem method.

With a <input name="foo"> in the form:

form.foo;

Instead use this...

form.elements.namedItem("foo");


The same goes for frames:

window.framename;

Instead use this...

window.frames["framename"];

}

[edit] Event Handlers

Normal JavaScript can access an element's event handlers with code like:

element.onclick = myClickHandler;

or

element.onclick = "myClickHandler(this)";


This does not work on XPCNativeWrappers; it will result in a Component not available error in the JavaScript console. Instead, use addEventListener:

element.addEventListener("click", myClickHandler, false);


Any Greasemonkey script written before version 0.5 was released in mid-2005 may need updating to use addEventListener.

Personal tools