Re: Problems activating an object

Barry MacKichan <[email protected]> Sun, 14 Sep 2014 13:28:12 -0700 (PDT)
Newsgroups gmane.comp.mozilla.devel.plugins
Message-ID <[email protected]>
I never got any response to this, and my search for solutions on the web was fruitless, so I thought I'd come back and say what the solution was. Maybe this can help someone else in the future.

The crucial clue (after many dead ends) was that I noticed that sometimes in the debugger (Venkman) obj.toString() would return ""[object XPCNativeWrapper [object HTMLObjectElement ..]]" and at other times it would return "[[HTMLObjectElement] [class: HTMLObjectElement...]]". In the latter case, everything worked correctly, and in the former it always failed, so it was time to research what XPCNativeWrapper really does.

It is there partly for security, to keep an evil web server from modifying methods on objects in the content document that would be executed in the chrome (main program) code. So a wrapped HTML object element supports only those methods that are in the IDL file for HTMLObjectElement, and it goes to the code in the C++ implementation, skipping over anything defined in JavaScript. (see http://https://developer.mozilla.org/en-US/docs/Xray_vision for more details). It also skips over any properties and methods defined in the plugin.

This is why some methods, such as obj.id, obj.tagName, etc. worked while all the properties and methods built into the plugin object failed when obj was wrapped.

There is a way around this, I discovered yesterday. Given a wrapped object, the .wrappedJSObject property is supposed to return the underlying object, unwrapped. Unfortunately, when you evaluate obj.wrappedJSObject in Venkman, you get void (another curve ball). If you ignore that and execute

     if (obj.wrappedJSObject) obj=obj.wrappedJSObject;

in the program, the condition evaluates to true, despite what the debugger said. The above line of code doesn't return an HTMLObjectElement, but a [XPCSafeJSObjectWrapper], but it works. So to fix the code, all that was necessary was the above line in a few key places. 

In retrospect, the only times that the plugin methods worked was just after the HTML object element was created and was still being held in memory. They failed every time the object was constructed using the object node in the document (which is always when you have loaded a document containing the plugin data). The debugger evidently finds the wrapped object when it evaluates something, which is why everything always worked in the debugger.

--Barry