@lwc/synthetic-shadow 9.3.5 → 9.4.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.
package/dist/index.cjs CHANGED
@@ -191,13 +191,10 @@ const KEY__SHADOW_STATIC = '$shadowStaticNode$';
191
191
  const KEY__SHADOW_STATIC_PRIVATE = '$shadowStaticNodeKey$';
192
192
  const KEY__SHADOW_TOKEN = '$shadowToken$';
193
193
  const KEY__SHADOW_TOKEN_PRIVATE = '$$ShadowTokenKey$$';
194
- // TODO [#3733]: remove support for legacy scope tokens
195
- const KEY__LEGACY_SHADOW_TOKEN = '$legacyShadowToken$';
196
- const KEY__LEGACY_SHADOW_TOKEN_PRIVATE = '$$LegacyShadowTokenKey$$';
197
194
  const KEY__SYNTHETIC_MODE = '$$lwc-synthetic-mode';
198
195
  const KEY__NATIVE_GET_ELEMENT_BY_ID = '$nativeGetElementById$';
199
196
  const KEY__NATIVE_QUERY_SELECTOR_ALL = '$nativeQuerySelectorAll$';
200
- /** version: 9.3.5 */
197
+ /** version: 9.4.0 */
201
198
 
202
199
  /**
203
200
  * Copyright (c) 2026 Salesforce, Inc.
@@ -205,7 +202,7 @@ const KEY__NATIVE_QUERY_SELECTOR_ALL = '$nativeQuerySelectorAll$';
205
202
  if (!globalThis.lwcRuntimeFlags) {
206
203
  Object.defineProperty(globalThis, 'lwcRuntimeFlags', { value: create(null) });
207
204
  }
208
- /** version: 9.3.5 */
205
+ /** version: 9.4.0 */
209
206
 
