lwc 2.33.0 → 2.34.0

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.
Files changed (35) hide show
  1. package/dist/engine-dom/esm/es2017/engine-dom.js +166 -42
  2. package/dist/engine-dom/iife/es2017/engine-dom.js +166 -42
  3. package/dist/engine-dom/iife/es2017/engine-dom.min.js +1 -1
  4. package/dist/engine-dom/iife/es2017/engine-dom_debug.js +170 -39
  5. package/dist/engine-dom/iife/es5/engine-dom.js +204 -91
  6. package/dist/engine-dom/iife/es5/engine-dom.min.js +1 -1
  7. package/dist/engine-dom/iife/es5/engine-dom_debug.js +217 -88
  8. package/dist/engine-dom/umd/es2017/engine-dom.js +166 -42
  9. package/dist/engine-dom/umd/es2017/engine-dom.min.js +1 -1
  10. package/dist/engine-dom/umd/es2017/engine-dom_debug.js +170 -39
  11. package/dist/engine-dom/umd/es5/engine-dom.js +204 -91
  12. package/dist/engine-dom/umd/es5/engine-dom.min.js +1 -1
  13. package/dist/engine-dom/umd/es5/engine-dom_debug.js +217 -88
  14. package/dist/engine-server/commonjs/es2017/engine-server.js +158 -39
  15. package/dist/engine-server/commonjs/es2017/engine-server.min.js +1 -1
  16. package/dist/engine-server/esm/es2017/engine-server.js +158 -39
  17. package/dist/synthetic-shadow/esm/es2017/synthetic-shadow.js +3 -3
  18. package/dist/synthetic-shadow/iife/es2017/synthetic-shadow.js +3 -3
  19. package/dist/synthetic-shadow/iife/es2017/synthetic-shadow_debug.js +3 -3
  20. package/dist/synthetic-shadow/iife/es5/synthetic-shadow.js +3 -3
  21. package/dist/synthetic-shadow/iife/es5/synthetic-shadow_debug.js +3 -3
  22. package/dist/synthetic-shadow/umd/es2017/synthetic-shadow.js +3 -3
  23. package/dist/synthetic-shadow/umd/es2017/synthetic-shadow_debug.js +3 -3
  24. package/dist/synthetic-shadow/umd/es5/synthetic-shadow.js +3 -3
  25. package/dist/synthetic-shadow/umd/es5/synthetic-shadow_debug.js +3 -3
  26. package/dist/wire-service/esm/es2017/wire-service.js +2 -2
  27. package/dist/wire-service/iife/es2017/wire-service.js +2 -2
  28. package/dist/wire-service/iife/es2017/wire-service_debug.js +2 -2
  29. package/dist/wire-service/iife/es5/wire-service.js +2 -2
  30. package/dist/wire-service/iife/es5/wire-service_debug.js +2 -2
  31. package/dist/wire-service/umd/es2017/wire-service.js +2 -2
  32. package/dist/wire-service/umd/es2017/wire-service_debug.js +2 -2
  33. package/dist/wire-service/umd/es5/wire-service.js +2 -2
  34. package/dist/wire-service/umd/es5/wire-service_debug.js +2 -2
  35. package/package.json +7 -7
@@ -339,7 +339,7 @@
339
339
  CACHED_ATTRIBUTE_PROPERTY_MAPPING.set(attrName, propertyName);
340
340
  return propertyName;
341
341
  }
342
- /** version: 2.33.0 */
342
+ /** version: 2.34.0 */
343
343
 
344
344
  /**
345
345
  * Copyright (C) 2018 salesforce.com, inc.
@@ -362,6 +362,7 @@
362
362
  ENABLE_SCOPED_CUSTOM_ELEMENT_REGISTRY: null,
363
363
  ENABLE_FROZEN_TEMPLATE: null,
364
364
  DISABLE_ARIA_REFLECTION_POLYFILL: null,
365
+ ENABLE_PROGRAMMATIC_STYLESHEETS: null,
365
366
  };
366
367
  if (!_globalThis.lwcRuntimeFlags) {
367
368
  Object.defineProperty(_globalThis, 'lwcRuntimeFlags', { value: create(null) });
@@ -405,7 +406,7 @@
405
406
  */
406
407
  function setFeatureFlagForTest(name, value) {
407
408
  }
408
- /** version: 2.33.0 */
409
+ /** version: 2.34.0 */
409
410
 
410
411
  /**
411
412
  * Copyright (C) 2018 salesforce.com, inc.
@@ -469,7 +470,7 @@
469
470
  }
470
471
  }
471
472
  }
472
- /** version: 2.33.0 */
473
+ /** version: 2.34.0 */
473
474
 
