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.
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.
Related to security.
[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.
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 */
}
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'];
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.
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