On 2009-11-25, at 08:33, Rami Ojares / AMG Oy wrote:
>
> > I think the documentation on makeChild is more accurate.
>
> Unfortunately makeChild is marked as private and thus is not part of the
> documentation.
I agree. I wasn't clear: the documentation from makeChild should be on
createChildren (or at least copied there). This should be filed as a bug.
> > createChildren is really just a hook to allow a subclass to change where
> > and when it actually makes its children.
>
> I have done a splitpane that automatically creates a divider for each pane.
> Fairly normal and straightforward use case. So I think createChildren is a
> very powerful place for overrides and strongly suggest it is kept as part of
> the official api.
Agree.
> > c.name is still valid, it is used to make a child be of the class that
> > implements a particular tag
>
> I don't think so.
>
> Code: (slightly modified from previous mail):
> -----
> <canvas debug="true">
> <view >
> <method name="createChildren" args="children"><![CDATA[
> for(var i=0; i<children.length; i++) {
> Debug.inspect(children[i]);
> }
> ]]></method>
> <view height="${canvas.height}"/>
> <view/>
> </view>
> </canvas>
>
> Output:
> -------
> «Object#0» {
> attrs: {…, height: $always{canvas.height}}
> class: <anonymous view>
> }
> «Object#4» {
> attrs: {…}
> class: <view>
> }
I guess I wasn't clear. `name` is still permitted and will be recognized and
it is the easiest way for script to instantiate a particular tag. The compiler
makes an optimization:
{name: 'view', attrs: ...} => {class: lz['view'], attrs: ...}
That is, when the compiler knows that `name` is a constant, and it knows the
class that implements that tag, it evaluates the lookup of the tag in `lz` at
compile time and inserts the class.
> > c.class is an optimization, used by the compiler to:
> > 1) Avoid having to look up the name
> > 2) Instantiate 'instance classes'
>
> Is there any other way for me (or the compiler) to recognize tags/classes
> from each other? Because if not then the word "optimization" is incorrect.
For any tag foo, the class that implements that tag is lz['foo'].
In script, if you want to know if a node is an instance of a particular tag
(say you want to know if it is a <foo>) you would say:
if (mynode is lz['foo']) ...
> > The tagname in this case, is just for debugging. If you were to look > at
> > the non-debug version, you would see the tagname is not emitted.
>
> What do you mean with "non-debug" version?
> It is clear to me that if there is no debug window then I will not see the
> debug messages :-)
If you could (e.g., using a browser debugger in DHTML, or using fdb in SWF10),
you would see that there is no `tagname` property on classes when debugging is
off. Hence, you should not rely on that in production code.
> > That's how it is supposed to be.
>
> So can I now rely on the tagname of my Pane tag to be either "Pane" or
> "anonymous Pane" ?
If you are trying to detect instances of <Pane> (even anonymous ones, which
would be subclasses), the recommended approach would be to use the `is`
operator as above. But I see where your problem lies, you are trying to sort
the child "specifications" before they have been instantiated. To be totally
accurate, that means you would have to look for `name` _or_ `class`, and that
you would need to know if the tag or class is a subclass of the tag's class you
are sorting on.
Something like:
function isPane(c) {
if (c.name) {
var childClass = lz[c.name];
} else {
var childClass = c.class;
}
return lz['Pane'].prototype.isPrototypeOf(childClass.prototype);
}
[That last line is pretty obscure, we should probably offer a built-in
`extends` or `isSubclassOf` predicate.]
> > Before, we never emitted a tagname for "instance classes".
>
> So was the
> - child['class'].tagname
> previously in my example case "undefined" or "Pane" (It must have been "Pane"
> because otherwise my SplitPane would not have worked previously.)
I see. Well, we had to introduce the class option because of the swf9/10
runtime, which forced us to create the anonymous classes. Hopfully the above
code will help.