@lwc/template-compiler 7.2.4 → 7.2.6

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.
@@ -49,7 +49,7 @@ export default class CodeGen {
49
49
  };
50
50
  usedLwcApis: Set<string>;
51
51
  slotNames: Set<string>;
52
- memorizedIds: t.Identifier[];
52
+ memoizedIds: t.Identifier[];
53
53
  referencedComponents: Set<string>;
54
54
  apiVersion: APIVersion;
55
55
  staticExpressionMap: WeakMap<Attribute | Text, string>;
@@ -89,7 +89,7 @@ export default class CodeGen {
89
89
  */
90
90
  getScopedSlotFactory(callback: t.FunctionExpression, slotName: t.Expression | t.SimpleLiteral): import("estree").CallExpression;
91
91
  genTabIndex(children: [t.Expression]): import("estree").CallExpression;
92
- getMemorizationId(): import("estree").Identifier;
92
+ getMemoizationId(): import("estree").Identifier;
93
93
  genBooleanAttributeExpr(bindExpr: t.Expression): import("estree").ConditionalExpression;
94
94
  genEventListeners(listeners: EventListener[]): import("estree").Property;
95
95
  genRef(ref: RefDirective): import("estree").Property;
@@ -18,7 +18,6 @@ export declare function shouldFlatten(codeGen: CodeGen, children: ChildNode[]):
18
18
  * @param node
19
19
  */
20
20
  export declare function hasIdAttribute(node: Node): boolean;
21
- export declare function memorizeHandler(codeGen: CodeGen, componentHandler: t.Expression, handler: t.Expression): t.Expression;
22
21
  export declare function generateTemplateMetadata(codeGen: CodeGen): t.Statement[];
23
22
  export declare function parseStyleText(cssText: string): {
24
23
  [name: string]: string;
package/dist/index.cjs.js CHANGED
@@ -12863,19 +12863,6 @@ function hasIdAttribute(node) {
12863
12863
  }
12864
12864
  return false;
12865
12865
  }
12866
- function memorizeHandler(codeGen, componentHandler, handler) {
12867
- // #439 - The handler can only be memorized if it is bound to component instance
12868
- const id = getMemberExpressionRoot(componentHandler);
12869
- const shouldMemorizeHandler = !codeGen.isLocalIdentifier(id);
12870
- // Apply memorization if the handler is memorizable.
12871
- // $cmp.handlePress -> _m1 || ($ctx._m1 = b($cmp.handlePress))
12872
- if (shouldMemorizeHandler) {
12873
- const memorizedId = codeGen.getMemorizationId();
12874
- const memorization = assignmentExpression('=', memberExpression(identifier(TEMPLATE_PARAMS.CONTEXT), memorizedId), handler);
12875
- handler = logicalExpression('||', memorizedId, memorization);
12876
- }
12877
- return handler;
12878
- }
12879
12866
  function generateTemplateMetadata(codeGen) {
12880
12867
  const metadataExpressions = [];
12881
12868
  if (codeGen.slotNames.size) {
@@ -13535,7 +13522,7 @@ class CodeGen {
13535
13522
  this.usedApis = {};
13536
13523
  this.usedLwcApis = new Set();
13537
13524
  this.slotNames = new Set();
13538
- this.memorizedIds = [];
13525
+ this.memoizedIds = [];
13539
13526
  this.referencedComponents = new Set();
13540
13527
  this.staticExpressionMap = new WeakMap();
13541
13528
  this.root = root;
@@ -13669,23 +13656,59 @@ class CodeGen {
13669
13656
  genTabIndex(children) {
13670
13657
  return this._renderApiCall(RENDER_APIS.tabindex, children);
13671
13658
  }
13672
- getMemorizationId() {
13659
+ getMemoizationId() {
13673
13660
  const currentId = this.currentId++;
13674
- const memorizationId = identifier(`_m${currentId}`);
13675
- this.memorizedIds.push(memorizationId);
13676
- return memorizationId;
13661
+ const memoizationId = identifier(`_m${currentId}`);
13662
+ this.memoizedIds.push(memoizationId);
13663
+ return memoizationId;
13677
13664
  }
13678
13665
  genBooleanAttributeExpr(bindExpr) {
13679
13666
  return conditionalExpression(bindExpr, literal$1(''), literal$1(null));
13680
13667
  }
13681
13668
  genEventListeners(listeners) {
13682
- const listenerObj = Object.fromEntries(listeners.map((listener) => [listener.name, listener]));
13683
- const listenerObjectAST = objectToAST(listenerObj, (key) => {
13684
- const componentHandler = this.bindExpression(listenerObj[key].handler);
13685
- const handler = this.genBind(componentHandler);
13686
- return memorizeHandler(this, componentHandler, handler);
13687
- });
13688
- return property$1(identifier('on'), listenerObjectAST);
13669
+ let hasLocalListeners = false;
13670
+ const listenerObj = {};
13671
+ for (const { name, handler } of listeners) {
13672
+ const componentHandler = this.bindExpression(handler);
13673
+ const id = getMemberExpressionRoot(componentHandler);
13674
+ const isLocal = this.isLocalIdentifier(id);
13675
+ if (isLocal) {
13676
+ hasLocalListeners = true;
13677
+ }
13678
+ listenerObj[name] = { handler: this.genBind(componentHandler), isLocal };
13679
+ }
13680
+ // Individually memoize a non-local event handler
13681
+ // Example input: <template for:each={list} for:item="task">
13682
+ // <button [...] ontouchstart={foo}>[X]</button>
13683
+ // </template>
13684
+ // Output: [...] touchstart: _m2 || ($ctx._m2 = api_bind($cmp.foo))
13685
+ const memoize = (expr) => {
13686
+ const memoizedId = this.getMemoizationId();
13687
+ return logicalExpression('||', memoizedId, assignmentExpression('=', memberExpression(identifier(TEMPLATE_PARAMS.CONTEXT), memoizedId), expr));
13688
+ };
13689
+ if (hasLocalListeners) {
13690
+ // If there are local listeners, we need to memoize individual handlers
13691
+ // Input: <template for:each={list} for:item="task">
13692
+ // <button onclick={task.delete} ontouchstart={foo}>[X]</button>
13693
+ // </template>
13694
+ // Output:
13695
+ // on: {
13696
+ // click: api_bind(task.delete),
13697
+ // touchstart: _m2 || ($ctx._m2 = api_bind($cmp.foo))
13698
+ // }
13699
+ return property$1(identifier('on'), objectToAST(listenerObj, (k) => {
13700
+ const { isLocal, handler } = listenerObj[k];
13701
+ return isLocal ? handler : memoize(handler);
13702
+ }));
13703
+ }
13704
+ else {
13705
+ // If there are no local listeners, we can memoize the entire `on` object
13706
+ // Input: <template>
13707
+ // <button onclick={create}>New</button>
13708
+ // </template>
13709
+ // Output: on: _m1 || ($ctx._m1 = { click: api_bind($cmp.create) })
13710
+ return property$1(identifier('on'), memoize(objectToAST(listenerObj, (k) => listenerObj[k].handler)));
13711
+ }
13689
13712
  }
13690
13713
  genRef(ref) {
13691
13714
  this.hasRefs = true;
@@ -14639,9 +14662,9 @@ function generateTemplateFunction(codeGen) {
14639
14662
  variableDeclarator(objectPattern(usedApis.map((name) => assignmentProperty(identifier(name), codeGen.usedApis[name]))), identifier(TEMPLATE_PARAMS.API)),
14640
14663
  ]),
14641
14664
  ];
14642
- if (codeGen.memorizedIds.length) {
14665
+ if (codeGen.memoizedIds.length) {
14643
14666
  body.push(variableDeclaration('const', [
14644
- variableDeclarator(objectPattern(codeGen.memorizedIds.map((id) => assignmentProperty(id, id, { shorthand: true }))), identifier(TEMPLATE_PARAMS.CONTEXT)),
14667
+ variableDeclarator(objectPattern(codeGen.memoizedIds.map((id) => assignmentProperty(id, id, { shorthand: true }))), identifier(TEMPLATE_PARAMS.CONTEXT)),
14645
14668
  ]));
14646
14669
  }
14647
14670
  body.push(returnStatement(returnedValue));
@@ -14722,5 +14745,5 @@ exports.default = compile;
14722
14745
  exports.kebabcaseToCamelcase = kebabcaseToCamelcase;
14723
14746
  exports.parse = parse;
14724
14747
  exports.toPropertyName = toPropertyName;
14725
- /** version: 7.2.4 */
14748
+ /** version: 7.2.6 */
14726
14749
  //# sourceMappingURL=index.cjs.js.map