Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust to tink_hxx v1. #6

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/bin
/node_modules
5 changes: 4 additions & 1 deletion dev.hxml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@
-lib travix
-cp tests
-main Playground
--interp
# --interp
--dce full
-D analyzer-optimize
-js bin/test.js
-dce full
7 changes: 3 additions & 4 deletions haxe_libraries/coconut.data.hxml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# @install: lix --silent download "gh://github.com/MVCoconut/coconut.data#b9dc933bbc8d42c8c144a81cf4b1cc96ffa8740c" into coconut.data/0.12.0/github/b9dc933bbc8d42c8c144a81cf4b1cc96ffa8740c
# @install: lix --silent download "gh://github.com/MVCoconut/coconut.data#8541cb4c07cd32e70229d8b97e16bd8fd4d546f8" into coconut.data/0.12.1/github/8541cb4c07cd32e70229d8b97e16bd8fd4d546f8
-lib tink_anon
-lib tink_priority
-lib tink_pure
-lib tink_state
-cp ${HAXE_LIBCACHE}/coconut.data/0.12.0/github/b9dc933bbc8d42c8c144a81cf4b1cc96ffa8740c/src
-D coconut.data=0.12.0
--macro coconut.data.macros.Setup.run()
-cp ${HAXE_LIBCACHE}/coconut.data/0.12.1/github/8541cb4c07cd32e70229d8b97e16bd8fd4d546f8/src
-D coconut.data=0.12.1
6 changes: 3 additions & 3 deletions haxe_libraries/coconut.ui.hxml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# @install: lix --silent download "gh://github.com/MVCoconut/coconut.ui#cd52df4838608e02ad593bf4a5eb222bb5673308" into coconut.ui/0.11.2/github/cd52df4838608e02ad593bf4a5eb222bb5673308
# @install: lix --silent download "gh://github.com/MVCoconut/coconut.ui#98a1c9d1a07ab54d9d0636f84a12c1969c345e2a" into coconut.ui/0.12.0/github/98a1c9d1a07ab54d9d0636f84a12c1969c345e2a
-lib coconut.data
-lib tink_anon
-lib tink_hxx
-cp ${HAXE_LIBCACHE}/coconut.ui/0.11.2/github/cd52df4838608e02ad593bf4a5eb222bb5673308/src
-D coconut.ui=0.11.2
-cp ${HAXE_LIBCACHE}/coconut.ui/0.12.0/github/98a1c9d1a07ab54d9d0636f84a12c1969c345e2a/src
-D coconut.ui=0.12.0
6 changes: 3 additions & 3 deletions haxe_libraries/tink_anon.hxml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-D tink_anon=0.5.0
# @install: lix --silent download "gh://github.com/haxetink/tink_anon#d6d341c39e086920743e4dac514aae07c6f5003d" into tink_anon/0.5.0/github/d6d341c39e086920743e4dac514aae07c6f5003d
# @install: lix --silent download "gh://github.com/haxetink/tink_anon#0277e6e3f97a7878f1aa9aeeccc4b7be0e9c82bc" into tink_anon/0.7.0/github/0277e6e3f97a7878f1aa9aeeccc4b7be0e9c82bc
-lib tink_macro
-cp ${HAXE_LIBCACHE}/tink_anon/0.5.0/github/d6d341c39e086920743e4dac514aae07c6f5003d/src
-cp ${HAXE_LIBCACHE}/tink_anon/0.7.0/github/0277e6e3f97a7878f1aa9aeeccc4b7be0e9c82bc/src
-D tink_anon=0.7.0
6 changes: 3 additions & 3 deletions haxe_libraries/tink_core.hxml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# @install: lix --silent download "gh://github.com/haxetink/tink_core#914f3cda113652bfa62226664fae49e17bd1730b" into tink_core/2.0.0-rc.3/github/914f3cda113652bfa62226664fae49e17bd1730b
-cp ${HAXE_LIBCACHE}/tink_core/2.0.0-rc.3/github/914f3cda113652bfa62226664fae49e17bd1730b/src
-D tink_core=2.0.0-rc.3
# @install: lix --silent download "gh://github.com/haxetink/tink_core#323f80d2ae63036e5b324dc68775f79e98bde396" into tink_core/2.1.1/github/323f80d2ae63036e5b324dc68775f79e98bde396
-cp ${HAXE_LIBCACHE}/tink_core/2.1.1/github/323f80d2ae63036e5b324dc68775f79e98bde396/src
-D tink_core=2.1.1
4 changes: 2 additions & 2 deletions haxe_libraries/tink_hxx.hxml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# @install: lix --silent download "gh://github.com/haxetink/tink_hxx#0d6cda883d5ef4c1186dbad476e016b98aad68b8" into tink_hxx/0.25.0/github/0d6cda883d5ef4c1186dbad476e016b98aad68b8
# @install: lix --silent download "gh://github.com/haxetink/tink_hxx#783a4606516582567d9f6f12505740ba48334c39" into tink_hxx/0.25.0/github/783a4606516582567d9f6f12505740ba48334c39
-lib html-entities
-lib tink_anon
-lib tink_parse
-cp ${HAXE_LIBCACHE}/tink_hxx/0.25.0/github/0d6cda883d5ef4c1186dbad476e016b98aad68b8/src
-cp ${HAXE_LIBCACHE}/tink_hxx/0.25.0/github/783a4606516582567d9f6f12505740ba48334c39/src
-D tink_hxx=0.25.0
6 changes: 3 additions & 3 deletions haxe_libraries/tink_state.hxml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# @install: lix --silent download "haxelib:/tink_state#1.0.0-beta.2" into tink_state/1.0.0-beta.2/haxelib
# @install: lix --silent download "gh://github.com/haxetink/tink_state#c693cf38fb4c5e19163ceb3770755fa85e22cec9" into tink_state/1.0.0-beta.3/github/c693cf38fb4c5e19163ceb3770755fa85e22cec9
-lib tink_core
-cp ${HAXE_LIBCACHE}/tink_state/1.0.0-beta.2/haxelib/src
-D tink_state=1.0.0-beta.2
-cp ${HAXE_LIBCACHE}/tink_state/1.0.0-beta.3/github/c693cf38fb4c5e19163ceb3770755fa85e22cec9/src
-D tink_state=1.0.0-beta.3
18 changes: 18 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "coconut.html",
"version": "1.0.0",
"description": "A special coconut backend to render plain HTML, for use in static generators and server side rendering.",
"main": "index.js",
"directories": {
"test": "tests"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"lix": "^15.12.4"
}
}
7 changes: 6 additions & 1 deletion src/coconut/html/FakeCallback.hx
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
package coconut.html;

