static.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /**
  2. * @license
  3. * Copyright 2020 Google LLC
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. // Any new exports need to be added to the export statement in
  7. // `packages/lit/src/index.all.ts`.
  8. import { html as coreHtml, svg as coreSvg } from './lit-html.js';
  9. /**
  10. * Wraps a string so that it behaves like part of the static template
  11. * strings instead of a dynamic value.
  12. *
  13. * Users must take care to ensure that adding the static string to the template
  14. * results in well-formed HTML, or else templates may break unexpectedly.
  15. *
  16. * Note that this function is unsafe to use on untrusted content, as it will be
  17. * directly parsed into HTML. Do not pass user input to this function
  18. * without sanitizing it.
  19. *
  20. * Static values can be changed, but they will cause a complete re-render
  21. * since they effectively create a new template.
  22. */
  23. export const unsafeStatic = (value) => ({
  24. ['_$litStatic$']: value,
  25. });
  26. const textFromStatic = (value) => {
  27. if (value['_$litStatic$'] !== undefined) {
  28. return value['_$litStatic$'];
  29. }
  30. else {
  31. throw new Error(`Value passed to 'literal' function must be a 'literal' result: ${value}. Use 'unsafeStatic' to pass non-literal values, but
  32. take care to ensure page security.`);
  33. }
  34. };
  35. /**
  36. * Tags a string literal so that it behaves like part of the static template
  37. * strings instead of a dynamic value.
  38. *
  39. * The only values that may be used in template expressions are other tagged
  40. * `literal` results or `unsafeStatic` values (note that untrusted content
  41. * should never be passed to `unsafeStatic`).
  42. *
  43. * Users must take care to ensure that adding the static string to the template
  44. * results in well-formed HTML, or else templates may break unexpectedly.
  45. *
  46. * Static values can be changed, but they will cause a complete re-render since
  47. * they effectively create a new template.
  48. */
  49. export const literal = (strings, ...values) => ({
  50. ['_$litStatic$']: values.reduce((acc, v, idx) => acc + textFromStatic(v) + strings[idx + 1], strings[0]),
  51. });
  52. const stringsCache = new Map();
  53. /**
  54. * Wraps a lit-html template tag (`html` or `svg`) to add static value support.
  55. */
  56. export const withStatic = (coreTag) => (strings, ...values) => {
  57. var _a;
  58. const l = values.length;
  59. let staticValue;
  60. let dynamicValue;
  61. const staticStrings = [];
  62. const dynamicValues = [];
  63. let i = 0;
  64. let hasStatics = false;
  65. let s;
  66. while (i < l) {
  67. s = strings[i];
  68. // Collect any unsafeStatic values, and their following template strings
  69. // so that we treat a run of template strings and unsafe static values as
  70. // a single template string.
  71. while (i < l &&
  72. ((dynamicValue = values[i]),
  73. (staticValue = (_a = dynamicValue) === null || _a === void 0 ? void 0 : _a['_$litStatic$'])) !==
  74. undefined) {
  75. s += staticValue + strings[++i];
  76. hasStatics = true;
  77. }
  78. dynamicValues.push(dynamicValue);
  79. staticStrings.push(s);
  80. i++;
  81. }
  82. // If the last value isn't static (which would have consumed the last
  83. // string), then we need to add the last string.
  84. if (i === l) {
  85. staticStrings.push(strings[l]);
  86. }
  87. if (hasStatics) {
  88. const key = staticStrings.join('$$lit$$');
  89. strings = stringsCache.get(key);
  90. if (strings === undefined) {
  91. // Beware: in general this pattern is unsafe, and doing so may bypass
  92. // lit's security checks and allow an attacker to execute arbitrary
  93. // code and inject arbitrary content.
  94. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  95. staticStrings.raw = staticStrings;
  96. stringsCache.set(key, (strings = staticStrings));
  97. }
  98. values = dynamicValues;
  99. }
  100. return coreTag(strings, ...values);
  101. };
  102. /**
  103. * Interprets a template literal as an HTML template that can efficiently
  104. * render to and update a container.
  105. *
  106. * Includes static value support from `lit-html/static.js`.
  107. */
  108. export const html = withStatic(coreHtml);
  109. /**
  110. * Interprets a template literal as an SVG template that can efficiently
  111. * render to and update a container.
  112. *
  113. * Includes static value support from `lit-html/static.js`.
  114. */
  115. export const svg = withStatic(coreSvg);
  116. //# sourceMappingURL=static.js.map