Skip to content

Commit

Permalink
allow components loading in domkit editor/viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
ncannasse committed Apr 8, 2024
1 parent c46d4de commit e6091d6
Show file tree
Hide file tree
Showing 4 changed files with 336 additions and 145 deletions.
158 changes: 126 additions & 32 deletions hide/comp/DomkitEditor.hx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ private class DomkitCssParser extends domkit.CssParser {
}

override function resolveComponent(i:String, p:Int) {
var c = @:privateAccess dom.components.get(i);
var c = @:privateAccess dom.resolveComp(i);
return c?.domkitComp;
}

Expand All @@ -56,14 +56,14 @@ class DomkitChecker extends ScriptEditor.ScriptChecker {
public var params : Map<String, Type> = new Map();
public var components : Map<String, TypedComponent>;
public var properties : Map<String, Array<TypedProperty>>;
public var definedIdents : Map<String, Array<TypedComponent>>;
public var definedIdents : Map<String, Array<TypedComponent>> = [];

public function new(config) {
super(config,"domkit");
t_string = checker.types.resolve("String");

parsers = [new h2d.domkit.BaseComponents.CustomParser()];
var dcfg : Array<String> = config.get("domkit-parsers");
var dcfg : Array<String> = config.get("domkit.parsers");
if( dcfg != null ) {
for( name in dcfg ) {
var cl = std.Type.resolveClass(name);
Expand Down Expand Up @@ -304,7 +304,65 @@ class DomkitChecker extends ScriptEditor.ScriptChecker {
}

function resolveComp( name : String ) : TypedComponent {
return components.get(name);
var c = components.get(name);
if( c != null )
return c;
// dynamic load from comps directories
var dirs : Array<String> = config.get("domkit.components");
if( dirs == null ) dirs = ["ui/comp"];
for( d in dirs ) {
var path = d+"/"+name+".domkit";
var content = try sys.io.File.getContent(ide.getPath(path)) catch( e : Dynamic ) continue;
var data = hrt.impl.DomkitViewer.parse(content);
var node = null, params = new Map();

var parser = new domkit.MarkupParser();
parser.allowRawText = true;
var expr = try parser.parse(data.dml,path,content.indexOf(data.dml)) catch( e : domkit.Error ) continue;

switch( expr.kind ) {
case Node(null):
for( c in expr.children )
switch( c.kind ) {
case Node(n) if( n == name ): node = c;
default:
}
default:
throw "assert";
}

if( node == null )
continue;

if( node.arguments != null ) {
var args = [for( a in node.arguments ) switch( a.value ) { case Code(ident): ident; default: null; }];
for( a in args )
if( a != null )
params.set(a, TLazy(() -> throw new hscript.Expr.Error(ECustom("Missing param type "+a),0,0,"",0)));
try {
var t = typeCode(data.params, content.indexOf(data.params));
switch( t ) {
case TAnon(fields):
var fm = [for( f in fields ) f.name => f.t];
for( a in args )
if( a != null ) {
var t = fm.get(a);
if( t != null )
params.set(a, t);
}
default:
}
} catch( e : hscript.Expr.Error ) {
}
}

try {
return defineComponent(name, node, params);
} catch( e : domkit.Error ) {
continue;
}
}
return null;
}

function parseCode( code : String, pos : Int ) {
Expand Down Expand Up @@ -411,38 +469,74 @@ class DomkitChecker extends ScriptEditor.ScriptChecker {
comps.push(c);
}

function domkitError(msg,pmin,pmax=-1) {
throw new domkit.Error(msg, pmin, pmax);
}

static var IDENT = ~/^([A-Za-z_][A-Za-z0-9_]*)$/;

function defineComponent( name : String, e : domkit.MarkupParser.Markup, params : Map<String,Type> ) {
var parts = name.split(":");
var parent = null;
var c = components.get(name);
if( parts.length == 2 ) {
name = parts[0];
c = components.get(name);
parent = resolveComp(parts[1]);
if( parent == null ) {
var start = e.pmin + name.length + 1;
domkitError("Unknown parent component "+parts[1], start, start + parts[1].length);
}
}
if( parent == null )
parent = components.get("flow");
if( c == null )
c = makeComponent(name);
c.parent = parent;
if( e.arguments == null )
c.arguments = parent == null ? [] : parent.arguments;
else {
c.arguments = [];
for( a in e.arguments ) {
var name = switch( a.value ) {
case Code(c) if( IDENT.match(c) ): c;
default:
domkitError("Invalid parameter", a.pmin, a.pmax);
continue;
}
var t = params.get(name);
if( t == null )
domkitError("Unknown parameter type", a.pmin, a.pmax);
c.arguments.push({
name : name,
t : t,
});
}
}
if( e.condition != null )
domkitError("Invalid condition", e.condition.pmin, e.condition.pmax);
if( e.attributes.length > 0 )
domkitError("Invalid attribute", e.attributes[0].pmin, e.attributes[0].pmax);
return c;
}

function checkDMLRec( e : domkit.MarkupParser.Markup, isRoot=false ) {
switch( e.kind ) {
case Node(null):
for( c in e.children )
checkDMLRec(c,isRoot);
case Node(name) if( isRoot ):
defineComponent(name, e, params);
for( c in e.children )
checkDMLRec(c);
case Node(name):
var c = resolveComp(name);
if( isRoot ) {
var parts = name.split(":");
var parent = null;
if( parts.length == 2 ) {
name = parts[0];
c = resolveComp(name);
parent = resolveComp(parts[1]);
if( parent == null ) {
var start = e.pmin + name.length + 1;
throw new domkit.Error("Unknown parent component "+parts[1], start, start + parts[1].length);
}
}
if( c == null )
c = makeComponent(name);
c.parent = parent;
c.arguments = parent == null ? [] : c.arguments;
}
if( c == null && isRoot )
c = resolveComp("flow");
if( c == null )
throw new domkit.Error("Unknown component "+name, e.pmin, e.pmin + name.length);
domkitError("Unknown component "+name, e.pmin, e.pmin + name.length);
for( i => a in e.arguments ) {
var arg = c.arguments[i];
if( arg == null )
throw new domkit.Error("Too many arguments (require "+[for( a in c.arguments ) a.name].join(",")+")",a.pmin,a.pmax);
domkitError("Too many arguments (require "+[for( a in c.arguments ) a.name].join(",")+")",a.pmin,a.pmax);
var t = switch( a.value ) {
case RawValue(_): t_string;
case Code(code): typeCode(code, a.pmin);
Expand All @@ -451,7 +545,7 @@ class DomkitChecker extends ScriptEditor.ScriptChecker {
}
for( i in e.arguments.length...c.arguments.length )
if( !c.arguments[i].opt )
throw new domkit.Error("Missing required argument "+c.arguments[i].name,e.pmin,e.pmax);
domkitError("Missing required argument "+c.arguments[i].name,e.pmin,e.pmax);
for( a in e.attributes ) {
var pname = haxeToCss(a.name);
switch( pname ) {
Expand All @@ -469,7 +563,7 @@ class DomkitChecker extends ScriptEditor.ScriptChecker {
unify(@:privateAccess checker.typeExpr(f.e, Value), TBool, c,"class",f.e);
}
default:
throw new domkit.Error("Invalid class value",a.pmin,a.pmax);
domkitError("Invalid class value",a.pmin,a.pmax);
}
}
continue;
Expand All @@ -482,13 +576,13 @@ class DomkitChecker extends ScriptEditor.ScriptChecker {
case RawValue(str) if( str.indexOf(" ") < 0 ):
defineIdent(c, "#"+str);
default:
throw new domkit.Error("Auto-id reference invalid class",a.pmin,a.pmax);
domkitError("Auto-id reference invalid class",a.pmin,a.pmax);
}
}
case RawValue(id):
defineIdent(c, "#"+id);
case Code(_):
throw new domkit.Error("Not constant id is not allowed",a.pmin,a.pmax);
domkitError("Not constant id is not allowed",a.pmin,a.pmax);
}
continue;
default:
Expand All @@ -501,7 +595,7 @@ class DomkitChecker extends ScriptEditor.ScriptChecker {
cur = cur.parent;
}
if( t == null )
throw new domkit.Error(c.name+" does not have property "+a.name, a.pmin, a.pmax);
domkitError(c.name+" does not have property "+a.name, a.pmin, a.pmax);
var pt = switch( a.value ) {
case RawValue(_): t_string;
case Code(code): typeCode(code, a.vmin);
Expand Down Expand Up @@ -544,9 +638,9 @@ class DomkitChecker extends ScriptEditor.ScriptChecker {
case Text(_):
// nothing
case CodeBlock(v):
throw new domkit.Error("Code block not supported", e.pmin);
domkitError("Code block not supported", e.pmin);
case Macro(id):
throw new domkit.Error("Macro not supported", e.pmin);
domkitError("Macro not supported", e.pmin);
}
}

Expand Down
2 changes: 1 addition & 1 deletion hide/comp/ScriptEditor.hx
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ class ScriptChecker {
#if !hl
class ScriptEditor extends CodeEditor {

var checker : ScriptChecker;
public var checker(default,null) : ScriptChecker;
var checkTypes : Bool;

public function new( script : String, ?checker : ScriptChecker, ?parent : Element, ?root : Element, ?lang = "javascript" ) {
Expand Down
59 changes: 18 additions & 41 deletions hide/view/Domkit.hx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ class Domkit extends FileView {
var paramsEditor : hide.comp.ScriptEditor;
var prevSave : { css : String, dml : String, params : String };
var checker : hide.comp.DomkitEditor.DomkitChecker;
static var DEFAULT_PARAMS = "var params = {}";

override function onDisplay() {

Expand Down Expand Up @@ -60,32 +59,12 @@ class Domkit extends FileView {
</div>');

var content = sys.io.File.getContent(getPath());
var cssText = "";
var paramsText = DEFAULT_PARAMS;

content = StringTools.trim(content);

if( StringTools.startsWith(content,"<css>") ) {
var pos = content.indexOf("</css>");
cssText = StringTools.trim(content.substr(5, pos - 6));
content = content.substr(pos + 6);
content = StringTools.trim(content);
}

if( StringTools.startsWith(content,"<params>") ) {
var pos = content.indexOf("</params>");
paramsText = StringTools.trim(content.substr(8, pos - 9));
content = content.substr(pos + 9);
content = StringTools.trim(content);
}

var dmlText = content;

prevSave = { css : cssText, dml : dmlText, params : paramsText };
dmlEditor = new hide.comp.DomkitEditor(config, DML, dmlText, element.find(".dmlEditor"));
cssEditor = new hide.comp.DomkitEditor(config, Less, cssText, dmlEditor.checker, element.find(".cssEditor"));
var data = hrt.impl.DomkitViewer.parse(content);
prevSave = data;
dmlEditor = new hide.comp.DomkitEditor(config, DML, data.dml, element.find(".dmlEditor"));
cssEditor = new hide.comp.DomkitEditor(config, Less, data.css, dmlEditor.checker, element.find(".cssEditor"));
var checker = new hide.comp.DomkitEditor.DomkitChecker(config);
paramsEditor = new hide.comp.ScriptEditor(paramsText, checker, element.find(".paramsEditor"));
paramsEditor = new hide.comp.ScriptEditor(data.params, checker, element.find(".paramsEditor"));
cssEditor.onChanged = dmlEditor.onChanged = paramsEditor.onChanged = check;
cssEditor.onSave = dmlEditor.onSave = paramsEditor.onSave = save;

Expand All @@ -99,13 +78,9 @@ class Domkit extends FileView {
var allParams = new Map();
dmlEditor.checker.params = allParams;
var comp = dmlEditor.getComponent();
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 tparams = @:privateAccess paramsEditor.checker.checker.locals.get("params");
var checker = cast(paramsEditor.checker,hide.comp.DomkitEditor.DomkitChecker);
var tparams = try @:privateAccess checker.typeCode(paramsEditor.code,0) catch( e : hscript.Expr.Error ) null;
if( tparams == null ) tparams = TAnon([]);
switch( tparams ) {
case TAnon(fields):
Expand Down Expand Up @@ -151,15 +126,17 @@ class Domkit extends FileView {

override function save() {
super.save();
var cssText = trimSpaces(cssEditor.code);
var dmlText = trimSpaces(dmlEditor.code);
var paramsText = trimSpaces(paramsEditor.code);
var hasParams = paramsText != DEFAULT_PARAMS;
prevSave = { css : cssText, dml : dmlText, params : paramsText };
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\n')+(hasParams?'<params>\n$paramsText\n</params>\n\n':'')+dmlText);
var data = {
css : trimSpaces(cssEditor.code),
dml : trimSpaces(dmlEditor.code),
params : trimSpaces(paramsEditor.code),
};
var str = hrt.impl.DomkitViewer.toStr(data);
prevSave = data;
if( data.css != cssEditor.code ) cssEditor.setCode(data.css);
if( data.dml != dmlEditor.code ) dmlEditor.setCode(data.dml);
if( data.params != paramsEditor.code ) paramsEditor.setCode(data.params);
sys.io.File.saveContent(getPath(),str);
}

override function getDefaultContent() {
Expand Down
Loading

0 comments on commit e6091d6

Please sign in to comment.