474
475
  /*
475
476
  * Copyright (c) 2018, salesforce.com, inc.
@@ -541,6 +542,18 @@
541
542
  }
542
543
  return result;
543
544
  }
545
+ function flattenStylesheets(stylesheets) {
546
+ const list = [];
547
+ for (const stylesheet of stylesheets) {
548
+ if (!Array.isArray(stylesheet)) {
549
+ list.push(stylesheet);
550
+ }
551
+ else {
552
+ list.push(...flattenStylesheets(stylesheet));
553
+ }
554
+ }
555
+ return list;
556
+ }
544
557
  // Set a ref (lwc:ref) on a VM, from a template API
545
558
  function setRefVNode(vm, ref, vnode) {
546
559
  // If this method is called, then vm.refVNodes is set as the template has refs.
@@ -786,6 +799,9 @@
786
799
  // Global HTML Attributes & Properties
787
800
  // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes
788
801
  // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement
802
+ //
803
+ // If you update this list, check for test files that recapitulate the same list. Searching the codebase
804
+ // for e.g. "dropzone" should suffice.
789
805
  assign(create(null), {
790
806
  accessKey: {
791
807
  attribute: 'accesskey',
@@ -2447,6 +2463,9 @@
2447
2463
  stylesheets: newStylesheets,
2448
2464
  stylesheetToken: newStylesheetToken
2449
2465
  } = template;
2466
+ const {
2467
+ stylesheets: newVmStylesheets
2468
+ } = vm;
2450
2469
  const isSyntheticShadow = renderMode === 1 /* RenderMode.Shadow */ && shadowMode === 1 /* ShadowMode.Synthetic */;
2451
2470
  const {
2452
2471
  hasScopedStyles
@@ -2470,7 +2489,9 @@
2470
2489
  }
2471
2490
  // Apply the new template styling token to the host element, if the new template has any
2472
2491
  // associated stylesheets. In the case of light DOM, also ensure there is at least one scoped stylesheet.
2473
- if (!isUndefined$1(newStylesheets) && newStylesheets.length !== 0) {
2492
+ const hasNewStylesheets = hasStyles(newStylesheets);
2493
+ const hasNewVmStylesheets = hasStyles(newVmStylesheets);
2494
+ if (hasNewStylesheets || hasNewVmStylesheets) {
2474
2495
  newToken = newStylesheetToken;
2475
2496
  }
2476
2497
  // Set the new styling token on the host element
@@ -2534,10 +2555,17 @@
2534
2555
  stylesheets,
2535
2556
  stylesheetToken
2536
2557
  } = template;
2558
+ const {
2559
+ stylesheets: vmStylesheets
2560
+ } = vm;
2537
2561
  let content = [];
2538
- if (!isUndefined$1(stylesheets) && stylesheets.length !== 0) {
2562
+ if (hasStyles(stylesheets)) {
2539
2563
  content = evaluateStylesheetsContent(stylesheets, stylesheetToken, vm);
2540
2564
  }
2565
+ // VM (component) stylesheets apply after template stylesheets
2566
+ if (hasStyles(vmStylesheets)) {
2567
+ ArrayPush$1.apply(content, evaluateStylesheetsContent(vmStylesheets, stylesheetToken, vm));
2568
+ }
2541
2569
  return content;
2542
2570
  }
2543
2571
  // It might be worth caching this to avoid doing the lookup repeatedly, but
@@ -2575,10 +2603,13 @@
2575
2603
  const {
2576
2604
  template
2577
2605
  } = getComponentInternalDef(vnode.ctor);
2606
+ const {
2607
+ vm
2608
+ } = vnode;
2578
2609
  const {
2579
2610
  stylesheetToken
2580
2611
  } = template;
2581
- return !isUndefined$1(stylesheetToken) && computeHasScopedStyles(template) ? makeHostToken(stylesheetToken) : null;
2612
+ return !isUndefined$1(stylesheetToken) && computeHasScopedStyles(template, vm) ? makeHostToken(stylesheetToken) : null;
2582
2613
  }
