[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