@lwc/ssr-runtime 8.6.0 → 8.7.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.
@@ -0,0 +1 @@
1
+ export declare function cloneAndDeepFreeze<T>(obj: T): T;
package/dist/index.cjs.js CHANGED
@@ -299,8 +299,18 @@ from: ArrayFrom, } = Array;
299
299
  // statement, rather than this declaration.
300
300
  const { concat: ArrayConcat, copyWithin: ArrayCopyWithin, every: ArrayEvery, fill: ArrayFill, filter: ArrayFilter, find: ArrayFind, findIndex: ArrayFindIndex, includes: ArrayIncludes, indexOf: ArrayIndexOf, join: ArrayJoin, map: ArrayMap, pop: ArrayPop, push: ArrayPush, reduce: ArrayReduce, reverse: ArrayReverse, shift: ArrayShift, slice: ArraySlice, some: ArraySome, sort: ArraySort, splice: ArraySplice, unshift: ArrayUnshift, forEach, // Weird anomaly!
301
301
  } = Array.prototype;
302
+ /** Detached {@linkcode String.fromCharCode}; see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode MDN Reference}. */
303
+ const { fromCharCode: StringFromCharCode } = String;
302
304
  // No JSDocs here - see comment for Array.prototype
303
305
  const { charAt: StringCharAt, charCodeAt: StringCharCodeAt, replace: StringReplace, split: StringSplit, slice: StringSlice, toLowerCase: StringToLowerCase, trim: StringTrim, } = String.prototype;
306
+ /**
307
+ * Determines whether the argument is `undefined`.
308
+ * @param obj Value to test
309
+ * @returns `true` if the value is `undefined`.
310
+ */
311
+ function isUndefined(obj) {
312
+ return obj === undefined;
313
+ }
304
314
  /**
305
315
  * Determines whether the argument is `null`.
306
316
  * @param obj Value to test
@@ -309,6 +319,14 @@ const { charAt: StringCharAt, charCodeAt: StringCharCodeAt, replace: StringRepla
309
319
  function isNull(obj) {
310
320
  return obj === null;
311
321
  }
322
+ /**
323
+ * Determines whether the argument is an object or null.
324
+ * @param obj Value to test
325
+ * @returns `true` if the value is an object or null.
326
+ */
327
+ function isObject(obj) {
328
+ return typeof obj === 'object';
329
+ }
312
330
  const OtS = {}.toString;
313
331
  /**
314
332
  * Converts the argument to a string, safely accounting for objects with "null" prototype.
@@ -423,11 +441,114 @@ const { AriaAttrNameToPropNameMap, AriaPropNameToAttrNameMap } = /*@__PURE__*/ (
423
441
  // Synthetic creation of all AOM property descriptors for Custom Elements
424
442
  forEach.call(AriaPropertyNames, (propName) => {
425
443
  const attrName = StringToLowerCase.call(StringReplace.call(propName, /^aria/, () => 'aria-'));
444
+ // These type assertions are because the map types are a 1:1 mapping of ariaX to aria-x.
445
+ // TypeScript knows we have one of ariaX | ariaY and one of aria-x | aria-y, and tries to
446
+ // prevent us from doing ariaX: aria-y, but we that it's safe.
426
447
  AriaAttrNameToPropNameMap[attrName] = propName;
427
448
  AriaPropNameToAttrNameMap[propName] = attrName;
428
449
  });
429
450
  return { AriaAttrNameToPropNameMap, AriaPropNameToAttrNameMap };
430
451
  })();
