ripple 0.2.6 → 0.2.8
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/README.md +1 -1
- package/package.json +1 -1
- package/src/compiler/errors.js +20 -22
- package/src/compiler/phases/1-parse/index.js +21 -19
- package/src/compiler/phases/1-parse/style.js +27 -27
- package/src/compiler/phases/2-analyze/index.js +25 -25
- package/src/compiler/phases/2-analyze/prune.js +64 -27
- package/src/compiler/phases/3-transform/index.js +150 -113
- package/src/compiler/phases/3-transform/segments.js +25 -20
- package/src/compiler/phases/3-transform/stylesheet.js +28 -28
- package/src/compiler/scope.js +3 -3
- package/src/compiler/utils.js +7 -9
- package/src/constants.js +1 -2
- package/src/jsx-runtime.d.ts +59 -59
- package/src/jsx-runtime.js +13 -13
- package/src/runtime/array.js +15 -15
- package/src/runtime/index.js +2 -0
- package/src/runtime/internal/client/blocks.js +16 -5
- package/src/runtime/internal/client/constants.js +1 -1
- package/src/runtime/internal/client/events.js +2 -2
- package/src/runtime/internal/client/for.js +6 -7
- package/src/runtime/internal/client/operations.js +1 -1
- package/src/runtime/internal/client/runtime.js +41 -20
- package/src/runtime/internal/client/template.js +1 -1
- package/src/runtime/internal/client/try.js +2 -2
- package/src/utils/ast.js +9 -9
- package/src/utils/builders.js +66 -28
- package/tests/__snapshots__/for.test.ripple.snap +81 -0
- package/tests/basic.test.ripple +292 -263
- package/tests/composite.test.ripple +151 -0
- package/tests/for.test.ripple +58 -0
- package/tests/ref.test.ripple +52 -0
- package/tests/use.test.ripple +24 -22
- package/types/index.d.ts +7 -1
|
@@ -4,7 +4,7 @@ export const mapping_data = {
|
|
|
4
4
|
verification: true,
|
|
5
5
|
completion: true,
|
|
6
6
|
semantic: true,
|
|
7
|
-
navigation: true
|
|
7
|
+
navigation: true,
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -16,27 +16,27 @@ export const mapping_data = {
|
|
|
16
16
|
*/
|
|
17
17
|
export function convert_source_map_to_mappings(source_map, source, generated_code) {
|
|
18
18
|
const mappings = [];
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
// Decode the VLQ mappings from esrap
|
|
21
21
|
const decoded_mappings = decode(source_map.mappings);
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
let generated_offset = 0;
|
|
24
24
|
const generated_lines = generated_code.split('\n');
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
// Process each line of generated code
|
|
27
27
|
for (let generated_line = 0; generated_line < generated_lines.length; generated_line++) {
|
|
28
28
|
const line = generated_lines[generated_line];
|
|
29
29
|
const line_mappings = decoded_mappings[generated_line] || [];
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
// Process mappings for this line
|
|
32
32
|
for (const mapping of line_mappings) {
|
|
33
33
|
const [generated_column, source_file_index, source_line, source_column] = mapping;
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
// Skip mappings without source information
|
|
36
36
|
if (source_file_index == null || source_line == null || source_column == null) {
|
|
37
37
|
continue;
|
|
38
38
|
}
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
// Calculate source offset
|
|
41
41
|
const source_lines = source.split('\n');
|
|
42
42
|
let source_offset = 0;
|
|
@@ -44,24 +44,29 @@ export function convert_source_map_to_mappings(source_map, source, generated_cod
|
|
|
44
44
|
source_offset += source_lines[i].length + 1; // +1 for newline
|
|
45
45
|
}
|
|
46
46
|
source_offset += source_column;
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
// Calculate generated offset
|
|
49
49
|
const current_generated_offset = generated_offset + generated_column;
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
// Determine segment length (look ahead to next mapping or end of line)
|
|
52
52
|
const next_mapping = line_mappings[line_mappings.indexOf(mapping) + 1];
|
|
53
|
-
let segment_length = next_mapping
|
|
54
|
-
|
|
53
|
+
let segment_length = next_mapping
|
|
54
|
+
? next_mapping[0] - generated_column
|
|
55
|
+
: Math.max(1, line.length - generated_column);
|
|
56
|
+
|
|
55
57
|
// Determine the actual segment content
|
|
56
|
-
const generated_content = generated_code.substring(
|
|
58
|
+
const generated_content = generated_code.substring(
|
|
59
|
+
current_generated_offset,
|
|
60
|
+
current_generated_offset + segment_length,
|
|
61
|
+
);
|
|
57
62
|
const source_content = source.substring(source_offset, source_offset + segment_length);
|
|
58
|
-
|
|
63
|
+
|
|
59
64
|
// Skip mappings for UseAttribute syntax to avoid overlapping sourcemaps
|
|
60
65
|
if (source_content.includes('{@use ') || source_content.match(/\{\s*@use\s+/)) {
|
|
61
66
|
continue;
|
|
62
67
|
}
|
|
63
|
-
|
|
64
|
-
// Fix for $children mapping: when generated content is "$children",
|
|
68
|
+
|
|
69
|
+
// Fix for $children mapping: when generated content is "$children",
|
|
65
70
|
// it should only map to the component name in the source, not include attributes
|
|
66
71
|
if (generated_content === '$children') {
|
|
67
72
|
// Look for the component name in the source content
|
|
@@ -71,24 +76,24 @@ export function convert_source_map_to_mappings(source_map, source, generated_cod
|
|
|
71
76
|
segment_length = component_name.length;
|
|
72
77
|
}
|
|
73
78
|
}
|
|
74
|
-
|
|
79
|
+
|
|
75
80
|
mappings.push({
|
|
76
81
|
sourceOffsets: [source_offset],
|
|
77
82
|
generatedOffsets: [current_generated_offset],
|
|
78
83
|
lengths: [segment_length],
|
|
79
|
-
data: mapping_data
|
|
84
|
+
data: mapping_data,
|
|
80
85
|
});
|
|
81
86
|
}
|
|
82
|
-
|
|
87
|
+
|
|
83
88
|
// Add line length + 1 for newline (except for last line)
|
|
84
89
|
generated_offset += line.length;
|
|
85
90
|
if (generated_line < generated_lines.length - 1) {
|
|
86
91
|
generated_offset += 1; // newline character
|
|
87
92
|
}
|
|
88
93
|
}
|
|
89
|
-
|
|
94
|
+
|
|
90
95
|
return {
|
|
91
96
|
code: generated_code,
|
|
92
|
-
mappings
|
|
97
|
+
mappings,
|
|
93
98
|
};
|
|
94
99
|
}
|
|
@@ -113,7 +113,7 @@ const visitors = {
|
|
|
113
113
|
|
|
114
114
|
next();
|
|
115
115
|
},
|
|
116
|
-
|
|
116
|
+
Declaration(node, { state }) {
|
|
117
117
|
const property = node.property && remove_css_prefix(node.property.toLowerCase());
|
|
118
118
|
if (property === 'animation' || property === 'animation-name') {
|
|
119
119
|
let index = node.start + node.property.length + 1;
|
|
@@ -140,19 +140,19 @@ const visitors = {
|
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
},
|
|
143
|
-
|
|
143
|
+
Rule(node, { state, next, visit, path }) {
|
|
144
144
|
if (is_empty(node, is_in_global_block(path))) {
|
|
145
145
|
state.code.prependRight(node.start, '/* (empty) ');
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
state.code.appendLeft(node.end, '*/');
|
|
147
|
+
escape_comment_close(node, state.code);
|
|
148
148
|
|
|
149
149
|
return;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
if (!is_used(node) && !is_in_global_block(path)) {
|
|
153
153
|
state.code.prependRight(node.start, '/* (unused) ');
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
state.code.appendLeft(node.end, '*/');
|
|
155
|
+
escape_comment_close(node, state.code);
|
|
156
156
|
|
|
157
157
|
return;
|
|
158
158
|
}
|
|
@@ -181,7 +181,7 @@ const visitors = {
|
|
|
181
181
|
|
|
182
182
|
next();
|
|
183
183
|
},
|
|
184
|
-
|
|
184
|
+
SelectorList(node, { state, next, path }) {
|
|
185
185
|
// Only add comments if we're not inside a complex selector that itself is unused or a global block
|
|
186
186
|
if (
|
|
187
187
|
!is_in_global_block(path) &&
|
|
@@ -264,7 +264,7 @@ const visitors = {
|
|
|
264
264
|
|
|
265
265
|
next({ ...state, specificity });
|
|
266
266
|
},
|
|
267
|
-
|
|
267
|
+
ComplexSelector(node, context) {
|
|
268
268
|
const before_bumped = context.state.specificity.bumped;
|
|
269
269
|
|
|
270
270
|
for (const relative_selector of node.children) {
|
|
@@ -347,26 +347,26 @@ const visitors = {
|
|
|
347
347
|
if (node.name === 'is' || node.name === 'where' || node.name === 'has' || node.name === 'not') {
|
|
348
348
|
context.next();
|
|
349
349
|
}
|
|
350
|
-
}
|
|
350
|
+
},
|
|
351
351
|
};
|
|
352
352
|
|
|
353
353
|
export function render_stylesheets(stylesheets) {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
}
|
|
354
|
+
let css = '';
|
|
355
|
+
|
|
356
|
+
for (const stylesheet of stylesheets) {
|
|
357
|
+
const code = new MagicString(stylesheet.source);
|
|
358
|
+
const state = {
|
|
359
|
+
code,
|
|
360
|
+
hash: stylesheet.hash,
|
|
361
|
+
selector: `.${stylesheet.hash}`,
|
|
362
|
+
specificity: {
|
|
363
|
+
bumped: false,
|
|
364
|
+
},
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
walk(stylesheet, state, visitors);
|
|
368
|
+
css += code.toString();
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return css;
|
|
372
|
+
}
|
package/src/compiler/scope.js
CHANGED
|
@@ -167,7 +167,7 @@ export function create_scopes(ast, root, parent) {
|
|
|
167
167
|
} else {
|
|
168
168
|
next();
|
|
169
169
|
}
|
|
170
|
-
}
|
|
170
|
+
},
|
|
171
171
|
});
|
|
172
172
|
|
|
173
173
|
for (const [scope, { node, path }] of references) {
|
|
@@ -193,7 +193,7 @@ export function create_scopes(ast, root, parent) {
|
|
|
193
193
|
|
|
194
194
|
return {
|
|
195
195
|
scope,
|
|
196
|
-
scopes
|
|
196
|
+
scopes,
|
|
197
197
|
};
|
|
198
198
|
}
|
|
199
199
|
|
|
@@ -293,7 +293,7 @@ export class Scope {
|
|
|
293
293
|
kind,
|
|
294
294
|
declaration_kind,
|
|
295
295
|
is_called: false,
|
|
296
|
-
metadata: null
|
|
296
|
+
metadata: null,
|
|
297
297
|
};
|
|
298
298
|
|
|
299
299
|
this.declarations.set(node.name, binding);
|
package/src/compiler/utils.js
CHANGED
|
@@ -51,7 +51,7 @@ const RESERVED_WORDS = [
|
|
|
51
51
|
'void',
|
|
52
52
|
'while',
|
|
53
53
|
'with',
|
|
54
|
-
'yield'
|
|
54
|
+
'yield',
|
|
55
55
|
];
|
|
56
56
|
|
|
57
57
|
export function is_reserved(word) {
|
|
@@ -90,7 +90,7 @@ const DOM_BOOLEAN_ATTRIBUTES = [
|
|
|
90
90
|
'webkitdirectory',
|
|
91
91
|
'defer',
|
|
92
92
|
'disablepictureinpicture',
|
|
93
|
-
'disableremoteplayback'
|
|
93
|
+
'disableremoteplayback',
|
|
94
94
|
];
|
|
95
95
|
|
|
96
96
|
export function is_boolean_attribute(name) {
|
|
@@ -112,7 +112,7 @@ const DOM_PROPERTIES = [
|
|
|
112
112
|
'noValidate',
|
|
113
113
|
'allowFullscreen',
|
|
114
114
|
'disablePictureInPicture',
|
|
115
|
-
'disableRemotePlayback'
|
|
115
|
+
'disableRemotePlayback',
|
|
116
116
|
];
|
|
117
117
|
|
|
118
118
|
export function is_dom_property(name) {
|
|
@@ -143,7 +143,7 @@ const DELEGATED_EVENTS = [
|
|
|
143
143
|
'pointerup',
|
|
144
144
|
'touchend',
|
|
145
145
|
'touchmove',
|
|
146
|
-
'touchstart'
|
|
146
|
+
'touchstart',
|
|
147
147
|
];
|
|
148
148
|
|
|
149
149
|
export function is_delegated(event_name) {
|
|
@@ -436,7 +436,7 @@ export function visit_assignment_expression(node, context, build_assignment) {
|
|
|
436
436
|
b.assignment(
|
|
437
437
|
'=',
|
|
438
438
|
/** @type {Pattern} */ (context.visit(path.node)),
|
|
439
|
-
/** @type {Expression} */ (context.visit(value))
|
|
439
|
+
/** @type {Expression} */ (context.visit(value)),
|
|
440
440
|
)
|
|
441
441
|
);
|
|
442
442
|
});
|
|
@@ -510,8 +510,8 @@ export function build_assignment(operator, left, right, context) {
|
|
|
510
510
|
b.assignment(
|
|
511
511
|
operator,
|
|
512
512
|
/** @type {Pattern} */ (context.visit(left)),
|
|
513
|
-
/** @type {Expression} */ (context.visit(right))
|
|
514
|
-
)
|
|
513
|
+
/** @type {Expression} */ (context.visit(right)),
|
|
514
|
+
),
|
|
515
515
|
);
|
|
516
516
|
}
|
|
517
517
|
|
|
@@ -548,5 +548,3 @@ export function hash(str) {
|
|
|
548
548
|
while (i--) hash = ((hash << 5) - hash) ^ str.charCodeAt(i);
|
|
549
549
|
return (hash >>> 0).toString(36);
|
|
550
550
|
}
|
|
551
|
-
|
|
552
|
-
|
package/src/constants.js
CHANGED
package/src/jsx-runtime.d.ts
CHANGED
|
@@ -11,9 +11,9 @@ export type ComponentType<P = {}> = (props: P) => void;
|
|
|
11
11
|
* In Ripple, this doesn't return anything - components are imperative
|
|
12
12
|
*/
|
|
13
13
|
export function jsx(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
type: string | ComponentType<any>,
|
|
15
|
+
props?: any,
|
|
16
|
+
key?: string | number | null,
|
|
17
17
|
): void;
|
|
18
18
|
|
|
19
19
|
/**
|
|
@@ -21,9 +21,9 @@ export function jsx(
|
|
|
21
21
|
* In Ripple, this doesn't return anything - components are imperative
|
|
22
22
|
*/
|
|
23
23
|
export function jsxs(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
type: string | ComponentType<any>,
|
|
25
|
+
props?: any,
|
|
26
|
+
key?: string | number | null,
|
|
27
27
|
): void;
|
|
28
28
|
|
|
29
29
|
/**
|
|
@@ -34,61 +34,61 @@ export function Fragment(props: { $children?: any }): void;
|
|
|
34
34
|
|
|
35
35
|
// Base HTML attributes
|
|
36
36
|
interface HTMLAttributes {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
37
|
+
class?: string;
|
|
38
|
+
className?: string;
|
|
39
|
+
id?: string;
|
|
40
|
+
style?: string | Record<string, string | number>;
|
|
41
|
+
onClick?: (event: MouseEvent) => void;
|
|
42
|
+
onInput?: (event: InputEvent) => void;
|
|
43
|
+
onChange?: (event: Event) => void;
|
|
44
|
+
$children?: any;
|
|
45
|
+
[key: string]: any;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
// Global JSX namespace for TypeScript
|
|
49
49
|
declare global {
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
50
|
+
namespace JSX {
|
|
51
|
+
// In Ripple, JSX expressions don't return elements - they're imperative
|
|
52
|
+
type Element = void;
|
|
53
|
+
|
|
54
|
+
interface IntrinsicElements {
|
|
55
|
+
// HTML elements with basic attributes
|
|
56
|
+
div: HTMLAttributes;
|
|
57
|
+
span: HTMLAttributes;
|
|
58
|
+
p: HTMLAttributes;
|
|
59
|
+
h1: HTMLAttributes;
|
|
60
|
+
h2: HTMLAttributes;
|
|
61
|
+
h3: HTMLAttributes;
|
|
62
|
+
h4: HTMLAttributes;
|
|
63
|
+
h5: HTMLAttributes;
|
|
64
|
+
h6: HTMLAttributes;
|
|
65
|
+
button: HTMLAttributes & {
|
|
66
|
+
type?: 'button' | 'submit' | 'reset';
|
|
67
|
+
disabled?: boolean;
|
|
68
|
+
};
|
|
69
|
+
input: HTMLAttributes & {
|
|
70
|
+
type?: string;
|
|
71
|
+
value?: string | number;
|
|
72
|
+
placeholder?: string;
|
|
73
|
+
disabled?: boolean;
|
|
74
|
+
};
|
|
75
|
+
form: HTMLAttributes;
|
|
76
|
+
a: HTMLAttributes & {
|
|
77
|
+
href?: string;
|
|
78
|
+
target?: string;
|
|
79
|
+
};
|
|
80
|
+
img: HTMLAttributes & {
|
|
81
|
+
src?: string;
|
|
82
|
+
alt?: string;
|
|
83
|
+
width?: string | number;
|
|
84
|
+
height?: string | number;
|
|
85
|
+
};
|
|
86
|
+
// Add more as needed...
|
|
87
|
+
[elemName: string]: HTMLAttributes;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
interface ElementChildrenAttribute {
|
|
91
|
+
$children: {};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
94
|
}
|
package/src/jsx-runtime.js
CHANGED
|
@@ -13,26 +13,26 @@
|
|
|
13
13
|
* @returns {void} Ripple components don't return anything
|
|
14
14
|
*/
|
|
15
15
|
export function jsx(type, props, key) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
// Ripple components are imperative - they don't return JSX elements
|
|
17
|
+
// This is a placeholder for the actual Ripple rendering logic
|
|
18
|
+
if (typeof type === 'function') {
|
|
19
|
+
// Call the Ripple component function
|
|
20
|
+
type(props);
|
|
21
|
+
} else {
|
|
22
|
+
// Handle DOM elements
|
|
23
|
+
console.warn('DOM element rendering not implemented in jsx runtime:', type, props);
|
|
24
|
+
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Create a JSX element with static children (optimization for multiple children)
|
|
29
|
-
* @param {string | Function} type - Element type (tag name or component function)
|
|
29
|
+
* @param {string | Function} type - Element type (tag name or component function)
|
|
30
30
|
* @param {object} props - Element properties
|
|
31
31
|
* @param {string} key - Element key (optional)
|
|
32
32
|
* @returns {void} Ripple components don't return anything
|
|
33
33
|
*/
|
|
34
34
|
export function jsxs(type, props, key) {
|
|
35
|
-
|
|
35
|
+
return jsx(type, props, key);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/**
|
|
@@ -41,6 +41,6 @@ export function jsxs(type, props, key) {
|
|
|
41
41
|
* @returns {void} Ripple fragments don't return anything
|
|
42
42
|
*/
|
|
43
43
|
export function Fragment(props) {
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
// Ripple fragments are imperative
|
|
45
|
+
console.warn('Fragment rendering not implemented in jsx runtime:', props);
|
|
46
46
|
}
|
package/src/runtime/array.js
CHANGED
|
@@ -30,7 +30,7 @@ const introspect_methods = [
|
|
|
30
30
|
'toString',
|
|
31
31
|
symbol_iterator,
|
|
32
32
|
'values',
|
|
33
|
-
'with'
|
|
33
|
+
'with',
|
|
34
34
|
];
|
|
35
35
|
|
|
36
36
|
let init = false;
|
|
@@ -172,25 +172,25 @@ class RippleArray extends Array {
|
|
|
172
172
|
return get(this.#tracked_index);
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
175
|
+
set $length(length) {
|
|
176
|
+
var block = scope();
|
|
177
|
+
var tracked_elements = this.#tracked_elements;
|
|
178
178
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
179
|
+
if (length !== this.$length) {
|
|
180
|
+
for (var i = 0; i < tracked_elements.length; i++) {
|
|
181
|
+
increment(tracked_elements[i], block);
|
|
182
|
+
}
|
|
183
|
+
this.length = length;
|
|
184
|
+
tracked_elements.length = length;
|
|
185
185
|
|
|
186
|
-
|
|
187
|
-
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
188
|
return false;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
set length(_) {
|
|
192
|
+
throw new Error('Cannot set length on RippleArray, use $length instead');
|
|
193
|
+
}
|
|
194
194
|
|
|
195
195
|
toJSON() {
|
|
196
196
|
this.$length;
|
package/src/runtime/index.js
CHANGED
|
@@ -19,13 +19,14 @@ import {
|
|
|
19
19
|
run_block,
|
|
20
20
|
run_teardown,
|
|
21
21
|
schedule_update,
|
|
22
|
+
set_property,
|
|
22
23
|
} from './runtime';
|
|
23
24
|
import { suspend } from './try';
|
|
24
25
|
|
|
25
26
|
export function user_effect(fn) {
|
|
26
27
|
if (active_block === null) {
|
|
27
28
|
throw new Error(
|
|
28
|
-
'effect() must be called within an active context, such as a component or effect'
|
|
29
|
+
'effect() must be called within an active context, such as a component or effect',
|
|
29
30
|
);
|
|
30
31
|
}
|
|
31
32
|
|
|
@@ -69,19 +70,29 @@ export function async(fn) {
|
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
export function use(element, get_fn) {
|
|
72
|
-
var
|
|
73
|
+
var use_obj = undefined;
|
|
73
74
|
var e;
|
|
75
|
+
var current_block = active_block;
|
|
74
76
|
|
|
75
77
|
return block(RENDER_BLOCK, () => {
|
|
76
|
-
if (
|
|
78
|
+
if (use_obj !== (use_obj = get_fn())) {
|
|
77
79
|
if (e) {
|
|
78
80
|
destroy_block(e);
|
|
79
81
|
e = null;
|
|
80
82
|
}
|
|
81
83
|
|
|
82
|
-
if (
|
|
84
|
+
if (use_obj) {
|
|
83
85
|
e = branch(() => {
|
|
84
|
-
effect(() =>
|
|
86
|
+
effect(() => {
|
|
87
|
+
if (typeof use_obj === 'function') {
|
|
88
|
+
return use_obj(element);
|
|
89
|
+
} else {
|
|
90
|
+
set_property(use_obj, '$current', element, current_block);
|
|
91
|
+
return () => {
|
|
92
|
+
set_property(use_obj, '$current', null, current_block);
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
});
|
|
85
96
|
});
|
|
86
97
|
}
|
|
87
98
|
}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
set_active_block,
|
|
6
6
|
set_active_reaction,
|
|
7
7
|
set_tracking,
|
|
8
|
-
tracking
|
|
8
|
+
tracking,
|
|
9
9
|
} from './runtime';
|
|
10
10
|
import { array_from, define_property, is_array } from './utils';
|
|
11
11
|
|
|
@@ -73,7 +73,7 @@ export function handle_event_propagation(event) {
|
|
|
73
73
|
configurable: true,
|
|
74
74
|
get() {
|
|
75
75
|
return current_target || owner_document;
|
|
76
|
-
}
|
|
76
|
+
},
|
|
77
77
|
});
|
|
78
78
|
|
|
79
79
|
var previous_block = active_block;
|
|
@@ -42,12 +42,11 @@ export function for_block(node, get_collection, render_fn, flags) {
|
|
|
42
42
|
var array = is_array(collection)
|
|
43
43
|
? collection
|
|
44
44
|
: collection == null
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
? []
|
|
46
|
+
: array_from(collection);
|
|
47
47
|
|
|
48
48
|
if (array[TRACKED_OBJECT] !== undefined) {
|
|
49
|
-
|
|
50
|
-
get_all_elements(collection);
|
|
49
|
+
array = get_all_elements(collection);
|
|
51
50
|
collection.$length;
|
|
52
51
|
}
|
|
53
52
|
|
|
@@ -71,7 +70,7 @@ function reconcile(anchor, block, b, render_fn, is_controlled) {
|
|
|
71
70
|
if (state === null) {
|
|
72
71
|
state = block.s = {
|
|
73
72
|
array: [],
|
|
74
|
-
blocks: []
|
|
73
|
+
blocks: [],
|
|
75
74
|
};
|
|
76
75
|
}
|
|
77
76
|
|
|
@@ -365,8 +364,8 @@ export function keyed(collection, key_fn) {
|
|
|
365
364
|
var b_array = is_array(collection)
|
|
366
365
|
? collection
|
|
367
366
|
: collection == null
|
|
368
|
-
|
|
369
|
-
|
|
367
|
+
? []
|
|
368
|
+
: array_from(collection);
|
|
370
369
|
var b_keys = b_array.map(key_fn);
|
|
371
370
|
|
|
372
371
|
// We only need to do this in DEV
|