Closed Bug 538131 Opened 14 years ago Closed 11 years ago

There seems to be no way to extend the prototype of MathML elements in JavaScript.

Categories

(Core :: MathML, defect)

1.9.1 Branch
x86
All
defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: sjoerd, Assigned: bzbarsky)

References

Details

(Keywords: regression)

Attachments

(1 file)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)

The constructor property of a MathML element equals Element, but it does not inherit from the prototype of the Element constructor.

Reproducible: Always

Steps to Reproduce:
1. Load a document with MathML in it.
2. Get hold of a MathML element in variable m
3. execute: m.constructor.prototype.test = 1
4. execute: m.test
Actual Results:  
m.test is undefined

Expected Results:  
m.test should return 1

This seems to be caused by bug 355548, as far as I can understand from https://bugzilla.mozilla.org/show_bug.cgi?id=427990#c5 as bug 355548 is not accessible to me.

For Xopus (a browser-based XML editor) this means that MathML support is completely broken in Firefox 3.5, both for input documents that contain MathML and for XSLT stylesheets that output MathML.

There is no workaround that we are aware of.
Did this used to work in a previous version of Firefox?
https://developer.mozilla.org/En/JavaScript-DOM_Prototypes_in_Mozilla says

"A third way through which one can access the prototype of an object is through the constructor's prototype property:

document.images[0].constructor.prototype.foo = bar;

Note though, the above may or may not work in Mozilla."

Does m.__proto__.test = 1 behave as expected?
It works in Firefox 3.0. I will try __proto__ tomorrow.
OK, thanks.  If 3.0 works then its not 355548.  Would be nice to know what caused the change, though.
I've narrowed it down:

works:
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b1) Gecko/20081007 Firefox/3.1b1 (.NET CLR 3.5.30729)

broken:
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b2) Gecko/20081201 Firefox/3.1b2 (.NET CLR 3.5.30729)
m.__proto__.test = 1 does behave as expected and m.__proto__ is shared by all mathml elements. For us this is an acceptable workaround.

But in the end it doesn't scale if we have to add workaround for every namespace that the Gecko engine wants to treat differently.
Thanks for looking into this.  (I not familiar enough with this to understand why MathML would be treated differently from other namespaces.)

These builds can further narrow the start of the problem
http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/2008/
(The dates may not correspond exactly as expected from the beta dates as beta builds are often made from source that is a few days old.)
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: regression
In general foo.constructor.prototype may or may not be the same thing as foo.__proto__.  The latter is guaranteed to be the prototype.  The former may or may not be; in particular the prototype of an object is immutable while the .prototype property of a random function (which is what foo.constructor is) is mutable and can be changed at any time.  So can the .constructor property of some random object, for that matter.

That said, the issue here is that the constructor of the mathml element is the constructor of Element but the prototype is not.  Testcase coming up that claims that, at least in 1.9.1.  That same testcase shows that on m-c the constructors are still equal but now the prototype is that of the mathml element(?).
Attached file Testcase
OK.  So it _used_ to be that the math.__proto__ was the same as other.__proto__.  It looks like we changed that in bug 462929 and that's what gave the 1.9.1b2 behavior.  After that change the constructors were still equal, but the protos were not anymore.  This is generally the case whenever classinfo with name is used.

Then on trunk at some point the behavior changed again in this range:  http://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=28aa23105a9e&tochange=5fe89f2c22f0

peter, any idea what's up there?
Blocks: 462929
Version: unspecified → 1.9.1 Branch
Sjoerd, note that you should be using Object.getPrototypeOf(m) (when possible) rather than __proto__, which is slowly inching toward deprecation as ES5 adds better ways of doing the things __proto__ permitted, with greater efficiency as well.
OS: Windows XP → All
(In reply to comment #10)
> Then on trunk at some point the behavior changed again in this range: 
> http://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=28aa23105a9e&tochange=5fe89f2c22f0
> 
> peter, any idea what's up there?

I think the patch in bug 462929 made us only define the "Element" property once with the constructor of the first element that has a DOMCI "named" Element, whereas before we'd define it every time an element was created (overwriting with the constructor of the last wrapper that we created). And the resolve hook for constructor looks up the constructor by name on the global object.

Ideally we wouldn't have DOMCI with name. I'll try to tink of a way to fix this bug without too many hacks.
Ah, so just changing my order of createElementNS would change Element.constructor (both before and after)?  Fun times.

In any case Sjoerd, the point is that if you really want the prototype (as opposed to what the prototype would be if you called the constructor), then .constructor.prototype is not reliable and shouldn't be used.
I am not using .constructor.prototype, but Element.prototype. I.e. I want a reliable way to add methods to all xml elements. It appears that mathml elements from one document share the same __proto__, but not mathml elements from different documents. So the workaround I thougth I had isn't a workaround after all.
> I.e. I want a reliable way to add methods to all xml elements

There is no such way in Gecko right now, if you want to include SVG and XHTML under "xml".

> It appears that mathml elements from one document share the same __proto__, but
> not mathml elements from different documents

Of course Element.prototype is per-document too, right?
Element.prototype is per-window as far as I can tell.
__proto__ and Element.prototype have the same scoping last I checked (they are per-inner-window).
I'm not sure what it the status of this bug, but I cc' Andrii who is working on bugs related to MathML and javascript for his Google Summer of Code project.
The status of this bug is that it'll probably get fixed once we finish converting the DOM to Paris bindings....  ;)
Depends on: 836822
Fixed by bug 836822.
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → FIXED
Assignee: nobody → bzbarsky
You need to log in before you can comment on or make changes to this bug.