/** * @see https://github.com/ractivejs/ractive/blob/dev/src/utils/html.js */ export function escapeHtml(str) { return str .replace(/&/g, '&') .replace(//g, '>'); } /** * Prepare HTML content that contains mustache characters for use with Ractive * @param {string} str * @return {string} */ export function unescapeHtml(str) { return str .replace(/</g, '<') .replace(/>/g, '>') .replace(/&/g, '&'); } /** * Get element data attributes * @param {DOMElement} node * @return {Array} data */ export function getNodeData(node) { // All attributes const attributes = node.attributes; // Regex Pattern const pattern = /^data\-(.+)$/; // Output const data = {}; for (let i in attributes) { if (!attributes[i]) { continue; } // Attributes name (ex: data-module) let name = attributes[i].name; // This happens. if (!name) { continue; } let match = name.match(pattern); if (!match) { continue; } // If this throws an error, you have some // serious problems in your HTML. data[match[1]] = getData(node.getAttribute(name)); } return data; } const rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/; /** * Parse value to data type. * * @link https://github.com/jquery/jquery/blob/3.1.1/src/data.js * @param {string} data - A value to convert. * @return {mixed} Returns the value in its natural data type. */ export function getData(data) { if (data === 'true') { return true; } if (data === 'false') { return false; } if (data === 'null') { return null; } // Only convert to a number if it doesn't change the string if (data === +data+'') { return +data; } if (rbrace.test( data )) { return JSON.parse( data ); } return data; } /** * Returns an array containing all the parent nodes of the given node * @param {object} node * @return {array} parent nodes */ export function getParents(elem) { // Set up a parent array let parents = []; // Push each parent element to the array for ( ; elem && elem !== document; elem = elem.parentNode ) { parents.push(elem); } // Return our parent array return parents; } // https://gomakethings.com/how-to-get-the-closest-parent-element-with-a-matching-selector-using-vanilla-javascript/ export function queryClosestParent(elem, selector) { // Element.matches() polyfill if (!Element.prototype.matches) { Element.prototype.matches = Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector || function(s) { var matches = (this.document || this.ownerDocument).querySelectorAll(s), i = matches.length; while (--i >= 0 && matches.item(i) !== this) {} return i > -1; }; } // Get the closest matching element for ( ; elem && elem !== document; elem = elem.parentNode ) { if ( elem.matches( selector ) ) return elem; } return null; };