^ This tag-name will be lower-cased when parsed by browser Should this just be XML? - Pro: parsing is easier. it's probably just a better tool. - Con: XML's brand sucks; html is universal and a better fit for mass appeal We totally lose the "fork the web" angle if we go with xml.
Vec //... no. }}> //is there a better, shorter name for `component`? //it's overloaded with a different concept from game engines //(the C in ECS) AND it would be ergonomically //beneficial to have a shorter name for use in expressions, //instead of `component.some_property` // Module, widget, entity, movie clip, // component, // ... Alphabet of injectables: `datum`: used by `repeat` to expose iterated data to expressions - How to reach across nested repeat frames? for i; for j - `this`: (or `self`, `me`, `component`, etc.) used as a reference to the containing component and its properties / children ` #template! |datum| { } #template-src!("./path/to/src.html") #template-behind! //automatically load same_file_name.html #template! @foreach (panel in panels) { } #template!( @foreach (panel in panels) { } ) // Properties: can be inlined or declared alongside #properties!( #outer-stacker { size: (Size::Percent(100.0),Size::Percent(100.0)) transform: || {} direction: cells: gutter: } ) // We really want language server aid here... // What about in rust, outside of macro: properties: [ //Vec #join!(#outer-stacker) { //automatically determine that this is a StackerProperties } ] **If we commit to full custom parsers**, we could do a CSS-like syntax, handling literals as needed w/ parser — and another parser for expressions. That is, three total parsers: - CSS-like parser for property-value binding - Expression parser, including stream injection - Template parser, Blazor-like // Properties: can be inlined or declared alongside ``` #template!( ) #properties!( #outer-stacker { size: 50px, (dash) => { dash.height }px, //expression syntax is JS-lambda-like, transform: { translate: 20px, x, //x is "don't care" i.e. "default" scale: 100%, 90%, anchor: 50%, 50%, } orientation: vertical, //enums are tricky. single global keywords are most ergonomic //but have obvious namespace collision risks. //To start we could give judicious global real estate to //orientation.{vertical|horizontal}, toward.{top,right,bottom,left} cells: 10, gutter: 10px, } #rect-0 { } ) #properties!( #outer-stacker { size: (50px, (dash) => { dash.height }px), //expression syntax is JS-lambda-like, transform: { translate: (20px, x); //x is "don't care" i.e. "default" scale: (100%, 90%); anchor: (50%, 50%), } orientation: vertical, //enums are tricky. single global keywords are most ergonomic //but have obvious namespace collision risks. //To start we could give judicious global real estate to //orientation.{vertical|horizontal}, toward.{top,right,bottom,left} cells: 10, gutter: 10px, } #rect-0 { } ) ``` It's important to have auto-complete here. We'll want to parse (or duplicate/declare, in a manifest) the source typedefs ```rust #template!( ) #properties!( #outer-stacker { } ) ``` ## Expressions — should be CEL-like Snippet from: https://github.com/google/cel-spec/blob/7972b9076513e6a4bbd184f9d073db949ea53c65/README.md ``` // Condition account.balance >= transaction.withdrawal || (account.overdraftProtection && account.overdraftLimit >= transaction.withdrawal - account.balance) // Object construction common.GeoPoint{ latitude: 10.0, longitude: -5.5 } ```