html_impl.mjs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /**
  2. * @license
  3. * SPDX-License-Identifier: Apache-2.0
  4. */
  5. import '../environment/dev';
  6. /* g3_import_pure from './pure' */
  7. import { ensureTokenIsValid, secretToken } from './secrets';
  8. import { getTrustedTypes, getTrustedTypesPolicy } from './trusted_types';
  9. /**
  10. * Runtime implementation of `TrustedHTML` in browsers that don't support it.
  11. */
  12. class HtmlImpl {
  13. privateDoNotAccessOrElseWrappedHtml;
  14. constructor(html, token) {
  15. if (process.env.NODE_ENV !== 'production') {
  16. ensureTokenIsValid(token);
  17. }
  18. this.privateDoNotAccessOrElseWrappedHtml = html;
  19. }
  20. toString() {
  21. return this.privateDoNotAccessOrElseWrappedHtml.toString();
  22. }
  23. }
  24. function createHtmlInternal(html, trusted) {
  25. return (trusted ?? new HtmlImpl(html, secretToken));
  26. }
  27. const GlobalTrustedHTML = (typeof window !== undefined) ? window.TrustedHTML : undefined;
  28. /**
  29. * Also exports the constructor so that instanceof checks work.
  30. */
  31. export const SafeHtml = (GlobalTrustedHTML ?? HtmlImpl);
  32. /**
  33. * Builds a new `SafeHtml` from the given string, without enforcing safety
  34. * guarantees. It may cause side effects by creating a Trusted Types policy.
  35. * This shouldn't be exposed to application developers, and must only be used as
  36. * a step towards safe builders or safe constants.
  37. */
  38. export function createHtml(html) {
  39. /** @noinline */
  40. const noinlineHtml = html;
  41. return createHtmlInternal(noinlineHtml, getTrustedTypesPolicy()?.createHTML(noinlineHtml));
  42. }
  43. /**
  44. * An empty `SafeHtml` constant.
  45. * Unlike the function above, using this will not create a policy.
  46. */
  47. export const EMPTY_HTML =
  48. /* #__PURE__ */ (() => createHtmlInternal('', getTrustedTypes()?.emptyHTML))();
  49. /**
  50. * Checks if the given value is a `SafeHtml` instance.
  51. */
  52. export function isHtml(value) {
  53. return value instanceof SafeHtml;
  54. }
  55. /**
  56. * Returns the value of the passed `SafeHtml` object while ensuring it
  57. * has the correct type.
  58. *
  59. * Returns a native `TrustedHTML` or a string if Trusted Types are disabled.
  60. */
  61. export function unwrapHtml(value) {
  62. if (getTrustedTypes()?.isHTML(value)) {
  63. return value;
  64. }
  65. else if (value instanceof HtmlImpl) {
  66. return value.privateDoNotAccessOrElseWrappedHtml;
  67. }
  68. else {
  69. let message = '';
  70. if (process.env.NODE_ENV !== 'production') {
  71. message = 'Unexpected type when unwrapping SafeHtml';
  72. }
  73. throw new Error(message);
  74. }
  75. }