Skip to content

Commit 1144e30

Browse files
updated: Add support for ref expressions
1 parent f731ddb commit 1144e30

File tree

7 files changed

+117
-51
lines changed

7 files changed

+117
-51
lines changed

package-lock.json

Lines changed: 46 additions & 44 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"@babel/core": "^7.26.9",
5454
"@babel/preset-env": "^7.26.9",
5555
"@playwright/test": "^1.50.1",
56-
"@riotjs/dom-bindings": "^9.2.5",
56+
"@riotjs/dom-bindings": "^9.2.6",
5757
"@riotjs/prettier-config": "^1.1.0",
5858
"@rollup/plugin-alias": "^5.1.1",
5959
"@rollup/plugin-commonjs": "^28.0.2",
@@ -68,16 +68,16 @@
6868
"eslint-config-riot": "^4.1.2",
6969
"eslint-plugin-fp": "^2.3.0",
7070
"mocha": "^11.1.0",
71-
"prettier": "^3.5.1",
71+
"prettier": "^3.5.2",
7272
"pug": "^3.0.3",
7373
"rollup": "^4.34.8",
7474
"rollup-plugin-node-builtins": "^2.1.2",
7575
"rollup-plugin-visualizer": "^5.14.0",
76-
"sass": "^1.85.0",
76+
"sass": "^1.85.1",
7777
"serve": "^14.2.4",
7878
"shelljs": "^0.8.5",
7979
"start-server-and-test": "^2.0.10",
80-
"typescript": "^5.7.3"
80+
"typescript": "^5.8.2"
8181
},
8282
"author": "Gianluca Guarini <[email protected]> (https://gianlucaguarini.com)",
8383
"license": "MIT",
@@ -88,14 +88,14 @@
8888
"dependencies": {
8989
"@babel/parser": "^7.26.9",
9090
"@riotjs/parser": "^9.0.1",
91-
"@riotjs/util": "2.4.0",
91+
"@riotjs/util": "2.5.0",
9292
"css-simple-parser": "^3.0.2",
9393
"cssesc": "^3.0.0",
9494
"cumpa": "^2.0.1",
9595
"curri": "^2.0.3",
9696
"dom-nodes": "^1.1.3",
9797
"globals": "^16.0.0",
98-
"recast": "^0.23.9",
98+
"recast": "^0.23.10",
9999
"source-map": "^0.7.4"
100100
}
101101
}

