├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── Towser.svg ├── build.hxml ├── haxelib.json ├── src └── towser │ ├── RenderFunction.hx │ ├── RenderType.hx │ ├── Towser.hx │ ├── html │ ├── Attribute.hx │ ├── Attributes.hx │ ├── Element.hx │ ├── Event.hx │ ├── Events.hx │ ├── Html.hx │ ├── Lazy.hx │ ├── Node.hx │ └── Text.hx │ └── platform │ ├── DomBuilder.hx │ ├── HtmlHelper.hx │ ├── LazyMap.hx │ ├── client │ ├── ClientDomBuilder.hx │ └── ClientTowser.hx │ ├── macro │ ├── MacroDomBuilder.hx │ └── MacroTowser.hx │ └── server │ ├── ServerDomBuilder.hx │ └── ServerTowser.hx └── tests ├── Main.hx └── TestApp.hx /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: haxe 2 | haxe: 3 | # - "3.4.4" 4 | - development # the latest stable release defined in https://haxe.org/download/list/ 5 | script: 6 | - haxe build.hxml -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Jeremy Meltingtallow 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | Towser 3 |
4 | 5 | # Towser [![Build Status](https://travis-ci.org/PongoEngine/Towser.svg?branch=master)](https://travis-ci.org/PongoEngine/Towser) [![Join the chat at https://gitter.im/pongo-towser/community](https://badges.gitter.im/pongo-towser/community.svg)](https://gitter.im/pongo-towser/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 6 | 🐶Incremental Dom + Haxe + Elm Architechture + SSR 7 | 8 | ## Table of Contents 9 | 10 | - [About](#about) 11 | - [Current Tasks](#current-tasks) 12 | - [Features](#features) 13 | - [Hello World](#hello-world) 14 | - [Why Haxe and why Mutability?](#why-haxe-and-why-mutability) 15 | 16 | ## About 17 | **Towser is the Mutable Elm Architechture** built using Haxe and Google's Incremental-Dom. Towser can easily be adopted into any node framework for serverside rendering using the compiler define '-D backend'. 18 | 19 | ## Current Tasks 20 | Towser is fully functional for making MVU applications but is far from being complete. Below is what you can expect now and in the future. 21 | - [ ] Documentation 22 | - [x] MVU 23 | - [x] SSR Strings 24 | - [ ] Generic SSR functionality 25 | - [ ] Attribute / Element array pool 26 | - [ ] CMD line utility for new projects 27 | - [ ] Example projects 28 | 29 | ## Features 30 | A few of the features you get with Towser 31 | - One-way data flow 32 | - Get / Set model 33 | - Manually trigger renders 34 | - Lazy wrappers for render functions 35 | - Mutable Elm Architcture 36 | 37 | ## Hello World 38 | ```haxe 39 | import towser.RenderType; 40 | import towser.RenderFunction; 41 | import towser.html.Event; 42 | import towser.html.Attributes.*; 43 | import towser.html.Html.*; 44 | import towser.html.Events.*; 45 | import towser.Towser; 46 | 47 | class TestApp { 48 | public static function view(model:Model) : RenderFunction 49 | { 50 | return switch model.section { 51 | case Hello: div([class_("full-screen"), onclick(ChangeName.bind("Robot"))], [ 52 | h1([], [text("Hello")]), 53 | p([], [text(model.name)]) 54 | ]); 55 | case VoidElements: div([], [ 56 | area([]), 57 | br([]), 58 | col([]), 59 | embed([]), 60 | hr([]), 61 | img([]), 62 | input([]), 63 | param([]), 64 | source([]), 65 | track([]), 66 | wbr([]) 67 | ]); 68 | } 69 | } 70 | 71 | public static function update(towser :Towser, msg:Msg, model:Model) : RenderType 72 | { 73 | return switch msg { 74 | case ChangeName(name, e): 75 | model.name = name; 76 | FULL; 77 | case ChangeSection(section_): 78 | model.section = section_; 79 | FULL; 80 | } 81 | } 82 | } 83 | 84 | enum Msg { 85 | ChangeName(name :String, e :MouseEvent); 86 | ChangeSection(section :Section); 87 | } 88 | 89 | typedef Model = 90 | { 91 | var name :String; 92 | var section :Section; 93 | } 94 | 95 | enum Section 96 | { 97 | Hello; 98 | VoidElements; 99 | } 100 | 101 | ``` 102 | 103 | ## Why Haxe and why Mutability? 104 | Haxe is a strongly typed programming language that transpiles to other target languages. It has many functional qualities like exhaustive pattern matching, first class functions, and currying to name a few. These functional features adapt to the Elm Architecture quite well given that Elm is a functional language. Additionaly Haxe has Abstracts which wrap concrete types. These abstract wrappers come with zero runtime cost and make for wonderful APIs. Lastly haxe has mutable data types. I love making games and although it is possible to make a purely functional game I would rather not. 105 | 106 | ### License 107 | 108 | Towser is [MIT licensed](./LICENSE). 109 | -------------------------------------------------------------------------------- /Towser.svg: -------------------------------------------------------------------------------- 1 | Towser_LogoAsset 1 -------------------------------------------------------------------------------- /build.hxml: -------------------------------------------------------------------------------- 1 | -cp src/ 2 | -cp tests/ 3 | -main Main 4 | -D client 5 | -lib hx3compat 6 | --js out.js 7 | --no-output 8 | 9 | --next 10 | 11 | -cp src/ 12 | -cp tests/ 13 | -main Main 14 | -D backend 15 | -lib hx3compat 16 | --interp 17 | -------------------------------------------------------------------------------- /haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "towser", 3 | "url" : "https://github.com/PongoEngine/Towser", 4 | "license": "MIT", 5 | "tags": ["incremental-dom", "declarative", "web", "framework", "elm", "architecture"], 6 | "description": "Incremental Dom + Haxe + Elm Architechture", 7 | "version": "0.1.1", 8 | "classPath": "src/", 9 | "releasenote": "Add Partial rendering", 10 | "contributors": ["Jeremy"], 11 | "dependencies": {} 12 | } -------------------------------------------------------------------------------- /src/towser/RenderFunction.hx: -------------------------------------------------------------------------------- 1 | package towser; 2 | 3 | import towser.Towser; 4 | 5 | /** 6 | * 7 | */ 8 | typedef RenderFunction = Towser -> Void; -------------------------------------------------------------------------------- /src/towser/RenderType.hx: -------------------------------------------------------------------------------- 1 | package towser; 2 | 3 | import towser.html.Element; 4 | 5 | enum RenderType 6 | { 7 | NONE; 8 | FULL; 9 | PARTIAL(element :Element, render :RenderFunction); 10 | } -------------------------------------------------------------------------------- /src/towser/Towser.hx: -------------------------------------------------------------------------------- 1 | package towser; 2 | 3 | import towser.platform.LazyMap; 4 | 5 | class Towser 6 | { 7 | public var markup (get, null) :String; 8 | public var model (get, set) :Model; 9 | 10 | public function new(element :String, update :Towser -> Msg -> Model -> RenderType, view :Model -> RenderFunction, model :Model) : Void 11 | { 12 | _arch = new 13 | #if backend towser.platform.server.ServerTowser(this, element, update, view, model); 14 | #elseif macro towser.platform.macro.MacroTowser(this, element, update, view, model); 15 | #elseif client towser.platform.client.ClientTowser(this, element, update, view, model); 16 | #end 17 | } 18 | 19 | public inline function update(msg :Msg) : Void 20 | { 21 | _arch.update(msg, this); 22 | } 23 | 24 | private inline function get_model() : Model 25 | { 26 | return _arch.getModel(); 27 | } 28 | 29 | private inline function set_model(model :Model) : Model 30 | { 31 | _arch.setModel(model); 32 | return model; 33 | } 34 | 35 | private inline function get_markup() : String 36 | { 37 | return _arch.markup; 38 | } 39 | 40 | private var _arch 41 | #if backend :towser.platform.server.ServerTowser; 42 | #elseif macro :towser.platform.macro.MacroTowser; 43 | #elseif client :towser.platform.client.ClientTowser; 44 | #end 45 | @:allow(towser.html.Lazy) 46 | private var _lazyMap = new LazyMap(); 47 | } -------------------------------------------------------------------------------- /src/towser/html/Attribute.hx: -------------------------------------------------------------------------------- 1 | package towser.html; 2 | 3 | typedef Attribute = Towser -> Void; -------------------------------------------------------------------------------- /src/towser/html/Attributes.hx: -------------------------------------------------------------------------------- 1 | package towser.html; 2 | 3 | import haxe.extern.EitherType; 4 | import towser.platform.DomBuilder; 5 | 6 | @:extern class Attributes 7 | { 8 | public static inline function accept(value :String) : Attribute 9 | { 10 | return (t) -> DomBuilder.attr("accept", value); 11 | } 12 | 13 | public static inline function acceptCharset(value :String) : Attribute 14 | { 15 | return (t) -> DomBuilder.attr("accept-charset", value); 16 | } 17 | 18 | public static inline function accesskey(value :String) : Attribute 19 | { 20 | return (t) -> DomBuilder.attr("accesskey", value); 21 | } 22 | 23 | public static inline function action(value :String) : Attribute 24 | { 25 | return (t) -> DomBuilder.attr("action", value); 26 | } 27 | 28 | public static inline function align(value :String) : Attribute 29 | { 30 | return (t) -> DomBuilder.attr("align", value); 31 | } 32 | 33 | public static inline function allow(value :String) : Attribute 34 | { 35 | return (t) -> DomBuilder.attr("allow", value); 36 | } 37 | 38 | public static inline function alt(value :String) : Attribute 39 | { 40 | return (t) -> DomBuilder.attr("alt", value); 41 | } 42 | 43 | public static inline function async(value :Bool) : Attribute 44 | { 45 | return function(t) { 46 | if(value) DomBuilder.attr("async", true); 47 | } 48 | } 49 | 50 | public static inline function autocapitalize(value :String) : Attribute 51 | { 52 | return (t) -> DomBuilder.attr("autocapitalize", value); 53 | } 54 | 55 | public static inline function autocomplete(value :Bool) : Attribute 56 | { 57 | return function(t) { 58 | if(value) DomBuilder.attr("autocomplete", true); 59 | } 60 | } 61 | 62 | public static inline function autofocus(value :Bool) : Attribute 63 | { 64 | return function(t) { 65 | if(value) DomBuilder.attr("autofocus", true); 66 | } 67 | } 68 | 69 | public static inline function autoplay(value :Bool) : Attribute 70 | { 71 | return function(t) { 72 | if(value) DomBuilder.attr("autoplay", true); 73 | } 74 | } 75 | 76 | public static inline function background(value :String) : Attribute 77 | { 78 | return (t) -> DomBuilder.attr("background", value); 79 | } 80 | 81 | public static inline function bgcolor(value :String) : Attribute 82 | { 83 | return (t) -> DomBuilder.attr("bgcolor", value); 84 | } 85 | 86 | public static inline function border(value :Bool) : Attribute 87 | { 88 | return function(t) { 89 | if(value) DomBuilder.attr("border", true); 90 | } 91 | } 92 | 93 | public static inline function buffered(value :String) : Attribute 94 | { 95 | return (t) -> DomBuilder.attr("buffered", value); 96 | } 97 | 98 | public static inline function challenge(value :Bool) : Attribute 99 | { 100 | return function(t) { 101 | if(value) DomBuilder.attr("challenge", true); 102 | } 103 | } 104 | 105 | public static inline function charset(value :String) : Attribute 106 | { 107 | return (t) -> DomBuilder.attr("charset", value); 108 | } 109 | 110 | public static inline function checked(value :Bool) : Attribute 111 | { 112 | return function(t) { 113 | if(value) DomBuilder.attr("checked", true); 114 | } 115 | } 116 | 117 | public static inline function cite(value :String) : Attribute 118 | { 119 | return (t) -> DomBuilder.attr("cite", value); 120 | } 121 | 122 | public static inline function class_(value :String) : Attribute 123 | { 124 | return (t) -> DomBuilder.attr("class", value); 125 | } 126 | 127 | public static inline function code(value :String) : Attribute 128 | { 129 | return (t) -> DomBuilder.attr("code", value); 130 | } 131 | 132 | public static inline function codebase(value :String) : Attribute 133 | { 134 | return (t) -> DomBuilder.attr("codebase", value); 135 | } 136 | 137 | public static inline function color(value :String) : Attribute 138 | { 139 | return (t) -> DomBuilder.attr("color", value); 140 | } 141 | 142 | public static inline function cols(value :String) : Attribute 143 | { 144 | return (t) -> DomBuilder.attr("cols", value); 145 | } 146 | 147 | public static inline function colspan(value :String) : Attribute 148 | { 149 | return (t) -> DomBuilder.attr("colspan", value); 150 | } 151 | 152 | public static inline function content(value :String) : Attribute 153 | { 154 | return (t) -> DomBuilder.attr("content", value); 155 | } 156 | 157 | public static inline function contenteditable(value :Bool) : Attribute 158 | { 159 | return function(t) { 160 | if(value) DomBuilder.attr("contenteditable", true); 161 | } 162 | } 163 | 164 | public static inline function contextmenu(value :String) : Attribute 165 | { 166 | return (t) -> DomBuilder.attr("contextmenu", value); 167 | } 168 | 169 | public static inline function controls(value :Bool) : Attribute 170 | { 171 | return function(t) { 172 | if(value) DomBuilder.attr("controls", true); 173 | } 174 | } 175 | 176 | public static inline function coords(value :String) : Attribute 177 | { 178 | return (t) -> DomBuilder.attr("coords", value); 179 | } 180 | 181 | public static inline function crossorigin(value :String) : Attribute 182 | { 183 | return (t) -> DomBuilder.attr("crossorigin", value); 184 | } 185 | 186 | public static inline function csp(value :String) : Attribute 187 | { 188 | return (t) -> DomBuilder.attr("csp", value); 189 | } 190 | 191 | public static inline function data(value :String) : Attribute 192 | { 193 | return (t) -> DomBuilder.attr("data", value); 194 | } 195 | 196 | public static inline function datetime(value :String) : Attribute 197 | { 198 | return (t) -> DomBuilder.attr("datetime", value); 199 | } 200 | 201 | public static inline function decoding(value :String) : Attribute 202 | { 203 | return (t) -> DomBuilder.attr("decoding", value); 204 | } 205 | 206 | public static inline function default_(value :Bool) : Attribute 207 | { 208 | return function(t) { 209 | if(value) DomBuilder.attr("default", true); 210 | } 211 | } 212 | 213 | public static inline function defer(value :Bool) : Attribute 214 | { 215 | return function(t) { 216 | if(value) DomBuilder.attr("defer", true); 217 | } 218 | } 219 | 220 | public static inline function dir(value :String) : Attribute 221 | { 222 | return (t) -> DomBuilder.attr("dir", value); 223 | } 224 | 225 | public static inline function directory(value :Bool) : Attribute 226 | { 227 | return function(t) { 228 | if(value) DomBuilder.attr("directory", true); 229 | } 230 | } 231 | 232 | public static inline function dirname(value :String) : Attribute 233 | { 234 | return (t) -> DomBuilder.attr("dirname", value); 235 | } 236 | 237 | public static inline function disabled(value :Bool) : Attribute 238 | { 239 | return function(t) { 240 | if(value) DomBuilder.attr("disabled", true); 241 | } 242 | } 243 | 244 | public static inline function download(value :String) : Attribute 245 | { 246 | return (t) -> DomBuilder.attr("download", value); 247 | } 248 | 249 | public static inline function draggable(value :String) : Attribute 250 | { 251 | return (t) -> DomBuilder.attr("draggable", value); 252 | } 253 | 254 | public static inline function dropzone(value :String) : Attribute 255 | { 256 | return (t) -> DomBuilder.attr("dropzone", value); 257 | } 258 | 259 | public static inline function enctype(value :String) : Attribute 260 | { 261 | return (t) -> DomBuilder.attr("enctype", value); 262 | } 263 | 264 | public static inline function enterkeyhint(value :String) : Attribute 265 | { 266 | return (t) -> DomBuilder.attr("enterkeyhint", value); 267 | } 268 | 269 | public static inline function for_(value :String) : Attribute 270 | { 271 | return (t) -> DomBuilder.attr("for", value); 272 | } 273 | 274 | public static inline function form(value :String) : Attribute 275 | { 276 | return (t) -> DomBuilder.attr("form", value); 277 | } 278 | 279 | public static inline function formaction(value :String) : Attribute 280 | { 281 | return (t) -> DomBuilder.attr("formaction", value); 282 | } 283 | 284 | public static inline function formenctype(value :String) : Attribute 285 | { 286 | return (t) -> DomBuilder.attr("formenctype", value); 287 | } 288 | 289 | public static inline function formmethod(value :String) : Attribute 290 | { 291 | return (t) -> DomBuilder.attr("formmethod", value); 292 | } 293 | 294 | public static inline function formnovalidate(value :Bool) : Attribute 295 | { 296 | return function(t) { 297 | if(value) DomBuilder.attr("formnovalidate", true); 298 | } 299 | } 300 | 301 | public static inline function formtarget(value :String) : Attribute 302 | { 303 | return (t) -> DomBuilder.attr("formtarget", value); 304 | } 305 | 306 | public static inline function headers(value :String) : Attribute 307 | { 308 | return (t) -> DomBuilder.attr("headers", value); 309 | } 310 | 311 | public static inline function height(value :String) : Attribute 312 | { 313 | return (t) -> DomBuilder.attr("height", value); 314 | } 315 | 316 | public static inline function hidden(value :Bool) : Attribute 317 | { 318 | return function(t) { 319 | if(value) DomBuilder.attr("hidden", true); 320 | } 321 | } 322 | 323 | public static inline function high(value :String) : Attribute 324 | { 325 | return (t) -> DomBuilder.attr("high", value); 326 | } 327 | 328 | public static inline function href(value :String) : Attribute 329 | { 330 | return (t) -> DomBuilder.attr("href", value); 331 | } 332 | 333 | public static inline function hreflang(value :String) : Attribute 334 | { 335 | return (t) -> DomBuilder.attr("hreflang", value); 336 | } 337 | 338 | public static inline function httpEquiv(value :String) : Attribute 339 | { 340 | return (t) -> DomBuilder.attr("http-equiv", value); 341 | } 342 | 343 | public static inline function icon(value :String) : Attribute 344 | { 345 | return (t) -> DomBuilder.attr("icon", value); 346 | } 347 | 348 | public static inline function id(value :String) : Attribute 349 | { 350 | return (t) -> DomBuilder.attr("id", value); 351 | } 352 | 353 | public static inline function importance(value :String) : Attribute 354 | { 355 | return (t) -> DomBuilder.attr("importance", value); 356 | } 357 | 358 | public static inline function integrity(value :String) : Attribute 359 | { 360 | return (t) -> DomBuilder.attr("integrity", value); 361 | } 362 | 363 | public static inline function intrinsicsize(value :String) : Attribute 364 | { 365 | return (t) -> DomBuilder.attr("intrinsicsize", value); 366 | } 367 | 368 | public static inline function inputmode(value :String) : Attribute 369 | { 370 | return (t) -> DomBuilder.attr("inputmode", value); 371 | } 372 | 373 | public static inline function ismap(value :Bool) : Attribute 374 | { 375 | return function(t) { 376 | if(value) DomBuilder.attr("ismap", true); 377 | } 378 | } 379 | 380 | public static inline function itemprop(value :String) : Attribute 381 | { 382 | return (t) -> DomBuilder.attr("itemprop", value); 383 | } 384 | 385 | public static inline function keytype(value :String) : Attribute 386 | { 387 | return (t) -> DomBuilder.attr("keytype", value); 388 | } 389 | 390 | public static inline function kind(value :String) : Attribute 391 | { 392 | return (t) -> DomBuilder.attr("kind", value); 393 | } 394 | 395 | public static inline function label(value :String) : Attribute 396 | { 397 | return (t) -> DomBuilder.attr("label", value); 398 | } 399 | 400 | public static inline function lang(value :String) : Attribute 401 | { 402 | return (t) -> DomBuilder.attr("lang", value); 403 | } 404 | 405 | public static inline function language(value :String) : Attribute 406 | { 407 | return (t) -> DomBuilder.attr("language", value); 408 | } 409 | 410 | public static inline function loading(value :String) : Attribute 411 | { 412 | return (t) -> DomBuilder.attr("loading", value); 413 | } 414 | 415 | public static inline function list(value :String) : Attribute 416 | { 417 | return (t) -> DomBuilder.attr("list", value); 418 | } 419 | 420 | public static inline function loop(value :Bool) : Attribute 421 | { 422 | return function(t) { 423 | if(value) DomBuilder.attr("loop", true); 424 | } 425 | } 426 | 427 | public static inline function low(value :String) : Attribute 428 | { 429 | return (t) -> DomBuilder.attr("low", value); 430 | } 431 | 432 | public static inline function manifest(value :String) : Attribute 433 | { 434 | return (t) -> DomBuilder.attr("manifest", value); 435 | } 436 | 437 | public static inline function max(value :String) : Attribute 438 | { 439 | return (t) -> DomBuilder.attr("max", value); 440 | } 441 | 442 | public static inline function maxlength(value :String) : Attribute 443 | { 444 | return (t) -> DomBuilder.attr("maxlength", value); 445 | } 446 | 447 | public static inline function minlength(value :String) : Attribute 448 | { 449 | return (t) -> DomBuilder.attr("minlength", value); 450 | } 451 | 452 | public static inline function media(value :String) : Attribute 453 | { 454 | return (t) -> DomBuilder.attr("media", value); 455 | } 456 | 457 | public static inline function method(value :String) : Attribute 458 | { 459 | return (t) -> DomBuilder.attr("method", value); 460 | } 461 | 462 | public static inline function min(value :String) : Attribute 463 | { 464 | return (t) -> DomBuilder.attr("min", value); 465 | } 466 | 467 | public static inline function multiple(value :Bool) : Attribute 468 | { 469 | return function(t) { 470 | if(value) DomBuilder.attr("multiple", true); 471 | } 472 | } 473 | 474 | public static inline function muted(value :Bool) : Attribute 475 | { 476 | return function(t) { 477 | if(value) DomBuilder.attr("muted", true); 478 | } 479 | } 480 | 481 | public static inline function name(value :String) : Attribute 482 | { 483 | return (t) -> DomBuilder.attr("name", value); 484 | } 485 | 486 | public static inline function novalidate(value :Bool) : Attribute 487 | { 488 | return function(t) { 489 | if(value) DomBuilder.attr("novalidate", true); 490 | } 491 | } 492 | 493 | public static inline function open(value :Bool) : Attribute 494 | { 495 | return function(t) { 496 | if(value) DomBuilder.attr("open", true); 497 | } 498 | } 499 | 500 | public static inline function optimum(value :String) : Attribute 501 | { 502 | return (t) -> DomBuilder.attr("optimum", value); 503 | } 504 | 505 | public static inline function pattern(value :String) : Attribute 506 | { 507 | return (t) -> DomBuilder.attr("pattern", value); 508 | } 509 | 510 | public static inline function ping(value :String) : Attribute 511 | { 512 | return (t) -> DomBuilder.attr("ping", value); 513 | } 514 | 515 | public static inline function placeholder(value :String) : Attribute 516 | { 517 | return (t) -> DomBuilder.attr("placeholder", value); 518 | } 519 | 520 | public static inline function poster(value :String) : Attribute 521 | { 522 | return (t) -> DomBuilder.attr("poster", value); 523 | } 524 | 525 | public static inline function preload(value :String) : Attribute 526 | { 527 | return (t) -> DomBuilder.attr("preload", value); 528 | } 529 | 530 | public static inline function radiogroup(value :String) : Attribute 531 | { 532 | return (t) -> DomBuilder.attr("radiogroup", value); 533 | } 534 | 535 | public static inline function readonly(value :Bool) : Attribute 536 | { 537 | return function(t) { 538 | if(value) DomBuilder.attr("readonly", true); 539 | } 540 | } 541 | 542 | public static inline function referrerpolicy(value :String) : Attribute 543 | { 544 | return (t) -> DomBuilder.attr("referrerpolicy", value); 545 | } 546 | 547 | public static inline function rel(value :String) : Attribute 548 | { 549 | return (t) -> DomBuilder.attr("rel", value); 550 | } 551 | 552 | public static inline function required(value :Bool) : Attribute 553 | { 554 | return function(t) { 555 | if(value) DomBuilder.attr("required", true); 556 | } 557 | } 558 | 559 | public static inline function reversed(value :Bool) : Attribute 560 | { 561 | return function(t) { 562 | if(value) DomBuilder.attr("reversed", true); 563 | } 564 | } 565 | 566 | public static inline function rows(value :String) : Attribute 567 | { 568 | return (t) -> DomBuilder.attr("rows", value); 569 | } 570 | 571 | public static inline function rowspan(value :String) : Attribute 572 | { 573 | return (t) -> DomBuilder.attr("rowspan", value); 574 | } 575 | 576 | public static inline function sandbox(value :String) : Attribute 577 | { 578 | return (t) -> DomBuilder.attr("sandbox", value); 579 | } 580 | 581 | public static inline function scope(value :String) : Attribute 582 | { 583 | return (t) -> DomBuilder.attr("scope", value); 584 | } 585 | 586 | public static inline function scoped(value :Bool) : Attribute 587 | { 588 | return function(t) { 589 | if(value) DomBuilder.attr("scoped", true); 590 | } 591 | } 592 | 593 | public static inline function selected(value :Bool) : Attribute 594 | { 595 | return function(t) { 596 | if(value) DomBuilder.attr("selected", true); 597 | } 598 | } 599 | 600 | public static inline function shape(value :String) : Attribute 601 | { 602 | return (t) -> DomBuilder.attr("shape", value); 603 | } 604 | 605 | public static inline function size(value :String) : Attribute 606 | { 607 | return (t) -> DomBuilder.attr("size", value); 608 | } 609 | 610 | public static inline function sizes(value :String) : Attribute 611 | { 612 | return (t) -> DomBuilder.attr("sizes", value); 613 | } 614 | 615 | public static inline function slot(value :String) : Attribute 616 | { 617 | return (t) -> DomBuilder.attr("slot", value); 618 | } 619 | 620 | public static inline function span(value :String) : Attribute 621 | { 622 | return (t) -> DomBuilder.attr("span", value); 623 | } 624 | 625 | public static inline function spellcheck(value :Bool) : Attribute 626 | { 627 | return function(t) { 628 | if(value) DomBuilder.attr("spellcheck", true); 629 | } 630 | } 631 | 632 | public static inline function src(value :String) : Attribute 633 | { 634 | return (t) -> DomBuilder.attr("src", value); 635 | } 636 | 637 | public static inline function srcdoc(value :String) : Attribute 638 | { 639 | return (t) -> DomBuilder.attr("srcdoc", value); 640 | } 641 | 642 | public static inline function srclang(value :String) : Attribute 643 | { 644 | return (t) -> DomBuilder.attr("srclang", value); 645 | } 646 | 647 | public static inline function srcset(value :String) : Attribute 648 | { 649 | return (t) -> DomBuilder.attr("srcset", value); 650 | } 651 | 652 | public static inline function start(value :String) : Attribute 653 | { 654 | return (t) -> DomBuilder.attr("start", value); 655 | } 656 | 657 | public static inline function step(value :String) : Attribute 658 | { 659 | return (t) -> DomBuilder.attr("step", value); 660 | } 661 | 662 | public static inline function style(value :EitherType) : Attribute 663 | { 664 | return (t) -> DomBuilder.attr("style", value); 665 | } 666 | 667 | public static inline function summary(value :String) : Attribute 668 | { 669 | return (t) -> DomBuilder.attr("summary", value); 670 | } 671 | 672 | public static inline function tabindex(value :String) : Attribute 673 | { 674 | return (t) -> DomBuilder.attr("tabindex", value); 675 | } 676 | 677 | public static inline function target(value :String) : Attribute 678 | { 679 | return (t) -> DomBuilder.attr("target", value); 680 | } 681 | 682 | public static inline function title(value :String) : Attribute 683 | { 684 | return (t) -> DomBuilder.attr("title", value); 685 | } 686 | 687 | public static inline function translate(value :Bool) : Attribute 688 | { 689 | return function(t) { 690 | if(value) DomBuilder.attr("translate", true); 691 | } 692 | } 693 | 694 | public static inline function type(value :String) : Attribute 695 | { 696 | return (t) -> DomBuilder.attr("type", value); 697 | } 698 | 699 | public static inline function usemap(value :String) : Attribute 700 | { 701 | return (t) -> DomBuilder.attr("usemap", value); 702 | } 703 | 704 | public static inline function value(value :String) : Attribute 705 | { 706 | return (t) -> DomBuilder.attr("value", new String(value)); 707 | } 708 | 709 | public static inline function width(value :String) : Attribute 710 | { 711 | return (t) -> DomBuilder.attr("width", value); 712 | } 713 | 714 | public static inline function wrap(value :String) : Attribute 715 | { 716 | return (t) -> DomBuilder.attr("wrap", value); 717 | } 718 | } -------------------------------------------------------------------------------- /src/towser/html/Element.hx: -------------------------------------------------------------------------------- 1 | package towser.html; 2 | 3 | typedef Element = #if backend Dynamic #elseif macro Dynamic #else js.html.Element #end; -------------------------------------------------------------------------------- /src/towser/html/Event.hx: -------------------------------------------------------------------------------- 1 | package towser.html; 2 | 3 | typedef TransitionEvent = #if backend Dynamic #elseif macro Dynamic #else js.html.TransitionEvent #end; 4 | typedef PointerEvent = #if backend Dynamic #elseif macro Dynamic #else js.html.PointerEvent #end; 5 | typedef ErrorEvent = #if backend Dynamic #elseif macro Dynamic #else js.html.ErrorEvent #end; 6 | typedef DragEvent = #if backend Dynamic #elseif macro Dynamic #else js.html.DragEvent #end; 7 | typedef FocusEvent = #if backend Dynamic #elseif macro Dynamic #else js.html.FocusEvent #end; 8 | typedef AnimationEvent = #if backend Dynamic #elseif macro Dynamic #else js.html.AnimationEvent #end; 9 | typedef WheelEvent = #if backend Dynamic #elseif macro Dynamic #else js.html.WheelEvent #end; 10 | typedef UIEvent = #if backend Dynamic #elseif macro Dynamic #else js.html.UIEvent #end; 11 | typedef InputEvent = #if backend Dynamic #elseif macro Dynamic #else js.html.InputEvent #end; 12 | typedef Event = #if backend Dynamic #elseif macro Dynamic #else js.html.Event #end; 13 | typedef KeyboardEvent = #if backend Dynamic #elseif macro Dynamic #else js.html.KeyboardEvent #end; 14 | typedef MouseEvent = #if backend Dynamic #elseif macro Dynamic #else js.html.MouseEvent #end; -------------------------------------------------------------------------------- /src/towser/html/Events.hx: -------------------------------------------------------------------------------- 1 | package towser.html; 2 | 3 | import towser.html.Event; 4 | import towser.platform.DomBuilder; 5 | 6 | @:extern class Events 7 | { 8 | public static inline function onanimationcancel(f :AnimationEvent -> Msg) : Attribute 9 | { 10 | return (t) -> DomBuilder.attr("onanimationcancel", (e) -> t.update(f(e))); 11 | } 12 | 13 | public static inline function onanimationend(f :AnimationEvent -> Msg) : Attribute 14 | { 15 | return (t) -> DomBuilder.attr("onanimationend", (e) -> t.update(f(e))); 16 | } 17 | 18 | public static inline function onblur(f :FocusEvent -> Msg) : Attribute 19 | { 20 | return (t) -> DomBuilder.attr("onblur", (e) -> t.update(f(e))); 21 | } 22 | 23 | public static inline function oncancel(f :Event -> Msg) : Attribute 24 | { 25 | return (t) -> DomBuilder.attr("oncancel", (e) -> t.update(f(e))); 26 | } 27 | 28 | public static inline function oncanplay(f :Event -> Msg) : Attribute 29 | { 30 | return (t) -> DomBuilder.attr("oncanplay", (e) -> t.update(f(e))); 31 | } 32 | 33 | public static inline function oncanplaythrough(f :Event -> Msg) : Attribute 34 | { 35 | return (t) -> DomBuilder.attr("oncanplaythrough", (e) -> t.update(f(e))); 36 | } 37 | 38 | public static inline function onchange(f :Event -> Msg) : Attribute 39 | { 40 | return (t) -> DomBuilder.attr("onchange", (e) -> t.update(f(e))); 41 | } 42 | 43 | public static inline function onclick(f :MouseEvent -> Msg) : Attribute 44 | { 45 | return onMouseEvent("onclick", f); 46 | } 47 | 48 | public static inline function onclose(f :Event -> Msg) : Attribute 49 | { 50 | return (t) -> DomBuilder.attr("onclose", (e) -> t.update(f(e))); 51 | } 52 | 53 | public static inline function oncontextmenu(f :Event -> Msg) : Attribute 54 | { 55 | return (t) -> DomBuilder.attr("oncontextmenu", (e) -> t.update(f(e))); 56 | } 57 | 58 | public static inline function oncuechange(f :Event -> Msg) : Attribute 59 | { 60 | return (t) -> DomBuilder.attr("oncuechange", (e) -> t.update(f(e))); 61 | } 62 | 63 | public static inline function ondblclick(f :MouseEvent -> Msg) : Attribute 64 | { 65 | return onMouseEvent("ondblclick", f); 66 | } 67 | 68 | public static inline function ondrag(f :DragEvent -> Msg) : Attribute 69 | { 70 | return (t) -> DomBuilder.attr("ondrag", (e) -> t.update(f(e))); 71 | } 72 | 73 | public static inline function ondragend(f :DragEvent -> Msg) : Attribute 74 | { 75 | return (t) -> DomBuilder.attr("ondragend", (e) -> t.update(f(e))); 76 | } 77 | 78 | public static inline function ondragenter(f :DragEvent -> Msg) : Attribute 79 | { 80 | return (t) -> DomBuilder.attr("ondragenter", (e) -> t.update(f(e))); 81 | } 82 | 83 | public static inline function ondragexit(f :DragEvent -> Msg) : Attribute 84 | { 85 | return (t) -> DomBuilder.attr("ondragexit", (e) -> t.update(f(e))); 86 | } 87 | 88 | public static inline function ondragleave(f :DragEvent -> Msg) : Attribute 89 | { 90 | return (t) -> DomBuilder.attr("ondragleave", (e) -> t.update(f(e))); 91 | } 92 | 93 | public static inline function ondragover(f :Event -> Msg) : Attribute 94 | { 95 | return (t) -> DomBuilder.attr("ondragover", (e) -> t.update(f(e))); 96 | } 97 | 98 | public static inline function ondragstart(f :Event -> Msg) : Attribute 99 | { 100 | return (t) -> DomBuilder.attr("ondragstart", (e) -> t.update(f(e))); 101 | } 102 | 103 | public static inline function ondrop(f :Event -> Msg) : Attribute 104 | { 105 | return (t) -> DomBuilder.attr("ondrop", (e) -> t.update(f(e))); 106 | } 107 | 108 | public static inline function ondurationchange(f :Event -> Msg) : Attribute 109 | { 110 | return (t) -> DomBuilder.attr("ondurationchange", (e) -> t.update(f(e))); 111 | } 112 | 113 | public static inline function onerror(f :ErrorEvent -> Msg) : Attribute 114 | { 115 | return (t) -> DomBuilder.attr("onerror", (e) -> t.update(f(e))); 116 | } 117 | 118 | public static inline function onemptied(f :Event -> Msg) : Attribute 119 | { 120 | return (t) -> DomBuilder.attr("onemptied", (e) -> t.update(f(e))); 121 | } 122 | 123 | public static inline function onended(f :Event -> Msg) : Attribute 124 | { 125 | return (t) -> DomBuilder.attr("onended", (e) -> t.update(f(e))); 126 | } 127 | 128 | public static inline function onfocus(f :FocusEvent -> Msg) : Attribute 129 | { 130 | return (t) -> DomBuilder.attr("onfocus", (e) -> t.update(f(e))); 131 | } 132 | 133 | public static inline function ongotpointercapture(f :FocusEvent -> Msg) : Attribute 134 | { 135 | return (t) -> DomBuilder.attr("ongotpointercapture", (e) -> t.update(f(e))); 136 | } 137 | 138 | public static inline function oninput(f :InputEvent -> Msg) : Attribute 139 | { 140 | return (t) -> DomBuilder.attr("oninput", (e) -> t.update(f(e))); 141 | } 142 | 143 | public static inline function oninvalid(f :Event -> Msg) : Attribute 144 | { 145 | return (t) -> DomBuilder.attr("oninvalid", (e) -> t.update(f(e))); 146 | } 147 | 148 | public static inline function onkeydown(f :KeyboardEvent -> Msg) : Attribute 149 | { 150 | return (t) -> DomBuilder.attr("onkeydown", (e) -> t.update(f(e))); 151 | } 152 | 153 | public static inline function onkeypress(f :KeyboardEvent -> Msg) : Attribute 154 | { 155 | return (t) -> DomBuilder.attr("onkeypress", (e) -> t.update(f(e))); 156 | } 157 | 158 | public static inline function onkeyup(f :KeyboardEvent -> Msg) : Attribute 159 | { 160 | return (t) -> DomBuilder.attr("onkeyup", (e) -> t.update(f(e))); 161 | } 162 | 163 | public static inline function onload(f :Event -> Msg) : Attribute 164 | { 165 | return (t) -> DomBuilder.attr("onload", (e) -> t.update(f(e))); 166 | } 167 | 168 | public static inline function onloadeddata(f :Event -> Msg) : Attribute 169 | { 170 | return (t) -> DomBuilder.attr("onloadeddata", (e) -> t.update(f(e))); 171 | } 172 | 173 | public static inline function onloadedmetadata(f :Event -> Msg) : Attribute 174 | { 175 | return (t) -> DomBuilder.attr("onloadedmetadata", (e) -> t.update(f(e))); 176 | } 177 | 178 | public static inline function onloadend(f :Event -> Msg) : Attribute 179 | { 180 | return (t) -> DomBuilder.attr("onloadend", (e) -> t.update(f(e))); 181 | } 182 | 183 | public static inline function onloadstart(f :Event -> Msg) : Attribute 184 | { 185 | return (t) -> DomBuilder.attr("onloadstart", (e) -> t.update(f(e))); 186 | } 187 | 188 | public static inline function onlostpointercapture(f :FocusEvent -> Msg) : Attribute 189 | { 190 | return (t) -> DomBuilder.attr("onlostpointercapture", (e) -> t.update(f(e))); 191 | } 192 | 193 | public static inline function onmousedown(f :MouseEvent -> Msg) : Attribute 194 | { 195 | return onMouseEvent("onmousedown", f); 196 | } 197 | 198 | public static inline function onmouseenter(f :MouseEvent -> Msg) : Attribute 199 | { 200 | return onMouseEvent("onmouseenter", f); 201 | } 202 | 203 | public static inline function onmouseleave(f :MouseEvent -> Msg) : Attribute 204 | { 205 | return onMouseEvent("onmouseleave", f); 206 | } 207 | 208 | public static inline function onmousemove(f :MouseEvent -> Msg) : Attribute 209 | { 210 | return onMouseEvent("onmousemove", f); 211 | } 212 | 213 | public static inline function onmouseout(f :MouseEvent -> Msg) : Attribute 214 | { 215 | return onMouseEvent("onmouseout", f); 216 | } 217 | 218 | public static inline function onmouseover(f :MouseEvent -> Msg) : Attribute 219 | { 220 | return onMouseEvent("onmouseover", f); 221 | } 222 | 223 | public static inline function onmouseup(f :MouseEvent -> Msg) : Attribute 224 | { 225 | return onMouseEvent("onmouseup", f); 226 | } 227 | 228 | public static inline function onwheel(f :WheelEvent -> Msg) : Attribute 229 | { 230 | return (t) -> DomBuilder.attr("onwheel", (e) -> t.update(f(e))); 231 | } 232 | 233 | public static inline function onpause(f :Event -> Msg) : Attribute 234 | { 235 | return (t) -> DomBuilder.attr("onpause", (e) -> t.update(f(e))); 236 | } 237 | 238 | public static inline function onplay(f :Event -> Msg) : Attribute 239 | { 240 | return (t) -> DomBuilder.attr("onplay", (e) -> t.update(f(e))); 241 | } 242 | 243 | public static inline function onpointerdown(f :PointerEvent -> Msg) : Attribute 244 | { 245 | return (t) -> DomBuilder.attr("onpointerdown", (e) -> t.update(f(e))); 246 | } 247 | 248 | public static inline function onpointermove(f :PointerEvent -> Msg) : Attribute 249 | { 250 | return (t) -> DomBuilder.attr("onpointermove", (e) -> t.update(f(e))); 251 | } 252 | 253 | public static inline function onpointerup(f :PointerEvent -> Msg) : Attribute 254 | { 255 | return (t) -> DomBuilder.attr("onpointerup", (e) -> t.update(f(e))); 256 | } 257 | 258 | public static inline function onpointercancel(f :PointerEvent -> Msg) : Attribute 259 | { 260 | return (t) -> DomBuilder.attr("onpointercancel", (e) -> t.update(f(e))); 261 | } 262 | 263 | public static inline function onpointerover(f :PointerEvent -> Msg) : Attribute 264 | { 265 | return (t) -> DomBuilder.attr("onpointerover", (e) -> t.update(f(e))); 266 | } 267 | 268 | public static inline function onpointerout(f :PointerEvent -> Msg) : Attribute 269 | { 270 | return (t) -> DomBuilder.attr("onpointerout", (e) -> t.update(f(e))); 271 | } 272 | 273 | public static inline function onpointerenter(f :PointerEvent -> Msg) : Attribute 274 | { 275 | return (t) -> DomBuilder.attr("onpointerenter", (e) -> t.update(f(e))); 276 | } 277 | 278 | public static inline function onpointerleave(f :PointerEvent -> Msg) : Attribute 279 | { 280 | return (t) -> DomBuilder.attr("onpointerleave", (e) -> t.update(f(e))); 281 | } 282 | 283 | public static inline function onreset(f :Event -> Msg) : Attribute 284 | { 285 | return (t) -> DomBuilder.attr("onreset", (e) -> t.update(f(e))); 286 | } 287 | 288 | public static inline function onresize(f :FocusEvent -> Msg) : Attribute 289 | { 290 | return (t) -> DomBuilder.attr("onresize", (e) -> t.update(f(e))); 291 | } 292 | 293 | public static inline function onscroll(f :UIEvent -> Msg) : Attribute 294 | { 295 | return (t) -> DomBuilder.attr("onscroll", (e) -> t.update(f(e))); 296 | } 297 | 298 | public static inline function onselect(f :UIEvent -> Msg) : Attribute 299 | { 300 | return (t) -> DomBuilder.attr("onselect", (e) -> t.update(f(e))); 301 | } 302 | 303 | public static inline function onselectstart(f :FocusEvent -> Msg) : Attribute 304 | { 305 | return (t) -> DomBuilder.attr("onselectstart", (e) -> t.update(f(e))); 306 | } 307 | 308 | public static inline function onselectionchange(f :FocusEvent -> Msg) : Attribute 309 | { 310 | return (t) -> DomBuilder.attr("onselectionchange", (e) -> t.update(f(e))); 311 | } 312 | 313 | public static inline function onsubmit(f :FocusEvent -> Msg) : Attribute 314 | { 315 | return (t) -> DomBuilder.attr("onsubmit", (e) -> t.update(f(e))); 316 | } 317 | 318 | public static inline function ontransitioncancel(f :TransitionEvent -> Msg) : Attribute 319 | { 320 | return (t) -> DomBuilder.attr("ontransitioncancel", (e) -> t.update(f(e))); 321 | } 322 | 323 | public static inline function ontransitionend(f :TransitionEvent -> Msg) : Attribute 324 | { 325 | return (t) -> DomBuilder.attr("ontransitionend", (e) -> t.update(f(e))); 326 | } 327 | 328 | private static inline function onMouseEvent(event :String, f :MouseEvent -> Msg) : Attribute 329 | { 330 | return (t) -> { 331 | #if client 332 | var timeout :Int = null; 333 | DomBuilder.attr(event, (e) -> { 334 | if (timeout != null) { 335 | js.Browser.window.cancelAnimationFrame(timeout); 336 | } 337 | 338 | timeout = js.Browser.window.requestAnimationFrame((time) -> t.update(f(e))); 339 | }); 340 | #end 341 | }; 342 | } 343 | } -------------------------------------------------------------------------------- /src/towser/html/Html.hx: -------------------------------------------------------------------------------- 1 | package towser.html; 2 | 3 | import towser.platform.HtmlHelper; 4 | import towser.Towser; 5 | import towser.html.Attributes; 6 | 7 | 8 | 9 | 10 | 11 | /** 12 | * 13 | */ 14 | @:extern class Html 15 | { 16 | //Content sectioning 17 | public static inline function address(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 18 | { 19 | return function(towser :Towser) { 20 | return HtmlHelper.containerElement(towser, "address", key, attributes, childRenders); 21 | } 22 | } 23 | 24 | public static inline function article(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 25 | { 26 | return function(towser :Towser) { 27 | return HtmlHelper.containerElement(towser, "article", key, attributes, childRenders); 28 | } 29 | } 30 | 31 | public static inline function aside(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 32 | { 33 | return function(towser :Towser) { 34 | return HtmlHelper.containerElement(towser, "aside", key, attributes, childRenders); 35 | } 36 | } 37 | 38 | public static inline function footer(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 39 | { 40 | return function(towser :Towser) { 41 | return HtmlHelper.containerElement(towser, "footer", key, attributes, childRenders); 42 | } 43 | } 44 | 45 | public static inline function header(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 46 | { 47 | return function(towser :Towser) { 48 | return HtmlHelper.containerElement(towser, "header", key, attributes, childRenders); 49 | } 50 | } 51 | 52 | public static inline function h1(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 53 | { 54 | return function(towser :Towser) { 55 | HtmlHelper.containerElement(towser, "h1", key, attributes, childRenders); 56 | } 57 | } 58 | 59 | public static inline function h2(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 60 | { 61 | return function(towser :Towser) { 62 | HtmlHelper.containerElement(towser, "h2", key, attributes, childRenders); 63 | } 64 | } 65 | 66 | public static inline function h3(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 67 | { 68 | return function(towser :Towser) { 69 | HtmlHelper.containerElement(towser, "h3", key, attributes, childRenders); 70 | } 71 | } 72 | 73 | public static inline function h4(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 74 | { 75 | return function(towser :Towser) { 76 | HtmlHelper.containerElement(towser, "h4", key, attributes, childRenders); 77 | } 78 | } 79 | 80 | public static inline function h5(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 81 | { 82 | return function(towser :Towser) { 83 | HtmlHelper.containerElement(towser, "h5", key, attributes, childRenders); 84 | } 85 | } 86 | 87 | public static inline function h6(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 88 | { 89 | return function(towser :Towser) { 90 | HtmlHelper.containerElement(towser, "h6", key, attributes, childRenders); 91 | } 92 | } 93 | 94 | public static inline function hgroup(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 95 | { 96 | return function(towser :Towser) { 97 | return HtmlHelper.containerElement(towser, "hgroup", key, attributes, childRenders); 98 | } 99 | } 100 | 101 | public static inline function main(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 102 | { 103 | return function(towser :Towser) { 104 | return HtmlHelper.containerElement(towser, "main", key, attributes, childRenders); 105 | } 106 | } 107 | 108 | public static inline function nav(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 109 | { 110 | return function(towser :Towser) { 111 | return HtmlHelper.containerElement(towser, "nav", key, attributes, childRenders); 112 | } 113 | } 114 | 115 | public static inline function section(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 116 | { 117 | return function(towser :Towser) { 118 | return HtmlHelper.containerElement(towser, "section", key, attributes, childRenders); 119 | } 120 | } 121 | 122 | //Text content 123 | public static inline function blockquote(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 124 | { 125 | return function(towser :Towser) { 126 | return HtmlHelper.containerElement(towser, "blockquote", key, attributes, childRenders); 127 | } 128 | } 129 | 130 | public static inline function dd(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 131 | { 132 | return function(towser :Towser) { 133 | return HtmlHelper.containerElement(towser, "dd", key, attributes, childRenders); 134 | } 135 | } 136 | 137 | public static inline function dir(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 138 | { 139 | return function(towser :Towser) { 140 | return HtmlHelper.containerElement(towser, "dir", key, attributes, childRenders); 141 | } 142 | } 143 | 144 | public static inline function div(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 145 | { 146 | return function(towser :Towser) { 147 | return HtmlHelper.containerElement(towser, "div", key, attributes, childRenders); 148 | } 149 | } 150 | 151 | public static inline function dl(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 152 | { 153 | return function(towser :Towser) { 154 | return HtmlHelper.containerElement(towser, "dl", key, attributes, childRenders); 155 | } 156 | } 157 | 158 | public static inline function dt(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 159 | { 160 | return function(towser :Towser) { 161 | return HtmlHelper.containerElement(towser, "dt", key, attributes, childRenders); 162 | } 163 | } 164 | 165 | public static inline function figcaption(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 166 | { 167 | return function(towser :Towser) { 168 | return HtmlHelper.containerElement(towser, "figcaption", key, attributes, childRenders); 169 | } 170 | } 171 | 172 | public static inline function figure(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 173 | { 174 | return function(towser :Towser) { 175 | return HtmlHelper.containerElement(towser, "figure", key, attributes, childRenders); 176 | } 177 | } 178 | 179 | public static inline function hr(key :String = "", attributes :Array>) : RenderFunction 180 | { 181 | return function(towser :Towser) { 182 | return HtmlHelper.voidElement(towser, "hr", key, attributes); 183 | } 184 | } 185 | 186 | public static inline function li(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 187 | { 188 | return function(towser :Towser) { 189 | return HtmlHelper.containerElement(towser, "li", key, attributes, childRenders); 190 | } 191 | } 192 | 193 | public static inline function main_(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 194 | { 195 | return function(towser :Towser) { 196 | return HtmlHelper.containerElement(towser, "main", key, attributes, childRenders); 197 | } 198 | } 199 | 200 | public static inline function ol(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 201 | { 202 | return function(towser :Towser) { 203 | return HtmlHelper.containerElement(towser, "ol", key, attributes, childRenders); 204 | } 205 | } 206 | 207 | public static inline function p(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 208 | { 209 | return function(towser :Towser) { 210 | return HtmlHelper.containerElement(towser, "p", key, attributes, childRenders); 211 | } 212 | } 213 | 214 | public static inline function pre(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 215 | { 216 | return function(towser :Towser) { 217 | return HtmlHelper.containerElement(towser, "pre", key, attributes, childRenders); 218 | } 219 | } 220 | 221 | public static inline function ul(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 222 | { 223 | return function(towser :Towser) { 224 | return HtmlHelper.containerElement(towser, "ul", key, attributes, childRenders); 225 | } 226 | } 227 | 228 | //Inline text semantics 229 | public static inline function a(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 230 | { 231 | return function(towser :Towser) { 232 | return HtmlHelper.containerElement(towser, "a", key, attributes, childRenders); 233 | } 234 | } 235 | 236 | public static inline function abbr(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 237 | { 238 | return function(towser :Towser) { 239 | return HtmlHelper.containerElement(towser, "abbr", key, attributes, childRenders); 240 | } 241 | } 242 | 243 | public static inline function b(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 244 | { 245 | return function(towser :Towser) { 246 | return HtmlHelper.containerElement(towser, "b", key, attributes, childRenders); 247 | } 248 | } 249 | 250 | public static inline function bdi(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 251 | { 252 | return function(towser :Towser) { 253 | return HtmlHelper.containerElement(towser, "bdi", key, attributes, childRenders); 254 | } 255 | } 256 | 257 | public static inline function bdo(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 258 | { 259 | return function(towser :Towser) { 260 | return HtmlHelper.containerElement(towser, "bdo", key, attributes, childRenders); 261 | } 262 | } 263 | 264 | public static inline function br(key :String = "", attributes :Array>) : RenderFunction 265 | { 266 | return function(towser :Towser) { 267 | return HtmlHelper.voidElement(towser, "br", key, attributes); 268 | } 269 | } 270 | 271 | public static inline function cite(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 272 | { 273 | return function(towser :Towser) { 274 | return HtmlHelper.containerElement(towser, "cite", key, attributes, childRenders); 275 | } 276 | } 277 | 278 | public static inline function code(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 279 | { 280 | return function(towser :Towser) { 281 | return HtmlHelper.containerElement(towser, "code", key, attributes, childRenders); 282 | } 283 | } 284 | 285 | public static inline function data(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 286 | { 287 | return function(towser :Towser) { 288 | return HtmlHelper.containerElement(towser, "data", key, attributes, childRenders); 289 | } 290 | } 291 | 292 | public static inline function dfn(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 293 | { 294 | return function(towser :Towser) { 295 | return HtmlHelper.containerElement(towser, "dfn", key, attributes, childRenders); 296 | } 297 | } 298 | 299 | public static inline function em(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 300 | { 301 | return function(towser :Towser) { 302 | return HtmlHelper.containerElement(towser, "em", key, attributes, childRenders); 303 | } 304 | } 305 | 306 | public static inline function i(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 307 | { 308 | return function(towser :Towser) { 309 | return HtmlHelper.containerElement(towser, "i", key, attributes, childRenders); 310 | } 311 | } 312 | 313 | public static inline function kbd(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 314 | { 315 | return function(towser :Towser) { 316 | return HtmlHelper.containerElement(towser, "kbd", key, attributes, childRenders); 317 | } 318 | } 319 | 320 | public static inline function mark(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 321 | { 322 | return function(towser :Towser) { 323 | return HtmlHelper.containerElement(towser, "mark", key, attributes, childRenders); 324 | } 325 | } 326 | 327 | public static inline function q(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 328 | { 329 | return function(towser :Towser) { 330 | return HtmlHelper.containerElement(towser, "q", key, attributes, childRenders); 331 | } 332 | } 333 | 334 | public static inline function rb(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 335 | { 336 | return function(towser :Towser) { 337 | return HtmlHelper.containerElement(towser, "rb", key, attributes, childRenders); 338 | } 339 | } 340 | 341 | public static inline function rp(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 342 | { 343 | return function(towser :Towser) { 344 | return HtmlHelper.containerElement(towser, "rp", key, attributes, childRenders); 345 | } 346 | } 347 | 348 | public static inline function rt(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 349 | { 350 | return function(towser :Towser) { 351 | return HtmlHelper.containerElement(towser, "rt", key, attributes, childRenders); 352 | } 353 | } 354 | 355 | public static inline function rtc(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 356 | { 357 | return function(towser :Towser) { 358 | return HtmlHelper.containerElement(towser, "rtc", key, attributes, childRenders); 359 | } 360 | } 361 | 362 | public static inline function ruby(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 363 | { 364 | return function(towser :Towser) { 365 | return HtmlHelper.containerElement(towser, "ruby", key, attributes, childRenders); 366 | } 367 | } 368 | 369 | public static inline function s(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 370 | { 371 | return function(towser :Towser) { 372 | return HtmlHelper.containerElement(towser, "s", key, attributes, childRenders); 373 | } 374 | } 375 | 376 | public static inline function samp(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 377 | { 378 | return function(towser :Towser) { 379 | return HtmlHelper.containerElement(towser, "samp", key, attributes, childRenders); 380 | } 381 | } 382 | 383 | public static inline function small(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 384 | { 385 | return function(towser :Towser) { 386 | return HtmlHelper.containerElement(towser, "small", key, attributes, childRenders); 387 | } 388 | } 389 | 390 | public static inline function span(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 391 | { 392 | return function(towser :Towser) { 393 | return HtmlHelper.containerElement(towser, "span", key, attributes, childRenders); 394 | } 395 | } 396 | 397 | public static inline function strong(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 398 | { 399 | return function(towser :Towser) { 400 | return HtmlHelper.containerElement(towser, "strong", key, attributes, childRenders); 401 | } 402 | } 403 | 404 | public static inline function sub(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 405 | { 406 | return function(towser :Towser) { 407 | return HtmlHelper.containerElement(towser, "sub", key, attributes, childRenders); 408 | } 409 | } 410 | 411 | public static inline function sup(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 412 | { 413 | return function(towser :Towser) { 414 | return HtmlHelper.containerElement(towser, "sup", key, attributes, childRenders); 415 | } 416 | } 417 | 418 | public static inline function time(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 419 | { 420 | return function(towser :Towser) { 421 | return HtmlHelper.containerElement(towser, "time", key, attributes, childRenders); 422 | } 423 | } 424 | 425 | public static inline function tt(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 426 | { 427 | return function(towser :Towser) { 428 | return HtmlHelper.containerElement(towser, "tt", key, attributes, childRenders); 429 | } 430 | } 431 | 432 | public static inline function u(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 433 | { 434 | return function(towser :Towser) { 435 | return HtmlHelper.containerElement(towser, "u", key, attributes, childRenders); 436 | } 437 | } 438 | 439 | public static inline function var_(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 440 | { 441 | return function(towser :Towser) { 442 | return HtmlHelper.containerElement(towser, "var", key, attributes, childRenders); 443 | } 444 | } 445 | 446 | public static inline function wbr(key :String = "", attributes :Array>) : RenderFunction 447 | { 448 | return function(towser :Towser) { 449 | return HtmlHelper.voidElement(towser, "wbr", key, attributes); 450 | } 451 | } 452 | 453 | //Image and multimedia 454 | public static inline function area(key :String = "", attributes :Array>) : RenderFunction 455 | { 456 | return function(towser :Towser) { 457 | return HtmlHelper.voidElement(towser, "area", key, attributes); 458 | } 459 | } 460 | 461 | public static inline function audio(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 462 | { 463 | return function(towser :Towser) { 464 | return HtmlHelper.containerElement(towser, "audio", key, attributes, childRenders); 465 | } 466 | } 467 | 468 | public static inline function img(key :String = "", attributes :Array>) : RenderFunction 469 | { 470 | return function(towser :Towser) { 471 | return HtmlHelper.voidElement(towser, "img", key, attributes); 472 | } 473 | } 474 | 475 | public static inline function map(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 476 | { 477 | return function(towser :Towser) { 478 | return HtmlHelper.containerElement(towser, "map", key, attributes, childRenders); 479 | } 480 | } 481 | 482 | public static inline function track(key :String = "", attributes :Array>) : RenderFunction 483 | { 484 | return function(towser :Towser) { 485 | return HtmlHelper.voidElement(towser, "track", key, attributes); 486 | } 487 | } 488 | 489 | public static inline function video(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 490 | { 491 | return function(towser :Towser) { 492 | return HtmlHelper.containerElement(towser, "video", key, attributes, childRenders); 493 | } 494 | } 495 | 496 | //Embedded content 497 | public static inline function applet(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 498 | { 499 | return function(towser :Towser) { 500 | return HtmlHelper.containerElement(towser, "applet", key, attributes, childRenders); 501 | } 502 | } 503 | 504 | public static inline function embed(key :String = "", attributes :Array>) : RenderFunction 505 | { 506 | return function(towser :Towser) { 507 | return HtmlHelper.voidElement(towser, "embed", key, attributes); 508 | } 509 | } 510 | 511 | public static inline function iframe(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 512 | { 513 | return function(towser :Towser) { 514 | return HtmlHelper.containerElement(towser, "iframe", key, attributes, childRenders); 515 | } 516 | } 517 | 518 | public static inline function noembed(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 519 | { 520 | return function(towser :Towser) { 521 | return HtmlHelper.containerElement(towser, "noembed", key, attributes, childRenders); 522 | } 523 | } 524 | 525 | public static inline function object(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 526 | { 527 | return function(towser :Towser) { 528 | return HtmlHelper.containerElement(towser, "object", key, attributes, childRenders); 529 | } 530 | } 531 | 532 | public static inline function param(key :String = "", attributes :Array>) : RenderFunction 533 | { 534 | return function(towser :Towser) { 535 | return HtmlHelper.voidElement(towser, "param", key, attributes); 536 | } 537 | } 538 | 539 | public static inline function picture(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 540 | { 541 | return function(towser :Towser) { 542 | return HtmlHelper.containerElement(towser, "picture", key, attributes, childRenders); 543 | } 544 | } 545 | 546 | public static inline function source(key :String = "", attributes :Array>) : RenderFunction 547 | { 548 | return function(towser :Towser) { 549 | return HtmlHelper.voidElement(towser, "source", key, attributes); 550 | } 551 | } 552 | 553 | //Scripting 554 | public static inline function canvas(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 555 | { 556 | return function(towser :Towser) { 557 | return HtmlHelper.containerElement(towser, "canvas", key, attributes, childRenders); 558 | } 559 | } 560 | 561 | public static inline function noscript(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 562 | { 563 | return function(towser :Towser) { 564 | return HtmlHelper.containerElement(towser, "noscript", key, attributes, childRenders); 565 | } 566 | } 567 | 568 | public static inline function script(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 569 | { 570 | return function(towser :Towser) { 571 | return HtmlHelper.containerElement(towser, "script", key, attributes, childRenders); 572 | } 573 | } 574 | 575 | //Demarcating edits 576 | public static inline function del(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 577 | { 578 | return function(towser :Towser) { 579 | return HtmlHelper.containerElement(towser, "del", key, attributes, childRenders); 580 | } 581 | } 582 | 583 | public static inline function ins(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 584 | { 585 | return function(towser :Towser) { 586 | return HtmlHelper.containerElement(towser, "ins", key, attributes, childRenders); 587 | } 588 | } 589 | 590 | //Table content 591 | public static inline function caption(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 592 | { 593 | return function(towser :Towser) { 594 | return HtmlHelper.containerElement(towser, "caption", key, attributes, childRenders); 595 | } 596 | } 597 | 598 | public static inline function col(key :String = "", attributes :Array>) : RenderFunction 599 | { 600 | return function(towser :Towser) { 601 | return HtmlHelper.voidElement(towser, "col", key, attributes); 602 | } 603 | } 604 | 605 | public static inline function colgroup(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 606 | { 607 | return function(towser :Towser) { 608 | return HtmlHelper.containerElement(towser, "colgroup", key, attributes, childRenders); 609 | } 610 | } 611 | 612 | public static inline function table(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 613 | { 614 | return function(towser :Towser) { 615 | return HtmlHelper.containerElement(towser, "table", key, attributes, childRenders); 616 | } 617 | } 618 | 619 | public static inline function tbody(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 620 | { 621 | return function(towser :Towser) { 622 | return HtmlHelper.containerElement(towser, "tbody", key, attributes, childRenders); 623 | } 624 | } 625 | 626 | public static inline function td(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 627 | { 628 | return function(towser :Towser) { 629 | return HtmlHelper.containerElement(towser, "td", key, attributes, childRenders); 630 | } 631 | } 632 | 633 | public static inline function tfoot(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 634 | { 635 | return function(towser :Towser) { 636 | return HtmlHelper.containerElement(towser, "tfoot", key, attributes, childRenders); 637 | } 638 | } 639 | 640 | public static inline function th(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 641 | { 642 | return function(towser :Towser) { 643 | return HtmlHelper.containerElement(towser, "th", key, attributes, childRenders); 644 | } 645 | } 646 | 647 | public static inline function thead(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 648 | { 649 | return function(towser :Towser) { 650 | return HtmlHelper.containerElement(towser, "thead", key, attributes, childRenders); 651 | } 652 | } 653 | 654 | public static inline function tr(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 655 | { 656 | return function(towser :Towser) { 657 | return HtmlHelper.containerElement(towser, "tr", key, attributes, childRenders); 658 | } 659 | } 660 | 661 | //Forms 662 | public static inline function button(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 663 | { 664 | return function(towser :Towser) { 665 | return HtmlHelper.containerElement(towser, "button", key, attributes, childRenders); 666 | } 667 | } 668 | 669 | public static inline function datalist(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 670 | { 671 | return function(towser :Towser) { 672 | return HtmlHelper.containerElement(towser, "datalist", key, attributes, childRenders); 673 | } 674 | } 675 | 676 | public static inline function fieldset(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 677 | { 678 | return function(towser :Towser) { 679 | return HtmlHelper.containerElement(towser, "fieldset", key, attributes, childRenders); 680 | } 681 | } 682 | 683 | public static inline function form(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 684 | { 685 | return function(towser :Towser) { 686 | return HtmlHelper.containerElement(towser, "form", key, attributes, childRenders); 687 | } 688 | } 689 | 690 | public static inline function input(key :String = "", attributes :Array>) : RenderFunction 691 | { 692 | return function(towser :Towser) { 693 | return HtmlHelper.voidElement(towser, "input", key, attributes); 694 | } 695 | } 696 | 697 | public static inline function label(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 698 | { 699 | return function(towser :Towser) { 700 | return HtmlHelper.containerElement(towser, "label", key, attributes, childRenders); 701 | } 702 | } 703 | 704 | public static inline function legend(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 705 | { 706 | return function(towser :Towser) { 707 | return HtmlHelper.containerElement(towser, "legend", key, attributes, childRenders); 708 | } 709 | } 710 | 711 | public static inline function meter(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 712 | { 713 | return function(towser :Towser) { 714 | return HtmlHelper.containerElement(towser, "meter", key, attributes, childRenders); 715 | } 716 | } 717 | 718 | public static inline function optgroup(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 719 | { 720 | return function(towser :Towser) { 721 | return HtmlHelper.containerElement(towser, "optgroup", key, attributes, childRenders); 722 | } 723 | } 724 | 725 | public static inline function option(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 726 | { 727 | return function(towser :Towser) { 728 | return HtmlHelper.containerElement(towser, "option", key, attributes, childRenders); 729 | } 730 | } 731 | 732 | public static inline function output(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 733 | { 734 | return function(towser :Towser) { 735 | return HtmlHelper.containerElement(towser, "output", key, attributes, childRenders); 736 | } 737 | } 738 | 739 | public static inline function progress(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 740 | { 741 | return function(towser :Towser) { 742 | return HtmlHelper.containerElement(towser, "progress", key, attributes, childRenders); 743 | } 744 | } 745 | 746 | public static inline function select(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 747 | { 748 | return function(towser :Towser) { 749 | return HtmlHelper.containerElement(towser, "select", key, attributes, childRenders); 750 | } 751 | } 752 | 753 | public static inline function textarea(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 754 | { 755 | return function(towser :Towser) { 756 | return HtmlHelper.containerElement(towser, "textarea", key, attributes, childRenders); 757 | } 758 | } 759 | 760 | //Interactive elements 761 | public static inline function details(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 762 | { 763 | return function(towser :Towser) { 764 | return HtmlHelper.containerElement(towser, "details", key, attributes, childRenders); 765 | } 766 | } 767 | 768 | public static inline function dialog(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 769 | { 770 | return function(towser :Towser) { 771 | return HtmlHelper.containerElement(towser, "dialog", key, attributes, childRenders); 772 | } 773 | } 774 | 775 | public static inline function menu(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 776 | { 777 | return function(towser :Towser) { 778 | return HtmlHelper.containerElement(towser, "menu", key, attributes, childRenders); 779 | } 780 | } 781 | 782 | public static inline function menuitem(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 783 | { 784 | return function(towser :Towser) { 785 | return HtmlHelper.containerElement(towser, "menuitem", key, attributes, childRenders); 786 | } 787 | } 788 | 789 | public static inline function summary(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 790 | { 791 | return function(towser :Towser) { 792 | return HtmlHelper.containerElement(towser, "summary", key, attributes, childRenders); 793 | } 794 | } 795 | 796 | //Web Components 797 | public static inline function content(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 798 | { 799 | return function(towser :Towser) { 800 | return HtmlHelper.containerElement(towser, "content", key, attributes, childRenders); 801 | } 802 | } 803 | 804 | public static inline function element(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 805 | { 806 | return function(towser :Towser) { 807 | return HtmlHelper.containerElement(towser, "element", key, attributes, childRenders); 808 | } 809 | } 810 | 811 | public static inline function shadow(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 812 | { 813 | return function(towser :Towser) { 814 | return HtmlHelper.containerElement(towser, "shadow", key, attributes, childRenders); 815 | } 816 | } 817 | 818 | public static inline function slot(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 819 | { 820 | return function(towser :Towser) { 821 | return HtmlHelper.containerElement(towser, "slot", key, attributes, childRenders); 822 | } 823 | } 824 | 825 | public static inline function template(key :String = "", attributes :Array>, childRenders :Array>) : RenderFunction 826 | { 827 | return function(towser :Towser) { 828 | return HtmlHelper.containerElement(towser, "template", key, attributes, childRenders); 829 | } 830 | } 831 | 832 | public static inline function skip() : RenderFunction 833 | { 834 | return function(towser :Towser) { 835 | return HtmlHelper.skip(); 836 | } 837 | } 838 | 839 | public static inline function text(text :String) : RenderFunction 840 | { 841 | return function(towser :Towser) { 842 | HtmlHelper.textElement(text); 843 | } 844 | } 845 | } -------------------------------------------------------------------------------- /src/towser/html/Lazy.hx: -------------------------------------------------------------------------------- 1 | package towser.html; 2 | 3 | import towser.Towser; 4 | import towser.RenderFunction; 5 | import towser.platform.DomBuilder; 6 | import towser.platform.LazyMap; 7 | 8 | typedef Lazy1 = A -> RenderFunction; 9 | typedef Lazy2 = A -> B -> RenderFunction; 10 | typedef Lazy3 = A -> B -> C -> RenderFunction; 11 | 12 | /** 13 | * 14 | */ 15 | class Lazy 16 | { 17 | public static function lazy1(selector :String, f :Lazy1, a :A) : RenderFunction 18 | { 19 | return function(towser :Towser) { 20 | if(!towser._lazyMap.shouldSkip1(selector, a)) { 21 | towser._lazyMap.setLazy1(selector, a); 22 | f(a)(towser); 23 | } 24 | else { 25 | DomBuilder.skipNode(); 26 | } 27 | } 28 | } 29 | 30 | public static function lazy2(selector :String, f :Lazy2, a :A, b:B) : RenderFunction 31 | { 32 | return function(towser :Towser) { 33 | if(!towser._lazyMap.shouldSkip2(selector, a, b)) { 34 | towser._lazyMap.setLazy2(selector, a, b); 35 | f(a, b)(towser); 36 | } 37 | else { 38 | DomBuilder.skipNode(); 39 | } 40 | } 41 | } 42 | 43 | public static function lazy3(selector :String, f :Lazy3, a :A, b:B, c :C) : RenderFunction 44 | { 45 | return function(towser :Towser) { 46 | if(!towser._lazyMap.shouldSkip3(selector, a, b, c)) { 47 | towser._lazyMap.setLazy3(selector, a, b, c); 48 | f(a, b, c)(towser); 49 | } 50 | else { 51 | DomBuilder.skipNode(); 52 | } 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /src/towser/html/Node.hx: -------------------------------------------------------------------------------- 1 | package towser.html; 2 | 3 | typedef Node = #if backend Dynamic #elseif macro Dynamic #else js.html.Node #end; -------------------------------------------------------------------------------- /src/towser/html/Text.hx: -------------------------------------------------------------------------------- 1 | package towser.html; 2 | 3 | typedef Text = #if backend Dynamic #elseif macro Dynamic #else js.html.Text #end; -------------------------------------------------------------------------------- /src/towser/platform/DomBuilder.hx: -------------------------------------------------------------------------------- 1 | package towser.platform; 2 | 3 | typedef DomBuilder = 4 | #if backend 5 | towser.platform.server.ServerDomBuilder; 6 | #elseif macro 7 | towser.platform.macro.MacroDomBuilder; 8 | #elseif client 9 | towser.platform.client.ClientDomBuilder; 10 | #end -------------------------------------------------------------------------------- /src/towser/platform/HtmlHelper.hx: -------------------------------------------------------------------------------- 1 | package towser.platform; 2 | 3 | import towser.html.Attribute; 4 | import towser.Towser; 5 | import towser.platform.DomBuilder; 6 | 7 | class HtmlHelper 8 | { 9 | @:extern public static inline function textElement(text :String) : Void 10 | { 11 | DomBuilder.text(text); 12 | } 13 | 14 | @:extern public static inline function skip() : Void 15 | { 16 | DomBuilder.skipNode(); 17 | } 18 | 19 | public static function containerElement(towser :Towser, tagname :String, key :String, attributes :Array>, childRenders :Array>) : Void 20 | { 21 | DomBuilder.elementOpenStart(tagname, key, _scratchStatics); 22 | for(attribute in attributes) attribute(towser); 23 | DomBuilder.elementOpenEnd(); 24 | for(r in childRenders) r(towser); 25 | DomBuilder.elementClose(tagname); 26 | } 27 | 28 | public static function voidElement(towser :Towser, tagname :String, key :String, attributes :Array>) : Void 29 | { 30 | DomBuilder.elementOpenStart(tagname, key, _scratchStatics); 31 | for(attribute in attributes) attribute(towser); 32 | DomBuilder.elementOpenEnd(); 33 | #if !backend 34 | DomBuilder.elementClose(tagname); 35 | #end 36 | } 37 | 38 | private static var _scratchStatics = []; 39 | } -------------------------------------------------------------------------------- /src/towser/platform/LazyMap.hx: -------------------------------------------------------------------------------- 1 | package towser.platform; 2 | 3 | /** 4 | * 5 | */ 6 | class LazyMap 7 | { 8 | public function new() : Void 9 | { 10 | _lazy1 = new Map(); 11 | _lazy2 = new Map(); 12 | _lazy3 = new Map(); 13 | } 14 | 15 | /** 16 | * [Description] 17 | * @param selector 18 | * @param valA 19 | */ 20 | public function setLazy1(selector :String, valA :A) : Void 21 | { 22 | _lazy1.set(selector, {valA:valA.stamp}); 23 | } 24 | 25 | /** 26 | * [Description] 27 | * @param selector 28 | * @param valA 29 | * @param valB 30 | */ 31 | public function setLazy2(selector :String, valA :A, valB :B) : Void 32 | { 33 | _lazy2.set(selector, {valA:valA.stamp, valB:valB.stamp}); 34 | } 35 | 36 | /** 37 | * [Description] 38 | * @param selector 39 | * @param valA 40 | * @param valB 41 | * @param valC 42 | */ 43 | public function setLazy3(selector :String, valA :A, valB :B, valC :C) : Void 44 | { 45 | _lazy3.set(selector, {valA:valA.stamp, valB:valB.stamp, valC:valC.stamp}); 46 | } 47 | 48 | /** 49 | * [Description] 50 | * @param selector 51 | * @param valA 52 | * @return Bool 53 | */ 54 | public function shouldSkip1(selector :String, valA :A) : Bool 55 | { 56 | var val = _lazy1.get(selector); 57 | return val != null && valA.stamp == val.valA; 58 | } 59 | 60 | /** 61 | * [Description] 62 | * @param selector 63 | * @param valA 64 | * @param valB 65 | * @return Bool 66 | */ 67 | public function shouldSkip2(selector :String, valA :A, valB :B) : Bool 68 | { 69 | var val = _lazy2.get(selector); 70 | return val != null && valA.stamp == val.valA && valB.stamp == val.valB; 71 | } 72 | 73 | /** 74 | * [Description] 75 | * @param selector 76 | * @param valA 77 | * @param valB 78 | * @param valC 79 | * @return Bool 80 | */ 81 | public function shouldSkip3(selector :String, valA :A, valB :B, valC :C) : Bool 82 | { 83 | var val = _lazy3.get(selector); 84 | return val != null && valA.stamp == val.valA && valB.stamp == val.valB && valC.stamp == val.valC; 85 | } 86 | 87 | private var _lazy1 :Map; 88 | private var _lazy2 :Map; 89 | private var _lazy3 :Map; 90 | } 91 | 92 | interface LazyStamp 93 | { 94 | var stamp :Stamp; 95 | } 96 | 97 | abstract Stamp(Int) 98 | { 99 | public inline function new() : Void 100 | { 101 | this = 0; 102 | } 103 | 104 | public inline function next() : Stamp 105 | { 106 | #if client 107 | return cast js.lib.Date.now(); 108 | #else 109 | return cast 0; 110 | #end 111 | } 112 | 113 | @:op(A > B) static function gt(a:Stamp, b:Stamp):Bool; 114 | @:op(A < B) static function lt(a:Stamp, b:Stamp):Bool; 115 | } -------------------------------------------------------------------------------- /src/towser/platform/client/ClientDomBuilder.hx: -------------------------------------------------------------------------------- 1 | package towser.platform.client; 2 | 3 | import towser.html.Element; 4 | import towser.html.Text; 5 | import towser.html.Node; 6 | 7 | @:jsRequire("incremental-dom") 8 | extern class ClientDomBuilder 9 | { 10 | /** 11 | * [Description] 12 | * @param tagname 13 | * @param key 14 | * @param staticPropertyValuePairs 15 | * @return Dynamic 16 | */ 17 | public static function elementOpenStart(tagname :String, key :String, staticPropertyValuePairs :Array) : Dynamic; 18 | 19 | /** 20 | * [Description] 21 | * @param name 22 | * @param value 23 | * @return Dynamic 24 | */ 25 | public static function attr(name :String, value :Any) : Dynamic; 26 | 27 | /** 28 | * [Description] 29 | * @return Element 30 | */ 31 | public static function elementOpenEnd() : Element; 32 | 33 | /** 34 | * [Description] 35 | * @param tagname 36 | * @return Element 37 | */ 38 | public static function elementClose(tagname :String) : Element; 39 | 40 | /** 41 | * [Description] 42 | * @param node 43 | * @param description 44 | * @param data 45 | * @return Element 46 | */ 47 | public static function text(value :Dynamic) : Text; 48 | 49 | /** 50 | * [Description] 51 | * @param node 52 | * @param description 53 | * @param data 54 | * @return Element 55 | */ 56 | public static function patch(node :Node, description :RenderFunction, data :Any) : Element; 57 | 58 | /** 59 | * [Description] 60 | */ 61 | public static function skipNode() : Void; 62 | } -------------------------------------------------------------------------------- /src/towser/platform/client/ClientTowser.hx: -------------------------------------------------------------------------------- 1 | package towser.platform.client; 2 | 3 | import towser.platform.DomBuilder; 4 | import towser.platform.LazyMap; 5 | 6 | class ClientTowser 7 | { 8 | public var markup (default, null) :String = ""; 9 | 10 | /** 11 | * [Description] 12 | * @param element - Root element ID 13 | * @param update - State Update Function 14 | * @param view - State View Function 15 | * @param model - State 16 | */ 17 | public function new(towser :Towser, element :String, update :Towser -> Msg -> Model -> RenderType, view :Model -> RenderFunction, model :Model) : Void 18 | { 19 | _update = update; 20 | _view = view; 21 | _model = model; 22 | init(element, towser); 23 | } 24 | 25 | public function update(msg :Msg, towser :Towser) : Void 26 | { 27 | var renderType = _update(towser, msg, _model); 28 | switch renderType { 29 | case NONE: 30 | case FULL: 31 | DomBuilder.patch(_element, _view(_model), towser); 32 | case PARTIAL(element, render): 33 | DomBuilder.patch(element, render, towser); 34 | } 35 | } 36 | 37 | public inline function getModel() : Model 38 | { 39 | return _model; 40 | } 41 | 42 | public inline function setModel(model :Model) : Void 43 | { 44 | _model = model; 45 | } 46 | 47 | private function init(element :String, towser :Towser) : Void 48 | { 49 | _element = js.Browser.document.getElementById(element); 50 | DomBuilder.patch(_element, _view(_model), towser); 51 | } 52 | 53 | private var _update : Towser -> Msg -> Model -> RenderType; 54 | private var _view :Model -> RenderFunction; 55 | private var _model :Model; 56 | private var _element :js.html.Element; 57 | private var _timeout :Int = null; 58 | } -------------------------------------------------------------------------------- /src/towser/platform/macro/MacroDomBuilder.hx: -------------------------------------------------------------------------------- 1 | package towser.platform.macro; 2 | 3 | import towser.Towser; 4 | 5 | class MacroDomBuilder 6 | { 7 | public static function patch(fn :RenderFunction, data :Towser) : String 8 | { 9 | return ""; 10 | } 11 | 12 | public static function elementOpenStart(tagname :String, key :String, staticPropertyValuePairs :Array) : Void 13 | { 14 | } 15 | 16 | public static function attr(name :String, value :Dynamic) : Void 17 | { 18 | } 19 | 20 | public static function elementOpenEnd() : Void 21 | { 22 | } 23 | 24 | public static function elementClose(tagname :String) : Void 25 | { 26 | } 27 | 28 | public static function text(value :Dynamic, ?formatters :RenderFunction) : Void 29 | { 30 | } 31 | 32 | public static function skipNode() : Void 33 | { 34 | } 35 | } -------------------------------------------------------------------------------- /src/towser/platform/macro/MacroTowser.hx: -------------------------------------------------------------------------------- 1 | package towser.platform.macro; 2 | 3 | class MacroTowser 4 | { 5 | public var markup (default, null) :String = ""; 6 | 7 | /** 8 | * [Description] 9 | * @param element - Root element ID 10 | * @param update - State Update Function 11 | * @param view - State View Function 12 | * @param model - State 13 | */ 14 | public function new(towser :Towser, element :String, update :Towser -> Msg -> Model -> RenderType, view :Model -> RenderFunction, model :Model) : Void 15 | { 16 | } 17 | 18 | public function update(msg :Msg, towser :Towser) : Void 19 | { 20 | } 21 | 22 | public inline function getModel() : Model 23 | { 24 | return null; 25 | } 26 | 27 | public inline function setModel(model :Model) : Void 28 | { 29 | } 30 | 31 | private function init(element :String, towser :Towser) : String 32 | { 33 | return ""; 34 | } 35 | } -------------------------------------------------------------------------------- /src/towser/platform/server/ServerDomBuilder.hx: -------------------------------------------------------------------------------- 1 | package towser.platform.server; 2 | 3 | import towser.Towser; 4 | 5 | class ServerDomBuilder 6 | { 7 | public static function patch(fn :RenderFunction, data :Towser) : String 8 | { 9 | _scratchText = ""; 10 | fn(data); 11 | return _scratchText; 12 | } 13 | 14 | public static function elementOpenStart(tagname :String, key :String, staticPropertyValuePairs :Array) : Void 15 | { 16 | _scratchText += "<"+ tagname; 17 | } 18 | 19 | public static function attr(name :String, value :Dynamic) : Void 20 | { 21 | if(!Reflect.isFunction(value)) { 22 | _scratchText += " " + name + '="' + value + '"'; 23 | } 24 | } 25 | 26 | public static function elementOpenEnd() : Void 27 | { 28 | _scratchText += ">"; 29 | } 30 | 31 | public static function elementClose(tagname :String) : Void 32 | { 33 | _scratchText += ""; 34 | } 35 | 36 | public static function text(value :Dynamic, ?formatters :RenderFunction) : Void 37 | { 38 | _scratchText += value; 39 | } 40 | 41 | public static function skipNode() : Void 42 | { 43 | } 44 | 45 | private static var _scratchText = ""; 46 | } -------------------------------------------------------------------------------- /src/towser/platform/server/ServerTowser.hx: -------------------------------------------------------------------------------- 1 | package towser.platform.server; 2 | 3 | class ServerTowser 4 | { 5 | public var markup (default, null) :String = ""; 6 | 7 | /** 8 | * [Description] 9 | * @param element - Root element ID 10 | * @param update - State Update Function 11 | * @param view - State View Function 12 | * @param model - State 13 | */ 14 | public function new(towser :Towser, element :String, update :Towser -> Msg -> Model -> RenderType, view :Model -> RenderFunction, model :Model) : Void 15 | { 16 | _update = update; 17 | _view = view; 18 | _model = model; 19 | markup = init(element, towser); 20 | } 21 | 22 | public function update(msg :Msg, towser :Towser) : Void 23 | { 24 | _update(towser, msg, _model); 25 | markup = DomBuilder.patch(_view(_model), towser); 26 | } 27 | 28 | public inline function getModel() : Model 29 | { 30 | return _model; 31 | } 32 | 33 | public inline function setModel(model :Model) : Void 34 | { 35 | _model = model; 36 | } 37 | 38 | private function init(element :String, towser :Towser) : String 39 | { 40 | return DomBuilder.patch(_view(_model), towser); 41 | } 42 | 43 | private var _update : Towser -> Msg -> Model -> RenderType; 44 | private var _view :Model -> RenderFunction; 45 | private var _model :Model; 46 | } -------------------------------------------------------------------------------- /tests/Main.hx: -------------------------------------------------------------------------------- 1 | import towser.Towser; 2 | 3 | import haxe.unit.TestCase; 4 | import haxe.unit.TestRunner; 5 | 6 | class Main { 7 | static function main() { 8 | var runner = new TestRunner(); 9 | runner.add(new BaseTest()); 10 | runner.run(); 11 | trace(runner.result); 12 | } 13 | } 14 | 15 | class BaseTest extends TestCase 16 | { 17 | public function testHelloPerdita() : Void 18 | { 19 | var towser = new Towser("app", TestApp.update, TestApp.view, {name: "Perdita", section: Hello}); 20 | assertEquals(towser.markup, '

