Closed Bug 420649 Opened 16 years ago Closed 16 years ago

JS object inherited (__proto__) from XBL bound element can't get access to xbl:field

Categories

(Core :: XBL, defect)

x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED WONTFIX

People

(Reporter: surkov, Unassigned)

References

Details

(Keywords: regression)

Attachments

(1 file)

Attached file testcase
JS object inherited (__proto__) from XBL bound element can't get access to xbl:field. For example,

<binding id="test">
    <implementation>
       <field name="_field">3</field>
    </implementation>
</binding>

var test = document.getElementById("test")
var obj = {
   __proto__: test
};
alert(obj._field);

throws Error: uncaught exception: An error occured throwing an exception.

But if I call xbl:field directly (test._field or obj.__proto__._field) then it won't happen and xbl:field is called correctly.

I'm not sure I choosed proper component, if it's not XBL related problem please move into more suitable component.
This is more or less "by design" with the lazy fields setup: the resolve hook will throw if the object the resolve is happening on is not the DOM node (which in this case it's not).

If we want this to not happen, I suppose we could walk up the proto chain from the original node looking for something that looks like a content node to install on.  But then there's no guarantee we'll install on the right node, depending on how the proto chain has been messed with.

So my gut feeling is that we should wontfix this.
Blocks: 372769
Note that as I recall that's also how XPConnect works: if you set up a DOM node as the proto of some JS object and then try to call DOM methods on that object, things won't necessarily work right.
From js guy point of view it's not evident, it's one more thing to remember and to search workarounds like we got this in bug 417051. Therefore I would like to get this worked.

(In reply to comment #1)
> If we want this to not happen, I suppose we could walk up the proto chain from
> the original node looking for something that looks like a content node to
> install on.  But then there's no guarantee we'll install on the right node,
> depending on how the proto chain has been messed with.

Could you give an example?
> Could you give an example?

Set the proto of a DOM node to another DOM node, install an XBL binding on that other DOM node, set the first DOM node to be the proto of you object, and reference a field.  Which DOM node should the field be installed on?  How is the code supposed to be able to tell?
(In reply to comment #4)
> > Could you give an example?
> 
> Set the proto of a DOM node to another DOM node, install an XBL binding on that
> other DOM node, set the first DOM node to be the proto of you object, and
> reference a field.  Which DOM node should the field be installed on?  How is
> the code supposed to be able to tell?
> 

It's plain inheritance chain, right? What's difference whould be if I will use JS object instead of DOM nodes?
> It's plain inheritance chain, right?

What is?

> What's difference whould be if I will use JS object instead of DOM nodes?

You can't attach XBL bindings to things that are not DOM nodes?
(In reply to comment #6)
> > It's plain inheritance chain, right?
> 
> What is?
> 
> > What's difference whould be if I will use JS object instead of DOM nodes?
> 
> You can't attach XBL bindings to things that are not DOM nodes?
> 

Sure but what's role does XBL play here? In example:

DOMNode1/XBL -> DOMNode2/XBL -> JSObject
  field                             field

JSObject.field should call DOMNode2/XBL.field I guess. That's will happen in the case of JS object usage:
JSObject1 -> JsObject2 -> JsObject
  field                field
JSObject.field will call JSObject2.field. Right? What did I miss?
> Sure but what's role does XBL play here?

XBL has a resolve hook which needs to define a JS property on the "right" JS object.  The problem is how to figure out what the right JS object is.  The current solution is that we throw in any case when it's not obviously the object the resolve is happening on to start with.

> That's will happen in the case of JS object usage

You can't create resolve hooks from JS itself, so you can't get into this situation with pure JS Objects.
Alexander: Why do the -> arrows in comment 7 point to the right? If they represent prototype chain links, shouldn't they point to the left?

Native or "host" objects may not be able to make their magic properties work on plain old JS objects. We could hunt up the prototype chain for the first DOM node or whatever, but that kind of DWIM is often wrong, and a bit scary.

Please try to avoid __proto__, it's not being standardized and we should strive to make it unnecessary.

This is so WONTFIX, IMHO.

/be
Since brendan agrees.... wontfix.
Status: NEW → RESOLVED
Closed: 16 years ago
Resolution: --- → WONTFIX
Alexander: please do mail the dev-tech-xbl@lists.mozilla.org list or its newsgroup mirror about cases where you can't get what you want done without trying __proto__ tricks. Thanks,

/be
Brendan, my case comes from XForms. Some details:

1) we have base XBL binding for XForms widget (like  http://lxr.mozilla.org/mozilla/source/extensions/xforms/resources/content/range.xml#61)
2) we have inherited XBL bindings which are implementation of XForms widget (like http://lxr.mozilla.org/mozilla/source/extensions/xforms/resources/content/range-xhtml.xml#52)
3) inherited XBL bindings contains presentation elements (like http://lxr.mozilla.org/mozilla/source/extensions/xforms/resources/content/range-xhtml.xml#57)
4) inherited XBL binding provides JS object to work with presentaiton elements, that JS object provides implements interface for all inherited XBL bindings (like http://lxr.mozilla.org/mozilla/source/extensions/xforms/resources/content/range-xhtml.xml#63) so that base XBL binding work with them in the same way (like http://lxr.mozilla.org/mozilla/source/extensions/xforms/resources/content/range.xml#75).
5) Our JS object often is inherited from presentation element (like http://lxr.mozilla.org/mozilla/source/extensions/xforms/resources/content/range-xhtml.xml#66) because presentation element and JS object may have similar interface.

We aren't forced to inherit JS Object from underlying presentation element but it saves some code lines. If the right way not to use __proto__ then we could stop to do this and add properties/methods to JS object explicitly. Is it the way we should follow to? Should I file this to newsgroup?
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: