UNPKG

svgedit

Version:

Powerful SVG-Editor for your browser

218 lines (213 loc) 5.89 kB
/** * @param {any} obj * @returns {any} */ export function findPos(obj) { let curleft = 0; let curtop = 0; if (obj.offsetParent) { do { curleft += obj.offsetLeft; curtop += obj.offsetTop; // eslint-disable-next-line no-cond-assign } while (obj = obj.offsetParent); return { left: curleft, top: curtop }; } return { left: curleft, top: curtop }; } export function isObject(item) { return (item && typeof item === 'object' && !Array.isArray(item)); } export function mergeDeep(target, source) { const output = Object.assign({}, target); if (isObject(target) && isObject(source)) { Object.keys(source).forEach((key) => { if (isObject(source[key])) { if (!(key in target)) Object.assign(output, { [key]: source[key] }); else output[key] = mergeDeep(target[key], source[key]); } else { Object.assign(output, { [key]: source[key] }); } }); } return output; } /** * Get the closest matching element up the DOM tree. * @param {Element} elem Starting element * @param {String} selector Selector to match against (class, ID, data attribute, or tag) * @return {Boolean|Element} Returns null if not match found */ export function getClosest(elem, selector) { const firstChar = selector.charAt(0); const supports = 'classList' in document.documentElement; let attribute; let value; // If selector is a data attribute, split attribute from value if (firstChar === '[') { selector = selector.substr(1, selector.length - 2); attribute = selector.split('='); if (attribute.length > 1) { value = true; attribute[1] = attribute[1].replace(/"/g, '').replace(/'/g, ''); } } // Get closest match for (; elem && elem !== document && elem.nodeType === 1; elem = elem.parentNode) { // If selector is a class if (firstChar === '.') { if (supports) { if (elem.classList.contains(selector.substr(1))) { return elem; } } else { if (new RegExp('(^|\\s)' + selector.substr(1) + '(\\s|$)').test(elem.className)) { return elem; } } } // If selector is an ID if (firstChar === '#') { if (elem.id === selector.substr(1)) { return elem; } } // If selector is a data attribute if (firstChar === '[') { if (elem.hasAttribute(attribute[0])) { if (value) { if (elem.getAttribute(attribute[0]) === attribute[1]) { return elem; } } else { return elem; } } } // If selector is a tag if (elem.tagName.toLowerCase() === selector) { return elem; } } return null; } /** * Get all DOM element up the tree that contain a class, ID, or data attribute * @param {Node} elem The base element * @param {String} selector The class, id, data attribute, or tag to look for * @return {Array} Null if no match */ export function getParents(elem, selector) { const parents = []; let firstChar; if ( selector ) { firstChar = selector.charAt(0); } // Get matches for ( ; elem && elem !== document; elem = elem.parentNode ) { if ( selector ) { // If selector is a class if ( firstChar === '.' ) { if ( elem.classList.contains( selector.substr(1) ) ) { parents.push( elem ); } } // If selector is an ID if ( firstChar === '#' ) { if ( elem.id === selector.substr(1) ) { parents.push( elem ); } } // If selector is a data attribute if ( firstChar === '[' ) { if ( elem.hasAttribute( selector.substr(1, selector.length - 1) ) ) { parents.push( elem ); } } // If selector is a tag if ( elem.tagName.toLowerCase() === selector ) { parents.push( elem ); } } else { parents.push( elem ); } } // Return parents if any exist if ( parents.length === 0 ) { return null; } else { return parents; } } export function getParentsUntil(elem, parent, selector) { const parents = []; let parentType; let selectorType; if ( parent ) { parentType = parent.charAt(0); } if ( selector ) { selectorType = selector.charAt(0); } // Get matches for ( ; elem && elem !== document; elem = elem.parentNode ) { // Check if parent has been reached if ( parent ) { // If parent is a class if ( parentType === '.' ) { if ( elem.classList.contains( parent.substr(1) ) ) { break; } } // If parent is an ID if ( parentType === '#' ) { if ( elem.id === parent.substr(1) ) { break; } } // If parent is a data attribute if ( parentType === '[' ) { if ( elem.hasAttribute( parent.substr(1, parent.length - 1) ) ) { break; } } // If parent is a tag if ( elem.tagName.toLowerCase() === parent ) { break; } } if ( selector ) { // If selector is a class if ( selectorType === '.' ) { if ( elem.classList.contains( selector.substr(1) ) ) { parents.push( elem ); } } // If selector is an ID if ( selectorType === '#' ) { if ( elem.id === selector.substr(1) ) { parents.push( elem ); } } // If selector is a data attribute if ( selectorType === '[' ) { if ( elem.hasAttribute( selector.substr(1, selector.length - 1) ) ) { parents.push( elem ); } } // If selector is a tag if ( elem.tagName.toLowerCase() === selector ) { parents.push( elem ); } } else { parents.push( elem ); } } // Return parents if any exist if ( parents.length === 0 ) { return null; } else { return parents; } }