@lwc/ssr-runtime 8.4.0 → 8.5.0

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.js CHANGED
@@ -146,6 +146,8 @@ defineProperty,
146
146
  entries,
147
147
  /** Detached {@linkcode Object.freeze}; see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze MDN Reference}. */
148
148
  freeze,
149
+ /** Detached {@linkcode Object.fromEntries}; see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries MDN Reference}. */
150
+ fromEntries,
149
151
  /** Detached {@linkcode Object.getOwnPropertyDescriptor}; see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor MDN Reference}. */
150
152
  getOwnPropertyDescriptor,
151
153
  /** Detached {@linkcode Object.getOwnPropertyDescriptors}; see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors MDN Reference}. */
@@ -328,7 +330,19 @@ function htmlEscape(str, attrMode = false) {
328
330
  const searchValue = attrMode ? /["&]/g : /["'<>&]/g;
329
331
  return str.replace(searchValue, (char) => ESCAPED_CHARS[char]);
330
332
  }
331
- /** version: 8.4.0 */
333
+ function flattenStylesheets(stylesheets) {
334
+ const list = [];
335
+ for (const stylesheet of stylesheets) {
336
+ if (!isArray(stylesheet)) {
337
+ list.push(stylesheet);
338
+ }
339
+ else {
340
+ list.push(...flattenStylesheets(stylesheet));
341
+ }
342
+ }
343
+ return list;
344
+ }
345
+ /** version: 8.5.0 */
332
346
 
333
347
  /*
334
348
  * Copyright (c) 2024, Salesforce, Inc.
@@ -377,8 +391,102 @@ const mutationTracker = new MutationTracker();
377
391
  * SPDX-License-Identifier: MIT
378
392
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
379
393
  */
380
- // Eventually include globals that also reflect
381
- const attrsToProps = AriaAttrNameToPropNameMap;
394
+ /**
395
+ * Map of global attribute or ARIA attribute to the corresponding property name.
396
+ * Not all global attributes are included, just those from `HTMLElementTheGoodParts`.
397
+ */
398
+ const attrsToProps = assign(create(null), {
399
+ accesskey: 'accessKey',
400
+ dir: 'dir',
401
+ draggable: 'draggable',
402
+ hidden: 'hidden',
403
+ id: 'id',
404
+ lang: 'lang',
405
+ spellcheck: 'spellcheck',
406
+ tabindex: 'tabIndex',
407
+ title: 'title',
408
+ ...AriaAttrNameToPropNameMap,
409
+ });
410
+ /**
411
+ * Descriptor for IDL attribute reflections that merely reflect the string, e.g. `title`.
412
+ */
413
+ const stringDescriptor = (attrName) => ({
414
+ configurable: true,
415
+ enumerable: true,
416
+ get() {
417
+ return this.getAttribute(attrName);
418
+ },
419
+ set(newValue) {
420
+ const currentValue = this.getAttribute(attrName);
421
+ const normalizedValue = String(newValue);
422
+ if (normalizedValue !== currentValue) {
423
+ this.setAttribute(attrName, normalizedValue);
424
+ }
425
+ },
426
+ });
427
+ /** Descriptor for a boolean that checks for `attr="true"` or `attr="false"`, e.g. `spellcheck` and `draggable`. */
428
+ const explicitBooleanDescriptor = (attrName, defaultValue) => ({
429
+ configurable: true,
430
+ enumerable: true,
431
+ get() {
432
+ const value = this.getAttribute(attrName);
433
+ return value === null ? defaultValue : value === String(defaultValue);
434
+ },
435
+ set(newValue) {
436
+ const currentValue = this.getAttribute(attrName);
437
+ const normalizedValue = String(Boolean(newValue));
438
+ if (normalizedValue !== currentValue) {
439
+ this.setAttribute(attrName, normalizedValue);
440
+ }
441
+ },
442
+ });
443
+ /**
444
+ * Descriptor for a "true" boolean attribute that checks solely for presence, e.g. `hidden`.
445
+ */
446
+ const booleanAttributeDescriptor = (attrName) => ({
447
+ configurable: true,
448
+ enumerable: true,
449
+ get() {
450
+ return this.hasAttribute(attrName);
451
+ },
452
+ set(newValue) {
453
+ const hasAttribute = this.hasAttribute(attrName);
454
+ if (newValue) {
455
+ if (!hasAttribute) {
456
+ this.setAttribute(attrName, '');
457
+ }
458
+ }
459
+ else {
460
+ if (hasAttribute) {
461
+ this.removeAttribute(attrName);
462
+ }
463
+ }
464
+ },
465
+ });
466
+ /**
467
+ * Descriptor for ARIA reflections, e.g. `ariaLabel` and `role`.
468
+ */
469
+ const ariaDescriptor = (attrName) => ({
470
+ configurable: true,
471
+ enumerable: true,
472
+ get() {
473
+ return this.getAttribute(attrName);
474
+ },
475
+ set(newValue) {
476
+ const currentValue = this.getAttribute(attrName);
477
+ if (newValue !== currentValue) {
478
+ // TODO [#3284]: According to the spec, IDL nullable type values
479
+ // (null and undefined) should remove the attribute; however, we
480
+ // only do so in the case of null for historical reasons.
481
+ if (isNull(newValue)) {
482
+ this.removeAttribute(attrName);
483
+ }
484
+ else {
485
+ this.setAttribute(attrName, toString(newValue));
486
+ }
487
+ }
488
+ },
489
+ });
382
490
  function reflectAttrToProp(instance, attrName, attrValue) {
383
491
  const reflectedPropName = attrsToProps[attrName];
384
492
  // If it is a reflected property and it was not overridden by the instance
@@ -389,30 +497,34 @@ function reflectAttrToProp(instance, attrName, attrValue) {
389
497
  }
390
498
  }
391
499
  }
