lwc 2.33.0 → 2.35.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 (39) hide show
  1. package/dist/engine-dom/esm/es2017/engine-dom.js +1022 -649
  2. package/dist/engine-dom/iife/es2017/engine-dom.js +1022 -648
  3. package/dist/engine-dom/iife/es2017/engine-dom.min.js +1 -1
  4. package/dist/engine-dom/iife/es2017/engine-dom_debug.js +824 -557
  5. package/dist/engine-dom/iife/es5/engine-dom.js +1179 -802
  6. package/dist/engine-dom/iife/es5/engine-dom.min.js +1 -1
  7. package/dist/engine-dom/iife/es5/engine-dom_debug.js +1002 -720
  8. package/dist/engine-dom/umd/es2017/engine-dom.js +1022 -648
  9. package/dist/engine-dom/umd/es2017/engine-dom.min.js +1 -1
  10. package/dist/engine-dom/umd/es2017/engine-dom_debug.js +824 -557
  11. package/dist/engine-dom/umd/es5/engine-dom.js +1179 -802
  12. package/dist/engine-dom/umd/es5/engine-dom.min.js +1 -1
  13. package/dist/engine-dom/umd/es5/engine-dom_debug.js +1002 -720
  14. package/dist/engine-server/commonjs/es2017/engine-server.js +789 -638
  15. package/dist/engine-server/commonjs/es2017/engine-server.min.js +1 -1
  16. package/dist/engine-server/esm/es2017/engine-server.js +789 -638
  17. package/dist/synthetic-shadow/esm/es2017/synthetic-shadow.js +15 -4
  18. package/dist/synthetic-shadow/iife/es2017/synthetic-shadow.js +15 -4
  19. package/dist/synthetic-shadow/iife/es2017/synthetic-shadow.min.js +2 -2
  20. package/dist/synthetic-shadow/iife/es2017/synthetic-shadow_debug.js +15 -4
  21. package/dist/synthetic-shadow/iife/es5/synthetic-shadow.js +18 -3
  22. package/dist/synthetic-shadow/iife/es5/synthetic-shadow.min.js +2 -2
  23. package/dist/synthetic-shadow/iife/es5/synthetic-shadow_debug.js +18 -3
  24. package/dist/synthetic-shadow/umd/es2017/synthetic-shadow.js +15 -4
  25. package/dist/synthetic-shadow/umd/es2017/synthetic-shadow.min.js +2 -2
  26. package/dist/synthetic-shadow/umd/es2017/synthetic-shadow_debug.js +15 -4
  27. package/dist/synthetic-shadow/umd/es5/synthetic-shadow.js +18 -3
  28. package/dist/synthetic-shadow/umd/es5/synthetic-shadow.min.js +2 -2
  29. package/dist/synthetic-shadow/umd/es5/synthetic-shadow_debug.js +18 -3
  30. package/dist/wire-service/esm/es2017/wire-service.js +2 -2
  31. package/dist/wire-service/iife/es2017/wire-service.js +2 -2
  32. package/dist/wire-service/iife/es2017/wire-service_debug.js +2 -2
  33. package/dist/wire-service/iife/es5/wire-service.js +2 -2
  34. package/dist/wire-service/iife/es5/wire-service_debug.js +2 -2
  35. package/dist/wire-service/umd/es2017/wire-service.js +2 -2
  36. package/dist/wire-service/umd/es2017/wire-service_debug.js +2 -2
  37. package/dist/wire-service/umd/es5/wire-service.js +2 -2
  38. package/dist/wire-service/umd/es5/wire-service_debug.js +2 -2
  39. package/package.json +7 -7
@@ -51,7 +51,7 @@
51
51
  const { isArray: isArray$1 } = Array;
52
52
  const { concat: ArrayConcat$1, copyWithin: ArrayCopyWithin, fill: ArrayFill, filter: ArrayFilter, find: ArrayFind, indexOf: ArrayIndexOf, join: ArrayJoin, map: ArrayMap, pop: ArrayPop, push: ArrayPush$1, reduce: ArrayReduce, reverse: ArrayReverse, shift: ArrayShift, slice: ArraySlice, some: ArraySome, sort: ArraySort, splice: ArraySplice, unshift: ArrayUnshift, forEach, } = Array.prototype;
53
53
  const { fromCharCode: StringFromCharCode } = String;
54
- const { charCodeAt: StringCharCodeAt, replace: StringReplace, slice: StringSlice, toLowerCase: StringToLowerCase, } = String.prototype;
54
+ const { charCodeAt: StringCharCodeAt, replace: StringReplace, split: StringSplit, slice: StringSlice, toLowerCase: StringToLowerCase, } = String.prototype;
55
55
  function isUndefined$1(obj) {
56
56
  return obj === undefined;
57
57
  }
@@ -188,6 +188,19 @@
188
188
  });
189
189
  return { AriaAttrNameToPropNameMap, AriaPropNameToAttrNameMap };
190
190
  })();
191
+ // These attributes take either an ID or a list of IDs as values.
192
+ // This includes aria-* attributes as well as the special non-ARIA "for" attribute
193
+ const ID_REFERENCING_ATTRIBUTES_SET = new Set([
194
+ 'aria-activedescendant',
195
+ 'aria-controls',
196
+ 'aria-describedby',
197
+ 'aria-details',
198
+ 'aria-errormessage',
199
+ 'aria-flowto',
200
+ 'aria-labelledby',
201
+ 'aria-owns',
202
+ 'for',
203
+ ]);
191
204
 
192
205
  /*
193
206
  * Copyright (c) 2018, salesforce.com, inc.
@@ -243,6 +256,8 @@
243
256
  const KEY__SHADOW_TOKEN = '$shadowToken$';
244
257
  const KEY__SYNTHETIC_MODE = '$$lwc-synthetic-mode';
245
258
  const KEY__SCOPED_CSS = '$scoped$';
259
+ const KEY__NATIVE_GET_ELEMENT_BY_ID = '$nativeGetElementById$';
260
+ const KEY__NATIVE_QUERY_SELECTOR_ALL = '$nativeQuerySelectorAll$';
246
261
  const XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
247
262
  const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
248
263
  const XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink';
@@ -350,9 +365,9 @@
350
365
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
351
366
  */
352
367
  // Increment whenever the LWC template compiler changes
353
- const LWC_VERSION = "2.33.0";
368
+ const LWC_VERSION = "2.35.0";
354
369
  const LWC_VERSION_COMMENT_REGEX = /\/\*LWC compiler v([\d.]+)\*\/\s*}/;
355
- /** version: 2.33.0 */
370
+ /** version: 2.35.0 */
356
371
 
357
372
  /**
358
373
  * Copyright (C) 2018 salesforce.com, inc.
@@ -375,6 +390,7 @@
375
390
  ENABLE_SCOPED_CUSTOM_ELEMENT_REGISTRY: null,
376
391
  ENABLE_FROZEN_TEMPLATE: null,
377
392
  DISABLE_ARIA_REFLECTION_POLYFILL: null,
393
+ ENABLE_PROGRAMMATIC_STYLESHEETS: null,
378
394
  };
379
395
  if (!_globalThis.lwcRuntimeFlags) {
380
396
  Object.defineProperty(_globalThis, 'lwcRuntimeFlags', { value: create(null) });
@@ -428,7 +444,7 @@
428
444
  setFeatureFlag(name, value);
429
445
  }
430
446
  }
431
- /** version: 2.33.0 */
447
+ /** version: 2.35.0 */
432
448
 
433
449
  /**
434
450
  * Copyright (C) 2018 salesforce.com, inc.
@@ -492,7 +508,7 @@
492
508
  }
493
509
  }
494
510
  }
495
- /** version: 2.33.0 */
511
+ /** version: 2.35.0 */
496
512
 
497
513
  /*
498
514
  * Copyright (c) 2018, salesforce.com, inc.
@@ -560,94 +576,167 @@
560
576
  * SPDX-License-Identifier: MIT
561
577
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
562
578
  */