2583
2614
  function getNearestNativeShadowComponent(vm) {
2584
2615
  const owner = getNearestShadowComponent(vm);
@@ -3161,6 +3192,28 @@
3161
3192
  // in fallback mode, the allocation will always set children to
3162
3193
  // empty and delegate the real allocation to the slot elements
3163
3194
  allocateChildren(n2, vm);
3195
+ // Solves an edge case with slotted VFragments in native shadow mode.
3196
+ //
3197
+ // During allocation, in native shadow, slotted VFragment nodes are flattened and their text delimiters are removed
3198
+ // to avoid interfering with native slot behavior. When this happens, if any of the fragments
3199
+ // were not stable, the children must go through the dynamic diffing algo.
3200
+ //
3201
+ // If the new children (n2.children) contain no VFragments, but the previous children (n1.children) were dynamic,
3202
+ // the new nodes must be marked dynamic so that all nodes are properly updated. The only indicator that the new
3203
+ // nodes need to be dynamic comes from the previous children, so we check that to determine whether we need to
3204
+ // mark the new children dynamic.
3205
+ //
3206
+ // Example:
3207
+ // n1.children: [div, VFragment('', div, null, ''), div] => [div, div, null, div]; // marked dynamic
3208
+ // n2.children: [div, null, div] => [div, null, div] // marked ???
3209
+ const {
3210
+ shadowMode,
3211
+ renderMode
3212
+ } = vm;
3213
+ if (shadowMode == 0 /* ShadowMode.Native */ && renderMode !== 0 /* RenderMode.Light */ && hasDynamicChildren(n1.children)) {
3214
+ // No-op if children has already been marked dynamic by 'allocateChildren()'.
3215
+ markAsDynamicChildren(n2.children);
3216
+ }
3164
3217
  }
3165
3218
  // in fallback mode, the children will be always empty, so, nothing
3166
3219
  // will happen, but in native, it does allocate the light dom
@@ -3322,20 +3375,65 @@
3322
3375
  //
3323
3376
  // In case #2, we will always get a fresh VCustomElement.
3324
3377
  const children = vnode.aChildren || vnode.children;
3325
- vm.aChildren = children;
3326
3378
  const {
3327
3379
  renderMode,
3328
3380
  shadowMode
3329
3381
  } = vm;
3382
+ // If any of the children being allocated are VFragments, we remove the text delimiters and flatten all immediate
3383
+ // children VFragments to avoid them interfering with default slot behavior.
3384
+ const allocatedChildren = flattenFragmentsInChildren(children);
3385
+ vnode.children = allocatedChildren;
3386
+ vm.aChildren = allocatedChildren;
3330
3387
  if (shadowMode === 1 /* ShadowMode.Synthetic */ || renderMode === 0 /* RenderMode.Light */) {
3331
3388
  // slow path
3332
- allocateInSlot(vm, children, vnode.owner);
3389
+ allocateInSlot(vm, allocatedChildren, vnode.owner);
3333
3390
  // save the allocated children in case this vnode is reused.
3334
- vnode.aChildren = children;
3391
+ vnode.aChildren = allocatedChildren;
3335
3392
  // every child vnode is now allocated, and the host should receive none directly, it receives them via the shadow!
3336
3393
  vnode.children = EmptyArray;
3337
3394
  }
3338
3395
  }
3396
+ /**
3397
+ * Flattens the contents of all VFragments in an array of VNodes, removes the text delimiters on those VFragments, and
3398
+ * marks the resulting children array as dynamic. Uses a stack (array) to iteratively traverse the nested VFragments
3399
+ * and avoid the perf overhead of creating/destroying throwaway arrays/objects in a recursive approach.
3400
+ *
3401
+ * With the delimiters removed, the contents are marked dynamic so they are diffed correctly.
3402
+ *
3403
+ * This function is used for slotted VFragments to avoid the text delimiters interfering with slotting functionality.
3404
+ */
3405
+ function flattenFragmentsInChildren(children) {
3406
+ const flattenedChildren = [];
3407
+ // Initialize our stack with the direct children of the custom component and check whether we have a VFragment.
3408
+ // If no VFragment is found in children, we don't need to traverse anything or mark the children dynamic and can return early.
3409
+ const nodeStack = [];
3410
+ let fragmentFound = false;
3411
+ for (let i = children.length - 1; i > -1; i -= 1) {
3412
+ const child = children[i];
3413
+ ArrayPush$1.call(nodeStack, child);
3414
+ fragmentFound = fragmentFound || !!(child && isVFragment(child));
3415
+ }
3416
+ if (!fragmentFound) {
3417
+ return children;
3418
+ }
3419
+ let currentNode;
3420
+ while (!isUndefined$1(currentNode = ArrayPop.call(nodeStack))) {
3421
+ if (!isNull(currentNode) && isVFragment(currentNode)) {
3422
+ const fChildren = currentNode.children;
3423
+ // Ignore the start and end text node delimiters
3424
+ for (let i = fChildren.length - 2; i > 0; i -= 1) {
3425
+ ArrayPush$1.call(nodeStack, fChildren[i]);
3426
+ }
3427
+ } else {
3428
+ ArrayPush$1.call(flattenedChildren, currentNode);
3429
+ }
3430
+ }
3431
+ // We always mark the children as dynamic because nothing generates stable VFragments yet.
3432
+ // If/when stable VFragments are generated by the compiler, this code should be updated to
3433
+ // not mark dynamic if all flattened VFragments were stable.
3434
+ markAsDynamicChildren(flattenedChildren);
3435
+ return flattenedChildren;
3436
+ }
3339
3437
  function createViewModelHook(elm, vnode, renderer) {
3340
3438
  let vm = getAssociatedVMIfPresent(elm);
3341
3439
  // There is a possibility that a custom element is registered under tagName, in which case, the
@@ -3357,22 +3455,20 @@
3357
3455
  });
