[Laszlo-checkins] r13927 - openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf9

bargull@openlaszlo.org bargull at openlaszlo.org
Sat May 16 01:04:17 PDT 2009


Author: bargull
Date: 2009-05-16 01:04:14 -0700 (Sat, 16 May 2009)
New Revision: 13927

Modified:
   openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf9/LzXMLTranslator.as
Log:
Change 20090516-bargull-NOm by bargull at dell--p4--2-53 on 2009-05-16 00:21:34
    in /home/Admin/src/svn/openlaszlo/trunk
    for http://svn.openlaszlo.org/openlaszlo/trunk

Summary: copy native xml-tree iteratively (SWF9)

New Features:

Bugs Fixed: LPP-8067 (Improve data performance) (SWF9) 

Technical Reviewer: henry
QA Reviewer: (pending)
Doc Reviewer: (pending)

Documentation:

Release Notes:

Details:
Remove recursion in copyFlashXML() when traversing the DOM tree. 
This is similar to the changes for the DHTML and SWF8 kernel. 

    

Tests:
smokecheck, alldata in swf9



Modified: openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf9/LzXMLTranslator.as
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf9/LzXMLTranslator.as	2009-05-16 08:00:08 UTC (rev 13926)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/kernel/swf9/LzXMLTranslator.as	2009-05-16 08:04:14 UTC (rev 13927)
@@ -13,121 +13,139 @@
   */
 public class LzXMLTranslator {
 
-static function copyXML (xmlobj:XML, trimwhitespace:Boolean, nsprefix:Boolean) :LzDataElement {
-    var lfcnode:LzDataNodeMixin = copyFlashXML(xmlobj, trimwhitespace, nsprefix);
-    if (lfcnode == null) {
-        trace('LzXMLTranslator.copyXML: lfcnode.children is null', lfcnode);
+    /**
+      * LzXMLTranslator interface
+      */
+    static function copyXML (xmlobj:XML, trimwhitespace:Boolean, nsprefix:Boolean) :LzDataElement {
+        var lfcnode:LzDataNodeMixin = copyFlashXML(xmlobj, trimwhitespace, nsprefix);
+        return (lfcnode cast LzDataElement);
     }
-    
-    if (lfcnode is LzDataText) {
-        return null;
-    }
-    // create a new, empty ownerDocument (LPP-7537)
-    new LzDataElement(null, {}, [lfcnode]);
-    return (lfcnode cast LzDataElement);
-}
 
-
-static const whitespaceChars :Object = {' ': true, '\r': true, '\n': true, '\t': true};
-
-
-/**
-  * trim whitespace from start and end of string
-  * @access private
-  */
-static function trim (str:String) :String {
-    var whitech:Object = whitespaceChars;
-    var len:int = str.length;
-    var sindex:int = 0;
-    var eindex:int = str.length -1;
-    var ch:String;
-    while (sindex < len) {
-        ch = str.charAt(sindex);
-        if (whitech[ch] != true) break;
-        sindex++;
+    private static function nextSibling (node:XML) :XML {
+        var p:XML = node.parent();
+        return p ? p.children()[node.childIndex() + 1] : null;
     }
 
-    while (eindex > sindex) {
-        ch = str.charAt(eindex);
-        if (whitech[ch] != true) break;
-        eindex--;
+    private static function firstChild (node:XML) :XML {
+        return node.children()[0];
     }
-        
-    return str.slice(sindex,eindex+1);
-}
 
-
-// Recursively copy a Flash XML(Node) tree into a LzDataElement
-// tree. Used by LzDataNode.stringToLzData
-/**
-  * @param boolean trimwhitespace: trim whitespace from start and end of text nodes
-  * @param boolean nsprefix: preserve namespace prefixes on node names and attribute names
-  * @access private
-  */
-static function copyFlashXML (node:XML, trimwhitespace:Boolean, nsprefix:Boolean) :LzDataNodeMixin {
-    var lfcnode:LzDataNodeMixin = null;
-    // text node?
-    if (node.nodeKind() == 'text') {
-        var nv:String = node.toString();
-        if (trimwhitespace == true) {
-            nv = trim(nv);
-        }
-        lfcnode = new LzDataText(nv);
-//PBR Changed to match swf kernel
-//    } else if (node.nodeKind() == 'element') {
-      } else {
-        
-        var nattrs:XMLList = node.attributes();
-        var cattrs:Object = {};
-        for (var i:int = 0; i < nattrs.length(); i++) {
-            var attr:XML = nattrs[i];
-            var qattr:QName = attr.name();
+    /**
+      * Translate a single Flash XML(Node) into a LzDataNode.
+      */
+    static function copyFlashNode (node:XML, trimwhitespace:Boolean, nsprefix:Boolean) :LzDataNodeMixin {
+        var kind:String = node.nodeKind();
+        if (kind == 'text') {
+            var nv:String = node.toString();
+            if (trimwhitespace) {
+                nv = LzDataElement.trim(nv);
+            }
+            return new LzDataText(nv);
+        } else if (kind == 'element') {
+            var nname:String;
+            var qname:QName = node.name();
             if (nsprefix) {
-                var ns:Namespace = attr.namespace();
-                var key:String;
+                var ns:Namespace = node.namespace();
                 if (ns != null && ns.prefix != "") {
-                    key = ns.prefix + ":" + qattr.localName;
+                    nname = ns.prefix + ":" + qname.localName;
                 } else {
-                    key = qattr.localName;
+                    nname = qname.localName;
                 }
-                cattrs[key] = attr.toString();
             } else {
-                cattrs[qattr.localName] = attr.toString();
+                nname = qname.localName;
             }
-        }
 
-        var nsDecl:Array = node.namespaceDeclarations();
-        for (var i:int = 0; i < nsDecl.length; ++i) {
-            var ns:Namespace = nsDecl[i];
-            var prefix:String = ns.prefix;
-            var key:String = (prefix == "" ? "xmlns" : nsprefix ? "xmlns:" + prefix : prefix);
-            cattrs[key] = ns.uri;
-        }
+            var nattrs:XMLList = node.attributes();
+            var cattrs:Object = {};
+            for (var i:int = 0, len:int = nattrs.length(); i < len; i++) {
+                var attr:XML = nattrs[i];
+                var qattr:QName = attr.name();
+                if (nsprefix) {
+                    var ns:Namespace = attr.namespace();
+                    var key:String;
+                    if (ns != null && ns.prefix != "") {
+                        key = ns.prefix + ":" + qattr.localName;
+                    } else {
+                        key = qattr.localName;
+                    }
+                    cattrs[key] = attr.toString();
+                } else {
+                    cattrs[qattr.localName] = attr.toString();
+                }
+            }
 
-        var nname:String;
-        var qname:QName = node.name();
-        if (nsprefix) {
-            var ns:Namespace = node.namespace();
-            if (ns != null && ns.prefix != "") {
-                nname = ns.prefix + ":" + qname.localName;
-            } else {
-                nname = qname.localName;
+            var nsDecl:Array = node.namespaceDeclarations();
+            for (var i:int = 0, len:int = nsDecl.length; i < len; ++i) {
+                var ns:Namespace = nsDecl[i];
+                var prefix:String = ns.prefix;
+                var key:String = (prefix == "" ? "xmlns" : nsprefix ? "xmlns:" + prefix : prefix);
+                cattrs[key] = ns.uri;
             }
+
+            var lfcnode:LzDataElement = new LzDataElement(nname);
+            // avoid copy of cattrs (see LzDataElement ctor)
+            lfcnode.attributes = cattrs;
+            return lfcnode;
         } else {
-            nname = qname.localName;
+            return null;
         }
+    }
 
-        lfcnode = new LzDataElement(nname, cattrs);
-        var children:XMLList = node.children();
-        var newchildren:Array = [];
-        for (var i:int  = 0; i < children.length(); i++) {
-            var child:XML = children[i];
-            var lfcchild:LzDataNodeMixin = copyFlashXML(child, trimwhitespace, nsprefix);
-            newchildren[i] = lfcchild;
+    /**
+      * Copy a Flash XML(Node) tree into a LzDataElement tree. Used by LzDataElement.stringToLzData
+      *
+      * @param boolean trimwhitespace: trim whitespace from start and end of text nodes
+      * @param boolean nsprefix: preserve namespace prefixes on node names and attribute names
+      * @access private
+      */
+    static function copyFlashXML (xmlnode:XML, trimwhitespace:Boolean, nsprefix:Boolean) :LzDataNodeMixin {
+        // create a new, empty ownerDocument (LPP-7537)
+        var document:LzDataElement = new LzDataElement(null);
+        // handle this separately so you don't need to worry about the
+        // case when xmlnode has got siblings
+        if (! firstChild(xmlnode)) {
+            return document.appendChild(copyFlashNode(xmlnode, trimwhitespace, nsprefix));
         }
-        (lfcnode cast LzDataElement).$lzc$set_childNodes(newchildren);
+        var lfcparent:LzDataElement = document;
+        var next:XML, node:XML = xmlnode;
+        // traverse DOM tree
+        for (;;) {
+            var kind:String = node.nodeKind();
+            if (kind == 'text') {
+                var lfctext:LzDataText = LzDataText(copyFlashNode(node, trimwhitespace, nsprefix));
+                // inlined lfcparent.appendChild(lfcnode)
+                lfctext.parentNode = lfcparent;
+                lfctext.ownerDocument = document;
+                lfctext.__LZo = (lfcparent.childNodes.push(lfctext) - 1);
+            } else if (kind == 'element') {
+                var lfcnode:LzDataElement = LzDataElement(copyFlashNode(node, trimwhitespace, nsprefix));
+                // inlined lfcparent.appendChild(lfcnode)
+                lfcnode.parentNode = lfcparent;
+                lfcnode.ownerDocument = document;
+                lfcnode.__LZo = (lfcparent.childNodes.push(lfcnode) - 1);
+
+                // traverse down first
+                if ((next = firstChild(node))) {
+                    // this node is the new context
+                    lfcparent = lfcnode;
+                    node = next;
+                    continue;
+                }
+            }
+            // select next node
+            while (! (next = nextSibling(node))) {
+                // no nextSibling, go back in DOM
+                node = node.parent();
+                lfcparent = lfcparent.parentNode;
+                if (node === xmlnode) {
+                    // reached top element, copy finished
+                    return document.childNodes[0];
+                }
+            }
+            node = next;
+        }
+        // add return to make flash compiler happy
+        return null;
     }
-    return lfcnode;
-}
 
 } // End of LzXMLTranslator



More information about the Laszlo-checkins mailing list