452
+ /**
453
+ *
454
+ * @param attrName
455
+ */
456
+ function isAriaAttribute(attrName) {
457
+ return attrName in AriaAttrNameToPropNameMap;
458
+ }
459
+ // This list is based on https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes
460
+ const GLOBAL_ATTRIBUTE = /*@__PURE__*/ new Set([
461
+ 'accesskey',
462
+ 'autocapitalize',
463
+ 'autofocus',
464
+ 'class',
465
+ 'contenteditable',
466
+ 'contextmenu',
467
+ 'dir',
468
+ 'draggable',
469
+ 'enterkeyhint',
470
+ 'exportparts',
471
+ 'hidden',
472
+ 'id',
473
+ 'inputmode',
474
+ 'is',
475
+ 'itemid',
476
+ 'itemprop',
477
+ 'itemref',
478
+ 'itemscope',
479
+ 'itemtype',
480
+ 'lang',
481
+ 'nonce',
482
+ 'part',
483
+ 'slot',
484
+ 'spellcheck',
485
+ 'style',
486
+ 'tabindex',
487
+ 'title',
488
+ 'translate',
489
+ ]);
490
+ /**
491
+ *
492
+ * @param attrName
493
+ */
494
+ function isGlobalHtmlAttribute(attrName) {
495
+ return GLOBAL_ATTRIBUTE.has(attrName);
496
+ }
497
+ // These are HTML standard prop/attribute IDL mappings, but are not predictable based on camel/kebab-case conversion
498
+ const SPECIAL_PROPERTY_ATTRIBUTE_MAPPING = /*@__PURE__@*/ new Map([
499
+ ['accessKey', 'accesskey'],
500
+ ['readOnly', 'readonly'],
501
+ ['tabIndex', 'tabindex'],
502
+ ['bgColor', 'bgcolor'],
503
+ ['colSpan', 'colspan'],
504
+ ['rowSpan', 'rowspan'],
505
+ ['contentEditable', 'contenteditable'],
506
+ ['crossOrigin', 'crossorigin'],
507
+ ['dateTime', 'datetime'],
508
+ ['formAction', 'formaction'],
509
+ ['isMap', 'ismap'],
510
+ ['maxLength', 'maxlength'],
511
+ ['minLength', 'minlength'],
512
+ ['noValidate', 'novalidate'],
513
+ ['useMap', 'usemap'],
514
+ ['htmlFor', 'for'],
515
+ ]);
516
+ /**
517
+ * Map associating previously transformed HTML property into HTML attribute.
518
+ */
519
+ const CACHED_PROPERTY_ATTRIBUTE_MAPPING = /*@__PURE__@*/ new Map();
520
+ /**
521
+ *
522
+ * @param propName
523
+ */
524
+ function htmlPropertyToAttribute(propName) {
525
+ const ariaAttributeName = AriaPropNameToAttrNameMap[propName];
526
+ if (!isUndefined(ariaAttributeName)) {
527
+ return ariaAttributeName;
528
+ }
529
+ const specialAttributeName = SPECIAL_PROPERTY_ATTRIBUTE_MAPPING.get(propName);
530
+ if (!isUndefined(specialAttributeName)) {
531
+ return specialAttributeName;
532
+ }
533
+ const cachedAttributeName = CACHED_PROPERTY_ATTRIBUTE_MAPPING.get(propName);
534
+ if (!isUndefined(cachedAttributeName)) {
535
+ return cachedAttributeName;
536
+ }
537
+ let attributeName = '';
538
+ for (let i = 0, len = propName.length; i < len; i++) {
539
+ const code = StringCharCodeAt.call(propName, i);
540
+ if (code >= 65 && // "A"
541
+ code <= 90 // "Z"
542
+ ) {
543
+ attributeName += '-' + StringFromCharCode(code + 32);
544
+ }
545
+ else {
546
+ attributeName += StringFromCharCode(code);
547
+ }
548
+ }
549
+ CACHED_PROPERTY_ATTRIBUTE_MAPPING.set(propName, attributeName);
550
+ return attributeName;
551
+ }
431
552
 
432
553
  /*
433
554
  * Copyright (c) 2020, salesforce.com, inc.
@@ -486,7 +607,7 @@ function flattenStylesheets(stylesheets) {
486
607
  }
487
608
  return list;
488
609
  }
489
- /** version: 8.6.0 */
610
+ /** version: 8.7.0 */
490
611
 
491
612
  /*
492
613
  * Copyright (c) 2024, Salesforce, Inc.
@@ -647,21 +768,25 @@ const mutationTracker = new MutationTracker();
647
768
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
648
769
  */
649
770
  /**
650
- * Map of global attribute or ARIA attribute to the corresponding property name.
651
- * Not all global attributes are included, just those from `HTMLElementTheGoodParts`.
771
+ * Filters out the following types of properties that should not be set.
772
+ * - Properties that are not public.
773
+ * - Properties that are not global.
774
+ * - Properties that are global but are internally overridden.
652
775
  */
653
- const attrsToProps = assign(create(null), {
654
- accesskey: 'accessKey',
655
- dir: 'dir',
656
- draggable: 'draggable',
657
- hidden: 'hidden',
658
- id: 'id',
659
- lang: 'lang',
660
- spellcheck: 'spellcheck',
661
- tabindex: 'tabIndex',
662
- title: 'title',
663
- ...AriaAttrNameToPropNameMap,
664
- });
776
+ function filterProperties(props, publicFields, privateFields) {
777
+ const propsToAssign = create(null);
778
+ const publicFieldSet = new Set(publicFields);
779
+ const privateFieldSet = new Set(privateFields);
780
+ keys(props).forEach((propName) => {
781
+ const attrName = htmlPropertyToAttribute(propName);
782
+ if (publicFieldSet.has(propName) ||
783
+ ((isGlobalHtmlAttribute(attrName) || isAriaAttribute(attrName)) &&
784
+ !privateFieldSet.has(propName))) {
785
+ propsToAssign[propName] = props[propName];
786
+ }
787
+ });
788
+ return propsToAssign;
789
+ }
665
790
  /**
666
791
  * Descriptor for IDL attribute reflections that merely reflect the string, e.g. `title`.
667
792
  */