Hello

Perdita

'); 21 | } 22 | 23 | public function testHelloPongo() : Void 24 | { 25 | var towser = new Towser("app", TestApp.update, TestApp.view, {name: "Perdita", section: Hello}); 26 | towser.update(ChangeName("Pongo", null)); 27 | assertEquals(towser.markup, '

Hello

Pongo

'); 28 | } 29 | 30 | public function testVoidElements() : Void 31 | { 32 | var towser = new Towser("app", TestApp.update, TestApp.view, {name: "Perdita", section: Hello}); 33 | towser.update(ChangeSection(VoidElements)); 34 | assertEquals(towser.markup, '


'); 35 | } 36 | } -------------------------------------------------------------------------------- /tests/TestApp.hx: -------------------------------------------------------------------------------- 1 | import towser.RenderType; 2 | import towser.RenderFunction; 3 | import towser.html.Event; 4 | import towser.html.Attributes.*; 5 | import towser.html.Html.*; 6 | import towser.html.Events.*; 7 | import towser.Towser; 8 | 9 | class TestApp { 10 | public static function view(model:Model) : RenderFunction 11 | { 12 | return switch model.section { 13 | case Hello: div([class_("full-screen"), onclick(ChangeName.bind("Robot"))], [ 14 | h1([], [text("Hello")]), 15 | p([], [text(model.name)]) 16 | ]); 17 | case VoidElements: div([], [ 18 | area([]), 19 | br([]), 20 | col([]), 21 | embed([]), 22 | hr([]), 23 | img([]), 24 | input([]), 25 | param([]), 26 | source([]), 27 | track([]), 28 | wbr([]) 29 | ]); 30 | } 31 | } 32 | 33 | public static function update(towser :Towser, msg:Msg, model:Model) : RenderType 34 | { 35 | return switch msg { 36 | case ChangeName(name, e): 37 | model.name = name; 38 | FULL; 39 | case ChangeSection(section_): 40 | model.section = section_; 41 | FULL; 42 | } 43 | } 44 | } 45 | 46 | enum Msg { 47 | ChangeName(name :String, e :MouseEvent); 48 | ChangeSection(section :Section); 49 | } 50 | 51 | typedef Model = 52 | { 53 | var name :String; 54 | var section :Section; 55 | } 56 | 57 | enum Section 58 | { 59 | Hello; 60 | VoidElements; 61 | } --------------------------------------------------------------------------------