export class DOMEditor { static nodeListToArray( list:NodeList ) { return Array.prototype.slice.call( list ); } static prefixData( source:string ) { let singleReplaceRegex = /\[\s*-/g; source = source.replace(singleReplaceRegex, "[data-"); let autoDataExtensionRegex = /\[(?!data-|([a-zA-Z0-9]+s*(\=|\~|\||\^|\$|\*|\])))/g; return source.replace( autoDataExtensionRegex, "[data-" ); } static copyAttribute( destination:Element, source:Element, sourceAttribute:string) { sourceAttribute = DOMEditor.prefixData( sourceAttribute ); let value = source.getAttribute (sourceAttribute ); destination.setAttribute( sourceAttribute, value ); } static copyAllAttributesThroughRawHTML( source:Element, destination:Element ) { let attributes:[string,string][] = []; for ( let i = 0; i < destination.attributes.length; i++ ) { let attribute = destination.attributes[ i ]; let attributeName = attribute.nodeName; let attributeValue = attribute.nodeValue; attributes.push( [ attributeName, attributeValue ] ); } for ( let i = 0; i < source.attributes.length; i++ ) { let attribute = source.attributes[ i ]; let attributeName = attribute.nodeName; let attributeValue = attribute.nodeValue; let index = attributes.findIndex( a => a[ 0 ] === attributeName ); if ( index === -1 ) { attributes.push( [ attributeName, attributeValue ] ); } else { attributes[ index ][ 1 ] = attributeValue; } } let innerHTML = destination.innerHTML; let attributesString = ""; for ( let i = 0; i < attributes.length; i++ ) { if ( i !== 0 ){ attributesString += " "; } let attribute = attributes[ i ]; attributesString += `${attribute[ 0 ]}="${attribute[ 1 ]}"`; } let tag = destination.nodeName.toLowerCase(); let html = `<${tag} ${attributesString}>${innerHTML}`; console.log( "Copied html:", html ); destination.outerHTML = html; return destination; } static copyAllAttributes( source:Element, destination:Element ) { for ( let i = 0; i < source.attributes.length; i++ ) { let attribute = source.attributes[ i ]; let attributeName = attribute.nodeName; let attributeValue = attribute.nodeValue; destination.setAttribute( attributeName, attributeValue ); } } static cloneChildren( element:Element ):Node[] { let clones:Node[] = []; for ( let i = 0; i < element.childNodes.length; i++ ) { clones.push( element.childNodes[ i ].cloneNode( true ) ); } return clones; } static _cssCreationRegex:RegExp; static get cssCreationRegex() { if ( DOMEditor._cssCreationRegex) { return DOMEditor._cssCreationRegex; } let cssCreationRules = [ //"Attribute", /\[\s*(?:\w|-)+\s*(?:(?:\~|\||\^|\$|\*)?=)\s*(?:(?:"(?:\\"|.)*?")|(?:'(?:\\'|.)*?')|(?:(?:\w|-)+))\s*\]/, //"ID", /#(?:\w|-)+/, //"Class", /\.(?:\w|-)+/, //"Empty Attribute", /\[\s*(?:\w|-)+\s*]/, //"Element", /(?:\w|-)+/ ]; let regexString = ""; for (let i = 0; i < cssCreationRules.length; i++) { if (i !== 0) { regexString += "|"; } regexString += "(" + cssCreationRules[i].source + ")"; } DOMEditor._cssCreationRegex = new RegExp(regexString, "g"); return DOMEditor._cssCreationRegex; } static stringToDocument( html:string ):Document { let parser = new DOMParser(); let doc = parser.parseFromString( html, "text/html" ); return doc; } static remove( node:Node ) { if ( ! node ) { return; } if ( ! node.parentNode ) { return; } node.parentNode.removeChild( node ); } }