[Laszlo-checkins] r12229 - in openlaszlo/trunk: WEB-INF/lps/lfc/core WEB-INF/lps/lfc/helpers lps/components/utils/replicator test/explicit-replicators
bargull@openlaszlo.org
bargull at openlaszlo.org
Wed Dec 24 09:38:37 PST 2008
Author: bargull
Date: 2008-12-24 09:38:14 -0800 (Wed, 24 Dec 2008)
New Revision: 12229
Modified:
openlaszlo/trunk/WEB-INF/lps/lfc/core/LzNode.lzs
openlaszlo/trunk/WEB-INF/lps/lfc/helpers/LzDataSelectionManager.lzs
openlaszlo/trunk/lps/components/utils/replicator/lazyreplicator.lzx
openlaszlo/trunk/lps/components/utils/replicator/replicator.lzx
openlaszlo/trunk/test/explicit-replicators/selection.lzx
Log:
Change 20081215-bargull-Dyr by bargull at dell--p4--2-53 on 2008-12-15 23:52:19
in /home/Admin/src/svn/openlaszlo/trunk
for http://svn.openlaszlo.org/openlaszlo/trunk
Summary: (lazy)replicator don't work in swf9
New Features:
Bugs Fixed: LPP-4667, LPP-7487
Technical Reviewer: ptw
QA Reviewer: henry
Doc Reviewer: (pending)
Documentation:
Release Notes:
Details:
The explicit replicator didn't work, esp. lz.lazyreplicator had some major problems.
LzNode:
VerifyError: Error #1068: LzDatapath and * cannot be reconciled
Flash9 wanted to say it cannot cast objects, why ever this wasn't detected at compile time...
LzDataSelectionManager:
lz.replicator wants to be a fake LzReplicationManager, actually a mixin would be the right solution here..
replicator:
adjust getCloneForNode() to be compatible to lz.lazyreplicator
lazyreplicator:
update getCloneForNode() so it can be compiled for swf9
selection.lzx:
update testcase so it will work properly
Tests:
selection.lzx in swf8/swf9
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/core/LzNode.lzs
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/core/LzNode.lzs 2008-12-24 09:00:05 UTC (rev 12228)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/core/LzNode.lzs 2008-12-24 17:38:14 UTC (rev 12229)
@@ -1778,7 +1778,8 @@
*/
function $lzc$set_data (data:*) :void {
this.data = data;
- (this.datapath || new LzDatapath(this)).setPointer(data /*cast LzDataNodeMixin*/);
+ var dp:LzDatapath = this.datapath || new LzDatapath(this);
+ dp.setPointer(data /*cast LzDataNodeMixin*/);
if (this.ondata.ready) this.ondata.sendEvent(data);
}
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/helpers/LzDataSelectionManager.lzs
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/helpers/LzDataSelectionManager.lzs 2008-12-24 09:00:05 UTC (rev 12228)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/helpers/LzDataSelectionManager.lzs 2008-12-24 17:38:14 UTC (rev 12229)
@@ -84,7 +84,11 @@
static var attributes :Object = new LzInheritedHash(LzSelectionManager.attributes);
/** @access private */
- var manager :LzReplicationManager;
+ var manager :*;
+ // FIXME [20081215 anba] lz.replicator wants to be a fake
+ // replication-manager, so I cannot use the proper type here; we
+ // should add a mixin for lz.replicator and LzReplicationManager.
+ //var manager :LzReplicationManager;
/** @access private */
var singleClone :LzView;
Modified: openlaszlo/trunk/lps/components/utils/replicator/lazyreplicator.lzx
===================================================================
--- openlaszlo/trunk/lps/components/utils/replicator/lazyreplicator.lzx 2008-12-24 09:00:05 UTC (rev 12228)
+++ openlaszlo/trunk/lps/components/utils/replicator/lazyreplicator.lzx 2008-12-24 17:38:14 UTC (rev 12229)
@@ -16,7 +16,7 @@
<attribute name="__emptyArray" value="null"/>
<!-- @keywords private -->
<attribute name="clonedel" value="null"/>
-
+
<!-- @keywords private -->
<method name="construct" args="p,a">
<![CDATA[
@@ -35,52 +35,52 @@
p.layouts[l].lock();
}
}
-
-
+
+
this.__emptyArray = [];
this.clonedel = new LzDelegate( this, '__adjustVisibleClones');
]]>
</method>
-
+
<!-- @keywords private -->
<method name="init">
this.clonedel.register( this.mask , "on" + this._sizes[ this.axis ] );
this.clonedel.register( this.container , "on" + this.axis );
super.init();
</method>
-
+
<!-- @keywords private -->
<attribute name="_lastNodesLength" value="0"/>
-
+
<!-- @keywords private -->
- <method name="__adjustVisibleClones" args="ignore=null" >
+ <method name="__adjustVisibleClones" args="ignore=null">
<![CDATA[
if ( ! this.nodes ) {
while ( this.clones.length ) this.poolClone( this.clones.pop() );
return;
}
-
+
if ( !this.replicatedsize ) this._setSize();
-
+
var sizeAxis = this._sizes[ this.axis ];
if ( this.nodes.length != null ){
this._lastNodesLength = this.nodes.length;
}
var s = this._lastNodesLength * this.replicatedsize;
-
+
if ( this.container[ sizeAxis ] != s ){
//Debug.write( sizeAxis, s, this.container[ sizeAxis ] );
this.container.setAttribute( sizeAxis, s );
}
-
+
if (! this.mask) {
Debug.warn("%w: cannot find clipping parent", this);
return;
}
-
+
if (! this.mask[ "hasset" + sizeAxis ] )
return;
-
+
//Here's the idea. Coming in, we have an old list of clones that
//represents some window into the dataset. Let's say the nodes are
//labelled alphabetically so to start, we have
@@ -88,44 +88,44 @@
//When the situation changes, we end up with a situation where we
//want the window to be like
//this.clones=[ l , m , n , o ]
-
+
//This algorithm moves the old list of clones to a temporary
//identifier and then constructs a new array for the clones going
//through one by one It keeps an offset, which represents the
//difference in position of the old new data windows. In the case
//above, the offset would be -2.
-
+
var newstart = Math.floor( -this.container[ this.axis ] /
this.replicatedsize );
-
+
if ( 0 > newstart ) newstart = 0;
-
+
var oldptr = 0;
var oldlength = this.clones.length;
var offset = newstart - this.clonesoffset;
-
+
var remainder = ( newstart * this.replicatedsize ) +
this.container[ this.axis ];
-
+
var newlength= Math.ceil(
Math.min( (this.mask[ sizeAxis ] - remainder )/this.replicatedsize ,
this.container[ sizeAxis ] /this.replicatedsize ) );
-
+
//newstart is the new absolute lowerbound of the data window
//newlength is the new length of the data window
if ( newlength + newstart > this.nodes.length ) {
newlength = this.nodes.length - newstart;
}
-
+
//no change
if ( offset == 0 && newlength == oldlength ) return;
-
+
//_root.lz.Instantiator.enableDataReplicationQueuing( );
var oldclones = this.clones;
//TODO: instead of allocating a new array, use two arrays and
//ping-pong
this.clones = this.__emptyArray;
-
+
for ( var i = 0 ; i < newlength; i++ ){
//before the new beginning
var cl = null;
@@ -146,7 +146,7 @@
cl = this.getClone();
}
}
-
+
if ( cl ){
this.clones[ i ] = cl;
var val = ( i + newstart ) * this.replicatedsize ;
@@ -158,31 +158,31 @@
this.clones[ i ] = oldclones[ i + offset ];
}
}
-
+
while ( oldptr < offset && oldptr < oldlength ){
var v = oldclones[ oldptr++ ];
this.poolClone( v );
}
-
+
while ( oldlength > newlength + offset && oldlength > 0 ){
var v = oldclones[ --oldlength ];
this.poolClone( v );
}
-
+
this.clonesoffset = newstart;
-
+
while ( oldclones.length ) oldclones.pop();
this.__emptyArray = oldclones;
-
+
//_root.lz.Instantiator.clearDataReplicationQueue( );
]]>
</method>
-
+
<!-- @keywords private -->
<method name="createChildren" args="c">
<![CDATA[
this.replicated = c.pop();
-
+
// TODO [hqm 2007 09] I need to set ignorelayout option before
// the clone gets instantiated, otherwise it might get placed
// by the parent layout during construction, which we don't
@@ -194,16 +194,16 @@
attrs = {};
this.replicated.attrs = attrs;
}
-
+
if ('options' in attrs) {
attrs.options.ignorelayout = true;
} else {
attrs.options = {ignorelayout: true};
}
-
+
//Debug.write( 'replicated', replicated );
if ( c.length ) {
- Debug.warn("%s: only a single child view is replicated", this);
+ if ($debug) Debug.warn("%s: only a single child view is replicated", this);
this.container.createChildren( c );
} else {
this.__LZinstantiationDone();
@@ -218,14 +218,14 @@
cl.setOption( 'ignorelayout', true );
return cl;
</method>
-
+
<!-- @keywords private -->
<method name="_setSize">
var c = this.getClone();
this.setAttribute( "replicatedsize", c[ this._sizes[ this.axis ] ] );
this.poolClone( c );
</method>
-
+
<!-- @keywords private -->
<method name="getCloneIfVisible" args="n">
<![CDATA[
@@ -234,15 +234,15 @@
else return null;
]]>
</method>
-
+
<!-- @keywords private -->
- <method name="getCloneForOffset" args="override">
+ <method name="getCloneForOffset" args="n">
this.ensureInView( n );
return this.clones[ n-this.clonesoffset];
</method>
-
+
<!-- @keywords private -->
- <method name="getCloneForNode" args="datanode,dontmake">
+ <method name="getCloneForNode" args="datanode,dontmake = false">
<![CDATA[
var cl = super.getCloneForNode( datanode ) ||
null;
@@ -252,19 +252,19 @@
cl = this.getClone();
this.setData( cl, datanode );
this.update( cl, datanode );
- if (v.datapath['sel'] != datanode['sel']) {
- v.datapath['sel'] = datanode['sel'] || false;
- v.setSelected(v.datapath['sel']);
+ if (cl.datapath['sel'] != datanode['sel']) {
+ cl.datapath['sel'] = datanode['sel'] || false;
+ cl.setSelected(cl.datapath['sel']);
}
if (cl['applyData']) cl.applyData( datanode );
this.poolClone( cl );
}
-
+
//cl.setOption( 'ignorelayout', true );
return cl;
]]>
</method>
-
+
<method name="destroy">
<![CDATA[
var p = this.container;
@@ -273,7 +273,7 @@
p.layouts[l].unlock();
}
}
- super.destroy.apply(this, arguments);
+ super.destroy();
]]>
</method>
</class>
Modified: openlaszlo/trunk/lps/components/utils/replicator/replicator.lzx
===================================================================
--- openlaszlo/trunk/lps/components/utils/replicator/replicator.lzx 2008-12-24 09:00:05 UTC (rev 12228)
+++ openlaszlo/trunk/lps/components/utils/replicator/replicator.lzx 2008-12-24 17:38:14 UTC (rev 12229)
@@ -17,22 +17,22 @@
<!--- The size (width or height) in the replication axis of the view
being replicated. Assumes all subviews have same replicated size. -->
<attribute name="replicatedsize" value="null" />
-
+
<!--- The axis in which to replicate-->
<attribute name="axis" value="y" type="string"/>
-
+
<!--- A pixel amount to use between each replicated view -->
<attribute name="spacing" value="0" />
-
+
<!--- The view that will contain the replicated nodes. Defaults to the immediateparent of the replicator. -->
<attribute name="container" />
<!--- The view that will clip the replicated nodes. Defaults to the immediateparent of the container -->
<attribute name="mask" />
-
+
<!--- The list of elements controlled by this repliator -->
<attribute name="clones" value="null"/>
-
+
<!--- The list of nodes over which this replictor acts -->
<attribute name="nodes" value="null" setter="this.setNodes(nodes)"/>
@@ -44,7 +44,7 @@
<attribute name="_sizes" value="{ x : 'width', y: 'height' }"/>
<attribute name="_cloneprops" value="null"/>
<attribute name="_clonepool" value="null"/>
-
+
<!-- @keywords private -->
<method name="construct" args="p,a">
this.clones = [];
@@ -54,7 +54,7 @@
this.container = this.immediateparent;
this.mask = this.container.immediateparent;
</method>
-
+
<!-- @keywords private -->
<method name="init">
<![CDATA[
@@ -66,14 +66,14 @@
}
]]>
</method>
-
+
<method name="destroy">
if (this['_ondatadel']) this._ondatadel.unregisterAll();
this._pointer = null;
this.dataset = null;
- super.destroy.apply(this, arguments);
+ super.destroy();
</method>
-
+
<!-- @keywords private -->
<method name="_updateChildren" args="ignore=null" >
<![CDATA[
@@ -83,29 +83,29 @@
this.setNodes(p);
]]>
</method>
-
+
<!-- @keywords private -->
<method name="createChildren" args="c">
<![CDATA[
super.createChildren( [] );
this.replicated = c[0];
-
+
if ( c.length > 1 ) {
- Debug.warn("%s: only a single child view is replicated", this);
+ if ($debug) Debug.warn("%s: only a single child view is replicated", this);
this.container.createChildren( c );
} else {
this.__LZinstantiationDone();
}
]]>
</method>
-
+
<event name="onnodes"/>
-
+
<!-- @keywords private -->
<method name="set_nodes" args="n">
this.setNodes(n);
</method>
-
+
<!-- Replicate over the given list of elements.
@param Array n: The list of elements over which to replicate -->
<method name="setNodes" args="n">
@@ -118,7 +118,7 @@
if (this.onnodes.ready) { this.onnodes.sendEvent(); }
]]>
</method>
-
+
<!-- Insert a node in existing list of elements.
@param Number idx: index to insert element
@param Object n: node to insert -->
@@ -127,7 +127,7 @@
this._cloneprops.splice(idx,0, undefined); // maintain cloneprops indices
this.__adjustVisibleClones();
</method>
-
+
<!-- Called internally, but may be overridden. This is the method
which binds a given clone to an element in the nodes array.
@param LzView v: the clone being bound
@@ -154,12 +154,12 @@
}
]]>
</method>
-
+
<!-- @keywords private -->
<method name="setCloneProperty" args="v,prop,val">
this.setClonePropertyByCN( v.clonenumber, prop ,val );
</method>
-
+
<!-- @keywords private -->
<method name="setClonePropertyByCN" args="n,prop,val">
if ( !this._cloneprops[ n ] ) this._cloneprops[ n ] = {};
@@ -167,12 +167,12 @@
var v = this.getCloneIfVisible( n );
if ( v ) v.setAttribute( prop , val );
</method>
-
+
<!-- @keywords private -->
<method name="update" args="v,n">
if ( v[ "update" ] ) v.update( v.data , n );
</method>
-
+
<!-- TODO: defaults for clone attributes
Called internally, but may be overridden. This method is called
when a given clone is about to be pooled or destroyed. -->
@@ -189,7 +189,7 @@
}
]]>
</method>
-
+
<!-- @keywords private -->
<method name="getClone">
var v;
@@ -201,7 +201,7 @@
}
return v;
</method>
-
+
<!-- @keywords private -->
<method name="_makeClone">
var v = this.container.makeChild( this.replicated );
@@ -210,31 +210,31 @@
v.setAttribute( "cloneManager", this );
return v;
</method>
-
+
<!-- @keywords private -->
<method name="poolClone" args="c">
if ( c.clonenumber ) this.unbind( c );
if (c.visible != false) c.setAttribute('visible', false );
this._clonepool.push( c );
</method>
-
+
<!-- @keywords private -->
<method name="getCloneIfVisible" args="n">
return this.clones[ n ];
</method>
-
+
<!-- Called internally, but may be overridden. This method is called
to set the data of a clone to an element in the nodes array.
@param LzView v: The clone whose data is being set.
@param n: The node to which it is being set. -->
- <method name="setData" args="v,n=null">
+ <method name="setData" args="v:*,n=null">
if (v) {
v.setAttribute('data', this.nodes[ n ]);
if (v['applyData']) v.applyData(this.nodes[n]);
}
</method>
-
+
<!-- @keywords private -->
<method name="__adjustVisibleClones" args="ignore=null" >
<![CDATA[
@@ -256,7 +256,7 @@
}
]]>
</method>
-
+
<!-- Gets the clone for the given offset, scrolling it into view first
if necessary.
@param Number n: The offset of the clone to get. -->
@@ -264,10 +264,10 @@
this.ensureInView( n );
return this.clones[ n ];
</method>
-
+
<!-- Gets the clone for the given datanode
@param LzDataNodeMixin datanode: The datanode of the clone to get -->
- <method name="getCloneForNode" args="datanode">
+ <method name="getCloneForNode" args="datanode,dontmake = false">
<![CDATA[
var l = this.clones.length;
for ( var i = 0; i < l; i++ ){
@@ -277,7 +277,7 @@
}
]]>
</method>
-
+
<!-- Ensures that the clone at the given offset is visible under the mask
@param Number n: The offset of the clone to scroll in view -->
<method name="ensureInView" args="n">
@@ -285,14 +285,14 @@
var y = this.container.y;
var pos = n*this.replicatedsize;
var ny = y;
-
+
if (typeof mask != 'undefined' && this.replicatedsize+pos >= this.mask.height - y) {
ny = this.mask.height - pos - this.replicatedsize;
} else if (pos < -y) ny = -pos;
-
+
if (y != ny) this.container.setAttribute('y', ny);
]]>
</method>
</class>
-
+
</library>
Modified: openlaszlo/trunk/test/explicit-replicators/selection.lzx
===================================================================
--- openlaszlo/trunk/test/explicit-replicators/selection.lzx 2008-12-24 09:00:05 UTC (rev 12228)
+++ openlaszlo/trunk/test/explicit-replicators/selection.lzx 2008-12-24 17:38:14 UTC (rev 12229)
@@ -1,4 +1,4 @@
-<!-- Copyright 2001-2007 Laszlo Systems, Inc. All Rights Reserved. -->
+<!-- Copyright 2001-2008 Laszlo Systems, Inc. All Rights Reserved. -->
<canvas debug="true" proxied="false">
<debug height="90%" width="40%" x="55%" y="5%" />
@@ -34,113 +34,84 @@
</fibs>
</dataset>
+ <!-- dataselectionmanagers cannot share datasets -->
+ <dataset name="testdata2" />
+ <dataset name="testdata3" />
+
+ <handler name="oninit" >
+ testdata2.setAttribute("childNodes", [testdata.getFirstChild().cloneNode(true)]);
+ testdata3.setAttribute("childNodes", [testdata.getFirstChild().cloneNode(true)]);
+ </handler>
+
<text multiline="true">
Compares selection behavior across replicators where the parent is a view (had problems with parent being a list.) Be sure to test range selection and scrolling at various speeds.
</text>
- <window width="20%" height="20%" x="5%" y="5%" name="explicitlazyrepltest"
+ <class name="textitem" extends="text" >
+ <attribute name="selected" value="false"/>
+ <attribute name="bgcolor"
+ value="${selected ? 0xCCDDEE : null }"/>
+ <attribute name="index" value="$path{'position()'}" />
+ <attribute name="value" value="$path{'@value'}" />
+ <!-- for explicit replication -->
+ <method name="applyData" args="d">
+ this.show();
+ </method>
+ <!-- for implicit replication -->
+ <handler name="ondata" method="show" />
+
+ <method name="show" args="v=null" >
+ this.format('%s: %d', this.index, this.value);
+ </method>
+ <handler name="onclick">
+ parent.selman.select( this );
+ </handler>
+ <method name="setSelected" args="value" override="true">
+ this.selected = value;
+ this.onselected.sendEvent(value);
+ </method>
+ </class>
+
+ <window width="20%" height="20%" x="5%" y="5%"
resizable="true" title="explicit lazy replicator">
<view>
<dataselectionmanager name="selman" id="dsel"/>
- <lazyreplicator id="elr" dataset="testdata" xpath="fibs/fib">
- <text width="100">
- <attribute name="selected" value="false"/>
- <attribute name="bgcolor"
- value="${selected ? 0xCCDDEE : null }"/>
- <attribute name="index" value="$path{'position()'}" />
- <attribute name="value" value="$path{'@value'}" />
- <method name="applyData">
- this.format('%s: %d', this.index, this.value);
- </method>
- <handler name="onclick">
- //Debug.write(parent.selman.isSelected( this ), parent.selman.toggle);
- parent.selman.select( this );
- </handler>
- <method name="setSelected" args="value">
- this.selected = value;
- this.onselected.sendEvent(value);
- </method>
- </text>
+ <lazyreplicator id="elr" dataset="testdata2" xpath="fibs/fib">
+ <textitem width="100" />
</lazyreplicator>
</view>
<scrollbar/>
</window>
- <window width="20%" height="20%" x="30%" y="5%" name="implicitlazyrepltest"
+ <window width="20%" height="20%" x="30%" y="5%"
resizable="true" title="implicit lazy replicator">
<view>
<dataselectionmanager name="selman" id="dsel2"/>
- <text width="100" id="ilr">
- <datapath xpath="testdata:/fibs/fib" replication="lazy" />
- <attribute name="selected" value="false"/>
- <attribute name="bgcolor"
- value="${('selected' in this && this.selected) ? 0xCCDDEE : null }"/>
- <attribute name="index" value="$path{'position()'}" />
- <attribute name="value" value="$path{'@value'}" />
- <handler name="ondata">
- this.format('%s: %d', this.index, this.value);
- </handler>
- <handler name="onclick">
- //Debug.write(parent.selman.isSelected( this ), parent.selman.toggle);
- parent.selman.select( this );
- </handler>
- <method name="setSelected" args="value">
- this.selected = value;
- this.onselected.sendEvent(value);
- </method>
- </text>
+ <textitem width="100" >
+ <datapath xpath="testdata3:/fibs/fib" replication="lazy" />
+ </textitem>
</view>
<scrollbar/>
</window>
- <window width="20%" height="20%" x="5%" y="50%" name="explicitsimplerepltest"
+ <window width="20%" height="20%" x="5%" y="50%"
resizable="true" title="explicit replicator">
<view>
<selectionmanager name="selman" />
<simplelayout axis="y" spacing="0" />
<replicator id="esr" dataset="testdata" xpath="/fibs/fib">
- <text width="100">
- <attribute name="selected" value="false"/>
- <attribute name="bgcolor"
- value="${selected ? 0xCCDDEE : null }"/>
- <attribute name="index" value="$path{'position()'}" />
- <attribute name="value" value="$path{'@value'}" />
- <method name="applyData">
- this.format('%s: %d', this.index, this.value);
- </method>
- <handler name="onclick">
- //Debug.write(parent.selman.isSelected( this ), parent.selman.toggle);
- parent.selman.select( this );
- </handler>
- </text>
+ <textitem width="100" />
</replicator>
</view>
<scrollbar/>
</window>
- <window width="20%" height="20%" x="30%" y="50%" name="implicitsimplerepltest"
+ <window width="20%" height="20%" x="30%" y="50%"
resizable="true" title="implicit replicator">
<view>
<selectionmanager name="selman" />
<simplelayout axis="y" spacing="0" />
- <text width="100" id="isr" datapath="testdata:/fibs/fib">
- <attribute name="selected" value="false" setter="setSelected" />
- <attribute name="bgcolor"
- value="${('selected' in this && this.selected) ? 0xCCDDEE : null }"/>
- <attribute name="index" value="$path{'position()'}" />
- <attribute name="value" value="$path{'@value'}" />
- <handler name="ondata">
- this.format('%s: %d', this.index, this.value);
- </handler>
- <handler name="onclick">
- //Debug.write(parent.selman.isSelected( this ), parent.selman.toggle);
- parent.selman.select( this );
- </handler>
- <method name="setSelected" args="value">
- this.selected = value;
- this.onselected.sendEvent(value);
- </method>
- </text>
+ <textitem width="100" datapath="testdata:/fibs/fib" />
</view>
<scrollbar/>
</window>
More information about the Laszlo-checkins
mailing list