@lwc/ssr-runtime 8.6.0 → 8.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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