@lwc/engine-core 2.13.1 → 2.13.4

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.
@@ -3,8 +3,33 @@
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
- var shared = require('@lwc/shared');
7
6
  var features = require('@lwc/features');
7
+ var shared = require('@lwc/shared');
8
+
9
+ /*
10
+ * Copyright (c) 2018, salesforce.com, inc.
11
+ * All rights reserved.
12
+ * SPDX-License-Identifier: MIT
13
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
14
+ */
15
+ // @ts-ignore
16
+
17
+ if (process.env.NODE_ENV !== 'production' && typeof __karma__ !== 'undefined') {
18
+ window.addEventListener('test-dummy-flag', () => {
19
+ let hasFlag = false;
20
+
21
+ if (features.runtimeFlags.DUMMY_TEST_FLAG) {
22
+ hasFlag = true;
23
+ }
24
+
25
+ window.dispatchEvent(new CustomEvent('has-dummy-flag', {
26
+ detail: {
27
+ package: '@lwc/engine-core',
28
+ hasFlag
29
+ }
30
+ }));
31
+ });
32
+ }
8
33
 
9
34
  /*
10
35
  * Copyright (c) 2018, salesforce.com, inc.
@@ -106,9 +131,7 @@ let HTMLElementExported;
106
131
  function setHTMLElement(HTMLElementImpl) {
107
132
  HTMLElementExported = HTMLElementImpl;
108
133
  }
109
- let isHydrating;
110
134
  function setIsHydrating(isHydratingImpl) {
111
- isHydrating = isHydratingImpl;
112
135
  }
113
136
  let insert;
114
137
  function setInsert(insertImpl) {
@@ -230,10 +253,6 @@ let isConnected;
230
253
  function setIsConnected(isConnectedImpl) {
231
254
  isConnected = isConnectedImpl;
232
255
  }
233
- let insertGlobalStylesheet;
234
- function setInsertGlobalStylesheet(insertGlobalStylesheetImpl) {
235
- insertGlobalStylesheet = insertGlobalStylesheetImpl;
236
- }
237
256
  let insertStylesheet;
238
257
  function setInsertStylesheet(insertStylesheetImpl) {
239
258
  insertStylesheet = insertStylesheetImpl;
@@ -2321,6 +2340,12 @@ function checkVersionMismatch(func, type) {
2321
2340
  }
2322
2341
  }
2323
2342
 
2343
+ /*
2344
+ * Copyright (c) 2018, salesforce.com, inc.
2345
+ * All rights reserved.
2346
+ * SPDX-License-Identifier: MIT
2347
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
2348
+ */
2324
2349
  const signedTemplateSet = new Set();
2325
2350
  function defaultEmptyTemplate() {
2326
2351
  return [];
@@ -2338,6 +2363,32 @@ function registerTemplate(tpl) {
2338
2363
  checkVersionMismatch(tpl, 'template');
2339
2364
  }
2340
2365
  signedTemplateSet.add(tpl);
2366
+ // FIXME[@W-10950976]: the template object should be frozen, and it should not be possible to set
2367
+ // the stylesheets or stylesheetToken(s). For backwards compat, though, we shim stylesheetTokens
2368
+ // on top of stylesheetToken for anyone who is accessing the old internal API.
2369
+ // Details: https://salesforce.quip.com/v1rmAFu2cKAr
2370
+ shared.defineProperty(tpl, 'stylesheetTokens', {
2371
+ enumerable: true,
2372
+ configurable: true,
2373
+ get() {
2374
+ const { stylesheetToken } = this;
2375
+ if (shared.isUndefined(stylesheetToken)) {
2376
+ return stylesheetToken;
2377
+ }
2378
+ // Shim for the old `stylesheetTokens` property
2379
+ // See https://github.com/salesforce/lwc/pull/2332/files#diff-7901555acef29969adaa6583185b3e9bce475cdc6f23e799a54e0018cb18abaa
2380
+ return {
2381
+ hostAttribute: `${stylesheetToken}-host`,
2382
+ shadowAttribute: stylesheetToken,
2383
+ };
2384
+ },
2385
+ set(value) {
2386
+ // If the value is null or some other exotic object, you would be broken anyway in the past
2387
+ // because the engine would try to access hostAttribute/shadowAttribute, which would throw an error.
2388
+ // However it may be undefined in newer versions of LWC, so we need to guard against that case.
2389
+ this.stylesheetToken = shared.isUndefined(value) ? undefined : value.shadowAttribute;
2390
+ },
2391
+ });
2341
2392
  // chaining this method as a way to wrap existing
2342
2393
  // assignment of templates easily, without too much transformation
2343
2394
  return tpl;
@@ -3402,15 +3453,16 @@ function mountVNodes(vnodes, parent, anchor, start = 0, end = vnodes.length) {
3402
3453
  }
3403
3454
  }
