element.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. "use strict";
  2. /**
  3. * @license
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. var __read = (this && this.__read) || function (o, n) {
  7. var m = typeof Symbol === "function" && o[Symbol.iterator];
  8. if (!m) return o;
  9. var i = m.call(o), r, ar = [], e;
  10. try {
  11. while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
  12. }
  13. catch (error) { e = { error: error }; }
  14. finally {
  15. try {
  16. if (r && !r.done && (m = i["return"])) m.call(i);
  17. }
  18. finally { if (e) throw e.error; }
  19. }
  20. return ar;
  21. };
  22. var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
  23. if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
  24. if (ar || !(i in from)) {
  25. if (!ar) ar = Array.prototype.slice.call(from, 0, i);
  26. ar[i] = from[i];
  27. }
  28. }
  29. return to.concat(ar || Array.prototype.slice.call(from));
  30. };
  31. Object.defineProperty(exports, "__esModule", { value: true });
  32. exports.setPrefixedAttribute = exports.buildPrefixedAttributeSetter = exports.insertAdjacentHtml = exports.setCssText = exports.setOuterHtml = exports.setInnerHtml = void 0;
  33. /**
  34. * @fileoverview This contains safe wrappers for properties that aren't specific
  35. * to one kind of HTMLElement (like innerHTML), plus other setters and functions
  36. * that are not tied to elements (like location.href or Worker constructor).
  37. */
  38. var attribute_impl_1 = require("../../internals/attribute_impl");
  39. var html_impl_1 = require("../../internals/html_impl");
  40. var style_impl_1 = require("../../internals/style_impl");
  41. /**
  42. * Safely set {@link Element.innerHTML} on a given ShadowRoot or Element which
  43. * may not be a `<script>` element or a `<style>` element.
  44. */
  45. function setInnerHtml(elOrRoot, v) {
  46. if (isElement(elOrRoot)) {
  47. throwIfScriptOrStyle(elOrRoot);
  48. }
  49. elOrRoot.innerHTML = (0, html_impl_1.unwrapHtml)(v);
  50. }
  51. exports.setInnerHtml = setInnerHtml;
  52. /**
  53. * Safely set {@link Element.outerHTML} for the given Element.
  54. */
  55. function setOuterHtml(e, v) {
  56. var parent = e.parentElement;
  57. if (parent !== null) {
  58. throwIfScriptOrStyle(parent);
  59. }
  60. e.outerHTML = (0, html_impl_1.unwrapHtml)(v);
  61. }
  62. exports.setOuterHtml = setOuterHtml;
  63. /**
  64. * Set `ElementCSSInlineStyle.cssText` for the given `ElementCSSInlineStyle`.
  65. */
  66. function setCssText(e, v) {
  67. e.style.cssText = (0, style_impl_1.unwrapStyle)(v);
  68. }
  69. exports.setCssText = setCssText;
  70. /**
  71. * Safely call {@link Element.insertAdjacentHTML} for the given Element.
  72. */
  73. function insertAdjacentHtml(element, position, v) {
  74. var tagContext = (position === 'beforebegin' || position === 'afterend') ?
  75. element.parentElement :
  76. element;
  77. if (tagContext !== null) {
  78. throwIfScriptOrStyle(tagContext);
  79. }
  80. element.insertAdjacentHTML(position, (0, html_impl_1.unwrapHtml)(v));
  81. }
  82. exports.insertAdjacentHtml = insertAdjacentHtml;
  83. /**
  84. * Given a set of known-to-be-safe prefixes (e.g., "data-", "aria-", "js"),
  85. * return a setter function that allows you to set attributes on an element,
  86. * as long as the names of the attributes to be set has one of the prefixes.
  87. *
  88. * The returned setter ensures that setting any dangerous attribute, e.g.,
  89. * "src", "href" will cause an exception. This is intended to be used as the
  90. * safe alterantive of `Element#setAttribute`, when applications need to set
  91. * attributes that do not have security implications and do not have a
  92. * corresponding DOM property.
  93. */
  94. function buildPrefixedAttributeSetter(prefix) {
  95. var otherPrefixes = [];
  96. for (var _i = 1; _i < arguments.length; _i++) {
  97. otherPrefixes[_i - 1] = arguments[_i];
  98. }
  99. var prefixes = __spreadArray([prefix], __read(otherPrefixes), false);
  100. return function (e, attr, value) {
  101. setPrefixedAttribute(prefixes, e, attr, value);
  102. };
  103. }
  104. exports.buildPrefixedAttributeSetter = buildPrefixedAttributeSetter;
  105. /**
  106. * The safe alternative to Element#setAttribute. The function takes a list of
  107. * `SafeAttributePrefix`, making developer intention explicit. The attribute
  108. * to be set must has one of the safe prefixes, otherwise the function throws
  109. * an Error.
  110. */
  111. function setPrefixedAttribute(attrPrefixes, e, attr, value) {
  112. if (attrPrefixes.length === 0) {
  113. throw new Error('No prefixes are provided');
  114. }
  115. var prefixes = attrPrefixes.map(function (s) { return (0, attribute_impl_1.unwrapAttributePrefix)(s); });
  116. var attrLower = attr.toLowerCase();
  117. if (prefixes.every(function (p) { return attrLower.indexOf(p) !== 0; })) {
  118. throw new Error("Attribute \"".concat(attr, "\" does not match any of the allowed prefixes."));
  119. }
  120. e.setAttribute(attr, value);
  121. }
  122. exports.setPrefixedAttribute = setPrefixedAttribute;
  123. function throwIfScriptOrStyle(element) {
  124. if (element.tagName.toLowerCase() === 'script') {
  125. throw new Error('Use setTextContent with a SafeScript.');
  126. }
  127. else if (element.tagName.toLowerCase() === 'style') {
  128. throw new Error('Use setTextContent with a SafeStyleSheet.');
  129. }
  130. }
  131. function isElement(elOrRoot) {
  132. return elOrRoot.tagName !== undefined;
  133. }