bobe 0.0.9 → 0.0.11
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/dist/bobe.cjs.js +699 -199
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.esm.js +693 -199
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +112 -94
- package/dist/index.umd.js +700 -203
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/bobe.esm.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { Store, Keys, effect, shareSignal, $ } from 'aoye';
|
|
2
|
+
export * from 'aoye';
|
|
3
|
+
import { BaseEvent, Queue, isNum } from 'bobe-shared';
|
|
4
|
+
|
|
1
5
|
var TokenType = /* @__PURE__ */ ((TokenType2) => {
|
|
2
6
|
TokenType2[TokenType2["NewLine"] = 1] = "NewLine";
|
|
3
7
|
TokenType2[TokenType2["Indent"] = 2] = "Indent";
|
|
@@ -6,6 +10,7 @@ var TokenType = /* @__PURE__ */ ((TokenType2) => {
|
|
|
6
10
|
TokenType2[TokenType2["Assign"] = 16] = "Assign";
|
|
7
11
|
TokenType2[TokenType2["Pipe"] = 32] = "Pipe";
|
|
8
12
|
TokenType2[TokenType2["Eof"] = 64] = "Eof";
|
|
13
|
+
TokenType2[TokenType2["InsertionExp"] = 128] = "InsertionExp";
|
|
9
14
|
return TokenType2;
|
|
10
15
|
})(TokenType || {});
|
|
11
16
|
var LogicType = /* @__PURE__ */ ((LogicType2) => {
|
|
@@ -13,28 +18,37 @@ var LogicType = /* @__PURE__ */ ((LogicType2) => {
|
|
|
13
18
|
LogicType2[LogicType2["ElseIf"] = 2] = "ElseIf";
|
|
14
19
|
LogicType2[LogicType2["Else"] = 4] = "Else";
|
|
15
20
|
LogicType2[LogicType2["For"] = 8] = "For";
|
|
21
|
+
LogicType2[LogicType2["Component"] = 16] = "Component";
|
|
22
|
+
LogicType2[LogicType2["Fragment"] = 32] = "Fragment";
|
|
23
|
+
LogicType2[LogicType2["Root"] = 64] = "Root";
|
|
16
24
|
return LogicType2;
|
|
17
25
|
})(LogicType || {});
|
|
26
|
+
var TerpEvt = /* @__PURE__ */ ((TerpEvt2) => {
|
|
27
|
+
TerpEvt2["AllAttrGot"] = "all-attr-got";
|
|
28
|
+
TerpEvt2["HandledComponentNode"] = "handled-component-node";
|
|
29
|
+
return TerpEvt2;
|
|
30
|
+
})(TerpEvt || {});
|
|
18
31
|
|
|
19
|
-
var __defProp = Object.defineProperty;
|
|
20
|
-
var __defProps = Object.defineProperties;
|
|
21
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
22
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
23
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
24
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
25
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
26
|
-
var __spreadValues = (a, b) => {
|
|
32
|
+
var __defProp$1 = Object.defineProperty;
|
|
33
|
+
var __defProps$1 = Object.defineProperties;
|
|
34
|
+
var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
|
|
35
|
+
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
|
|
36
|
+
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
37
|
+
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
|
|
38
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
39
|
+
var __spreadValues$1 = (a, b) => {
|
|
27
40
|
for (var prop in b || (b = {}))
|
|
28
|
-
if (__hasOwnProp.call(b, prop))
|
|
29
|
-
__defNormalProp(a, prop, b[prop]);
|
|
30
|
-
if (__getOwnPropSymbols)
|
|
31
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
32
|
-
if (__propIsEnum.call(b, prop))
|
|
33
|
-
__defNormalProp(a, prop, b[prop]);
|
|
41
|
+
if (__hasOwnProp$1.call(b, prop))
|
|
42
|
+
__defNormalProp$1(a, prop, b[prop]);
|
|
43
|
+
if (__getOwnPropSymbols$1)
|
|
44
|
+
for (var prop of __getOwnPropSymbols$1(b)) {
|
|
45
|
+
if (__propIsEnum$1.call(b, prop))
|
|
46
|
+
__defNormalProp$1(a, prop, b[prop]);
|
|
34
47
|
}
|
|
35
48
|
return a;
|
|
36
49
|
};
|
|
37
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
50
|
+
var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
|
|
51
|
+
const tap = new BaseEvent();
|
|
38
52
|
class Interpreter {
|
|
39
53
|
constructor(tokenizer) {
|
|
40
54
|
this.tokenizer = tokenizer;
|
|
@@ -44,107 +58,112 @@ class Interpreter {
|
|
|
44
58
|
this.data = {};
|
|
45
59
|
/** 模板字符串动态节点索引 */
|
|
46
60
|
this.hookI = 0;
|
|
47
|
-
this.stack = [];
|
|
48
61
|
this._hook = (props) => {
|
|
49
62
|
const value = this.tokenizer.token.value;
|
|
50
|
-
const
|
|
51
|
-
|
|
63
|
+
const isDynamicHook = this.tokenizer.token.type & TokenType.InsertionExp;
|
|
64
|
+
const isStaticHook = typeof value === "string" && value.indexOf(this.HookId) === 0;
|
|
65
|
+
const hookType = isDynamicHook ? "dynamic" : isStaticHook ? "static" : void 0;
|
|
66
|
+
if (this.hook && isStaticHook) {
|
|
52
67
|
const hookI = Number(value.slice(this.HookId.length));
|
|
53
|
-
const res = this.hook(__spreadProps(__spreadValues({}, props), {
|
|
68
|
+
const res = this.hook(__spreadProps$1(__spreadValues$1({}, props), {
|
|
54
69
|
HookId: this.HookId,
|
|
55
70
|
i: hookI
|
|
56
71
|
}));
|
|
57
72
|
this.hookI++;
|
|
58
|
-
return [
|
|
73
|
+
return [hookType, res];
|
|
74
|
+
} else if (isDynamicHook) {
|
|
75
|
+
return [hookType, value];
|
|
59
76
|
}
|
|
60
|
-
return [
|
|
77
|
+
return [hookType, value];
|
|
61
78
|
};
|
|
62
79
|
}
|
|
63
|
-
program
|
|
80
|
+
// /** program 要挂载的父节点位置 */
|
|
81
|
+
// root: any;
|
|
82
|
+
// /** program 挂载的前置节点 */
|
|
83
|
+
// anchor: any;
|
|
84
|
+
program(root, before) {
|
|
85
|
+
const componentNode = {
|
|
86
|
+
__logicType: LogicType.Component,
|
|
87
|
+
realParent: root,
|
|
88
|
+
store: new Store()
|
|
89
|
+
};
|
|
64
90
|
this.tokenizer.consume();
|
|
91
|
+
let prevSibling = null;
|
|
65
92
|
let current;
|
|
66
|
-
|
|
67
|
-
const rootList = [];
|
|
93
|
+
const stack = [{ node: root, prev: prevSibling }];
|
|
68
94
|
while (1) {
|
|
69
95
|
if (this.tokenizer.isEof()) {
|
|
70
|
-
|
|
96
|
+
this.handleInsert(root, current, prevSibling, componentNode);
|
|
71
97
|
break;
|
|
72
98
|
}
|
|
73
99
|
const token = this.tokenizer.token;
|
|
74
100
|
if (token.type & TokenType.Indent) {
|
|
75
101
|
this.tokenizer.consume();
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
102
|
+
stack.push({
|
|
103
|
+
node: current,
|
|
104
|
+
prev: prevSibling
|
|
79
105
|
});
|
|
106
|
+
current = this.declaration({ stack, prevSibling });
|
|
80
107
|
prevSibling = null;
|
|
81
|
-
current = this.declaration();
|
|
82
108
|
continue;
|
|
83
109
|
}
|
|
84
110
|
if (current) {
|
|
85
|
-
if (
|
|
86
|
-
const parent =
|
|
87
|
-
this.
|
|
111
|
+
if (stack.length > 1) {
|
|
112
|
+
const { node: parent } = stack[stack.length - 1];
|
|
113
|
+
this.handleInsert(parent, current, prevSibling);
|
|
88
114
|
} else {
|
|
89
|
-
|
|
115
|
+
if (!prevSibling) {
|
|
116
|
+
prevSibling = before;
|
|
117
|
+
}
|
|
118
|
+
this.handleInsert(root, current, prevSibling, componentNode);
|
|
90
119
|
}
|
|
91
120
|
}
|
|
92
121
|
if (this.tokenizer.token.type & TokenType.Dedent) {
|
|
93
122
|
this.tokenizer.consume();
|
|
94
|
-
const { node: parent,
|
|
95
|
-
prevSibling =
|
|
123
|
+
const { node: parent, prev } = stack.pop();
|
|
124
|
+
prevSibling = prev;
|
|
96
125
|
current = parent;
|
|
97
126
|
} else {
|
|
98
127
|
prevSibling = current;
|
|
99
|
-
current = this.declaration();
|
|
128
|
+
current = this.declaration({ stack, prevSibling });
|
|
100
129
|
}
|
|
101
130
|
}
|
|
102
|
-
|
|
131
|
+
componentNode.lastInserted = this.lastInserted;
|
|
132
|
+
this.lastInserted = null;
|
|
133
|
+
return componentNode;
|
|
103
134
|
}
|
|
104
|
-
/**
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
* |
|
|
135
|
+
/** 处理
|
|
136
|
+
* 是逻辑 是普通
|
|
137
|
+
* 父节点 将子节点加入 directList 调用 insert 方法挨个插入子节点
|
|
138
|
+
* 子节点 仅插入到父逻辑节点 将本节点插入父节点
|
|
139
|
+
* 理论上父节点不能是一个 逻辑节点,遇到if 时 Terp 会重新执行 program 这种情况下,会指定 root 为真实 dom
|
|
110
140
|
*/
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if (this.tokenizer.token.type & TokenType.Dedent) {
|
|
120
|
-
this.tokenizer.consume();
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
_node = this.node();
|
|
124
|
-
const insert = parent.__logicType ? this.defaultInsert : this.insert.bind(this);
|
|
125
|
-
parent.__logicType ? this.defaultRemove : this.remove.bind(this);
|
|
126
|
-
if (!_node.__logicType) {
|
|
127
|
-
const realPrev = this.getPrevRealSibling(prevSibling);
|
|
128
|
-
const currItem = insert(parent, _node, realPrev, prevItem);
|
|
129
|
-
prevItem = currItem;
|
|
130
|
-
prevSibling = _node;
|
|
131
|
-
continue;
|
|
141
|
+
handleInsert(parent, child, prev, parentComponent) {
|
|
142
|
+
if (!child.__logicType) {
|
|
143
|
+
if (!prev || !prev.__logicType) {
|
|
144
|
+
this.insertAfter(parent, child, prev);
|
|
145
|
+
} else {
|
|
146
|
+
const before = prev.lastInserted;
|
|
147
|
+
this.insertAfter(parent, child, before);
|
|
148
|
+
prev.realAfter = child;
|
|
132
149
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
150
|
+
} else {
|
|
151
|
+
const childCmp = child;
|
|
152
|
+
childCmp.realParent = parent;
|
|
153
|
+
if (!prev) {
|
|
154
|
+
const anchor = this.createAnchor();
|
|
155
|
+
this.insertAfter(parent, anchor, prev);
|
|
156
|
+
this.insertAfter(parent, child, anchor);
|
|
157
|
+
childCmp.realBefore = anchor;
|
|
158
|
+
} else if (prev.__logicType) {
|
|
159
|
+
const before = prev.lastInserted;
|
|
160
|
+
const anchor = this.createAnchor();
|
|
161
|
+
this.insertAfter(parent, anchor, before);
|
|
162
|
+
this.insertAfter(parent, child, anchor);
|
|
163
|
+
childCmp.realBefore = anchor;
|
|
164
|
+
prev.realAfter = anchor;
|
|
165
|
+
} else {
|
|
166
|
+
childCmp.realBefore = prev;
|
|
148
167
|
}
|
|
149
168
|
}
|
|
150
169
|
}
|
|
@@ -161,54 +180,111 @@ class Interpreter {
|
|
|
161
180
|
point = point.anchor;
|
|
162
181
|
}
|
|
163
182
|
}
|
|
164
|
-
/**
|
|
165
|
-
* 单个节点:
|
|
166
|
-
* 由声明部分和(可选的)子节点块组成
|
|
167
|
-
* <node> ::= <declaration> <childrenBlockOpt>
|
|
168
|
-
* */
|
|
169
|
-
node() {
|
|
170
|
-
const _declaration = this.declaration();
|
|
171
|
-
if (_declaration.__logicType & LogicType.If && !_declaration.condition()) {
|
|
172
|
-
return _declaration;
|
|
173
|
-
}
|
|
174
|
-
this.childrenBlockOpt(_declaration);
|
|
175
|
-
return _declaration;
|
|
176
|
-
}
|
|
177
183
|
/**
|
|
178
184
|
* 声明部分:
|
|
179
185
|
* 包含首行定义和(可选的)多行属性扩展
|
|
180
186
|
* <declaration> ::= <tagName=token> <headerLine> <extensionLines>
|
|
181
187
|
* */
|
|
182
|
-
declaration() {
|
|
183
|
-
const [
|
|
188
|
+
declaration(ctx) {
|
|
189
|
+
const [hookType, value] = this._hook({});
|
|
184
190
|
let _node;
|
|
185
|
-
if (
|
|
186
|
-
const { tree, data } = value();
|
|
187
|
-
_node = tree;
|
|
188
|
-
} else if (value === "if") {
|
|
191
|
+
if (value === "if") {
|
|
189
192
|
return this.ifDeclaration();
|
|
193
|
+
} else if (hookType) {
|
|
194
|
+
if (hookType === "static") {
|
|
195
|
+
if (typeof value === "function" && value.prototype instanceof Store) {
|
|
196
|
+
_node = this.componentDeclaration(value, ctx);
|
|
197
|
+
} else if (typeof value === "function") {
|
|
198
|
+
_node = this.fragmentDeclaration(value);
|
|
199
|
+
} else {
|
|
200
|
+
throw new SyntaxError(`declaration \u4E0D\u652F\u6301 ${value} \u7C7B\u578B\u7684\u9759\u6001\u63D2\u503C`);
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
203
|
+
Boolean(this.data[Keys.Raw][value]);
|
|
204
|
+
new Function("data", `let v;with(data){v=(${value})};return v`);
|
|
205
|
+
_node = this.createNode(value);
|
|
206
|
+
}
|
|
190
207
|
} else {
|
|
191
208
|
_node = this.createNode(value);
|
|
192
209
|
}
|
|
193
210
|
this.tokenizer.consume();
|
|
194
211
|
this.headerLine(_node);
|
|
195
212
|
this.extensionLines(_node);
|
|
213
|
+
if (_node.__logicType === LogicType.Component) {
|
|
214
|
+
tap.once(TerpEvt.HandledComponentNode, (node) => _node = node);
|
|
215
|
+
tap.emit(TerpEvt.AllAttrGot);
|
|
216
|
+
}
|
|
196
217
|
return _node;
|
|
197
218
|
}
|
|
219
|
+
// TODO: 指定挂载位置
|
|
220
|
+
fragmentDeclaration(renderFragment) {
|
|
221
|
+
const fragmentNode = {
|
|
222
|
+
__logicType: LogicType.Fragment,
|
|
223
|
+
realParent: null
|
|
224
|
+
};
|
|
225
|
+
renderFragment.call(this.data, this.opt, { data: this.data, root: "", anchor: "" });
|
|
226
|
+
return fragmentNode;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* key 元素,组件的 key
|
|
230
|
+
* value
|
|
231
|
+
* 1. 静态类型值
|
|
232
|
+
* 2. 插值计算 函数,可以考虑 使用 effect 或 computed 做处理
|
|
233
|
+
*
|
|
234
|
+
* mapKey 映射, 对应子组件的属性
|
|
235
|
+
* */
|
|
236
|
+
onePropParsed(node, key, value, valueIsMapKey, hookI) {
|
|
237
|
+
if (typeof value === "function") {
|
|
238
|
+
effect(() => {
|
|
239
|
+
const res = value();
|
|
240
|
+
this.setProp(node, key, res, hookI);
|
|
241
|
+
});
|
|
242
|
+
} else if (valueIsMapKey) {
|
|
243
|
+
effect(() => {
|
|
244
|
+
const res = this.data[value];
|
|
245
|
+
this.setProp(node, key, res, hookI);
|
|
246
|
+
});
|
|
247
|
+
} else {
|
|
248
|
+
this.setProp(node, key, value, hookI);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
componentDeclaration(Component, ctx) {
|
|
252
|
+
const child = Component.new();
|
|
253
|
+
const prevOnePropParsed = this.onePropParsed;
|
|
254
|
+
this.onePropParsed = (node, key, value, valueIsMapKey, hookI) => {
|
|
255
|
+
if (valueIsMapKey) {
|
|
256
|
+
shareSignal(this.data, value, child, key);
|
|
257
|
+
} else if (typeof value === "function") {
|
|
258
|
+
const meta = child[Keys.Meta];
|
|
259
|
+
const cells = meta.cells;
|
|
260
|
+
const computed = $(value);
|
|
261
|
+
cells.set(key, computed);
|
|
262
|
+
} else {
|
|
263
|
+
child[Keys.Raw][key] = value;
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
tap.once(TerpEvt.AllAttrGot, () => {
|
|
267
|
+
const parent = ctx.stack[ctx.stack.length - 1].node;
|
|
268
|
+
const prev = ctx.prevSibling;
|
|
269
|
+
this.onePropParsed = prevOnePropParsed;
|
|
270
|
+
const componentNode = child["ui"](this.opt, { data: child }, parent, prev);
|
|
271
|
+
tap.emit(TerpEvt.HandledComponentNode, componentNode);
|
|
272
|
+
});
|
|
273
|
+
return { __logicType: LogicType.Component };
|
|
274
|
+
}
|
|
198
275
|
ifDeclaration() {
|
|
199
276
|
this.tokenizer.consume();
|
|
200
277
|
const [isHook, value] = this._hook({});
|
|
201
278
|
const ifNode = {
|
|
202
279
|
__logicType: LogicType.If,
|
|
203
280
|
condition: value,
|
|
204
|
-
|
|
205
|
-
realList: [],
|
|
281
|
+
realParent: null,
|
|
206
282
|
snapshot: this.tokenizer.snapshot(),
|
|
207
283
|
isFirstRender: true,
|
|
208
284
|
watcher: null,
|
|
209
285
|
anchor: null
|
|
210
286
|
};
|
|
211
|
-
ifNode.watcher =
|
|
287
|
+
ifNode.watcher = effect(
|
|
212
288
|
({ val }) => {
|
|
213
289
|
if (val) {
|
|
214
290
|
this.tokenizer.consume();
|
|
@@ -253,130 +329,84 @@ class Interpreter {
|
|
|
253
329
|
* <attributeList> ::= <attribute> <attributeList>
|
|
254
330
|
* | ε
|
|
255
331
|
*
|
|
256
|
-
* <attribute> ::= <key>
|
|
257
|
-
*
|
|
332
|
+
* <attribute> ::= <key> = <value>
|
|
333
|
+
* 1. 普通节点 执行 setProps 🪝
|
|
334
|
+
* 2. 组件节点 收集映射关系,或通过 effect 直接设值
|
|
258
335
|
*/
|
|
259
336
|
attributeList(_node) {
|
|
260
|
-
let
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
defaultVal = v2;
|
|
275
|
-
}
|
|
337
|
+
let key, eq;
|
|
338
|
+
while (!(this.tokenizer.token.type & TokenType.NewLine)) {
|
|
339
|
+
if (key == null) {
|
|
340
|
+
key = this.tokenizer.token.value;
|
|
341
|
+
} else if (eq == null) {
|
|
342
|
+
eq = "=";
|
|
343
|
+
} else {
|
|
344
|
+
const [hookType, value] = this._hook({});
|
|
345
|
+
if (hookType === "dynamic") {
|
|
346
|
+
const valueIsMapKey = Reflect.has(this.data[Keys.Raw], value);
|
|
347
|
+
const fn = valueIsMapKey ? value : new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0, this.data);
|
|
348
|
+
this.onePropParsed(_node, key, fn, valueIsMapKey, this.hookI);
|
|
349
|
+
} else if (hookType === "static") {
|
|
350
|
+
this.onePropParsed(_node, key, value, false, this.hookI);
|
|
276
351
|
} else {
|
|
277
|
-
|
|
352
|
+
this.onePropParsed(_node, key, value, false, this.hookI);
|
|
278
353
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
val = this.setDataProp(this.data, dataKey, defaultVal);
|
|
282
|
-
}
|
|
283
|
-
this.setProp(_node, key, val, this.hookI - 1);
|
|
284
|
-
const [isHook, value] = this._hook({});
|
|
285
|
-
values = [value];
|
|
286
|
-
} else if (this.tokenizer.token.type !== TokenType.Assign) {
|
|
287
|
-
const [isHook, value] = this._hook({});
|
|
288
|
-
values.push(value);
|
|
289
|
-
}
|
|
290
|
-
if (!(this.tokenizer.token.type & (TokenType.Identifier | TokenType.Assign))) {
|
|
291
|
-
break;
|
|
354
|
+
key = null;
|
|
355
|
+
eq = null;
|
|
292
356
|
}
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
/** 子节点块:
|
|
297
|
-
* 必须被缩进包裹
|
|
298
|
-
* <childrenBlockOpt> ::= INDENT <nodeList>
|
|
299
|
-
* | ε /* 空(表示叶子节点,没有孩子)
|
|
300
|
-
* */
|
|
301
|
-
childrenBlockOpt(parent) {
|
|
302
|
-
if (!(this.tokenizer.token.type & TokenType.Indent)) {
|
|
303
|
-
return [];
|
|
357
|
+
this.tokenizer.consume();
|
|
304
358
|
}
|
|
305
|
-
this.tokenizer.consume();
|
|
306
|
-
const list = this.nodeList(parent);
|
|
307
|
-
return list;
|
|
308
359
|
}
|
|
309
360
|
config(opt) {
|
|
310
361
|
Object.assign(this, opt);
|
|
311
|
-
|
|
312
|
-
createData(data) {
|
|
313
|
-
return data;
|
|
314
|
-
}
|
|
315
|
-
setDataProp(data, key, value) {
|
|
316
|
-
return data[key] = value;
|
|
317
|
-
}
|
|
318
|
-
setChildren(node, children) {
|
|
319
|
-
node.children = children;
|
|
362
|
+
this.opt = opt;
|
|
320
363
|
}
|
|
321
364
|
createNode(name) {
|
|
322
365
|
return {
|
|
323
366
|
name,
|
|
324
|
-
props: {}
|
|
367
|
+
props: {},
|
|
368
|
+
nextSibling: null
|
|
325
369
|
};
|
|
326
370
|
}
|
|
327
|
-
|
|
328
|
-
return
|
|
371
|
+
nextSib(node) {
|
|
372
|
+
return node.nextSibling;
|
|
329
373
|
}
|
|
330
|
-
|
|
331
|
-
return
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
if (!parent.child) {
|
|
335
|
-
return parent.child = parent.lastChild = {
|
|
336
|
-
value: node,
|
|
337
|
-
next: null
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
const nextItem = prevItem.next;
|
|
341
|
-
const item = {
|
|
342
|
-
value: node,
|
|
343
|
-
next: nextItem
|
|
374
|
+
createAnchor() {
|
|
375
|
+
return {
|
|
376
|
+
name: "anchor",
|
|
377
|
+
nextSibling: null
|
|
344
378
|
};
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
379
|
+
}
|
|
380
|
+
insertAfter(parent, node, prev) {
|
|
381
|
+
this.lastInserted = node;
|
|
382
|
+
return this.defaultInsert(parent, node, prev);
|
|
383
|
+
}
|
|
384
|
+
defaultInsert(parent, node, prev) {
|
|
385
|
+
if (prev) {
|
|
386
|
+
const next = prev.nextSibling;
|
|
387
|
+
prev.nextSibling = node;
|
|
388
|
+
node.nextSibling = next;
|
|
389
|
+
} else {
|
|
390
|
+
parent.firstChild = node;
|
|
348
391
|
}
|
|
349
|
-
return item;
|
|
350
392
|
}
|
|
351
|
-
remove(parent, node, prevSibling
|
|
352
|
-
return this.defaultRemove(parent, node, prevSibling
|
|
393
|
+
remove(parent, node, prevSibling) {
|
|
394
|
+
return this.defaultRemove(parent, node, prevSibling);
|
|
353
395
|
}
|
|
354
396
|
// TODO: 默认改成 prevItem
|
|
355
|
-
defaultRemove(parent, node, prevSibling
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
prevItem.next = null;
|
|
363
|
-
parent.lastChild = prevItem;
|
|
364
|
-
}
|
|
365
|
-
} else {
|
|
366
|
-
if (nextItem) {
|
|
367
|
-
parent.child = nextItem;
|
|
368
|
-
} else {
|
|
369
|
-
parent.child = null;
|
|
370
|
-
parent.lastChild = null;
|
|
371
|
-
}
|
|
397
|
+
defaultRemove(parent, node, prevSibling) {
|
|
398
|
+
const next = node.nextSibling;
|
|
399
|
+
if (prevSibling) {
|
|
400
|
+
prevSibling.nextSibling = next;
|
|
401
|
+
}
|
|
402
|
+
if (parent.firstChild === node) {
|
|
403
|
+
parent.firstChild = next;
|
|
372
404
|
}
|
|
373
|
-
currItem.next = null;
|
|
374
405
|
}
|
|
375
406
|
setProp(node, key, value, hookI) {
|
|
376
407
|
node.props[key] = value;
|
|
377
408
|
}
|
|
378
409
|
init(fragments) {
|
|
379
|
-
this.data = this.createData(this.data);
|
|
380
410
|
if (typeof fragments === "string") {
|
|
381
411
|
this.tokenizer.setCode(fragments);
|
|
382
412
|
} else {
|
|
@@ -390,5 +420,469 @@ class Interpreter {
|
|
|
390
420
|
}
|
|
391
421
|
}
|
|
392
422
|
|
|
393
|
-
|
|
423
|
+
const _Tokenizer = class _Tokenizer {
|
|
424
|
+
constructor() {
|
|
425
|
+
/** 缩进大小 默认 2 */
|
|
426
|
+
this.TabSize = 2;
|
|
427
|
+
/** 缩进字符 */
|
|
428
|
+
this.Tab = Array.from({ length: this.TabSize }, () => " ").join("");
|
|
429
|
+
/** 匹配标识符 */
|
|
430
|
+
this.IdExp = /[\d\w\/]/;
|
|
431
|
+
/** 回车后需要判断缩进 */
|
|
432
|
+
this.needIndent = false;
|
|
433
|
+
/** 用于跳过第一个节点前的空白字符串,以及生成基础缩进 */
|
|
434
|
+
this.isFirstToken = true;
|
|
435
|
+
/** 记录历史缩进的长度,相对于行首 */
|
|
436
|
+
this.dentStack = [0];
|
|
437
|
+
/** 当前字符 index */
|
|
438
|
+
this.i = 0;
|
|
439
|
+
this.handledTokens = [];
|
|
440
|
+
/**
|
|
441
|
+
* 有些标识符能产生多个 token
|
|
442
|
+
* 例如 dedent
|
|
443
|
+
* parent1
|
|
444
|
+
* child
|
|
445
|
+
* subChild
|
|
446
|
+
* parent2 <- 产生两个 dedent
|
|
447
|
+
*/
|
|
448
|
+
this.waitingTokens = new Queue();
|
|
449
|
+
}
|
|
450
|
+
consume() {
|
|
451
|
+
const token = this.token;
|
|
452
|
+
this.nextToken();
|
|
453
|
+
return token;
|
|
454
|
+
}
|
|
455
|
+
// /** 恢复至某一个现场,进行 token 重算 */
|
|
456
|
+
resume(_snapshot) {
|
|
457
|
+
this.token = void 0;
|
|
458
|
+
this.needIndent = false;
|
|
459
|
+
this.isFirstToken = true;
|
|
460
|
+
this.dentStack = [0];
|
|
461
|
+
Object.assign(this, _snapshot);
|
|
462
|
+
}
|
|
463
|
+
snapshot() {
|
|
464
|
+
return {
|
|
465
|
+
i: this.i,
|
|
466
|
+
waitingTokens: this.waitingTokens.clone()
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
skip() {
|
|
470
|
+
const dentLen = this.dentStack[this.dentStack.length - 1];
|
|
471
|
+
let needIndent = false;
|
|
472
|
+
let skipFragment = ``;
|
|
473
|
+
this.token = void 0;
|
|
474
|
+
while (1) {
|
|
475
|
+
const char = this.char;
|
|
476
|
+
if (char === "\n") {
|
|
477
|
+
needIndent = true;
|
|
478
|
+
skipFragment += char;
|
|
479
|
+
this.next();
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
if (!needIndent) {
|
|
483
|
+
skipFragment += char;
|
|
484
|
+
this.next();
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
487
|
+
needIndent = false;
|
|
488
|
+
const { value, isEmptyLine } = this.getDentValue();
|
|
489
|
+
const currLen = value.length;
|
|
490
|
+
if (isEmptyLine) continue;
|
|
491
|
+
if (value.length > dentLen) {
|
|
492
|
+
skipFragment += value;
|
|
493
|
+
} else {
|
|
494
|
+
for (let i = this.dentStack.length - 1; i >= 0; i--) {
|
|
495
|
+
const expLen = this.dentStack[i];
|
|
496
|
+
if (currLen === expLen) break;
|
|
497
|
+
if (currLen > expLen) {
|
|
498
|
+
throw SyntaxError(`\u7F29\u8FDB\u9519\u8BEF\uFF0C\u7F29\u8FDB\u957F\u5EA6\u4E0D\u5339\u914D`);
|
|
499
|
+
}
|
|
500
|
+
this.dentStack.pop();
|
|
501
|
+
if (!this.token) {
|
|
502
|
+
this.setToken(TokenType.Dedent, String(expLen));
|
|
503
|
+
} else {
|
|
504
|
+
this.waitingTokens.push({
|
|
505
|
+
type: TokenType.Dedent,
|
|
506
|
+
typeName: TokenType[TokenType.Dedent],
|
|
507
|
+
value: String(expLen)
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
break;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
if (!this.token) {
|
|
515
|
+
this.nextToken();
|
|
516
|
+
}
|
|
517
|
+
return skipFragment;
|
|
518
|
+
}
|
|
519
|
+
setCode(code) {
|
|
520
|
+
this.code = "\n" + code.trimEnd() + `
|
|
521
|
+
${_Tokenizer.EofId}`;
|
|
522
|
+
}
|
|
523
|
+
tokenize() {
|
|
524
|
+
var _a, _b;
|
|
525
|
+
do {
|
|
526
|
+
this.nextToken();
|
|
527
|
+
console.log("token:", TokenType[(_a = this.token) == null ? void 0 : _a.type], JSON.stringify(((_b = this.token) == null ? void 0 : _b.value) || ""));
|
|
528
|
+
} while (!this.isEof());
|
|
529
|
+
}
|
|
530
|
+
isEof() {
|
|
531
|
+
if (!this.token) return false;
|
|
532
|
+
return this.token.type & TokenType.Identifier && this.token.value === _Tokenizer.EofId;
|
|
533
|
+
}
|
|
534
|
+
get char() {
|
|
535
|
+
return this.code[this.i];
|
|
536
|
+
}
|
|
537
|
+
get prev() {
|
|
538
|
+
return this.code[this.i - 1];
|
|
539
|
+
}
|
|
540
|
+
get after() {
|
|
541
|
+
return this.code[this.i + 1];
|
|
542
|
+
}
|
|
543
|
+
next() {
|
|
544
|
+
const prev = this.code[this.i];
|
|
545
|
+
this.i++;
|
|
546
|
+
const curr = this.code[this.i];
|
|
547
|
+
return [prev, curr];
|
|
548
|
+
}
|
|
549
|
+
setToken(type, value) {
|
|
550
|
+
this.token = {
|
|
551
|
+
type,
|
|
552
|
+
typeName: TokenType[type],
|
|
553
|
+
value
|
|
554
|
+
};
|
|
555
|
+
this.isFirstToken = false;
|
|
556
|
+
}
|
|
557
|
+
testId(value) {
|
|
558
|
+
if (typeof value !== "string") return false;
|
|
559
|
+
return this.IdExp.test(value);
|
|
560
|
+
}
|
|
561
|
+
nextToken() {
|
|
562
|
+
try {
|
|
563
|
+
if (this.isEof()) {
|
|
564
|
+
return this.token;
|
|
565
|
+
}
|
|
566
|
+
this.token = void 0;
|
|
567
|
+
if (this.waitingTokens.len) {
|
|
568
|
+
const item = this.waitingTokens.shift();
|
|
569
|
+
this.setToken(item.type, item.value);
|
|
570
|
+
return this.token;
|
|
571
|
+
}
|
|
572
|
+
outer: while (1) {
|
|
573
|
+
if (this.needIndent) {
|
|
574
|
+
this.dent();
|
|
575
|
+
} else {
|
|
576
|
+
let { char } = this;
|
|
577
|
+
switch (char) {
|
|
578
|
+
case " ":
|
|
579
|
+
case " ":
|
|
580
|
+
break;
|
|
581
|
+
// 找后续所有 newLine
|
|
582
|
+
case "\n":
|
|
583
|
+
this.newLine();
|
|
584
|
+
this.needIndent = true;
|
|
585
|
+
break;
|
|
586
|
+
case "=":
|
|
587
|
+
this.assignment();
|
|
588
|
+
break;
|
|
589
|
+
case "|":
|
|
590
|
+
this.pipe();
|
|
591
|
+
break;
|
|
592
|
+
case "'":
|
|
593
|
+
case '"':
|
|
594
|
+
this.str(char);
|
|
595
|
+
break;
|
|
596
|
+
case "{":
|
|
597
|
+
this.brace();
|
|
598
|
+
break;
|
|
599
|
+
case "$":
|
|
600
|
+
const handled = this.dynamic(char);
|
|
601
|
+
if (handled) break;
|
|
602
|
+
default:
|
|
603
|
+
if (isNum(char)) {
|
|
604
|
+
this.number(char);
|
|
605
|
+
break;
|
|
606
|
+
}
|
|
607
|
+
if (this.testId(char)) {
|
|
608
|
+
this.identifier(char);
|
|
609
|
+
}
|
|
610
|
+
break;
|
|
611
|
+
}
|
|
612
|
+
this.next();
|
|
613
|
+
}
|
|
614
|
+
if (this.token) {
|
|
615
|
+
break;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
return this.token;
|
|
619
|
+
} catch (error) {
|
|
620
|
+
console.error(error);
|
|
621
|
+
} finally {
|
|
622
|
+
this.handledTokens.push(this.token);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
assignment() {
|
|
626
|
+
this.setToken(TokenType.Assign, "=");
|
|
627
|
+
}
|
|
628
|
+
pipe() {
|
|
629
|
+
this.setToken(TokenType.Pipe, "|");
|
|
630
|
+
}
|
|
631
|
+
dynamic(char) {
|
|
632
|
+
let nextC = this.after;
|
|
633
|
+
if (nextC !== "{") {
|
|
634
|
+
return false;
|
|
635
|
+
}
|
|
636
|
+
this.next();
|
|
637
|
+
let value = "${";
|
|
638
|
+
let innerBrace = 0;
|
|
639
|
+
while (1) {
|
|
640
|
+
nextC = this.after;
|
|
641
|
+
value += nextC;
|
|
642
|
+
this.next();
|
|
643
|
+
if (nextC === "{") {
|
|
644
|
+
innerBrace++;
|
|
645
|
+
}
|
|
646
|
+
if (nextC === "}") {
|
|
647
|
+
if (!innerBrace) {
|
|
648
|
+
break;
|
|
649
|
+
}
|
|
650
|
+
innerBrace--;
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
this.setToken(TokenType.Identifier, value);
|
|
654
|
+
return true;
|
|
655
|
+
}
|
|
656
|
+
brace() {
|
|
657
|
+
let inComment, inString, count = 0, value = "", backslashCount = 0;
|
|
658
|
+
while (1) {
|
|
659
|
+
const char = this.char;
|
|
660
|
+
const nextChar = this.after;
|
|
661
|
+
if (inComment === "single" && char === "\n") {
|
|
662
|
+
inComment = null;
|
|
663
|
+
} else if (inComment === "multi" && char === "*" && nextChar === "/") {
|
|
664
|
+
inComment = null;
|
|
665
|
+
value += this.next()[0];
|
|
666
|
+
} else if (inString) {
|
|
667
|
+
if (char === inString && backslashCount % 2 === 0) {
|
|
668
|
+
inString = null;
|
|
669
|
+
}
|
|
670
|
+
backslashCount = char === "\\" ? backslashCount + 1 : 0;
|
|
671
|
+
} else {
|
|
672
|
+
if (char === "/" && nextChar === "/") {
|
|
673
|
+
inComment = "single";
|
|
674
|
+
value += this.next()[0];
|
|
675
|
+
} else if (char === "/" && nextChar === "*") {
|
|
676
|
+
inComment = "multi";
|
|
677
|
+
value += this.next()[0];
|
|
678
|
+
} else if (char === "'" || char === '"' || char === "`") {
|
|
679
|
+
inString = char;
|
|
680
|
+
} else if (char === "{") {
|
|
681
|
+
count++;
|
|
682
|
+
} else if (char === "}") {
|
|
683
|
+
count--;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
if (count === 0 && inString == null && inComment == null) {
|
|
687
|
+
this.setToken(TokenType.InsertionExp, value.slice(1));
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
value += this.next()[0];
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
newLine() {
|
|
694
|
+
let value = "\n";
|
|
695
|
+
let nextC;
|
|
696
|
+
while (1) {
|
|
697
|
+
nextC = this.after;
|
|
698
|
+
if (nextC !== "\n") {
|
|
699
|
+
break;
|
|
700
|
+
}
|
|
701
|
+
value += nextC;
|
|
702
|
+
this.next();
|
|
703
|
+
}
|
|
704
|
+
if (this.isFirstToken) {
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
this.setToken(TokenType.NewLine, value);
|
|
708
|
+
}
|
|
709
|
+
getDentValue() {
|
|
710
|
+
let value = "";
|
|
711
|
+
let nextC;
|
|
712
|
+
let isEmptyLine = false;
|
|
713
|
+
while (1) {
|
|
714
|
+
const nextChar = this.char;
|
|
715
|
+
switch (nextChar) {
|
|
716
|
+
case " ":
|
|
717
|
+
nextC = this.Tab;
|
|
718
|
+
break;
|
|
719
|
+
case " ":
|
|
720
|
+
nextC = " ";
|
|
721
|
+
break;
|
|
722
|
+
case "\n":
|
|
723
|
+
nextC = "\n";
|
|
724
|
+
break;
|
|
725
|
+
default:
|
|
726
|
+
nextC = "";
|
|
727
|
+
break;
|
|
728
|
+
}
|
|
729
|
+
if (nextC === "\n") {
|
|
730
|
+
isEmptyLine = true;
|
|
731
|
+
break;
|
|
732
|
+
}
|
|
733
|
+
if (!nextC) {
|
|
734
|
+
break;
|
|
735
|
+
}
|
|
736
|
+
value += nextC;
|
|
737
|
+
this.next();
|
|
738
|
+
}
|
|
739
|
+
return {
|
|
740
|
+
value,
|
|
741
|
+
isEmptyLine
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
dent() {
|
|
745
|
+
const { value, isEmptyLine } = this.getDentValue();
|
|
746
|
+
if (isEmptyLine) {
|
|
747
|
+
this.needIndent = true;
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
this.needIndent = false;
|
|
751
|
+
if (this.isFirstToken) {
|
|
752
|
+
this.dentStack[0] = value.length;
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
let currLen = value.length;
|
|
756
|
+
const indentHasLen = currLen > 0;
|
|
757
|
+
const prevLen = this.dentStack[this.dentStack.length - 1];
|
|
758
|
+
if (currLen > prevLen) {
|
|
759
|
+
this.dentStack.push(currLen);
|
|
760
|
+
this.setToken(TokenType.Indent, String(currLen));
|
|
761
|
+
return indentHasLen;
|
|
762
|
+
}
|
|
763
|
+
if (currLen < prevLen) {
|
|
764
|
+
for (let i = this.dentStack.length - 2; i >= 0; i--) {
|
|
765
|
+
const expLen = this.dentStack[i];
|
|
766
|
+
const prevExpLen = this.dentStack[i + 1];
|
|
767
|
+
if (currLen > expLen && currLen < prevExpLen) {
|
|
768
|
+
throw SyntaxError("\u7F29\u8FDB\u5927\u5C0F\u4E0D\u7EDF\u4E00");
|
|
769
|
+
}
|
|
770
|
+
this.dentStack.pop();
|
|
771
|
+
if (!this.token) {
|
|
772
|
+
this.setToken(TokenType.Dedent, String(expLen));
|
|
773
|
+
} else {
|
|
774
|
+
this.waitingTokens.push({
|
|
775
|
+
type: TokenType.Dedent,
|
|
776
|
+
typeName: TokenType[TokenType.Dedent],
|
|
777
|
+
value: String(expLen)
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
if (currLen === expLen) {
|
|
781
|
+
break;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
return indentHasLen;
|
|
785
|
+
}
|
|
786
|
+
return indentHasLen;
|
|
787
|
+
}
|
|
788
|
+
identifier(char) {
|
|
789
|
+
let value = char;
|
|
790
|
+
let nextC;
|
|
791
|
+
while (1) {
|
|
792
|
+
nextC = this.after;
|
|
793
|
+
if (!this.testId(nextC)) {
|
|
794
|
+
break;
|
|
795
|
+
}
|
|
796
|
+
value += nextC;
|
|
797
|
+
this.next();
|
|
798
|
+
}
|
|
799
|
+
let realValue = value === "null" ? null : value === "undefined" ? void 0 : value === "false" ? false : value === "true" ? true : value;
|
|
800
|
+
this.setToken(TokenType.Identifier, realValue);
|
|
801
|
+
}
|
|
802
|
+
str(char) {
|
|
803
|
+
let value = '"';
|
|
804
|
+
let nextC;
|
|
805
|
+
let continuousBackslashCount = 0;
|
|
806
|
+
while (1) {
|
|
807
|
+
nextC = this.after;
|
|
808
|
+
value += nextC;
|
|
809
|
+
const memoCount = continuousBackslashCount;
|
|
810
|
+
if (nextC === "\\") {
|
|
811
|
+
continuousBackslashCount++;
|
|
812
|
+
} else {
|
|
813
|
+
continuousBackslashCount = 0;
|
|
814
|
+
}
|
|
815
|
+
this.next();
|
|
816
|
+
if (nextC === char && memoCount % 2 === 0) {
|
|
817
|
+
break;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
this.setToken(TokenType.Identifier, JSON.parse(value.slice(0, -1) + '"'));
|
|
821
|
+
}
|
|
822
|
+
number(char) {
|
|
823
|
+
let value = char;
|
|
824
|
+
let nextC;
|
|
825
|
+
while (1) {
|
|
826
|
+
nextC = this.after;
|
|
827
|
+
if (!isNum(nextC)) {
|
|
828
|
+
break;
|
|
829
|
+
}
|
|
830
|
+
value += nextC;
|
|
831
|
+
this.next();
|
|
832
|
+
}
|
|
833
|
+
this.setToken(TokenType.Identifier, Number(value));
|
|
834
|
+
}
|
|
835
|
+
eof() {
|
|
836
|
+
this.setToken(TokenType.Eof, "End Of File");
|
|
837
|
+
}
|
|
838
|
+
};
|
|
839
|
+
/** Eof 标识符的值 */
|
|
840
|
+
_Tokenizer.EofId = `__EOF__${Date.now()}`;
|
|
841
|
+
let Tokenizer = _Tokenizer;
|
|
842
|
+
|
|
843
|
+
var __defProp = Object.defineProperty;
|
|
844
|
+
var __defProps = Object.defineProperties;
|
|
845
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
846
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
847
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
848
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
849
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
850
|
+
var __spreadValues = (a, b) => {
|
|
851
|
+
for (var prop in b || (b = {}))
|
|
852
|
+
if (__hasOwnProp.call(b, prop))
|
|
853
|
+
__defNormalProp(a, prop, b[prop]);
|
|
854
|
+
if (__getOwnPropSymbols)
|
|
855
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
856
|
+
if (__propIsEnum.call(b, prop))
|
|
857
|
+
__defNormalProp(a, prop, b[prop]);
|
|
858
|
+
}
|
|
859
|
+
return a;
|
|
860
|
+
};
|
|
861
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
862
|
+
function bobe(fragments, ...values) {
|
|
863
|
+
const ui = function ui2(options, valueOpt, root, before) {
|
|
864
|
+
const tokenizer = new Tokenizer();
|
|
865
|
+
const cmp = new Interpreter(tokenizer);
|
|
866
|
+
Object.assign(cmp, valueOpt);
|
|
867
|
+
cmp.config(__spreadProps(__spreadValues({}, options), {
|
|
868
|
+
hook({ i }) {
|
|
869
|
+
return values[i];
|
|
870
|
+
},
|
|
871
|
+
setProp(node, key, value, hookI) {
|
|
872
|
+
node.props[key] = value;
|
|
873
|
+
}
|
|
874
|
+
}));
|
|
875
|
+
cmp.init(Array.from(fragments));
|
|
876
|
+
return cmp.program(root, before);
|
|
877
|
+
};
|
|
878
|
+
return ui;
|
|
879
|
+
}
|
|
880
|
+
function customRender(option) {
|
|
881
|
+
return function render(Ctor, root) {
|
|
882
|
+
const store = Ctor.new();
|
|
883
|
+
return [store["ui"](option, { data: store }, root), store];
|
|
884
|
+
};
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
export { bobe, customRender };
|
|
394
888
|
//# sourceMappingURL=bobe.esm.js.map
|