210
207
  /*
211
208
  * Copyright (c) 2018, salesforce.com, inc.
@@ -855,6 +852,9 @@ StaticNodeList.prototype = create(NodeList.prototype, {
855
852
  enumerable: true,
856
853
  configurable: true,
857
854
  value(index) {
855
+ if (!Items$1.has(this) && !lwcRuntimeFlags.ENABLE_LEGACY_ITEM_POLYFILL) {
856
+ throw new TypeError('Cannot call "item" on object that is not a NodeList.');
857
+ }
858
858
  return this[index];
859
859
  },
860
860
  },
@@ -1035,6 +1035,9 @@ StaticHTMLCollection.prototype = create(HTMLCollection.prototype, {
1035
1035
  enumerable: true,
1036
1036
  configurable: true,
1037
1037
  value(index) {
1038
+ if (!Items.has(this) && !lwcRuntimeFlags.ENABLE_LEGACY_ITEM_POLYFILL) {
1039
+ throw new TypeError('Cannot call "item" on object that is not an HTMLCollection.');
1040
+ }
1038
1041
  return this[index];
1039
1042
  },
1040
1043
  },
@@ -1056,7 +1059,7 @@ StaticHTMLCollection.prototype = create(HTMLCollection.prototype, {
1056
1059
  }
1057
1060
  const items = Items.get(this);
1058
1061
  for (let i = 0, len = items.length; i < len; i++) {
1059
- const item = items[len];
1062
+ const item = items[lwcRuntimeFlags.ENABLE_BROKEN_HTML_COLLECTION_NAMED_ITEM ? len : i];
1060
1063
  if (name === getAttribute.call(item, 'id') ||
1061
1064
  name === getAttribute.call(item, 'name')) {
1062
1065
  return item;
@@ -1808,6 +1811,9 @@ function containsPatched(otherNode) {
1808
1811
  return ((compareDocumentPosition.call(host, otherNode) & DOCUMENT_POSITION_CONTAINED_BY) !== 0 &&
1809
1812
  isNodeOwnedBy(host, otherNode));
1810
1813
  }
1814
+ function disallowedGetElementById() {
1815
+ throw new Error(`Disallowed method "getElementById" on ShadowRoot.`);
1816
+ }
1811
1817
  const SyntheticShadowRootDescriptors = {
1812
1818
  constructor: {
1813
1819
  writable: true,
@@ -2199,12 +2205,24 @@ const ParentNodePatchDescriptors = {
2199
2205
  return children.item(children.length - 1) || null;
2200
2206
  },
2201
2207
  },
2208
+ // An accessor, unlike the other stubs, so the flag is read at call time (not at import) and the
2209
+ // setter preserves `root.getElementById = fn`. The flag exposes it as `undefined` so callers
2210
+ // that value-detect it fall back to `querySelector`; default OFF keeps the throwing stub.
2202
2211
  getElementById: {
2203
- writable: true,
2204
2212
  enumerable: true,
2205
2213
  configurable: true,
2206
- value() {
2207
- throw new Error('Disallowed method "getElementById" on ShadowRoot.');
2214
+ get() {
2215
+ return lwcRuntimeFlags.ENABLE_SHADOW_ROOT_UNDEFINED_GET_ELEMENT_BY_ID
2216
+ ? undefined
2217
+ : disallowedGetElementById;
2218
+ },
2219
+ set(value) {
2220
+ defineProperty(this, 'getElementById', {
2221
+ writable: true,
2222
+ enumerable: true,
2223
+ configurable: true,
2224
+ value,
2225
+ });
2208
2226
  },
2209
2227
  },
2210
2228
  querySelector: {
@@ -4231,40 +4249,6 @@ defineProperty(Element.prototype, KEY__SHADOW_STATIC, {
4231
4249
  configurable: true,
4232
4250
  });
4233
4251
 
4234
- /*
4235
- * Copyright (c) 2023, salesforce.com, inc.
4236
- * All rights reserved.
4237
- * SPDX-License-Identifier: MIT
4238
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
4239
- */
4240
- // TODO [#3733]: remove this entire file when we can remove legacy scope tokens
4241
- function getLegacyShadowToken(node) {
4242
- return node[KEY__LEGACY_SHADOW_TOKEN];
4243
- }
4244
- function setLegacyShadowToken(node, shadowToken) {
4245
- node[KEY__LEGACY_SHADOW_TOKEN] = shadowToken;
4246
- }
4247
- /**
4248
- * Patching Element.prototype.$legacyShadowToken$ to mark elements a portal:
4249
- * Same as $shadowToken$ but for legacy CSS scope tokens.
4250
- */
4251
- defineProperty(Element.prototype, KEY__LEGACY_SHADOW_TOKEN, {
4252
- set(shadowToken) {
4253
- const oldShadowToken = this[KEY__LEGACY_SHADOW_TOKEN_PRIVATE];
4254
- if (!isUndefined(oldShadowToken) && oldShadowToken !== shadowToken) {
4255
- removeAttribute.call(this, oldShadowToken);
4256
- }
4257
- if (!isUndefined(shadowToken)) {
4258
- setAttribute.call(this, shadowToken, '');
4259
- }
4260
- this[KEY__LEGACY_SHADOW_TOKEN_PRIVATE] = shadowToken;
4261
- },
4262
- get() {
4263
- return this[KEY__LEGACY_SHADOW_TOKEN_PRIVATE];
4264
- },
4265
- configurable: true,
4266
- });
4267
-
4268
4252
  /*
4269
4253
  * Copyright (c) 2018, salesforce.com, inc.
4270
4254
  * All rights reserved.
@@ -4282,8 +4266,7 @@ let portalObserver;
4282
4266
  const portalObserverConfig = {
4283
4267
  childList: true,
4284
4268
  };
4285
- // TODO [#3733]: remove support for legacy scope tokens
4286
- function adoptChildNode(node, fn, shadowToken, legacyShadowToken) {
4269
+ function adoptChildNode(node, fn, shadowToken) {
4287
4270
  const previousNodeShadowResolver = getShadowRootResolver(node);
4288
4271
  if (previousNodeShadowResolver === fn) {
4289
4272
  return; // nothing to do here, it is already correctly patched
@@ -4291,9 +4274,6 @@ function adoptChildNode(node, fn, shadowToken, legacyShadowToken) {
4291
4274
  setShadowRootResolver(node, fn);
4292
4275
  if (node instanceof Element) {
4293
4276
  setShadowToken(node, shadowToken);
4294
- if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
4295
- setLegacyShadowToken(node, legacyShadowToken);
4296
- }
4297
4277
  if (isSyntheticShadowHost(node)) {
4298
4278
  // Root LWC elements can't get content slotted into them, therefore we don't observe their children.
4299
4279
  return;
@@ -4305,7 +4285,7 @@ function adoptChildNode(node, fn, shadowToken, legacyShadowToken) {
4305
4285
  // recursively patching all children as well
4306
4286
  const childNodes = childNodesGetter.call(node);
4307
4287
  for (let i = 0, len = childNodes.length; i < len; i += 1) {
4308
- adoptChildNode(childNodes[i], fn, shadowToken, legacyShadowToken);
4288
+ adoptChildNode(childNodes[i], fn, shadowToken);
4309
4289
  }
4310
4290
  }
4311
4291
  }
@@ -4326,20 +4306,17 @@ function initPortalObserver() {
4326
4306
  // the target of the mutation should always have a ShadowRootResolver attached to it
4327
4307
  const fn = getShadowRootResolver(elm);
4328
4308
  const shadowToken = getShadowToken(elm);
4329
- const legacyShadowToken = lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS
4330
- ? getLegacyShadowToken(elm)
4331
- : undefined;
4332
4309
  // Process removals first to handle the case where an element is removed and reinserted
4333
4310
  for (let i = 0, len = removedNodes.length; i < len; i += 1) {
4334
4311
  const node = removedNodes[i];
4335
4312
  if (!(compareDocumentPosition.call(elm, node) & _Node.DOCUMENT_POSITION_CONTAINED_BY)) {
4336
- adoptChildNode(node, DocumentResolverFn, undefined, undefined);
4313
+ adoptChildNode(node, DocumentResolverFn, undefined);
4337
4314
  }
4338
4315
  }
4339
4316
  for (let i = 0, len = addedNodes.length; i < len; i += 1) {
4340
4317
  const node = addedNodes[i];
4341
4318
  if (compareDocumentPosition.call(elm, node) & _Node.DOCUMENT_POSITION_CONTAINED_BY) {
4342
- adoptChildNode(node, fn, shadowToken, legacyShadowToken);
4319
+ adoptChildNode(node, fn, shadowToken);
4343
4320
  }
4344
4321
  }
4345
4322
  });
@@ -4382,6 +4359,6 @@ defineProperty(Element.prototype, '$domManual$', {
4382
4359
  },
4383
4360
  configurable: true,
4384
4361
  });
4385
- /** version: 9.3.5 */
4362
+ /** version: 9.4.0 */
4386
4363
  }