3404
3455
  function unmount(vnode, parent, doRemove = false) {
3405
- const { type, elm } = vnode;
3456
+ const { type, elm, sel } = vnode;
3406
3457
  // When unmounting a VNode subtree not all the elements have to removed from the DOM. The
3407
3458
  // subtree root, is the only element worth unmounting from the subtree.
3408
3459
  if (doRemove) {
3409
3460
  removeNode(elm, parent);
3410
3461
  }
3462
+ const removeChildren = sel === 'slot'; // slot content is removed to trigger slotchange event when removing slot
3411
3463
  switch (type) {
3412
3464
  case 2 /* Element */:
3413
- unmountVNodes(vnode.children, elm);
3465
+ unmountVNodes(vnode.children, elm, removeChildren);
3414
3466
  break;
3415
3467
  case 3 /* CustomElement */: {
3416
3468
  const { vm } = vnode;
@@ -4328,10 +4380,10 @@ function createStylesheet(vm, stylesheets) {
4328
4380
  const { renderMode, shadowMode } = vm;
4329
4381
  if (renderMode === 1 /* Shadow */ && shadowMode === 1 /* Synthetic */) {
4330
4382
  for (let i = 0; i < stylesheets.length; i++) {
4331
- insertGlobalStylesheet(stylesheets[i]);
4383
+ insertStylesheet(stylesheets[i]);
4332
4384
  }
4333
4385
  }
4334
- else if (ssr || isHydrating()) {
4386
+ else if (ssr || vm.hydrated) {
4335
4387
  // Note: We need to ensure that during hydration, the stylesheets method is the same as those in ssr.
4336
4388
  // This works in the client, because the stylesheets are created, and cached in the VM
4337
4389
  // the first time the VM renders.
@@ -4342,15 +4394,10 @@ function createStylesheet(vm, stylesheets) {
4342
4394
  else {
4343
4395
  // native shadow or light DOM, DOM renderer
4344
4396
  const root = getNearestNativeShadowComponent(vm);
4345
- const isGlobal = shared.isNull(root);
4397
+ // null root means a global style
4398
+ const target = shared.isNull(root) ? undefined : root.shadowRoot;
4346
4399
  for (let i = 0; i < stylesheets.length; i++) {
4347
- if (isGlobal) {
4348
- insertGlobalStylesheet(stylesheets[i]);
4349
- }
4350
- else {
4351
- // local level
4352
- insertStylesheet(stylesheets[i], root.shadowRoot);
4353
- }
4400
+ insertStylesheet(stylesheets[i], target);
4354
4401
  }
4355
4402
  }
4356
4403
  return null;
@@ -4892,24 +4939,14 @@ function removeVM(vm) {
4892
4939
 
4893
4940
  resetComponentStateWhenRemoved(vm);
4894
4941
  }
4895
-
4896
- function getNearestShadowAncestor(vm) {
4897
- let ancestor = vm.owner;
4898
-
4899
- while (!shared.isNull(ancestor) && ancestor.renderMode === 0
4900
- /* Light */
4901
- ) {
4902
- ancestor = ancestor.owner;
4903
- }
4904
-
4905
- return ancestor;
4906
- }
4907
-
4908
4942
  function createVM(elm, ctor, options) {
4943
+ var _a;
4944
+
4909
4945
  const {
4910
4946
  mode,
4911
4947
  owner,
4912
- tagName
4948
+ tagName,
4949
+ hydrated
4913
4950
  } = options;
4914
4951
  const def = getComponentInternalDef(ctor);
4915
4952
  const vm = {
@@ -4932,7 +4969,10 @@ function createVM(elm, ctor, options) {
4932
4969
  cmpSlots: shared.create(null),
4933
4970
  oar: shared.create(null),
4934
4971
  cmpTemplate: null,
4972
+ hydrated: Boolean(hydrated),
4935
4973
  renderMode: def.renderMode,
4974
+ shadowMode: computeShadowMode(def, owner),
4975
+ nearestShadowMode: (owner === null || owner === void 0 ? void 0 : owner.shadowRoot) ? owner.shadowMode : (_a = owner === null || owner === void 0 ? void 0 : owner.nearestShadowMode) !== null && _a !== void 0 ? _a : null,
4936
4976
  context: {
4937
4977
  stylesheetToken: undefined,
4938
4978
  hasTokenInClass: undefined,
@@ -4945,7 +4985,6 @@ function createVM(elm, ctor, options) {
4945
4985
  },
4946
4986
  // Properties set right after VM creation.
4947
4987
  tro: null,
4948
- shadowMode: null,
4949
4988
  // Properties set by the LightningElement constructor.
4950
4989
  component: null,
4951
4990
  shadowRoot: null,
@@ -4954,7 +4993,6 @@ function createVM(elm, ctor, options) {
4954
4993
  setHook,
4955
4994
  getHook
4956
4995
  };
4957
- vm.shadowMode = computeShadowMode(vm);
4958
4996
  vm.tro = getTemplateReactiveObserver(vm);
4959
4997
 
4960
4998
  if (process.env.NODE_ENV !== 'production') {
@@ -4979,10 +5017,9 @@ function createVM(elm, ctor, options) {
4979
5017
  return vm;
4980
5018
  }
4981
5019
 
4982
- function computeShadowMode(vm) {
4983
- const {
4984
- def
4985
- } = vm;
5020
+ function computeShadowMode(def, owner) {
5021
+ var _a;
5022
+
4986
5023
  let shadowMode;
4987
5024
 
4988
5025
  if (isSyntheticShadowDefined) {
@@ -5005,23 +5042,13 @@ function computeShadowMode(vm) {
5005
5042
  /* Native */
5006
5043
  ;
5007
5044
  } else {
5008
- const shadowAncestor = getNearestShadowAncestor(vm);
5009
-
5010
- if (!shared.isNull(shadowAncestor) && shadowAncestor.shadowMode === 0
5011
- /* Native */
5012
- ) {
5013
- // Transitive support for native Shadow DOM. A component in native mode
5014
- // transitively opts all of its descendants into native.
5015
- shadowMode = 0
5016
- /* Native */
5017
- ;
5018
- } else {
5019
- // Synthetic if neither this component nor any of its ancestors are configured
5020
- // to be native.
5021
- shadowMode = 1
5022
- /* Synthetic */
5023
- ;
5024
- }
5045
+ // Transitive support for native Shadow DOM. A component in native mode
5046
+ // transitively opts all of its descendants into native.
5047
+ // Synthetic if neither this component nor any of its ancestors are configured
5048
+ // to be native.
5049
+ shadowMode = (_a = owner === null || owner === void 0 ? void 0 : owner.nearestShadowMode) !== null && _a !== void 0 ? _a : 1
5050
+ /* Synthetic */
5051
+ ;
5025
5052
  }
5026
5053
  } else {
5027
5054
  shadowMode = 1
@@ -5917,6 +5944,7 @@ function hydrateCustomElement(elm, vnode) {
5917
5944
  mode,
5918
5945
  owner,
5919
5946
  tagName: sel,
5947
+ hydrated: true,
5920
5948
  });
5921
5949
  vnode.elm = elm;
5922
5950
  vnode.vm = vm;
@@ -6111,6 +6139,128 @@ function setHooks(hooks) {
6111
6139
  setSanitizeHtmlContentHook(hooks.sanitizeHtmlContent);
6112
6140
  }
6113
6141
 
6142
+ /*
6143
+ * Copyright (c) 2018, salesforce.com, inc.
6144
+ * All rights reserved.
6145
+ * SPDX-License-Identifier: MIT
6146
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
6147
+ */
6148
+ // See @lwc/engine-core/src/framework/template.ts
6149
+ const TEMPLATE_PROPS = ['slots', 'stylesheetToken', 'stylesheets', 'renderMode'];
6150
+ // Via https://www.npmjs.com/package/object-observer
6151
+ const ARRAY_MUTATION_METHODS = [
6152
+ 'pop',
6153
+ 'push',
6154
+ 'shift',
6155
+ 'unshift',
6156
+ 'reverse',
6157
+ 'sort',
6158
+ 'fill',
6159
+ 'splice',
6160
+ 'copyWithin',
6161
+ ];
6162
+ function getOriginalArrayMethod(prop) {
6163
+ switch (prop) {
6164
+ case 'pop':
6165
+ return shared.ArrayPop;
6166
+ case 'push':
6167
+ return shared.ArrayPush;
6168
+ case 'shift':
6169
+ return shared.ArrayShift;
6170
+ case 'unshift':
6171
+ return shared.ArrayUnshift;
6172
+ case 'reverse':
6173
+ return shared.ArrayReverse;
6174
+ case 'sort':
6175
+ return shared.ArraySort;
6176
+ case 'fill':
6177
+ return shared.ArrayFill;
6178
+ case 'splice':
6179
+ return shared.ArraySplice;
6180
+ case 'copyWithin':
6181
+ return shared.ArrayCopyWithin;
6182
+ }
6183
+ }
6184
+ let mutationWarningsSilenced = false;
6185
+ // Warn if the user tries to mutate tmpl.stylesheets, e.g.:
6186
+ // `tmpl.stylesheets.push(someStylesheetFunction)`
6187
+ function warnOnArrayMutation(stylesheets) {
6188
+ // We can't handle users calling Array.prototype.slice.call(tmpl.stylesheets), but
6189
+ // we can at least warn when they use the most common mutation methods.
6190
+ for (const prop of ARRAY_MUTATION_METHODS) {
6191
+ const originalArrayMethod = getOriginalArrayMethod(prop);
6192
+ stylesheets[prop] = function arrayMutationWarningWrapper() {
6193
+ logError(`Mutating the "stylesheets" array on a template function ` +
6194
+ `is deprecated and may be removed in a future version of LWC.`);
6195
+ // @ts-ignore
6196
+ return originalArrayMethod.apply(this, arguments);
6197
+ };
6198
+ }
6199
+ }
6200
+ // TODO [#2782]: eventually freezeTemplate() will _actually_ freeze the tmpl object. Today it
6201
+ // just warns on mutation.
6202
+ function freezeTemplate(tmpl) {
6203
+ if (process.env.NODE_ENV !== 'production') {
6204
+ if (!shared.isUndefined(tmpl.stylesheets)) {
6205
+ warnOnArrayMutation(tmpl.stylesheets);
6206
+ }
6207
+ for (const prop of TEMPLATE_PROPS) {
6208
+ let value = tmpl[prop];
6209
+ shared.defineProperty(tmpl, prop, {
6210
+ enumerable: true,
6211
+ configurable: true,
6212
+ get() {
6213
+ return value;
6214
+ },
6215
+ set(newValue) {
6216
+ if (!mutationWarningsSilenced) {
6217
+ logError(`Dynamically setting the "${prop}" property on a template function ` +
6218
+ `is deprecated and may be removed in a future version of LWC.`);
6219
+ }
6220
+ value = newValue;
6221
+ },
6222
+ });
6223
+ }
6224
+ const originalDescriptor = shared.getOwnPropertyDescriptor(tmpl, 'stylesheetTokens');
6225
+ shared.defineProperty(tmpl, 'stylesheetTokens', {
6226
+ enumerable: true,
6227
+ configurable: true,
6228
+ get: originalDescriptor.get,
6229
+ set(value) {
6230
+ logError(`Dynamically setting the "stylesheetTokens" property on a template function ` +
6231
+ `is deprecated and may be removed in a future version of LWC.`);
6232
+ // Avoid logging twice (for both stylesheetToken and stylesheetTokens)
6233
+ mutationWarningsSilenced = true;
6234
+ originalDescriptor.set.call(this, value);
6235
+ mutationWarningsSilenced = false;
6236
+ },
6237
+ });
6238
+ }
6239
+ }
6240
+
6241
+ /*
6242
+ * Copyright (c) 2018, salesforce.com, inc.
6243
+ * All rights reserved.
6244
+ * SPDX-License-Identifier: MIT
6245
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
6246
+ */
6247
+ /**
6248
+ * EXPERIMENTAL: This function provides access to the component constructor, given an HTMLElement.
6249
+ * This API is subject to change or being removed.
6250
+ */
6251
+ function getComponentConstructor(elm) {
6252
+ let ctor = null;
6253
+ // intentionally checking for undefined due to some funky libraries patching weakmap.get
6254
+ // to throw when undefined.
6255
+ if (!shared.isUndefined(elm)) {
6256
+ const vm = getAssociatedVMIfPresent(elm);
6257
+ if (!shared.isUndefined(vm)) {
6258
+ ctor = vm.def.ctor;
6259
+ }
6260
+ }
6261
+ return ctor;
6262
+ }
6263
+
6114
6264
  Object.defineProperty(exports, 'setFeatureFlag', {
6115
6265
  enumerable: true,
6116
6266
  get: function () { return features.setFeatureFlag; }
@@ -6126,7 +6276,9 @@ exports.connectRootElement = connectRootElement;
6126
6276
  exports.createContextProvider = createContextProvider;
6127
6277
  exports.createVM = createVM;
6128
6278
  exports.disconnectRootElement = disconnectRootElement;
6279
+ exports.freezeTemplate = freezeTemplate;
6129
6280
  exports.getAssociatedVMIfPresent = getAssociatedVMIfPresent;
6281
+ exports.getComponentConstructor = getComponentConstructor;
6130
6282
  exports.getComponentDef = getComponentDef;
6131
6283
  exports.getComponentHtmlPrototype = getComponentHtmlPrototype;
6132
6284
  exports.getUpgradableConstructor = getUpgradableConstructor;
@@ -6162,7 +6314,6 @@ exports.setGetProperty = setGetProperty;
6162
6314
  exports.setHTMLElement = setHTMLElement;
6163
6315
  exports.setHooks = setHooks;
6164
6316
  exports.setInsert = setInsert;
6165
- exports.setInsertGlobalStylesheet = setInsertGlobalStylesheet;
6166
6317
  exports.setInsertStylesheet = setInsertStylesheet;
6167
6318
  exports.setIsConnected = setIsConnected;
6168
6319
  exports.setIsHydrating = setIsHydrating;
@@ -6185,4 +6336,4 @@ exports.swapTemplate = swapTemplate;
6185
6336
  exports.track = track;
6186
6337
  exports.unwrap = unwrap;
6187
6338
  exports.wire = wire;
6188
- /* version: 2.13.1 */
6339
+ /* version: 2.13.4 */
@@ -1,7 +1,32 @@
1
1
  /* proxy-compat-disable */
2
- import { seal, create, isFunction as isFunction$1, ArrayPush as ArrayPush$1, isUndefined as isUndefined$1, ArrayIndexOf, ArraySplice, StringToLowerCase, ArrayJoin, isNull, isFrozen, defineProperty, hasOwnProperty as hasOwnProperty$1, assign, forEach, keys, AriaPropNameToAttrNameMap, getPropertyDescriptor, defineProperties, getOwnPropertyNames as getOwnPropertyNames$1, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, isObject, assert, KEY__SYNTHETIC_MODE, toString as toString$1, isFalse, isTrue, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, LWC_VERSION_COMMENT_REGEX, LWC_VERSION, freeze, htmlPropertyToAttribute, ArraySlice, StringCharCodeAt, XML_NAMESPACE, XLINK_NAMESPACE, isString, StringSlice, SVG_NAMESPACE, KEY__SHADOW_RESOLVER, isArray as isArray$1, isNumber, StringReplace, KEY__SCOPED_CSS, noop, ArrayUnshift } from '@lwc/shared';
3
2
  import { runtimeFlags } from '@lwc/features';
4
3
  export { setFeatureFlag, setFeatureFlagForTest } from '@lwc/features';
4
+ import { seal, create, isFunction as isFunction$1, ArrayPush as ArrayPush$1, isUndefined as isUndefined$1, ArrayIndexOf, ArraySplice, StringToLowerCase, ArrayJoin, isNull, isFrozen, defineProperty, hasOwnProperty as hasOwnProperty$1, assign, forEach, keys, AriaPropNameToAttrNameMap, getPropertyDescriptor, defineProperties, getOwnPropertyNames as getOwnPropertyNames$1, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, isObject, assert, KEY__SYNTHETIC_MODE, toString as toString$1, isFalse, isTrue, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, LWC_VERSION_COMMENT_REGEX, LWC_VERSION, freeze, htmlPropertyToAttribute, ArraySlice, StringCharCodeAt, XML_NAMESPACE, XLINK_NAMESPACE, isString, StringSlice, SVG_NAMESPACE, KEY__SHADOW_RESOLVER, isArray as isArray$1, isNumber, StringReplace, KEY__SCOPED_CSS, noop, ArrayUnshift, ArrayCopyWithin, ArrayFill, ArraySort, ArrayReverse, ArrayShift, ArrayPop } from '@lwc/shared';
5
+
6
+ /*
7
+ * Copyright (c) 2018, salesforce.com, inc.
8
+ * All rights reserved.
9
+ * SPDX-License-Identifier: MIT
10
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
11
+ */
12
+ // @ts-ignore
13
+
14
+ if (process.env.NODE_ENV !== 'production' && typeof __karma__ !== 'undefined') {
15
+ window.addEventListener('test-dummy-flag', () => {
16
+ let hasFlag = false;
17
+
18
+ if (runtimeFlags.DUMMY_TEST_FLAG) {
19
+ hasFlag = true;
20
+ }
21
+
22
+ window.dispatchEvent(new CustomEvent('has-dummy-flag', {
23
+ detail: {
24
+ package: '@lwc/engine-core',
25
+ hasFlag
26
+ }
27
+ }));
28
+ });
29
+ }
5
30
 
6
31
  /*
7
32
  * Copyright (c) 2018, salesforce.com, inc.
@@ -103,9 +128,7 @@ let HTMLElementExported;
103
128
  function setHTMLElement(HTMLElementImpl) {
104
129
  HTMLElementExported = HTMLElementImpl;
105
130
  }
106
- let isHydrating;
107
131
  function setIsHydrating(isHydratingImpl) {
108
- isHydrating = isHydratingImpl;
109
132
  }
110
133
  let insert;
111
134
  function setInsert(insertImpl) {
@@ -227,10 +250,6 @@ let isConnected;
227
250
  function setIsConnected(isConnectedImpl) {
228
251
  isConnected = isConnectedImpl;
229
252
  }
230
- let insertGlobalStylesheet;
231
- function setInsertGlobalStylesheet(insertGlobalStylesheetImpl) {
232
- insertGlobalStylesheet = insertGlobalStylesheetImpl;
233
- }
234
253
  let insertStylesheet;
235
254
  function setInsertStylesheet(insertStylesheetImpl) {
236
255
  insertStylesheet = insertStylesheetImpl;
@@ -2318,6 +2337,12 @@ function checkVersionMismatch(func, type) {
2318
2337
  }
2319
2338
  }
2320
2339
 
2340
+ /*
2341
+ * Copyright (c) 2018, salesforce.com, inc.
2342
+ * All rights reserved.
2343
+ * SPDX-License-Identifier: MIT
2344
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
2345
+ */
2321
2346
  const signedTemplateSet = new Set();
2322
2347
  function defaultEmptyTemplate() {
2323
2348
  return [];
@@ -2335,6 +2360,32 @@ function registerTemplate(tpl) {
2335
2360
  checkVersionMismatch(tpl, 'template');
2336
2361
  }
2337
2362
  signedTemplateSet.add(tpl);
2363
+ // FIXME[@W-10950976]: the template object should be frozen, and it should not be possible to set
2364
+ // the stylesheets or stylesheetToken(s). For backwards compat, though, we shim stylesheetTokens
2365
+ // on top of stylesheetToken for anyone who is accessing the old internal API.
2366
+ // Details: https://salesforce.quip.com/v1rmAFu2cKAr
2367
+ defineProperty(tpl, 'stylesheetTokens', {
2368
+ enumerable: true,
2369
+ configurable: true,
2370
+ get() {
2371
+ const { stylesheetToken } = this;
2372
+ if (isUndefined$1(stylesheetToken)) {
2373
+ return stylesheetToken;
2374
+ }
2375
+ // Shim for the old `stylesheetTokens` property
2376
+ // See https://github.com/salesforce/lwc/pull/2332/files#diff-7901555acef29969adaa6583185b3e9bce475cdc6f23e799a54e0018cb18abaa
2377
+ return {
2378
+ hostAttribute: `${stylesheetToken}-host`,
2379
+ shadowAttribute: stylesheetToken,
2380
+ };
2381
+ },
2382
+ set(value) {
2383
+ // If the value is null or some other exotic object, you would be broken anyway in the past
2384
+ // because the engine would try to access hostAttribute/shadowAttribute, which would throw an error.
2385
+ // However it may be undefined in newer versions of LWC, so we need to guard against that case.
2386
+ this.stylesheetToken = isUndefined$1(value) ? undefined : value.shadowAttribute;
2387
+ },
2388
+ });
2338
2389
  // chaining this method as a way to wrap existing
2339
2390
  // assignment of templates easily, without too much transformation
2340
2391
  return tpl;
@@ -3399,15 +3450,16 @@ function mountVNodes(vnodes, parent, anchor, start = 0, end = vnodes.length) {
3399
3450
  }
3400
3451
  }
3401
3452
  function unmount(vnode, parent, doRemove = false) {
3402
- const { type, elm } = vnode;
3453
+ const { type, elm, sel } = vnode;
3403
3454
  // When unmounting a VNode subtree not all the elements have to removed from the DOM. The
3404
3455
  // subtree root, is the only element worth unmounting from the subtree.
3405
3456
  if (doRemove) {
3406
3457
  removeNode(elm, parent);
3407
3458
  }
3459
+ const removeChildren = sel === 'slot'; // slot content is removed to trigger slotchange event when removing slot
3408
3460
  switch (type) {
3409
3461
  case 2 /* Element */:
3410
- unmountVNodes(vnode.children, elm);
3462
+ unmountVNodes(vnode.children, elm, removeChildren);
3411
3463
  break;
3412
3464
  case 3 /* CustomElement */: {
3413
3465
  const { vm } = vnode;
@@ -4325,10 +4377,10 @@ function createStylesheet(vm, stylesheets) {
4325
4377
  const { renderMode, shadowMode } = vm;
4326
4378
  if (renderMode === 1 /* Shadow */ && shadowMode === 1 /* Synthetic */) {
4327
4379
  for (let i = 0; i < stylesheets.length; i++) {
4328
- insertGlobalStylesheet(stylesheets[i]);
4380
+ insertStylesheet(stylesheets[i]);
4329
4381
  }
4330
4382
  }
4331
- else if (ssr || isHydrating()) {
4383
+ else if (ssr || vm.hydrated) {
4332
4384
  // Note: We need to ensure that during hydration, the stylesheets method is the same as those in ssr.
4333
4385
  // This works in the client, because the stylesheets are created, and cached in the VM
4334
4386
  // the first time the VM renders.
@@ -4339,15 +4391,10 @@ function createStylesheet(vm, stylesheets) {
4339
4391
  else {
4340
4392
  // native shadow or light DOM, DOM renderer
4341
4393
  const root = getNearestNativeShadowComponent(vm);
4342
- const isGlobal = isNull(root);
4394
+ // null root means a global style
4395
+ const target = isNull(root) ? undefined : root.shadowRoot;
4343
4396
  for (let i = 0; i < stylesheets.length; i++) {
4344
- if (isGlobal) {
4345
- insertGlobalStylesheet(stylesheets[i]);
4346
- }
4347
- else {
4348
- // local level
4349
- insertStylesheet(stylesheets[i], root.shadowRoot);
4350
- }
4397
+ insertStylesheet(stylesheets[i], target);
4351
4398
  }
4352
4399
  }
4353
4400
  return null;
@@ -4889,24 +4936,14 @@ function removeVM(vm) {
4889
4936
 
4890
4937
  resetComponentStateWhenRemoved(vm);
4891
4938
  }
4892
-
4893
- function getNearestShadowAncestor(vm) {
4894
- let ancestor = vm.owner;
4895
-
4896
- while (!isNull(ancestor) && ancestor.renderMode === 0
4897
- /* Light */
4898
- ) {
4899
- ancestor = ancestor.owner;
4900
- }
4901
-
4902
- return ancestor;
4903
- }
4904
-
4905
4939
  function createVM(elm, ctor, options) {
4940
+ var _a;
4941
+
4906
4942
  const {
4907
4943
  mode,
4908
4944
  owner,
4909
- tagName
4945
+ tagName,
4946
+ hydrated
4910
4947
  } = options;
4911
4948
  const def = getComponentInternalDef(ctor);
4912
4949
  const vm = {
@@ -4929,7 +4966,10 @@ function createVM(elm, ctor, options) {
4929
4966
  cmpSlots: create(null),
4930
4967
  oar: create(null),
4931
4968
  cmpTemplate: null,
4969
+ hydrated: Boolean(hydrated),
4932
4970
  renderMode: def.renderMode,
4971
+ shadowMode: computeShadowMode(def, owner),
4972
+ nearestShadowMode: (owner === null || owner === void 0 ? void 0 : owner.shadowRoot) ? owner.shadowMode : (_a = owner === null || owner === void 0 ? void 0 : owner.nearestShadowMode) !== null && _a !== void 0 ? _a : null,
4933
4973
  context: {
4934
4974
  stylesheetToken: undefined,
4935
4975
  hasTokenInClass: undefined,
@@ -4942,7 +4982,6 @@ function createVM(elm, ctor, options) {
4942
4982
  },
4943
4983
  // Properties set right after VM creation.
4944
4984
  tro: null,
4945
- shadowMode: null,
4946
4985
  // Properties set by the LightningElement constructor.
4947
4986
  component: null,
4948
4987
  shadowRoot: null,
@@ -4951,7 +4990,6 @@ function createVM(elm, ctor, options) {
4951
4990
  setHook,
4952
4991
  getHook
4953
4992
  };
4954
- vm.shadowMode = computeShadowMode(vm);
4955
4993
  vm.tro = getTemplateReactiveObserver(vm);
4956
4994
 
4957
4995
  if (process.env.NODE_ENV !== 'production') {
@@ -4976,10 +5014,9 @@ function createVM(elm, ctor, options) {
4976
5014
  return vm;
4977
5015
  }
4978
5016
 
4979
- function computeShadowMode(vm) {
4980
- const {
4981
- def
4982
- } = vm;
5017
+ function computeShadowMode(def, owner) {
5018
+ var _a;
5019
+
4983
5020
  let shadowMode;
4984
5021
 
4985
5022
  if (isSyntheticShadowDefined) {
@@ -5002,23 +5039,13 @@ function computeShadowMode(vm) {
5002
5039
  /* Native */
5003
5040
  ;
5004
5041
  } else {
5005
- const shadowAncestor = getNearestShadowAncestor(vm);
5006
-
5007
- if (!isNull(shadowAncestor) && shadowAncestor.shadowMode === 0
5008
- /* Native */
5009
- ) {
5010
- // Transitive support for native Shadow DOM. A component in native mode
5011
- // transitively opts all of its descendants into native.
5012
- shadowMode = 0
5013
- /* Native */
5014
- ;
5015
- } else {
5016
- // Synthetic if neither this component nor any of its ancestors are configured
5017
- // to be native.
5018
- shadowMode = 1
5019
- /* Synthetic */
5020
- ;
5021
- }
5042
+ // Transitive support for native Shadow DOM. A component in native mode
5043
+ // transitively opts all of its descendants into native.
5044
+ // Synthetic if neither this component nor any of its ancestors are configured
5045
+ // to be native.
5046
+ shadowMode = (_a = owner === null || owner === void 0 ? void 0 : owner.nearestShadowMode) !== null && _a !== void 0 ? _a : 1
5047
+ /* Synthetic */
5048
+ ;
5022
5049
  }
5023
5050
  } else {
5024
5051
  shadowMode = 1
@@ -5914,6 +5941,7 @@ function hydrateCustomElement(elm, vnode) {
5914
5941
  mode,
5915
5942
  owner,
5916
5943
  tagName: sel,
5944
+ hydrated: true,
5917
5945
  });
5918
5946
  vnode.elm = elm;
5919
5947
  vnode.vm = vm;
@@ -6108,5 +6136,127 @@ function setHooks(hooks) {
6108
6136
  setSanitizeHtmlContentHook(hooks.sanitizeHtmlContent);
6109
6137
  }
6110
6138
 
6111
- export { LightningElement, profilerControl as __unstable__ProfilerControl, api$1 as api, connectRootElement, createContextProvider, createVM, disconnectRootElement, getAssociatedVMIfPresent, getComponentDef, getComponentHtmlPrototype, getUpgradableConstructor, hydrateRoot, isComponentConstructor, readonly, register, registerComponent, registerDecorators, registerTemplate, sanitizeAttribute, setAddEventListener, setAssertInstanceOfHTMLElement, setAttachShadow, setCreateComment, setCreateElement, setCreateText, setDefineCustomElement, setDispatchEvent, setGetAttribute, setGetBoundingClientRect, setGetChildNodes, setGetChildren, setGetClassList, setGetCustomElement, setGetElementsByClassName, setGetElementsByTagName, setGetFirstChild, setGetFirstElementChild, setGetLastChild, setGetLastElementChild, setGetProperty, setHTMLElement, setHooks, setInsert, setInsertGlobalStylesheet, setInsertStylesheet, setIsConnected, setIsHydrating, setIsNativeShadowDefined, setIsSyntheticShadowDefined, setNextSibling, setQuerySelector, setQuerySelectorAll, setRemove, setRemoveAttribute, setRemoveEventListener, setSetAttribute, setSetCSSStyleProperty, setSetProperty, setSetText, setSsr, swapComponent, swapStyle, swapTemplate, track, unwrap, wire };
6112
- /* version: 2.13.1 */
6139
+ /*
6140
+ * Copyright (c) 2018, salesforce.com, inc.
6141
+ * All rights reserved.
6142
+ * SPDX-License-Identifier: MIT
6143
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
6144
+ */
6145
+ // See @lwc/engine-core/src/framework/template.ts
6146
+ const TEMPLATE_PROPS = ['slots', 'stylesheetToken', 'stylesheets', 'renderMode'];
6147
+ // Via https://www.npmjs.com/package/object-observer
6148
+ const ARRAY_MUTATION_METHODS = [
6149
+ 'pop',
6150
+ 'push',
6151
+ 'shift',
6152
+ 'unshift',
6153
+ 'reverse',
6154
+ 'sort',
6155
+ 'fill',
6156
+ 'splice',
6157
+ 'copyWithin',
6158
+ ];
6159
+ function getOriginalArrayMethod(prop) {
6160
+ switch (prop) {
6161
+ case 'pop':
6162
+ return ArrayPop;
6163
+ case 'push':
6164
+ return ArrayPush$1;
6165
+ case 'shift':
6166
+ return ArrayShift;
6167
+ case 'unshift':
6168
+ return ArrayUnshift;
6169
+ case 'reverse':
6170
+ return ArrayReverse;
6171
+ case 'sort':
6172
+ return ArraySort;
6173
+ case 'fill':
6174
+ return ArrayFill;
6175
+ case 'splice':
6176
+ return ArraySplice;
6177
+ case 'copyWithin':
6178
+ return ArrayCopyWithin;
6179
+ }
6180
+ }
6181
+ let mutationWarningsSilenced = false;
6182
+ // Warn if the user tries to mutate tmpl.stylesheets, e.g.:
6183
+ // `tmpl.stylesheets.push(someStylesheetFunction)`
6184
+ function warnOnArrayMutation(stylesheets) {
6185
+ // We can't handle users calling Array.prototype.slice.call(tmpl.stylesheets), but
6186
+ // we can at least warn when they use the most common mutation methods.
6187
+ for (const prop of ARRAY_MUTATION_METHODS) {
6188
+ const originalArrayMethod = getOriginalArrayMethod(prop);
6189
+ stylesheets[prop] = function arrayMutationWarningWrapper() {
6190
+ logError(`Mutating the "stylesheets" array on a template function ` +
6191
+ `is deprecated and may be removed in a future version of LWC.`);
6192
+ // @ts-ignore
6193
+ return originalArrayMethod.apply(this, arguments);
6194
+ };
6195
+ }
6196
+ }
6197
+ // TODO [#2782]: eventually freezeTemplate() will _actually_ freeze the tmpl object. Today it
6198
+ // just warns on mutation.
6199
+ function freezeTemplate(tmpl) {
6200
+ if (process.env.NODE_ENV !== 'production') {
6201
+ if (!isUndefined$1(tmpl.stylesheets)) {
6202
+ warnOnArrayMutation(tmpl.stylesheets);
6203
+ }
6204
+ for (const prop of TEMPLATE_PROPS) {
6205
+ let value = tmpl[prop];
6206
+ defineProperty(tmpl, prop, {
6207
+ enumerable: true,
6208
+ configurable: true,
6209
+ get() {
6210
+ return value;
6211
+ },
6212
+ set(newValue) {
6213
+ if (!mutationWarningsSilenced) {
6214
+ logError(`Dynamically setting the "${prop}" property on a template function ` +
6215
+ `is deprecated and may be removed in a future version of LWC.`);
6216
+ }
6217
+ value = newValue;
6218
+ },
6219
+ });
6220
+ }
6221
+ const originalDescriptor = getOwnPropertyDescriptor$1(tmpl, 'stylesheetTokens');
6222
+ defineProperty(tmpl, 'stylesheetTokens', {
6223
+ enumerable: true,
6224
+ configurable: true,
6225
+ get: originalDescriptor.get,
6226
+ set(value) {
6227
+ logError(`Dynamically setting the "stylesheetTokens" property on a template function ` +
6228
+ `is deprecated and may be removed in a future version of LWC.`);
6229
+ // Avoid logging twice (for both stylesheetToken and stylesheetTokens)
6230
+ mutationWarningsSilenced = true;
6231
+ originalDescriptor.set.call(this, value);
6232
+ mutationWarningsSilenced = false;
6233
+ },
6234
+ });
6235
+ }
6236
+ }
6237
+
6238
+ /*
6239
+ * Copyright (c) 2018, salesforce.com, inc.
6240
+ * All rights reserved.
6241
+ * SPDX-License-Identifier: MIT
6242
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
6243
+ */
6244
+ /**
6245
+ * EXPERIMENTAL: This function provides access to the component constructor, given an HTMLElement.
6246
+ * This API is subject to change or being removed.
6247
+ */
6248
+ function getComponentConstructor(elm) {
6249
+ let ctor = null;
6250
+ // intentionally checking for undefined due to some funky libraries patching weakmap.get
6251
+ // to throw when undefined.
6252
+ if (!isUndefined$1(elm)) {
6253
+ const vm = getAssociatedVMIfPresent(elm);
6254
+ if (!isUndefined$1(vm)) {
6255
+ ctor = vm.def.ctor;
6256
+ }
6257
+ }
6258
+ return ctor;
6259
+ }
6260
+
6261
+ export { LightningElement, profilerControl as __unstable__ProfilerControl, api$1 as api, connectRootElement, createContextProvider, createVM, disconnectRootElement, freezeTemplate, getAssociatedVMIfPresent, getComponentConstructor, getComponentDef, getComponentHtmlPrototype, getUpgradableConstructor, hydrateRoot, isComponentConstructor, readonly, register, registerComponent, registerDecorators, registerTemplate, sanitizeAttribute, setAddEventListener, setAssertInstanceOfHTMLElement, setAttachShadow, setCreateComment, setCreateElement, setCreateText, setDefineCustomElement, setDispatchEvent, setGetAttribute, setGetBoundingClientRect, setGetChildNodes, setGetChildren, setGetClassList, setGetCustomElement, setGetElementsByClassName, setGetElementsByTagName, setGetFirstChild, setGetFirstElementChild, setGetLastChild, setGetLastElementChild, setGetProperty, setHTMLElement, setHooks, setInsert, setInsertStylesheet, setIsConnected, setIsHydrating, setIsNativeShadowDefined, setIsSyntheticShadowDefined, setNextSibling, setQuerySelector, setQuerySelectorAll, setRemove, setRemoveAttribute, setRemoveEventListener, setSetAttribute, setSetCSSStyleProperty, setSetProperty, setSetText, setSsr, swapComponent, swapStyle, swapTemplate, track, unwrap, wire };
6262
+ /* version: 2.13.4 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lwc/engine-core",
3
- "version": "2.13.1",
3
+ "version": "2.13.4",
4
4
  "description": "Core LWC engine APIs.",
5
5
  "homepage": "https://lwc.dev/",
6
6
  "repository": {
@@ -25,8 +25,8 @@
25
25
  "types/"
26
26
  ],
27
27
  "dependencies": {
28
- "@lwc/features": "2.13.1",
29
- "@lwc/shared": "2.13.1"
28
+ "@lwc/features": "2.13.4",
29
+ "@lwc/shared": "2.13.4"
30
30
  },
31
31
  "devDependencies": {
32
32
  "observable-membrane": "2.0.0"
@@ -0,0 +1,2 @@
1
+ import { Template } from './template';
2
+ export declare function freezeTemplate(tmpl: Template): void;
@@ -0,0 +1,6 @@
1
+ import { LightningElement } from './base-lightning-element';
2
+ /**
3
+ * EXPERIMENTAL: This function provides access to the component constructor, given an HTMLElement.
4
+ * This API is subject to change or being removed.
5
+ */
6
+ export declare function getComponentConstructor(elm: HTMLElement): typeof LightningElement | null;
@@ -19,5 +19,7 @@ export { profilerControl as __unstable__ProfilerControl } from './profiler';
19
19
  export { getUpgradableConstructor } from './upgradable-element';
20
20
  export { swapTemplate, swapComponent, swapStyle } from './hot-swaps';
21
21
  export { setHooks } from './overridable-hooks';
22
+ export { freezeTemplate } from './freeze-template';
23
+ export { getComponentConstructor } from './get-component-constructor';
22
24
  export type { ConfigValue as WireConfigValue, ContextValue as WireContextValue, DataCallback, WireAdapter, WireAdapterConstructor, WireAdapterSchemaValue, } from './wiring';
23
- export { setAssertInstanceOfHTMLElement, setAttachShadow, setCreateComment, setCreateElement, setCreateText, setDefineCustomElement, setDispatchEvent, setGetAttribute, setGetBoundingClientRect, setGetChildNodes, setGetChildren, setGetClassList, setGetCustomElement, setGetElementsByClassName, setGetElementsByTagName, setGetFirstChild, setGetFirstElementChild, setGetLastChild, setGetLastElementChild, setGetProperty, setHTMLElement, setInsert, setInsertGlobalStylesheet, setInsertStylesheet, setIsConnected, setIsHydrating, setIsNativeShadowDefined, setIsSyntheticShadowDefined, setNextSibling, setQuerySelector, setQuerySelectorAll, setRemove, setRemoveAttribute, setRemoveEventListener, setSetAttribute, setSetCSSStyleProperty, setSetProperty, setSetText, setSsr, setAddEventListener, } from '../renderer';
25
+ export { setAssertInstanceOfHTMLElement, setAttachShadow, setCreateComment, setCreateElement, setCreateText, setDefineCustomElement, setDispatchEvent, setGetAttribute, setGetBoundingClientRect, setGetChildNodes, setGetChildren, setGetClassList, setGetCustomElement, setGetElementsByClassName, setGetElementsByTagName, setGetFirstChild, setGetFirstElementChild, setGetLastChild, setGetLastElementChild, setGetProperty, setHTMLElement, setInsert, setIsConnected, setIsHydrating, setIsNativeShadowDefined, setIsSyntheticShadowDefined, setNextSibling, setQuerySelector, setQuerySelectorAll, setRemove, setRemoveAttribute, setRemoveEventListener, setSetAttribute, setSetCSSStyleProperty, setSetProperty, setSetText, setSsr, setAddEventListener, setInsertStylesheet, } from '../renderer';
@@ -62,9 +62,14 @@ export interface VM<N = HostNode, E = HostElement> {
62
62
  readonly context: Context;
63
63
  /** The owner VM or null for root elements. */
64
64
  readonly owner: VM<N, E> | null;
65
+ /** Whether or not the VM was hydrated */
66
+ readonly hydrated: boolean;
65
67
  /** Rendering operations associated with the VM */
66
- renderMode: RenderMode;
68
+ readonly renderMode: RenderMode;
67
69
  shadowMode: ShadowMode;
70
+ /** Transitive support for native Shadow DOM. A component in native mode
71
+ * transitively opts all of its descendants into native. */
72
+ readonly nearestShadowMode: ShadowMode | null;
68
73
  /** The component creation index. */
69
74
  idx: number;
70
75
  /** Component state, analogous to Element.isConnected */
@@ -130,6 +135,7 @@ export declare function createVM<HostNode, HostElement>(elm: HostElement, ctor:
130
135
  mode: ShadowRootMode;
131
136
  owner: VM<HostNode, HostElement> | null;
132
137
  tagName: string;
138
+ hydrated?: boolean;
133
139
  }): VM;
134
140
  export declare function associateVM(obj: VMAssociable, vm: VM): void;
135
141
  export declare function getAssociatedVM(obj: VMAssociable): VM;
package/types/index.d.ts CHANGED
@@ -1 +1,2 @@
1
+ import './testFeatureFlag';
1
2
  export * from './framework/main';
@@ -105,10 +105,7 @@ export declare function setGetLastElementChild(getLastElementChildImpl: getLastE
105
105
  declare type isConnectedFunc = (node: N) => boolean;
106
106
  export declare let isConnected: isConnectedFunc;
107
107
  export declare function setIsConnected(isConnectedImpl: isConnectedFunc): void;
108
- declare type insertGlobalStylesheetFunc = (content: string) => void;
109
- export declare let insertGlobalStylesheet: insertGlobalStylesheetFunc;
110
- export declare function setInsertGlobalStylesheet(insertGlobalStylesheetImpl: insertGlobalStylesheetFunc): void;
111
- declare type insertStylesheetFunc = (content: string, target: ShadowRoot) => void;
108
+ declare type insertStylesheetFunc = (content: string, target?: ShadowRoot) => void;
112
109
  export declare let insertStylesheet: insertStylesheetFunc;
113
110
  export declare function setInsertStylesheet(insertStylesheetImpl: insertStylesheetFunc): void;
114
111
  declare type assertInstanceOfHTMLElementFunc = (elm: any, msg: string) => void;
@@ -0,0 +1 @@
1
+ export {};