392
- const descriptors = create(null);
393
- for (const [attrName, propName] of entries(attrsToProps)) {
394
- descriptors[propName] = {
500
+ const descriptors = {
501
+ accessKey: stringDescriptor('accesskey'),
502
+ dir: stringDescriptor('dir'),
503
+ draggable: explicitBooleanDescriptor('draggable', true),
504
+ hidden: booleanAttributeDescriptor('hidden'),
505
+ id: stringDescriptor('id'),
506
+ lang: stringDescriptor('lang'),
507
+ spellcheck: explicitBooleanDescriptor('spellcheck', false),
508
+ tabIndex: {
395
509
  get() {
396
- return this.getAttribute(attrName);
510
+ const str = this.getAttribute('tabindex');
511
+ const num = Number(str);
512
+ return isFinite(num) ? Math.trunc(num) : -1;
397
513
  },
398
514
  set(newValue) {
399
- const currentValue = this.getAttribute(attrName);
400
- if (newValue !== currentValue) {
401
- // TODO [#3284]: According to the spec, IDL nullable type values
402
- // (null and undefined) should remove the attribute; however, we
403
- // only do so in the case of null for historical reasons.
404
- // See also https://github.com/w3c/aria/issues/1858
405
- if (isNull(newValue)) {
406
- this.removeAttribute(attrName);
407
- }
408
- else {
409
- this.setAttribute(attrName, toString(newValue));
410
- }
515
+ const currentValue = this.getAttribute('tabindex');
516
+ const num = Number(newValue);
517
+ const normalizedValue = isFinite(num) ? String(Math.trunc(num)) : '0';
518
+ if (normalizedValue !== currentValue) {
519
+ this.setAttribute('tabindex', toString(newValue));
411
520
  }
412
521
  },
413
- configurable: true,
414
- enumerable: true,
415
- };
522
+ },
523
+ title: stringDescriptor('title'),
524
+ };
525
+ // Add descriptors for ARIA attributes
526
+ for (const [attrName, propName] of entries(AriaAttrNameToPropNameMap)) {
527
+ descriptors[propName] = ariaDescriptor(attrName);
416
528
  }
417
529
 
418
530
  /*
@@ -423,6 +535,7 @@ for (const [attrName, propName] of entries(attrsToProps)) {
423
535
  */
424
536
  var _LightningElement_attrs, _LightningElement_classList;
425
537
  const SYMBOL__SET_INTERNALS = Symbol('set-internals');
538
+ const SYMBOL__GENERATE_MARKUP = Symbol('generate-markup');
426
539
  class LightningElement {
427
540
  constructor(propsAvailableAtConstruction) {
428
541
  this.isConnected = false;
@@ -599,21 +712,26 @@ function fallbackTmplNoYield(emit, _props, _attrs, _slotted, Cmp, _instance) {
599
712
  emit('<template shadowrootmode="open"></template>');
600
713
  }
601
714
  }
602
- async function serverSideRenderComponent(tagName, compiledGenerateMarkup, props, mode = 'asyncYield') {
715
+ async function serverSideRenderComponent(tagName, Component, props = {}, mode = 'asyncYield') {
716
+ if (typeof tagName !== 'string') {
717
+ throw new Error(`tagName must be a string, found: ${tagName}`);
718
+ }
719
+ // TODO [#4726]: remove `generateMarkup` export
720
+ const generateMarkup = SYMBOL__GENERATE_MARKUP in Component ? Component[SYMBOL__GENERATE_MARKUP] : Component;
603
721
  let markup = '';
604
722
  const emit = (segment) => {
605
723
  markup += segment;
606
724
  };
607
725
  if (mode === 'asyncYield') {
608
- for await (const segment of compiledGenerateMarkup(tagName, props, null, null)) {
726
+ for await (const segment of generateMarkup(tagName, props, null, null)) {
609
727
  markup += segment;
610
728
  }
611
729
  }
612
730
  else if (mode === 'async') {
613
- await compiledGenerateMarkup(emit, tagName, props, null, null);
731
+ await generateMarkup(emit, tagName, props, null, null);
614
732
  }
615
733
  else if (mode === 'sync') {
616
- compiledGenerateMarkup(emit, tagName, props, null, null);
734
+ generateMarkup(emit, tagName, props, null, null);
617
735
  }
618
736
  else {
619
737
  throw new Error(`Invalid mode: ${mode}`);
@@ -927,6 +1045,36 @@ function validateStyleTextContents(contents) {
927
1045
  }
928
1046
  }
929
1047
 
930
- export { ClassList, LightningElement, SYMBOL__SET_INTERNALS, api, createContextProvider, createElement, fallbackTmpl, fallbackTmplNoYield, freezeTemplate, getComponentDef, hot, htmlEscape, isComponentConstructor, mutationTracker, parseFragment, parseSVGFragment, readonly, registerComponent, registerDecorators, registerTemplate, renderAttrs, renderAttrsNoYield, serverSideRenderComponent as renderComponent, renderer, sanitizeAttribute, serverSideRenderComponent, setFeatureFlag, setFeatureFlagForTest, setHooks, swapComponent, swapStyle, swapTemplate, toIteratorDirective, track, unwrap, validateStyleTextContents, wire };
931
- /** version: 8.4.0 */
1048
+ /*
1049
+ * Copyright (c) 2024, Salesforce, Inc.
1050
+ * All rights reserved.
1051
+ * SPDX-License-Identifier: MIT
1052
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
1053
+ */
1054
+ function hasScopedStaticStylesheets(Component) {
1055
+ const { stylesheets } = Component;
1056
+ if (stylesheets) {
1057
+ return flattenStylesheets(stylesheets).some((stylesheet) => stylesheet.$scoped$);
1058
+ }
1059
+ return false;
1060
+ }
1061
+ function renderStylesheets(stylesheets, scopeToken, Component, hasScopedTemplateStyles) {
1062
+ const hasAnyScopedStyles = hasScopedTemplateStyles || hasScopedStaticStylesheets(Component);
1063
+ let result = '';
1064
+ const truthyStylesheets = stylesheets.filter(Boolean);
1065
+ for (const stylesheet of flattenStylesheets(truthyStylesheets)) {
1066
+ // TODO [#2869]: `<style>`s should not have scope token classes
1067
+ result += `<style${hasAnyScopedStyles ? ` class="${scopeToken}"` : ''} type="text/css">`;
1068
+ const token = stylesheet.$scoped$ ? scopeToken : undefined;
1069
+ const useActualHostSelector = !stylesheet.$scoped$ || Component.renderMode !== 'light';
1070
+ const useNativeDirPseudoclass = true;
1071
+ const styleContents = stylesheet(token, useActualHostSelector, useNativeDirPseudoclass);
1072
+ validateStyleTextContents(styleContents);
1073
+ result += styleContents + '</style>';
1074
+ }
1075
+ return result;
1076
+ }
1077
+
1078
+ export { ClassList, LightningElement, SYMBOL__GENERATE_MARKUP, SYMBOL__SET_INTERNALS, api, createContextProvider, createElement, fallbackTmpl, fallbackTmplNoYield, freezeTemplate, getComponentDef, hasScopedStaticStylesheets, hot, htmlEscape, isComponentConstructor, mutationTracker, parseFragment, parseSVGFragment, readonly, registerComponent, registerDecorators, registerTemplate, renderAttrs, renderAttrsNoYield, serverSideRenderComponent as renderComponent, renderStylesheets, renderer, sanitizeAttribute, serverSideRenderComponent, setFeatureFlag, setFeatureFlagForTest, setHooks, swapComponent, swapStyle, swapTemplate, toIteratorDirective, track, unwrap, validateStyleTextContents, wire };
1079
+ /** version: 8.5.0 */
932
1080
  //# sourceMappingURL=index.js.map