@@ -742,16 +867,6 @@ const ariaDescriptor = (attrName) => ({
742
867
  }
743
868
  },
744
869
  });
745
- function reflectAttrToProp(instance, attrName, attrValue) {
746
- const reflectedPropName = attrsToProps[attrName];
747
- // If it is a reflected property and it was not overridden by the instance
748
- if (reflectedPropName && !hasOwnProperty.call(instance, reflectedPropName)) {
749
- const currentValue = instance[reflectedPropName];
750
- if (currentValue !== attrValue) {
751
- instance[reflectedPropName] = attrValue;
752
- }
753
- }
754
- }
755
870
  const descriptors = {
756
871
  accessKey: stringDescriptor('accesskey'),
757
872
  dir: stringDescriptor('dir'),
@@ -823,7 +938,6 @@ class LightningElement {
823
938
  const normalizedName = StringToLowerCase.call(toString(attrName));
824
939
  const normalizedValue = String(attrValue);
825
940
  __classPrivateFieldGet(this, _LightningElement_attrs, "f")[normalizedName] = normalizedValue;
826
- reflectAttrToProp(this, normalizedName, normalizedValue);
827
941
  mutationTracker.add(this, normalizedName);
828
942
  }
829
943
  getAttribute(attrName) {
@@ -840,7 +954,6 @@ class LightningElement {
840
954
  removeAttribute(attrName) {
841
955
  const normalizedName = StringToLowerCase.call(toString(attrName));
842
956
  delete __classPrivateFieldGet(this, _LightningElement_attrs, "f")[normalizedName];
843
- reflectAttrToProp(this, normalizedName, null);
844
957
  // Track mutations for removal of non-existing attributes
845
958
  mutationTracker.add(this, normalizedName);
846
959
  }
@@ -1109,15 +1222,50 @@ function* toIteratorDirective(iterable) {
1109
1222
  }
1110
1223
  }
1111
1224
 
1225
+ /*
1226
+ * Copyright (c) 2024, Salesforce, Inc.
1227
+ * All rights reserved.
1228
+ * SPDX-License-Identifier: MIT
1229
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
1230
+ */
1231
+ // Deep freeze and clone an object. Designed for cloning/freezing child props when passed from a parent to a child so
1232
+ // that they are immutable. This is one of the normal guarantees of both engine-dom and engine-server that we want to
1233
+ // emulate in ssr-runtime. The goal here is that a child cannot mutate the props of its parent and thus affect
1234
+ // the parent's rendering, which would lead to bidirectional reactivity and mischief.
1235
+ function cloneAndDeepFreeze(obj) {
1236
+ if (isArray(obj)) {
1237
+ const res = [];
1238
+ for (const item of obj) {
1239
+ ArrayPush.call(res, cloneAndDeepFreeze(item));
1240
+ }
1241
+ freeze(res);
1242
+ return res;
1243
+ }
1244
+ else if (isObject(obj) && !isNull(obj)) {
1245
+ const res = create(null);
1246
+ for (const [key, value] of entries(obj)) {
1247
+ res[key] = cloneAndDeepFreeze(value);
1248
+ }
1249
+ freeze(res);
1250
+ return res;
1251
+ }
1252
+ else {
1253
+ // primitive
1254
+ return obj;
1255
+ }
1256
+ }
1257
+
1112
1258
  exports.ClassList = ClassList;
1113
1259
  exports.LightningElement = LightningElement;
1114
1260
  exports.SYMBOL__GENERATE_MARKUP = SYMBOL__GENERATE_MARKUP;
1115
1261
  exports.SYMBOL__SET_INTERNALS = SYMBOL__SET_INTERNALS;
1116
1262
  exports.api = api;
1263
+ exports.cloneAndDeepFreeze = cloneAndDeepFreeze;
1117
1264
  exports.createContextProvider = createContextProvider;
1118
1265
  exports.createElement = createElement;
1119
1266
  exports.fallbackTmpl = fallbackTmpl;
1120
1267
  exports.fallbackTmplNoYield = fallbackTmplNoYield;
1268
+ exports.filterProperties = filterProperties;
1121
1269
  exports.freezeTemplate = freezeTemplate;
1122
1270
  exports.getComponentDef = getComponentDef;
1123
1271
  exports.hasScopedStaticStylesheets = hasScopedStaticStylesheets;
@@ -1149,5 +1297,5 @@ exports.track = track;
1149
1297
  exports.unwrap = unwrap;
1150
1298
  exports.validateStyleTextContents = validateStyleTextContents;
1151
1299
  exports.wire = wire;
1152
- /** version: 8.6.0 */
1300
+ /** version: 8.7.0 */
1153
1301
  //# sourceMappingURL=index.cjs.js.map