/**
* @fileoverview DOM utility methods.
*
* @see https://google.github.io/styleguide/javascriptguide.xml
* @see https://developers.google.com/closure/compiler/docs/js-for-compiler
* @module glize/dom
*/
import * as cookies from './cookies.js';
import * as template from './template.js';
export { cookies, template };
/**
* Gets default document charset.
* @return {string} Returns default document charset.
* @method
*/
export const getCharset = () => {
const doc = getDocument();
const charset = doc && (doc.charset || doc.characterSet);
return (charset || 'utf-8').toLowerCase();
};
/**
* Loads script.
* @param {string} src The script source to load.
* @param {number=} [timeout=1000] The maximum execution timeout in seconds.
* @return {!Promise} Returns the result as a Promise object.
* @method
*/
export const loadScript = (src, timeout = 1E4) => {
return new Promise((resolve, reject) => {
const doc = getDocument();
if (doc) {
const script = makeNode('SCRIPT');
const cleanup = (fn) => {
timer && clearTimeout(timer);
script.onload = script.onerror = null;
deleteNode(script);
fn();
};
script.onload = () => cleanup(resolve);
script.onerror = () => cleanup(reject);
script.async = true;
appendNode(doc.body, script).src = src;
const timer = setTimeout(() => cleanup(reject), timeout);
} else {
reject();
}
});
};
/**
* Gets root context object, <code>Window</code> for browsers
* and <code>global</code> obkect for Node.
* @return {!Window|!Object} Returns root context object.
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window
* @see https://nodejs.org/api/globals.html#globals_global
* @method
*/
export const getRootContext = () => {
const context =
('object' === typeof self && self.self === self && self) ||
('object' === typeof global && global.global === global && global);
return /** @type {!Window|!Object} */ (context);
};
/**
* Gets HTML document object.
* @return {?HTMLDocument} Returns HTML document object.
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document
* @method
*/
export const getDocument = () => {
const ctx = getRootContext();
const doc = ctx.document;
return /** @type {?HTMLDocument} */ (doc);
};
/**
* Removes the object from the document hierarchy.
* @param {?Node} element The element to remove.
* @see https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove
* @see https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild
* @see https://msdn.microsoft.com/en-us/library/ms536708%28v=vs.85%29.aspx
* @method
*/
export const deleteNode = (element) => {
element && element.parentNode && element.parentNode.removeChild(element);
};
/**
* Alias of W3C <code>element.appendChild</code>.
* Used to reduce size after code compilation.
* @param {?Node|?Element} parent The parent element.
* @param {?Node|?Element} child The child element.
* @return {!Node} Returns a reference to the <code>child</code> that
* is appended to the parent.
* @method
*/
export const appendNode = (parent, child) => parent.appendChild(child);
/**
* Alias of W3C <code>document.createElement</code>.
* Used to reduce size after code compilation.
* @param {string} tagName Tag name.
* @return {?Element} Returns created element.
* @method
*/
export const makeNode = (tagName) => getDocument().createElement(tagName);
/**
* Alias of W3C <code>document.getElementById</code>.
* Used to reduce size after code compilation.
* @param {string} id A case-sensitive string representing the unique ID of the
* element being sought.
* @return {?Element} Returns reference to an Element object, or null if an
* element with the specified ID is not in the document.
* @method
*/
export const getElement = (id) => getDocument().getElementById(id);
/**
* Alias of W3C <code>element.getElementsByTagName</code>.
* Used to reduce size after code compilation.
* @param {!Element|!Node} element Element to search tags.
* @param {string} tagName Tag name.
* @return {?NodeList} Returns list of found elements in the
* order they appear in the tree.
* @method
*/
export const getElementsByTag = (element, tagName) => {
return element && element.getElementsByTagName(tagName);
};
/**
* Alias of W3C <code>element.getElementsByClassName</code>.
* Used to reduce size after code compilation.
* @param {!Element|!Node} element Element to start searching.
* @param {string} className Class name to match.
* @return {?NodeList} Array of found elements.
* @method
*/
export const getElementsByClass = (element, className) => {
return element && element.getElementsByClassName(className);
};
/**
* Alias of W3C <code>element.querySelectorAll</code>.
* Used to reduce size after code compilation.
* @param {!Element|!DocumentFragment} element Element to start searching.
* @param {string} selectors One or more CSS selectors separated by commas.
* @return {?NodeList} Returns a list of the elements within the document that
* match the specified group of selectors.
* @see https://www.w3.org/TR/selectors-api/#queryselectorall
* @method
*/
export const getElementsBySelectors = (element, selectors) => {
return element && element.querySelectorAll(selectors);
};
/**
* Alias of W3C <code>element.querySelector</code>.
* Used to reduce size after code compilation.
* @param {!Element|!DocumentFragment} element Element to start searching.
* @param {string} selectors One or more CSS selectors separated by commas.
* @return {?Element} Returns the first element that is a descendant of the
* element on which it is invoked that matches the specified group of
* selectors.
* @see https://www.w3.org/TR/selectors-api/#queryselector
* @method
*/
export const getElementBySelectors = (element, selectors) => {
return element && element.querySelector(selectors);
};
/**
* Alias of W3C <code>element.addEventListener</code>.
* Used to reduce size after code compilation.
* @param {!Element|!Node|!Window} element Element to which attach event.
* @param {string} type Type of event.
* @param {function(!Event, ...)} listener Event listener.
* @method
*/
export const addEvent = (element, type, listener) => {
element && element.addEventListener(type, listener, false);
};