Menu

XPCNativeWrapper

mmartz

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.

wrappedJSObject

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

Fair sample:

var realObj = wrappedObj.wrappedJSObject;

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

Security

Related to security.

Limitations / Problems

Expando Properties

[Expando_Properties] do not work on XPCNativeWrappers. This means that, for example, this will not work:

Bad sample:

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, and any event handler, not just onclick.

for ... in on HTMLCollections

DOM methods like getElementsByTagName return HTMLCollections.

Bad sample:

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

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:

Bad sample:

form.foo;

Instead use this...

form.elements.namedItem('foo');

The same goes for frames:

Bad sample

window.framename;

Instead use this...

window.frames['framename'];

Event Handlers

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

Bad samples:

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.

Notes


Related

Wiki: Global_object
Wiki: Greasemonkey_Manual:Environment
Wiki: Greasemonkey_Manual:Other_Useful_Tools
Wiki: Main_Page
Wiki: Metadata_Block
Wiki: Sandbox
Wiki: Security
Wiki: unsafeWindow

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.