563
- let nextTickCallbackQueue = [];
564
- const SPACE_CHAR = 32;
565
- const EmptyObject = seal(create(null));
566
- const EmptyArray = seal([]);
567
- function flushCallbackQueue() {
568
- if (process.env.NODE_ENV !== 'production') {
569
- if (nextTickCallbackQueue.length === 0) {
570
- throw new Error(`Internal Error: If callbackQueue is scheduled, it is because there must be at least one callback on this pending queue.`);
579
+ /** Callbacks to invoke when reporting is enabled **/
580
+ const onReportingEnabledCallbacks = [];
581
+ /** The currently assigned reporting dispatcher. */
582
+ let currentDispatcher$1 = noop;
583
+ /**
584
+ * Whether reporting is enabled.
585
+ *
586
+ * Note that this may seem redundant, given you can just check if the currentDispatcher is undefined,
587
+ * but it turns out that Terser only strips out unused code if we use this explicit boolean.
588
+ */
589
+ let enabled$1 = false;
590
+ const reportingControl = {
591
+ /**
592
+ * Attach a new reporting control (aka dispatcher).
593
+ *
594
+ * @param dispatcher - reporting control
595
+ */
596
+ attachDispatcher(dispatcher) {
597
+ enabled$1 = true;
598
+ currentDispatcher$1 = dispatcher;
599
+ for (const callback of onReportingEnabledCallbacks) {
600
+ try {
601
+ callback();
602
+ }
603
+ catch (err) {
604
+ // This should never happen. But if it does, we don't want one callback to cause another to fail
605
+ // eslint-disable-next-line no-console
606
+ console.error('Could not invoke callback', err);
607
+ }
571
608
  }
609
+ onReportingEnabledCallbacks.length = 0; // clear the array
610
+ },
611
+ /**
612
+ * Detach the current reporting control (aka dispatcher).
613
+ */
614
+ detachDispatcher() {
615
+ enabled$1 = false;
616
+ currentDispatcher$1 = noop;
617
+ },
618
+ };
619
+ /**
620
+ * Call a callback when reporting is enabled, or immediately if reporting is already enabled.
621
+ * Will only ever be called once.
622
+ * @param callback
623
+ */
624
+ function onReportingEnabled(callback) {
625
+ if (enabled$1) {
626
+ // call immediately
627
+ callback();
572
628
  }
573
- const callbacks = nextTickCallbackQueue;
574
- nextTickCallbackQueue = []; // reset to a new queue
575
- for (let i = 0, len = callbacks.length; i < len; i += 1) {
576
- callbacks[i]();
629
+ else {
630
+ // call later
631
+ onReportingEnabledCallbacks.push(callback);
577
632
  }
578
633
  }
579
- function addCallbackToNextTick(callback) {
580
- if (process.env.NODE_ENV !== 'production') {
581
- if (!isFunction$1(callback)) {
582
- throw new Error(`Internal Error: addCallbackToNextTick() can only accept a function callback`);
583
- }
584
- }
585
- if (nextTickCallbackQueue.length === 0) {
586
- Promise.resolve().then(flushCallbackQueue);
634
+ /**
635
+ * Report to the current dispatcher, if there is one.
636
+ * @param reportingEventId
637
+ * @param vm
638
+ */
639
+ function report(reportingEventId, vm) {
640
+ if (enabled$1) {
641
+ currentDispatcher$1(reportingEventId, vm.tagName, vm.idx);
587
642
  }
588
- ArrayPush$1.call(nextTickCallbackQueue, callback);
589
643
  }
590
- function guid() {
591
- function s4() {
592
- return Math.floor((1 + Math.random()) * 0x10000)
593
- .toString(16)
594
- .substring(1);
644
+
645
+ /*
646
+ * Copyright (c) 2018, salesforce.com, inc.
647
+ * All rights reserved.
648
+ * SPDX-License-Identifier: MIT
649
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
650
+ */
651
+ function getComponentTag(vm) {
652
+ return `<${StringToLowerCase.call(vm.tagName)}>`;
653
+ }
654
+ // TODO [#1695]: Unify getComponentStack and getErrorComponentStack
655
+ function getComponentStack(vm) {
656
+ const stack = [];
657
+ let prefix = '';
658
+ while (!isNull(vm.owner)) {
659
+ ArrayPush$1.call(stack, prefix + getComponentTag(vm));
660
+ vm = vm.owner;
661
+ prefix += '\t';
595
662
  }
596
- return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
663
+ return ArrayJoin.call(stack, '\n');
597
664
  }
598
- // Borrowed from Vue template compiler.
599
- // https://github.com/vuejs/vue/blob/531371b818b0e31a989a06df43789728f23dc4e8/src/platforms/web/util/style.js#L5-L16
600
- const DECLARATION_DELIMITER = /;(?![^(]*\))/g;
601
- const PROPERTY_DELIMITER = /:(.+)/;
602
- function parseStyleText(cssText) {
603
- const styleMap = {};
604
- const declarations = cssText.split(DECLARATION_DELIMITER);
605
- for (const declaration of declarations) {
606
- if (declaration) {
607
- const [prop, value] = declaration.split(PROPERTY_DELIMITER);
608
- if (prop !== undefined && value !== undefined) {
609
- styleMap[prop.trim()] = value.trim();
610
- }
611
- }
665
+ function getErrorComponentStack(vm) {
666
+ const wcStack = [];
667
+ let currentVm = vm;
668
+ while (!isNull(currentVm)) {
669
+ ArrayPush$1.call(wcStack, getComponentTag(currentVm));
670
+ currentVm = currentVm.owner;
612
671
  }
613
- return styleMap;
672
+ return wcStack.reverse().join('\n\t');
614
673
  }
615
- // Make a shallow copy of an object but omit the given key
616
- function cloneAndOmitKey(object, keyToOmit) {
617
- const result = {};
618
- for (const key of Object.keys(object)) {
619
- if (key !== keyToOmit) {
620
- result[key] = object[key];
621
- }
674
+
675
+ /*
676
+ * Copyright (c) 2018, salesforce.com, inc.
677
+ * All rights reserved.
678
+ * SPDX-License-Identifier: MIT
679
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
680
+ */
681
+ function addErrorComponentStack(vm, error) {
682
+ if (!isFrozen(error) && isUndefined$1(error.wcStack)) {
683
+ const wcStack = getErrorComponentStack(vm);
684
+ defineProperty(error, 'wcStack', {
685
+ get() {
686
+ return wcStack;
687
+ },
688
+ });
622
689
  }
623
- return result;
624
690
  }
625
- function flattenStylesheets(stylesheets) {
626
- const list = [];
627
- for (const stylesheet of stylesheets) {
628
- if (!Array.isArray(stylesheet)) {
629
- list.push(stylesheet);
630
- }
631
- else {
632
- list.push(...flattenStylesheets(stylesheet));
691
+
692
+ /*
693
+ * Copyright (c) 2018, salesforce.com, inc.
694
+ * All rights reserved.
695
+ * SPDX-License-Identifier: MIT
696
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
697
+ */
698
+ const alreadyLoggedMessages = new Set();
699
+ // @ts-ignore
700
+ if (process.env.NODE_ENV !== 'production' && typeof __karma__ !== 'undefined') {
701
+ // @ts-ignore
702
+ window.__lwcResetAlreadyLoggedMessages = () => {
703
+ alreadyLoggedMessages.clear();
704
+ };
705
+ }
706
+ function log(method, message, vm, once) {
707
+ let msg = `[LWC ${method}]: ${message}`;
708
+ if (!isUndefined$1(vm)) {
709
+ msg = `${msg}\n${getComponentStack(vm)}`;
710
+ }
711
+ if (once) {
712
+ if (alreadyLoggedMessages.has(msg)) {
713
+ return;
633
714
  }
715
+ alreadyLoggedMessages.add(msg);
634
716
  }
635
- return list;
636
- }
637
- // Set a ref (lwc:ref) on a VM, from a template API
638
- function setRefVNode(vm, ref, vnode) {
639
- if (process.env.NODE_ENV !== 'production' && isUndefined$1(vm.refVNodes)) {
640
- throw new Error('refVNodes must be defined when setting a ref');
717
+ // In Jest tests, reduce the warning and error verbosity by not printing the callstack
718
+ if (process.env.NODE_ENV === 'test') {
719
+ /* eslint-disable-next-line no-console */
720
+ console[method](msg);
721
+ return;
641
722
  }
642
- // If this method is called, then vm.refVNodes is set as the template has refs.
643
- // If not, then something went wrong and we threw an error above.
644
- const refVNodes = vm.refVNodes;
645
- // In cases of conflict (two elements with the same ref), prefer, the last one,
646
- // in depth-first traversal order.
647
- if (!(ref in refVNodes) || refVNodes[ref].key < vnode.key) {
648
- refVNodes[ref] = vnode;
723
+ try {
724
+ throw new Error(msg);
725
+ }
726
+ catch (e) {
727
+ /* eslint-disable-next-line no-console */
728
+ console[method](e);
649
729
  }
650
730
  }
731
+ function logError(message, vm) {
732
+ log('error', message, vm, false);
733
+ }
734
+ function logWarn(message, vm) {
735
+ log('warn', message, vm, false);
736
+ }
737
+ function logWarnOnce(message, vm) {
738
+ log('warn', message, vm, true);
739
+ }
651
740
 
652
741
  /*
653
742
  * Copyright (c) 2019, salesforce.com, inc.
@@ -769,80 +858,97 @@
769
858
  * SPDX-License-Identifier: MIT
770
859
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
771
860
  */
772
- function getComponentTag(vm) {
773
- return `<${StringToLowerCase.call(vm.tagName)}>`;
774
- }
775
- // TODO [#1695]: Unify getComponentStack and getErrorComponentStack
776
- function getComponentStack(vm) {
777
- const stack = [];
778
- let prefix = '';
779
- while (!isNull(vm.owner)) {
780
- ArrayPush$1.call(stack, prefix + getComponentTag(vm));
781
- vm = vm.owner;
782
- prefix += '\t';
783
- }
784
- return ArrayJoin.call(stack, '\n');
785
- }
786
- function getErrorComponentStack(vm) {
787
- const wcStack = [];
788
- let currentVm = vm;
789
- while (!isNull(currentVm)) {
790
- ArrayPush$1.call(wcStack, getComponentTag(currentVm));
791
- currentVm = currentVm.owner;
861
+ let nextTickCallbackQueue = [];
862
+ const SPACE_CHAR = 32;
863
+ const EmptyObject = seal(create(null));
864
+ const EmptyArray = seal([]);
865
+ function flushCallbackQueue() {
866
+ if (process.env.NODE_ENV !== 'production') {
867
+ if (nextTickCallbackQueue.length === 0) {
868
+ throw new Error(`Internal Error: If callbackQueue is scheduled, it is because there must be at least one callback on this pending queue.`);
869
+ }
792
870
  }
793
- return wcStack.reverse().join('\n\t');
794
- }
795
-
796
- /*
797
- * Copyright (c) 2018, salesforce.com, inc.
798
- * All rights reserved.
799
- * SPDX-License-Identifier: MIT
800
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
801
- */
802
- function addErrorComponentStack(vm, error) {
803
- if (!isFrozen(error) && isUndefined$1(error.wcStack)) {
804
- const wcStack = getErrorComponentStack(vm);
805
- defineProperty(error, 'wcStack', {
806
- get() {
807
- return wcStack;
808
- },
809
- });
871
+ const callbacks = nextTickCallbackQueue;
872
+ nextTickCallbackQueue = []; // reset to a new queue
873
+ for (let i = 0, len = callbacks.length; i < len; i += 1) {
874
+ callbacks[i]();
810
875
  }
811
876
  }
812
-
813
- /*
814
- * Copyright (c) 2018, salesforce.com, inc.
815
- * All rights reserved.
816
- * SPDX-License-Identifier: MIT
817
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
818
- */
819
- function log(method, message, vm) {
820
- let msg = `[LWC ${method}]: ${message}`;
821
- if (!isUndefined$1(vm)) {
822
- msg = `${msg}\n${getComponentStack(vm)}`;
823
- }
824
- if (process.env.NODE_ENV === 'test') {
825
- /* eslint-disable-next-line no-console */
826
- console[method](msg);
827
- return;
828
- }
829
- try {
830
- throw new Error(msg);
877
+ function addCallbackToNextTick(callback) {
878
+ if (process.env.NODE_ENV !== 'production') {
879
+ if (!isFunction$1(callback)) {
880
+ throw new Error(`Internal Error: addCallbackToNextTick() can only accept a function callback`);
881
+ }
831
882
  }
832
- catch (e) {
833
- /* eslint-disable-next-line no-console */
834
- console[method](e);
883
+ if (nextTickCallbackQueue.length === 0) {
884
+ Promise.resolve().then(flushCallbackQueue);
835
885
  }
886
+ ArrayPush$1.call(nextTickCallbackQueue, callback);
836
887
  }
837
- function logError(message, vm) {
838
- log('error', message, vm);
839
- }
840
- function logWarn(message, vm) {
841
- log('warn', message, vm);
888
+ function guid() {
889
+ function s4() {
890
+ return Math.floor((1 + Math.random()) * 0x10000)
891
+ .toString(16)
892
+ .substring(1);
893
+ }
894
+ return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
842
895
  }
843
-
844
- /*
845
- * Copyright (c) 2020, salesforce.com, inc.
896
+ // Borrowed from Vue template compiler.
897
+ // https://github.com/vuejs/vue/blob/531371b818b0e31a989a06df43789728f23dc4e8/src/platforms/web/util/style.js#L5-L16
898
+ const DECLARATION_DELIMITER = /;(?![^(]*\))/g;
899
+ const PROPERTY_DELIMITER = /:(.+)/;
900
+ function parseStyleText(cssText) {
901
+ const styleMap = {};
902
+ const declarations = cssText.split(DECLARATION_DELIMITER);
903
+ for (const declaration of declarations) {
904
+ if (declaration) {
905
+ const [prop, value] = declaration.split(PROPERTY_DELIMITER);
906
+ if (prop !== undefined && value !== undefined) {
907
+ styleMap[prop.trim()] = value.trim();
908
+ }
909
+ }
910
+ }
911
+ return styleMap;
912
+ }
913
+ // Make a shallow copy of an object but omit the given key
914
+ function cloneAndOmitKey(object, keyToOmit) {
915
+ const result = {};
916
+ for (const key of Object.keys(object)) {
917
+ if (key !== keyToOmit) {
918
+ result[key] = object[key];
919
+ }
920
+ }
921
+ return result;
922
+ }
923
+ function flattenStylesheets(stylesheets) {
924
+ const list = [];
925
+ for (const stylesheet of stylesheets) {
926
+ if (!Array.isArray(stylesheet)) {
927
+ list.push(stylesheet);
928
+ }
929
+ else {
930
+ list.push(...flattenStylesheets(stylesheet));
931
+ }
932
+ }
933
+ return list;
934
+ }
935
+ // Set a ref (lwc:ref) on a VM, from a template API
936
+ function setRefVNode(vm, ref, vnode) {
937
+ if (process.env.NODE_ENV !== 'production' && isUndefined$1(vm.refVNodes)) {
938
+ throw new Error('refVNodes must be defined when setting a ref');
939
+ }
940
+ // If this method is called, then vm.refVNodes is set as the template has refs.
941
+ // If not, then something went wrong and we threw an error above.
942
+ const refVNodes = vm.refVNodes;
943
+ // In cases of conflict (two elements with the same ref), prefer, the last one,
944
+ // in depth-first traversal order.
945
+ if (!(ref in refVNodes) || refVNodes[ref].key < vnode.key) {
946
+ refVNodes[ref] = vnode;
947
+ }
948
+ }
949
+
950
+ /*
951
+ * Copyright (c) 2020, salesforce.com, inc.
846
952
  * All rights reserved.
847
953
  * SPDX-License-Identifier: MIT
848
954
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
@@ -890,7 +996,10 @@
890
996
  // Global HTML Attributes & Properties
891
997
  // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes
892
998
  // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement
893
- const globalHTMLProperties = assign(create(null), {
999
+ //
1000
+ // If you update this list, check for test files that recapitulate the same list. Searching the codebase
1001
+ // for e.g. "dropzone" should suffice.
1002
+ const globalHTMLProperties = {
894
1003
  accessKey: {
895
1004
  attribute: 'accesskey',
896
1005
  },
@@ -975,7 +1084,7 @@
975
1084
  role: {
976
1085
  attribute: 'role',
977
1086
  },
978
- });
1087
+ };
979
1088
  let controlledElement = null;
980
1089
  let controlledAttributeName;
981
1090
  function isAttributeLocked(elm, attrName) {
@@ -2437,89 +2546,377 @@
2437
2546
  * SPDX-License-Identifier: MIT
2438
2547
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
2439
2548
  */
2440
- function api$1() {
2441
- if (process.env.NODE_ENV !== 'production') {
2442
- assert.fail(`@api decorator can only be used as a decorator function.`);
2443
- }
2444
- throw new Error();
2549
+ const DeprecatedWiredElementHost = '$$DeprecatedWiredElementHostKey$$';
2550
+ const DeprecatedWiredParamsMeta = '$$DeprecatedWiredParamsMetaKey$$';
2551
+ const WIRE_DEBUG_ENTRY = '@wire';
2552
+ const WireMetaMap = new Map();
2553
+ class WireContextRegistrationEvent extends CustomEvent {
2554
+ constructor(adapterToken, {
2555
+ setNewContext,
2556
+ setDisconnectedCallback
2557
+ }) {
2558
+ super(adapterToken, {
2559
+ bubbles: true,
2560
+ composed: true
2561
+ });
2562
+ defineProperties(this, {
2563
+ setNewContext: {
2564
+ value: setNewContext
2565
+ },
2566
+ setDisconnectedCallback: {
2567
+ value: setDisconnectedCallback
2568
+ }
2569
+ });
2570
+ }
2445
2571
  }
2446
- function createPublicPropertyDescriptor(key) {
2447
- return {
2448
- get() {
2449
- const vm = getAssociatedVM(this);
2450
- if (isBeingConstructed(vm)) {
2451
- if (process.env.NODE_ENV !== 'production') {
2452
- logError(`Can’t read the value of property \`${toString$1(key)}\` from the constructor because the owner component hasn’t set the value yet. Instead, use the constructor to set a default value for the property.`, vm);
2453
- }
2454
- return;
2455
- }
2456
- componentValueObserved(vm, key);
2457
- return vm.cmpProps[key];
2458
- },
2459
- set(newValue) {
2460
- const vm = getAssociatedVM(this);
2461
- if (process.env.NODE_ENV !== 'production') {
2462
- const vmBeingRendered = getVMBeingRendered();
2463
- assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm}.${toString$1(key)}`);
2464
- assert.invariant(!isUpdatingTemplate, `Updating the template of ${vmBeingRendered} has side effects on the state of ${vm}.${toString$1(key)}`);
2465
- }
2466
- vm.cmpProps[key] = newValue;
2467
- componentValueMutated(vm, key);
2468
- },
2469
- enumerable: true,
2470
- configurable: true,
2471
- };
2572
+ function createFieldDataCallback(vm, name) {
2573
+ return value => {
2574
+ updateComponentValue(vm, name, value);
2575
+ };
2472
2576
  }
2473
- function createPublicAccessorDescriptor(key, descriptor) {
2474
- const { get, set, enumerable, configurable } = descriptor;
2475
- if (!isFunction$1(get)) {
2476
- if (process.env.NODE_ENV !== 'production') {
2477
- assert.invariant(isFunction$1(get), `Invalid compiler output for public accessor ${toString$1(key)} decorated with @api`);
2478
- }
2479
- throw new Error();
2577
+ function createMethodDataCallback(vm, method) {
2578
+ return value => {
2579
+ // dispatching new value into the wired method
2580
+ runWithBoundaryProtection(vm, vm.owner, noop, () => {
2581
+ // job
2582
+ method.call(vm.component, value);
2583
+ }, noop);
2584
+ };
2585
+ }
2586
+ function createConfigWatcher(component, configCallback, callbackWhenConfigIsReady) {
2587
+ let hasPendingConfig = false;
2588
+ // creating the reactive observer for reactive params when needed
2589
+ const ro = createReactiveObserver(() => {
2590
+ if (hasPendingConfig === false) {
2591
+ hasPendingConfig = true;
2592
+ // collect new config in the micro-task
2593
+ Promise.resolve().then(() => {
2594
+ hasPendingConfig = false;
2595
+ // resetting current reactive params
2596
+ ro.reset();
2597
+ // dispatching a new config due to a change in the configuration
2598
+ computeConfigAndUpdate();
2599
+ });
2480
2600
  }
2481
- return {
2482
- get() {
2483
- if (process.env.NODE_ENV !== 'production') {
2484
- // Assert that the this value is an actual Component with an associated VM.
2485
- getAssociatedVM(this);
2486
- }
2487
- return get.call(this);
2488
- },
2489
- set(newValue) {
2490
- const vm = getAssociatedVM(this);
2491
- if (process.env.NODE_ENV !== 'production') {
2492
- const vmBeingRendered = getVMBeingRendered();
2493
- assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm}.${toString$1(key)}`);
2494
- assert.invariant(!isUpdatingTemplate, `Updating the template of ${vmBeingRendered} has side effects on the state of ${vm}.${toString$1(key)}`);
2495
- }
2496
- if (set) {
2497
- set.call(this, newValue);
2498
- }
2499
- else if (process.env.NODE_ENV !== 'production') {
2500
- assert.fail(`Invalid attempt to set a new value for property ${toString$1(key)} of ${vm} that does not has a setter decorated with @api.`);
2501
- }
2502
- },
2503
- enumerable,
2504
- configurable,
2505
- };
2601
+ });
2602
+ const computeConfigAndUpdate = () => {
2603
+ let config;
2604
+ ro.observe(() => config = configCallback(component));
2605
+ // eslint-disable-next-line @lwc/lwc-internal/no-invalid-todo
2606
+ // TODO: dev-mode validation of config based on the adapter.configSchema
2607
+ // @ts-ignore it is assigned in the observe() callback
2608
+ callbackWhenConfigIsReady(config);
2609
+ };
2610
+ return {
2611
+ computeConfigAndUpdate,
2612
+ ro
2613
+ };
2506
2614
  }
2615
+ function createContextWatcher(vm, wireDef, callbackWhenContextIsReady) {
2616
+ const {
2617
+ adapter
2618
+ } = wireDef;
2619
+ const adapterContextToken = getAdapterToken(adapter);
2620
+ if (isUndefined$1(adapterContextToken)) {
2621
+ return; // no provider found, nothing to be done
2622
+ }
2507
2623
 
2508
- /*
2509
- * Copyright (c) 2018, salesforce.com, inc.
2510
- * All rights reserved.
2511
- * SPDX-License-Identifier: MIT
2512
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
2513
- */
2514
- function track(target) {
2515
- if (arguments.length === 1) {
2516
- return getReactiveProxy(target);
2624
+ const {
2625
+ elm,
2626
+ context: {
2627
+ wiredConnecting,
2628
+ wiredDisconnecting
2629
+ },
2630
+ renderer: {
2631
+ dispatchEvent
2517
2632
  }
2633
+ } = vm;
2634
+ // waiting for the component to be connected to formally request the context via the token
2635
+ ArrayPush$1.call(wiredConnecting, () => {
2636
+ // This event is responsible for connecting the host element with another
2637
+ // element in the composed path that is providing contextual data. The provider
2638
+ // must be listening for a special dom event with the name corresponding to the value of
2639
+ // `adapterContextToken`, which will remain secret and internal to this file only to
2640
+ // guarantee that the linkage can be forged.
2641
+ const contextRegistrationEvent = new WireContextRegistrationEvent(adapterContextToken, {
2642
+ setNewContext(newContext) {
2643
+ // eslint-disable-next-line @lwc/lwc-internal/no-invalid-todo
2644
+ // TODO: dev-mode validation of config based on the adapter.contextSchema
2645
+ callbackWhenContextIsReady(newContext);
2646
+ },
2647
+ setDisconnectedCallback(disconnectCallback) {
2648
+ // adds this callback into the disconnect bucket so it gets disconnected from parent
2649
+ // the the element hosting the wire is disconnected
2650
+ ArrayPush$1.call(wiredDisconnecting, disconnectCallback);
2651
+ }
2652
+ });
2653
+ dispatchEvent(elm, contextRegistrationEvent);
2654
+ });
2655
+ }
2656
+ function createConnector(vm, name, wireDef) {
2657
+ const {
2658
+ method,
2659
+ adapter,
2660
+ configCallback,
2661
+ dynamic
2662
+ } = wireDef;
2663
+ let debugInfo;
2664
+ if (process.env.NODE_ENV !== 'production') {
2665
+ const wiredPropOrMethod = isUndefined$1(method) ? name : method.name;
2666
+ debugInfo = create(null);
2667
+ debugInfo.wasDataProvisionedForConfig = false;
2668
+ vm.debugInfo[WIRE_DEBUG_ENTRY][wiredPropOrMethod] = debugInfo;
2669
+ }
2670
+ const fieldOrMethodCallback = isUndefined$1(method) ? createFieldDataCallback(vm, name) : createMethodDataCallback(vm, method);
2671
+ const dataCallback = value => {
2518
2672
  if (process.env.NODE_ENV !== 'production') {
2519
- assert.fail(`@track decorator can only be used with one argument to return a trackable object, or as a decorator function.`);
2673
+ debugInfo.data = value;
2674
+ // Note: most of the time, the data provided is for the current config, but there may be
2675
+ // some conditions in which it does not, ex:
2676
+ // race conditions in a poor network while the adapter does not cancel a previous request.
2677
+ debugInfo.wasDataProvisionedForConfig = true;
2520
2678
  }
2521
- throw new Error();
2522
- }
2679
+ fieldOrMethodCallback(value);
2680
+ };
2681
+ let context;
2682
+ let connector;
2683
+ // Workaround to pass the component element associated to this wire adapter instance.
2684
+ defineProperty(dataCallback, DeprecatedWiredElementHost, {
2685
+ value: vm.elm
2686
+ });
2687
+ defineProperty(dataCallback, DeprecatedWiredParamsMeta, {
2688
+ value: dynamic
2689
+ });
2690
+ runWithBoundaryProtection(vm, vm, noop, () => {
2691
+ // job
2692
+ connector = new adapter(dataCallback);
2693
+ }, noop);
2694
+ const updateConnectorConfig = config => {
2695
+ // every time the config is recomputed due to tracking,
2696
+ // this callback will be invoked with the new computed config
2697
+ runWithBoundaryProtection(vm, vm, noop, () => {
2698
+ // job
2699
+ if (process.env.NODE_ENV !== 'production') {
2700
+ debugInfo.config = config;
2701
+ debugInfo.context = context;
2702
+ debugInfo.wasDataProvisionedForConfig = false;
2703
+ }
2704
+ connector.update(config, context);
2705
+ }, noop);
2706
+ };
2707
+ // Computes the current wire config and calls the update method on the wire adapter.
2708
+ // If it has params, we will need to observe changes in the next tick.
2709
+ const {
2710
+ computeConfigAndUpdate,
2711
+ ro
2712
+ } = createConfigWatcher(vm.component, configCallback, updateConnectorConfig);
2713
+ // if the adapter needs contextualization, we need to watch for new context and push it alongside the config
2714
+ if (!isUndefined$1(adapter.contextSchema)) {
2715
+ createContextWatcher(vm, wireDef, newContext => {
2716
+ // every time the context is pushed into this component,
2717
+ // this callback will be invoked with the new computed context
2718
+ if (context !== newContext) {
2719
+ context = newContext;
2720
+ // Note: when new context arrives, the config will be recomputed and pushed along side the new
2721
+ // context, this is to preserve the identity characteristics, config should not have identity
2722
+ // (ever), while context can have identity
2723
+ if (vm.state === 1 /* VMState.connected */) {
2724
+ computeConfigAndUpdate();
2725
+ }
2726
+ }
2727
+ });
2728
+ }
2729
+ return {
2730
+ // @ts-ignore the boundary protection executes sync, connector is always defined
2731
+ connector,
2732
+ computeConfigAndUpdate,
2733
+ resetConfigWatcher: () => ro.reset()
2734
+ };
2735
+ }
2736
+ const AdapterToTokenMap = new Map();
2737
+ function getAdapterToken(adapter) {
2738
+ return AdapterToTokenMap.get(adapter);
2739
+ }
2740
+ function setAdapterToken(adapter, token) {
2741
+ AdapterToTokenMap.set(adapter, token);
2742
+ }
2743
+ function storeWiredMethodMeta(descriptor, adapter, configCallback, dynamic) {
2744
+ // support for callable adapters
2745
+ if (adapter.adapter) {
2746
+ adapter = adapter.adapter;
2747
+ }
2748
+ const method = descriptor.value;
2749
+ const def = {
2750
+ adapter,
2751
+ method,
2752
+ configCallback,
2753
+ dynamic
2754
+ };
2755
+ WireMetaMap.set(descriptor, def);
2756
+ }
2757
+ function storeWiredFieldMeta(descriptor, adapter, configCallback, dynamic) {
2758
+ // support for callable adapters
2759
+ if (adapter.adapter) {
2760
+ adapter = adapter.adapter;
2761
+ }
2762
+ const def = {
2763
+ adapter,
2764
+ configCallback,
2765
+ dynamic
2766
+ };
2767
+ WireMetaMap.set(descriptor, def);
2768
+ }
2769
+ function installWireAdapters(vm) {
2770
+ const {
2771
+ context,
2772
+ def: {
2773
+ wire
2774
+ }
2775
+ } = vm;
2776
+ if (process.env.NODE_ENV !== 'production') {
2777
+ vm.debugInfo[WIRE_DEBUG_ENTRY] = create(null);
2778
+ }
2779
+ const wiredConnecting = context.wiredConnecting = [];
2780
+ const wiredDisconnecting = context.wiredDisconnecting = [];
2781
+ for (const fieldNameOrMethod in wire) {
2782
+ const descriptor = wire[fieldNameOrMethod];
2783
+ const wireDef = WireMetaMap.get(descriptor);
2784
+ if (process.env.NODE_ENV !== 'production') {
2785
+ assert.invariant(wireDef, `Internal Error: invalid wire definition found.`);
2786
+ }
2787
+ if (!isUndefined$1(wireDef)) {
2788
+ const {
2789
+ connector,
2790
+ computeConfigAndUpdate,
2791
+ resetConfigWatcher
2792
+ } = createConnector(vm, fieldNameOrMethod, wireDef);
2793
+ const hasDynamicParams = wireDef.dynamic.length > 0;
2794
+ ArrayPush$1.call(wiredConnecting, () => {
2795
+ connector.connect();
2796
+ if (!lwcRuntimeFlags.ENABLE_WIRE_SYNC_EMIT) {
2797
+ if (hasDynamicParams) {
2798
+ Promise.resolve().then(computeConfigAndUpdate);
2799
+ return;
2800
+ }
2801
+ }
2802
+ computeConfigAndUpdate();
2803
+ });
2804
+ ArrayPush$1.call(wiredDisconnecting, () => {
2805
+ connector.disconnect();
2806
+ resetConfigWatcher();
2807
+ });
2808
+ }
2809
+ }
2810
+ }
2811
+ function connectWireAdapters(vm) {
2812
+ const {
2813
+ wiredConnecting
2814
+ } = vm.context;
2815
+ for (let i = 0, len = wiredConnecting.length; i < len; i += 1) {
2816
+ wiredConnecting[i]();
2817
+ }
2818
+ }
2819
+ function disconnectWireAdapters(vm) {
2820
+ const {
2821
+ wiredDisconnecting
2822
+ } = vm.context;
2823
+ runWithBoundaryProtection(vm, vm, noop, () => {
2824
+ // job
2825
+ for (let i = 0, len = wiredDisconnecting.length; i < len; i += 1) {
2826
+ wiredDisconnecting[i]();
2827
+ }
2828
+ }, noop);
2829
+ }
2830
+
2831
+ /*
2832
+ * Copyright (c) 2018, salesforce.com, inc.
2833
+ * All rights reserved.
2834
+ * SPDX-License-Identifier: MIT
2835
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
2836
+ */
2837
+ function api$1() {
2838
+ if (process.env.NODE_ENV !== 'production') {
2839
+ assert.fail(`@api decorator can only be used as a decorator function.`);
2840
+ }
2841
+ throw new Error();
2842
+ }
2843
+ function createPublicPropertyDescriptor(key) {
2844
+ return {
2845
+ get() {
2846
+ const vm = getAssociatedVM(this);
2847
+ if (isBeingConstructed(vm)) {
2848
+ if (process.env.NODE_ENV !== 'production') {
2849
+ logError(`Can’t read the value of property \`${toString$1(key)}\` from the constructor because the owner component hasn’t set the value yet. Instead, use the constructor to set a default value for the property.`, vm);
2850
+ }
2851
+ return;
2852
+ }
2853
+ componentValueObserved(vm, key);
2854
+ return vm.cmpProps[key];
2855
+ },
2856
+ set(newValue) {
2857
+ const vm = getAssociatedVM(this);
2858
+ if (process.env.NODE_ENV !== 'production') {
2859
+ const vmBeingRendered = getVMBeingRendered();
2860
+ assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm}.${toString$1(key)}`);
2861
+ assert.invariant(!isUpdatingTemplate, `Updating the template of ${vmBeingRendered} has side effects on the state of ${vm}.${toString$1(key)}`);
2862
+ }
2863
+ vm.cmpProps[key] = newValue;
2864
+ componentValueMutated(vm, key);
2865
+ },
2866
+ enumerable: true,
2867
+ configurable: true,
2868
+ };
2869
+ }
2870
+ function createPublicAccessorDescriptor(key, descriptor) {
2871
+ const { get, set, enumerable, configurable } = descriptor;
2872
+ if (!isFunction$1(get)) {
2873
+ if (process.env.NODE_ENV !== 'production') {
2874
+ assert.invariant(isFunction$1(get), `Invalid compiler output for public accessor ${toString$1(key)} decorated with @api`);
2875
+ }
2876
+ throw new Error();
2877
+ }
2878
+ return {
2879
+ get() {
2880
+ if (process.env.NODE_ENV !== 'production') {
2881
+ // Assert that the this value is an actual Component with an associated VM.
2882
+ getAssociatedVM(this);
2883
+ }
2884
+ return get.call(this);
2885
+ },
2886
+ set(newValue) {
2887
+ const vm = getAssociatedVM(this);
2888
+ if (process.env.NODE_ENV !== 'production') {
2889
+ const vmBeingRendered = getVMBeingRendered();
2890
+ assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm}.${toString$1(key)}`);
2891
+ assert.invariant(!isUpdatingTemplate, `Updating the template of ${vmBeingRendered} has side effects on the state of ${vm}.${toString$1(key)}`);
2892
+ }
2893
+ if (set) {
2894
+ set.call(this, newValue);
2895
+ }
2896
+ else if (process.env.NODE_ENV !== 'production') {
2897
+ assert.fail(`Invalid attempt to set a new value for property ${toString$1(key)} of ${vm} that does not has a setter decorated with @api.`);
2898
+ }
2899
+ },
2900
+ enumerable,
2901
+ configurable,
2902
+ };
2903
+ }
2904
+
2905
+ /*
2906
+ * Copyright (c) 2018, salesforce.com, inc.
2907
+ * All rights reserved.
2908
+ * SPDX-License-Identifier: MIT
2909
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
2910
+ */
2911
+ function track(target) {
2912
+ if (arguments.length === 1) {
2913
+ return getReactiveProxy(target);
2914
+ }
2915
+ if (process.env.NODE_ENV !== 'production') {
2916
+ assert.fail(`@track decorator can only be used with one argument to return a trackable object, or as a decorator function.`);
2917
+ }
2918
+ throw new Error();
2919
+ }
2523
2920
  function internalTrackDecorator(key) {
2524
2921
  return {
2525
2922
  get() {
@@ -3482,6 +3879,9 @@
3482
3879
  stylesheets: newStylesheets,
3483
3880
  stylesheetToken: newStylesheetToken
3484
3881
  } = template;
3882
+ const {
3883
+ stylesheets: newVmStylesheets
3884
+ } = vm;
3485
3885
  const isSyntheticShadow = renderMode === 1 /* RenderMode.Shadow */ && shadowMode === 1 /* ShadowMode.Synthetic */;
3486
3886
  const {
3487
3887
  hasScopedStyles
@@ -3505,7 +3905,9 @@
3505
3905
  }
3506
3906
  // Apply the new template styling token to the host element, if the new template has any
3507
3907
  // associated stylesheets. In the case of light DOM, also ensure there is at least one scoped stylesheet.
3508
- if (!isUndefined$1(newStylesheets) && newStylesheets.length !== 0) {
3908
+ const hasNewStylesheets = hasStyles(newStylesheets);
3909
+ const hasNewVmStylesheets = hasStyles(newVmStylesheets);
3910
+ if (hasNewStylesheets || hasNewVmStylesheets) {
3509
3911
  newToken = newStylesheetToken;
3510
3912
  }
3511
3913
  // Set the new styling token on the host element
@@ -3577,10 +3979,17 @@
3577
3979
  stylesheets,
3578
3980
  stylesheetToken
3579
3981
  } = template;
3982
+ const {
3983
+ stylesheets: vmStylesheets
3984
+ } = vm;
3580
3985
  let content = [];
3581
- if (!isUndefined$1(stylesheets) && stylesheets.length !== 0) {
3986
+ if (hasStyles(stylesheets)) {
3582
3987
  content = evaluateStylesheetsContent(stylesheets, stylesheetToken, vm);
3583
3988
  }
3989
+ // VM (component) stylesheets apply after template stylesheets
3990
+ if (hasStyles(vmStylesheets)) {
3991
+ ArrayPush$1.apply(content, evaluateStylesheetsContent(vmStylesheets, stylesheetToken, vm));
3992
+ }
3584
3993
  return content;
3585
3994
  }
3586
3995
  // It might be worth caching this to avoid doing the lookup repeatedly, but
@@ -3618,10 +4027,13 @@
3618
4027
  const {
3619
4028
  template
3620
4029
  } = getComponentInternalDef(vnode.ctor);
4030
+ const {
4031
+ vm
4032
+ } = vnode;
3621
4033
  const {
3622
4034
  stylesheetToken
3623
4035
  } = template;
3624
- return !isUndefined$1(stylesheetToken) && computeHasScopedStyles(template) ? makeHostToken(stylesheetToken) : null;
4036
+ return !isUndefined$1(stylesheetToken) && computeHasScopedStyles(template, vm) ? makeHostToken(stylesheetToken) : null;
3625
4037
  }
3626
4038
  function getNearestNativeShadowComponent(vm) {
3627
4039
  const owner = getNearestShadowComponent(vm);
@@ -4234,6 +4646,28 @@
4234
4646
  // in fallback mode, the allocation will always set children to
4235
4647
  // empty and delegate the real allocation to the slot elements
4236
4648
  allocateChildren(n2, vm);
4649
+ // Solves an edge case with slotted VFragments in native shadow mode.
4650
+ //
4651
+ // During allocation, in native shadow, slotted VFragment nodes are flattened and their text delimiters are removed
4652
+ // to avoid interfering with native slot behavior. When this happens, if any of the fragments
4653
+ // were not stable, the children must go through the dynamic diffing algo.
4654
+ //
4655
+ // If the new children (n2.children) contain no VFragments, but the previous children (n1.children) were dynamic,
4656
+ // the new nodes must be marked dynamic so that all nodes are properly updated. The only indicator that the new
4657
+ // nodes need to be dynamic comes from the previous children, so we check that to determine whether we need to
4658
+ // mark the new children dynamic.
4659
+ //
4660
+ // Example:
4661
+ // n1.children: [div, VFragment('', div, null, ''), div] => [div, div, null, div]; // marked dynamic
4662
+ // n2.children: [div, null, div] => [div, null, div] // marked ???
4663
+ const {
4664
+ shadowMode,
4665
+ renderMode
4666
+ } = vm;
4667
+ if (shadowMode == 0 /* ShadowMode.Native */ && renderMode !== 0 /* RenderMode.Light */ && hasDynamicChildren(n1.children)) {
4668
+ // No-op if children has already been marked dynamic by 'allocateChildren()'.
4669
+ markAsDynamicChildren(n2.children);
4670
+ }
4237
4671
  }
4238
4672
  // in fallback mode, the children will be always empty, so, nothing
4239
4673
  // will happen, but in native, it does allocate the light dom
@@ -4426,7 +4860,6 @@
4426
4860
  //
4427
4861
  // In case #2, we will always get a fresh VCustomElement.
4428
4862
  const children = vnode.aChildren || vnode.children;
4429
- vm.aChildren = children;
4430
4863
  const {
4431
4864
  renderMode,
4432
4865
  shadowMode
@@ -4439,20 +4872,66 @@
4439
4872
  logError(`Invalid usage of 'lwc:slot-data' on ${getComponentTag(vm)} tag. Scoped slot content can only be passed to a light dom child.`);
4440
4873
  }
4441
4874
  }
4875
+ // If any of the children being allocated are VFragments, we remove the text delimiters and flatten all immediate
4876
+ // children VFragments to avoid them interfering with default slot behavior.
4877
+ const allocatedChildren = flattenFragmentsInChildren(children);
4878
+ vnode.children = allocatedChildren;
4879
+ vm.aChildren = allocatedChildren;
4442
4880
  if (shadowMode === 1 /* ShadowMode.Synthetic */ || renderMode === 0 /* RenderMode.Light */) {
4443
4881
  // slow path
4444
- allocateInSlot(vm, children, vnode.owner);
4882
+ allocateInSlot(vm, allocatedChildren, vnode.owner);
4445
4883
  // save the allocated children in case this vnode is reused.
4446
- vnode.aChildren = children;
4884
+ vnode.aChildren = allocatedChildren;
4447
4885
  // every child vnode is now allocated, and the host should receive none directly, it receives them via the shadow!
4448
4886
  vnode.children = EmptyArray;
4449
4887
  }
4450
4888
  }
4451
- function createViewModelHook(elm, vnode, renderer) {
4452
- let vm = getAssociatedVMIfPresent(elm);
4453
- // There is a possibility that a custom element is registered under tagName, in which case, the
4454
- // initialization is already carry on, and there is nothing else to do here since this hook is
4455
- // called right after invoking `document.createElement`.
4889
+ /**
4890
+ * Flattens the contents of all VFragments in an array of VNodes, removes the text delimiters on those VFragments, and
4891
+ * marks the resulting children array as dynamic. Uses a stack (array) to iteratively traverse the nested VFragments
4892
+ * and avoid the perf overhead of creating/destroying throwaway arrays/objects in a recursive approach.
4893
+ *
4894
+ * With the delimiters removed, the contents are marked dynamic so they are diffed correctly.
4895
+ *
4896
+ * This function is used for slotted VFragments to avoid the text delimiters interfering with slotting functionality.
4897
+ */
4898
+ function flattenFragmentsInChildren(children) {
4899
+ const flattenedChildren = [];
4900
+ // Initialize our stack with the direct children of the custom component and check whether we have a VFragment.
4901
+ // If no VFragment is found in children, we don't need to traverse anything or mark the children dynamic and can return early.
4902
+ const nodeStack = [];
4903
+ let fragmentFound = false;
4904
+ for (let i = children.length - 1; i > -1; i -= 1) {
4905
+ const child = children[i];
4906
+ ArrayPush$1.call(nodeStack, child);
4907
+ fragmentFound = fragmentFound || !!(child && isVFragment(child));
4908
+ }
4909
+ if (!fragmentFound) {
4910
+ return children;
4911
+ }
4912
+ let currentNode;
4913
+ while (!isUndefined$1(currentNode = ArrayPop.call(nodeStack))) {
4914
+ if (!isNull(currentNode) && isVFragment(currentNode)) {
4915
+ const fChildren = currentNode.children;
4916
+ // Ignore the start and end text node delimiters
4917
+ for (let i = fChildren.length - 2; i > 0; i -= 1) {
4918
+ ArrayPush$1.call(nodeStack, fChildren[i]);
4919
+ }
4920
+ } else {
4921
+ ArrayPush$1.call(flattenedChildren, currentNode);
4922
+ }
4923
+ }
4924
+ // We always mark the children as dynamic because nothing generates stable VFragments yet.
4925
+ // If/when stable VFragments are generated by the compiler, this code should be updated to
4926
+ // not mark dynamic if all flattened VFragments were stable.
4927
+ markAsDynamicChildren(flattenedChildren);
4928
+ return flattenedChildren;
4929
+ }
4930
+ function createViewModelHook(elm, vnode, renderer) {
4931
+ let vm = getAssociatedVMIfPresent(elm);
4932
+ // There is a possibility that a custom element is registered under tagName, in which case, the
4933
+ // initialization is already carry on, and there is nothing else to do here since this hook is
4934
+ // called right after invoking `document.createElement`.
4456
4935
  if (!isUndefined$1(vm)) {
4457
4936
  return vm;
4458
4937
  }
@@ -4472,22 +4951,20 @@
4472
4951
  }
4473
4952
  return vm;
4474
4953
  }
4475
- /**
4476
- * Collects all slots into a SlotSet, traversing through VFragment Nodes
4477
- */
4478
- function collectSlots(vm, children, cmpSlotsMapping) {
4954
+ function allocateInSlot(vm, children, owner) {
4479
4955
  var _a, _b;
4956
+ const {
4957
+ cmpSlots: {
4958
+ slotAssignments: oldSlotsMapping
4959
+ }
4960
+ } = vm;
4961
+ const cmpSlotsMapping = create(null);
4962
+ // Collect all slots into cmpSlotsMapping
4480
4963
  for (let i = 0, len = children.length; i < len; i += 1) {
4481
4964
  const vnode = children[i];
4482
4965
  if (isNull(vnode)) {
4483
4966
  continue;
4484
4967
  }
4485
- // Dive further iff the content is wrapped in a VFragment
4486
- if (isVFragment(vnode)) {
4487
- // Remove the text delimiter nodes to avoid overriding default slot content
4488
- collectSlots(vm, vnode.children.slice(1, -1), cmpSlotsMapping);
4489
- continue;
4490
- }
4491
4968
  let slotName = '';
4492
4969
  if (isVBaseElement(vnode)) {
4493
4970
  slotName = (_b = (_a = vnode.data.attrs) === null || _a === void 0 ? void 0 : _a.slot) !== null && _b !== void 0 ? _b : '';
@@ -4497,15 +4974,6 @@
4497
4974
  const vnodes = cmpSlotsMapping[slotName] = cmpSlotsMapping[slotName] || [];
4498
4975
  ArrayPush$1.call(vnodes, vnode);
4499
4976
  }
4500
- }
4501
- function allocateInSlot(vm, children, owner) {
4502
- const {
4503
- cmpSlots: {
4504
- slotAssignments: oldSlotsMapping
4505
- }
4506
- } = vm;
4507
- const cmpSlotsMapping = create(null);
4508
- collectSlots(vm, children, cmpSlotsMapping);
4509
4977
  vm.cmpSlots = {
4510
4978
  owner,
4511
4979
  slotAssignments: cmpSlotsMapping
@@ -4536,14 +5004,14 @@
4536
5004
  }
4537
5005
  }
4538
5006
  // Using a WeakMap instead of a WeakSet because this one works in IE11 :(
4539
- const FromIteration = new WeakMap();
4540
- // dynamic children means it was generated by an iteration
4541
- // in a template, and will require a more complex diffing algo.
5007
+ const DynamicChildren = new WeakMap();
5008
+ // dynamic children means it was either generated by an iteration in a template
5009
+ // or part of an unstable fragment, and will require a more complex diffing algo.
4542
5010
  function markAsDynamicChildren(children) {
4543
- FromIteration.set(children, 1);
5011
+ DynamicChildren.set(children, 1);
4544
5012
  }
4545
5013
  function hasDynamicChildren(children) {
4546
- return FromIteration.has(children);
5014
+ return DynamicChildren.has(children);
4547
5015
  }
4548
5016
  function createKeyToOldIdx(children, beginIdx, endIdx) {
4549
5017
  const map = {};
@@ -5409,7 +5877,7 @@
5409
5877
  // Create a brand new template cache for the swapped templated.
5410
5878
  context.tplCache = create(null);
5411
5879
  // Set the computeHasScopedStyles property in the context, to avoid recomputing it repeatedly.
5412
- context.hasScopedStyles = computeHasScopedStyles(html);
5880
+ context.hasScopedStyles = computeHasScopedStyles(html, vm);
5413
5881
  // Update the scoping token on the host element.
5414
5882
  updateStylesheetToken(vm, html);
5415
5883
  // Evaluate, create stylesheet and cache the produced VNode for future
@@ -5452,9 +5920,8 @@
5452
5920
  }
5453
5921
  return vnodes;
5454
5922
  }
5455
- function computeHasScopedStyles(template) {
5456
- const { stylesheets } = template;
5457
- if (!isUndefined$1(stylesheets)) {
5923
+ function computeHasScopedStylesInStylesheets(stylesheets) {
5924
+ if (hasStyles(stylesheets)) {
5458
5925
  for (let i = 0; i < stylesheets.length; i++) {
5459
5926
  if (isTrue(stylesheets[i][KEY__SCOPED_CSS])) {
5460
5927
  return true;
@@ -5463,6 +5930,15 @@
5463
5930
  }
5464
5931
  return false;
5465
5932
  }
5933
+ function computeHasScopedStyles(template, vm) {
5934
+ const { stylesheets } = template;
5935
+ const vmStylesheets = !isUndefined$1(vm) ? vm.stylesheets : null;
5936
+ return (computeHasScopedStylesInStylesheets(stylesheets) ||
5937
+ computeHasScopedStylesInStylesheets(vmStylesheets));
5938
+ }
5939
+ function hasStyles(stylesheets) {
5940
+ return !isUndefined$1(stylesheets) && !isNull(stylesheets) && stylesheets.length > 0;
5941
+ }
5466
5942
 
5467
5943
  /*
5468
5944
  * Copyright (c) 2018, salesforce.com, inc.
@@ -5778,6 +6254,7 @@
5778
6254
  // Properties set right after VM creation.
5779
6255
  tro: null,
5780
6256
  shadowMode: null,
6257
+ stylesheets: null,
5781
6258
  // Properties set by the LightningElement constructor.
5782
6259
  component: null,
5783
6260
  shadowRoot: null,
@@ -5790,6 +6267,7 @@
5790
6267
  if (process.env.NODE_ENV !== 'production') {
5791
6268
  vm.debugInfo = create(null);
5792
6269
  }
6270
+ vm.stylesheets = computeStylesheets(vm, def.ctor);
5793
6271
  vm.shadowMode = computeShadowMode(vm, renderer);
5794
6272
  vm.tro = getTemplateReactiveObserver(vm);
5795
6273
  if (process.env.NODE_ENV !== 'production') {
@@ -5808,6 +6286,42 @@
5808
6286
  }
5809
6287
  return vm;
5810
6288
  }
6289
+ function validateComponentStylesheets(vm, stylesheets) {
6290
+ let valid = true;
6291
+ const validate = arrayOrStylesheet => {
6292
+ if (isArray$1(arrayOrStylesheet)) {
6293
+ for (let i = 0; i < arrayOrStylesheet.length; i++) {
6294
+ validate(arrayOrStylesheet[i]);
6295
+ }
6296
+ } else if (!isFunction$1(arrayOrStylesheet)) {
6297
+ // function assumed to be a stylesheet factory
6298
+ valid = false;
6299
+ }
6300
+ };
6301
+ if (!isArray$1(stylesheets)) {
6302
+ valid = false;
6303
+ } else {
6304
+ validate(stylesheets);
6305
+ }
6306
+ return valid;
6307
+ }
6308
+ // Validate and flatten any stylesheets defined as `static stylesheets`
6309
+ function computeStylesheets(vm, ctor) {
6310
+ if (lwcRuntimeFlags.ENABLE_PROGRAMMATIC_STYLESHEETS) {
6311
+ const {
6312
+ stylesheets
6313
+ } = ctor;
6314
+ if (!isUndefined$1(stylesheets)) {
6315
+ const valid = validateComponentStylesheets(vm, stylesheets);
6316
+ if (valid) {
6317
+ return flattenStylesheets(stylesheets);
6318
+ } else if (process.env.NODE_ENV !== 'production') {
6319
+ logError(`static stylesheets must be an array of CSS stylesheets. Found invalid stylesheets on <${vm.tagName}>`, vm);
6320
+ }
6321
+ }
6322
+ }
6323
+ return null;
6324
+ }
5811
6325
  function computeShadowMode(vm, renderer) {
5812
6326
  const {
5813
6327
  def
@@ -6050,411 +6564,268 @@
6050
6564
  // in the case where the VM failed in the middle of its creation,
6051
6565
  // eg: constructor throwing before invoking super().
6052
6566
  if (!isUndefined$1(childVM)) {
6053
- resetComponentStateWhenRemoved(childVM);
6054
- }
6055
- }
6056
- }
6057
- }
6058
- function runLightChildNodesDisconnectedCallback(vm) {
6059
- const {
6060
- aChildren: adoptedChildren
6061
- } = vm;
6062
- recursivelyDisconnectChildren(adoptedChildren);
6063
- }
6064
- /**
6065
- * The recursion doesn't need to be a complete traversal of the vnode graph,
6066
- * instead it can be partial, when a custom element vnode is found, we don't
6067
- * need to continue into its children because by attempting to disconnect the
6068
- * custom element itself will trigger the removal of anything slotted or anything
6069
- * defined on its shadow.
6070
- */
6071
- function recursivelyDisconnectChildren(vnodes) {
6072
- for (let i = 0, len = vnodes.length; i < len; i += 1) {
6073
- const vnode = vnodes[i];
6074
- if (!isNull(vnode) && !isUndefined$1(vnode.elm)) {
6075
- switch (vnode.type) {
6076
- case 2 /* VNodeType.Element */:
6077
- recursivelyDisconnectChildren(vnode.children);
6078
- break;
6079
- case 3 /* VNodeType.CustomElement */:
6080
- {
6081
- const vm = getAssociatedVM(vnode.elm);
6082
- resetComponentStateWhenRemoved(vm);
6083
- break;
6084
- }
6085
- }
6086
- }
6087
- }
6088
- }
6089
- // This is a super optimized mechanism to remove the content of the root node (shadow root
6090
- // for shadow DOM components and the root element itself for light DOM) without having to go
6091
- // into snabbdom. Especially useful when the reset is a consequence of an error, in which case the
6092
- // children VNodes might not be representing the current state of the DOM.
6093
- function resetComponentRoot(vm) {
6094
- const {
6095
- children,
6096
- renderRoot,
6097
- renderer: {
6098
- remove
6099
- }
6100
- } = vm;
6101
- for (let i = 0, len = children.length; i < len; i++) {
6102
- const child = children[i];
6103
- if (!isNull(child) && !isUndefined$1(child.elm)) {
6104
- remove(child.elm, renderRoot);
6105
- }
6106
- }
6107
- vm.children = EmptyArray;
6108
- runChildNodesDisconnectedCallback(vm);
6109
- vm.velements = EmptyArray;
6110
- }
6111
- function scheduleRehydration(vm) {
6112
- if (isTrue(vm.isScheduled)) {
6113
- return;
6114
- }
6115
- vm.isScheduled = true;
6116
- if (rehydrateQueue.length === 0) {
6117
- addCallbackToNextTick(flushRehydrationQueue);
6118
- }
6119
- ArrayPush$1.call(rehydrateQueue, vm);
6120
- }
6121
- function getErrorBoundaryVM(vm) {
6122
- let currentVm = vm;
6123
- while (!isNull(currentVm)) {
6124
- if (!isUndefined$1(currentVm.def.errorCallback)) {
6125
- return currentVm;
6126
- }
6127
- currentVm = currentVm.owner;
6128
- }
6129
- }
6130
- function runWithBoundaryProtection(vm, owner, pre, job, post) {
6131
- let error;
6132
- pre();
6133
- try {
6134
- job();
6135
- } catch (e) {
6136
- error = Object(e);
6137
- } finally {
6138
- post();
6139
- if (!isUndefined$1(error)) {
6140
- addErrorComponentStack(vm, error);
6141
- const errorBoundaryVm = isNull(owner) ? undefined : getErrorBoundaryVM(owner);
6142
- if (isUndefined$1(errorBoundaryVm)) {
6143
- throw error; // eslint-disable-line no-unsafe-finally
6144
- }
6145
-
6146
- resetComponentRoot(vm); // remove offenders
6147
- logOperationStart(6 /* OperationId.ErrorCallback */, vm);
6148
- // error boundaries must have an ErrorCallback
6149
- const errorCallback = errorBoundaryVm.def.errorCallback;
6150
- invokeComponentCallback(errorBoundaryVm, errorCallback, [error, error.wcStack]);
6151
- logOperationEnd(6 /* OperationId.ErrorCallback */, vm);
6152
- }
6153
- }
6154
- }
6155
- function forceRehydration(vm) {
6156
- // if we must reset the shadowRoot content and render the template
6157
- // from scratch on an active instance, the way to force the reset
6158
- // is by replacing the value of old template, which is used during
6159
- // to determine if the template has changed or not during the rendering
6160
- // process. If the template returned by render() is different from the
6161
- // previous stored template, the styles will be reset, along with the
6162
- // content of the shadowRoot, this way we can guarantee that all children
6163
- // elements will be throw away, and new instances will be created.
6164
- vm.cmpTemplate = () => [];
6165
- if (isFalse(vm.isDirty)) {
6166
- // forcing the vm to rehydrate in the next tick
6167
- markComponentAsDirty(vm);
6168
- scheduleRehydration(vm);
6169
- }
6170
- }
6171
-
6172
- /*
6173
- * Copyright (c) 2018, salesforce.com, inc.
6174
- * All rights reserved.
6175
- * SPDX-License-Identifier: MIT
6176
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
6177
- */
6178
- const DeprecatedWiredElementHost = '$$DeprecatedWiredElementHostKey$$';
6179
- const DeprecatedWiredParamsMeta = '$$DeprecatedWiredParamsMetaKey$$';
6180
- const WIRE_DEBUG_ENTRY = '@wire';
6181
- const WireMetaMap = new Map();
6182
- class WireContextRegistrationEvent extends CustomEvent {
6183
- constructor(adapterToken, {
6184
- setNewContext,
6185
- setDisconnectedCallback
6186
- }) {
6187
- super(adapterToken, {
6188
- bubbles: true,
6189
- composed: true
6190
- });
6191
- defineProperties(this, {
6192
- setNewContext: {
6193
- value: setNewContext
6194
- },
6195
- setDisconnectedCallback: {
6196
- value: setDisconnectedCallback
6197
- }
6198
- });
6199
- }
6200
- }
6201
- function createFieldDataCallback(vm, name) {
6202
- return value => {
6203
- updateComponentValue(vm, name, value);
6204
- };
6205
- }
6206
- function createMethodDataCallback(vm, method) {
6207
- return value => {
6208
- // dispatching new value into the wired method
6209
- runWithBoundaryProtection(vm, vm.owner, noop, () => {
6210
- // job
6211
- method.call(vm.component, value);
6212
- }, noop);
6213
- };
6214
- }
6215
- function createConfigWatcher(component, configCallback, callbackWhenConfigIsReady) {
6216
- let hasPendingConfig = false;
6217
- // creating the reactive observer for reactive params when needed
6218
- const ro = createReactiveObserver(() => {
6219
- if (hasPendingConfig === false) {
6220
- hasPendingConfig = true;
6221
- // collect new config in the micro-task
6222
- Promise.resolve().then(() => {
6223
- hasPendingConfig = false;
6224
- // resetting current reactive params
6225
- ro.reset();
6226
- // dispatching a new config due to a change in the configuration
6227
- computeConfigAndUpdate();
6228
- });
6229
- }
6230
- });
6231
- const computeConfigAndUpdate = () => {
6232
- let config;
6233
- ro.observe(() => config = configCallback(component));
6234
- // eslint-disable-next-line @lwc/lwc-internal/no-invalid-todo
6235
- // TODO: dev-mode validation of config based on the adapter.configSchema
6236
- // @ts-ignore it is assigned in the observe() callback
6237
- callbackWhenConfigIsReady(config);
6238
- };
6239
- return {
6240
- computeConfigAndUpdate,
6241
- ro
6242
- };
6243
- }
6244
- function createContextWatcher(vm, wireDef, callbackWhenContextIsReady) {
6245
- const {
6246
- adapter
6247
- } = wireDef;
6248
- const adapterContextToken = getAdapterToken(adapter);
6249
- if (isUndefined$1(adapterContextToken)) {
6250
- return; // no provider found, nothing to be done
6251
- }
6252
-
6253
- const {
6254
- elm,
6255
- context: {
6256
- wiredConnecting,
6257
- wiredDisconnecting
6258
- },
6259
- renderer: {
6260
- dispatchEvent
6261
- }
6262
- } = vm;
6263
- // waiting for the component to be connected to formally request the context via the token
6264
- ArrayPush$1.call(wiredConnecting, () => {
6265
- // This event is responsible for connecting the host element with another
6266
- // element in the composed path that is providing contextual data. The provider
6267
- // must be listening for a special dom event with the name corresponding to the value of
6268
- // `adapterContextToken`, which will remain secret and internal to this file only to
6269
- // guarantee that the linkage can be forged.
6270
- const contextRegistrationEvent = new WireContextRegistrationEvent(adapterContextToken, {
6271
- setNewContext(newContext) {
6272
- // eslint-disable-next-line @lwc/lwc-internal/no-invalid-todo
6273
- // TODO: dev-mode validation of config based on the adapter.contextSchema
6274
- callbackWhenContextIsReady(newContext);
6275
- },
6276
- setDisconnectedCallback(disconnectCallback) {
6277
- // adds this callback into the disconnect bucket so it gets disconnected from parent
6278
- // the the element hosting the wire is disconnected
6279
- ArrayPush$1.call(wiredDisconnecting, disconnectCallback);
6280
- }
6281
- });
6282
- dispatchEvent(elm, contextRegistrationEvent);
6283
- });
6284
- }
6285
- function createConnector(vm, name, wireDef) {
6286
- const {
6287
- method,
6288
- adapter,
6289
- configCallback,
6290
- dynamic
6291
- } = wireDef;
6292
- let debugInfo;
6293
- if (process.env.NODE_ENV !== 'production') {
6294
- const wiredPropOrMethod = isUndefined$1(method) ? name : method.name;
6295
- debugInfo = create(null);
6296
- debugInfo.wasDataProvisionedForConfig = false;
6297
- vm.debugInfo[WIRE_DEBUG_ENTRY][wiredPropOrMethod] = debugInfo;
6298
- }
6299
- const fieldOrMethodCallback = isUndefined$1(method) ? createFieldDataCallback(vm, name) : createMethodDataCallback(vm, method);
6300
- const dataCallback = value => {
6301
- if (process.env.NODE_ENV !== 'production') {
6302
- debugInfo.data = value;
6303
- // Note: most of the time, the data provided is for the current config, but there may be
6304
- // some conditions in which it does not, ex:
6305
- // race conditions in a poor network while the adapter does not cancel a previous request.
6306
- debugInfo.wasDataProvisionedForConfig = true;
6307
- }
6308
- fieldOrMethodCallback(value);
6309
- };
6310
- let context;
6311
- let connector;
6312
- // Workaround to pass the component element associated to this wire adapter instance.
6313
- defineProperty(dataCallback, DeprecatedWiredElementHost, {
6314
- value: vm.elm
6315
- });
6316
- defineProperty(dataCallback, DeprecatedWiredParamsMeta, {
6317
- value: dynamic
6318
- });
6319
- runWithBoundaryProtection(vm, vm, noop, () => {
6320
- // job
6321
- connector = new adapter(dataCallback);
6322
- }, noop);
6323
- const updateConnectorConfig = config => {
6324
- // every time the config is recomputed due to tracking,
6325
- // this callback will be invoked with the new computed config
6326
- runWithBoundaryProtection(vm, vm, noop, () => {
6327
- // job
6328
- if (process.env.NODE_ENV !== 'production') {
6329
- debugInfo.config = config;
6330
- debugInfo.context = context;
6331
- debugInfo.wasDataProvisionedForConfig = false;
6567
+ resetComponentStateWhenRemoved(childVM);
6332
6568
  }
6333
- connector.update(config, context);
6334
- }, noop);
6335
- };
6336
- // Computes the current wire config and calls the update method on the wire adapter.
6337
- // If it has params, we will need to observe changes in the next tick.
6569
+ }
6570
+ }
6571
+ }
6572
+ function runLightChildNodesDisconnectedCallback(vm) {
6338
6573
  const {
6339
- computeConfigAndUpdate,
6340
- ro
6341
- } = createConfigWatcher(vm.component, configCallback, updateConnectorConfig);
6342
- // if the adapter needs contextualization, we need to watch for new context and push it alongside the config
6343
- if (!isUndefined$1(adapter.contextSchema)) {
6344
- createContextWatcher(vm, wireDef, newContext => {
6345
- // every time the context is pushed into this component,
6346
- // this callback will be invoked with the new computed context
6347
- if (context !== newContext) {
6348
- context = newContext;
6349
- // Note: when new context arrives, the config will be recomputed and pushed along side the new
6350
- // context, this is to preserve the identity characteristics, config should not have identity
6351
- // (ever), while context can have identity
6352
- if (vm.state === 1 /* VMState.connected */) {
6353
- computeConfigAndUpdate();
6354
- }
6574
+ aChildren: adoptedChildren
6575
+ } = vm;
6576
+ recursivelyDisconnectChildren(adoptedChildren);
6577
+ }
6578
+ /**
6579
+ * The recursion doesn't need to be a complete traversal of the vnode graph,
6580
+ * instead it can be partial, when a custom element vnode is found, we don't
6581
+ * need to continue into its children because by attempting to disconnect the
6582
+ * custom element itself will trigger the removal of anything slotted or anything
6583
+ * defined on its shadow.
6584
+ */
6585
+ function recursivelyDisconnectChildren(vnodes) {
6586
+ for (let i = 0, len = vnodes.length; i < len; i += 1) {
6587
+ const vnode = vnodes[i];
6588
+ if (!isNull(vnode) && !isUndefined$1(vnode.elm)) {
6589
+ switch (vnode.type) {
6590
+ case 2 /* VNodeType.Element */:
6591
+ recursivelyDisconnectChildren(vnode.children);
6592
+ break;
6593
+ case 3 /* VNodeType.CustomElement */:
6594
+ {
6595
+ const vm = getAssociatedVM(vnode.elm);
6596
+ resetComponentStateWhenRemoved(vm);
6597
+ break;
6598
+ }
6355
6599
  }
6356
- });
6600
+ }
6357
6601
  }
6358
- return {
6359
- // @ts-ignore the boundary protection executes sync, connector is always defined
6360
- connector,
6361
- computeConfigAndUpdate,
6362
- resetConfigWatcher: () => ro.reset()
6363
- };
6364
- }
6365
- const AdapterToTokenMap = new Map();
6366
- function getAdapterToken(adapter) {
6367
- return AdapterToTokenMap.get(adapter);
6368
6602
  }
6369
- function setAdapterToken(adapter, token) {
6370
- AdapterToTokenMap.set(adapter, token);
6603
+ // This is a super optimized mechanism to remove the content of the root node (shadow root
6604
+ // for shadow DOM components and the root element itself for light DOM) without having to go
6605
+ // into snabbdom. Especially useful when the reset is a consequence of an error, in which case the
6606
+ // children VNodes might not be representing the current state of the DOM.
6607
+ function resetComponentRoot(vm) {
6608
+ const {
6609
+ children,
6610
+ renderRoot,
6611
+ renderer: {
6612
+ remove
6613
+ }
6614
+ } = vm;
6615
+ for (let i = 0, len = children.length; i < len; i++) {
6616
+ const child = children[i];
6617
+ if (!isNull(child) && !isUndefined$1(child.elm)) {
6618
+ remove(child.elm, renderRoot);
6619
+ }
6620
+ }
6621
+ vm.children = EmptyArray;
6622
+ runChildNodesDisconnectedCallback(vm);
6623
+ vm.velements = EmptyArray;
6371
6624
  }
6372
- function storeWiredMethodMeta(descriptor, adapter, configCallback, dynamic) {
6373
- // support for callable adapters
6374
- if (adapter.adapter) {
6375
- adapter = adapter.adapter;
6625
+ function scheduleRehydration(vm) {
6626
+ if (isTrue(vm.isScheduled)) {
6627
+ return;
6376
6628
  }
6377
- const method = descriptor.value;
6378
- const def = {
6379
- adapter,
6380
- method,
6381
- configCallback,
6382
- dynamic
6383
- };
6384
- WireMetaMap.set(descriptor, def);
6629
+ vm.isScheduled = true;
6630
+ if (rehydrateQueue.length === 0) {
6631
+ addCallbackToNextTick(flushRehydrationQueue);
6632
+ }
6633
+ ArrayPush$1.call(rehydrateQueue, vm);
6385
6634
  }
6386
- function storeWiredFieldMeta(descriptor, adapter, configCallback, dynamic) {
6387
- // support for callable adapters
6388
- if (adapter.adapter) {
6389
- adapter = adapter.adapter;
6635
+ function getErrorBoundaryVM(vm) {
6636
+ let currentVm = vm;
6637
+ while (!isNull(currentVm)) {
6638
+ if (!isUndefined$1(currentVm.def.errorCallback)) {
6639
+ return currentVm;
6640
+ }
6641
+ currentVm = currentVm.owner;
6390
6642
  }
6391
- const def = {
6392
- adapter,
6393
- configCallback,
6394
- dynamic
6395
- };
6396
- WireMetaMap.set(descriptor, def);
6397
6643
  }
6398
- function installWireAdapters(vm) {
6399
- const {
6400
- context,
6401
- def: {
6402
- wire
6644
+ function runWithBoundaryProtection(vm, owner, pre, job, post) {
6645
+ let error;
6646
+ pre();
6647
+ try {
6648
+ job();
6649
+ } catch (e) {
6650
+ error = Object(e);
6651
+ } finally {
6652
+ post();
6653
+ if (!isUndefined$1(error)) {
6654
+ addErrorComponentStack(vm, error);
6655
+ const errorBoundaryVm = isNull(owner) ? undefined : getErrorBoundaryVM(owner);
6656
+ if (isUndefined$1(errorBoundaryVm)) {
6657
+ throw error; // eslint-disable-line no-unsafe-finally
6658
+ }
6659
+
6660
+ resetComponentRoot(vm); // remove offenders
6661
+ logOperationStart(6 /* OperationId.ErrorCallback */, vm);
6662
+ // error boundaries must have an ErrorCallback
6663
+ const errorCallback = errorBoundaryVm.def.errorCallback;
6664
+ invokeComponentCallback(errorBoundaryVm, errorCallback, [error, error.wcStack]);
6665
+ logOperationEnd(6 /* OperationId.ErrorCallback */, vm);
6403
6666
  }
6404
- } = vm;
6405
- if (process.env.NODE_ENV !== 'production') {
6406
- vm.debugInfo[WIRE_DEBUG_ENTRY] = create(null);
6407
6667
  }
6408
- const wiredConnecting = context.wiredConnecting = [];
6409
- const wiredDisconnecting = context.wiredDisconnecting = [];
6410
- for (const fieldNameOrMethod in wire) {
6411
- const descriptor = wire[fieldNameOrMethod];
6412
- const wireDef = WireMetaMap.get(descriptor);
6668
+ }
6669
+ function forceRehydration(vm) {
6670
+ // if we must reset the shadowRoot content and render the template
6671
+ // from scratch on an active instance, the way to force the reset
6672
+ // is by replacing the value of old template, which is used during
6673
+ // to determine if the template has changed or not during the rendering
6674
+ // process. If the template returned by render() is different from the
6675
+ // previous stored template, the styles will be reset, along with the
6676
+ // content of the shadowRoot, this way we can guarantee that all children
6677
+ // elements will be throw away, and new instances will be created.
6678
+ vm.cmpTemplate = () => [];
6679
+ if (isFalse(vm.isDirty)) {
6680
+ // forcing the vm to rehydrate in the next tick
6681
+ markComponentAsDirty(vm);
6682
+ scheduleRehydration(vm);
6683
+ }
6684
+ }
6685
+
6686
+ /*
6687
+ * Copyright (c) 2018, salesforce.com, inc.
6688
+ * All rights reserved.
6689
+ * SPDX-License-Identifier: MIT
6690
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
6691
+ */
6692
+ //
6693
+ // The goal of this code is to detect invalid cross-root ARIA references in synthetic shadow DOM.
6694
+ // These invalid references should be fixed before the offending components can be migrated to native shadow DOM.
6695
+ // When invalid usage is detected, we warn in dev mode and call the reporting API if enabled.
6696
+ // See: https://lwc.dev/guide/accessibility#link-ids-and-aria-attributes-from-different-templates
6697
+ //
6698
+ // Use the unpatched native getElementById/querySelectorAll rather than the synthetic one
6699
+ const getElementById = _globalThis[KEY__NATIVE_GET_ELEMENT_BY_ID];
6700
+ const querySelectorAll = _globalThis[KEY__NATIVE_QUERY_SELECTOR_ALL];
6701
+ function isSyntheticShadowRootInstance(rootNode) {
6702
+ return rootNode !== document && isTrue(rootNode.synthetic);
6703
+ }
6704
+ function reportViolation(source, target, attrName) {
6705
+ // The vm is either for the source, the target, or both. Either one or both must be using synthetic
6706
+ // shadow for a violation to be detected.
6707
+ let vm = getAssociatedVMIfPresent(source.getRootNode().host);
6708
+ if (isUndefined$1(vm)) {
6709
+ vm = getAssociatedVMIfPresent(target.getRootNode().host);
6710
+ }
6711
+ if (isUndefined$1(vm)) {
6712
+ // vm should never be undefined here, but just to be safe, bail out and don't report
6713
+ return;
6714
+ }
6715
+ report(0 /* ReportingEventId.CrossRootAriaInSyntheticShadow */, vm);
6413
6716
  if (process.env.NODE_ENV !== 'production') {
6414
- assert.invariant(wireDef, `Internal Error: invalid wire definition found.`);
6717
+ // Avoid excessively logging to the console in the case of duplicates.
6718
+ logWarnOnce(`Element <${source.tagName.toLowerCase()}> uses attribute "${attrName}" to reference element ` +
6719
+ `<${target.tagName.toLowerCase()}>, which is not in the same shadow root. This will break in native shadow DOM. ` +
6720
+ `For details, see: https://lwc.dev/guide/accessibility#link-ids-and-aria-attributes-from-different-templates`, vm);
6415
6721
  }
6416
- if (!isUndefined$1(wireDef)) {
6417
- const {
6418
- connector,
6419
- computeConfigAndUpdate,
6420
- resetConfigWatcher
6421
- } = createConnector(vm, fieldNameOrMethod, wireDef);
6422
- const hasDynamicParams = wireDef.dynamic.length > 0;
6423
- ArrayPush$1.call(wiredConnecting, () => {
6424
- connector.connect();
6425
- if (!lwcRuntimeFlags.ENABLE_WIRE_SYNC_EMIT) {
6426
- if (hasDynamicParams) {
6427
- Promise.resolve().then(computeConfigAndUpdate);
6722
+ }
6723
+ function parseIdRefAttributeValue(attrValue) {
6724
+ // split on whitespace and skip empty strings after splitting
6725
+ return isString(attrValue) ? ArrayFilter.call(StringSplit.call(attrValue, /\s+/), Boolean) : [];
6726
+ }
6727
+ function detectSyntheticCrossRootAria(elm, attrName, attrValue) {
6728
+ const root = elm.getRootNode();
6729
+ if (!isSyntheticShadowRootInstance(root)) {
6730
+ return;
6731
+ }
6732
+ if (attrName === 'id') {
6733
+ // elm is the target, find the source
6734
+ if (!isString(attrValue) || attrValue.length === 0) {
6735
+ // if our id is null or empty, nobody can reference us
6428
6736
  return;
6429
- }
6430
6737
  }
6431
- computeConfigAndUpdate();
6432
- });
6433
- ArrayPush$1.call(wiredDisconnecting, () => {
6434
- connector.disconnect();
6435
- resetConfigWatcher();
6436
- });
6738
+ for (const idRefAttrName of ID_REFERENCING_ATTRIBUTES_SET) {
6739
+ // Query all global elements with this attribute. The attribute selector syntax `~=` is for values
6740
+ // that reference multiple IDs, separated by whitespace.
6741
+ const query = `[${idRefAttrName}~="${CSS.escape(attrValue)}"]`;
6742
+ const sourceElements = querySelectorAll.call(document, query);
6743
+ for (let i = 0; i < sourceElements.length; i++) {
6744
+ const sourceElement = sourceElements[i];
6745
+ const sourceRoot = sourceElement.getRootNode();
6746
+ if (sourceRoot !== root) {
6747
+ reportViolation(sourceElement, elm, idRefAttrName);
6748
+ break;
6749
+ }
6750
+ }
6751
+ }
6752
+ }
6753
+ else {
6754
+ // elm is the source, find the target
6755
+ const ids = parseIdRefAttributeValue(attrValue);
6756
+ for (const id of ids) {
6757
+ const target = getElementById.call(document, id);
6758
+ if (!isNull(target)) {
6759
+ const targetRoot = target.getRootNode();
6760
+ if (targetRoot !== root) {
6761
+ // target element's shadow root is not the same as ours
6762
+ reportViolation(elm, target, attrName);
6763
+ }
6764
+ }
6765
+ }
6437
6766
  }
6438
- }
6439
6767
  }
6440
- function connectWireAdapters(vm) {
6441
- const {
6442
- wiredConnecting
6443
- } = vm.context;
6444
- for (let i = 0, len = wiredConnecting.length; i < len; i += 1) {
6445
- wiredConnecting[i]();
6446
- }
6768
+ let enabled = false;
6769
+ // We want to avoid patching globals whenever possible, so this should be tree-shaken out in prod-mode and if
6770
+ // reporting is not enabled. It should also only run once
6771
+ function enableDetection() {
6772
+ if (enabled) {
6773
+ return; // don't double-apply the patches
6774
+ }
6775
+ enabled = true;
6776
+ const { setAttribute } = Element.prototype;
6777
+ // Detect calling `setAttribute` to set an idref or an id
6778
+ assign(Element.prototype, {
6779
+ setAttribute(attrName, attrValue) {
6780
+ setAttribute.call(this, attrName, attrValue);
6781
+ if (attrName === 'id' || ID_REFERENCING_ATTRIBUTES_SET.has(attrName)) {
6782
+ detectSyntheticCrossRootAria(this, attrName, attrValue);
6783
+ }
6784
+ },
6785
+ });
6786
+ // Detect `elm.id = 'foo'`
6787
+ const idDescriptor = getOwnPropertyDescriptor$1(Element.prototype, 'id');
6788
+ if (!isUndefined$1(idDescriptor)) {
6789
+ const { get, set } = idDescriptor;
6790
+ // These should always be a getter and a setter, but if someone is monkeying with the global descriptor, ignore it
6791
+ if (isFunction$1(get) && isFunction$1(set)) {
6792
+ defineProperty(Element.prototype, 'id', {
6793
+ get() {
6794
+ return get.call(this);
6795
+ },
6796
+ set(value) {
6797
+ set.call(this, value);
6798
+ detectSyntheticCrossRootAria(this, 'id', value);
6799
+ },
6800
+ // On the default descriptor for 'id', enumerable and configurable are true
6801
+ enumerable: true,
6802
+ configurable: true,
6803
+ });
6804
+ }
6805
+ }
6447
6806
  }
6448
- function disconnectWireAdapters(vm) {
6449
- const {
6450
- wiredDisconnecting
6451
- } = vm.context;
6452
- runWithBoundaryProtection(vm, vm, noop, () => {
6453
- // job
6454
- for (let i = 0, len = wiredDisconnecting.length; i < len; i += 1) {
6455
- wiredDisconnecting[i]();
6807
+ // Our detection logic relies on some modern browser features. We can just skip reporting the data
6808
+ // for unsupported browsers
6809
+ function supportsCssEscape() {
6810
+ return typeof CSS !== 'undefined' && isFunction$1(CSS.escape);
6811
+ }
6812
+ // If this page is not using synthetic shadow, then we don't need to install detection. Note
6813
+ // that we are assuming synthetic shadow is loaded before LWC.
6814
+ function isSyntheticShadowLoaded() {
6815
+ // We should probably be calling `renderer.isSyntheticShadowDefined`, but 1) we don't have access to the renderer,
6816
+ // and 2) this code needs to run in @lwc/engine-core, so it can access `logWarn()` and `report()`.
6817
+ return hasOwnProperty$1.call(Element.prototype, KEY__SHADOW_TOKEN);
6818
+ }
6819
+ // Detecting cross-root ARIA in synthetic shadow only makes sense for the browser
6820
+ if (supportsCssEscape() && isSyntheticShadowLoaded()) {
6821
+ // Always run detection in dev mode, so we can at least print to the console
6822
+ if (process.env.NODE_ENV !== 'production') {
6823
+ enableDetection();
6824
+ }
6825
+ else {
6826
+ // In prod mode, only enable detection if reporting is enabled
6827
+ onReportingEnabled(enableDetection);
6456
6828
  }
6457
- }, noop);
6458
6829
  }
6459
6830
 
6460
6831
  /*
@@ -7126,7 +7497,7 @@
7126
7497
  }
7127
7498
  return ctor;
7128
7499
  }
7129
- /* version: 2.33.0 */
7500
+ /* version: 2.35.0 */
7130
7501
 
7131
7502
  /*
7132
7503
  * Copyright (c) 2018, salesforce.com, inc.
@@ -7233,7 +7604,9 @@
7233
7604
  //
7234
7605
  // Test utilities
7235
7606
  //
7236
- if (process.env.NODE_ENV === 'development') {
7607
+ // Only used in LWC's Karma tests
7608
+ // @ts-ignore
7609
+ if (process.env.NODE_ENV !== 'production' && typeof __karma__ !== 'undefined') {
7237
7610
  // @ts-ignore
7238
7611
  window.__lwcResetGlobalStylesheets = () => {
7239
7612
  stylesheetCache.clear();
@@ -8099,7 +8472,7 @@
8099
8472
  function isNull(obj) {
8100
8473
  return obj === null;
8101
8474
  }
8102
- /** version: 2.33.0 */
8475
+ /** version: 2.35.0 */
8103
8476
 
8104
8477
  /*
8105
8478
  * Copyright (c) 2018, salesforce.com, inc.
@@ -8660,10 +9033,11 @@
8660
9033
  });
8661
9034
  freeze(LightningElement);
8662
9035
  seal(LightningElement.prototype);
8663
- /* version: 2.33.0 */
9036
+ /* version: 2.35.0 */
8664
9037
 
8665
9038
  exports.LightningElement = LightningElement;
8666
9039
  exports.__unstable__ProfilerControl = profilerControl;
9040
+ exports.__unstable__ReportingControl = reportingControl;
8667
9041
  exports.api = api$1;
8668
9042
  exports.buildCustomElementConstructor = deprecatedBuildCustomElementConstructor;
8669
9043
  exports.createContextProvider = createContextProvider;