@vue/compiler-sfc 3.6.0-beta.15 → 3.6.0-beta.17

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @vue/compiler-sfc v3.6.0-beta.15
2
+ * @vue/compiler-sfc v3.6.0-beta.17
3
3
  * (c) 2018-present Yuxi (Evan) You and Vue contributors
4
4
  * @license MIT
5
5
  **/
@@ -18394,7 +18394,7 @@ function mergeSourceMaps(scriptMap, templateMap, templateLineOffset) {
18394
18394
  }
18395
18395
  //#endregion
18396
18396
  //#region packages/compiler-sfc/src/index.ts
18397
- const version = "3.6.0-beta.15";
18397
+ const version = "3.6.0-beta.17";
18398
18398
  const parseCache = parseCache$1;
18399
18399
  const errorMessages = {
18400
18400
  ..._vue_compiler_dom.errorMessages,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @vue/compiler-sfc v3.6.0-beta.15
2
+ * @vue/compiler-sfc v3.6.0-beta.17
3
3
  * (c) 2018-present Yuxi (Evan) You and Vue contributors
4
4
  * @license MIT
5
5
  **/
@@ -24908,6 +24908,7 @@ function getBlockShape(block) {
24908
24908
  //#endregion
24909
24909
  //#region packages/compiler-vapor/src/transform.ts
24910
24910
  const generatedVarRE = /^[nxr](\d+)$/;
24911
+ const childContextInfoCache = /* @__PURE__ */ new WeakMap();
24911
24912
  var TransformContext = class TransformContext {
24912
24913
  constructor(ir, node, options = {}) {
24913
24914
  this.ir = ir;
@@ -24933,6 +24934,7 @@ var TransformContext = class TransformContext {
24933
24934
  this.operationIndex = this.block.operation.length;
24934
24935
  this.isLastEffectiveChild = true;
24935
24936
  this.isOnRightmostPath = true;
24937
+ this.isSingleRoot = false;
24936
24938
  this.templateCloseTags = void 0;
24937
24939
  this.templateCloseBlocks = false;
24938
24940
  this.globalId = 0;
@@ -25058,8 +25060,10 @@ var TransformContext = class TransformContext {
25058
25060
  create(node, index) {
25059
25061
  let effectiveParent = this;
25060
25062
  while (effectiveParent && effectiveParent.node.type === 1 && effectiveParent.node.tagType === 3) effectiveParent = effectiveParent.parent;
25061
- const isLastEffectiveChild = this.isEffectivelyLastChild(index);
25063
+ const childInfo = this.getChildContextInfo();
25064
+ const isLastEffectiveChild = childInfo.isLastEffectiveChild[index];
25062
25065
  const isOnRightmostPath = this.isOnRightmostPath && isLastEffectiveChild;
25066
+ const isSingleRoot = this.isSingleRootChild(childInfo);
25063
25067
  return Object.assign(Object.create(TransformContext.prototype), this, {
25064
25068
  node,
25065
25069
  parent: this,
@@ -25074,6 +25078,7 @@ var TransformContext = class TransformContext {
25074
25078
  effectiveParent,
25075
25079
  isLastEffectiveChild,
25076
25080
  isOnRightmostPath,
25081
+ isSingleRoot,
25077
25082
  templateCloseTags: this.templateCloseTags,
25078
25083
  templateCloseBlocks: this.templateCloseBlocks
25079
25084
  });
@@ -25083,12 +25088,59 @@ var TransformContext = class TransformContext {
25083
25088
  if (operation && isBlockOperation(operation) && operation.effectIndex !== void 0 && operation.effectIndex >= index) operation.effectIndex++;
25084
25089
  for (const child of dynamic.children) this.shiftEffectBoundaries(index, child);
25085
25090
  }
25086
- isEffectivelyLastChild(index) {
25087
- const children = this.node.children;
25088
- if (!children) return true;
25089
- return children.every((c, i) => i <= index || c.type === 1 && c.tagType === 1);
25091
+ getChildContextInfo() {
25092
+ const node = this.node;
25093
+ if (node.type !== 0 && node.type !== 1) return {
25094
+ node,
25095
+ hasSingleRootChild: true,
25096
+ isLastEffectiveChild: []
25097
+ };
25098
+ const cached = childContextInfoCache.get(this);
25099
+ if (cached && cached.node === node) return cached;
25100
+ const { children } = node;
25101
+ const isLastEffectiveChild = new Array(children.length);
25102
+ let hasFollowingEffectiveChild = false;
25103
+ for (let i = children.length - 1; i >= 0; i--) {
25104
+ isLastEffectiveChild[i] = !hasFollowingEffectiveChild;
25105
+ if (!isComponentChild(children[i])) hasFollowingEffectiveChild = true;
25106
+ }
25107
+ const childInfo = {
25108
+ node,
25109
+ hasSingleRootChild: hasSingleRootChild(children),
25110
+ isLastEffectiveChild
25111
+ };
25112
+ childContextInfoCache.set(this, childInfo);
25113
+ return childInfo;
25114
+ }
25115
+ isSingleRootChild(childInfo) {
25116
+ if (this.inVFor || !childInfo.hasSingleRootChild) return false;
25117
+ if (this.node.type === 0) return true;
25118
+ return this.node.type === 1 && this.node.tagType === 3 && !!this.parent && this.isSingleRoot;
25090
25119
  }
25091
25120
  };
25121
+ function hasSingleRootChild(children) {
25122
+ let nonCommentChildren = 0;
25123
+ let hasEncounteredIf = false;
25124
+ let isSingleIfBlock = true;
25125
+ for (const child of children) {
25126
+ if (isCommentOrWhitespace(child)) continue;
25127
+ nonCommentChildren++;
25128
+ if (isIfChild(child)) {
25129
+ if (hasEncounteredIf) isSingleIfBlock = false;
25130
+ hasEncounteredIf = true;
25131
+ } else if (!hasEncounteredIf || !isElseChild(child)) isSingleIfBlock = false;
25132
+ }
25133
+ return nonCommentChildren === 1 || isSingleIfBlock;
25134
+ }
25135
+ function isComponentChild(child) {
25136
+ return child.type === 1 && child.tagType === 1;
25137
+ }
25138
+ function isIfChild(child) {
25139
+ return child.type === 9 || child.type === 1 && !!findDir$1(child, "if");
25140
+ }
25141
+ function isElseChild(child) {
25142
+ return child.type === 1 && !!findDir$1(child, /^else(-if)?$/, true);
25143
+ }
25092
25144
  const defaultOptions = {
25093
25145
  filename: "",
25094
25146
  prefixIdentifiers: true,
@@ -25350,6 +25402,8 @@ init_objectSpread2();
25350
25402
  function genExpression(node, context, assignment) {
25351
25403
  node = context.getExpressionReplacement(node);
25352
25404
  const { content, ast, isStatic, loc } = node;
25405
+ const { options } = context;
25406
+ const { inline } = options;
25353
25407
  if (isStatic) return [[
25354
25408
  JSON.stringify(content),
25355
25409
  -2,
@@ -25371,23 +25425,31 @@ function genExpression(node, context, assignment) {
25371
25425
  let hasMemberExpression = false;
25372
25426
  if (ids.length) {
25373
25427
  const [frag, push] = buildCodeFragment();
25374
- ids.sort((a, b) => a.start - b.start).forEach((id, i) => {
25375
- const start = id.start - 1;
25376
- const end = id.end - 1;
25377
- const last = ids[i - 1];
25378
- const leadingText = content.slice(last ? last.end - 1 : 0, start);
25379
- if (leadingText.length) push([leadingText, -3]);
25380
- const source = content.slice(start, end);
25428
+ let lastEnd = 0;
25429
+ ids.sort((a, b) => a.start - b.start).forEach((id) => {
25430
+ const idStart = id.start - 1;
25431
+ const idEnd = id.end - 1;
25432
+ const source = content.slice(idStart, idEnd);
25381
25433
  const parentStack = parentStackMap.get(id);
25382
25434
  const parent = parentStack[parentStack.length - 1];
25435
+ let start = idStart;
25436
+ let end = idEnd;
25437
+ if (inline && options.bindingMetadata && options.bindingMetadata[source] === "setup-let" && parent && parent.type === "UpdateExpression" && parent.argument === id) {
25438
+ start = parent.start - 1;
25439
+ end = parent.end - 1;
25440
+ }
25441
+ if (start < lastEnd) return;
25442
+ const leadingText = content.slice(lastEnd, start);
25443
+ if (leadingText.length) push([leadingText, -3]);
25383
25444
  hasMemberExpression || (hasMemberExpression = parent && (parent.type === "MemberExpression" || parent.type === "OptionalMemberExpression"));
25384
25445
  push(...genIdentifier(source, context, {
25385
25446
  start: advancePositionWithClone(node.loc.start, source, start),
25386
25447
  end: advancePositionWithClone(node.loc.start, source, end),
25387
25448
  source
25388
- }, hasMemberExpression ? void 0 : assignment, id, parent, parentStack));
25389
- if (i === ids.length - 1 && end < content.length) push([content.slice(end), -3]);
25449
+ }, hasMemberExpression ? void 0 : assignment, id, parent, parentStack, node));
25450
+ lastEnd = end;
25390
25451
  });
25452
+ if (lastEnd < content.length) push([content.slice(lastEnd), -3]);
25391
25453
  if (assignment && hasMemberExpression) push(` = ${assignment}`);
25392
25454
  return frag;
25393
25455
  } else return [[
@@ -25396,7 +25458,7 @@ function genExpression(node, context, assignment) {
25396
25458
  loc
25397
25459
  ]];
25398
25460
  }
25399
- function genIdentifier(raw, context, loc, assignment, id, parent, parentStack) {
25461
+ function genIdentifier(raw, context, loc, assignment, id, parent, parentStack, sourceNode) {
25400
25462
  const { options, helper, identifiers } = context;
25401
25463
  const { inline, bindingMetadata } = options;
25402
25464
  let name = raw;
@@ -25416,19 +25478,49 @@ function genIdentifier(raw, context, loc, assignment, id, parent, parentStack) {
25416
25478
  else return genExpression(replacement, context, assignment);
25417
25479
  }
25418
25480
  let prefix;
25419
- if (isStaticProperty(parent) && parent.shorthand) prefix = `${raw}: `;
25420
25481
  const type = bindingMetadata && bindingMetadata[raw];
25482
+ const isDestructureAssignment = parent && isInDestructureAssignment(parent, parentStack || []);
25483
+ const isAssignmentLVal = parent && parent.type === "AssignmentExpression" && parent.left === id;
25484
+ const isUpdateArg = parent && parent.type === "UpdateExpression" && parent.argument === id;
25485
+ if (isStaticProperty(parent) && parent.shorthand && !(inline && type === "setup-let" && isDestructureAssignment)) prefix = `${raw}: `;
25421
25486
  if (inline) switch (type) {
25422
25487
  case "setup-let":
25423
- name = raw = assignment ? `_isRef(${raw}) ? (${raw}.value = ${assignment}) : (${raw} = ${assignment})` : unref();
25488
+ if (isAssignmentLVal) {
25489
+ const { right, operator } = parent;
25490
+ const source = sourceNode;
25491
+ const sourceContent = source.content;
25492
+ const rightStart = right.start - 1;
25493
+ const rightEnd = right.end - 1;
25494
+ const rightContent = sourceContent.slice(rightStart, rightEnd);
25495
+ const rightExp = createSimpleExpression(rightContent, false, {
25496
+ start: advancePositionWithClone(source.loc.start, sourceContent, rightStart),
25497
+ end: advancePositionWithClone(source.loc.start, sourceContent, rightEnd),
25498
+ source: rightContent
25499
+ });
25500
+ rightExp.ast = parseExp(context, rightContent);
25501
+ return [
25502
+ prefix,
25503
+ `${helper("isRef")}(${raw}) ? ${raw}.value ${operator} `,
25504
+ ...genExpression(rightExp, context),
25505
+ ` : `,
25506
+ [
25507
+ raw,
25508
+ -2,
25509
+ loc,
25510
+ name
25511
+ ]
25512
+ ];
25513
+ } else if (isUpdateArg) {
25514
+ const { prefix: isPrefix, operator } = parent;
25515
+ const updatePrefix = isPrefix ? operator : ``;
25516
+ const updatePostfix = isPrefix ? `` : operator;
25517
+ raw = `${helper("isRef")}(${raw}) ? ${updatePrefix}${raw}.value${updatePostfix} : ${updatePrefix}${raw}${updatePostfix}`;
25518
+ } else if (!isDestructureAssignment) name = raw = assignment ? `${helper("isRef")}(${raw}) ? (${raw}.value = ${assignment}) : (${raw} = ${assignment})` : unref();
25424
25519
  break;
25425
25520
  case "setup-ref":
25426
25521
  name = raw = withAssignment(`${raw}.value`);
25427
25522
  break;
25428
25523
  case "setup-maybe-ref":
25429
- const isDestructureAssignment = parent && isInDestructureAssignment(parent, parentStack || []);
25430
- const isAssignmentLVal = parent && parent.type === "AssignmentExpression" && parent.left === id;
25431
- const isUpdateArg = parent && parent.type === "UpdateExpression" && parent.argument === id;
25432
25524
  raw = isAssignmentLVal || isUpdateArg || isDestructureAssignment ? name = `${raw}.value` : assignment ? `${helper("isRef")}(${raw}) ? (${raw}.value = ${assignment}) : null` : unref();
25433
25525
  break;
25434
25526
  case "props":
@@ -25464,28 +25556,31 @@ function canPrefix(name) {
25464
25556
  }
25465
25557
  function processExpressions(context, expressions, shouldDeclare) {
25466
25558
  const expressionReplacements = /* @__PURE__ */ new Map();
25467
- const { seenVariable, variableToExpMap, expToVariableMap, seenIdentifier, updatedVariable } = analyzeExpressions(expressions);
25559
+ const { seenVariable, variableToExpMap, expressionRecords, seenIdentifier, updatedVariable } = analyzeExpressions(expressions);
25468
25560
  const reservedNames = new Set(seenIdentifier);
25469
- const varDeclarations = processRepeatedVariables(context, seenVariable, variableToExpMap, expToVariableMap, seenIdentifier, updatedVariable, reservedNames, expressionReplacements);
25470
- const expDeclarations = processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expToVariableMap, reservedNames, expressionReplacements);
25561
+ const varDeclarations = processRepeatedVariables(context, seenVariable, variableToExpMap, expressionRecords, seenIdentifier, updatedVariable, reservedNames, expressionReplacements);
25562
+ const expDeclarations = processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expressionRecords, reservedNames, expressionReplacements);
25471
25563
  return _objectSpread2(_objectSpread2({}, genDeclarations([...varDeclarations, ...expDeclarations], context, shouldDeclare)), {}, { expressionReplacements });
25472
25564
  }
25473
25565
  function analyzeExpressions(expressions) {
25474
25566
  const seenVariable = Object.create(null);
25475
25567
  const variableToExpMap = /* @__PURE__ */ new Map();
25476
- const expToVariableMap = /* @__PURE__ */ new Map();
25568
+ const expressionRecords = /* @__PURE__ */ new Map();
25477
25569
  const seenIdentifier = /* @__PURE__ */ new Set();
25478
25570
  const updatedVariable = /* @__PURE__ */ new Set();
25571
+ const getRecord = (exp) => {
25572
+ let record = expressionRecords.get(exp);
25573
+ if (!record) expressionRecords.set(exp, record = { variables: [] });
25574
+ return record;
25575
+ };
25479
25576
  const registerVariable = (name, exp, isIdentifier, loc, parentStack = []) => {
25480
25577
  if (isIdentifier) seenIdentifier.add(name);
25481
25578
  seenVariable[name] = (seenVariable[name] || 0) + 1;
25482
25579
  variableToExpMap.set(name, (variableToExpMap.get(name) || /* @__PURE__ */ new Set()).add(exp));
25483
- const variables = expToVariableMap.get(exp) || [];
25484
- variables.push({
25580
+ getRecord(exp).variables.push({
25485
25581
  name,
25486
25582
  loc
25487
25583
  });
25488
- expToVariableMap.set(exp, variables);
25489
25584
  if (parentStack.some((p) => p.type === "UpdateExpression" || p.type === "AssignmentExpression")) updatedVariable.add(name);
25490
25585
  };
25491
25586
  for (const exp of expressions) {
@@ -25522,7 +25617,7 @@ function analyzeExpressions(expressions) {
25522
25617
  seenVariable,
25523
25618
  seenIdentifier,
25524
25619
  variableToExpMap,
25525
- expToVariableMap,
25620
+ expressionRecords,
25526
25621
  updatedVariable
25527
25622
  };
25528
25623
  }
@@ -25532,9 +25627,10 @@ function getProcessedExpression(exp, expressionReplacements) {
25532
25627
  function setExpressionReplacement(expressionReplacements, exp, content, ast) {
25533
25628
  expressionReplacements.set(exp, extend({ ast }, createSimpleExpression(content, exp.isStatic, exp.loc, exp.constType)));
25534
25629
  }
25535
- function processRepeatedVariables(context, seenVariable, variableToExpMap, expToVariableMap, seenIdentifier, updatedVariable, reservedNames, expressionReplacements) {
25630
+ function processRepeatedVariables(context, seenVariable, variableToExpMap, expressionRecords, seenIdentifier, updatedVariable, reservedNames, expressionReplacements) {
25536
25631
  const declarations = [];
25537
- const expToReplacementMap = /* @__PURE__ */ new Map();
25632
+ const declaredNames = /* @__PURE__ */ new Set();
25633
+ const replacementPlan = /* @__PURE__ */ new Map();
25538
25634
  for (const [name, exps] of variableToExpMap) {
25539
25635
  if (updatedVariable.has(name)) continue;
25540
25636
  if (isGloballyAllowed(name)) continue;
@@ -25543,96 +25639,201 @@ function processRepeatedVariables(context, seenVariable, variableToExpMap, expTo
25543
25639
  const varName = isIdentifier ? name : getUniqueDeclarationName(genVarName(name), reservedNames);
25544
25640
  exps.forEach((node) => {
25545
25641
  if (node.ast && varName !== name) {
25546
- const replacements = expToReplacementMap.get(node) || [];
25547
- replacements.push({
25548
- name: varName,
25549
- locs: expToVariableMap.get(node).reduce((locs, v) => {
25550
- if (v.name === name && v.loc) locs.push(v.loc);
25551
- return locs;
25552
- }, [])
25642
+ for (const variable of getExpressionVariables(expressionRecords, node)) if (variable.name === name && variable.loc) queueContentReplacement(replacementPlan, node, {
25643
+ start: variable.loc.start - 1,
25644
+ end: variable.loc.end - 1,
25645
+ content: varName
25553
25646
  });
25554
- expToReplacementMap.set(node, replacements);
25555
25647
  }
25556
25648
  });
25557
- if (!declarations.some((d) => d.name === varName) && (!isIdentifier || shouldDeclareVariable(name, expToVariableMap, exps))) declarations.push({
25558
- name: varName,
25559
- isIdentifier,
25560
- value: extend({ ast: isIdentifier ? null : parseExp(context, name) }, createSimpleExpression(name)),
25561
- rawName: name,
25562
- exps,
25563
- seenCount: seenVariable[name]
25564
- });
25649
+ if (!declaredNames.has(varName) && (!isIdentifier || shouldDeclareVariable(name, expressionRecords, exps))) {
25650
+ declaredNames.add(varName);
25651
+ declarations.push({
25652
+ name: varName,
25653
+ isIdentifier,
25654
+ value: extend({ ast: isIdentifier ? null : parseExp(context, name) }, createSimpleExpression(name)),
25655
+ rawName: name,
25656
+ exps,
25657
+ seenCount: seenVariable[name]
25658
+ });
25659
+ }
25565
25660
  }
25566
25661
  }
25567
- for (const [exp, replacements] of expToReplacementMap) {
25568
- let content = getProcessedExpression(exp, expressionReplacements).content;
25569
- replacements.flatMap(({ name, locs }) => locs.map(({ start, end }) => ({
25570
- start,
25571
- end,
25572
- name
25573
- }))).sort((a, b) => b.end - a.end).forEach(({ start, end, name }) => {
25574
- content = content.slice(0, start - 1) + name + content.slice(end - 1);
25575
- });
25576
- setExpressionReplacement(expressionReplacements, exp, content, parseExp(context, content));
25577
- }
25662
+ applyReplacementPlan(context, expressionReplacements, replacementPlan);
25578
25663
  return declarations;
25579
25664
  }
25580
- function shouldDeclareVariable(name, expToVariableMap, exps) {
25581
- const vars = Array.from(exps, (exp) => expToVariableMap.get(exp).map((v) => v.name));
25582
- if (vars.every((v) => v.length === 1)) return true;
25583
- if (vars.some((v) => v.filter((e) => e === name).length > 1)) return true;
25584
- const first = vars[0];
25585
- if (vars.some((v) => v.length !== first.length)) {
25586
- if (vars.some((v) => v.length > first.length && v.every((e) => first.includes(e))) || vars.some((v) => first.length > v.length && first.every((e) => v.includes(e)))) return false;
25665
+ function shouldDeclareVariable(name, expressionRecords, exps) {
25666
+ const variableUsages = [];
25667
+ let allSingleVariable = true;
25668
+ let hasRepeatedName = false;
25669
+ let hasDifferentLength = false;
25670
+ outer: for (const exp of exps) {
25671
+ const variables = getExpressionVariables(expressionRecords, exp);
25672
+ if (allSingleVariable && variables.length !== 1) allSingleVariable = false;
25673
+ if (!hasDifferentLength && variableUsages.length > 0 && variables.length !== variableUsages[0].length) hasDifferentLength = true;
25674
+ let nameCount = 0;
25675
+ for (const variable of variables) if (variable.name === name && ++nameCount > 1) {
25676
+ hasRepeatedName = true;
25677
+ break outer;
25678
+ }
25679
+ variableUsages.push(variables);
25680
+ }
25681
+ if (allSingleVariable) return true;
25682
+ if (hasRepeatedName) return true;
25683
+ const first = variableUsages[0];
25684
+ if (hasDifferentLength) {
25685
+ for (const variables of variableUsages) {
25686
+ if (variables.length === first.length) continue;
25687
+ const longer = variables.length > first.length ? variables : first;
25688
+ const shorter = variables.length > first.length ? first : variables;
25689
+ const shorterNames = /* @__PURE__ */ new Set();
25690
+ for (const variable of shorter) shorterNames.add(variable.name);
25691
+ let isSubset = true;
25692
+ for (const variable of longer) if (!shorterNames.has(variable.name)) {
25693
+ isSubset = false;
25694
+ break;
25695
+ }
25696
+ if (isSubset) return false;
25697
+ }
25587
25698
  return true;
25588
25699
  }
25589
- if (vars.every((v) => v.every((e, idx) => e === first[idx]))) return false;
25590
- return true;
25700
+ for (const variables of variableUsages) for (let i = 0; i < variables.length; i++) if (variables[i].name !== first[i].name) return true;
25701
+ return false;
25591
25702
  }
25592
- function processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expToVariableMap, reservedNames, expressionReplacements) {
25703
+ function processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expressionRecords, reservedNames, expressionReplacements) {
25593
25704
  const declarations = [];
25594
- const seenExp = expressions.reduce((acc, exp) => {
25595
- const vars = expToVariableMap.get(exp);
25596
- if (!vars) return acc;
25705
+ const seenExp = /* @__PURE__ */ new Map();
25706
+ for (const exp of expressions) {
25707
+ var _expressionRecords$ge;
25708
+ const vars = (_expressionRecords$ge = expressionRecords.get(exp)) === null || _expressionRecords$ge === void 0 ? void 0 : _expressionRecords$ge.variables;
25709
+ if (!vars) continue;
25597
25710
  const processed = getProcessedExpression(exp, expressionReplacements);
25598
- const variables = vars.map((v) => v.name);
25599
- if (processed.ast && processed.ast.type !== "Identifier" && !(variables && variables.some((v) => updatedVariable.has(v))) && !variables.some((v) => isGloballyAllowed(v))) acc[processed.content] = (acc[processed.content] || 0) + 1;
25600
- return acc;
25601
- }, Object.create(null));
25602
- Object.entries(seenExp).forEach(([content, count]) => {
25603
- if (count > 1) {
25604
- const delVars = {};
25605
- for (let i = varDeclarations.length - 1; i >= 0; i--) {
25606
- const item = varDeclarations[i];
25607
- if (!item.exps || !item.seenCount) continue;
25608
- if ([...item.exps].every((node) => getProcessedExpression(node, expressionReplacements).content === content && item.seenCount === count)) {
25609
- delVars[item.name] = item.rawName;
25610
- reservedNames.delete(item.name);
25611
- varDeclarations.splice(i, 1);
25612
- }
25613
- }
25614
- const value = extend({}, getProcessedExpression(expressions.find((exp) => getProcessedExpression(exp, expressionReplacements).content === content), expressionReplacements));
25615
- Object.keys(delVars).forEach((name) => {
25616
- value.content = value.content.replace(name, delVars[name]);
25617
- if (value.ast) value.ast = parseExp(context, value.content);
25711
+ if (canCacheExpression(processed, vars, updatedVariable)) {
25712
+ const seen = seenExp.get(processed.content);
25713
+ if (seen) seen.count++;
25714
+ else seenExp.set(processed.content, {
25715
+ count: 1,
25716
+ first: exp
25618
25717
  });
25619
- const varName = getUniqueDeclarationName(genVarName(content), reservedNames);
25620
- declarations.push({
25621
- name: varName,
25622
- value
25623
- });
25624
- expressions.forEach((exp) => {
25625
- const processed = getProcessedExpression(exp, expressionReplacements);
25626
- if (processed.content === content) setExpressionReplacement(expressionReplacements, exp, varName, null);
25627
- else if (processed.content.includes(content)) {
25628
- const replacedContent = processed.content.replace(new RegExp(escapeRegExp(content), "g"), varName);
25718
+ }
25719
+ }
25720
+ const repeatedExpressions = [...seenExp].sort(([contentA], [contentB]) => contentB.length - contentA.length);
25721
+ for (const [content, { count, first }] of repeatedExpressions) if (count > 1) {
25722
+ const removedDeclarations = [];
25723
+ for (let i = varDeclarations.length - 1; i >= 0; i--) {
25724
+ const item = varDeclarations[i];
25725
+ if (!item.exps || !item.seenCount) continue;
25726
+ if ([...item.exps].every((node) => getProcessedExpression(node, expressionReplacements).content === content && item.seenCount === count)) {
25727
+ removedDeclarations.push({
25728
+ name: item.name,
25729
+ rawName: item.rawName
25730
+ });
25731
+ reservedNames.delete(item.name);
25732
+ varDeclarations.splice(i, 1);
25733
+ }
25734
+ }
25735
+ const value = extend({}, getProcessedExpression(first, expressionReplacements));
25736
+ const restorePlan = [];
25737
+ for (const { name, rawName } of removedDeclarations) restorePlan.push(...findIdentifierReplacements(value, name, rawName));
25738
+ if (restorePlan.length) {
25739
+ value.content = applyContentReplacements(value.content, restorePlan);
25740
+ if (value.ast) value.ast = parseExp(context, value.content);
25741
+ }
25742
+ const varName = getUniqueDeclarationName(genVarName(content), reservedNames);
25743
+ declarations.push({
25744
+ name: varName,
25745
+ value
25746
+ });
25747
+ for (const exp of expressions) {
25748
+ const processed = getProcessedExpression(exp, expressionReplacements);
25749
+ if (processed.content === content) setExpressionReplacement(expressionReplacements, exp, varName, null);
25750
+ else if (processed.content.includes(content)) {
25751
+ const replacements = findContentReplacements(processed, content, varName);
25752
+ if (replacements.length) {
25753
+ const replacedContent = applyContentReplacements(processed.content, replacements);
25629
25754
  setExpressionReplacement(expressionReplacements, exp, replacedContent, parseExp(context, replacedContent));
25630
25755
  }
25631
- });
25756
+ }
25632
25757
  }
25633
- });
25758
+ }
25634
25759
  return declarations;
25635
25760
  }
25761
+ function canCacheExpression(processed, vars, updatedVariable) {
25762
+ if (!processed.ast || processed.ast.type === "Identifier") return false;
25763
+ for (const { name } of vars) if (updatedVariable.has(name) || isGloballyAllowed(name)) return false;
25764
+ return true;
25765
+ }
25766
+ function getExpressionVariables(expressionRecords, exp) {
25767
+ var _expressionRecords$ge2;
25768
+ return ((_expressionRecords$ge2 = expressionRecords.get(exp)) === null || _expressionRecords$ge2 === void 0 ? void 0 : _expressionRecords$ge2.variables) || [];
25769
+ }
25770
+ function queueContentReplacement(replacementPlan, exp, replacement) {
25771
+ const replacements = replacementPlan.get(exp);
25772
+ if (replacements) replacements.push(replacement);
25773
+ else replacementPlan.set(exp, [replacement]);
25774
+ }
25775
+ function applyReplacementPlan(context, expressionReplacements, replacementPlan) {
25776
+ for (const [exp, replacements] of replacementPlan) {
25777
+ if (!replacements.length) continue;
25778
+ const content = applyContentReplacements(getProcessedExpression(exp, expressionReplacements).content, replacements);
25779
+ setExpressionReplacement(expressionReplacements, exp, content, parseExp(context, content));
25780
+ }
25781
+ }
25782
+ function findContentReplacements(exp, content, replacement) {
25783
+ const identifiers = getIdentifierRanges(exp);
25784
+ if (!identifiers.length) return [];
25785
+ const replacements = [];
25786
+ let searchStart = 0;
25787
+ let start = exp.content.indexOf(content, searchStart);
25788
+ while (start !== -1) {
25789
+ const end = start + content.length;
25790
+ let canReplace = false;
25791
+ for (const identifier of identifiers) {
25792
+ if (start >= identifier.end || end <= identifier.start) continue;
25793
+ if (start > identifier.start || end < identifier.end) {
25794
+ canReplace = false;
25795
+ break;
25796
+ }
25797
+ canReplace = true;
25798
+ }
25799
+ if (canReplace) {
25800
+ replacements.push({
25801
+ start,
25802
+ end,
25803
+ content: replacement
25804
+ });
25805
+ searchStart = end;
25806
+ } else searchStart = start + 1;
25807
+ start = exp.content.indexOf(content, searchStart);
25808
+ }
25809
+ return replacements;
25810
+ }
25811
+ function findIdentifierReplacements(exp, name, replacement) {
25812
+ const replacements = [];
25813
+ for (const { start, end } of getIdentifierRanges(exp)) if (exp.content.slice(start, end) === name) replacements.push({
25814
+ start,
25815
+ end,
25816
+ content: replacement
25817
+ });
25818
+ return replacements;
25819
+ }
25820
+ function getIdentifierRanges(exp) {
25821
+ if (!exp.ast || typeof exp.ast !== "object") return [];
25822
+ const identifiers = [];
25823
+ walkIdentifiers(exp.ast, (id) => {
25824
+ identifiers.push({
25825
+ start: id.start - 1,
25826
+ end: id.end - 1
25827
+ });
25828
+ }, false);
25829
+ return identifiers;
25830
+ }
25831
+ function applyContentReplacements(content, replacements) {
25832
+ replacements.sort((a, b) => b.start - a.start).forEach(({ start, end, content: replacement }) => {
25833
+ content = content.slice(0, start) + replacement + content.slice(end);
25834
+ });
25835
+ return content;
25836
+ }
25636
25837
  function genDeclarations(declarations, context, shouldDeclare) {
25637
25838
  const [frag, push] = buildCodeFragment();
25638
25839
  const ids = Object.create(null);
@@ -25660,9 +25861,6 @@ function genDeclarations(declarations, context, shouldDeclare) {
25660
25861
  varNames: [...varNames]
25661
25862
  };
25662
25863
  }
25663
- function escapeRegExp(string) {
25664
- return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
25665
- }
25666
25864
  function parseExp(context, content) {
25667
25865
  return (0, import_lib.parseExpression)(`(${content})`, getParserOptions(context.options.expressionPlugins));
25668
25866
  }
@@ -25853,7 +26051,7 @@ function genFor(oper, context) {
25853
26051
  idMap[rawIndex] = `${indexVar}.value`;
25854
26052
  idMap[indexVar] = null;
25855
26053
  }
25856
- const { selectorPatterns, keyOnlyBindingPatterns } = matchPatterns(render, keyProp, idMap, context);
26054
+ const { selectorPatterns, keyOnlyBindingPatterns, skippedEffectIndexes } = matchPatterns(render, keyProp, idMap, context);
25857
26055
  const selectorDeclarations = [];
25858
26056
  const selectorName = (i) => selectorPatterns.length > 1 ? `_selector${id}_${i}` : `_selector${id}`;
25859
26057
  for (let i = 0; i < selectorPatterns.length; i++) {
@@ -25873,26 +26071,20 @@ function genFor(oper, context) {
25873
26071
  }
25874
26072
  for (const { effect } of keyOnlyBindingPatterns) for (const oper of effect.operations) patternFrag.push(...genOperation(oper, context));
25875
26073
  return patternFrag;
25876
- }));
26074
+ }, skippedEffectIndexes));
25877
26075
  else frag.push(...genBlockContent(render, context));
25878
26076
  frag.push(INDENT_END, NEWLINE, "}");
25879
26077
  return frag;
25880
26078
  }, idMap);
25881
26079
  exitScope();
25882
- let flags = 0;
25883
- if (onlyChild) flags |= 1;
25884
- if (component) flags |= 2;
25885
- if (isFragmentBlock(render)) flags |= 16;
25886
- if (!component && isSingleNodeBlock(render)) flags |= 8;
25887
- if (once) flags |= 4;
25888
- if (slotRoot) flags |= 32;
26080
+ const flags = genForFlags(onlyChild, component, isFragmentBlock(render), !component && isSingleNodeBlock(render), once, slotRoot);
25889
26081
  const onResetCalls = [];
25890
26082
  for (let i = 0; i < selectorPatterns.length; i++) onResetCalls.push(NEWLINE, `n${id}.onReset(${selectorName(i)}.reset)`);
25891
26083
  return [
25892
26084
  NEWLINE,
25893
26085
  ...selectorDeclarations,
25894
26086
  `const n${id} = `,
25895
- ...genCall([helper("createFor"), "undefined"], sourceExpr, blockFn, genCallback(keyProp), flags ? String(flags) : void 0),
26087
+ ...genCall([helper("createFor"), "undefined"], sourceExpr, blockFn, genCallback(keyProp), flags),
25896
26088
  ...onResetCalls
25897
26089
  ];
25898
26090
  function genCallback(expr) {
@@ -25917,6 +26109,36 @@ function genFor(oper, context) {
25917
26109
  return idMap;
25918
26110
  }
25919
26111
  }
26112
+ function genForFlags(onlyChild, component, isFragment, isSingleNode, once, slotRoot) {
26113
+ let flags = 0;
26114
+ const names = [];
26115
+ if (onlyChild) {
26116
+ flags |= 1;
26117
+ names.push("FAST_REMOVE");
26118
+ }
26119
+ if (component) {
26120
+ flags |= 2;
26121
+ names.push("IS_COMPONENT");
26122
+ }
26123
+ if (isFragment) {
26124
+ flags |= 16;
26125
+ names.push("IS_FRAGMENT");
26126
+ }
26127
+ if (isSingleNode) {
26128
+ flags |= 8;
26129
+ names.push("IS_SINGLE_NODE");
26130
+ }
26131
+ if (once) {
26132
+ flags |= 4;
26133
+ names.push("ONCE");
26134
+ }
26135
+ if (slotRoot) {
26136
+ flags |= 32;
26137
+ names.push("SLOT_ROOT");
26138
+ }
26139
+ if (!flags) return;
26140
+ return `${flags} /* ${names.join(", ")} */`;
26141
+ }
25920
26142
  function isSingleNodeBlock(block) {
25921
26143
  const child = getSingleReturnedChild(block);
25922
26144
  return !!child && child.template != null;
@@ -26003,39 +26225,35 @@ function buildDestructureIdMap(idToPathMap, baseAccessor, plugins) {
26003
26225
  function matchPatterns(render, keyProp, idMap, context) {
26004
26226
  const selectorPatterns = [];
26005
26227
  const keyOnlyBindingPatterns = [];
26006
- const removedEffectIndexes = [];
26007
- render.effect = render.effect.filter((effect, index) => {
26008
- if (keyProp !== void 0) {
26009
- const selector = matchSelectorPattern(effect, keyProp.content, idMap, context);
26010
- if (selector) {
26011
- selectorPatterns.push(selector);
26012
- removedEffectIndexes.push(index);
26013
- return false;
26014
- }
26015
- const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.content);
26016
- if (keyOnly) {
26017
- keyOnlyBindingPatterns.push(keyOnly);
26018
- removedEffectIndexes.push(index);
26019
- return false;
26020
- }
26228
+ let skippedEffectIndexes;
26229
+ if (keyProp === void 0) return {
26230
+ keyOnlyBindingPatterns,
26231
+ selectorPatterns,
26232
+ skippedEffectIndexes
26233
+ };
26234
+ for (let index = 0; index < render.effect.length; index++) {
26235
+ const effect = render.effect[index];
26236
+ const selector = matchSelectorPattern(effect, keyProp.content, idMap, context);
26237
+ if (selector) {
26238
+ selectorPatterns.push(selector);
26239
+ skipEffect(index);
26240
+ continue;
26021
26241
  }
26022
- return true;
26023
- });
26024
- if (removedEffectIndexes.length) shiftEffectBoundaries(render.dynamic, removedEffectIndexes);
26242
+ const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.content);
26243
+ if (keyOnly) {
26244
+ keyOnlyBindingPatterns.push(keyOnly);
26245
+ skipEffect(index);
26246
+ }
26247
+ }
26025
26248
  return {
26026
26249
  keyOnlyBindingPatterns,
26027
- selectorPatterns
26250
+ selectorPatterns,
26251
+ skippedEffectIndexes
26028
26252
  };
26029
- }
26030
- function shiftEffectBoundaries(dynamic, removedEffectIndexes) {
26031
- const operation = dynamic.operation;
26032
- if (operation && isBlockOperation(operation) && operation.effectIndex !== void 0) {
26033
- let offset = 0;
26034
- for (const removedIndex of removedEffectIndexes) if (removedIndex < operation.effectIndex) offset++;
26035
- else break;
26036
- operation.effectIndex -= offset;
26253
+ function skipEffect(index) {
26254
+ if (!skippedEffectIndexes) skippedEffectIndexes = /* @__PURE__ */ new Set();
26255
+ skippedEffectIndexes.add(index);
26037
26256
  }
26038
- for (const child of dynamic.children) shiftEffectBoundaries(child, removedEffectIndexes);
26039
26257
  }
26040
26258
  function matchKeyOnlyBindingPattern(effect, key) {
26041
26259
  if (effect.expressions.length === 1) {
@@ -26140,14 +26358,25 @@ function genIfFlags(blockShape, once, slotRoot, index) {
26140
26358
  return `${flags} /* ${genIfFlagNames(once, slotRoot, index, blockShape)} */`;
26141
26359
  }
26142
26360
  function genIfFlagNames(once, slotRoot, index, blockShape) {
26143
- const names = ["BLOCK_SHAPE"];
26361
+ const names = [`TRUE_${genBlockShapeName(blockShape)}`];
26362
+ const falseShape = blockShape >> 2;
26363
+ const hasFalseBranch = (falseShape & 3) !== 0;
26364
+ if (hasFalseBranch) names.push(`FALSE_${genBlockShapeName(falseShape)}`);
26144
26365
  if (blockShape & 32) names.push("TRUE_NO_SCOPE");
26145
- if (blockShape & 64) names.push("FALSE_NO_SCOPE");
26366
+ if (hasFalseBranch && blockShape & 64) names.push("FALSE_NO_SCOPE");
26146
26367
  if (once) names.push("ONCE");
26147
26368
  if (slotRoot) names.push("SLOT_ROOT");
26148
- if (!once && index !== void 0) names.push("INDEX_SHIFT");
26369
+ if (!once && index !== void 0) names.push(`KEYED_INDEX_${index}`);
26149
26370
  return names.join(", ");
26150
26371
  }
26372
+ function genBlockShapeName(flags) {
26373
+ switch (flags & 3) {
26374
+ case 0: return "EMPTY";
26375
+ case 1: return "SINGLE_ROOT";
26376
+ case 2: return "MULTI_ROOT";
26377
+ }
26378
+ return "UNKNOWN";
26379
+ }
26151
26380
  //#endregion
26152
26381
  //#region packages/compiler-vapor/src/generators/prop.ts
26153
26382
  const helpers = {
@@ -26329,7 +26558,12 @@ function genPropKey({ key: node, modifier, runtimeCamelize, handler, handlerModi
26329
26558
  if (runtimeCamelize) {
26330
26559
  key.push(" || \"\"");
26331
26560
  key = genCall(helper("camelize"), key);
26332
- }
26561
+ } else if (modifier) key = [
26562
+ "(",
26563
+ ...key,
26564
+ " || \"\"",
26565
+ ")"
26566
+ ];
26333
26567
  if (handler) key = genCall(helper("toHandlerKey"), key);
26334
26568
  return [
26335
26569
  "[",
@@ -26421,6 +26655,11 @@ function genVShow(oper, context) {
26421
26655
  ])];
26422
26656
  }
26423
26657
  //#endregion
26658
+ //#region packages/compiler-vapor/src/generators/modifier.ts
26659
+ function genDirectiveModifiers(modifiers) {
26660
+ return modifiers.map((value) => `${isSimpleIdentifier(value) ? value : JSON.stringify(value)}: true`).join(", ");
26661
+ }
26662
+ //#endregion
26424
26663
  //#region packages/compiler-vapor/src/generators/vModel.ts
26425
26664
  const helperMap = {
26426
26665
  text: "applyTextModel",
@@ -26435,7 +26674,7 @@ function genVModel(oper, context) {
26435
26674
  `() => (`,
26436
26675
  ...genExpression(exp, context),
26437
26676
  `)`
26438
- ], genModelHandler(exp, context), modifiers.length ? `{ ${modifiers.map((e) => e.content + ": true").join(",")} }` : void 0)];
26677
+ ], genModelHandler(exp, context), modifiers.length ? `{ ${genDirectiveModifiers(modifiers.map((e) => e.content))} }` : void 0)];
26439
26678
  }
26440
26679
  function genModelHandler(exp, context) {
26441
26680
  return [
@@ -26477,14 +26716,15 @@ function genCustomDirectives(opers, context) {
26477
26716
  return genMulti(DELIMITERS_ARRAY.concat("void 0"), directiveVar, value, argument, modifiers);
26478
26717
  }
26479
26718
  }
26480
- function genDirectiveModifiers(modifiers) {
26481
- return modifiers.map((value) => `${isSimpleIdentifier(value) ? value : JSON.stringify(value)}: true`).join(", ");
26482
- }
26483
26719
  function filterCustomDirectives(id, operations) {
26484
26720
  return operations.filter((oper) => oper.type === 14 && oper.element === id && !oper.builtin);
26485
26721
  }
26486
26722
  //#endregion
26487
26723
  //#region packages/compiler-vapor/src/generators/component.ts
26724
+ function genStaticModifierPropKey(name) {
26725
+ const key = getModifierPropName(name);
26726
+ return [isSimpleIdentifier(key) ? key : JSON.stringify(key)];
26727
+ }
26488
26728
  function genCreateComponent(operation, context) {
26489
26729
  const { helper } = context;
26490
26730
  const singleUseAssetComponentNames = context.singleUseAssetComponentNames;
@@ -26493,7 +26733,7 @@ function genCreateComponent(operation, context) {
26493
26733
  const tag = genTag();
26494
26734
  const { root, props, slots, once, slotRoot } = operation;
26495
26735
  const isRuntimeDynamicComponent = !!(operation.dynamic && !operation.dynamic.isStatic);
26496
- const dynamicComponentFlags = isRuntimeDynamicComponent ? (root ? 1 : 0) | (once ? 2 : 0) | (slotRoot ? 4 : 0) : 0;
26736
+ const dynamicComponentFlags = isRuntimeDynamicComponent ? genDynamicComponentFlags(root, once, slotRoot) : false;
26497
26737
  const rawSlots = genRawSlots(slots, context);
26498
26738
  const [ids, handlers] = processInlineHandlers(props, context);
26499
26739
  const rawProps = context.withId(() => genRawProps(props, context, true), ids);
@@ -26509,7 +26749,7 @@ function genCreateComponent(operation, context) {
26509
26749
  ];
26510
26750
  }, []),
26511
26751
  `const n${operation.id} = `,
26512
- ...genCall(isRuntimeDynamicComponent ? helper("createDynamicComponent") : operation.useCreateElement ? helper("createPlainElement") : useAssetComponentHelper ? helper("createAssetComponent") : operation.asset ? helper("createComponentWithFallback") : helper("createComponent"), tag, rawProps, rawSlots, isRuntimeDynamicComponent ? dynamicComponentFlags ? String(dynamicComponentFlags) : false : root ? "true" : false, isRuntimeDynamicComponent ? false : once && "true", isRuntimeDynamicComponent ? false : maybeSelfReference && "true"),
26752
+ ...genCall(isRuntimeDynamicComponent ? helper("createDynamicComponent") : operation.useCreateElement ? helper("createPlainElement") : useAssetComponentHelper ? helper("createAssetComponent") : operation.asset ? helper("createComponentWithFallback") : helper("createComponent"), tag, rawProps, rawSlots, isRuntimeDynamicComponent ? dynamicComponentFlags : root ? "true" : false, isRuntimeDynamicComponent ? false : once && "true", isRuntimeDynamicComponent ? false : maybeSelfReference && "true"),
26513
26753
  ...genDirectivesForElement(operation.id, context)
26514
26754
  ];
26515
26755
  function genTag() {
@@ -26535,6 +26775,24 @@ function genCreateComponent(operation, context) {
26535
26775
  }
26536
26776
  }
26537
26777
  }
26778
+ function genDynamicComponentFlags(root, once, slotRoot) {
26779
+ let flags = 0;
26780
+ const names = [];
26781
+ if (root) {
26782
+ flags |= 1;
26783
+ names.push("SINGLE_ROOT");
26784
+ }
26785
+ if (once) {
26786
+ flags |= 2;
26787
+ names.push("ONCE");
26788
+ }
26789
+ if (slotRoot) {
26790
+ flags |= 4;
26791
+ names.push("SLOT_ROOT");
26792
+ }
26793
+ if (!flags) return false;
26794
+ return `${flags} /* ${names.join(", ")} */`;
26795
+ }
26538
26796
  function getUniqueHandlerName(context, name) {
26539
26797
  const { seenInlineHandlerNames } = context;
26540
26798
  name = genVarName(name);
@@ -26626,7 +26884,7 @@ function genStaticProps(props, context, dynamicProps, directStaticLiteralProps =
26626
26884
  }
26627
26885
  const { key, modelModifiers } = prop;
26628
26886
  if (modelModifiers && modelModifiers.length) {
26629
- const modifiersKey = key.isStatic ? [getModifierPropName(key.content)] : [
26887
+ const modifiersKey = key.isStatic ? genStaticModifierPropKey(key.content) : [
26630
26888
  "[",
26631
26889
  ...genExpression(key, context),
26632
26890
  " + \"Modifiers\"]"
@@ -26669,7 +26927,7 @@ function genDynamicProps(props, context, directStaticLiteralProps = false) {
26669
26927
  ]);
26670
26928
  const { modelModifiers } = p;
26671
26929
  if (modelModifiers && modelModifiers.length) {
26672
- const modifiersKey = p.key.isStatic ? [getModifierPropName(p.key.content)] : [
26930
+ const modifiersKey = p.key.isStatic ? genStaticModifierPropKey(p.key.content) : [
26673
26931
  "[",
26674
26932
  ...genExpression(p.key, context),
26675
26933
  " + \"Modifiers\"]"
@@ -26794,7 +27052,7 @@ function genDynamicSlot(slot, context, withFunction = false) {
26794
27052
  }
26795
27053
  function genBasicDynamicSlot(slot, context) {
26796
27054
  const { name, fn } = slot;
26797
- return genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...genExpression(name, context)], ["fn: ", ...genSlotBlockWithProps(fn, context)]);
27055
+ return genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...genExpression(name, context)], ["fn: ", ...genSlotBlockWithProps(fn, context, false)]);
26798
27056
  }
26799
27057
  function genLoopSlot(slot, context) {
26800
27058
  const { name, fn, loop } = slot;
@@ -26806,7 +27064,7 @@ function genLoopSlot(slot, context) {
26806
27064
  if (rawValue) idMap[rawValue] = rawValue;
26807
27065
  if (rawKey) idMap[rawKey] = rawKey;
26808
27066
  if (rawIndex) idMap[rawIndex] = rawIndex;
26809
- const slotExpr = genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...context.withId(() => genExpression(name, context), idMap)], ["fn: ", ...context.withId(() => genSlotBlockWithProps(fn, context), idMap)]);
27067
+ const slotExpr = genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...context.withId(() => genExpression(name, context), idMap)], ["fn: ", ...context.withId(() => genSlotBlockWithProps(fn, context, false), idMap)]);
26810
27068
  return [...genCall(context.helper("createForSlots"), genExpression(source, context), [
26811
27069
  ...genMulti([
26812
27070
  "(",
@@ -26832,7 +27090,7 @@ function genConditionalSlot(slot, context) {
26832
27090
  INDENT_END
26833
27091
  ];
26834
27092
  }
26835
- function genSlotBlockWithProps(oper, context) {
27093
+ function genSlotBlockWithProps(oper, context, emitNonStableFlag = true) {
26836
27094
  let propsName;
26837
27095
  let exitScope;
26838
27096
  let depth;
@@ -26845,12 +27103,56 @@ function genSlotBlockWithProps(oper, context) {
26845
27103
  const idMap = idToPathMap.size ? buildDestructureIdMap(idToPathMap, propsName || "", context.options.expressionPlugins) : {};
26846
27104
  if (propsName) idMap[propsName] = null;
26847
27105
  const exitSlotBlock = context.enterSlotBlock();
26848
- markSlotRootOperations(oper);
27106
+ const hasStableRoot = hasStableSlotRoot(oper, context);
27107
+ if (!hasStableRoot) markSlotRootOperations(oper);
26849
27108
  let blockFn = context.withId(() => genBlock(oper, context, propsName ? [propsName] : []), idMap);
27109
+ if (emitNonStableFlag && !hasStableRoot) blockFn = genCall(context.helper("extend"), blockFn, [`{ _: ${genSlotFlags$1(8)} }`]);
26850
27110
  exitSlotBlock();
26851
27111
  exitScope && exitScope();
26852
27112
  return blockFn;
26853
27113
  }
27114
+ function genSlotFlags$1(flags) {
27115
+ const names = [];
27116
+ if (flags & 1) names.push("NO_SLOTTED");
27117
+ if (flags & 2) names.push("ONCE");
27118
+ if (flags & 4) names.push("SLOT_ROOT");
27119
+ if (flags & 8) names.push("NON_STABLE");
27120
+ return `${flags} /* ${names.join(", ")} */`;
27121
+ }
27122
+ const commentOnlyTemplateRE = /^(?:<!--[\s\S]*?-->)+$/;
27123
+ function hasStableSlotRoot(block, context) {
27124
+ let hasValidRoot = false;
27125
+ for (let i = 0; i < block.returns.length; i++) {
27126
+ const id = block.returns[i];
27127
+ const child = findReturnedDynamic$1(block, id);
27128
+ const operation = child && child.operation;
27129
+ if (!operation) {
27130
+ if (child && isStableTemplateSlotRoot(child, context)) hasValidRoot = true;
27131
+ continue;
27132
+ }
27133
+ switch (operation.type) {
27134
+ case 12:
27135
+ if (!operation.dynamic || operation.dynamic.isStatic) {
27136
+ hasValidRoot = true;
27137
+ continue;
27138
+ }
27139
+ continue;
27140
+ case 17:
27141
+ if (hasStableSlotRoot(operation.block, context)) {
27142
+ hasValidRoot = true;
27143
+ continue;
27144
+ }
27145
+ continue;
27146
+ default: continue;
27147
+ }
27148
+ }
27149
+ return hasValidRoot;
27150
+ }
27151
+ function isStableTemplateSlotRoot(child, context) {
27152
+ if (child.template == null) return false;
27153
+ const content = context.ir.template.entries[child.template].content;
27154
+ return content !== "" && !commentOnlyTemplateRE.test(content.trim());
27155
+ }
26854
27156
  //#endregion
26855
27157
  //#region packages/compiler-vapor/src/generators/slotOutlet.ts
26856
27158
  function genSlotOutlet(oper, context) {
@@ -26859,7 +27161,7 @@ function genSlotOutlet(oper, context) {
26859
27161
  const [frag, push] = buildCodeFragment();
26860
27162
  let fallbackArg;
26861
27163
  if (fallback) {
26862
- markSlotRootOperations(fallback);
27164
+ if (context.inSlotBlock) markSlotRootOperations(fallback);
26863
27165
  fallbackArg = genBlock(fallback, context);
26864
27166
  }
26865
27167
  const createSlot = helper("createSlot");
@@ -26869,9 +27171,17 @@ function genSlotOutlet(oper, context) {
26869
27171
  ...genExpression(name, context),
26870
27172
  ")"
26871
27173
  ];
26872
- push(NEWLINE, `const n${id} = `, ...genCall(createSlot, nameArg, rawPropsArg, fallbackArg, flags ? String(flags) : void 0));
27174
+ push(NEWLINE, `const n${id} = `, ...genCall(createSlot, nameArg, rawPropsArg, fallbackArg, genSlotFlags(flags)));
26873
27175
  return frag;
26874
27176
  }
27177
+ function genSlotFlags(flags) {
27178
+ if (!flags) return;
27179
+ const names = [];
27180
+ if (flags & 1) names.push("NO_SLOTTED");
27181
+ if (flags & 2) names.push("ONCE");
27182
+ if (flags & 4) names.push("SLOT_ROOT");
27183
+ return `${flags} /* ${names.join(", ")} */`;
27184
+ }
26875
27185
  //#endregion
26876
27186
  //#region packages/compiler-vapor/src/generators/key.ts
26877
27187
  function genKey(oper, context) {
@@ -27144,7 +27454,7 @@ function genBlock(oper, context, args = [], root) {
27144
27454
  "}"
27145
27455
  ];
27146
27456
  }
27147
- function genBlockContent(block, context, root, genEffectsExtraFrag) {
27457
+ function genBlockContent(block, context, root, genEffectsExtraFrag, skippedEffectIndexes) {
27148
27458
  const [frag, push] = buildCodeFragment();
27149
27459
  const { dynamic, effect, operation, returns } = block;
27150
27460
  const resetBlock = context.enterBlock(block);
@@ -27169,7 +27479,7 @@ function genBlockContent(block, context, root, genEffectsExtraFrag) {
27169
27479
  operationIndex++;
27170
27480
  }
27171
27481
  if (effectIndex < effectEnd) {
27172
- push(...genEffects(effect.slice(effectIndex, effectEnd), context));
27482
+ push(...genEffectRange(effectIndex, effectEnd));
27173
27483
  effectIndex = effectEnd;
27174
27484
  }
27175
27485
  };
@@ -27183,14 +27493,21 @@ function genBlockContent(block, context, root, genEffectsExtraFrag) {
27183
27493
  }
27184
27494
  for (const child of dynamic.children) if (!child.hasDynamicChild) push(...genChildren(child, context, push, `n${child.id}`, flushBeforeDynamic));
27185
27495
  if (operationIndex < operation.length) push(...genOperations(operation.slice(operationIndex), context));
27186
- if (effectIndex < effect.length) push(...genEffects(effect.slice(effectIndex), context, genEffectsExtraFrag));
27496
+ if (effectIndex < effect.length) push(...genEffectRange(effectIndex, effect.length, genEffectsExtraFrag));
27187
27497
  else if (genEffectsExtraFrag) push(...genEffects([], context, genEffectsExtraFrag));
27188
27498
  push(NEWLINE, `return `);
27189
27499
  const returnNodes = returns.map((n) => `n${n}`);
27190
- push(...returnNodes.length > 1 ? genMulti(DELIMITERS_ARRAY, ...returnNodes) : [returnNodes[0] || "null"]);
27500
+ push(...returnNodes.length > 1 ? genMulti(DELIMITERS_ARRAY, ...returnNodes) : [returnNodes[0] || "[]"]);
27191
27501
  resetBlock();
27192
27502
  context.singleUseAssetComponentNames = prevSingleUseAssetComponentNames;
27193
27503
  return frag;
27504
+ function genEffectRange(start, end, genExtraFrag) {
27505
+ if (!skippedEffectIndexes) return genEffects(effect.slice(start, end), context, genExtraFrag);
27506
+ const effects = [];
27507
+ for (let i = start; i < end; i++) if (!skippedEffectIndexes.has(i)) effects.push(effect[i]);
27508
+ if (effects.length || genExtraFrag) return genEffects(effects, context, genExtraFrag);
27509
+ return [];
27510
+ }
27194
27511
  function genResolveAssets(kind, helper) {
27195
27512
  for (const name of context.ir[kind]) push(NEWLINE, `const ${toValidAssetId(name, kind)} = `, ...genCall(context.helper(helper), JSON.stringify(name)));
27196
27513
  }
@@ -27202,7 +27519,6 @@ function markSlotRootOperations(block) {
27202
27519
  if (!operation) continue;
27203
27520
  if (operation.type === 15) markSlotRootIf(operation);
27204
27521
  else if (operation.type === 16) markSlotRootFor(operation);
27205
- else if (operation.type === 13) markSlotRootSlotOutlet(operation);
27206
27522
  else if (operation.type === 12) markSlotRootComponent(operation);
27207
27523
  }
27208
27524
  }
@@ -27218,10 +27534,6 @@ function markSlotRootFor(operation) {
27218
27534
  if (!operation.once) operation.slotRoot = true;
27219
27535
  markSlotRootOperations(operation.render);
27220
27536
  }
27221
- function markSlotRootSlotOutlet(operation) {
27222
- operation.flags |= 4;
27223
- if (operation.fallback) markSlotRootOperations(operation.fallback);
27224
- }
27225
27537
  function markSlotRootComponent(operation) {
27226
27538
  if (!operation.once && operation.dynamic && !operation.dynamic.isStatic) operation.slotRoot = true;
27227
27539
  }
@@ -27526,12 +27838,37 @@ const transformVBind = (dir, node, context) => {
27526
27838
  };
27527
27839
  };
27528
27840
  //#endregion
27841
+ //#region packages/compiler-vapor/src/transforms/vHtml.ts
27842
+ function ignoreVHtmlChildren(node, context, clear) {
27843
+ if (!node.children.length) return;
27844
+ const dir = findDir$1(node, "html");
27845
+ if (!dir) return;
27846
+ context.options.onError(createDOMCompilerError(55, dir.loc));
27847
+ if (clear === "node") node.children.length = 0;
27848
+ else context.childrenTemplate.length = 0;
27849
+ }
27850
+ const transformVHtml = (dir, node, context) => {
27851
+ let { exp, loc } = dir;
27852
+ if (!exp) {
27853
+ context.options.onError(createDOMCompilerError(54, loc));
27854
+ exp = EMPTY_EXPRESSION;
27855
+ }
27856
+ ignoreVHtmlChildren(node, context, "template");
27857
+ context.registerEffect([exp], {
27858
+ type: 8,
27859
+ element: context.reference(),
27860
+ value: exp,
27861
+ isComponent: node.tagType === 1
27862
+ });
27863
+ };
27864
+ //#endregion
27529
27865
  //#region packages/compiler-vapor/src/transforms/transformElement.ts
27530
27866
  init_objectSpread2();
27531
27867
  const isReservedProp = /* @__PURE__ */ makeMap(",key,ref,ref_for,ref_key,");
27532
27868
  const transformElement = (node, context) => {
27533
27869
  let effectIndex = context.block.effect.length;
27534
27870
  const getEffectIndex = () => effectIndex++;
27871
+ if (node.type === 1 && node.children.length) ignoreVHtmlChildren(node, context, "node");
27535
27872
  let parentSlots;
27536
27873
  if (node.type === 1 && (node.tagType === 1 || context.options.isCustomElement(node.tag))) {
27537
27874
  parentSlots = context.slots;
@@ -27545,7 +27882,7 @@ const transformElement = (node, context) => {
27545
27882
  const isDynamicComponent = isComponentTag(node.tag);
27546
27883
  const staticKey = resolveStaticKey(node, context, isComponent);
27547
27884
  const propsResult = buildProps(node, context, isComponent, isDynamicComponent, getEffectIndex);
27548
- const singleRoot = isSingleRoot(context);
27885
+ const singleRoot = context.isSingleRoot;
27549
27886
  if (isComponent) transformComponentElement(node, propsResult, staticKey, singleRoot, context, isDynamicComponent, useCreateElement);
27550
27887
  else transformNativeElement(node, propsResult, staticKey, singleRoot, context, getEffectIndex, context.root === context.effectiveParent || canOmitEndTag(node, context));
27551
27888
  if (parentSlots) context.slots = parentSlots;
@@ -27584,16 +27921,6 @@ function isInSameTemplateAsParent(context) {
27584
27921
  if (parentNode.type !== 1 || parentNode.tagType !== 0) return false;
27585
27922
  return !shouldUseCreateElement(parentNode, parent) && isValidHTMLNesting(parentNode.tag, node.tag);
27586
27923
  }
27587
- function isSingleRoot(context) {
27588
- if (context.inVFor) return false;
27589
- let { parent } = context;
27590
- if (parent && !(hasSingleChild(parent.node) || isSingleIfBlock(parent.node))) return false;
27591
- while (parent && parent.parent && parent.node.type === 1 && parent.node.tagType === 3) {
27592
- parent = parent.parent;
27593
- if (!(hasSingleChild(parent.node) || isSingleIfBlock(parent.node))) return false;
27594
- }
27595
- return context.root === parent;
27596
- }
27597
27924
  function transformComponentElement(node, propsResult, staticKey, singleRoot, context, isDynamicComponent, useCreateElement) {
27598
27925
  const dynamicComponent = isDynamicComponent ? resolveDynamicComponent(node) : void 0;
27599
27926
  let { tag } = node;
@@ -27682,17 +28009,18 @@ function transformNativeElement(node, propsResult, staticKey, singleRoot, contex
27682
28009
  };
27683
28010
  for (const prop of propsResult[1]) {
27684
28011
  const { key, values } = prop;
28012
+ const canStringifyAttrName = key.isStatic && !UNSAFE_ATTR_NAME_RE.test(key.content);
27685
28013
  let foldedValue;
27686
- if (context.imports.some((imported) => values[0].content.includes(imported.exp.content))) {
28014
+ if (canStringifyAttrName && context.imports.some((imported) => values[0].content.includes(imported.exp.content))) {
27687
28015
  if (!prevWasQuoted) template += ` `;
27688
28016
  template += `${key.content}="${IMPORT_EXP_START}${values[0].content}${IMPORT_EXP_END}"`;
27689
28017
  prevWasQuoted = true;
27690
- } else if (key.isStatic && values.length === 1 && (values[0].isStatic || values[0].content === "''") && !dynamicKeys.includes(key.content)) {
28018
+ } else if (canStringifyAttrName && values.length === 1 && (values[0].isStatic || values[0].content === "''") && !dynamicKeys.includes(key.content)) {
27691
28019
  const value = values[0].content === "''" ? "" : values[0].content;
27692
28020
  appendTemplateProp(key.content, value);
27693
- } else if (key.isStatic && !prop.modifier && isBooleanAttr(key.content) && (foldedValue = foldBooleanAttrValue(values)) != null) {
28021
+ } else if (canStringifyAttrName && !prop.modifier && isBooleanAttr(key.content) && (foldedValue = foldBooleanAttrValue(values)) != null) {
27694
28022
  if (foldedValue) appendTemplateProp(key.content);
27695
- } else if (key.isStatic && !prop.modifier && hasBoundValue(values) && (foldedValue = key.content === "class" ? foldClassValues(values) : key.content === "style" ? foldStyleValues(values) : void 0) != null) {
28023
+ } else if (canStringifyAttrName && !prop.modifier && hasBoundValue(values) && (foldedValue = key.content === "class" ? foldClassValues(values) : key.content === "style" ? foldStyleValues(values) : void 0) != null) {
27696
28024
  if (foldedValue) appendTemplateProp(key.content, foldedValue, true);
27697
28025
  } else context.registerEffect(values, {
27698
28026
  type: 3,
@@ -28212,25 +28540,6 @@ const transformVOnce = (node, context) => {
28212
28540
  if (node.type === 1 && findDir$1(node, "once", true)) context.inVOnce = true;
28213
28541
  };
28214
28542
  //#endregion
28215
- //#region packages/compiler-vapor/src/transforms/vHtml.ts
28216
- const transformVHtml = (dir, node, context) => {
28217
- let { exp, loc } = dir;
28218
- if (!exp) {
28219
- context.options.onError(createDOMCompilerError(54, loc));
28220
- exp = EMPTY_EXPRESSION;
28221
- }
28222
- if (node.children.length) {
28223
- context.options.onError(createDOMCompilerError(55, loc));
28224
- context.childrenTemplate.length = 0;
28225
- }
28226
- context.registerEffect([exp], {
28227
- type: 8,
28228
- element: context.reference(),
28229
- value: exp,
28230
- isComponent: node.tagType === 1
28231
- });
28232
- };
28233
- //#endregion
28234
28543
  //#region packages/compiler-vapor/src/transforms/transformText.ts
28235
28544
  const seen = /* @__PURE__ */ new WeakMap();
28236
28545
  function markNonTemplate(node, context) {
@@ -28276,13 +28585,7 @@ const transformText = (node, context) => {
28276
28585
  };
28277
28586
  function processInterpolation(context) {
28278
28587
  const parentNode = context.parent.node;
28279
- const children = parentNode.children;
28280
- const nexts = children.slice(context.index);
28281
- const idx = nexts.findIndex((n) => !isTextLike(n));
28282
- const nodes = idx > -1 ? nexts.slice(0, idx) : nexts;
28283
- const prev = children[context.index - 1];
28284
- if (prev && prev.type === 2) nodes.unshift(prev);
28285
- const values = processTextLikeChildren(nodes, context);
28588
+ const values = processTextLikeChildren(collectAdjacentText(context), context);
28286
28589
  if (values.length === 0 && parentNode.type !== 0) return;
28287
28590
  const literalValues = values.map((v) => getLiteralExpressionValue(v));
28288
28591
  if (literalValues.every((v) => v != null) && parentNode.type !== 0) {
@@ -28304,6 +28607,18 @@ function processInterpolation(context) {
28304
28607
  values
28305
28608
  });
28306
28609
  }
28610
+ function collectAdjacentText(context) {
28611
+ const children = context.parent.node.children;
28612
+ const nodes = [];
28613
+ const prev = children[context.index - 1];
28614
+ let index = prev && prev.type === 2 ? context.index - 1 : context.index;
28615
+ for (; index < children.length; index++) {
28616
+ const child = children[index];
28617
+ if (!isTextLike(child)) break;
28618
+ nodes.push(child);
28619
+ }
28620
+ return nodes;
28621
+ }
28307
28622
  function processTextContainer(children, context) {
28308
28623
  const values = processTextLikeChildren(children, context);
28309
28624
  const literals = values.map((value) => getLiteralExpressionValue(value));
@@ -28926,7 +29241,7 @@ function transformTemplateSlot(node, dir, context) {
28926
29241
  });
28927
29242
  else if (vElse) {
28928
29243
  const vIfSlot = slots[slots.length - 1];
28929
- if (vIfSlot.slotType === 3) {
29244
+ if (vIfSlot && vIfSlot.slotType === 3) {
28930
29245
  let ifNode = vIfSlot;
28931
29246
  while (ifNode.negative && ifNode.negative.slotType === 3) ifNode = ifNode.negative;
28932
29247
  const negative = vElse.exp ? {
@@ -42205,7 +42520,7 @@ function mergeSourceMaps(scriptMap, templateMap, templateLineOffset) {
42205
42520
  //#endregion
42206
42521
  //#region packages/compiler-sfc/src/index.ts
42207
42522
  init_objectSpread2();
42208
- const version = "3.6.0-beta.15";
42523
+ const version = "3.6.0-beta.17";
42209
42524
  const parseCache = parseCache$1;
42210
42525
  const errorMessages = _objectSpread2(_objectSpread2({}, errorMessages$1), DOMErrorMessages);
42211
42526
  const walk = walk$2;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/compiler-sfc",
3
- "version": "3.6.0-beta.15",
3
+ "version": "3.6.0-beta.17",
4
4
  "description": "@vue/compiler-sfc",
5
5
  "main": "dist/compiler-sfc.cjs.js",
6
6
  "module": "dist/compiler-sfc.esm-browser.js",
@@ -47,11 +47,11 @@
47
47
  "magic-string": "^0.30.21",
48
48
  "postcss": "^8.5.14",
49
49
  "source-map-js": "^1.2.1",
50
- "@vue/compiler-core": "3.6.0-beta.15",
51
- "@vue/compiler-ssr": "3.6.0-beta.15",
52
- "@vue/compiler-dom": "3.6.0-beta.15",
53
- "@vue/compiler-vapor": "3.6.0-beta.15",
54
- "@vue/shared": "3.6.0-beta.15"
50
+ "@vue/compiler-core": "3.6.0-beta.17",
51
+ "@vue/compiler-dom": "3.6.0-beta.17",
52
+ "@vue/compiler-ssr": "3.6.0-beta.17",
53
+ "@vue/compiler-vapor": "3.6.0-beta.17",
54
+ "@vue/shared": "3.6.0-beta.17"
55
55
  },
56
56
  "devDependencies": {
57
57
  "@babel/types": "^7.29.7",