3358
3456
  return vm;
3359
3457
  }
3360
- /**
3361
- * Collects all slots into a SlotSet, traversing through VFragment Nodes
3362
- */
3363
- function collectSlots(vm, children, cmpSlotsMapping) {
3458
+ function allocateInSlot(vm, children, owner) {
3364
3459
  var _a, _b;
3460
+ const {
3461
+ cmpSlots: {
3462
+ slotAssignments: oldSlotsMapping
3463
+ }
3464
+ } = vm;
3465
+ const cmpSlotsMapping = create(null);
3466
+ // Collect all slots into cmpSlotsMapping
3365
3467
  for (let i = 0, len = children.length; i < len; i += 1) {
3366
3468
  const vnode = children[i];
3367
3469
  if (isNull(vnode)) {
3368
3470
  continue;
3369
3471
  }
3370
- // Dive further iff the content is wrapped in a VFragment
3371
- if (isVFragment(vnode)) {
3372
- // Remove the text delimiter nodes to avoid overriding default slot content
3373
- collectSlots(vm, vnode.children.slice(1, -1), cmpSlotsMapping);
3374
- continue;
3375
- }
3376
3472
  let slotName = '';
3377
3473
  if (isVBaseElement(vnode)) {
3378
3474
  slotName = (_b = (_a = vnode.data.attrs) === null || _a === void 0 ? void 0 : _a.slot) !== null && _b !== void 0 ? _b : '';
@@ -3382,15 +3478,6 @@
3382
3478
  const vnodes = cmpSlotsMapping[slotName] = cmpSlotsMapping[slotName] || [];
3383
3479
  ArrayPush$1.call(vnodes, vnode);
3384
3480
  }
3385
- }
3386
- function allocateInSlot(vm, children, owner) {
3387
- const {
3388
- cmpSlots: {
3389
- slotAssignments: oldSlotsMapping
3390
- }
3391
- } = vm;
3392
- const cmpSlotsMapping = create(null);
3393
- collectSlots(vm, children, cmpSlotsMapping);
3394
3481
  vm.cmpSlots = {
3395
3482
  owner,
3396
3483
  slotAssignments: cmpSlotsMapping
@@ -3421,14 +3508,14 @@
3421
3508
  }
3422
3509
  }
3423
3510
  // Using a WeakMap instead of a WeakSet because this one works in IE11 :(
3424
- const FromIteration = new WeakMap();
3425
- // dynamic children means it was generated by an iteration
3426
- // in a template, and will require a more complex diffing algo.
3511
+ const DynamicChildren = new WeakMap();
3512
+ // dynamic children means it was either generated by an iteration in a template
3513
+ // or part of an unstable fragment, and will require a more complex diffing algo.
3427
3514
  function markAsDynamicChildren(children) {
3428
- FromIteration.set(children, 1);
3515
+ DynamicChildren.set(children, 1);
3429
3516
  }
3430
3517
  function hasDynamicChildren(children) {
3431
- return FromIteration.has(children);
3518
+ return DynamicChildren.has(children);
3432
3519
  }
3433
3520
  function createKeyToOldIdx(children, beginIdx, endIdx) {
3434
3521
  const map = {};
@@ -4087,7 +4174,7 @@
4087
4174
  // Create a brand new template cache for the swapped templated.
4088
4175
  context.tplCache = create(null);
4089
4176
  // Set the computeHasScopedStyles property in the context, to avoid recomputing it repeatedly.
4090
- context.hasScopedStyles = computeHasScopedStyles(html);
4177
+ context.hasScopedStyles = computeHasScopedStyles(html, vm);
4091
4178
  // Update the scoping token on the host element.
4092
4179
  updateStylesheetToken(vm, html);
4093
4180
  // Evaluate, create stylesheet and cache the produced VNode for future
@@ -4122,9 +4209,8 @@
4122
4209
  });
4123
4210
  return vnodes;
4124
4211
  }
