ripple 0.1.1 → 0.2.0
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/LICENSE +21 -0
- package/package.json +56 -24
- package/src/ai.js +292 -0
- package/src/compiler/errors.js +26 -0
- package/src/compiler/index.js +26 -0
- package/src/compiler/phases/1-parse/index.js +543 -0
- package/src/compiler/phases/1-parse/style.js +566 -0
- package/src/compiler/phases/2-analyze/index.js +509 -0
- package/src/compiler/phases/2-analyze/prune.js +572 -0
- package/src/compiler/phases/3-transform/index.js +1572 -0
- package/src/compiler/phases/3-transform/segments.js +91 -0
- package/src/compiler/phases/3-transform/stylesheet.js +372 -0
- package/src/compiler/scope.js +421 -0
- package/src/compiler/utils.js +552 -0
- package/src/constants.js +4 -0
- package/src/jsx-runtime.d.ts +94 -0
- package/src/jsx-runtime.js +46 -0
- package/src/runtime/array.js +215 -0
- package/src/runtime/index.js +39 -0
- package/src/runtime/internal/client/blocks.js +247 -0
- package/src/runtime/internal/client/constants.js +23 -0
- package/src/runtime/internal/client/events.js +223 -0
- package/src/runtime/internal/client/for.js +388 -0
- package/src/runtime/internal/client/if.js +35 -0
- package/src/runtime/internal/client/index.js +53 -0
- package/src/runtime/internal/client/operations.js +72 -0
- package/src/runtime/internal/client/portal.js +33 -0
- package/src/runtime/internal/client/render.js +156 -0
- package/src/runtime/internal/client/runtime.js +909 -0
- package/src/runtime/internal/client/template.js +51 -0
- package/src/runtime/internal/client/try.js +139 -0
- package/src/runtime/internal/client/utils.js +16 -0
- package/src/utils/ast.js +214 -0
- package/src/utils/builders.js +733 -0
- package/src/utils/patterns.js +23 -0
- package/src/utils/sanitize_template_string.js +7 -0
- package/test-mappings.js +0 -0
- package/types/index.d.ts +2 -0
- package/.npmignore +0 -2
- package/History.md +0 -3
- package/Readme.md +0 -151
- package/lib/exec/index.js +0 -60
- package/ripple.js +0 -645
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { TRACKED_OBJECT } from './constants.js';
|
|
2
|
+
import { get_descriptor } from './utils.js';
|
|
3
|
+
|
|
4
|
+
/** @type {() => Node | null} */
|
|
5
|
+
var first_child_getter;
|
|
6
|
+
/** @type {() => Node | null} */
|
|
7
|
+
var next_sibling_getter;
|
|
8
|
+
|
|
9
|
+
export var is_firefox;
|
|
10
|
+
|
|
11
|
+
export function init_operations() {
|
|
12
|
+
var node_prototype = Node.prototype;
|
|
13
|
+
var element_prototype = Element.prototype;
|
|
14
|
+
var object_prototype = Object.prototype;
|
|
15
|
+
var event_target_prototype = EventTarget.prototype;
|
|
16
|
+
|
|
17
|
+
is_firefox = /Firefox/.test(navigator.userAgent);
|
|
18
|
+
|
|
19
|
+
// @ts-ignore
|
|
20
|
+
first_child_getter = get_descriptor(node_prototype, 'firstChild').get;
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
next_sibling_getter = get_descriptor(node_prototype, 'nextSibling').get;
|
|
23
|
+
|
|
24
|
+
// the following assignments improve perf of lookups on DOM nodes
|
|
25
|
+
// @ts-expect-error
|
|
26
|
+
element_prototype.__click = undefined;
|
|
27
|
+
// @ts-expect-error
|
|
28
|
+
element_prototype.__className = '';
|
|
29
|
+
// @ts-expect-error
|
|
30
|
+
element_prototype.__attributes = null;
|
|
31
|
+
// @ts-expect-error
|
|
32
|
+
element_prototype.__styles = null;
|
|
33
|
+
// @ts-expect-error
|
|
34
|
+
element_prototype.__e = undefined;
|
|
35
|
+
// @ts-expect-error
|
|
36
|
+
object_prototype[TRACKED_OBJECT] = undefined;
|
|
37
|
+
// @ts-expect-error
|
|
38
|
+
event_target_prototype.__root = undefined;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @template {Node} N
|
|
43
|
+
* @param {N} node
|
|
44
|
+
* @returns {Node | null}
|
|
45
|
+
*/
|
|
46
|
+
/*@__NO_SIDE_EFFECTS__*/
|
|
47
|
+
export function first_child(node) {
|
|
48
|
+
return first_child_getter.call(node);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function child_frag(node) {
|
|
52
|
+
var child = first_child(node);
|
|
53
|
+
|
|
54
|
+
if (child.nodeType === 8 && child.data === '') {
|
|
55
|
+
return next_sibling(child);
|
|
56
|
+
}
|
|
57
|
+
return child;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @template {Node} N
|
|
62
|
+
* @param {N} node
|
|
63
|
+
* @returns {Node | null}
|
|
64
|
+
*/
|
|
65
|
+
/*@__NO_SIDE_EFFECTS__*/
|
|
66
|
+
export function next_sibling(node) {
|
|
67
|
+
return next_sibling_getter.call(node);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function create_text(value = '') {
|
|
71
|
+
return document.createTextNode(value);
|
|
72
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { branch, destroy_block, render } from './blocks';
|
|
2
|
+
import { UNINITIALIZED } from './constants';
|
|
3
|
+
import { handle_root_events } from './events';
|
|
4
|
+
import { create_text } from './operations';
|
|
5
|
+
import { get_property } from './runtime';
|
|
6
|
+
|
|
7
|
+
export function Portal(_, props) {
|
|
8
|
+
let $target = UNINITIALIZED;
|
|
9
|
+
let children = UNINITIALIZED;
|
|
10
|
+
var b = null;
|
|
11
|
+
var anchor = null;
|
|
12
|
+
|
|
13
|
+
render(() => {
|
|
14
|
+
if ($target === ($target = get_property(props, '$target'))) return;
|
|
15
|
+
if (children === (children = get_property(props, 'children'))) return;
|
|
16
|
+
|
|
17
|
+
if (b !== null) {
|
|
18
|
+
destroy_block(b);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
anchor = create_text();
|
|
22
|
+
$target.append(anchor);
|
|
23
|
+
|
|
24
|
+
const cleanup_events = handle_root_events($target);
|
|
25
|
+
|
|
26
|
+
b = branch(() => children(anchor));
|
|
27
|
+
|
|
28
|
+
return () => {
|
|
29
|
+
cleanup_events();
|
|
30
|
+
anchor.remove();
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { effect } from './blocks';
|
|
2
|
+
import { get_descriptors, get_prototype_of } from './utils';
|
|
3
|
+
|
|
4
|
+
export function set_text(text, value) {
|
|
5
|
+
// For objects, we apply string coercion (which might make things like $state array references in the template reactive) before diffing
|
|
6
|
+
var str = value == null ? '' : typeof value === 'object' ? value + '' : value;
|
|
7
|
+
// @ts-expect-error
|
|
8
|
+
if (str !== (text.__t ??= text.nodeValue)) {
|
|
9
|
+
// @ts-expect-error
|
|
10
|
+
text.__t = str;
|
|
11
|
+
text.nodeValue = str + '';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
var setters_cache = new Map();
|
|
16
|
+
|
|
17
|
+
function get_setters(element) {
|
|
18
|
+
var setters = setters_cache.get(element.nodeName);
|
|
19
|
+
if (setters) return setters;
|
|
20
|
+
setters_cache.set(element.nodeName, (setters = []));
|
|
21
|
+
|
|
22
|
+
var descriptors;
|
|
23
|
+
var proto = element; // In the case of custom elements there might be setters on the instance
|
|
24
|
+
var element_proto = Element.prototype;
|
|
25
|
+
|
|
26
|
+
// Stop at Element, from there on there's only unnecessary setters we're not interested in
|
|
27
|
+
// Do not use contructor.name here as that's unreliable in some browser environments
|
|
28
|
+
while (element_proto !== proto) {
|
|
29
|
+
descriptors = get_descriptors(proto);
|
|
30
|
+
|
|
31
|
+
for (var key in descriptors) {
|
|
32
|
+
if (descriptors[key].set) {
|
|
33
|
+
setters.push(key);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
proto = get_prototype_of(proto);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return setters;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function set_attribute(element, attribute, value) {
|
|
44
|
+
// @ts-expect-error
|
|
45
|
+
var attributes = (element.__attributes ??= {});
|
|
46
|
+
|
|
47
|
+
if (attributes[attribute] === (attributes[attribute] = value)) return;
|
|
48
|
+
|
|
49
|
+
if (attribute === 'style' && '__styles' in element) {
|
|
50
|
+
// reset styles to force style: directive to update
|
|
51
|
+
element.__styles = {};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (value == null) {
|
|
55
|
+
element.removeAttribute(attribute);
|
|
56
|
+
} else if (typeof value !== 'string' && get_setters(element).includes(attribute)) {
|
|
57
|
+
element[attribute] = value;
|
|
58
|
+
} else {
|
|
59
|
+
element.setAttribute(attribute, value);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @template V
|
|
65
|
+
* @param {V} value
|
|
66
|
+
* @param {string} [hash]
|
|
67
|
+
* @returns {string | V}
|
|
68
|
+
*/
|
|
69
|
+
function to_class(value, hash) {
|
|
70
|
+
return (value == null ? '' : value) + (hash ? ' ' + hash : '');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @param {HTMLElement} dom
|
|
75
|
+
* @param {string} value
|
|
76
|
+
* @param {string} [hash]
|
|
77
|
+
* @returns {void}
|
|
78
|
+
*/
|
|
79
|
+
export function set_class(dom, value, hash) {
|
|
80
|
+
// @ts-expect-error need to add __className to patched prototype
|
|
81
|
+
var prev_class_name = dom.__className;
|
|
82
|
+
var next_class_name = to_class(value, hash);
|
|
83
|
+
|
|
84
|
+
if (prev_class_name !== next_class_name) {
|
|
85
|
+
// Removing the attribute when the value is only an empty string causes
|
|
86
|
+
// peformance issues vs simply making the className an empty string. So
|
|
87
|
+
// we should only remove the class if the the value is nullish.
|
|
88
|
+
if (value == null && !hash) {
|
|
89
|
+
dom.removeAttribute('class');
|
|
90
|
+
} else {
|
|
91
|
+
dom.className = next_class_name;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// @ts-expect-error need to add __className to patched prototype
|
|
95
|
+
dom.__className = next_class_name;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function set_value(element, value) {
|
|
100
|
+
// @ts-expect-error
|
|
101
|
+
var attributes = (element.__attributes ??= {});
|
|
102
|
+
|
|
103
|
+
if (
|
|
104
|
+
attributes.value ===
|
|
105
|
+
(attributes.value =
|
|
106
|
+
// treat null and undefined the same for the initial value
|
|
107
|
+
value ?? undefined) ||
|
|
108
|
+
// @ts-expect-error
|
|
109
|
+
// `progress` elements always need their value set when it's `0`
|
|
110
|
+
(element.value === value && (value !== 0 || element.nodeName !== 'PROGRESS'))
|
|
111
|
+
) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// @ts-expect-error
|
|
116
|
+
element.value = value ?? '';
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function set_checked(element, checked) {
|
|
120
|
+
// @ts-expect-error
|
|
121
|
+
var attributes = (element.__attributes ??= {});
|
|
122
|
+
|
|
123
|
+
if (
|
|
124
|
+
attributes.checked ===
|
|
125
|
+
(attributes.checked =
|
|
126
|
+
// treat null and undefined the same for the initial value
|
|
127
|
+
checked ?? undefined)
|
|
128
|
+
) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// @ts-expect-error
|
|
133
|
+
element.checked = checked;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function set_selected(element, selected) {
|
|
137
|
+
if (selected) {
|
|
138
|
+
// The selected option could've changed via user selection, and
|
|
139
|
+
// setting the value without this check would set it back.
|
|
140
|
+
if (!element.hasAttribute('selected')) {
|
|
141
|
+
element.setAttribute('selected', '');
|
|
142
|
+
}
|
|
143
|
+
} else {
|
|
144
|
+
element.removeAttribute('selected');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function set_ref(dom, fn) {
|
|
149
|
+
effect(() => {
|
|
150
|
+
fn(dom);
|
|
151
|
+
|
|
152
|
+
return () => {
|
|
153
|
+
fn(null);
|
|
154
|
+
};
|
|
155
|
+
});
|
|
156
|
+
}
|