abstract FakeCallback(Dynamic) {}
@:fromHxx(
transform = coconut.html.FakeCallback.create(_)
)
abstract FakeCallback(Dynamic) {
macro static public function create(e);
}
10 changes: 10 additions & 0 deletions src/coconut/html/FakeCallback.macro.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package coconut.html;

abstract FakeCallback(Dynamic) {
static function create(e:haxe.macro.Expr) {
return switch e.expr {
case EConst(CString(_)): macro @:pos(e.pos) cast $e;
default: macro null;
}
}
}
27 changes: 15 additions & 12 deletions src/coconut/html/Html.hx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package coconut.html;

import haxe.DynamicAccess;
import coconut.html.RenderResult;
import tink.HtmlString;

using StringTools;

@:build(coconut.html.macros.Setup.addTags())
Expand Down Expand Up @@ -35,12 +37,13 @@ private class HtmlFragment implements RenderResultObject {

private typedef HtmlFragmentAttr = { content:String, ?className:tink.domspec.ClassName, ?tag:String };

@:transitive
abstract AttrValue(Dynamic) from Int from String from Bool from Float {
public inline function toString():Null<String>
return
#if js
switch js.Lib.typeof(this) {
case 'string': tink.HtmlString.escape(this);
case 'string': HtmlString.escape(this);
case 'boolean' if (this): '';
case 'number': '' + (this:Float);
default: null;
Expand All @@ -50,19 +53,21 @@ abstract AttrValue(Dynamic) from Int from String from Bool from Float {
case TBool if (this): '';
case TInt: '' + (this:Int);
case TFloat: '' + (this:Float);
case TClass(String): tink.HtmlString.escape(this);
case TClass(String): HtmlString.escape(this);
default: null;
}
#end
}

private class Tag implements RenderResultObject {
final tag:String;
final isVoid:Bool;
final attr:DynamicAccess<AttrValue>;
final children:Children;

public function new(tag, attr, ?children) {
public function new(tag, isVoid, attr, ?children) {
this.tag = tag;
this.isVoid = isVoid;
this.attr = attr;
this.children = children;
}
Expand All @@ -86,14 +91,12 @@ private class Tag implements RenderResultObject {
}
}

switch children {
case null:
buf.addRaw('/>');
default:
buf.addRaw('>');
for (c in children)
c.renderInto(implicits, buf);
buf.addRaw('</$tag>');
}
buf.addRaw('>');

if (isVoid) return;

for (c in children)
c.renderInto(implicits, buf);
buf.addRaw('</$tag>');
}
}
23 changes: 23 additions & 0 deletions src/coconut/html/Implicit.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package coconut.html;

import tink.htmlstring.HtmlBuffer;
import coconut.ui.internal.ImplicitContext;
import coconut.html.RenderResult.RenderResultObject;

class Implicit implements RenderResultObject {

final children:Children;
final defaults:ImplicitValues;

public function new(attr) {
this.children = attr.children;
this.defaults = attr.defaults;
}

public function renderInto(implicits:ImplicitContext, buffer:HtmlBuffer) {
var ctx = new ImplicitContext(implicits);
ctx.update(defaults);
for (c in children)
c.renderInto(ctx, buffer);
}
}
133 changes: 133 additions & 0 deletions src/coconut/html/macros/Generator.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package coconut.html.macros;

#if macro
import haxe.macro.Type;
import tink.hxx.StringAt;
import tink.hxx.Tag;
import haxe.macro.Context;
import haxe.macro.Expr;

using haxe.macro.Tools;
using StringTools;
using tink.MacroApi;

class Generator extends tink.hxx.Generator {

static function unwrap(e:Expr)
return if (e == null) null else switch e.expr {
case EParenthesis(e) | ECheckType(e, _) | ECast(e, _): unwrap(e);
default: e;
}

static function tUnwrap(e:TypedExpr)
return switch e.expr {
case TParenthesis(e) | TCast(e, _) | TMeta(_, e): tUnwrap(e);
default: e;
}

override function childList(c:tink.hxx.Node.Children, ?t:Type):{expr:ExprDef, pos:Position} {
return
if (t != null && t.toString() == 'coconut.html.Children' && c == null || c.value.length == 0) macro [];
else super.childList(c, t);
}

override function invoke(name:StringAt, create:TagCreate, args:Array<Expr>, pos:Position):{expr:ExprDef, pos:Position} {

var tagName = name.value;

switch tink.domspec.Macro.tags[tagName] {
case null:
case tag:

switch Context.typeExpr(macro @:pos(name.pos) $i{name.value}).expr {
case TField(_, FStatic(_.toString() => 'coconut.html.Html', _)):
default: return super.invoke(name, create, args, pos);
}

switch unwrap(args[1]).expr {
case EObjectDecl(fields):
var dyn = [];
var stat = [];

for (f in fields) switch tUnwrap(Context.typeExpr(f.expr)) {
case { expr: TConst(c) }:
switch c {
case TInt(Std.string(_) => s)
| TFloat(s) | TString(_.htmlEscape() => s):
stat.push(' ${f.field}="$s"');
case TBool(b):
if (b)
stat.push(' ${f.field}');
default:
}

case e:
var v = Context.storeTypedExpr(e),
attr = ' ${f.field}';

dyn.push(
switch Context.followWithAbstracts(e.t).toString() {
case 'Bool': macro if ($v) $v{attr} else '';
case 'Int' | 'Float':
attr += '="';
macro $v{attr} + $v + '"';
case 'String':
attr += '="';
macro $v{attr} + tink.HtmlString.escape($v) + '"';
case t: e.pos.error('Cannot handle ${t.toString()}');
}
);
}

var start = '<${tagName}${stat.join('')}';

var noArgs = switch unwrap(args[2]) {
case null, macro null, macro []: true;
default: false;
}

var end =
if (noArgs)
if (tag.kind == VOID) '>';
else '></$tagName>';
else '>';

var open =
switch dyn {
case []:
macro $v{start + end};
default:
var e = macro $v{start};
for (a in dyn)
e = macro $e + $a;
macro $e + $v{end};
}

open = raw(open);

if (noArgs)
return open;
else {
var close = macro $v{'</$tagName>'};
close = raw(close);

return switch unwrap(args[2]) {
case macro [$e]:
macro coconut.html.RenderResult.fragment({}, [$open, $e, $close]);
case e:
macro coconut.html.RenderResult.fragment({}, {
var __open = $open;
$e.prepend(__open).append($close);
});
}
}
default:
}
}
return super.invoke(name, create, args, pos);
}

static function raw(e)
return macro coconut.html.RenderResult.raw(new tink.HtmlString($e));
}
#end
3 changes: 1 addition & 2 deletions src/coconut/html/macros/HXX.hx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ package coconut.html.macros;

#if macro
import coconut.ui.macros.Helpers;
import tink.hxx.*;

using tink.MacroApi;

class HXX {
static final generator = new Generator(Tag.extractAllFrom(macro coconut.html.Html));
static final generator = new tink.hxx.Generator();

static public function parse(e)
return Helpers.parse(e, generator, 'coconut.html.RenderResult.fragment').as(macro : coconut.html.RenderResult);
Expand Down
8 changes: 2 additions & 6 deletions src/coconut/html/macros/Setup.hx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ using tink.MacroApi;
class Setup {

static function perform() {
tink.hxx.Helpers.setCustomTransformer('coconut.html.FakeCallback', {
reduceType: t -> t,
postprocessor: PUntyped(e -> macro @:pos(e.pos) null),
});
}

static inline var NAMELESS = '';
Expand Down Expand Up @@ -58,7 +54,7 @@ class Setup {
opt: false
}
];
var callArgs = [macro $v{name}, macro cast attr];
var callArgs = [macro $v{name}, macro $v{tag.kind == VOID}, macro cast attr];
if (tag.kind != VOID) {
args.push({
name: 'children',
Expand All @@ -69,7 +65,7 @@ class Setup {
}
{
args: args,
expr: macro return new Tag($a{callArgs}),//VNode.native($a{callArgs}),
expr: macro return new Tag($a{callArgs}),
ret: macro : coconut.html.RenderResult
}
})
Expand Down
3 changes: 3 additions & 0 deletions src/coconut/ui/Implicit.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package coconut.ui;

typedef Implicit = coconut.html.Implicit;
Loading