4125
- function computeHasScopedStyles(template) {
4126
- const { stylesheets } = template;
4127
- if (!isUndefined$1(stylesheets)) {
4212
+ function computeHasScopedStylesInStylesheets(stylesheets) {
4213
+ if (hasStyles(stylesheets)) {
4128
4214
  for (let i = 0; i < stylesheets.length; i++) {
4129
4215
  if (isTrue(stylesheets[i][KEY__SCOPED_CSS])) {
4130
4216
  return true;
@@ -4133,6 +4219,15 @@
4133
4219
  }
4134
4220
  return false;
4135
4221
  }
4222
+ function computeHasScopedStyles(template, vm) {
4223
+ const { stylesheets } = template;
4224
+ const vmStylesheets = !isUndefined$1(vm) ? vm.stylesheets : null;
4225
+ return (computeHasScopedStylesInStylesheets(stylesheets) ||
4226
+ computeHasScopedStylesInStylesheets(vmStylesheets));
4227
+ }
4228
+ function hasStyles(stylesheets) {
4229
+ return !isUndefined$1(stylesheets) && !isNull(stylesheets) && stylesheets.length > 0;
4230
+ }
4136
4231
  let vmBeingConstructed = null;
4137
4232
  function isBeingConstructed(vm) {
4138
4233
  return vmBeingConstructed === vm;
@@ -4409,6 +4504,7 @@
4409
4504
  // Properties set right after VM creation.
4410
4505
  tro: null,
4411
4506
  shadowMode: null,
4507
+ stylesheets: null,
4412
4508
  // Properties set by the LightningElement constructor.
4413
4509
  component: null,
4414
4510
  shadowRoot: null,
@@ -4418,6 +4514,7 @@
4418
4514
  getHook,
4419
4515
  renderer
4420
4516
  };
4517
+ vm.stylesheets = computeStylesheets(vm, def.ctor);
4421
4518
  vm.shadowMode = computeShadowMode(vm, renderer);
4422
4519
  vm.tro = getTemplateReactiveObserver(vm);
4423
4520
  // Create component instance associated to the vm and the element.
@@ -4428,6 +4525,40 @@
4428
4525
  }
4429
4526
  return vm;
4430
4527
  }
4528
+ function validateComponentStylesheets(vm, stylesheets) {
4529
+ let valid = true;
4530
+ const validate = arrayOrStylesheet => {
4531
+ if (isArray$1(arrayOrStylesheet)) {
4532
+ for (let i = 0; i < arrayOrStylesheet.length; i++) {
4533
+ validate(arrayOrStylesheet[i]);
4534
+ }
4535
+ } else if (!isFunction$1(arrayOrStylesheet)) {
4536
+ // function assumed to be a stylesheet factory
4537
+ valid = false;
4538
+ }
4539
+ };
4540
+ if (!isArray$1(stylesheets)) {
4541
+ valid = false;
4542
+ } else {
4543
+ validate(stylesheets);
4544
+ }
4545
+ return valid;
4546
+ }
4547
+ // Validate and flatten any stylesheets defined as `static stylesheets`
4548
+ function computeStylesheets(vm, ctor) {
4549
+ if (lwcRuntimeFlags.ENABLE_PROGRAMMATIC_STYLESHEETS) {
4550
+ const {
4551
+ stylesheets
4552
+ } = ctor;
4553
+ if (!isUndefined$1(stylesheets)) {
4554
+ const valid = validateComponentStylesheets(vm, stylesheets);
4555
+ if (valid) {
4556
+ return flattenStylesheets(stylesheets);
4557
+ }
4558
+ }
4559
+ }
4560
+ return null;
4561
+ }
4431
4562
  function computeShadowMode(vm, renderer) {
4432
4563
  const {
4433
4564
  def
@@ -6383,7 +6514,7 @@
6383
6514
  function isNull(obj) {
6384
6515
  return obj === null;
6385
6516
  }
6386
- /** version: 2.33.0 */
6517
+ /** version: 2.34.0 */
6387
6518
 
6388
6519
  /*
6389
6520
  * Copyright (c) 2018, salesforce.com, inc.
@@ -6936,7 +7067,7 @@
6936
7067
  });
6937
7068
  freeze(LightningElement);
6938
7069
  seal(LightningElement.prototype);
6939
- /* version: 2.33.0 */
7070
+ /* version: 2.34.0 */
6940
7071
 
6941
7072
  exports.LightningElement = LightningElement;
6942
7073
  exports.__unstable__ProfilerControl = profilerControl;