XPCNativeWrapper

From GreaseSpot
(Redirected from XPCNativeWrappers)
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 interfere. Mostly the wrapping is "transparent" - wrapped and unwrapped objects behave the same because the wrapping object passes all access through to the wrapped object; there are some exceptions though.

Note: in Firefox 4, XrayWrapper replaced XPCNativeWrapper. They have different names but in effect serve the same purpose.

[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 */
}

or

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

for each(var elmInput in arInputs) {
  /* 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