src/generators/template/checks.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ import {
33
IS_SPREAD_ATTRIBUTE,
44
IS_VOID_NODE,
55
PROGRESS_TAG_NODE_NAME,
6+
REF_ATTRIBUTE,
67
SLOT_ATTRIBUTE,
78
SLOT_TAG_NODE_NAME,
89
TEMPLATE_TAG_NODE_NAME,
10+
VALUE_ATTRIBUTE,
911
} from './constants.js'
1012
import {
1113
findAttribute,
@@ -179,7 +181,16 @@ export function isSpreadAttribute(node) {
179181
* @returns {boolean} true only for value attribute nodes
180182
*/
181183
export function isValueAttribute(node) {
182-
return node.name === 'value'
184+
return node.name === VALUE_ATTRIBUTE
185+
}
186+
187+
/**
188+
* True if the node is an attribute and its name is "ref"
189+
* @param {RiotParser.Node} node - riot parser node
190+
* @returns {boolean} true only for ref attribute nodes
191+
*/
192+
export function isRefAttribute(node) {
193+
return node.name === REF_ATTRIBUTE
183194
}
184195

185196
/**

src/generators/template/constants.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const SLOT_BINDING_TYPE = 'SLOT'
99
export const EXPRESSION_TYPES = 'expressionTypes'
1010
export const ATTRIBUTE_EXPRESSION_TYPE = 'ATTRIBUTE'
1111
export const VALUE_EXPRESSION_TYPE = 'VALUE'
12+
export const REF_EXPRESSION_TYPE = 'REF'
1213
export const TEXT_EXPRESSION_TYPE = 'TEXT'
1314
export const EVENT_EXPRESSION_TYPE = 'EVENT'
1415

@@ -43,6 +44,8 @@ export const IF_DIRECTIVE = 'if'
4344
export const EACH_DIRECTIVE = 'each'
4445
export const KEY_ATTRIBUTE = 'key'
4546
export const SLOT_ATTRIBUTE = 'slot'
47+
export const VALUE_ATTRIBUTE = 'value'
48+
export const REF_ATTRIBUTE = 'ref'
4649
export const NAME_ATTRIBUTE = 'name'
4750
export const IS_DIRECTIVE = 'is'
4851

src/generators/template/expressions/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
isEventAttribute,
33
isProgressNode,
4+
isRefAttribute,
45
isTextNode,
56
isValueAttribute,
67
} from '../checks.js'
@@ -10,6 +11,7 @@ import { findDynamicAttributes } from '../find.js'
1011
import { hasValueAttribute } from 'dom-nodes'
1112
import textExpression from './text.js'
1213
import valueExpression from './value.js'
14+
import refExpression from './ref.js'
1315

1416
export function createExpression(
1517
sourceNode,
@@ -27,6 +29,8 @@ export function createExpression(
2729
hasValueAttribute(parentNode.name) &&
2830
!isProgressNode(parentNode):
2931
return valueExpression(sourceNode, sourceFile, sourceCode)
32+
case isRefAttribute(sourceNode):
33+
return refExpression(sourceNode, sourceFile, sourceCode)
3034
case isEventAttribute(sourceNode):
3135
return eventExpression(sourceNode, sourceFile, sourceCode)
3236
default:
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import {
2+
BINDING_EVALUATE_KEY,
3+
BINDING_TYPE_KEY,
4+
EXPRESSION_TYPES,
5+
REF_EXPRESSION_TYPE,
6+
} from '../constants.js'
7+
import { builders } from '../../../utils/build-types.js'
8+
import { createAttributeEvaluationFunction } from '../utils.js'
9+
import { simplePropertyNode } from '../../../utils/custom-ast-nodes.js'
10+
11+
export default function createRefExpression(
12+
sourceNode,
13+
sourceFile,
14+
sourceCode,
15+
) {
16+
return builders.objectExpression([
17+
simplePropertyNode(
18+
BINDING_TYPE_KEY,
19+
builders.memberExpression(
20+
builders.identifier(EXPRESSION_TYPES),
21+
builders.identifier(REF_EXPRESSION_TYPE),
22+
false,
23+
),
24+
),
25+
simplePropertyNode(
26+
BINDING_EVALUATE_KEY,
27+
createAttributeEvaluationFunction(sourceNode, sourceFile, sourceCode),
28+
),
29+
])
30+
}

test/generators/template.spec.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,22 @@ describe('Generators - Template', () => {
672672
)
673673
})
674674

675+
it('Simple ref expression', () => {
676+
const source = '<div ref={ref}/>'
677+
const { template } = parse(source)
678+
const input = simpleBinding(template, 'expr0', FAKE_SRC_FILE, source)
679+
const output = evaluateOutput(input)
680+
const expression = output.expressions[0]
681+
682+
expect(output[BINDING_SELECTOR_KEY]).to.be.equal('[expr0]')
683+
684+
expect(expression[BINDING_EVALUATE_KEY]).to.be.a('function')
685+
expect(expression[BINDING_TYPE_KEY]).to.be.equal(expressionTypes.REF)
686+
expect(expression[BINDING_EVALUATE_KEY]({ ref: 'ref' })).to.be.equal(
687+
'ref',
688+
)
689+
})
690+
675691
it('Simple event expression', () => {
676692
const source = '<input oninput={foo}/>'
677693
const { template } = parse(source)

0 commit comments

Comments
 (0)