script_impl.mjs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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 `TrustedScript` in browswers that don't support it.
  11. * script element.
  12. */
  13. class ScriptImpl {
  14. privateDoNotAccessOrElseWrappedScript;
  15. constructor(script, token) {
  16. if (process.env.NODE_ENV !== 'production') {
  17. ensureTokenIsValid(token);
  18. }
  19. this.privateDoNotAccessOrElseWrappedScript = script;
  20. }
  21. toString() {
  22. return this.privateDoNotAccessOrElseWrappedScript.toString();
  23. }
  24. }
  25. function createScriptInternal(script, trusted) {
  26. return (trusted ?? new ScriptImpl(script, secretToken));
  27. }
  28. const GlobalTrustedScript = (typeof window !== undefined) ? window.TrustedScript : undefined;
  29. /**
  30. * Also exports the constructor so that instanceof checks work.
  31. */
  32. export const SafeScript = (GlobalTrustedScript ?? ScriptImpl);
  33. /**
  34. * Builds a new `SafeScript` from the given string, without enforcing
  35. * safety guarantees. It may cause side effects by creating a Trusted Types
  36. * policy. This shouldn't be exposed to application developers, and must only be
  37. * used as a step towards safe builders or safe constants.
  38. */
  39. export function createScript(script) {
  40. /** @noinline */
  41. const noinlineScript = script;
  42. return createScriptInternal(noinlineScript, getTrustedTypesPolicy()?.createScript(noinlineScript));
  43. }
  44. /**
  45. * An empty `SafeScript` constant.
  46. * Unlike the functions above, using this will not create a policy.
  47. */
  48. export const EMPTY_SCRIPT =
  49. /* #__PURE__ */ (() => createScriptInternal('', getTrustedTypes()?.emptyScript))();
  50. /**
  51. * Checks if the given value is a `SafeScript` instance.
  52. */
  53. export function isScript(value) {
  54. return value instanceof SafeScript;
  55. }
  56. /**
  57. * Returns the value of the passed `SafeScript` object while ensuring it
  58. * has the correct type.
  59. *
  60. * Returns a native `TrustedScript` or a string if Trusted Types are disabled.
  61. */
  62. export function unwrapScript(value) {
  63. if (getTrustedTypes()?.isScript(value)) {
  64. return value;
  65. }
  66. else if (value instanceof ScriptImpl) {
  67. return value.privateDoNotAccessOrElseWrappedScript;
  68. }
  69. else {
  70. let message = '';
  71. if (process.env.NODE_ENV !== 'production') {
  72. message = 'Unexpected type when unwrapping SafeScript';
  73. }
  74. throw new Error(message);
  75. }
  76. }