Hi James,
I'm trying to understand waypoint by going through your code. I must say
it is not self explanatory so let me try to explain it my own words so
you can correct it.
1) If the immediate parent is already a waypoint exit
2) If parent is canvas exit
3) Waypoint creates a "name registry" to first of it's ancestors
(excluding parent) to which applies:
- It already is a "name registry"
- it has id attribute defined
- it's nodeLeve == 0 (= canvas)
To this "name registry" it adds the mapping
"named attribute value" --> parent
4) It also creates a "name registry" to it's parent and to this registry
it only creates mapping
"parent" --> reference to the ancestor mentioned in the previous point
So applying these steps to your example it would seem that the first
waypoint tag creates the "name registry" to the parent of the class foo
instead to the root node of class foo.
So there must be some mistake in my understanding.
<class name="foo">
<waypoint/>
<handler name="oninit">
Debug.write("this._.one", this._.one);
</handler>
<view>
<view>
<view>
<waypoint named="one"/>
</view>
</view>
</view>
</class>
jamesr wrote:
Welll, after receiving the excellent news that Henry will be
promoting mixins to a first class laszlo construct, wherein after
completion i'll be able to rewrite and share the enabling concepts i
currently have in the officially sanctioned format. I'm loving that,
however, since I have to wait a week or so before mixins can support
what i currently do without them, rather then waiting i would like to
start discussing the mixins i will offer, one by one, and hopefully
have a nice discussion about why, when, and how to use these new
techniques while not presenting too much info at once.
In that spirit, here are a list of the most important traits (mixins)
i'll be introducing; some of the names might change before the official
release:
waypoint
interesting
interested
multiclickable
dragmatchable
registerDropzone
dropable
moveble
resizeable
verticallysizeable
frontmost
hindmost
openable
selectable
upperShadow
shadowed
Some of these are truly new areas of study, while some (like, say,
selectable) are more obvious exercises and I expect to add many more
traits for UI paradigms. I've not scratched the surface of useful traits
and what you see was more or less what was required of me by contract work.
For our first discussion, i'd like to introduce something special,
waypoints.
Waypoints are a major new approach to navigating deeply nested
hierarchies and it is both a good example of a mixin while and adds a
feature that i think many will come to use every day and in every
project. It removes the nesscessity to have typical
"parent.parent.parent" calls and allows a programmer to refactor code
for appearance and containment without damaging references, as would be
the case, for instance, if a new view was wrapped around an existing
view, which either requires using an ID, or altering every reference in
the program with every change, resulting in "brittle" code. No longer.
Below is a complete code listing of the waypoint trait as-it-exists,
preceded by a short but complete example. it's not a big piece of code,
just a very powerful piece, as you'll see. I'll be happy to answer all
questions anyone has about it - which will also help me to see how much
the community in general understands the approach. I developed this
class over two years ago, and i would absolutely *refuse* to develop
without it now, but this is it's first public release. Although it might
take time to fully understand the ramifications this class brings to the
laszlo world it is very worth it. Enjoy!
Waypoint code listing:
<!-- Author: James Robey, [email protected]. Licensed under the
MPL .
see http://code.google.com/p/viewablegroup for more.
Waypoints:
A very useful namespace mechanism. The waypoint class allows for
"deep" navigation
of nested namespaces by causing an entry specified by the
"named" attribute
to be added to the first waypoint encoutered above it. A
waypoint will attach itself
to the first valid recipientm which is the canvas, a node with
an ID, or another waypoint anointed node.
Example:
<class name="foo">
<waypoint/>
<handler name="oninit">
Debug.write("this._.one", this._.one);
</handler>
<view>
<view>
<view>
<waypoint named="one"/>
</view>
</view>
</view>
</class>
-->
<class name="waypoint" extends="node" initstage="early">
<!-- if this attribute is specified, then a waypoint by this name
will be added to the waypoint parent -->
<attribute name="named" type="string"/>
<!-- at construct time, determine the waypoint parent and add
references, as/if needed -->
<method name="construct" args="p, a">
<![CDATA[
super.construct(p, a);
//retrieve values from the tag
var named = a['named'];
var np = p.parent;
//is this object already a way point? do no
more.
if(!p['_'])
p['_'] = new Object;
else return;
//we need do no more for the canvas element
if(p == canvas)
return;
//find out which node will receive the
new waypoint
while(1){
//have we found a potential parent
waypoint? We either find it above or use the topmost node.
if((np['_'] || np['id'] || np.nodeLevel == 0)){
//initialize space ('_') to
hold waypoints if this is a new waypoint parent.
if(np['_'] == undefined) np._ = {};
//if no name given make a name based on the
number of other nameless waypoints
//otherwise ensure the name doesn't overwrite
anything in the target waypoint space.
if(!named){
// if __waypointCount is not defined
initialize it to zero, otherwise increment
np.__waypointcount = np['__waypointcount'] !=
undefined ? np.__waypointcount + 1 :
0;
// and use value that to generate a unique name
named = "unnammed_waypoint"+np.__waypointcount;
}else if(np._[named] !=
undefined){
Debug.warn('waypoint overwritten:', np,
'name', named);
}
//Add this node to a waypoint parent, add the
waypoint to this node ("parent"), then break
np._[named] = p;
//record the parent
waypoint to this tag
p._.parent = np;
break;
}
//...or just keep looking up the tree until we find a
good target.
np = np.parent;
}
//we don't need the this anymore, it's done
it's job (cyclic GC? investigate)
]]>
</method>
</class>
what do you think? Thanks for reading,
Sincerely, James