4387
4364
  //# sourceMappingURL=index.cjs.map
package/dist/index.js CHANGED
@@ -189,13 +189,10 @@ const KEY__SHADOW_STATIC = '$shadowStaticNode$';
189
189
  const KEY__SHADOW_STATIC_PRIVATE = '$shadowStaticNodeKey$';
190
190
  const KEY__SHADOW_TOKEN = '$shadowToken$';
191
191
  const KEY__SHADOW_TOKEN_PRIVATE = '$$ShadowTokenKey$$';
192
- // TODO [#3733]: remove support for legacy scope tokens
193
- const KEY__LEGACY_SHADOW_TOKEN = '$legacyShadowToken$';
194
- const KEY__LEGACY_SHADOW_TOKEN_PRIVATE = '$$LegacyShadowTokenKey$$';
195
192
  const KEY__SYNTHETIC_MODE = '$$lwc-synthetic-mode';
196
193
  const KEY__NATIVE_GET_ELEMENT_BY_ID = '$nativeGetElementById$';
197
194
  const KEY__NATIVE_QUERY_SELECTOR_ALL = '$nativeQuerySelectorAll$';
198
- /** version: 9.3.5 */
195
+ /** version: 9.4.0 */
199
196
 
200
197
  /**
201
198
  * Copyright (c) 2026 Salesforce, Inc.
@@ -203,7 +200,7 @@ const KEY__NATIVE_QUERY_SELECTOR_ALL = '$nativeQuerySelectorAll$';
203
200
  if (!globalThis.lwcRuntimeFlags) {
204
201
  Object.defineProperty(globalThis, 'lwcRuntimeFlags', { value: create(null) });
205
202
  }
206
- /** version: 9.3.5 */
203
+ /** version: 9.4.0 */
207
204
 
