Closed Bug 877491 Opened 9 years ago Closed 9 years ago

Document proto chain blocked by XPCOM wrapper preventing patching.

Categories

(Core :: DOM: Core & HTML, defect)

21 Branch
x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED DUPLICATE of bug 855971

People

(Reporter: mynameisdustinlam, Unassigned)

Details

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36

Steps to reproduce:

While patching some polyfill for Document.querySelector on Document.prototype, I noticed that the XPC wrapper, "XPC_WN_ModsAllowed_NoCall_Proto_JSClass", for document objects block the proto chain, so it ends up calling the native implementation of the function I'm trying to patch.


Actual results:

Since the XPC wrapper blocks the proto chain (it implements the functions I'm trying to patch), calling the function I'm patching on a newly created document uses the native implementation.

Document.prototype.querySelector = function(){ return 'foo'; };
var doc = document.implementation.createHTMLDocument('bar');
Document.prototype.querySelector === doc.querySelector; // Returns false.

Instead of falling back to the Document implementation, it uses the native implementation defined by the XPC wrapper.


Expected results:

Patching the Document prototype should patch the prototype for both newly created XML and HTML documents, and should not be blocked by the native implementation in the XPC wrapper:

Document.prototype.querySelector = function(){ return 'foo'; };
var doc = document.implementation.createHTMLDocument('bar');
doc.querySelector() // Should return 'foo'.

As an interesting note, patching Document.prototype seems to work correctly on both Chrome (version 27) and Internet Explorer (9, 10).
Dustin, thank you for the bug report.

What you're seeing is that there is an HTMLDocument.prototype.querySelector, and HTMLDocument.prototype is closer to the document object than Document.prototype, so just changing Document.prototype does not change the value of doc.querySelector.

In any case, this was fixed in bug 855971.  You should be able to see the fix in a nightly or Aurora build.
Status: UNCONFIRMED → RESOLVED
Closed: 9 years ago
Resolution: --- → DUPLICATE
Duplicate of bug: 855971
Oh, and as a workaround if you need one, setting both Document.prototype.querySelector and HTMLDocument.prototype.querySelector should work.
Hi Boris, thanks for your reply.

I have one more case with this bug that I need help clarifying before closing this off as a duplicate.

If we create a Document using this method and patch the Document.prototype, the result is:

var parser = new DOMParser();
var doc = parser.parseFromString('<a/>', 'text/xml');
Document.prototype.querySelector = function(){ return 'foo'; };
Document.querySelector === doc.querySelector; // Returns false.
doc.__proto__.constructor.name; // Returns "Document".

Am I missing something or does this seem to be a separate issue from bug 855971?
Status: RESOLVED → UNCONFIRMED
Resolution: DUPLICATE → ---
> Document.querySelector === doc.querySelector; // Returns false.

As it should.  The relevant check is Document.prototype.querySelector == doc.querySelector, and is true for me in Firefox beta or later.  

In Firefox 21 it does in fact return false.  But in Firefox 21 doc.__proto__.hasOwnProperty("constructor") is also false, so doc.__proto__.constructor.name is actually getting it from further up the prototype chain.

That said, doc.__proto__.constructor.name returns "" for me in every build I have here, so I'm not sure where you're getting "Document"....
Status: UNCONFIRMED → RESOLVED
Closed: 9 years ago9 years ago
Resolution: --- → DUPLICATE
Duplicate of bug: 855971
Oops, you're right. I meant "" and not "Document".

Thanks for clearing things up.
You need to log in before you can comment on or make changes to this bug.