bobe 0.0.48 → 0.0.50

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/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Queue } from 'bobe-shared';
2
2
  import * as aoye from 'aoye';
3
- import { Store, Effect, effect as effect$1, Scope, Signal, Computed, SignalNode, ValueDiff, CustomEffectOpt } from 'aoye';
3
+ import { Store, Keys, Effect, effect as effect$1, Scope, Signal, Computed, SignalNode, ValueDiff, CustomEffectOpt } from 'aoye';
4
4
  export { Store } from 'aoye';
5
5
 
6
6
  declare class Interpreter {
@@ -27,7 +27,7 @@ declare class Interpreter {
27
27
  /**
28
28
  * 声明部分:
29
29
  * 包含首行定义和(可选的)多行属性扩展
30
- * <declaration> ::= <tagName=token> <headerLine> <extensionLines>
30
+ * <declaration> ::= <tagName=token> <headerLineAndExtensions>
31
31
  * */
32
32
  declaration(ctx: ProgramCtx): any;
33
33
  createContextNode(): ContextNode;
@@ -49,22 +49,25 @@ declare class Interpreter {
49
49
  * */
50
50
  onePropParsed(data: Store, node: any, key: string, value: any, valueIsMapKey: boolean, isFn: boolean, hookI?: number): void;
51
51
  oneRealPropParsed: Interpreter['onePropParsed'];
52
- componentOrFragmentDeclaration(ComponentOrRender: BobeUI | typeof Store, ctx: ProgramCtx): ComponentNode$1;
52
+ componentOrFragmentDeclaration(ComponentOrRender: UI | typeof Store | InlineFragment, ctx: ProgramCtx): ComponentNode$1;
53
53
  getFn(data: any, expression: string | number): any;
54
54
  getAssignFn(data: any, expression: string | number): any;
55
55
  condDeclaration(ctx: ProgramCtx): IfNode;
56
56
  removeLogicNode(node: LogicNode): void;
57
57
  /**
58
- * <extensionLines> ::= PIPE <attributeList> NEWLINE <extensionLines>
59
- * | ε
58
+ * 首行属性 + 可选的 pipe 扩展行
59
+ * <headerLineAndExtensions> ::= <attributeList> NEWLINE (PIPE <attributeList> NEWLINE)*
60
60
  */
61
- extensionLines(_node: any): void;
61
+ headerLineAndExtensions(_node: any): void;
62
62
  /**
63
- * 首行:
64
- * 节点名称 + 属性列表 + 换行
65
- * <headerLine> ::= <attributeList> NEWLINE
63
+ * 1. 快照
64
+ * 2. 跳过 行内模板片段
65
+ * 3. 准备
66
+ * 1. tokenizer
67
+ * 2. 快照
68
+ * 3. 使用 CtxProvider 中 数据作为 data
66
69
  */
67
- headerLine(_node: any): void;
70
+ inlineFragment(_node: any, snapshot: Partial<Tokenizer>, data: any, key?: string): void;
68
71
  /**
69
72
  * 属性列表:
70
73
  * 可以是空的,或者包含多个属性
@@ -75,7 +78,7 @@ declare class Interpreter {
75
78
  * 1. 普通节点 执行 setProps 🪝
76
79
  * 2. 组件节点 收集映射关系,或 产生 computed
77
80
  */
78
- attributeList(_node: any): void;
81
+ attributeList(_node: any, data: any): string;
79
82
  config(opt: TerpConf): void;
80
83
  createNode(name: string): {
81
84
  name: string;
@@ -96,6 +99,14 @@ declare class Interpreter {
96
99
  Effect: typeof Effect;
97
100
  effect: typeof effect$1;
98
101
  }
102
+ declare class InlineFragment {
103
+ snapshot: Partial<Tokenizer>;
104
+ data: any;
105
+ key: string;
106
+ tokenizer: Tokenizer;
107
+ [Keys.ProxyFreeObject]: boolean;
108
+ constructor(snapshot: Partial<Tokenizer>, data: any, key: string, tokenizer: Tokenizer);
109
+ }
99
110
 
100
111
  interface StackNode<T> {
101
112
  value: T;
@@ -226,9 +237,11 @@ type ProgramCtx = {
226
237
  before: any;
227
238
  };
228
239
  /** 返回值是用户自定义的节点 */
229
- type BobeUI = {
240
+ type UI<T = any> = {
230
241
  /** 在哪个 Store 声明的 */
231
242
  boundStore: Store;
243
+ /** 用户声明片段内可用的 props */
244
+ defineProps?: T;
232
245
  (isSub: boolean): Tokenizer;
233
246
  };
234
247
  type LogicNode = {
@@ -277,6 +290,10 @@ type FragmentNode$1 = LogicNode & {
277
290
  };
278
291
  type ComponentNode$1 = LogicNode & {
279
292
  tokenizer: Tokenizer;
293
+ /** 模版片段快照 */
294
+ fragmentSnapshot?: ReturnType<Tokenizer['snapshot']>;
295
+ /** 渲染模版片段前的 快照,渲染完成后用于恢复 */
296
+ resumeSnapshot?: ReturnType<Tokenizer['snapshot']>;
280
297
  };
281
298
  type Dep = Signal | Computed | (() => any) | string;
282
299
 
@@ -320,19 +337,22 @@ declare class Tokenizer {
320
337
  /** 当前文件路径 */
321
338
  source: string;
322
339
  constructor(hook: Hook, useDedentAsEof: boolean);
340
+ initIndentWhenUseDedentAsEof(): void;
323
341
  private next;
324
342
  getCurrentPos(): Position;
325
343
  /** 构造从当前扫描起始位置到模板结尾的 SourceLocation,用于未闭合错误 */
326
344
  private unclosedLoc;
327
345
  private throwUnclosed;
328
- resume(_snapshot: ReturnType<Tokenizer['snapshot']>): void;
329
- snapshot(keys?: (keyof Tokenizer)[]): Partial<Tokenizer>;
330
- skip(): string;
346
+ resume({ dentStack, waitingTokens, ..._snapshot }: ReturnType<Tokenizer['snapshot']>): void;
347
+ snapshot(keys?: (keyof Tokenizer)[], dtI?: number): Partial<Tokenizer>;
348
+ skip(targetDentLen?: number): string;
331
349
  setCode(code: string): void;
332
350
  tokenize(): void;
333
351
  isEof(): boolean;
334
352
  private setToken;
335
353
  nextToken(): Token;
354
+ locStart(): void;
355
+ locEnd(): void;
336
356
  getComment(): string;
337
357
  /**
338
358
  * 处理处于行末尾的 comment 例如:
@@ -428,7 +448,7 @@ interface Property extends BaseNode {
428
448
  type PropertyValue = StaticValue | DynamicValue;
429
449
  interface StaticValue extends BaseNode {
430
450
  type: NodeType.StaticValue;
431
- value: string | number | boolean;
451
+ value: string | number | boolean | TemplateNode[];
432
452
  }
433
453
  interface PropertyKeyNode extends BaseNode {
434
454
  type: NodeType.PropertyKey;
@@ -503,6 +523,8 @@ declare class Compiler {
503
523
  */
504
524
  private attributeList;
505
525
  parseProperty(node?: Property): Property;
526
+ handleOnlyKeyLoc(node: Property): void;
527
+ handleKeyValueLoc(node: Property): void;
506
528
  /**
507
529
  * 根据值类型创建属性 key 节点
508
530
  */
@@ -515,6 +537,7 @@ declare class Compiler {
515
537
  * 根据值类型创建属性值节点
516
538
  */
517
539
  parsePropertyValue(node?: PropertyValue): PropertyValue;
540
+ parsePropertyInlineFragment(node?: PropertyValue): PropertyValue;
518
541
  /**
519
542
  * 根据值类型创建名称
520
543
  */
@@ -532,7 +555,7 @@ type ParseHooks = Partial<{
532
555
  };
533
556
  }>;
534
557
 
535
- declare function bobe(fragments: TemplateStringsArray, ...values: any[]): BobeUI;
558
+ declare function bobe<T extends Record<any, any> = any>(fragments: TemplateStringsArray, ...values: any[]): UI<T>;
536
559
  declare function customRender(option: CustomRenderConf): <T>(Ctor: typeof Store, root: any) => (ComponentNode$1 | Store)[];
537
560
 
538
561
  type IContext = {
package/dist/index.umd.js CHANGED
@@ -107,10 +107,13 @@
107
107
  this.hook = hook;
108
108
  this.useDedentAsEof = useDedentAsEof;
109
109
  if (useDedentAsEof) {
110
- this.setToken(TokenType.Indent, '');
111
- this.isFirstToken = true;
110
+ this.initIndentWhenUseDedentAsEof();
112
111
  }
113
112
  }
113
+ initIndentWhenUseDedentAsEof() {
114
+ this.setToken(TokenType.Indent, '');
115
+ this.isFirstToken = true;
116
+ }
114
117
  next() {
115
118
  this.i++;
116
119
  }
@@ -140,16 +143,23 @@
140
143
  throwUnclosed(code, message, startOffset, startLine, startCol) {
141
144
  throw new ParseSyntaxError(code, message, this.unclosedLoc(startOffset, startLine, startCol));
142
145
  }
143
- resume(_snapshot) {
146
+ resume({
147
+ dentStack,
148
+ waitingTokens,
149
+ ..._snapshot
150
+ }) {
144
151
  this.token = undefined;
145
152
  this.needIndent = false;
146
153
  this.isFirstToken = true;
147
- this.dentStack = [0];
154
+ this.dentStack = dentStack ? dentStack.slice() : [0];
155
+ if (waitingTokens) {
156
+ this.waitingTokens = waitingTokens.clone();
157
+ }
148
158
  Object.assign(this, _snapshot);
149
159
  }
150
- snapshot(keys) {
160
+ snapshot(keys, dtI = 0) {
151
161
  const snap = {
152
- i: this.i,
162
+ i: this.i + dtI,
153
163
  waitingTokens: this.waitingTokens.clone()
154
164
  };
155
165
  if (keys) {
@@ -162,8 +172,10 @@
162
172
  }
163
173
  return snap;
164
174
  }
165
- skip() {
166
- const logicDentLen = this.dentStack[this.dentStack.length - 1];
175
+ skip(targetDentLen) {
176
+ if (targetDentLen == undefined) {
177
+ targetDentLen = this.dentStack[this.dentStack.length - 1];
178
+ }
167
179
  let needIndent = false;
168
180
  let skipFragment = ``;
169
181
  this.token = undefined;
@@ -186,7 +198,7 @@
186
198
  isEmptyLine = _this$getDentValue.isEmptyLine;
187
199
  const currLen = value.length;
188
200
  if (isEmptyLine) continue;
189
- if (currLen > logicDentLen) {
201
+ if (currLen > targetDentLen) {
190
202
  skipFragment += value;
191
203
  } else {
192
204
  for (let i = this.dentStack.length - 1; i >= 0; i--) {
@@ -199,6 +211,9 @@
199
211
  break;
200
212
  }
201
213
  this.dentStack.pop();
214
+ if (expLen > targetDentLen) {
215
+ continue;
216
+ }
202
217
  if (!this.token) {
203
218
  this.setToken(TokenType.Dedent, String(expLen));
204
219
  } else {
@@ -253,29 +268,31 @@
253
268
  }
254
269
  outer: while (1) {
255
270
  if (this.needIndent) {
271
+ this.locStart();
256
272
  this.dent();
273
+ this.locEnd();
257
274
  } else {
258
275
  const char = this.code[this.i];
259
276
  switch (char) {
260
277
  case '\t':
261
278
  case ' ':
262
279
  break;
263
- case '\n':
264
- this.newLine();
265
- this.needIndent = true;
266
- break;
267
- case '=':
268
- this.assignment();
269
- break;
270
- case '|':
271
- this.pipe();
272
- break;
273
- case ';':
274
- this.setToken(TokenType.Semicolon, ';');
275
- break;
276
280
  default:
277
- if (false) ;
281
+ this.locStart();
278
282
  switch (char) {
283
+ case '\n':
284
+ this.newLine();
285
+ this.needIndent = true;
286
+ break;
287
+ case '=':
288
+ this.assignment();
289
+ break;
290
+ case '|':
291
+ this.pipe();
292
+ break;
293
+ case ';':
294
+ this.setToken(TokenType.Semicolon, ';');
295
+ break;
279
296
  case '/':
280
297
  this.comment();
281
298
  break;
@@ -300,7 +317,7 @@
300
317
  }
301
318
  break;
302
319
  }
303
- if (false) ;
320
+ this.locEnd();
304
321
  break;
305
322
  }
306
323
  this.next();
@@ -316,6 +333,10 @@
316
333
  this.handledTokens.push(this.token);
317
334
  }
318
335
  }
336
+ locStart() {
337
+ }
338
+ locEnd() {
339
+ }
319
340
  getComment() {
320
341
  let value = '/';
321
342
  let nextC = this.code[this.i + 1];
@@ -332,6 +353,7 @@
332
353
  this.getComment();
333
354
  }
334
355
  condExp() {
356
+ this.locStart();
335
357
  let value = '';
336
358
  this.token = null;
337
359
  let char = this.code[this.i];
@@ -346,12 +368,14 @@
346
368
  const trimmed = value.replace(/\/\/[\s\S]+/, '').trim();
347
369
  this.setToken(TokenType.Identifier, trimmed ? trimmed : true, 0);
348
370
  this.handledTokens.push(this.token);
371
+ this.locEnd();
349
372
  return this.token;
350
373
  }
351
374
  isEol(i) {
352
375
  return this.code[i] === '\n' || this.code[i] === '/';
353
376
  }
354
377
  jsExp() {
378
+ this.locStart();
355
379
  this.token = null;
356
380
  let value = '';
357
381
  let char = this.code[this.i];
@@ -365,6 +389,7 @@
365
389
  }
366
390
  this.setToken(TokenType.Identifier, value, 0);
367
391
  this.handledTokens.push(this.token);
392
+ this.locEnd();
368
393
  return this.token;
369
394
  }
370
395
  peekChar() {
@@ -552,7 +577,7 @@
552
577
  const prevLen = this.dentStack[this.dentStack.length - 1];
553
578
  if (currLen > prevLen) {
554
579
  this.dentStack.push(currLen);
555
- this.setToken(TokenType.Indent, currLen);
580
+ this.setToken(TokenType.Indent, currLen, 0);
556
581
  return indentHasLen;
557
582
  }
558
583
  if (currLen < prevLen) {
@@ -567,7 +592,7 @@
567
592
  }
568
593
  this.dentStack.pop();
569
594
  if (!this.token) {
570
- this.setToken(TokenType.Dedent, String(expLen));
595
+ this.setToken(TokenType.Dedent, String(expLen), 0);
571
596
  } else {
572
597
  this.waitingTokens.push({
573
598
  type: TokenType.Dedent,
@@ -976,7 +1001,7 @@
976
1001
  let _initProto;
977
1002
  class Compiler {
978
1003
  static {
979
- var _applyDecs$e = _slicedToArray(_applyDecs2311(this, [], [[NodeHook, 2, "parseProgram"], [[NodeHook, NodeLoc], 2, "parseComponentNode"], [[NodeHook, NodeLoc], 2, "parseElementNode"], [[NodeHook, NodeLoc], 2, "parseConditionalNode"], [[NodeHook, NodeLoc], 2, "parseLoopNode"], [NodeHook, 2, "parseProperty"], [[NodeHook, TokenLoc], 2, "parsePropertyKey"], [[NodeHook, TokenLoc], 2, "parseJsExp"], [[NodeHook, TokenLoc], 2, "parsePropertyValue"], [[NodeHook, TokenLoc], 2, "parseName"]]).e, 1);
1004
+ var _applyDecs$e = _slicedToArray(_applyDecs2311(this, [], [[NodeHook, 2, "parseProgram"], [[NodeHook, NodeLoc], 2, "parseComponentNode"], [[NodeHook, NodeLoc], 2, "parseElementNode"], [[NodeHook, NodeLoc], 2, "parseConditionalNode"], [[NodeHook, NodeLoc], 2, "parseLoopNode"], [NodeHook, 2, "parseProperty"], [[NodeHook, TokenLoc], 2, "parsePropertyKey"], [[NodeHook, TokenLoc], 2, "parseJsExp"], [[NodeHook, TokenLoc], 2, "parsePropertyValue"], [[NodeHook, NodeLoc], 2, "parsePropertyInlineFragment"], [[NodeHook, TokenLoc], 2, "parseName"]]).e, 1);
980
1005
  _initProto = _applyDecs$e[0];
981
1006
  }
982
1007
  errors = (_initProto(this), []);
@@ -1078,9 +1103,9 @@
1078
1103
  parseComponentNode(node) {
1079
1104
  const name = this.parseName();
1080
1105
  this.tokenizer.nextToken();
1081
- const props = this.headerLineAndExtensions();
1082
1106
  node.type = NodeType.Component;
1083
1107
  node.componentName = name;
1108
+ const props = this.headerLineAndExtensions();
1084
1109
  node.props = props;
1085
1110
  this.hooks.parseComponentNode?.propsAdded?.call(this, node);
1086
1111
  const children = this.handleChildren();
@@ -1098,9 +1123,9 @@
1098
1123
  }
1099
1124
  const tagName = tagToken.value;
1100
1125
  this.tokenizer.nextToken();
1101
- const props = this.headerLineAndExtensions();
1102
1126
  node.type = NodeType.Element;
1103
1127
  node.tagName = tagName;
1128
+ const props = this.headerLineAndExtensions();
1104
1129
  node.props = props;
1105
1130
  this.hooks.parseElementNode?.propsAdded?.call(this, node);
1106
1131
  const children = this.handleChildren();
@@ -1174,17 +1199,17 @@
1174
1199
  }
1175
1200
  headerLineAndExtensions() {
1176
1201
  const props = [];
1177
- props.push(...this.attributeList());
1178
- if (this.tokenizer.token.type & TokenType.NewLine) {
1179
- this.tokenizer.nextToken();
1180
- }
1181
- while (this.tokenizer.token.type & TokenType.Pipe) {
1182
- this.tokenizer.nextToken();
1202
+ do {
1183
1203
  props.push(...this.attributeList());
1184
1204
  if (this.tokenizer.token.type & TokenType.NewLine) {
1185
1205
  this.tokenizer.nextToken();
1186
1206
  }
1187
- }
1207
+ if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
1208
+ break;
1209
+ } else {
1210
+ this.tokenizer.nextToken();
1211
+ }
1212
+ } while (true);
1188
1213
  return props;
1189
1214
  }
1190
1215
  attributeList() {
@@ -1208,25 +1233,35 @@
1208
1233
  const token = this.tokenizer.nextToken();
1209
1234
  if (token.value !== '=') {
1210
1235
  this.addError(ParseErrorCode.MISSING_ASSIGN, `属性 "${node.key.key}" 缺少 "=" 赋值符号`, node.key.loc ?? this.tokenizer.emptyLoc(), node);
1211
- node.loc.start = node.key.loc.start;
1212
- node.loc.end = node.key.loc.end;
1213
- node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1236
+ this.handleOnlyKeyLoc(node);
1214
1237
  return node;
1215
1238
  }
1216
1239
  const valueToken = this.tokenizer.nextToken();
1240
+ if (valueToken.type & TokenType.NewLine) {
1241
+ this.tokenizer.nextToken();
1242
+ node.value = this.parsePropertyInlineFragment();
1243
+ this.handleKeyValueLoc(node);
1244
+ return node;
1245
+ }
1217
1246
  if ((valueToken.type & ValueTokenType) === 0) {
1218
1247
  this.addError(ParseErrorCode.MISSING_PROP_ASSIGNMENT, `属性值不合法, "${valueToken.value}" 不合法`, valueToken.loc ?? this.tokenizer.emptyLoc(), node);
1219
- node.loc.start = node.key.loc.start;
1220
- node.loc.end = node.key.loc.end;
1221
- node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1248
+ this.handleOnlyKeyLoc(node);
1222
1249
  return node;
1223
1250
  }
1224
1251
  node.value = this.parsePropertyValue();
1225
1252
  this.tokenizer.nextToken();
1253
+ this.handleKeyValueLoc(node);
1254
+ return node;
1255
+ }
1256
+ handleOnlyKeyLoc(node) {
1257
+ node.loc.start = node.key.loc.start;
1258
+ node.loc.end = node.key.loc.end;
1259
+ node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1260
+ }
1261
+ handleKeyValueLoc(node) {
1226
1262
  node.loc.start = node.key.loc.start;
1227
1263
  node.loc.end = node.value.loc.end;
1228
1264
  node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1229
- return node;
1230
1265
  }
1231
1266
  parsePropertyKey(node) {
1232
1267
  node.type = NodeType.PropertyKey;
@@ -1251,6 +1286,12 @@
1251
1286
  node.value = value;
1252
1287
  return node;
1253
1288
  }
1289
+ parsePropertyInlineFragment(node) {
1290
+ const list = this.handleChildren();
1291
+ node.type = NodeType.StaticValue;
1292
+ node.value = list;
1293
+ return node;
1294
+ }
1254
1295
  parseName(node) {
1255
1296
  const _this$tokenizer$_hook7 = this.tokenizer._hook({}),
1256
1297
  _this$tokenizer$_hook8 = _slicedToArray(_this$tokenizer$_hook7, 2),
@@ -1474,6 +1515,9 @@
1474
1515
  }
1475
1516
  if (sort & NodeSort.TokenizerSwitcher) {
1476
1517
  const switcher = stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
1518
+ if (parent.resumeSnapshot) {
1519
+ this.tokenizer.resume(parent.resumeSnapshot);
1520
+ }
1477
1521
  this.tokenizer = switcher.tokenizer;
1478
1522
  }
1479
1523
  if (parent.__logicType === FakeType.ForItem) {
@@ -1568,7 +1612,7 @@
1568
1612
  } else {
1569
1613
  const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
1570
1614
  const val = data[aoye.Keys.Raw][value];
1571
- if (typeof val === 'function') {
1615
+ if (typeof val === 'function' || val instanceof InlineFragment) {
1572
1616
  _node = this.componentOrFragmentDeclaration(val, ctx);
1573
1617
  } else {
1574
1618
  const str = valueIsMapKey ? value : this.getFn(data, value);
@@ -1580,11 +1624,15 @@
1580
1624
  _node = this.createNode(value);
1581
1625
  }
1582
1626
  this.tokenizer.nextToken();
1583
- this.headerLine(_node);
1584
- this.extensionLines(_node);
1627
+ this.headerLineAndExtensions(_node);
1585
1628
  this.onePropParsed = this.oneRealPropParsed;
1586
1629
  if (_node.__logicType & TokenizerSwitcherBit) {
1587
1630
  this.tokenizer = _node.tokenizer;
1631
+ if (_node.fragmentSnapshot) {
1632
+ this.tokenizer.resume(_node.fragmentSnapshot);
1633
+ this.tokenizer.useDedentAsEof = true;
1634
+ this.tokenizer.initIndentWhenUseDedentAsEof();
1635
+ }
1588
1636
  }
1589
1637
  return _node;
1590
1638
  }
@@ -1960,16 +2008,25 @@
1960
2008
  }
1961
2009
  oneRealPropParsed = this.onePropParsed.bind(this);
1962
2010
  componentOrFragmentDeclaration(ComponentOrRender, ctx) {
1963
- let Component, render, child;
2011
+ let Component, tokenizer, child, fragmentSnapshot, resumeSnapshot;
1964
2012
  const isCC = ComponentOrRender.prototype instanceof aoye.Store;
1965
2013
  if (isCC) {
1966
2014
  Component = ComponentOrRender;
1967
2015
  child = Component.new();
2016
+ tokenizer = child.ui(true);
2017
+ } else if (ComponentOrRender instanceof InlineFragment) {
2018
+ const conf = ComponentOrRender;
2019
+ child = aoye.deepSignal({}, aoye.getPulling(), true);
2020
+ Object.setPrototypeOf(child, conf.data);
2021
+ tokenizer = conf.tokenizer;
2022
+ fragmentSnapshot = conf.snapshot;
2023
+ resumeSnapshot = tokenizer.snapshot(['token', 'needIndent', 'isFirstToken', 'dentStack', 'isFirstToken', 'useDedentAsEof']);
1968
2024
  } else {
1969
- render = ComponentOrRender;
2025
+ const render = ComponentOrRender;
1970
2026
  const boundStore = render.boundStore;
1971
2027
  child = aoye.deepSignal({}, aoye.getPulling(), true);
1972
2028
  Object.setPrototypeOf(child, boundStore);
2029
+ tokenizer = render(true);
1973
2030
  }
1974
2031
  const node = {
1975
2032
  __logicType: isCC ? FakeType.Component : FakeType.Fragment,
@@ -1977,7 +2034,9 @@
1977
2034
  realBefore: null,
1978
2035
  realAfter: null,
1979
2036
  data: child,
1980
- tokenizer: render ? render(true) : child.ui(true)
2037
+ tokenizer,
2038
+ fragmentSnapshot,
2039
+ resumeSnapshot
1981
2040
  };
1982
2041
  this.onePropParsed = createStoreOnePropParsed(child);
1983
2042
  node.realAfter = this.insertAfterAnchor('component-after');
@@ -2114,26 +2173,38 @@
2114
2173
  point = next;
2115
2174
  }
2116
2175
  }
2117
- extensionLines(_node) {
2118
- while (1) {
2119
- if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
2120
- return;
2176
+ headerLineAndExtensions(_node) {
2177
+ const tokenizer = this.tokenizer;
2178
+ do {
2179
+ const isComponent = _node.__logicType & TokenizerSwitcherBit;
2180
+ let snapshot, dentLen;
2181
+ const data = this.getData();
2182
+ const unHandledKey = this.attributeList(_node, data);
2183
+ if (isComponent) {
2184
+ snapshot = tokenizer.snapshot(undefined, -1);
2185
+ dentLen = tokenizer.dentStack[tokenizer.dentStack.length - 1];
2121
2186
  }
2122
- this.tokenizer.nextToken();
2123
- this.attributeList(_node);
2124
- if ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
2125
- return;
2187
+ tokenizer.nextToken();
2188
+ if ((tokenizer.token.type & TokenType.Pipe) === 0) {
2189
+ if (isComponent && tokenizer.token.type & TokenType.Indent) {
2190
+ this.inlineFragment(_node, snapshot, data, unHandledKey);
2191
+ tokenizer.skip(dentLen);
2192
+ if ((tokenizer.token.type & TokenType.Pipe) === 0) {
2193
+ break;
2194
+ }
2195
+ } else {
2196
+ break;
2197
+ }
2126
2198
  }
2127
- this.tokenizer.nextToken();
2128
- }
2199
+ tokenizer.nextToken();
2200
+ } while (true);
2129
2201
  }
2130
- headerLine(_node) {
2131
- this.attributeList(_node);
2132
- this.tokenizer.nextToken();
2202
+ inlineFragment(_node, snapshot, data, key = 'children') {
2203
+ const value = new InlineFragment(snapshot, data, key, this.tokenizer);
2204
+ this.onePropParsed(data, _node, key, value, false, true);
2133
2205
  }
2134
- attributeList(_node) {
2206
+ attributeList(_node, data) {
2135
2207
  let key, eq;
2136
- const data = this.getData();
2137
2208
  while ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
2138
2209
  if (key == null) {
2139
2210
  key = this.tokenizer.token.value;
@@ -2181,6 +2252,7 @@
2181
2252
  }
2182
2253
  this.tokenizer.nextToken();
2183
2254
  }
2255
+ return key;
2184
2256
  }
2185
2257
  config(opt) {
2186
2258
  Object.assign(this, opt);
@@ -2264,6 +2336,15 @@
2264
2336
  };
2265
2337
  return onePropParsed;
2266
2338
  }
2339
+ class InlineFragment {
2340
+ [aoye.Keys.ProxyFreeObject] = true;
2341
+ constructor(snapshot, data, key, tokenizer) {
2342
+ this.snapshot = snapshot;
2343
+ this.data = data;
2344
+ this.key = key;
2345
+ this.tokenizer = tokenizer;
2346
+ }
2347
+ }
2267
2348
 
2268
2349
  function bobe(fragments, ...values) {
2269
2350
  const ui = function ui(isSub) {