Browse Source

more work on hide domkit (ids, component hook)

Nicolas Cannasse 1 year ago
parent
commit
7fc9cf01d4
3 changed files with 91 additions and 14 deletions
  1. 14 0
      hide/comp/DomkitEditor.hx
  2. 11 7
      hide/view/Domkit.hx
  3. 66 7
      hrt/impl/DomkitViewer.hx

+ 14 - 0
hide/comp/DomkitEditor.hx

@@ -23,6 +23,7 @@ private typedef TypedProperty = {
 
 private typedef TypedComponent = {
 	var name : String;
+	var ?classDef : hscript.Checker.CClass;
 	var ?parent : TypedComponent;
 	var properties : Map<String, TypedProperty>;
 	var vars : Map<String, Type>;
@@ -77,6 +78,7 @@ class DomkitChecker extends ScriptEditor.ScriptChecker {
 	}
 
 	public function checkDML( dmlCode : String, filePath : String, position = 0 ) {
+		init();
 		// reset locals and other vars
 		checker.check({ e : EBlock([]), pmin : 0, pmax : 0, origin : "", line : 0 });
 		@:privateAccess checker.locals = params.copy();
@@ -84,6 +86,17 @@ class DomkitChecker extends ScriptEditor.ScriptChecker {
 		var parser = new domkit.MarkupParser();
 		parser.allowRawText = true;
 		var expr = parser.parse(dmlCode,filePath, position);
+		switch( expr.kind ) {
+		case Node(null) if( expr.children.length == 1 ): expr = expr.children[0];
+		default:
+		}
+		switch( expr.kind ) {
+		case Node(name) if( name != null ):
+			var comp = resolveComp(name.split(":")[0]);
+			if( comp != null && comp.classDef != null )
+				checker.setGlobal("this",TInst(comp.classDef,[]));
+		default:
+		}
 		try {
 			checkDMLRec(expr, true);
 		} catch( e : hscript.Expr.Error ) {
@@ -213,6 +226,7 @@ class DomkitChecker extends ScriptEditor.ScriptChecker {
 			if( name == null )
 				continue;
 			var comp = makeComponent(name);
+			comp.classDef = c;
 			cmap.set(c.name, comp);
 			if( StringTools.startsWith(c.name,"h2d.domkit.") )
 				cmap.set("h2d."+c.name.substr(11,c.name.length-11-4), comp);

+ 11 - 7
hide/view/Domkit.hx

@@ -96,15 +96,19 @@ class Domkit extends FileView {
 
 	function check() {
 		modified = prevSave.css != cssEditor.code || prevSave.dml != dmlEditor.code || prevSave.params != paramsEditor.code;
+		var allParams = new Map();
+		dmlEditor.checker.params = allParams;
 		var comp = dmlEditor.getComponent();
-		if( comp != null && comp.arguments.length > 0 )
+		if( comp != null && comp.arguments.length > 0 ) {
 			@:privateAccess paramsEditor.checker.checker.setGlobal("defaultArgs", TAnon(comp.arguments.copy()));
+			for( a in comp.arguments )
+				allParams.set(a.name, a.t);
+		}
 		paramsEditor.doCheckScript();
-		var params = @:privateAccess paramsEditor.checker.checker.locals.get("params");
-		if( params == null ) params = TAnon([]);
-		switch( params ) {
+		var tparams = @:privateAccess paramsEditor.checker.checker.locals.get("params");
+		if( tparams == null ) tparams = TAnon([]);
+		switch( tparams ) {
 		case TAnon(fields):
-			dmlEditor.checker.params = new Map();
 			var any : hscript.Checker.TType = TUnresolved("???");
 			for( f in fields ) {
 				var t = f.t;
@@ -130,7 +134,7 @@ class Domkit extends FileView {
 					}
 				}
 				setRec(t);
-				dmlEditor.checker.params.set(f.name, t);
+				allParams.set(f.name, t);
 			}
 		case null, _:
 			paramsEditor.setError("Params definition is missing", 0, 0, 0);
@@ -155,7 +159,7 @@ class Domkit extends FileView {
 		if( cssText != cssEditor.code ) cssEditor.setCode(cssText);
 		if( dmlText != dmlEditor.code ) dmlEditor.setCode(dmlText);
 		if( paramsText != paramsEditor.code ) paramsEditor.setCode(paramsText);
-		sys.io.File.saveContent(getPath(),('<css>\n$cssText\n</css>\n')+(hasParams?'<params>\n$paramsText\n</params>':'')+dmlText);
+		sys.io.File.saveContent(getPath(),('<css>\n$cssText\n</css>\n\n')+(hasParams?'<params>\n$paramsText\n</params>\n\n':'')+dmlText);
 	}
 
 	override function getDefaultContent() {

+ 66 - 7
hrt/impl/DomkitViewer.hx

@@ -69,6 +69,7 @@ class DomkitViewer extends h2d.Object {
 	var variables : Map<String,Dynamic> = [];
 	var rebuilding = false;
 	var compArgs : Map<String,Dynamic>;
+	var rootObject : h2d.Object;
 
 	public function new( style : h2d.domkit.Style, res : hxd.res.Resource, ?parent ) {
 		super(parent);
@@ -282,9 +283,10 @@ class DomkitViewer extends h2d.Object {
 				if( !evalCode(expr) )
 					return;
 			}
+			var isRoot = parent.parent == null;
 			var c = domkit.Component.get(name, true);
 			// if we are top component, resolve our parent component
-			if( parent.parent == null ) {
+			if( isRoot ) {
 				var parts = name.split(":");
 				var parent = null;
 				if( parts.length == 2 ) {
@@ -314,23 +316,77 @@ class DomkitViewer extends h2d.Object {
 				// TODO : typecheck argument
 				v;
 			}];
-			if( compArgs != null ) {
+			if( isRoot && compArgs != null  ) {
 				if( e.arguments.length == 0 ) {
-					for( a in c.argsNames )
-						args.push(compArgs.get(a));
+					for( a in @:privateAccess c.argsNames ) {
+						var v : Dynamic = compArgs.get(a);
+						args.push(v);
+						interp.variables.set(a, v);
+					}
 				}
 				compArgs = null;
 			}
 			var attributes = {};
+			var objId = null, objIdArray = false;
 			for( a in e.attributes ) {
+				if( a.name == "id" ) {
+					objId = switch( a.value ) {
+					case RawValue("true"):
+						var name = null;
+						for( a in e.attributes )
+							if( a.name == "class" ) {
+								name = switch( a.value ) { case RawValue(v): v; default: null; };
+								break;
+							}
+						name;
+					case RawValue(name) if( StringTools.endsWith(name,"[]") ):
+						objIdArray = true;
+						name.substr(0,name.length - 2);
+					case RawValue(name):
+						name;
+					case Code(_): null;
+					}
+					if( objId != null )
+						(attributes:Dynamic).id = objId;
+					continue;
+				}
 				switch( a.value ) {
 				case RawValue(v):
 					Reflect.setField(attributes,a.name,v);
 				case Code(_):
-					throw "TODO";
+					// skip (init after)
 				}
 			}
+			var childrenCreated = false;
+			if( isRoot ) {
+				// only create parent structure, since we will create our own structure here
+				@:privateAccess c.createHook = function(obj) {
+					rootObject = obj;
+					interp.variables.set("this", obj);
+					// create children immediately as our post-init code might require some components to be init
+					childrenCreated = true;
+					for( c in e.children )
+						addRec(c, obj);
+				};
+			}
 			var p = @:privateAccess domkit.Properties.createNew(c.name, parent.dom, args, attributes);
+			if( isRoot ) {
+				rootObject = cast p.obj;
+				@:privateAccess c.createHook = null;
+				interp.variables.set("this", p.obj);
+			}
+			if( objId != null ) {
+				if( objIdArray ) {
+					var arr : Array<Dynamic> = try Reflect.getProperty(rootObject, objId) catch( e : Dynamic ) null;
+					if( arr == null ) {
+						arr = [];
+						try Reflect.setProperty(rootObject, objId, arr) catch( e : Dynamic ) {};
+					}
+					arr.push(p.obj);
+				} else {
+					try Reflect.setProperty(rootObject, objId, p.obj) catch( e : Dynamic ) {}
+				}
+			}
 			for( a in e.attributes ) {
 				var h = p.component.getHandler(domkit.Property.get(a.name));
 				if( h == null ) {
@@ -342,10 +398,13 @@ class DomkitViewer extends h2d.Object {
 				case Code(code):
 					var v : Dynamic = evalCode(parseCode(code, a.pmin));
 					@:privateAccess p.initStyle(a.name, v);
+					h.apply(p.obj, v);
 				}
 			}
-			for( c in e.children )
-				addRec(c, cast p.contentRoot);
+			if( !childrenCreated ) {
+				for( c in e.children )
+					addRec(c, cast p.contentRoot);
+			}
 		case Text(text):
 			var tf = new h2d.HtmlText(hxd.res.DefaultFont.get(), parent);
 			tf.dom = domkit.Properties.create("html-text", tf);