ripple 0.2.82 → 0.2.84
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/compiler/phases/1-parse/index.js +1151 -1062
- package/src/compiler/phases/2-analyze/index.js +561 -523
- package/src/compiler/phases/3-transform/client/index.js +105 -28
- package/src/compiler/phases/3-transform/server/index.js +1 -1
- package/src/compiler/utils.js +613 -595
- package/src/runtime/array.js +4 -0
- package/src/runtime/index-client.js +8 -2
- package/src/runtime/internal/client/constants.js +9 -8
- package/src/runtime/internal/client/head.js +14 -0
- package/src/runtime/internal/client/index.js +43 -34
- package/src/runtime/internal/client/operations.js +34 -30
- package/src/runtime/internal/client/runtime.js +30 -29
- package/src/utils/builders.js +1 -0
- package/tests/client/basic.test.ripple +130 -22
- package/types/index.d.ts +6 -11
package/src/compiler/utils.js
CHANGED
|
@@ -5,22 +5,22 @@ import { get_attribute_event_name, is_delegated, is_event_attribute } from '../u
|
|
|
5
5
|
const regex_return_characters = /\r/g;
|
|
6
6
|
|
|
7
7
|
const VOID_ELEMENT_NAMES = [
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
8
|
+
'area',
|
|
9
|
+
'base',
|
|
10
|
+
'br',
|
|
11
|
+
'col',
|
|
12
|
+
'command',
|
|
13
|
+
'embed',
|
|
14
|
+
'hr',
|
|
15
|
+
'img',
|
|
16
|
+
'input',
|
|
17
|
+
'keygen',
|
|
18
|
+
'link',
|
|
19
|
+
'meta',
|
|
20
|
+
'param',
|
|
21
|
+
'source',
|
|
22
|
+
'track',
|
|
23
|
+
'wbr',
|
|
24
24
|
];
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -28,684 +28,702 @@ const VOID_ELEMENT_NAMES = [
|
|
|
28
28
|
* @param {string} name
|
|
29
29
|
*/
|
|
30
30
|
export function is_void_element(name) {
|
|
31
|
-
|
|
31
|
+
return VOID_ELEMENT_NAMES.includes(name) || name.toLowerCase() === '!doctype';
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
const RESERVED_WORDS = [
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
35
|
+
'arguments',
|
|
36
|
+
'await',
|
|
37
|
+
'break',
|
|
38
|
+
'case',
|
|
39
|
+
'catch',
|
|
40
|
+
'class',
|
|
41
|
+
'const',
|
|
42
|
+
'continue',
|
|
43
|
+
'debugger',
|
|
44
|
+
'default',
|
|
45
|
+
'delete',
|
|
46
|
+
'do',
|
|
47
|
+
'else',
|
|
48
|
+
'enum',
|
|
49
|
+
'eval',
|
|
50
|
+
'export',
|
|
51
|
+
'extends',
|
|
52
|
+
'false',
|
|
53
|
+
'finally',
|
|
54
|
+
'for',
|
|
55
|
+
'function',
|
|
56
|
+
'if',
|
|
57
|
+
'implements',
|
|
58
|
+
'import',
|
|
59
|
+
'in',
|
|
60
|
+
'instanceof',
|
|
61
|
+
'interface',
|
|
62
|
+
'let',
|
|
63
|
+
'new',
|
|
64
|
+
'null',
|
|
65
|
+
'package',
|
|
66
|
+
'private',
|
|
67
|
+
'protected',
|
|
68
|
+
'public',
|
|
69
|
+
'return',
|
|
70
|
+
'static',
|
|
71
|
+
'super',
|
|
72
|
+
'switch',
|
|
73
|
+
'this',
|
|
74
|
+
'throw',
|
|
75
|
+
'true',
|
|
76
|
+
'try',
|
|
77
|
+
'typeof',
|
|
78
|
+
'var',
|
|
79
|
+
'void',
|
|
80
|
+
'while',
|
|
81
|
+
'with',
|
|
82
|
+
'yield',
|
|
83
83
|
];
|
|
84
84
|
|
|
85
85
|
export function is_reserved(word) {
|
|
86
|
-
|
|
86
|
+
return RESERVED_WORDS.includes(word);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
/**
|
|
90
90
|
* Attributes that are boolean, i.e. they are present or not present.
|
|
91
91
|
*/
|
|
92
92
|
const DOM_BOOLEAN_ATTRIBUTES = [
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
93
|
+
'allowfullscreen',
|
|
94
|
+
'async',
|
|
95
|
+
'autofocus',
|
|
96
|
+
'autoplay',
|
|
97
|
+
'checked',
|
|
98
|
+
'controls',
|
|
99
|
+
'default',
|
|
100
|
+
'disabled',
|
|
101
|
+
'formnovalidate',
|
|
102
|
+
'hidden',
|
|
103
|
+
'indeterminate',
|
|
104
|
+
'inert',
|
|
105
|
+
'ismap',
|
|
106
|
+
'loop',
|
|
107
|
+
'multiple',
|
|
108
|
+
'muted',
|
|
109
|
+
'nomodule',
|
|
110
|
+
'novalidate',
|
|
111
|
+
'open',
|
|
112
|
+
'playsinline',
|
|
113
|
+
'readonly',
|
|
114
|
+
'required',
|
|
115
|
+
'reversed',
|
|
116
|
+
'seamless',
|
|
117
|
+
'selected',
|
|
118
|
+
'webkitdirectory',
|
|
119
|
+
'defer',
|
|
120
|
+
'disablepictureinpicture',
|
|
121
|
+
'disableremoteplayback',
|
|
122
122
|
];
|
|
123
123
|
|
|
124
124
|
export function is_boolean_attribute(name) {
|
|
125
|
-
|
|
125
|
+
return DOM_BOOLEAN_ATTRIBUTES.includes(name);
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
const DOM_PROPERTIES = [
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
129
|
+
...DOM_BOOLEAN_ATTRIBUTES,
|
|
130
|
+
'formNoValidate',
|
|
131
|
+
'isMap',
|
|
132
|
+
'noModule',
|
|
133
|
+
'playsInline',
|
|
134
|
+
'readOnly',
|
|
135
|
+
'value',
|
|
136
|
+
'volume',
|
|
137
|
+
'defaultValue',
|
|
138
|
+
'defaultChecked',
|
|
139
|
+
'srcObject',
|
|
140
|
+
'noValidate',
|
|
141
|
+
'allowFullscreen',
|
|
142
|
+
'disablePictureInPicture',
|
|
143
|
+
'disableRemotePlayback',
|
|
144
144
|
];
|
|
145
145
|
|
|
146
146
|
export function is_dom_property(name) {
|
|
147
|
-
|
|
147
|
+
return DOM_PROPERTIES.includes(name);
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
const unhoisted = { hoisted: false };
|
|
151
151
|
|
|
152
152
|
export function get_delegated_event(event_name, handler, state) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
153
|
+
// Handle delegated event handlers. Bail out if not a delegated event.
|
|
154
|
+
if (!handler || !is_delegated(event_name)) {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** @type {FunctionExpression | FunctionDeclaration | ArrowFunctionExpression | null} */
|
|
159
|
+
let target_function = null;
|
|
160
|
+
let binding = null;
|
|
161
|
+
|
|
162
|
+
if (handler.type === 'ArrowFunctionExpression' || handler.type === 'FunctionExpression') {
|
|
163
|
+
target_function = handler;
|
|
164
|
+
} else if (handler.type === 'Identifier') {
|
|
165
|
+
binding = state.scope.get(handler.name);
|
|
166
|
+
|
|
167
|
+
if (state.analysis.module.scope.references.has(handler.name)) {
|
|
168
|
+
// If a binding with the same name is referenced in the module scope (even if not declared there), bail out
|
|
169
|
+
return unhoisted;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (binding != null) {
|
|
173
|
+
for (const { path } of binding.references) {
|
|
174
|
+
const parent = path.at(-1);
|
|
175
|
+
if (parent === undefined) return unhoisted;
|
|
176
|
+
|
|
177
|
+
const grandparent = path.at(-2);
|
|
178
|
+
|
|
179
|
+
/** @type {AST.RegularElement | null} */
|
|
180
|
+
let element = null;
|
|
181
|
+
/** @type {string | null} */
|
|
182
|
+
let event_name = null;
|
|
183
|
+
if (
|
|
184
|
+
parent.type === 'ExpressionTag' &&
|
|
185
|
+
grandparent?.type === 'Attribute' &&
|
|
186
|
+
is_event_attribute(grandparent)
|
|
187
|
+
) {
|
|
188
|
+
element = /** @type {AST.RegularElement} */ (path.at(-3));
|
|
189
|
+
const attribute = /** @type {AST.Attribute} */ (grandparent);
|
|
190
|
+
event_name = get_attribute_event_name(attribute.name);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (element && event_name) {
|
|
194
|
+
if (
|
|
195
|
+
element.type !== 'Element' ||
|
|
196
|
+
element.metadata.has_spread ||
|
|
197
|
+
!is_delegated(event_name)
|
|
198
|
+
) {
|
|
199
|
+
return unhoisted;
|
|
200
|
+
}
|
|
201
|
+
} else if (parent.type !== 'FunctionDeclaration' && parent.type !== 'VariableDeclarator') {
|
|
202
|
+
return unhoisted;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// If the binding is exported, bail out
|
|
208
|
+
if (state.analysis.exports.find((node) => node.name === handler.name)) {
|
|
209
|
+
return unhoisted;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (binding !== null && binding.initial !== null && !binding.updated && !binding.is_called) {
|
|
213
|
+
const binding_type = binding.initial.type;
|
|
214
|
+
|
|
215
|
+
if (
|
|
216
|
+
binding_type === 'ArrowFunctionExpression' ||
|
|
217
|
+
binding_type === 'FunctionDeclaration' ||
|
|
218
|
+
binding_type === 'FunctionExpression'
|
|
219
|
+
) {
|
|
220
|
+
target_function = binding.initial;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// If we can't find a function, or the function has multiple parameters, bail out
|
|
226
|
+
if (target_function == null || target_function.params.length > 1) {
|
|
227
|
+
return unhoisted;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const visited_references = new Set();
|
|
231
|
+
const scope = target_function.metadata.scope;
|
|
232
|
+
for (const [reference] of scope.references) {
|
|
233
|
+
// Bail out if the arguments keyword is used or $host is referenced
|
|
234
|
+
if (reference === 'arguments') return unhoisted;
|
|
235
|
+
|
|
236
|
+
const binding = scope.get(reference);
|
|
237
|
+
const local_binding = state.scope.get(reference);
|
|
238
|
+
|
|
239
|
+
// If we are referencing a binding that is shadowed in another scope then bail out.
|
|
240
|
+
if (local_binding !== null && binding !== null && local_binding.node !== binding.node) {
|
|
241
|
+
return unhoisted;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (
|
|
245
|
+
binding !== null &&
|
|
246
|
+
// Bail out if the the binding is a rest param
|
|
247
|
+
(binding.declaration_kind === 'rest_param' || // or any normal not reactive bindings that are mutated.
|
|
248
|
+
// Bail out if we reference anything from the EachBlock (for now) that mutates in non-runes mode,
|
|
249
|
+
(binding.kind === 'normal' && binding.updated))
|
|
250
|
+
) {
|
|
251
|
+
return unhoisted;
|
|
252
|
+
}
|
|
253
|
+
visited_references.add(reference);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return { hoisted: true, function: target_function };
|
|
257
257
|
}
|
|
258
258
|
|
|
259
259
|
function get_hoisted_params(node, context) {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
260
|
+
const scope = context.state.scope;
|
|
261
|
+
|
|
262
|
+
/** @type {Identifier[]} */
|
|
263
|
+
const params = [];
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* We only want to push if it's not already present to avoid name clashing
|
|
267
|
+
* @param {Identifier} id
|
|
268
|
+
*/
|
|
269
|
+
function push_unique(id) {
|
|
270
|
+
if (!params.find((param) => param.name === id.name)) {
|
|
271
|
+
params.push(id);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
for (const [reference] of scope.references) {
|
|
276
|
+
let binding = scope.get(reference);
|
|
277
|
+
|
|
278
|
+
if (binding !== null && !scope.declarations.has(reference) && binding.initial !== node) {
|
|
279
|
+
if (binding.kind === 'prop') {
|
|
280
|
+
push_unique(b.id('__props'));
|
|
281
|
+
} else if (binding.kind === 'prop_fallback') {
|
|
282
|
+
push_unique(b.id(binding.node.name));
|
|
283
|
+
} else if (
|
|
284
|
+
// imports don't need to be hoisted
|
|
285
|
+
binding.declaration_kind !== 'import'
|
|
286
|
+
) {
|
|
287
|
+
// create a copy to remove start/end tags which would mess up source maps
|
|
288
|
+
push_unique(b.id(binding.node.name));
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return params;
|
|
293
293
|
}
|
|
294
294
|
|
|
295
295
|
export function build_hoisted_params(node, context) {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
296
|
+
const hoisted_params = get_hoisted_params(node, context);
|
|
297
|
+
node.metadata.hoisted_params = hoisted_params;
|
|
298
|
+
|
|
299
|
+
/** @type {Pattern[]} */
|
|
300
|
+
const params = [];
|
|
301
|
+
|
|
302
|
+
if (node.params.length === 0) {
|
|
303
|
+
if (hoisted_params.length > 0) {
|
|
304
|
+
// For the event object
|
|
305
|
+
params.push(b.id(context.state.scope.generate('_')));
|
|
306
|
+
}
|
|
307
|
+
} else {
|
|
308
|
+
for (const param of node.params) {
|
|
309
|
+
params.push(/** @type {Pattern} */ (context.visit(param)));
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
params.push(...hoisted_params, b.id('__block'));
|
|
314
|
+
return params;
|
|
315
315
|
}
|
|
316
316
|
|
|
317
317
|
export function is_top_level_await(context) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
318
|
+
if (!is_inside_component(context)) {
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
for (let i = context.path.length - 1; i >= 0; i -= 1) {
|
|
323
|
+
const context_node = context.path[i];
|
|
324
|
+
const type = context_node.type;
|
|
325
|
+
|
|
326
|
+
if (type === 'Component') {
|
|
327
|
+
return true;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (
|
|
331
|
+
type === 'FunctionExpression' ||
|
|
332
|
+
type === 'ArrowFunctionExpression' ||
|
|
333
|
+
type === 'FunctionDeclaration'
|
|
334
|
+
) {
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return true;
|
|
339
339
|
}
|
|
340
340
|
|
|
341
341
|
export function is_inside_component(context, includes_functions = false) {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
342
|
+
for (let i = context.path.length - 1; i >= 0; i -= 1) {
|
|
343
|
+
const context_node = context.path[i];
|
|
344
|
+
const type = context_node.type;
|
|
345
|
+
|
|
346
|
+
if (
|
|
347
|
+
!includes_functions &&
|
|
348
|
+
(type === 'FunctionExpression' ||
|
|
349
|
+
type === 'ArrowFunctionExpression' ||
|
|
350
|
+
type === 'FunctionDeclaration')
|
|
351
|
+
) {
|
|
352
|
+
return false;
|
|
353
|
+
}
|
|
354
|
+
if (type === 'Component') {
|
|
355
|
+
return true;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
return false;
|
|
359
359
|
}
|
|
360
360
|
|
|
361
361
|
export function is_component_level_function(context) {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
362
|
+
for (let i = context.path.length - 1; i >= 0; i -= 1) {
|
|
363
|
+
const context_node = context.path[i];
|
|
364
|
+
const type = context_node.type;
|
|
365
|
+
|
|
366
|
+
if (type === 'BlockStatement' && context_node.body.find((n) => n.type === 'Component')) {
|
|
367
|
+
return true;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (
|
|
371
|
+
type === 'FunctionExpression' ||
|
|
372
|
+
type === 'ArrowFunctionExpression' ||
|
|
373
|
+
type === 'FunctionDeclaration'
|
|
374
|
+
) {
|
|
375
|
+
return false;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return true;
|
|
379
379
|
}
|
|
380
380
|
|
|
381
381
|
export function is_ripple_track_call(callee, context) {
|
|
382
|
+
<<<<<<< Updated upstream
|
|
382
383
|
return (
|
|
383
|
-
(callee.type === 'Identifier' && callee.name === 'track') ||
|
|
384
|
+
(callee.type === 'Identifier' && (callee.name === 'track' || callee.name === 'trackSplit')) ||
|
|
384
385
|
(callee.type === 'MemberExpression' &&
|
|
385
386
|
callee.object.type === 'Identifier' &&
|
|
386
387
|
callee.property.type === 'Identifier' &&
|
|
387
|
-
callee.property.name === 'track' &&
|
|
388
|
+
(callee.property.name === 'track' || callee.property.name === 'trackSplit') &&
|
|
388
389
|
!callee.computed &&
|
|
389
390
|
is_ripple_import(callee, context))
|
|
390
391
|
);
|
|
392
|
+
=======
|
|
393
|
+
return (
|
|
394
|
+
(callee.type === 'Identifier' && callee.name === 'track') ||
|
|
395
|
+
(callee.type === 'MemberExpression' &&
|
|
396
|
+
callee.object.type === 'Identifier' &&
|
|
397
|
+
callee.property.type === 'Identifier' &&
|
|
398
|
+
callee.property.name === 'track' &&
|
|
399
|
+
!callee.computed &&
|
|
400
|
+
is_ripple_import(callee, context))
|
|
401
|
+
);
|
|
402
|
+
>>>>>>> Stashed changes
|
|
391
403
|
}
|
|
392
404
|
|
|
393
405
|
export function is_inside_call_expression(context) {
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
406
|
+
for (let i = context.path.length - 1; i >= 0; i -= 1) {
|
|
407
|
+
const context_node = context.path[i];
|
|
408
|
+
const type = context_node.type;
|
|
409
|
+
|
|
410
|
+
if (
|
|
411
|
+
type === 'FunctionExpression' ||
|
|
412
|
+
type === 'ArrowFunctionExpression' ||
|
|
413
|
+
type === 'FunctionDeclaration'
|
|
414
|
+
) {
|
|
415
|
+
return false;
|
|
416
|
+
}
|
|
417
|
+
if (type === 'CallExpression') {
|
|
418
|
+
const callee = context_node.callee;
|
|
419
|
+
if (is_ripple_track_call(callee, context)) {
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
422
|
+
return true;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return false;
|
|
414
426
|
}
|
|
415
427
|
|
|
416
428
|
export function is_value_static(node) {
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
429
|
+
if (node.type === 'Literal') {
|
|
430
|
+
return true;
|
|
431
|
+
}
|
|
432
|
+
if (node.type === 'ArrayExpression') {
|
|
433
|
+
return true;
|
|
434
|
+
}
|
|
435
|
+
if (node.type === 'NewExpression') {
|
|
436
|
+
if (node.callee.type === 'Identifier' && node.callee.name === 'Array') {
|
|
437
|
+
return true;
|
|
438
|
+
}
|
|
439
|
+
return false;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
return false;
|
|
431
443
|
}
|
|
432
444
|
|
|
433
445
|
export function is_ripple_import(callee, context) {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
446
|
+
if (callee.type === 'Identifier') {
|
|
447
|
+
const binding = context.state.scope.get(callee.name);
|
|
448
|
+
|
|
449
|
+
return (
|
|
450
|
+
binding?.declaration_kind === 'import' &&
|
|
451
|
+
binding.initial.source.type === 'Literal' &&
|
|
452
|
+
binding.initial.source.value === 'ripple'
|
|
453
|
+
);
|
|
454
|
+
} else if (
|
|
455
|
+
callee.type === 'MemberExpression' &&
|
|
456
|
+
callee.object.type === 'Identifier' &&
|
|
457
|
+
!callee.computed
|
|
458
|
+
) {
|
|
459
|
+
const binding = context.state.scope.get(callee.object.name);
|
|
460
|
+
|
|
461
|
+
return (
|
|
462
|
+
binding?.declaration_kind === 'import' &&
|
|
463
|
+
binding.initial.source.type === 'Literal' &&
|
|
464
|
+
binding.initial.source.value === 'ripple'
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
return false;
|
|
457
469
|
}
|
|
458
470
|
|
|
459
471
|
export function is_declared_function_within_component(node, context) {
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
472
|
+
const component = context.path.find((n) => n.type === 'Component');
|
|
473
|
+
|
|
474
|
+
if (node.type === 'Identifier' && component) {
|
|
475
|
+
const binding = context.state.scope.get(node.name);
|
|
476
|
+
const component_scope = context.state.scopes.get(component);
|
|
477
|
+
|
|
478
|
+
if (binding !== null && component_scope !== null) {
|
|
479
|
+
if (
|
|
480
|
+
binding.declaration_kind !== 'function' &&
|
|
481
|
+
binding.initial?.type !== 'FunctionDeclaration' &&
|
|
482
|
+
binding.initial?.type !== 'ArrowFunctionExpression' &&
|
|
483
|
+
binding.initial?.type !== 'FunctionExpression'
|
|
484
|
+
) {
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
let scope = binding.scope;
|
|
488
|
+
|
|
489
|
+
while (scope !== null) {
|
|
490
|
+
if (scope === component_scope) {
|
|
491
|
+
return true;
|
|
492
|
+
}
|
|
493
|
+
scope = scope.parent;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
return false;
|
|
487
499
|
}
|
|
488
500
|
|
|
489
501
|
function is_non_coercive_operator(operator) {
|
|
490
|
-
|
|
502
|
+
return ['=', '||=', '&&=', '??='].includes(operator);
|
|
491
503
|
}
|
|
492
504
|
|
|
493
505
|
export function visit_assignment_expression(node, context, build_assignment) {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
506
|
+
if (
|
|
507
|
+
node.left.type === 'ArrayPattern' ||
|
|
508
|
+
node.left.type === 'ObjectPattern' ||
|
|
509
|
+
node.left.type === 'RestElement'
|
|
510
|
+
) {
|
|
511
|
+
const value = /** @type {Expression} */ (context.visit(node.right));
|
|
512
|
+
const should_cache = value.type !== 'Identifier';
|
|
513
|
+
const rhs = should_cache ? b.id('$$value') : value;
|
|
514
|
+
|
|
515
|
+
let changed = false;
|
|
516
|
+
|
|
517
|
+
const assignments = extract_paths(node.left).map((path) => {
|
|
518
|
+
const value = path.expression?.(rhs);
|
|
519
|
+
|
|
520
|
+
let assignment = build_assignment('=', path.node, value, context);
|
|
521
|
+
if (assignment !== null) changed = true;
|
|
522
|
+
|
|
523
|
+
return (
|
|
524
|
+
assignment ??
|
|
525
|
+
b.assignment(
|
|
526
|
+
'=',
|
|
527
|
+
/** @type {Pattern} */ (context.visit(path.node)),
|
|
528
|
+
/** @type {Expression} */ (context.visit(value)),
|
|
529
|
+
)
|
|
530
|
+
);
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
if (!changed) {
|
|
534
|
+
// No change to output -> nothing to transform -> we can keep the original assignment
|
|
535
|
+
return null;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
const is_standalone = /** @type {Node} */ (context.path.at(-1)).type.endsWith('Statement');
|
|
539
|
+
const sequence = b.sequence(assignments);
|
|
540
|
+
|
|
541
|
+
if (!is_standalone) {
|
|
542
|
+
// this is part of an expression, we need the sequence to end with the value
|
|
543
|
+
sequence.expressions.push(rhs);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
if (should_cache) {
|
|
547
|
+
// the right hand side is a complex expression, wrap in an IIFE to cache it
|
|
548
|
+
const iife = b.arrow([rhs], sequence);
|
|
549
|
+
|
|
550
|
+
const iife_is_async =
|
|
551
|
+
is_expression_async(value) ||
|
|
552
|
+
assignments.some((assignment) => is_expression_async(assignment));
|
|
553
|
+
|
|
554
|
+
return iife_is_async ? b.await(b.call(b.async(iife), value)) : b.call(iife, value);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
return sequence;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
if (node.left.type !== 'Identifier' && node.left.type !== 'MemberExpression') {
|
|
561
|
+
throw new Error(`Unexpected assignment type ${node.left.type}`);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
const transformed = build_assignment(node.operator, node.left, node.right, context);
|
|
565
|
+
|
|
566
|
+
if (transformed === node.left) {
|
|
567
|
+
return node;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
return transformed;
|
|
559
571
|
}
|
|
560
572
|
|
|
561
573
|
export function build_assignment(operator, left, right, context) {
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
574
|
+
let object = left;
|
|
575
|
+
|
|
576
|
+
while (object.type === 'MemberExpression') {
|
|
577
|
+
// @ts-expect-error
|
|
578
|
+
object = object.object;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
if (object.type !== 'Identifier') {
|
|
582
|
+
return null;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
const binding = context.state.scope.get(object.name);
|
|
586
|
+
if (!binding) return null;
|
|
587
|
+
|
|
588
|
+
const transform = binding.transform;
|
|
589
|
+
|
|
590
|
+
// reassignment
|
|
591
|
+
if (object === left || (left.type === 'MemberExpression' && left.computed && operator === '=')) {
|
|
592
|
+
const assign_fn = transform?.assign || transform?.assign_tracked;
|
|
593
|
+
if (assign_fn) {
|
|
594
|
+
let value = /** @type {Expression} */ (
|
|
595
|
+
context.visit(build_assignment_value(operator, left, right))
|
|
596
|
+
);
|
|
597
|
+
|
|
598
|
+
return assign_fn(
|
|
599
|
+
object,
|
|
600
|
+
value,
|
|
601
|
+
left.type === 'MemberExpression' && left.computed
|
|
602
|
+
? context.visit(left.property)
|
|
603
|
+
: undefined,
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// mutation
|
|
609
|
+
if (transform?.mutate) {
|
|
610
|
+
return transform.mutate(
|
|
611
|
+
object,
|
|
612
|
+
b.assignment(
|
|
613
|
+
operator,
|
|
614
|
+
/** @type {Pattern} */ (context.visit(left)),
|
|
615
|
+
/** @type {Expression} */ (context.visit(right)),
|
|
616
|
+
),
|
|
617
|
+
);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
return null;
|
|
609
621
|
}
|
|
610
622
|
|
|
611
623
|
const ATTR_REGEX = /[&"<]/g;
|
|
612
624
|
const CONTENT_REGEX = /[&<]/g;
|
|
613
625
|
|
|
614
626
|
export function escape_html(value, is_attr = false) {
|
|
615
|
-
|
|
627
|
+
const str = String(value ?? '');
|
|
616
628
|
|
|
617
|
-
|
|
618
|
-
|
|
629
|
+
const pattern = is_attr ? ATTR_REGEX : CONTENT_REGEX;
|
|
630
|
+
pattern.lastIndex = 0;
|
|
619
631
|
|
|
620
|
-
|
|
621
|
-
|
|
632
|
+
let escaped = '';
|
|
633
|
+
let last = 0;
|
|
622
634
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
635
|
+
while (pattern.test(str)) {
|
|
636
|
+
const i = pattern.lastIndex - 1;
|
|
637
|
+
const ch = str[i];
|
|
638
|
+
escaped += str.substring(last, i) + (ch === '&' ? '&' : ch === '"' ? '"' : '<');
|
|
639
|
+
last = i + 1;
|
|
640
|
+
}
|
|
629
641
|
|
|
630
|
-
|
|
642
|
+
return escaped + str.substring(last);
|
|
631
643
|
}
|
|
632
644
|
|
|
633
645
|
export function hash(str) {
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
646
|
+
str = str.replace(regex_return_characters, '');
|
|
647
|
+
let hash = 5381;
|
|
648
|
+
let i = str.length;
|
|
637
649
|
|
|
638
|
-
|
|
639
|
-
|
|
650
|
+
while (i--) hash = ((hash << 5) - hash) ^ str.charCodeAt(i);
|
|
651
|
+
return (hash >>> 0).toString(36);
|
|
640
652
|
}
|
|
641
653
|
|
|
642
654
|
export function is_element_dom_element(node) {
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
655
|
+
return (
|
|
656
|
+
node.id.type === 'Identifier' &&
|
|
657
|
+
node.id.name[0].toLowerCase() === node.id.name[0] &&
|
|
658
|
+
node.id.name !== 'children' &&
|
|
659
|
+
!node.id.tracked
|
|
660
|
+
);
|
|
649
661
|
}
|
|
650
662
|
|
|
651
|
-
export function normalize_children(children) {
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
663
|
+
export function normalize_children(children, context) {
|
|
664
|
+
const normalized = [];
|
|
665
|
+
|
|
666
|
+
for (const node of children) {
|
|
667
|
+
normalize_child(node, normalized, context);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
for (let i = normalized.length - 1; i >= 0; i--) {
|
|
671
|
+
const child = normalized[i];
|
|
672
|
+
const prev_child = normalized[i - 1];
|
|
673
|
+
|
|
674
|
+
if (child.type === 'Text' && prev_child?.type === 'Text') {
|
|
675
|
+
if (child.expression.type === 'Literal' && prev_child.expression.type === 'Literal') {
|
|
676
|
+
prev_child.expression = b.literal(
|
|
677
|
+
prev_child.expression.value + String(child.expression.value),
|
|
678
|
+
);
|
|
679
|
+
} else {
|
|
680
|
+
prev_child.expression = b.binary(
|
|
681
|
+
'+',
|
|
682
|
+
prev_child.expression,
|
|
683
|
+
b.call('String', child.expression),
|
|
684
|
+
);
|
|
685
|
+
}
|
|
686
|
+
normalized.splice(i, 1);
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
return normalized;
|
|
679
691
|
}
|
|
680
692
|
|
|
681
|
-
function normalize_child(node, normalized) {
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
693
|
+
function normalize_child(node, normalized, context) {
|
|
694
|
+
if (node.type === 'EmptyStatement') {
|
|
695
|
+
return;
|
|
696
|
+
} else if (
|
|
697
|
+
node.type === 'Element' &&
|
|
698
|
+
node.id.type === 'Identifier' &&
|
|
699
|
+
((node.id.name === 'style' && !context.state.inside_head) ||
|
|
700
|
+
node.id.name === 'head' ||
|
|
701
|
+
(node.id.name === 'title' && context.state.inside_head))
|
|
702
|
+
) {
|
|
703
|
+
return;
|
|
704
|
+
} else {
|
|
705
|
+
normalized.push(node);
|
|
706
|
+
}
|
|
689
707
|
}
|
|
690
708
|
|
|
691
709
|
export function build_getter(node, context) {
|
|
692
|
-
|
|
710
|
+
const state = context.state;
|
|
693
711
|
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
712
|
+
for (let i = context.path.length - 1; i >= 0; i -= 1) {
|
|
713
|
+
const binding = state.scope.get(node.name);
|
|
714
|
+
const transform = binding?.transform;
|
|
697
715
|
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
716
|
+
// don't transform the declaration itself
|
|
717
|
+
if (node !== binding?.node) {
|
|
718
|
+
const read_fn = transform?.read;
|
|
701
719
|
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
720
|
+
if (read_fn) {
|
|
721
|
+
return read_fn(node, context.state?.metadata?.spread, context.visit);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
707
725
|
|
|
708
|
-
|
|
726
|
+
return node;
|
|
709
727
|
}
|
|
710
728
|
|
|
711
729
|
export function determine_namespace_for_children(element_name, current_namespace) {
|
|
@@ -722,4 +740,4 @@ export function determine_namespace_for_children(element_name, current_namespace
|
|
|
722
740
|
}
|
|
723
741
|
|
|
724
742
|
return current_namespace;
|
|
725
|
-
}
|
|
743
|
+
}
|