dom/index.js

  1. /**
  2. * @fileoverview DOM utility methods.
  3. *
  4. * @see https://google.github.io/styleguide/javascriptguide.xml
  5. * @see https://developers.google.com/closure/compiler/docs/js-for-compiler
  6. * @module glize/dom
  7. */
  8. import * as cookies from './cookies.js';
  9. import * as template from './template.js';
  10. export { cookies, template };
  11. /**
  12. * Gets default document charset.
  13. * @return {string} Returns default document charset.
  14. * @method
  15. */
  16. export const getCharset = () => {
  17. const doc = getDocument();
  18. const charset = doc && (doc.charset || doc.characterSet);
  19. return (charset || 'utf-8').toLowerCase();
  20. };
  21. /**
  22. * Loads script.
  23. * @param {string} src The script source to load.
  24. * @param {number=} [timeout=1000] The maximum execution timeout in seconds.
  25. * @return {!Promise} Returns the result as a Promise object.
  26. * @method
  27. */
  28. export const loadScript = (src, timeout = 1E4) => {
  29. return new Promise((resolve, reject) => {
  30. const doc = getDocument();
  31. if (doc) {
  32. const script = makeNode('SCRIPT');
  33. const cleanup = (fn) => {
  34. timer && clearTimeout(timer);
  35. script.onload = script.onerror = null;
  36. deleteNode(script);
  37. fn();
  38. };
  39. script.onload = () => cleanup(resolve);
  40. script.onerror = () => cleanup(reject);
  41. script.async = true;
  42. appendNode(doc.body, script).src = src;
  43. const timer = setTimeout(() => cleanup(reject), timeout);
  44. } else {
  45. reject();
  46. }
  47. });
  48. };
  49. /**
  50. * Gets root context object, <code>Window</code> for browsers
  51. * and <code>global</code> obkect for Node.
  52. * @return {!Window|!Object} Returns root context object.
  53. * @see https://developer.mozilla.org/en-US/docs/Web/API/Window
  54. * @see https://nodejs.org/api/globals.html#globals_global
  55. * @method
  56. */
  57. export const getRootContext = () => {
  58. const context =
  59. ('object' === typeof self && self.self === self && self) ||
  60. ('object' === typeof global && global.global === global && global);
  61. return /** @type {!Window|!Object} */ (context);
  62. };
  63. /**
  64. * Gets HTML document object.
  65. * @return {?HTMLDocument} Returns HTML document object.
  66. * @see https://developer.mozilla.org/en-US/docs/Web/API/Document
  67. * @method
  68. */
  69. export const getDocument = () => {
  70. const ctx = getRootContext();
  71. const doc = ctx.document;
  72. return /** @type {?HTMLDocument} */ (doc);
  73. };
  74. /**
  75. * Removes the object from the document hierarchy.
  76. * @param {?Node} element The element to remove.
  77. * @see https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove
  78. * @see https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild
  79. * @see https://msdn.microsoft.com/en-us/library/ms536708%28v=vs.85%29.aspx
  80. * @method
  81. */
  82. export const deleteNode = (element) => {
  83. element && element.parentNode && element.parentNode.removeChild(element);
  84. };
  85. /**
  86. * Alias of W3C <code>element.appendChild</code>.
  87. * Used to reduce size after code compilation.
  88. * @param {?Node|?Element} parent The parent element.
  89. * @param {?Node|?Element} child The child element.
  90. * @return {!Node} Returns a reference to the <code>child</code> that
  91. * is appended to the parent.
  92. * @method
  93. */
  94. export const appendNode = (parent, child) => parent.appendChild(child);
  95. /**
  96. * Alias of W3C <code>document.createElement</code>.
  97. * Used to reduce size after code compilation.
  98. * @param {string} tagName Tag name.
  99. * @return {?Element} Returns created element.
  100. * @method
  101. */
  102. export const makeNode = (tagName) => getDocument().createElement(tagName);
  103. /**
  104. * Alias of W3C <code>document.getElementById</code>.
  105. * Used to reduce size after code compilation.
  106. * @param {string} id A case-sensitive string representing the unique ID of the
  107. * element being sought.
  108. * @return {?Element} Returns reference to an Element object, or null if an
  109. * element with the specified ID is not in the document.
  110. * @method
  111. */
  112. export const getElement = (id) => getDocument().getElementById(id);
  113. /**
  114. * Alias of W3C <code>element.getElementsByTagName</code>.
  115. * Used to reduce size after code compilation.
  116. * @param {!Element|!Node} element Element to search tags.
  117. * @param {string} tagName Tag name.
  118. * @return {?NodeList} Returns list of found elements in the
  119. * order they appear in the tree.
  120. * @method
  121. */
  122. export const getElementsByTag = (element, tagName) => {
  123. return element && element.getElementsByTagName(tagName);
  124. };
  125. /**
  126. * Alias of W3C <code>element.getElementsByClassName</code>.
  127. * Used to reduce size after code compilation.
  128. * @param {!Element|!Node} element Element to start searching.
  129. * @param {string} className Class name to match.
  130. * @return {?NodeList} Array of found elements.
  131. * @method
  132. */
  133. export const getElementsByClass = (element, className) => {
  134. return element && element.getElementsByClassName(className);
  135. };
  136. /**
  137. * Alias of W3C <code>element.querySelectorAll</code>.
  138. * Used to reduce size after code compilation.
  139. * @param {!Element|!DocumentFragment} element Element to start searching.
  140. * @param {string} selectors One or more CSS selectors separated by commas.
  141. * @return {?NodeList} Returns a list of the elements within the document that
  142. * match the specified group of selectors.
  143. * @see https://www.w3.org/TR/selectors-api/#queryselectorall
  144. * @method
  145. */
  146. export const getElementsBySelectors = (element, selectors) => {
  147. return element && element.querySelectorAll(selectors);
  148. };
  149. /**
  150. * Alias of W3C <code>element.querySelector</code>.
  151. * Used to reduce size after code compilation.
  152. * @param {!Element|!DocumentFragment} element Element to start searching.
  153. * @param {string} selectors One or more CSS selectors separated by commas.
  154. * @return {?Element} Returns the first element that is a descendant of the
  155. * element on which it is invoked that matches the specified group of
  156. * selectors.
  157. * @see https://www.w3.org/TR/selectors-api/#queryselector
  158. * @method
  159. */
  160. export const getElementBySelectors = (element, selectors) => {
  161. return element && element.querySelector(selectors);
  162. };
  163. /**
  164. * Alias of W3C <code>element.addEventListener</code>.
  165. * Used to reduce size after code compilation.
  166. * @param {!Element|!Node|!Window} element Element to which attach event.
  167. * @param {string} type Type of event.
  168. * @param {function(!Event, ...)} listener Event listener.
  169. * @method
  170. */
  171. export const addEvent = (element, type, listener) => {
  172. element && element.addEventListener(type, listener, false);
  173. };