├── .gitignore ├── src ├── dom.rs ├── shared.rs ├── dom │ ├── constants.rs │ └── template.rs ├── config.rs ├── lib.rs └── shared │ ├── fragment.rs │ ├── structs.rs │ ├── constants.rs │ ├── transform.rs │ ├── utils.rs │ └── component.rs ├── .vscode └── settings.json ├── tests ├── fixture │ └── babel │ │ ├── namespace-elements │ │ ├── code.js │ │ └── output.js │ │ ├── custom-elements │ │ ├── code.js │ │ └── output.js │ │ ├── simple-elements │ │ ├── output.js │ │ └── code.js │ │ ├── event-expressions │ │ ├── code.js │ │ └── output.js │ │ ├── fragments │ │ ├── code.js │ │ └── output.js │ │ ├── insert-children │ │ ├── code.js │ │ └── output.js │ │ ├── SVG │ │ ├── code.js │ │ └── output.js │ │ ├── text-interpolation │ │ ├── code.js │ │ └── output.js │ │ ├── conditional-expressions │ │ ├── code.js │ │ └── output.js │ │ ├── components │ │ ├── code.js │ │ └── output.js │ │ └── attribute-expressions │ │ ├── code.js │ │ └── output.js └── fixture.rs ├── .cargo └── config.toml ├── README.md ├── package.json └── Cargo.toml /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | ^target/ 3 | target 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /src/dom.rs: -------------------------------------------------------------------------------- 1 | pub mod constants; 2 | pub mod element; 3 | pub mod template; 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.tabCompletion": "on", 3 | "diffEditor.codeLens": true 4 | } 5 | -------------------------------------------------------------------------------- /src/shared.rs: -------------------------------------------------------------------------------- 1 | pub mod component; 2 | pub mod constants; 3 | pub mod fragment; 4 | pub mod structs; 5 | pub mod transform; 6 | pub mod utils; 7 | -------------------------------------------------------------------------------- /tests/fixture/babel/namespace-elements/code.js: -------------------------------------------------------------------------------- 1 | const template = ; 2 | const template2 = ; 3 | const template3 = ; 4 | const template4 = ; 5 | const template5 = ; 6 | const template6 = ; 7 | -------------------------------------------------------------------------------- /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | # These command aliases are not final, may change 2 | [alias] 3 | # Alias to build actual plugin binary for the specified target. 4 | build-wasi = "rustc --release --target wasm32-wasi --crate-type cdylib" 5 | build-wasm32 = "build --release --target wasm32-unknown-unknown" 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SWC JSX Dom Expressions 2 | 3 | PRs welcome! We're working on converting babel-plugin-dom-expressions to swc. 4 | 5 | # Contributing 6 | 7 | After installing rust, the main command used is `cargo test`, which compares files in `tests/fixture/**/input.js` with the corresponding `output.js`. -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "swc-plugin-jsx-dom-expressions", 3 | "version": "0.1.0", 4 | "description": "", 5 | "author": "", 6 | "license": "ISC", 7 | "keywords": ["swc-plugin"], 8 | "main": "target/wasm32-wasi/release/swc-plugin-jsx-dom-expressions.wasm", 9 | "scripts": { 10 | "prepublishOnly": "cargo build-wasi && cargo build-wasm32" 11 | }, 12 | "files": [] 13 | } 14 | -------------------------------------------------------------------------------- /tests/fixture/babel/namespace-elements/output.js: -------------------------------------------------------------------------------- 1 | import { template as _$template } from "r-dom"; 2 | import { createComponent as _$createComponent } from "r-dom"; 3 | const _tmpl$ = /*#__PURE__*/ _$template(``); 4 | const template = _$createComponent(module.A, {}); 5 | const template2 = _$createComponent(module.a.B, {}); 6 | const template3 = _$createComponent(module.A.B, {}); 7 | const template4 = _$createComponent(module["a-b"], {}); 8 | const template5 = _$createComponent(module["a-b"]["c-d"], {}); 9 | const template6 = _tmpl$(); 10 | -------------------------------------------------------------------------------- /tests/fixture/babel/custom-elements/code.js: -------------------------------------------------------------------------------- 1 | const template = ( 2 | 3 | ); 4 | 5 | const template2 = ( 6 | 12 | ); 13 | 14 | const template3 = ( 15 | 16 |
Title
17 |
18 | ); 19 | 20 | const template4 = ( 21 | <> 22 | 23 | 24 | ); 25 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "jsx-dom-expressions" 3 | version = "0.1.0" 4 | edition = "2024" 5 | 6 | [lib] 7 | crate-type = ["cdylib", "rlib"] 8 | 9 | [profile.release] 10 | lto = true 11 | strip = "symbols" 12 | opt-level = "z" 13 | codegen-units = 1 14 | 15 | [dependencies] 16 | convert_case = "0.8.0" 17 | html-escape = "0.2.13" 18 | once_cell = "1.19.0" 19 | regex = "1.10.5" 20 | serde = { version = "1.0.204", features = ["derive"] } 21 | serde_json = "1.0.120" 22 | swc_core = { version = "33.0", features = [ 23 | "common", 24 | "ecma_ast", 25 | "ecma_minifier", 26 | "ecma_plugin_transform", 27 | "ecma_utils", 28 | "ecma_visit", 29 | "swc_atoms", 30 | ] } 31 | rustc-hash = "2.1.1" 32 | 33 | [dev-dependencies] 34 | swc_core = { version = "33.0", features = [ 35 | "ecma_parser", 36 | "testing_transform", 37 | ] } 38 | testing = "15.0" 39 | -------------------------------------------------------------------------------- /src/dom/constants.rs: -------------------------------------------------------------------------------- 1 | pub const INLINE_ELEMENTS: [&str; 53] = [ 2 | "a", "abbr", "acronym", "b", "bdi", "bdo", "big", "br", "button", "canvas", "cite", "code", 3 | "data", "datalist", "del", "dfn", "em", "embed", "i", "iframe", "img", "input", "ins", "kbd", 4 | "label", "map", "mark", "meter", "noscript", "object", "output", "picture", "progress", "q", 5 | "ruby", "s", "samp", "script", "select", "slot", "small", "span", "strong", "sub", "sup", 6 | "svg", "template", "textarea", "time", "u", "tt", "var", "video", 7 | ]; 8 | 9 | pub const BLOCK_ELEMENTS: [&str; 34] = [ 10 | "address", 11 | "article", 12 | "aside", 13 | "blockquote", 14 | "dd", 15 | "details", 16 | "dialog", 17 | "div", 18 | "dl", 19 | "dt", 20 | "fieldset", 21 | "figcaption", 22 | "figure", 23 | "footer", 24 | "form", 25 | "h1", 26 | "h2", 27 | "h3", 28 | "h4", 29 | "h5", 30 | "h6", 31 | "header", 32 | "hgroup", 33 | "hr", 34 | "li", 35 | "main", 36 | "menu", 37 | "nav", 38 | "ol", 39 | "p", 40 | "pre", 41 | "section", 42 | "table", 43 | "ul", 44 | ]; 45 | -------------------------------------------------------------------------------- /tests/fixture/babel/simple-elements/output.js: -------------------------------------------------------------------------------- 1 | import { template as _$template } from "r-dom"; 2 | import { memo as _$memo } from "r-dom"; 3 | const _tmpl$ = /*#__PURE__*/ _$template( 4 | `

Welcome

` 5 | ), 6 | _tmpl$2 = /*#__PURE__*/ _$template(`
`), 7 | _tmpl$3 = /*#__PURE__*/ _$template(`
`), 8 | _tmpl$4 = /*#__PURE__*/ _$template( 9 | `
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 22 | 27 |
28 | ); 29 | -------------------------------------------------------------------------------- /tests/fixture/babel/simple-elements/code.js: -------------------------------------------------------------------------------- 1 | const template = ( 2 |
3 | 4 |

Welcome

5 | 6 | 7 | {/* Comment Node */} 8 |
9 | ); 10 | 11 | const template2 = ( 12 |
13 | 14 | 15 | 16 | 17 |
18 | ); 19 | 20 | const template3 = ( 21 |
22 |
23 | 24 | 25 |
26 |
27 |
28 |
29 | ); 30 | 31 | const template4 = ( 32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | 42 |
43 |
44 | ); 45 | 46 | const template5 = <>Hello 47 | const template6 = <>{"Hello"} 48 | const template7 = <>{props.id} 49 | const template8 = <>{"1"}{"2"} 50 | const template9 = <>{"1"}{props.id} 51 | const template10 = <>{1} 52 | const template11 = <>{`Hello ${props.name}`} 53 | let id = 123; 54 | const template12 = <>{id} 55 | const signal = () => 1; 56 | const template13 = <>{signal()} 57 | -------------------------------------------------------------------------------- /tests/fixture/babel/fragments/code.js: -------------------------------------------------------------------------------- 1 | const multiStatic = ( 2 | <> 3 |
First
4 |
Last
5 | 6 | ); 7 | 8 | const multiExpression = ( 9 | <> 10 |
First
11 | {inserted} 12 |
Last
13 | After 14 | 15 | ); 16 | 17 | const multiDynamic = ( 18 | <> 19 |
First
20 | {state.inserted} 21 |
Last
22 | After 23 | 24 | ); 25 | 26 | const singleExpression = <>{inserted}; 27 | 28 | const singleDynamic = <>{inserted()}; 29 | 30 | const firstStatic = ( 31 | <> 32 | {inserted} 33 |
34 | 35 | ); 36 | 37 | const firstDynamic = ( 38 | <> 39 | {inserted()} 40 |
41 | 42 | ); 43 | 44 | const firstComponent = ( 45 | <> 46 | 47 |
48 | 49 | ); 50 | 51 | const lastStatic = ( 52 | <> 53 |
54 | {inserted} 55 | 56 | ); 57 | 58 | const lastDynamic = ( 59 | <> 60 |
61 | {inserted()} 62 | 63 | ); 64 | 65 | const lastComponent = ( 66 | <> 67 |
68 | 69 | 70 | ); 71 | 72 | const spaces = <>1 2 3 73 | const multiLineTrailing = <> 74 | 1 75 | 2 76 | 3 77 | -------------------------------------------------------------------------------- /src/config.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Serialize, Deserialize)] 4 | #[serde(rename_all = "camelCase")] 5 | #[serde(default)] 6 | pub struct Config { 7 | pub module_name: String, 8 | pub generate: String, 9 | pub hydratable: bool, 10 | pub delegate_events: bool, 11 | pub delegated_events: Vec, 12 | pub built_ins: Vec, 13 | pub require_import_source: bool, 14 | pub wrap_conditionals: bool, 15 | pub omit_nested_closing_tags: bool, 16 | pub context_to_custom_elements: bool, 17 | pub static_marker: String, 18 | pub effect_wrapper: String, 19 | pub memo_wrapper: String, 20 | pub validate: bool, 21 | } 22 | 23 | impl Default for Config { 24 | fn default() -> Self { 25 | Config { 26 | module_name: "solid-js/web".to_owned(), 27 | generate: "dom".to_owned(), 28 | hydratable: false, 29 | delegate_events: true, 30 | delegated_events: vec![], 31 | built_ins: vec![], 32 | require_import_source: false, 33 | wrap_conditionals: true, 34 | omit_nested_closing_tags: false, 35 | context_to_custom_elements: false, 36 | static_marker: "@once".to_owned(), 37 | effect_wrapper: "effect".to_owned(), 38 | memo_wrapper: "memo".to_owned(), 39 | validate: true, 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/fixture.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use jsx_dom_expressions::TransformVisitor; 4 | use jsx_dom_expressions::config::Config; 5 | use swc_core::common::Mark; 6 | use swc_core::ecma::visit::visit_mut_pass; 7 | use swc_core::{ 8 | ecma::parser::{EsSyntax, Syntax}, 9 | ecma::transforms::base::resolver, 10 | ecma::transforms::testing::test_fixture, 11 | }; 12 | use testing::fixture; 13 | 14 | fn syntax() -> Syntax { 15 | Syntax::Es(EsSyntax { 16 | jsx: true, 17 | ..Default::default() 18 | }) 19 | } 20 | 21 | #[fixture("tests/fixture/babel/**/code.js")] 22 | fn jsx_dom_expressions_fixture_babel(input: PathBuf) { 23 | let output = input.parent().unwrap().join("output.js"); 24 | 25 | test_fixture( 26 | syntax(), 27 | &|t| { 28 | ( 29 | resolver(Mark::new(), Mark::new(), false), 30 | visit_mut_pass(TransformVisitor::new( 31 | Config { 32 | module_name: "r-dom".to_string(), 33 | built_ins: vec!["For".to_string(), "Show".to_string()], 34 | context_to_custom_elements: true, 35 | ..Default::default() 36 | }, 37 | t.comments.clone(), 38 | )), 39 | ) 40 | }, 41 | &input, 42 | &output, 43 | Default::default(), 44 | ); 45 | } 46 | -------------------------------------------------------------------------------- /tests/fixture/babel/custom-elements/output.js: -------------------------------------------------------------------------------- 1 | import { template as _$template } from "r-dom"; 2 | import { setAttribute as _$setAttribute } from "r-dom"; 3 | import { getOwner as _$getOwner } from "r-dom"; 4 | import { effect as _$effect } from "r-dom"; 5 | const _tmpl$ = /*#__PURE__*/ _$template(``, true, false), _tmpl$2 = /*#__PURE__*/ _$template(`
Title`, true, false), _tmpl$3 = /*#__PURE__*/ _$template(``); 6 | const template = (()=>{ 7 | const _el$ = _tmpl$(); 8 | _el$.someAttr = name; 9 | _el$.notprop = data; 10 | _$setAttribute(_el$, "my-attr", data); 11 | _el$.someProp = data; 12 | _el$._$owner = _$getOwner(); 13 | return _el$; 14 | })(); 15 | const template2 = (()=>{ 16 | const _el$2 = _tmpl$(); 17 | _el$2._$owner = _$getOwner(); 18 | _$effect((_p$)=>{ 19 | const _v$ = state.name, _v$2 = state.data, _v$3 = state.data, _v$4 = state.data; 20 | _v$ !== _p$._v$ && (_el$2.someAttr = _p$._v$ = _v$); 21 | _v$2 !== _p$._v$2 && (_el$2.notprop = _p$._v$2 = _v$2); 22 | _v$3 !== _p$._v$3 && _$setAttribute(_el$2, "my-attr", _p$._v$3 = _v$3); 23 | _v$4 !== _p$._v$4 && (_el$2.someProp = _p$._v$4 = _v$4); 24 | return _p$; 25 | }, { 26 | _v$: undefined, 27 | _v$2: undefined, 28 | _v$3: undefined, 29 | _v$4: undefined 30 | }); 31 | return _el$2; 32 | })(); 33 | const template3 = (()=>{ 34 | const _el$3 = _tmpl$2(); 35 | _el$3._$owner = _$getOwner(); 36 | return _el$3; 37 | })(); 38 | const template4 = (()=>{ 39 | const _el$4 = _tmpl$3(); 40 | _el$4._$owner = _$getOwner(); 41 | return _el$4; 42 | })(); 43 | -------------------------------------------------------------------------------- /tests/fixture/babel/insert-children/code.js: -------------------------------------------------------------------------------- 1 | const children =
; 2 | const dynamic = { 3 | children 4 | }; 5 | const template = ; 6 | const template2 = ; 7 | const template3 = Hello; 8 | const template4 = ( 9 | 10 | 11 | 12 | ); 13 | const template5 = ; 14 | const template6 = ; 15 | const template7 = ; 16 | const template8 = Hello; 17 | const template9 = {dynamic.children}; 18 | const template10 = Hello; 19 | const template11 = ; 20 | const template12 = ; 21 | const template13 = {...children}; 22 | const template14 = {...children}; 23 | const template15 = {...dynamic.children}; 24 | const template16 = {...dynamic.children}; 25 | const template18 = Hi {...children}; 26 | const template19 = Hi {...children}; 27 | const template20 = {children()}; 28 | const template21 = {children()}; 29 | const template22 = {state.children()}; 30 | const template23 = {state.children()}; 31 | const template24 = Hi{dynamic.children}; 32 | 33 | const tiles = []; 34 | tiles.push(
Test 1
); 35 | const template25 =
{tiles}
; 36 | 37 | const comma =
{expression(), "static"}
38 | -------------------------------------------------------------------------------- /tests/fixture/babel/SVG/code.js: -------------------------------------------------------------------------------- 1 | const template = ( 2 | 3 | 13 | 14 | 15 | 16 | 17 | ); 18 | 19 | const template2 = ( 20 | 21 | 37 | 38 | ); 39 | 40 | const template3 = ( 41 | 42 | 43 | 44 | ); 45 | 46 | const template4 = ; 47 | 48 | const template5 = ( 49 | <> 50 | 51 | 52 | ); 53 | 54 | const template6 = ( 55 | 56 | 57 | 58 | ); 59 | 60 | const template7 = ( 61 | 62 | 63 | 64 | MDN Web Docs 65 | 66 | 67 | 68 | ); 69 | 70 | const template8 = ( 71 | 72 | 73 | 74 | ); 75 | -------------------------------------------------------------------------------- /tests/fixture/babel/fragments/output.js: -------------------------------------------------------------------------------- 1 | import { template as _$template } from "r-dom"; 2 | import { setAttribute as _$setAttribute } from "r-dom"; 3 | import { memo as _$memo } from "r-dom"; 4 | import { effect as _$effect } from "r-dom"; 5 | import { createComponent as _$createComponent } from "r-dom"; 6 | const _tmpl$ = /*#__PURE__*/ _$template(`
First`), _tmpl$2 = /*#__PURE__*/ _$template(`
Last`), _tmpl$3 = /*#__PURE__*/ _$template(`
`), _tmpl$4 = /*#__PURE__*/ _$template(`1`), _tmpl$5 = /*#__PURE__*/ _$template(`2`), _tmpl$6 = /*#__PURE__*/ _$template(`3`); 7 | const multiStatic = [ 8 | _tmpl$(), 9 | _tmpl$2() 10 | ]; 11 | const multiExpression = [ 12 | _tmpl$(), 13 | inserted, 14 | _tmpl$2(), 15 | "After" 16 | ]; 17 | const multiDynamic = [ 18 | (()=>{ 19 | const _el$5 = _tmpl$(); 20 | _$effect(()=>_$setAttribute(_el$5, "id", state.first)); 21 | return _el$5; 22 | })(), 23 | _$memo(()=>state.inserted), 24 | (()=>{ 25 | const _el$6 = _tmpl$2(); 26 | _$effect(()=>_$setAttribute(_el$6, "id", state.last)); 27 | return _el$6; 28 | })(), 29 | "After" 30 | ]; 31 | const singleExpression = inserted; 32 | const singleDynamic = _$memo(inserted); 33 | const firstStatic = [ 34 | inserted, 35 | _tmpl$3() 36 | ]; 37 | const firstDynamic = [ 38 | _$memo(inserted), 39 | _tmpl$3() 40 | ]; 41 | const firstComponent = [ 42 | _$createComponent(Component, {}), 43 | _tmpl$3() 44 | ]; 45 | const lastStatic = [ 46 | _tmpl$3(), 47 | inserted 48 | ]; 49 | const lastDynamic = [ 50 | _tmpl$3(), 51 | _$memo(inserted) 52 | ]; 53 | const lastComponent = [ 54 | _tmpl$3(), 55 | _$createComponent(Component, {}) 56 | ]; 57 | const spaces = [ 58 | _tmpl$4(), 59 | " ", 60 | _tmpl$5(), 61 | " ", 62 | _tmpl$6() 63 | ]; 64 | const multiLineTrailing = [ 65 | _tmpl$4(), 66 | _tmpl$5(), 67 | _tmpl$6() 68 | ]; 69 | -------------------------------------------------------------------------------- /tests/fixture/babel/event-expressions/output.js: -------------------------------------------------------------------------------- 1 | import { template as _$template } from "r-dom"; 2 | import { delegateEvents as _$delegateEvents } from "r-dom"; 3 | import { addEventListener as _$addEventListener } from "r-dom"; 4 | const _tmpl$ = /*#__PURE__*/ _$template(`
85 | ); 86 | 87 | const template17 = ( 88 | 98 | ); 99 | 100 | const template18 = ( 101 |
108 | ); 109 | 110 | const template19 =
; 111 | 112 | const template20 = ( 113 |
114 | 115 | 116 |
117 | ); 118 | 119 | const template21 =
; 120 | 121 | const template22 =
; 122 | 123 | const template23 =
{"t" in test && "true"}
; 124 | 125 | const template24 = ; 126 | 127 | const template25 = ( 128 | 132 | ); 133 | 134 | const template26 = ( 135 |
136 | Hi 137 |
138 | ); 139 | 140 | const template27 = ( 141 |
142 | Hi 143 |
144 | ); 145 | 146 | const template28 = ( 147 |
151 | 152 | ); 153 | 154 | const template29 =
{!!someValue}
; 155 | 156 | const template30 = ( 157 |
168 | ); 169 | 170 | const template31 = ( 171 |
174 | ); 175 | 176 | const template32 = ( 177 |
180 | ); -------------------------------------------------------------------------------- /tests/fixture/babel/text-interpolation/output.js: -------------------------------------------------------------------------------- 1 | import { template as _$template } from "r-dom"; 2 | import { insert as _$insert } from "r-dom"; 3 | import { createComponent as _$createComponent } from "r-dom"; 4 | const _tmpl$ = /*#__PURE__*/ _$template(`Hello `), _tmpl$2 = /*#__PURE__*/ _$template(` John`), _tmpl$3 = /*#__PURE__*/ _$template(`Hello John`), _tmpl$4 = /*#__PURE__*/ _$template(` `), _tmpl$5 = /*#__PURE__*/ _$template(` `), _tmpl$6 = /*#__PURE__*/ _$template(` `), _tmpl$7 = /*#__PURE__*/ _$template(`Hello`), _tmpl$8 = /*#__PURE__*/ _$template(` <Hi> `), _tmpl$9 = /*#__PURE__*/ _$template(`Hi<script>alert();</script>`), _tmpl$10 = /*#__PURE__*/ _$template(`4 + 5 = 9`), _tmpl$11 = /*#__PURE__*/ _$template(`
5 | d`), _tmpl$12 = /*#__PURE__*/ _$template(`
`), _tmpl$13 = /*#__PURE__*/ _$template(`
`), _tmpl$14 = /*#__PURE__*/ _$template(`
`); 6 | const trailing = _tmpl$(); 7 | const leading = _tmpl$2(); 8 | /* prettier-ignore */ const extraSpaces = _tmpl$3(); 9 | const trailingExpr = (()=>{ 10 | const _el$4 = _tmpl$(), _el$5 = _el$4.firstChild; 11 | _$insert(_el$4, name, null); 12 | return _el$4; 13 | })(); 14 | const leadingExpr = (()=>{ 15 | const _el$6 = _tmpl$2(), _el$7 = _el$6.firstChild; 16 | _$insert(_el$6, greeting, _el$7); 17 | return _el$6; 18 | })(); 19 | /* prettier-ignore */ const multiExpr = (()=>{ 20 | const _el$8 = _tmpl$4(), _el$9 = _el$8.firstChild; 21 | _$insert(_el$8, greeting, _el$9); 22 | _$insert(_el$8, name, null); 23 | return _el$8; 24 | })(); 25 | /* prettier-ignore */ const multiExprSpaced = (()=>{ 26 | const _el$10 = _tmpl$5(), _el$11 = _el$10.firstChild, _el$14 = _el$11.nextSibling, _el$12 = _el$14.nextSibling, _el$15 = _el$12.nextSibling, _el$13 = _el$15.nextSibling; 27 | _$insert(_el$10, greeting, _el$14); 28 | _$insert(_el$10, name, _el$15); 29 | return _el$10; 30 | })(); 31 | /* prettier-ignore */ const multiExprTogether = (()=>{ 32 | const _el$16 = _tmpl$6(), _el$17 = _el$16.firstChild, _el$19 = _el$17.nextSibling, _el$18 = _el$19.nextSibling; 33 | _$insert(_el$16, greeting, _el$19); 34 | _$insert(_el$16, name, _el$19); 35 | return _el$16; 36 | })(); 37 | /* prettier-ignore */ const multiLine = _tmpl$7(); 38 | /* prettier-ignore */ const multiLineTrailingSpace = _tmpl$3(); 39 | /* prettier-ignore */ const multiLineNoTrailingSpace = _tmpl$3(); 40 | /* prettier-ignore */ const escape = _tmpl$8(); 41 | /* prettier-ignore */ const escape2 = _$createComponent(Comp, { 42 | children: "\xa0\xa0" 43 | }); 44 | /* prettier-ignore */ const escape3 = "\xa0\xa0"; 45 | const injection = _tmpl$9(); 46 | let value = "World"; 47 | const evaluated = (()=>{ 48 | const _el$25 = _tmpl$(), _el$26 = _el$25.firstChild; 49 | _$insert(_el$25, value + "!", null); 50 | return _el$25; 51 | })(); 52 | let number = 4 + 5; 53 | const evaluatedNonString = _tmpl$10(); 54 | const newLineLiteral = (()=>{ 55 | const _el$28 = _tmpl$11(), _el$29 = _el$28.firstChild; 56 | _$insert(_el$28, s, _el$29); 57 | return _el$28; 58 | })(); 59 | const trailingSpace = (()=>{ 60 | const _el$30 = _tmpl$12(); 61 | _$insert(_el$30, expr); 62 | return _el$30; 63 | })(); 64 | const trailingSpaceComp = _$createComponent(Comp, { 65 | children: expr 66 | }); 67 | const trailingSpaceFrag = expr; 68 | const leadingSpaceElement = (()=>{ 69 | const _el$31 = _tmpl$4(), _el$32 = _el$31.firstChild; 70 | _$insert(_el$31, expr, null); 71 | return _el$31; 72 | })(); 73 | const leadingSpaceComponent = _$createComponent(Div, { 74 | get children () { 75 | return [ 76 | " ", 77 | expr 78 | ]; 79 | } 80 | }); 81 | const leadingSpaceFragment = [ 82 | " ", 83 | expr 84 | ]; 85 | const trailingSpaceElement = (()=>{ 86 | const _el$33 = _tmpl$4(), _el$34 = _el$33.firstChild; 87 | _$insert(_el$33, expr, _el$34); 88 | return _el$33; 89 | })(); 90 | const trailingSpaceComponent = _$createComponent(Div, { 91 | get children () { 92 | return [ 93 | expr, 94 | " " 95 | ]; 96 | } 97 | }); 98 | const trailingSpaceFragment = [ 99 | expr, 100 | " " 101 | ]; 102 | const escapeAttribute = _tmpl$13(); 103 | const escapeCompAttribute = _$createComponent(Div, { 104 | normal: "Search…", 105 | title: "Search…" 106 | }); 107 | const lastElementExpression = (()=>{ 108 | const _el$36 = _tmpl$14(), _el$37 = _el$36.firstChild; 109 | _$insert(_el$36, expr, null); 110 | return _el$36; 111 | })(); 112 | -------------------------------------------------------------------------------- /src/shared/constants.rs: -------------------------------------------------------------------------------- 1 | use once_cell::sync::Lazy; 2 | use std::collections::{HashMap, HashSet}; 3 | 4 | pub static PROP_ALIASES_OBJ: Lazy>> = Lazy::new(|| { 5 | HashMap::from([ 6 | ( 7 | "formnovalidate", 8 | HashMap::from([("$", "formNoValidate"), ("BUTTON", "1"), ("INPUT", "1")]), 9 | ), 10 | ("ismap", HashMap::from([("$", "isMap"), ("IMG", "1")])), 11 | ( 12 | "nomodule", 13 | HashMap::from([("$", "noModule"), ("SCRIPT", "1")]), 14 | ), 15 | ( 16 | "playsinline", 17 | HashMap::from([("$", "playsInline"), ("VIDEO", "1")]), 18 | ), 19 | ( 20 | "readonly", 21 | HashMap::from([("$", "readOnly"), ("INPUT", "1"), ("TEXTAREA", "1")]), 22 | ), 23 | ]) 24 | }); 25 | 26 | pub fn get_prop_alias(prop: &str, tag_name: &str) -> Option { 27 | if prop == "class" { 28 | return Some("className".to_string()); 29 | } 30 | let a = PROP_ALIASES_OBJ.get(prop)?; 31 | a.get(tag_name).map(|_| a.get("$").unwrap().to_string()) 32 | } 33 | 34 | pub static DELEGATED_EVENTS: Lazy> = Lazy::new(|| { 35 | HashSet::from([ 36 | "beforeinput", 37 | "click", 38 | "dblclick", 39 | "contextmenu", 40 | "focusin", 41 | "focusout", 42 | "input", 43 | "keydown", 44 | "keyup", 45 | "mousedown", 46 | "mousemove", 47 | "mouseout", 48 | "mouseover", 49 | "mouseup", 50 | "pointerdown", 51 | "pointermove", 52 | "pointerout", 53 | "pointerover", 54 | "pointerup", 55 | "touchend", 56 | "touchmove", 57 | "touchstart", 58 | ]) 59 | }); 60 | 61 | pub const SVG_ELEMENTS: [&str; 76] = [ 62 | "altGlyph", 63 | "altGlyphDef", 64 | "altGlyphItem", 65 | "animate", 66 | "animateColor", 67 | "animateMotion", 68 | "animateTransform", 69 | "circle", 70 | "clipPath", 71 | "color-profile", 72 | "cursor", 73 | "defs", 74 | "desc", 75 | "ellipse", 76 | "feBlend", 77 | "feColorMatrix", 78 | "feComponentTransfer", 79 | "feComposite", 80 | "feConvolveMatrix", 81 | "feDiffuseLighting", 82 | "feDisplacementMap", 83 | "feDistantLight", 84 | "feFlood", 85 | "feFuncA", 86 | "feFuncB", 87 | "feFuncG", 88 | "feFuncR", 89 | "feGaussianBlur", 90 | "feImage", 91 | "feMerge", 92 | "feMergeNode", 93 | "feMorphology", 94 | "feOffset", 95 | "fePointLight", 96 | "feSpecularLighting", 97 | "feSpotLight", 98 | "feTile", 99 | "feTurbulence", 100 | "filter", 101 | "font", 102 | "font-face", 103 | "font-face-format", 104 | "font-face-name", 105 | "font-face-src", 106 | "font-face-uri", 107 | "foreignObject", 108 | "g", 109 | "glyph", 110 | "glyphRef", 111 | "hkern", 112 | "image", 113 | "line", 114 | "linearGradient", 115 | "marker", 116 | "mask", 117 | "metadata", 118 | "missing-glyph", 119 | "mpath", 120 | "path", 121 | "pattern", 122 | "polygon", 123 | "polyline", 124 | "radialGradient", 125 | "rect", 126 | "set", 127 | "stop", 128 | "svg", 129 | "switch", 130 | "symbol", 131 | "text", 132 | "textPath", 133 | "tref", 134 | "tspan", 135 | "use", 136 | "view", 137 | "vkern", 138 | ]; 139 | 140 | pub static SVGNAMESPACE: Lazy> = Lazy::new(|| { 141 | HashMap::from([ 142 | ("xlink", "http://www.w3.org/1999/xlink"), 143 | ("xml", "http://www.w3.org/XML/1998/namespace"), 144 | ]) 145 | }); 146 | 147 | pub const VOID_ELEMENTS: [&str; 16] = [ 148 | "area", "base", "br", "col", "embed", "hr", "img", "input", "keygen", "link", "menuitem", 149 | "meta", "param", "source", "track", "wbr", 150 | ]; 151 | 152 | pub static ALIASES: Lazy> = 153 | Lazy::new(|| HashMap::from([("className", "class"), ("htmlFor", "for")])); 154 | 155 | pub static CHILD_PROPERTIES: Lazy> = 156 | Lazy::new(|| HashSet::from(["innerHTML", "textContent", "innerText", "children"])); 157 | 158 | pub const BOOLEANS: [&str; 24] = [ 159 | "allowfullscreen", 160 | "async", 161 | "autofocus", 162 | "autoplay", 163 | "checked", 164 | "controls", 165 | "default", 166 | "disabled", 167 | "formnovalidate", 168 | "hidden", 169 | "indeterminate", 170 | "ismap", 171 | "loop", 172 | "multiple", 173 | "muted", 174 | "nomodule", 175 | "novalidate", 176 | "open", 177 | "playsinline", 178 | "readonly", 179 | "required", 180 | "reversed", 181 | "seamless", 182 | "selected", 183 | ]; 184 | 185 | pub static PROPERTIES: Lazy> = Lazy::new(|| { 186 | [ 187 | "className", 188 | "value", 189 | "readOnly", 190 | "formNoValidate", 191 | "isMap", 192 | "noModule", 193 | "playsInline", 194 | ] 195 | .into_iter() 196 | .chain(BOOLEANS) 197 | .collect() 198 | }); 199 | -------------------------------------------------------------------------------- /tests/fixture/babel/conditional-expressions/output.js: -------------------------------------------------------------------------------- 1 | import { template as _$template } from "r-dom"; 2 | import { memo as _$memo } from "r-dom"; 3 | import { insert as _$insert } from "r-dom"; 4 | import { effect as _$effect } from "r-dom"; 5 | import { createComponent as _$createComponent } from "r-dom"; 6 | const _tmpl$ = /*#__PURE__*/ _$template(`
`); 7 | const template1 = (()=>{ 8 | const _el$ = _tmpl$(); 9 | _$insert(_el$, simple); 10 | return _el$; 11 | })(); 12 | const template2 = (()=>{ 13 | const _el$2 = _tmpl$(); 14 | _$insert(_el$2, ()=>state.dynamic); 15 | return _el$2; 16 | })(); 17 | const template3 = (()=>{ 18 | const _el$3 = _tmpl$(); 19 | _$insert(_el$3, simple ? good : bad); 20 | return _el$3; 21 | })(); 22 | const template4 = (()=>{ 23 | const _el$4 = _tmpl$(); 24 | _$insert(_el$4, ()=>simple ? good() : bad); 25 | return _el$4; 26 | })(); 27 | const template5 = (()=>{ 28 | const _el$5 = _tmpl$(); 29 | _$insert(_el$5, (()=>{ 30 | const _c$ = _$memo(()=>!!state.dynamic); 31 | return ()=>_c$() ? good() : bad; 32 | })()); 33 | return _el$5; 34 | })(); 35 | const template6 = (()=>{ 36 | const _el$6 = _tmpl$(); 37 | _$insert(_el$6, (()=>{ 38 | const _c$2 = _$memo(()=>!!state.dynamic); 39 | return ()=>_c$2() && good(); 40 | })()); 41 | return _el$6; 42 | })(); 43 | const template7 = (()=>{ 44 | const _el$7 = _tmpl$(); 45 | _$insert(_el$7, (()=>{ 46 | const _c$3 = _$memo(()=>state.count > 5); 47 | return ()=>_c$3() ? (()=>{ 48 | const _c$4 = _$memo(()=>!!state.dynamic); 49 | return ()=>_c$4() ? best : good(); 50 | })() : bad; 51 | })()); 52 | return _el$7; 53 | })(); 54 | const template8 = (()=>{ 55 | const _el$8 = _tmpl$(); 56 | _$insert(_el$8, (()=>{ 57 | const _c$5 = _$memo(()=>!!(state.dynamic && state.something)); 58 | return ()=>_c$5() && good(); 59 | })()); 60 | return _el$8; 61 | })(); 62 | const template9 = (()=>{ 63 | const _el$9 = _tmpl$(); 64 | _$insert(_el$9, (()=>{ 65 | const _c$6 = _$memo(()=>!!state.dynamic); 66 | return ()=>_c$6() && good() || bad; 67 | })() 68 | ); 69 | return _el$9; 70 | })(); 71 | const template10 = (()=>{ 72 | const _el$10 = _tmpl$(); 73 | _$insert(_el$10, ()=>state.a ? "a" : state.b ? "b" : state.c ? "c" : "fallback"); 74 | return _el$10; 75 | })(); 76 | const template11 = (()=>{ 77 | const _el$11 = _tmpl$(); 78 | _$insert(_el$11, (()=>{ 79 | const _c$7 = _$memo(()=>!!state.a); 80 | return ()=>_c$7() ? a() : (()=>{ 81 | const _c$8 = _$memo(()=>!!state.b); 82 | return ()=>_c$8() ? b() : state.c ? "c" : "fallback"; 83 | })(); 84 | })()); 85 | return _el$11; 86 | })(); 87 | const template12 = _$createComponent(Comp, { 88 | get render () { 89 | return _$memo(()=>!!state.dynamic)() ? good() : bad; 90 | } 91 | }); 92 | // no dynamic predicate 93 | const template13 = _$createComponent(Comp, { 94 | get render () { 95 | return state.dynamic ? good : bad; 96 | } 97 | }); 98 | const template14 = _$createComponent(Comp, { 99 | get render () { 100 | return _$memo(()=>!!state.dynamic)() && good(); 101 | } 102 | }); 103 | // no dynamic predicate 104 | const template15 = _$createComponent(Comp, { 105 | get render () { 106 | return state.dynamic && good; 107 | } 108 | }); 109 | const template16 = _$createComponent(Comp, { 110 | get render () { 111 | return state.dynamic || good(); 112 | } 113 | }); 114 | const template17 = _$createComponent(Comp, { 115 | get render () { 116 | return _$memo(()=>!!state.dynamic)() ? _$createComponent(Comp, {}) : _$createComponent(Comp, {}); 117 | } 118 | }); 119 | const template18 = _$createComponent(Comp, { 120 | get children () { 121 | return _$memo(()=>!!state.dynamic)() ? _$createComponent(Comp, {}) : _$createComponent(Comp, {}); 122 | } 123 | }); 124 | const template19 = (()=>{ 125 | const _el$12 = _tmpl$(); 126 | _$effect(()=>_el$12.innerHTML = state.dynamic ? _$createComponent(Comp, {}) : _$createComponent(Comp, {})); 127 | return _el$12; 128 | })(); 129 | const template20 = (()=>{ 130 | const _el$13 = _tmpl$(); 131 | _$insert(_el$13, (()=>{ 132 | const _c$9 = _$memo(()=>!!state.dynamic); 133 | return ()=>_c$9() ? _$createComponent(Comp, {}) : _$createComponent(Comp, {}); 134 | })()); 135 | return _el$13; 136 | })(); 137 | const template21 = _$createComponent(Comp, { 138 | get render () { 139 | return state?.dynamic ? "a" : "b"; 140 | } 141 | }); 142 | const template22 = _$createComponent(Comp, { 143 | get children () { 144 | return state?.dynamic ? "a" : "b"; 145 | } 146 | }); 147 | const template23 = (()=>{ 148 | const _el$14 = _tmpl$(); 149 | _$effect(()=>_el$14.innerHTML = state?.dynamic ? "a" : "b"); 150 | return _el$14; 151 | })(); 152 | const template24 = (()=>{ 153 | const _el$15 = _tmpl$(); 154 | _$insert(_el$15, ()=>state?.dynamic ? "a" : "b"); 155 | return _el$15; 156 | })(); 157 | const template25 = _$createComponent(Comp, { 158 | get render () { 159 | return state.dynamic ?? _$createComponent(Comp, {}); 160 | } 161 | }); 162 | const template26 = _$createComponent(Comp, { 163 | get children () { 164 | return state.dynamic ?? _$createComponent(Comp, {}); 165 | } 166 | }); 167 | const template27 = (()=>{ 168 | const _el$16 = _tmpl$(); 169 | _$effect(()=>_el$16.innerHTML = state.dynamic ?? _$createComponent(Comp, {})); 170 | return _el$16; 171 | })(); 172 | const template28 = (()=>{ 173 | const _el$17 = _tmpl$(); 174 | _$insert(_el$17, ()=>state.dynamic ?? _$createComponent(Comp, {})); 175 | return _el$17; 176 | })(); 177 | const template29 = (()=>{ 178 | const _el$18 = _tmpl$(); 179 | _$insert(_el$18, (()=>{ 180 | const _c$10 = _$memo(()=>!!thing()); 181 | return ()=>(_c$10() && thing1()) ?? thing2() ?? thing3(); 182 | })()); 183 | return _el$18; 184 | })(); 185 | const template30 = (()=>{ 186 | const _el$19 = _tmpl$(); 187 | _$insert(_el$19, ()=>thing() || thing1() || thing2()); 188 | return _el$19; 189 | })(); 190 | const template31 = _$createComponent(Comp, { 191 | get value () { 192 | return _$memo(()=>!!count())() ? _$memo(()=>!!count())() ? count() : count() : count(); 193 | } 194 | }); 195 | const template32 = (()=>{ 196 | const _el$20 = _tmpl$(); 197 | _$insert(_el$20, ()=>something?.()); 198 | return _el$20; 199 | })(); 200 | const template33 = _$createComponent(Comp, { 201 | get children () { 202 | return something?.(); 203 | } 204 | }); 205 | -------------------------------------------------------------------------------- /tests/fixture/babel/components/output.js: -------------------------------------------------------------------------------- 1 | import { use as _$use } from "r-dom"; 2 | import { template as _$template } from "r-dom"; 3 | import { mergeProps as _$mergeProps } from "r-dom"; 4 | import { memo as _$memo } from "r-dom"; 5 | import { insert as _$insert } from "r-dom"; 6 | import { createComponent as _$createComponent } from "r-dom"; 7 | import { For as _$For } from "r-dom"; 8 | const _tmpl$ = /*#__PURE__*/ _$template(`
Hello `), _tmpl$2 = /*#__PURE__*/ _$template(`
`), _tmpl$3 = /*#__PURE__*/ _$template(`
From Parent`), _tmpl$4 = /*#__PURE__*/ _$template(`
| | | | | `), _tmpl$5 = /*#__PURE__*/ _$template(`
| | | `), _tmpl$6 = /*#__PURE__*/ _$template(`
| | | | | `), _tmpl$7 = /*#__PURE__*/ _$template(`1`), _tmpl$8 = /*#__PURE__*/ _$template(`2`), _tmpl$9 = /*#__PURE__*/ _$template(`3`); 9 | import { Show } from "somewhere"; 10 | const Child = (props1)=>{ 11 | const [s, set] = createSignal(); 12 | return [ 13 | (()=>{ 14 | const _el$ = _tmpl$(), _ref$ = props1.ref, _el$2 = _el$.firstChild; 15 | typeof _ref$ === "function" ? _$use(_ref$, _el$) : props1.ref = _el$; 16 | _$insert(_el$, ()=>props1.name, null); 17 | return _el$; 18 | })(), 19 | (()=>{ 20 | const _el$3 = _tmpl$2(); 21 | _$use(set, _el$3); 22 | _$insert(_el$3, ()=>props1.children); 23 | return _el$3; 24 | })() 25 | ]; 26 | }; 27 | const template = (props1)=>{ 28 | let childRef; 29 | const { content } = props1; 30 | return (()=>{ 31 | const _el$4 = _tmpl$2(); 32 | _$insert(_el$4, _$createComponent(Child, _$mergeProps({ 33 | name: "John" 34 | }, props1, { 35 | ref (r$) { 36 | const _ref$2 = childRef; 37 | typeof _ref$2 === "function" ? _ref$2(r$) : childRef = r$; 38 | }, 39 | booleanProperty: true, 40 | get children () { 41 | return _tmpl$3(); 42 | } 43 | })), null); 44 | _$insert(_el$4, _$createComponent(Child, _$mergeProps({ 45 | name: "Jason" 46 | }, dynamicSpread, { 47 | ref (r$) { 48 | const _ref$3 = props1.ref; 49 | typeof _ref$3 === "function" ? _ref$3(r$) : props1.ref = r$; 50 | }, 51 | get children () { 52 | const _el$6 = _tmpl$2(); 53 | _$insert(_el$6, content); 54 | return _el$6; 55 | } 56 | })), null); 57 | _$insert(_el$4, _$createComponent(Context.Consumer, { 58 | ref (r$) { 59 | const _ref$4 = props1.consumerRef(); 60 | typeof _ref$4 === "function" && _ref$4(r$); 61 | }, 62 | children: (context)=>context 63 | }), null); 64 | return _el$4; 65 | })(); 66 | }; 67 | const template2 = _$createComponent(Child, { 68 | name: "Jake", 69 | get dynamic () { 70 | return state.data; 71 | }, 72 | stale: state.data, 73 | handleClick: clickHandler, 74 | get "hyphen-ated" () { 75 | return state.data; 76 | }, 77 | ref: (el)=>e = el 78 | }); 79 | const template3 = _$createComponent(Child, { 80 | get children () { 81 | return [ 82 | _tmpl$2(), 83 | _tmpl$2(), 84 | _tmpl$2(), 85 | "After" 86 | ]; 87 | } 88 | }); 89 | const [s, set] = createSignal(); 90 | const template4 = _$createComponent(Child, { 91 | ref: set, 92 | get children () { 93 | return _tmpl$2(); 94 | } 95 | }); 96 | const template5 = _$createComponent(Child, { 97 | get dynamic () { 98 | return state.dynamic; 99 | }, 100 | get children () { 101 | return state.dynamic; 102 | } 103 | }); 104 | // builtIns 105 | const template6 = _$createComponent(_$For, { 106 | get each () { 107 | return state.list; 108 | }, 109 | get fallback () { 110 | return _$createComponent(Loading, {}); 111 | }, 112 | children: (item)=>_$createComponent(Show, { 113 | get when () { 114 | return state.condition; 115 | }, 116 | children: item 117 | }) 118 | }); 119 | const template7 = _$createComponent(Child, { 120 | get children () { 121 | return [ 122 | _tmpl$2(), 123 | _$memo(()=>state.dynamic) 124 | ]; 125 | } 126 | }); 127 | const template8 = _$createComponent(Child, { 128 | get children () { 129 | return [ 130 | (item)=>item, 131 | (item)=>item 132 | ]; 133 | } 134 | }); 135 | const template9 = _$createComponent(_garbage, { 136 | children: "Hi" 137 | }); 138 | const template10 = (()=>{ 139 | const _el$12 = _tmpl$4(), _el$13 = _el$12.firstChild, _el$18 = _el$13.nextSibling, _el$14 = _el$18.nextSibling, _el$19 = _el$14.nextSibling, _el$15 = _el$19.nextSibling, _el$20 = _el$15.nextSibling, _el$16 = _el$20.nextSibling, _el$21 = _el$16.nextSibling, _el$17 = _el$21.nextSibling; 140 | _$insert(_el$12, _$createComponent(Link, { 141 | children: "new" 142 | }), _el$13); 143 | _$insert(_el$12, _$createComponent(Link, { 144 | children: "comments" 145 | }), _el$18); 146 | _$insert(_el$12, _$createComponent(Link, { 147 | children: "show" 148 | }), _el$19); 149 | _$insert(_el$12, _$createComponent(Link, { 150 | children: "ask" 151 | }), _el$20); 152 | _$insert(_el$12, _$createComponent(Link, { 153 | children: "jobs" 154 | }), _el$21); 155 | _$insert(_el$12, _$createComponent(Link, { 156 | children: "submit" 157 | }), null); 158 | return _el$12; 159 | })(); 160 | const template11 = (()=>{ 161 | const _el$22 = _tmpl$5(), _el$23 = _el$22.firstChild, _el$26 = _el$23.nextSibling, _el$24 = _el$26.nextSibling, _el$27 = _el$24.nextSibling, _el$25 = _el$27.nextSibling; 162 | _$insert(_el$22, _$createComponent(Link, { 163 | children: "new" 164 | }), _el$23); 165 | _$insert(_el$22, _$createComponent(Link, { 166 | children: "comments" 167 | }), _el$26); 168 | _$insert(_el$22, _$createComponent(Link, { 169 | children: "show" 170 | }), _el$26); 171 | _$insert(_el$22, _$createComponent(Link, { 172 | children: "ask" 173 | }), _el$27); 174 | _$insert(_el$22, _$createComponent(Link, { 175 | children: "jobs" 176 | }), _el$27); 177 | _$insert(_el$22, _$createComponent(Link, { 178 | children: "submit" 179 | }), null); 180 | return _el$22; 181 | })(); 182 | const template12 = (()=>{ 183 | const _el$28 = _tmpl$6(), _el$29 = _el$28.firstChild, _el$34 = _el$29.nextSibling, _el$30 = _el$34.nextSibling, _el$35 = _el$30.nextSibling, _el$33 = _el$35.nextSibling; 184 | _$insert(_el$28, _$createComponent(Link, { 185 | children: "comments" 186 | }), _el$34); 187 | _$insert(_el$28, _$createComponent(Link, { 188 | children: "show" 189 | }), _el$35); 190 | return _el$28; 191 | })(); 192 | class Template13 { 193 | render() { 194 | const _self$ = this; 195 | _$createComponent(Component, { 196 | get prop () { 197 | return _self$.something; 198 | }, 199 | onClick: ()=>_self$.shouldStay, 200 | get children () { 201 | return _$createComponent(Nested, { 202 | get prop () { 203 | return _self$.data; 204 | }, 205 | get children () { 206 | return _self$.content; 207 | } 208 | }); 209 | } 210 | }); 211 | } 212 | } 213 | const Template14 = _$createComponent(Component, { 214 | get children () { 215 | return data(); 216 | } 217 | }); 218 | const Template15 = _$createComponent(Component, props); 219 | const Template16 = _$createComponent(Component, _$mergeProps({ 220 | something: something 221 | }, props)); 222 | const Template17 = _$createComponent(Pre, { 223 | get children () { 224 | return [ 225 | _tmpl$7(), 226 | " ", 227 | _tmpl$8(), 228 | " ", 229 | _tmpl$9() 230 | ]; 231 | } 232 | }); 233 | const Template18 = _$createComponent(Pre, { 234 | get children () { 235 | return [ 236 | _tmpl$7(), 237 | _tmpl$8(), 238 | _tmpl$9() 239 | ]; 240 | } 241 | }); 242 | const Template19 = _$createComponent(Component, _$mergeProps(()=>s.dynamic())); 243 | const Template20 = _$createComponent(Component, { 244 | get "class" () { 245 | return prop.red ? "red" : "green"; 246 | } 247 | }); 248 | const template21 = _$createComponent(Component, _$mergeProps(()=>({ 249 | get [key()] () { 250 | return props.value; 251 | } 252 | }))); 253 | const template22 = _$createComponent(Component, { 254 | get passObject () { 255 | return { 256 | ...a 257 | }; 258 | } 259 | }); 260 | const template23 = _$createComponent(Component, { 261 | get disabled () { 262 | return "t" in test; 263 | }, 264 | get children () { 265 | return "t" in test && "true"; 266 | } 267 | }); 268 | const template24 = _$createComponent(Component, { 269 | get children () { 270 | return state.dynamic; 271 | } 272 | }); 273 | const template25 = _$createComponent(Component, { 274 | get children () { 275 | return _tmpl$2(); 276 | } 277 | }); 278 | -------------------------------------------------------------------------------- /tests/fixture/babel/attribute-expressions/output.js: -------------------------------------------------------------------------------- 1 | import { use as _$use } from "r-dom"; 2 | import { template as _$template } from "r-dom"; 3 | import { style as _$style } from "r-dom"; 4 | import { spread as _$spread } from "r-dom"; 5 | import { setAttribute as _$setAttribute } from "r-dom"; 6 | import { mergeProps as _$mergeProps } from "r-dom"; 7 | import { memo as _$memo } from "r-dom"; 8 | import { insert as _$insert } from "r-dom"; 9 | import { effect as _$effect } from "r-dom"; 10 | import { delegateEvents as _$delegateEvents } from "r-dom"; 11 | import { className as _$className } from "r-dom"; 12 | import { classList as _$classList } from "r-dom"; 13 | import { addEventListener as _$addEventListener } from "r-dom"; 14 | const _tmpl$ = /*#__PURE__*/ _$template(`

Welcome`), _tmpl$2 = /*#__PURE__*/ _$template(`
`), _tmpl$3 = /*#__PURE__*/ _$template(`
`), _tmpl$4 = /*#__PURE__*/ _$template(`
`), _tmpl$5 = /*#__PURE__*/ _$template(`
`), _tmpl$6 = /*#__PURE__*/ _$template(``), _tmpl$7 = /*#__PURE__*/ _$template(`
\`$\``), _tmpl$8 = /*#__PURE__*/ _$template(`