[Laszlo-checkins] r8515 - in openlaszlo/trunk: WEB-INF/lps/lfc/compiler WEB-INF/lps/lfc/core WEB-INF/lps/lfc/data WEB-INF/lps/lfc/views WEB-INF/lps/server/src/org/openlaszlo/compiler lps/components/base
ptw@openlaszlo.org
ptw at openlaszlo.org
Tue Apr 1 19:37:21 PDT 2008
Author: ptw
Date: 2008-04-01 19:37:15 -0700 (Tue, 01 Apr 2008)
New Revision: 8515
Modified:
openlaszlo/trunk/WEB-INF/lps/lfc/compiler/LzRuntime.lzs
openlaszlo/trunk/WEB-INF/lps/lfc/core/LzNode.lzs
openlaszlo/trunk/WEB-INF/lps/lfc/data/LzReplicationManager.lzs
openlaszlo/trunk/WEB-INF/lps/lfc/views/LaszloCanvas.lzs
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassCompiler.java
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassModel.java
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/NodeModel.java
openlaszlo/trunk/lps/components/base/basecomponent.lzx
Log:
Change 20080401-ptw-A by ptw at dueling-banjos.local on 2008-04-01 16:15:19 EDT
in /Users/ptw/OpenLaszlo/ringding-clean
for http://svn.openlaszlo.org/openlaszlo/trunk
Summary: Compile instances with methods as classes
Bugs Fixed:
LPP-5625 'Implement instances with methods as singleton classes'
Technical Reviewer: hqm (Message-ID: <8c61fad60804011441l41dae5ceucdbadfeb02b8b74b at mail.gmail.com>)
QA Reviewer: dda (Message-Id: <A3A3C1CC-2BFE-488A-858B-3DCA6BD2CF7D at ddanderson.com>)
Details:
LzNode, NodeModel: Move $classrootdepth computation to compile-time.
LzNode, LaszloCanvas, LzReplicationManager: Take care that
_instanceAttrs may be null
LzRuntime: Don't clobber global in swf9
ClassCompiler, ClassModel: Move emitClassDeclaration to ClassModel
NodeModel: Leave id as an attribute, declare named children as
attributes so they can be resolved. Predicate for nodes that have
methods. Compile nodes with methods as singleton classes.
basecomponent: Make the optional argument optional
Tests:
smokecheck, lztest, Henry's checkbox test compiles
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/compiler/LzRuntime.lzs
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/compiler/LzRuntime.lzs 2008-04-02 00:40:03 UTC (rev 8514)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/compiler/LzRuntime.lzs 2008-04-02 02:37:15 UTC (rev 8515)
@@ -25,7 +25,11 @@
/**
* Define runtime module
*/
+if ($swf9) {
+$modules.runtime = global;
+} else {
$modules.runtime = this;
+}
/**
* Define LZ module
@@ -45,7 +49,10 @@
* Define global
* TODO [2006-03-12 ptw] if the LFC is shared this needs to be multiplexed
*/
+if ($swf9) {
+} else {
var global = $modules.user;
+}
if ($debug) {
/**
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/core/LzNode.lzs
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/core/LzNode.lzs 2008-04-02 00:40:03 UTC (rev 8514)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/core/LzNode.lzs 2008-04-02 02:37:15 UTC (rev 8515)
@@ -262,15 +262,6 @@
var classChildren = this['constructor']['children'];
if ( classChildren is Array ){
- // classroot will not be defined for members of a state
- // class, this is hard because the classroot is not a
- // parent of its lexical children
- // TODO: [2008-03-11 ptw] This should be computed at
- // compile time
- if (!classChildren['doneClassRoot'] && ! this.$isstate) {
- classChildren.doneClassRoot=true;
- this.__LZassignClassRoot(classChildren, 1);
- }
children = LzNode.mergeChildren(children, classChildren);
}
@@ -1543,10 +1534,12 @@
* constraint from
*/
function releaseConstraint(attr:String) {
- var c = this._instanceAttrs[attr];
- if (c instanceof LzConstraintExpr) {
- var m = c.methodName;
- return this.releaseConstraintMethod(m);
+ if (this._instanceAttrs != null) {
+ var c = this._instanceAttrs[attr];
+ if (c instanceof LzConstraintExpr) {
+ var m = c.methodName;
+ return this.releaseConstraintMethod(m);
+ }
}
return false;
}
@@ -2154,31 +2147,6 @@
//+++++ Wacky class stuff
-
-/**
- * called when the first instance of the class is instantiated
- * must be called only once for each class
- * @param arr: classChildren
- * @param depth: call with depth=1 (recursive function)
- * @access private
- */
-function __LZassignClassRoot( arr , depth){
- if (arr != null) {
- var l = arr.length;
- for ( var i = 0; i < l ; i++ ){
- arr[ i ].attrs.$classrootdepth = depth;
- var a = ('children' in arr[i]) ? arr[i].children : null;
- if ( a && ('length' in a) ){
- var cl = ConstructorMap[arr[i].name];
- // note: when states are applied, they add their children as
- // siblings therefore classChildren that appear within a state
- // do not gain a level of depth
- this.__LZassignClassRoot( a , (('$isstate' in cl.prototype) && (cl.prototype.$isstate)) ? depth : depth+1);
- }
- }
- }
-}
-
if ($swf9) { // TODO [hqm 2008-03] This is just a debugging print utility function for swf9
public static function objAsString(obj) {
var s = "";
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/data/LzReplicationManager.lzs
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/data/LzReplicationManager.lzs 2008-04-02 00:40:03 UTC (rev 8514)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/data/LzReplicationManager.lzs 2008-04-02 02:37:15 UTC (rev 8515)
@@ -133,24 +133,26 @@
return;
}
-
//this is so that when it looks like you're refering to the view in source
//you can say view.datapath and you'll get what you want (which is this)
this.datapath = this;
//null, or name of view that was replicated
- var name = view._instanceAttrs.name;
+ var name = view.name;
+ if (name != null) {
+ args.name = name;
+ // remove view we replace to avoid warning in LzNode.$lzc$set_name
+ delete view.immediateparent[name];
+ delete view.parent[name];
+ }
- args.name = name;
- // remove view we replace to avoid warning in LzNode.$lzc$set_name
- delete view.immediateparent[name];
- delete view.parent[name];
-
//same deal for id
- var id = view._instanceAttrs.id;
- args.id = id;
- // remove any LzNode with this id
- if (global[id] instanceof LzNode) global[id] = null;
+ var id = view.id;
+ if (id != null) {
+ args.id = id;
+ // remove any LzNode with this id
+ if (global[id] instanceof LzNode) global[id] = null;
+ }
//don't want to rerunxpath
args.xpath = LzNode._ignoreAttribute;
@@ -249,7 +251,7 @@
this.visible = odp.datacontrolsvisibility ||
(!view.isinited &&
- ('visible' in view._instanceAttrs) ? view._instanceAttrs.visible : view.visible);
+ (view._instanceAttrs != null && 'visible' in view._instanceAttrs) ? view._instanceAttrs.visible : view.visible);
if ( args.pooling != null ){
this.pooling = args.pooling;
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/views/LaszloCanvas.lzs
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/views/LaszloCanvas.lzs 2008-04-02 00:40:03 UTC (rev 8514)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/views/LaszloCanvas.lzs 2008-04-02 02:37:15 UTC (rev 8515)
@@ -404,18 +404,19 @@
function initDone (){
//reorder initial subviews so preloaded stuff is first
var sva = new Array;
+ var is = this._lzinitialsubviews;
- for ( var i = 0; i < this._lzinitialsubviews.length; i++ ){
- if ( 'initimmediate' in this._lzinitialsubviews[ i ].attrs &&
- this._lzinitialsubviews[ i ].attrs.initimmediate ){
- sva.push( this._lzinitialsubviews[ i ] );
+ for ( var i = 0; i < is.length; i++ ){
+ var isi = is[i];
+ if ( isi['attrs'] && isi.attrs['initimmediate'] ){
+ sva.push( isi );
}
}
- for ( var i = 0; i < this._lzinitialsubviews.length; i++ ){
- if ( !('initimmediate' in this._lzinitialsubviews[ i ].attrs &&
- this._lzinitialsubviews[ i ].attrs.initimmediate) ){
- sva.push( this._lzinitialsubviews[ i ] );
+ for ( var i = 0; i < is.length; i++ ){
+ var isi = is[i];
+ if ( ! ( isi['attrs'] && isi.attrs['initimmediate'] ) ){
+ sva.push( isi );
}
}
Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassCompiler.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassCompiler.java 2008-04-02 00:40:03 UTC (rev 8514)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassCompiler.java 2008-04-02 02:37:15 UTC (rev 8515)
@@ -23,7 +23,7 @@
/** Compiler for <code>class</code> class elements.
*/
-class ClassCompiler extends ViewCompiler {
+class ClassCompiler extends ViewCompiler {
/**
For a declaration of a class named "foobar"
@@ -235,38 +235,6 @@
schema.addElement(element, classname, superclass, attributeDefs, mEnv);
}
- // Map of LFC tag names
- static HashMap LFCTagTable = new HashMap();
- static {
- LFCTagTable.put("node", "LzNode");
- LFCTagTable.put("view", "LzView");
- LFCTagTable.put("text", "LzText");
- LFCTagTable.put("inputtext", "LzInputText");
- LFCTagTable.put("canvas", "LzCanvas");
- LFCTagTable.put("script", "LzScript");
- LFCTagTable.put("animatorgroup", "LzAnimatorGroup");
- LFCTagTable.put("animator", "LzAnimator");
- LFCTagTable.put("layout", "LzLayout");
- LFCTagTable.put("state", "LzState");
- LFCTagTable.put("command", "LzCommand");
- LFCTagTable.put("selectionmanager", "LzSelectionManager");
- LFCTagTable.put("dataselectionmanager", "LzDataSelectionManager");
- LFCTagTable.put("datapointer", "LzDataPointer");
- LFCTagTable.put("dataprovider", "LzDataProvider");
- LFCTagTable.put("datapath", "LzDatapath");
- LFCTagTable.put("dataset", "LzDataset");
- LFCTagTable.put("datasource", "LzDatasource");
- LFCTagTable.put("lzhttpdataprovider", "LzHTTPDataProvider");
- }
-
- public static String tagToClass(String s) {
- if (LFCTagTable.containsKey(s)) {
- return (String)(LFCTagTable.get(s));
- }
- String lzcPackagePrefix = "$lzc$class_";
- return lzcPackagePrefix + s;
- }
-
public void compile(Element elt) {
String tagName = elt.getAttributeValue("name");
ViewSchema schema = mEnv.getSchema();
@@ -284,148 +252,17 @@
, elt);
}
}
- String className = tagToClass(tagName);
- // className will be a global
- mEnv.addId(className, elt);
-
- ClassModel classModel = schema.getClassModel(tagName);
-
- String linedir = CompilerUtils.sourceLocationDirective(elt, true);
- ViewCompiler.preprocess(elt, mEnv);
-
// We compile a class declaration just like a view, and then
// add attribute declarations and perhaps some other stuff that
// the runtime wants.
+ ClassModel classModel = schema.getClassModel(tagName);
+ ViewCompiler.preprocess(elt, mEnv);
NodeModel model = NodeModel.elementAsModel(elt, schema, mEnv);
model = model.expandClassDefinitions();
+ // Establish class root
+ model.assignClassRoot(0);
classModel.setNodeModel(model);
- // Should the package prefix be in the model? Should the
- // model store class and tagname separately?
- String supertagname = classModel.getSuperclassName();
- String superclassname = tagToClass(supertagname);
- ClassModel superclassModel = schema.getClassModel(supertagname);
-
-
- // Build the constructor
- String body = "";
- body += "super(parent, attrs, children, async);\n";
-
- model.setAttribute(
- className,
- new Function(
- className,
- // All nodes get these args when constructed
- // Apparently AS3 does not allow defaulting of
- // primitive args
-// "parent:LzNode, attrs:Object, children:Object? = null, async:boolean = false",
- "parent:LzNode? = null, attrs:Object? = null, children:Object? = null, async:Boolean = false",
- body,
- null));
-
- // Build the class body
- String classBody = "";
- // Set the tag name
- model.setClassAttribute("tagname", ScriptCompiler.quote(tagName));
-
- // --- This should only be for subclasses of Node
- String children = ScriptCompiler.objectAsJavascript(model.childrenMaps());
- // class#classChildren now class.children
- model.setClassAttribute("children", "LzNode.mergeChildren(" + children + ", " + superclassname + "['children'])");
-
- // Declare all instance vars and methods, save initialization
- // in <class>.attributes
- Map attrs = model.getAttrs(); // classModel.getMergedAttributes();
- Map setters = classModel.getMergedSetters();
- Map decls = new LinkedHashMap();
- Map inits = new LinkedHashMap();
- boolean isstate = classModel.isSubclassOf(schema.getClassModel("state"));
- for (Iterator i = attrs.entrySet().iterator(); i.hasNext(); ) {
- Map.Entry entry = (Map.Entry) i.next();
- String key = (String) entry.getKey();
- Object value = entry.getValue();
- boolean redeclared = (superclassModel.getAttribute(key) != null);
- if ((value instanceof NodeModel.BindingExpr)) {
- // Bindings always have to be installed as an init
- if (! redeclared) {
- decls.put(key, null);
- }
- inits.put(key, ((NodeModel.BindingExpr)value).getExpr());
- } else if (value instanceof Function &&
- ((! isstate) ||
- className.equals(key))) {
- // Methods are just decls. Except in states, because they
- // have to be applied to the parent, except for the
- // constructor!
- decls.put(key, value);
- } else if (value != null) {
- // If this is a re-declared attribute, we just init it,
- // don't re-declare it
- if (superclassModel.getAttribute(key) != null) {
- inits.put(key, value);
- }
- // If there is a setter for this attribute, or this is a
- // state, or this is an Array or Map argument that needs
- // magic merging, the value has to be installed as an init,
- // otherwise it should be installed as a decl
- //
- // TODO: [2008-03-15 ptw] This won't work until we know
- // (in the classModel) the setters for the built-in
- // classes, so we install as an init for now and this is
- // fixed up in LzNode by installing inits that have no
- // setters when the arguments are merged
-
- if (true) { // (! (value instanceof String)) || setters.containsKey(key) || isstate) {
- if (! redeclared) {
- decls.put(key, null);
- }
- inits.put(key, value);
- } else {
- if (! redeclared) {
- decls.put(key, value);
- // If there is a property that would have been shadowed,
- // you have to hide that from applyArgs, or you will get
- // clobbered!
- inits.put(key, "LzNode._ignoreAttribute");
- } else {
- inits.put(key, value);
- }
- }
- } else {
- // Just a declaration
- if (! redeclared) {
- decls.put(key, value);
- }
- }
- }
- // mergedAttrs does not deal with our methods
-// Map methods = model.getAttrs();
-// for (Iterator i = methods.entrySet().iterator(); i.hasNext(); ) {
-// Map.Entry entry = (Map.Entry) i.next();
-// String key = (String) entry.getKey();
-// Object value = entry.getValue();
-// if ((value instanceof Function)) {
-// decls.put(key, value);
-// }
-// }
- model.setClassAttribute("attributes", "new LzInheritedHash(" + superclassname + ".attributes)");
- classBody += "LzNode.mergeAttributes(" +
- ScriptCompiler.objectAsJavascript(inits) +
- ", " + className + ".attributes);\n";
-
- Map viewMap = model.asMap();
- // Put in the class name, not "class"
- viewMap.put("name", ScriptCompiler.quote(className));
-
- ScriptClass scriptClass =
- new ScriptClass(className,
- superclassname,
- decls,
- (Map)viewMap.get("classAttrs"),
- classBody);
-
- mEnv.compileScript(scriptClass.toString(), elt);
- // Install in constructor map
- mEnv.compileScript("ConstructorMap[" + ScriptCompiler.quote(tagName) + "] = " + className + ";\n");
+ classModel.emitClassDeclaration(mEnv);
}
protected void compileClass(Element elt, ClassModel classModel, String initobj) {
Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassModel.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassModel.java 2008-04-02 00:40:03 UTC (rev 8514)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassModel.java 2008-04-02 02:37:15 UTC (rev 8515)
@@ -8,9 +8,12 @@
import java.util.*;
import org.jdom.Element;
import org.openlaszlo.sc.Function;
+import org.openlaszlo.sc.ScriptCompiler;
+import org.openlaszlo.sc.ScriptClass;
class ClassModel implements Comparable {
protected final ViewSchema schema;
+ /** This is really the LZX tag name */
protected final String className;
// This is null for builtin classes
protected final ClassModel superclass;
@@ -90,7 +93,160 @@
return lzx;
}
-
+ // Map of LFC tag names
+ static HashMap LFCTag2JSClass = new HashMap();
+ static {
+ LFCTag2JSClass.put("node", "LzNode");
+ LFCTag2JSClass.put("view", "LzView");
+ LFCTag2JSClass.put("text", "LzText");
+ LFCTag2JSClass.put("inputtext", "LzInputText");
+ LFCTag2JSClass.put("canvas", "LzCanvas");
+ LFCTag2JSClass.put("script", "LzScript");
+ LFCTag2JSClass.put("animatorgroup", "LzAnimatorGroup");
+ LFCTag2JSClass.put("animator", "LzAnimator");
+ LFCTag2JSClass.put("layout", "LzLayout");
+ LFCTag2JSClass.put("state", "LzState");
+ LFCTag2JSClass.put("command", "LzCommand");
+ LFCTag2JSClass.put("selectionmanager", "LzSelectionManager");
+ LFCTag2JSClass.put("dataselectionmanager", "LzDataSelectionManager");
+ LFCTag2JSClass.put("datapointer", "LzDatapointer");
+ LFCTag2JSClass.put("dataprovider", "LzDataProvider");
+ LFCTag2JSClass.put("datapath", "LzDatapath");
+ LFCTag2JSClass.put("dataset", "LzDataset");
+ LFCTag2JSClass.put("datasource", "LzDatasource");
+ LFCTag2JSClass.put("lzhttpdataprovider", "LzHTTPDataProvider");
+ }
+
+ public static String LZXTag2JSClass(String s) {
+ if (LFCTag2JSClass.containsKey(s)) {
+ return (String)(LFCTag2JSClass.get(s));
+ }
+ String lzcPackagePrefix = "$lzc$class_";
+ return lzcPackagePrefix + s;
+ }
+
+ /**
+ * Emits a class model as a JS2 class declaration. This is used
+ * both by the class compiler and the instance compiler (when an
+ * instance has methods, either explicit or implicit).
+ */
+ void emitClassDeclaration(CompilationEnvironment env) {
+ String tagName = getClassName();
+ String className = LZXTag2JSClass(tagName);
+ // className will be a global
+ env.addId(className, definition);
+ // Should the package prefix be in the model? Should the
+ // model store class and tagname separately?
+ ClassModel superclassModel = getSuperclassModel();
+ String superTagName = superclassModel.getClassName();
+ String superclassName = LZXTag2JSClass(superTagName);
+
+ // Build the constructor
+ String body = "";
+ body += "super($lzc$parent, $lzc$attrs, $lzc$children, $lzc$async);\n";
+ nodeModel.setAttribute(
+ className,
+ new Function(
+ className,
+ // All nodes get these args when constructed
+ // Apparently AS3 does not allow defaulting of
+ // primitive args
+ "$lzc$parent:LzNode? = null, $lzc$attrs:Object? = null, $lzc$children:Array? = null, $lzc$async:Boolean = false",
+ body,
+ null));
+
+ // Build the class body
+ String classBody = "";
+ // Set the tag name
+ nodeModel.setClassAttribute("tagname", ScriptCompiler.quote(tagName));
+
+ // --- This should only be for subclasses of Node
+ String children = ScriptCompiler.objectAsJavascript(nodeModel.childrenMaps());
+ // class#classChildren now class.children
+ nodeModel.setClassAttribute("children", "LzNode.mergeChildren(" + children + ", " + superclassName + "['children'])");
+
+ // Declare all instance vars and methods, save initialization
+ // in <class>.attributes
+ Map attrs = nodeModel.getAttrs(); // classModel.getMergedAttributes();
+ Map setters = getMergedSetters();
+ Map decls = new LinkedHashMap();
+ Map inits = new LinkedHashMap();
+ boolean isstate = isSubclassOf(schema.getClassModel("state"));
+ for (Iterator i = attrs.entrySet().iterator(); i.hasNext(); ) {
+ Map.Entry entry = (Map.Entry) i.next();
+ String key = (String) entry.getKey();
+ Object value = entry.getValue();
+ boolean redeclared = (superclassModel.getAttribute(key) != null);
+ if ((value instanceof NodeModel.BindingExpr)) {
+ // Bindings always have to be installed as an init
+ if (! redeclared) {
+ decls.put(key, null);
+ }
+ inits.put(key, ((NodeModel.BindingExpr)value).getExpr());
+ } else if (value instanceof Function &&
+ ((! isstate) ||
+ className.equals(key))) {
+ // Methods are just decls. Except in states, because they
+ // have to be applied to the parent, except for the
+ // constructor!
+ decls.put(key, value);
+ } else if (value != null) {
+ // If this is a re-declared attribute, we just init it,
+ // don't re-declare it
+ if (superclassModel.getAttribute(key) != null) {
+ inits.put(key, value);
+ }
+ // If there is a setter for this attribute, or this is a
+ // state, or this is an Array or Map argument that needs
+ // magic merging, the value has to be installed as an init,
+ // otherwise it should be installed as a decl
+ //
+ // TODO: [2008-03-15 ptw] This won't work until we know
+ // (in the classModel) the setters for the built-in
+ // classes, so we install as an init for now and this is
+ // fixed up in LzNode by installing inits that have no
+ // setters when the arguments are merged
+ if (true) { // (! (value instanceof String)) || setters.containsKey(key) || isstate) {
+ if (! redeclared) {
+ decls.put(key, null);
+ }
+ inits.put(key, value);
+ } else {
+ if (! redeclared) {
+ decls.put(key, value);
+ // If there is a property that would have been shadowed,
+ // you have to hide that from applyArgs, or you will get
+ // clobbered!
+ inits.put(key, "LzNode._ignoreAttribute");
+ } else {
+ inits.put(key, value);
+ }
+ }
+ } else {
+ // Just a declaration
+ if (! redeclared) {
+ decls.put(key, value);
+ }
+ }
+ }
+ // Create inits list, merged with superclass inits
+ nodeModel.setClassAttribute("attributes", "new LzInheritedHash(" + superclassName + ".attributes)");
+ classBody += "LzNode.mergeAttributes(" +
+ ScriptCompiler.objectAsJavascript(inits) +
+ ", " + className + ".attributes);\n";
+
+ // Emit the class decl
+ ScriptClass scriptClass =
+ new ScriptClass(className,
+ superclassName,
+ decls,
+ nodeModel.getClassAttrs(),
+ classBody);
+ env.compileScript(scriptClass.toString(), definition);
+ // Install in constructor map
+ env.compileScript("ConstructorMap[" + ScriptCompiler.quote(tagName) + "] = " + className + ";\n");
+ }
+
/** Returns true if this is equal to or a subclass of
* superclass. */
boolean isSubclassOf(ClassModel superclass) {
@@ -163,10 +319,12 @@
return merged;
}
+ /** This is really the LZX tag name */
String getClassName () {
return this.className;
}
+ /** This is really the LZX tag name */
String getSuperclassName() {
if (superclassName != null) {
return superclassName;
Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/NodeModel.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/NodeModel.java 2008-04-02 00:40:03 UTC (rev 8514)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/NodeModel.java 2008-04-02 02:37:15 UTC (rev 8515)
@@ -816,11 +816,13 @@
type = ViewSchema.EXPRESSION_TYPE;
}
- if (type == schema.ID_TYPE) {
- this.id = value;
- } else if (type == schema.EVENT_HANDLER_TYPE) {
+ if (type == schema.EVENT_HANDLER_TYPE) {
addHandlerFromAttribute(element, name, value);
} else {
+ // NOTE: [2008-04-01 ptw] May be obsolete?
+ if (type == schema.ID_TYPE) {
+ this.id = value;
+ }
String when = this.getAttributeValueDefault(
name, "when", WHEN_IMMEDIATELY);
// NYI
@@ -1061,6 +1063,13 @@
checkChildNameConflict(element.getName(), child, env);
NodeModel childModel = elementAsModel(child, schema, env);
children.add(childModel);
+ // Declare the child name (if any) as a property
+ // of the node so that references to it from
+ // methods can be resolved at compile-time
+ String childName = child.getAttributeValue("name");
+ if (childName != null) {
+ attrs.put(childName, null);
+ }
totalSubnodes += childModel.totalSubnodes();
}
} catch (CompilationError e) {
@@ -1800,41 +1809,83 @@
return attrs;
}
+ boolean hasMethods() {
+ for (Iterator i = attrs.values().iterator(); i.hasNext(); ) {
+ if (i.next() instanceof Function) { return true; }
+ }
+ return false;
+ }
+
+ Map getClassAttrs() {
+ return classAttrs;
+ }
+
Map getSetters() {
return setters;
}
Map asMap() {
+ updateAttrs();
Map map = new LinkedHashMap();
- updateAttrs();
- map.put("name", ScriptCompiler.quote(className));
- Map inits = new LinkedHashMap();
- // Node as map just wants to see all the attrs, so clean out
- // the binding markers
- for (Iterator i = attrs.entrySet().iterator(); i.hasNext(); ) {
- Map.Entry entry = (Map.Entry) i.next();
- String key = (String) entry.getKey();
- Object value = entry.getValue();
- if (! (value instanceof NodeModel.BindingExpr)) {
- inits.put(key, value);
- } else {
- inits.put(key, ((NodeModel.BindingExpr)value).getExpr());
- }
+ String tagName = className;
+ if (hasMethods()) {
+ // Emit a class declaration to hold the methods
+ String name = id;
+ if (name == null) {
+ name = CompilerUtils.attributeUniqueName(element, "class");
+ }
+ tagName = className + "_" + name;
+ ClassModel classModel = new ClassModel(tagName, parentClassModel, schema, element);
+ classModel.setNodeModel(this);
+ classModel.emitClassDeclaration(env);
+ } else {
+ Map inits = new LinkedHashMap();
+ // Node as map just wants to see all the attrs, so clean out
+ // the binding markers
+ for (Iterator i = attrs.entrySet().iterator(); i.hasNext(); ) {
+ Map.Entry entry = (Map.Entry) i.next();
+ String key = (String) entry.getKey();
+ Object value = entry.getValue();
+ if (! (value instanceof NodeModel.BindingExpr)) {
+ inits.put(key, value);
+ } else {
+ inits.put(key, ((NodeModel.BindingExpr)value).getExpr());
+ }
+ }
+ if (!attrs.isEmpty()) {
+ map.put("attrs", inits);
+ }
+ if (!classAttrs.isEmpty()) {
+ map.put("classAttrs", classAttrs);
+ }
+ if (!children.isEmpty()) {
+ map.put("children", childrenMaps());
+ }
}
- map.put("attrs", inits);
- if (!classAttrs.isEmpty()) {
- map.put("classAttrs", classAttrs);
- }
+
+ // The tag to instantiate
+ // TODO: [2008-04-01 ptw] we could have a flag day and put the
+ // class here, eliminating having to go through the
+ // constructor map...
+ map.put("name", ScriptCompiler.quote(tagName));
if (id != null) {
+ // NOTE: [2008-04-01 ptw] May be obsolete?
map.put("id", ScriptCompiler.quote(id));
- inits.put("id", ScriptCompiler.quote(id));
}
- if (!children.isEmpty()) {
- map.put("children", childrenMaps());
- }
+
return map;
}
+ void assignClassRoot(int depth) {
+ if (! parentClassModel.isSubclassOf(schema.getClassModel("state"))) { depth++; }
+ Integer d = new Integer(depth);
+ for (Iterator i = children.iterator(); i.hasNext(); ) {
+ NodeModel child = (NodeModel)i.next();
+ child.attrs.put("$classrootdepth", d);
+ child.assignClassRoot(depth);
+ }
+ }
+
List childrenMaps() {
List childMaps = new Vector(children.size());
for (Iterator iter = children.iterator(); iter.hasNext(); )
Modified: openlaszlo/trunk/lps/components/base/basecomponent.lzx
===================================================================
--- openlaszlo/trunk/lps/components/base/basecomponent.lzx 2008-04-02 00:40:03 UTC (rev 8514)
+++ openlaszlo/trunk/lps/components/base/basecomponent.lzx 2008-04-02 02:37:15 UTC (rev 8515)
@@ -299,11 +299,10 @@
0xddddff)
<br/>param Number brightness: -255 to 255, optional parameter
will lighten or darken everything that is colorized -->
- <method name="setTint" args="v, color, brightness">
+ <method name="setTint" args="v, color, brightness=0">
<![CDATA[
if (v.capabilities.colortransform) {
if (color != "" && color != null){
- if (brightness == null) { brightness = 0; }
var rgb = color;
var red=(rgb >> 16) & 0xFF;
var green=(rgb >> 8) & 0xFF;
More information about the Laszlo-checkins
mailing list