ripple 0.2.77 → 0.2.79
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 +6 -6
- package/src/compiler/phases/3-transform/client/index.js +8 -8
- package/src/compiler/phases/3-transform/server/index.js +143 -15
- package/src/runtime/index-server.js +32 -0
- package/src/runtime/internal/server/context.js +67 -0
- package/src/runtime/internal/server/index.js +79 -24
- package/src/server/index.js +1 -1
- /package/src/runtime/{index.js → index-client.js} +0 -0
package/package.json
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
"description": "Ripple is an elegant TypeScript UI framework",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Dominic Gannaway",
|
|
6
|
-
"version": "0.2.
|
|
6
|
+
"version": "0.2.79",
|
|
7
7
|
"type": "module",
|
|
8
|
-
"module": "src/runtime/index.js",
|
|
9
|
-
"main": "src/runtime/index.js",
|
|
8
|
+
"module": "src/runtime/index-client.js",
|
|
9
|
+
"main": "src/runtime/index-client.js",
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
12
|
"url": "git+https://github.com/trueadm/ripple.git",
|
|
@@ -24,9 +24,9 @@
|
|
|
24
24
|
"exports": {
|
|
25
25
|
".": {
|
|
26
26
|
"types": "./types/index.d.ts",
|
|
27
|
-
"worker": "./src/runtime/index.js",
|
|
28
|
-
"browser": "./src/runtime/index.js",
|
|
29
|
-
"default": "./src/runtime/index.js"
|
|
27
|
+
"worker": "./src/runtime/index-server.js",
|
|
28
|
+
"browser": "./src/runtime/index-client.js",
|
|
29
|
+
"default": "./src/runtime/index-server.js"
|
|
30
30
|
},
|
|
31
31
|
"./package.json": "./package.json",
|
|
32
32
|
"./server": {
|
|
@@ -478,18 +478,18 @@ const visitors = {
|
|
|
478
478
|
continue;
|
|
479
479
|
}
|
|
480
480
|
|
|
481
|
-
if (name === 'class'
|
|
481
|
+
if (name === 'class') {
|
|
482
482
|
class_attribute = attr;
|
|
483
483
|
|
|
484
484
|
continue;
|
|
485
485
|
}
|
|
486
486
|
|
|
487
|
-
if (name === 'value'
|
|
487
|
+
if (name === 'value') {
|
|
488
488
|
const id = state.flush_node();
|
|
489
489
|
const metadata = { tracking: false, await: false };
|
|
490
490
|
const expression = visit(attr.value, { ...state, metadata });
|
|
491
491
|
|
|
492
|
-
if (
|
|
492
|
+
if (metadata.tracking) {
|
|
493
493
|
local_updates.push(b.stmt(b.call('_$_.set_value', id, expression)));
|
|
494
494
|
} else {
|
|
495
495
|
state.init.push(b.stmt(b.call('_$_.set_value', id, expression)));
|
|
@@ -498,7 +498,7 @@ const visitors = {
|
|
|
498
498
|
continue;
|
|
499
499
|
}
|
|
500
500
|
|
|
501
|
-
if (name === 'checked'
|
|
501
|
+
if (name === 'checked') {
|
|
502
502
|
const id = state.flush_node();
|
|
503
503
|
const metadata = { tracking: false, await: false };
|
|
504
504
|
const expression = visit(attr.value, { ...state, metadata });
|
|
@@ -511,12 +511,12 @@ const visitors = {
|
|
|
511
511
|
continue;
|
|
512
512
|
}
|
|
513
513
|
|
|
514
|
-
if (name === 'selected'
|
|
514
|
+
if (name === 'selected') {
|
|
515
515
|
const id = state.flush_node();
|
|
516
516
|
const metadata = { tracking: false, await: false };
|
|
517
517
|
const expression = visit(attr.value, { ...state, metadata });
|
|
518
518
|
|
|
519
|
-
if (
|
|
519
|
+
if (metadata.tracking) {
|
|
520
520
|
local_updates.push(b.stmt(b.call('_$_.set_selected', id, expression)));
|
|
521
521
|
} else {
|
|
522
522
|
state.init.push(b.stmt(b.call('_$_.set_selected', id, expression)));
|
|
@@ -635,11 +635,11 @@ const visitors = {
|
|
|
635
635
|
let expression = visit(class_attribute.value, { ...state, metadata });
|
|
636
636
|
|
|
637
637
|
if (node.metadata.scoped && state.component.css) {
|
|
638
|
-
expression = b.binary('+', b.literal(state.component.css.hash
|
|
638
|
+
expression = b.binary('+', expression, b.literal(' ' + state.component.css.hash));
|
|
639
639
|
}
|
|
640
640
|
const is_html = context.state.metadata.namespace === 'html' && node.id.name !== 'svg';
|
|
641
641
|
|
|
642
|
-
if (
|
|
642
|
+
if (metadata.tracking) {
|
|
643
643
|
local_updates.push(
|
|
644
644
|
b.stmt(b.call('_$_.set_class', id, expression, undefined, b.literal(is_html))),
|
|
645
645
|
);
|
|
@@ -5,6 +5,8 @@ import path from 'node:path';
|
|
|
5
5
|
import { print } from 'esrap';
|
|
6
6
|
import {
|
|
7
7
|
build_getter,
|
|
8
|
+
escape_html,
|
|
9
|
+
is_boolean_attribute,
|
|
8
10
|
is_element_dom_element,
|
|
9
11
|
is_inside_component,
|
|
10
12
|
is_void_element,
|
|
@@ -12,6 +14,7 @@ import {
|
|
|
12
14
|
} from '../../../utils.js';
|
|
13
15
|
import is_reference from 'is-reference';
|
|
14
16
|
import { escape } from '../../../../utils/escaping.js';
|
|
17
|
+
import { is_event_attribute } from '../../../../utils/events.js';
|
|
15
18
|
|
|
16
19
|
function add_ripple_internal_import(context) {
|
|
17
20
|
if (!context.state.to_ts) {
|
|
@@ -106,6 +109,8 @@ const visitors = {
|
|
|
106
109
|
const { state, visit } = context;
|
|
107
110
|
|
|
108
111
|
const is_dom_element = is_element_dom_element(node);
|
|
112
|
+
const is_spreading = node.attributes.some((attr) => attr.type === 'SpreadAttribute');
|
|
113
|
+
const spread_attributes = is_spreading ? [] : null;
|
|
109
114
|
|
|
110
115
|
if (is_dom_element) {
|
|
111
116
|
const is_void = is_void_element(node.id.name);
|
|
@@ -115,13 +120,117 @@ const visitors = {
|
|
|
115
120
|
);
|
|
116
121
|
let class_attribute = null;
|
|
117
122
|
|
|
123
|
+
const handle_static_attr = (name, value) => {
|
|
124
|
+
const attr_value = b.literal(
|
|
125
|
+
` ${name}${
|
|
126
|
+
is_boolean_attribute(name) && value === true
|
|
127
|
+
? ''
|
|
128
|
+
: `="${value === true ? '' : escape_html(value, true)}"`
|
|
129
|
+
}`,
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
if (is_spreading) {
|
|
133
|
+
// For spread attributes, store just the actual value, not the full attribute string
|
|
134
|
+
const actual_value =
|
|
135
|
+
is_boolean_attribute(name) && value === true
|
|
136
|
+
? b.literal(true)
|
|
137
|
+
: b.literal(value === true ? '' : value);
|
|
138
|
+
spread_attributes.push(b.prop('init', b.literal(name), actual_value));
|
|
139
|
+
} else {
|
|
140
|
+
state.init.push(
|
|
141
|
+
b.stmt(b.call(b.member(b.id('__output'), b.id('push')), b.literal(String(attr_value)))),
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
118
146
|
for (const attr of node.attributes) {
|
|
147
|
+
if (attr.type === 'Attribute') {
|
|
148
|
+
if (attr.name.type === 'Identifier') {
|
|
149
|
+
const name = attr.name.name;
|
|
150
|
+
|
|
151
|
+
if (attr.value === null) {
|
|
152
|
+
handle_static_attr(name, true);
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (attr.value.type === 'Literal' && name !== 'class') {
|
|
157
|
+
handle_static_attr(name, attr.value.value);
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (name === 'class') {
|
|
162
|
+
class_attribute = attr;
|
|
163
|
+
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (is_event_attribute(name)) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const metadata = { tracking: false, await: false };
|
|
171
|
+
const expression = visit(attr.value, { ...state, metadata });
|
|
172
|
+
|
|
173
|
+
state.init.push(
|
|
174
|
+
b.stmt(
|
|
175
|
+
b.call(
|
|
176
|
+
b.member(b.id('__output'), b.id('push')),
|
|
177
|
+
b.call('_$_.attr', b.literal(name), expression),
|
|
178
|
+
),
|
|
179
|
+
),
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
} else if (attr.type === 'SpreadAttribute') {
|
|
183
|
+
spread_attributes.push(b.spread(visit(attr.argument, state)));
|
|
184
|
+
}
|
|
119
185
|
}
|
|
120
186
|
|
|
121
187
|
if (class_attribute !== null) {
|
|
122
|
-
|
|
188
|
+
if (class_attribute.value.type === 'Literal') {
|
|
189
|
+
let value = class_attribute.value.value;
|
|
190
|
+
|
|
191
|
+
if (node.metadata.scoped && state.component.css) {
|
|
192
|
+
value = `${state.component.css.hash} ${value}`;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
handle_static_attr(class_attribute.name.name, value);
|
|
196
|
+
} else {
|
|
197
|
+
const metadata = { tracking: false, await: false };
|
|
198
|
+
let expression = visit(class_attribute.value, { ...state, metadata });
|
|
199
|
+
|
|
200
|
+
if (node.metadata.scoped && state.component.css) {
|
|
201
|
+
expression = b.binary('+', b.literal(state.component.css.hash + ' '), expression);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
state.init.push(
|
|
205
|
+
b.stmt(
|
|
206
|
+
b.call(
|
|
207
|
+
b.member(b.id('__output'), b.id('push')),
|
|
208
|
+
b.call('_$_.attr', b.literal('class'), expression),
|
|
209
|
+
),
|
|
210
|
+
),
|
|
211
|
+
);
|
|
212
|
+
}
|
|
123
213
|
} else if (node.metadata.scoped && state.component.css) {
|
|
124
|
-
|
|
214
|
+
const value = state.component.css.hash;
|
|
215
|
+
|
|
216
|
+
// TOOO
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (spread_attributes !== null && spread_attributes.length > 0) {
|
|
220
|
+
state.init.push(
|
|
221
|
+
b.stmt(
|
|
222
|
+
b.call(
|
|
223
|
+
b.member(b.id('__output'), b.id('push')),
|
|
224
|
+
b.call(
|
|
225
|
+
'_$_.spread_attrs',
|
|
226
|
+
b.object(spread_attributes),
|
|
227
|
+
node.metadata.scoped && state.component.css
|
|
228
|
+
? b.literal(state.component.css.hash)
|
|
229
|
+
: undefined,
|
|
230
|
+
),
|
|
231
|
+
),
|
|
232
|
+
),
|
|
233
|
+
);
|
|
125
234
|
}
|
|
126
235
|
|
|
127
236
|
state.init.push(b.stmt(b.call(b.member(b.id('__output'), b.id('push')), b.literal(`>`))));
|
|
@@ -134,8 +243,26 @@ const visitors = {
|
|
|
134
243
|
);
|
|
135
244
|
}
|
|
136
245
|
} else {
|
|
137
|
-
|
|
138
|
-
|
|
246
|
+
const props = [];
|
|
247
|
+
|
|
248
|
+
for (const attr of node.attributes) {
|
|
249
|
+
if (attr.type === 'Attribute') {
|
|
250
|
+
if (attr.name.type === 'Identifier') {
|
|
251
|
+
const metadata = { tracking: false, await: false };
|
|
252
|
+
let property = visit(attr.value, { ...state, metadata });
|
|
253
|
+
|
|
254
|
+
props.push(b.prop('init', attr.name, property));
|
|
255
|
+
} else if (attr.type === 'SpreadAttribute') {
|
|
256
|
+
props.push(
|
|
257
|
+
b.spread(
|
|
258
|
+
visit(attr.argument, { ...state, metadata: { ...state.metadata, spread: true } }),
|
|
259
|
+
),
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
state.init.push(b.stmt(b.call(node.id.name, b.id('__output'), b.object(props))));
|
|
139
266
|
}
|
|
140
267
|
},
|
|
141
268
|
|
|
@@ -146,17 +273,18 @@ const visitors = {
|
|
|
146
273
|
}
|
|
147
274
|
const body_scope = context.state.scopes.get(node.body);
|
|
148
275
|
|
|
276
|
+
const body = transform_body(node.body.body, {
|
|
277
|
+
...context,
|
|
278
|
+
state: { ...context.state, scope: body_scope },
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
if (node.index) {
|
|
282
|
+
context.state.init.push(b.var(node.index, b.literal(0)));
|
|
283
|
+
body.push(b.update('++', node.index));
|
|
284
|
+
}
|
|
285
|
+
|
|
149
286
|
context.state.init.push(
|
|
150
|
-
b.for_of(
|
|
151
|
-
context.visit(node.left),
|
|
152
|
-
context.visit(node.right),
|
|
153
|
-
b.block(
|
|
154
|
-
transform_body(node.body.body, {
|
|
155
|
-
...context,
|
|
156
|
-
state: { ...context.state, scope: body_scope },
|
|
157
|
-
}),
|
|
158
|
-
),
|
|
159
|
-
),
|
|
287
|
+
b.for_of(context.visit(node.left), context.visit(node.right), b.block(body)),
|
|
160
288
|
);
|
|
161
289
|
},
|
|
162
290
|
|
|
@@ -184,7 +312,7 @@ const visitors = {
|
|
|
184
312
|
const parent = /** @type {Node} */ (context.path.at(-1));
|
|
185
313
|
|
|
186
314
|
if (is_reference(node, parent) && node.tracked) {
|
|
187
|
-
|
|
315
|
+
add_ripple_internal_import(context);
|
|
188
316
|
return b.call('_$_.get', build_getter(node, context));
|
|
189
317
|
}
|
|
190
318
|
},
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { DERIVED, TRACKED, UNINITIALIZED } from './internal/client/constants';
|
|
2
|
+
import { is_tracked_object } from './internal/client/utils';
|
|
3
|
+
|
|
4
|
+
export { create_context as createContext } from './internal/server/context.js';
|
|
5
|
+
|
|
6
|
+
export function effect() {
|
|
7
|
+
// NO-OP
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const TrackedArray = Array;
|
|
11
|
+
|
|
12
|
+
export function track(v, o) {
|
|
13
|
+
var is_tracked = is_tracked_object(v);
|
|
14
|
+
|
|
15
|
+
if (is_tracked) {
|
|
16
|
+
return v;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (typeof v === 'function') {
|
|
20
|
+
return {
|
|
21
|
+
f: TRACKED | DERIVED,
|
|
22
|
+
fn: v,
|
|
23
|
+
v: UNINITIALIZED,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
f: TRACKED,
|
|
29
|
+
v,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { active_component } from './index.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @template T
|
|
5
|
+
*/
|
|
6
|
+
export class Context {
|
|
7
|
+
/**
|
|
8
|
+
* @param {T} initial_value
|
|
9
|
+
*/
|
|
10
|
+
constructor(initial_value) {
|
|
11
|
+
/** @type {T} */
|
|
12
|
+
this._v = initial_value;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get() {
|
|
16
|
+
const component = active_component;
|
|
17
|
+
const context = this;
|
|
18
|
+
|
|
19
|
+
if (component === null) {
|
|
20
|
+
throw new Error('No active component found, cannot get context');
|
|
21
|
+
}
|
|
22
|
+
/** @type {Component | null} */
|
|
23
|
+
let current_component = component;
|
|
24
|
+
|
|
25
|
+
while (current_component !== null) {
|
|
26
|
+
const context_map = current_component.c;
|
|
27
|
+
|
|
28
|
+
if (context_map?.has(context)) {
|
|
29
|
+
return context_map.get(context);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
current_component = current_component.p;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return context._v;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @template T
|
|
40
|
+
* @param {T} value
|
|
41
|
+
*/
|
|
42
|
+
set(value) {
|
|
43
|
+
const component = active_component;
|
|
44
|
+
const context = this;
|
|
45
|
+
|
|
46
|
+
if (component === null) {
|
|
47
|
+
throw new Error('No active component found, cannot set context');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let current_context = component.c;
|
|
51
|
+
|
|
52
|
+
if (current_context === null) {
|
|
53
|
+
current_context = component.c = new Map();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
current_context.set(context, value);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @template T
|
|
62
|
+
* @param {T} initial_value
|
|
63
|
+
* @returns {Context<T>}
|
|
64
|
+
*/
|
|
65
|
+
export function create_context(initial_value) {
|
|
66
|
+
return new Context(initial_value);
|
|
67
|
+
}
|
|
@@ -1,7 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { is_tracked_object } from "../client/utils";
|
|
1
|
+
/** @import { Derived } from '#client' */
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
import { DERIVED, UNINITIALIZED } from '../client/constants';
|
|
4
|
+
import { is_tracked_object } from '../client/utils';
|
|
5
|
+
|
|
6
|
+
import { escape } from '../../../utils/escaping.js';
|
|
7
|
+
import { is_boolean_attribute } from '../../../compiler/utils';
|
|
8
|
+
|
|
9
|
+
export { escape };
|
|
10
|
+
|
|
11
|
+
export let active_component = null;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* `<div translate={false}>` should be rendered as `<div translate="no">` and _not_
|
|
15
|
+
* `<div translate="false">`, which is equivalent to `<div translate="yes">`. There
|
|
16
|
+
* may be other odd cases that need to be added to this list in future
|
|
17
|
+
* @type {Record<string, Map<any, string>>}
|
|
18
|
+
*/
|
|
19
|
+
const replacements = {
|
|
20
|
+
translate: new Map([
|
|
21
|
+
[true, 'yes'],
|
|
22
|
+
[false, 'no'],
|
|
23
|
+
]),
|
|
24
|
+
};
|
|
5
25
|
|
|
6
26
|
class Output {
|
|
7
27
|
head = '';
|
|
@@ -12,16 +32,12 @@ class Output {
|
|
|
12
32
|
this.#parent = parent;
|
|
13
33
|
}
|
|
14
34
|
|
|
15
|
-
component() {
|
|
16
|
-
return new Output(this);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
35
|
push(str) {
|
|
20
36
|
this.body += str;
|
|
21
37
|
}
|
|
22
38
|
}
|
|
23
39
|
|
|
24
|
-
export async function
|
|
40
|
+
export async function render(component) {
|
|
25
41
|
const output = new Output(null);
|
|
26
42
|
|
|
27
43
|
// TODO add expando "async" property to component functions during SSR
|
|
@@ -37,11 +53,16 @@ export async function renderToString(component) {
|
|
|
37
53
|
}
|
|
38
54
|
|
|
39
55
|
export function push_component() {
|
|
40
|
-
|
|
56
|
+
var component = {
|
|
57
|
+
c: null,
|
|
58
|
+
p: active_component,
|
|
59
|
+
};
|
|
60
|
+
active_component = component;
|
|
41
61
|
}
|
|
42
62
|
|
|
43
63
|
export function pop_component() {
|
|
44
|
-
|
|
64
|
+
var component = active_component;
|
|
65
|
+
active_component = component.p;
|
|
45
66
|
}
|
|
46
67
|
|
|
47
68
|
export async function async(fn) {
|
|
@@ -49,22 +70,56 @@ export async function async(fn) {
|
|
|
49
70
|
}
|
|
50
71
|
|
|
51
72
|
function get_derived(tracked) {
|
|
52
|
-
|
|
73
|
+
let v = tracked.v;
|
|
53
74
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
75
|
+
if (v === UNINITIALIZED) {
|
|
76
|
+
v = tracked.fn();
|
|
77
|
+
tracked.v = v;
|
|
78
|
+
}
|
|
79
|
+
return v;
|
|
59
80
|
}
|
|
60
81
|
|
|
61
82
|
export function get(tracked) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
83
|
+
// reflect back the value if it's not boxed
|
|
84
|
+
if (!is_tracked_object(tracked)) {
|
|
85
|
+
return tracked;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return (tracked.f & DERIVED) !== 0 ? get_derived(/** @type {Derived} */ (tracked)) : tracked.v;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @template V
|
|
93
|
+
* @param {string} name
|
|
94
|
+
* @param {V} value
|
|
95
|
+
* @param {boolean} [is_boolean]
|
|
96
|
+
* @returns {string}
|
|
97
|
+
*/
|
|
98
|
+
export function attr(name, value, is_boolean = false) {
|
|
99
|
+
if (name === 'hidden' && value !== 'until-found') {
|
|
100
|
+
is_boolean = true;
|
|
101
|
+
}
|
|
102
|
+
if (value == null || (!value && is_boolean)) return '';
|
|
103
|
+
const normalized = (name in replacements && replacements[name].get(value)) || value;
|
|
104
|
+
const assignment = is_boolean ? '' : `="${escape(normalized, true)}"`;
|
|
105
|
+
return ` ${name}${assignment}`;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function spread_attrs(attrs, css_hash) {
|
|
109
|
+
let attr_str = '';
|
|
110
|
+
let name;
|
|
111
|
+
|
|
112
|
+
for (name in attrs) {
|
|
113
|
+
var value = attrs[name];
|
|
114
|
+
|
|
115
|
+
if (typeof value === 'function') continue;
|
|
116
|
+
|
|
117
|
+
if (name === 'class' && css_hash) {
|
|
118
|
+
value = (value == null ? '' : value) + ' ' + css_hash;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
attr_str += attr(name, value, is_boolean_attribute(name));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return attr_str;
|
|
70
125
|
}
|
package/src/server/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { render } from '../runtime/internal/server/index.js';
|
|
File without changes
|