208
205
  /*
209
206
  * Copyright (c) 2018, salesforce.com, inc.
@@ -853,6 +850,9 @@ StaticNodeList.prototype = create(NodeList.prototype, {
853
850
  enumerable: true,
854
851
  configurable: true,
855
852
  value(index) {
853
+ if (!Items$1.has(this) && !lwcRuntimeFlags.ENABLE_LEGACY_ITEM_POLYFILL) {
854
+ throw new TypeError('Cannot call "item" on object that is not a NodeList.');
855
+ }
856
856
  return this[index];
857
857
  },
858
858
  },
@@ -1033,6 +1033,9 @@ StaticHTMLCollection.prototype = create(HTMLCollection.prototype, {
1033
1033
  enumerable: true,
1034
1034
  configurable: true,
1035
1035
  value(index) {
1036
+ if (!Items.has(this) && !lwcRuntimeFlags.ENABLE_LEGACY_ITEM_POLYFILL) {
1037
+ throw new TypeError('Cannot call "item" on object that is not an HTMLCollection.');
1038
+ }
1036
1039
  return this[index];
1037
1040
  },
1038
1041
  },
@@ -1054,7 +1057,7 @@ StaticHTMLCollection.prototype = create(HTMLCollection.prototype, {
1054
1057
  }
1055
1058
  const items = Items.get(this);
1056
1059
  for (let i = 0, len = items.length; i < len; i++) {
1057
- const item = items[len];
1060
+ const item = items[lwcRuntimeFlags.ENABLE_BROKEN_HTML_COLLECTION_NAMED_ITEM ? len : i];
1058
1061
  if (name === getAttribute.call(item, 'id') ||
1059
1062
  name === getAttribute.call(item, 'name')) {
1060
1063
  return item;
@@ -1806,6 +1809,9 @@ function containsPatched(otherNode) {
1806
1809
  return ((compareDocumentPosition.call(host, otherNode) & DOCUMENT_POSITION_CONTAINED_BY) !== 0 &&
1807
1810
  isNodeOwnedBy(host, otherNode));
1808
1811
  }
1812
+ function disallowedGetElementById() {
1813
+ throw new Error(`Disallowed method "getElementById" on ShadowRoot.`);
1814
+ }
1809
1815
  const SyntheticShadowRootDescriptors = {
1810
1816
  constructor: {
1811
1817
  writable: true,
@@ -2197,12 +2203,24 @@ const ParentNodePatchDescriptors = {
2197
2203
  return children.item(children.length - 1) || null;
2198
2204
  },
2199
2205
  },
2206
+ // An accessor, unlike the other stubs, so the flag is read at call time (not at import) and the
2207
+ // setter preserves `root.getElementById = fn`. The flag exposes it as `undefined` so callers
2208
+ // that value-detect it fall back to `querySelector`; default OFF keeps the throwing stub.
2200
2209
  getElementById: {
2201
- writable: true,
2202
2210
  enumerable: true,
2203
2211
  configurable: true,
2204
- value() {
2205
- throw new Error('Disallowed method "getElementById" on ShadowRoot.');
2212
+ get() {
2213
+ return lwcRuntimeFlags.ENABLE_SHADOW_ROOT_UNDEFINED_GET_ELEMENT_BY_ID
2214
+ ? undefined
2215
+ : disallowedGetElementById;
2216
+ },
2217
+ set(value) {
2218
+ defineProperty(this, 'getElementById', {
2219
+ writable: true,
2220
+ enumerable: true,
2221
+ configurable: true,
2222
+ value,
2223
+ });
2206
2224
  },
2207
2225
  },
2208
2226
  querySelector: {
@@ -4229,40 +4247,6 @@ defineProperty(Element.prototype, KEY__SHADOW_STATIC, {
4229
4247
  configurable: true,
4230
4248
  });
4231
4249
 
4232
- /*
4233
- * Copyright (c) 2023, salesforce.com, inc.
4234
- * All rights reserved.
4235
- * SPDX-License-Identifier: MIT
4236
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
4237
- */
4238
- // TODO [#3733]: remove this entire file when we can remove legacy scope tokens
4239
- function getLegacyShadowToken(node) {
4240
- return node[KEY__LEGACY_SHADOW_TOKEN];
4241
- }
4242
- function setLegacyShadowToken(node, shadowToken) {
4243
- node[KEY__LEGACY_SHADOW_TOKEN] = shadowToken;
4244
- }
4245
- /**
4246
- * Patching Element.prototype.$legacyShadowToken$ to mark elements a portal:
4247
- * Same as $shadowToken$ but for legacy CSS scope tokens.
4248
- */
4249
- defineProperty(Element.prototype, KEY__LEGACY_SHADOW_TOKEN, {
4250
- set(shadowToken) {
4251
- const oldShadowToken = this[KEY__LEGACY_SHADOW_TOKEN_PRIVATE];
4252
- if (!isUndefined(oldShadowToken) && oldShadowToken !== shadowToken) {
4253
- removeAttribute.call(this, oldShadowToken);
4254
- }
4255
- if (!isUndefined(shadowToken)) {
4256
- setAttribute.call(this, shadowToken, '');
4257
- }
4258
- this[KEY__LEGACY_SHADOW_TOKEN_PRIVATE] = shadowToken;
4259
- },
4260
- get() {
4261
- return this[KEY__LEGACY_SHADOW_TOKEN_PRIVATE];
4262
- },
4263
- configurable: true,
4264
- });
4265
-
4266
4250
  /*
4267
4251
  * Copyright (c) 2018, salesforce.com, inc.
4268
4252
  * All rights reserved.
@@ -4280,8 +4264,7 @@ let portalObserver;
4280
4264
  const portalObserverConfig = {
4281
4265
  childList: true,
4282
4266
  };
4283
- // TODO [#3733]: remove support for legacy scope tokens
4284
- function adoptChildNode(node, fn, shadowToken, legacyShadowToken) {
4267
+ function adoptChildNode(node, fn, shadowToken) {
4285
4268
  const previousNodeShadowResolver = getShadowRootResolver(node);
4286
4269
  if (previousNodeShadowResolver === fn) {
4287
4270
  return; // nothing to do here, it is already correctly patched
@@ -4289,9 +4272,6 @@ function adoptChildNode(node, fn, shadowToken, legacyShadowToken) {
4289
4272
  setShadowRootResolver(node, fn);
4290
4273
  if (node instanceof Element) {
4291
4274
  setShadowToken(node, shadowToken);
4292
- if (lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS) {
4293
- setLegacyShadowToken(node, legacyShadowToken);
4294
- }
4295
4275
  if (isSyntheticShadowHost(node)) {
4296
4276
  // Root LWC elements can't get content slotted into them, therefore we don't observe their children.
4297
4277
  return;
@@ -4303,7 +4283,7 @@ function adoptChildNode(node, fn, shadowToken, legacyShadowToken) {
4303
4283
  // recursively patching all children as well
4304
4284
  const childNodes = childNodesGetter.call(node);
4305
4285
  for (let i = 0, len = childNodes.length; i < len; i += 1) {
4306
- adoptChildNode(childNodes[i], fn, shadowToken, legacyShadowToken);
4286
+ adoptChildNode(childNodes[i], fn, shadowToken);
4307
4287
  }
4308
4288
  }
4309
4289
  }
@@ -4324,20 +4304,17 @@ function initPortalObserver() {
4324
4304
  // the target of the mutation should always have a ShadowRootResolver attached to it
4325
4305
  const fn = getShadowRootResolver(elm);
4326
4306
  const shadowToken = getShadowToken(elm);
4327
- const legacyShadowToken = lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS
4328
- ? getLegacyShadowToken(elm)
4329
- : undefined;
4330
4307
  // Process removals first to handle the case where an element is removed and reinserted
4331
4308
  for (let i = 0, len = removedNodes.length; i < len; i += 1) {
4332
4309
  const node = removedNodes[i];
4333
4310
  if (!(compareDocumentPosition.call(elm, node) & _Node.DOCUMENT_POSITION_CONTAINED_BY)) {
4334
- adoptChildNode(node, DocumentResolverFn, undefined, undefined);
4311
+ adoptChildNode(node, DocumentResolverFn, undefined);
4335
4312
  }
4336
4313
  }
4337
4314
  for (let i = 0, len = addedNodes.length; i < len; i += 1) {
4338
4315
  const node = addedNodes[i];
4339
4316
  if (compareDocumentPosition.call(elm, node) & _Node.DOCUMENT_POSITION_CONTAINED_BY) {
4340
- adoptChildNode(node, fn, shadowToken, legacyShadowToken);
4317
+ adoptChildNode(node, fn, shadowToken);
4341
4318
  }
4342
4319
  }
4343
4320
  });
@@ -4380,6 +4357,6 @@ defineProperty(Element.prototype, '$domManual$', {
4380
4357
  },
4381
4358
  configurable: true,
4382
4359
  });
4383
- /** version: 9.3.5 */
4360
+ /** version: 9.4.0 */
4384
4361
  }
4385
4362
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten."
5
5
  ],
6
6
  "name": "@lwc/synthetic-shadow",
7
- "version": "9.3.5",
7
+ "version": "9.4.0",
8
8
  "description": "Synthetic Shadow Root for LWC",
9
9
  "keywords": [
10
10
  "lwc"
@@ -51,8 +51,8 @@
51
51
  }
52
52
  },
53
53
  "devDependencies": {
54
- "@lwc/features": "9.3.5",
55
- "@lwc/shared": "9.3.5"
54
+ "@lwc/features": "9.4.0",
55
+ "@lwc/shared": "9.4.0"
56
56
  },
57
57
  "lwc": {
58
58
  "modules": [
@@ -1,3 +0,0 @@
1
- export declare function getLegacyShadowToken(node: Node): string | undefined;
2
- export declare function setLegacyShadowToken(node: Node, shadowToken: string | undefined): void;
3
- //# sourceMappingURL=legacy-shadow-token.d.ts.map