79 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			79 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
declare var document: Document;
 | 
						|
export function serializeFunction(rootNode) {
 | 
						|
  const uuidv4 = () => {
 | 
						|
    return 'unixxxxxxxxxxx'.replace(/[xy]/g, c => {
 | 
						|
      const r = (Math.random() * 16) | 0;
 | 
						|
      const v = c === 'x' ? r : (r & 0x3) | 0x8;
 | 
						|
      return v.toString(16);
 | 
						|
    });
 | 
						|
  };
 | 
						|
 | 
						|
  const prependCss = (uuidID: string, styleTemplate: string) => {
 | 
						|
    if (!styleTemplate.includes(':host')) {
 | 
						|
      styleTemplate = `:host {}\n\n${styleTemplate}`;
 | 
						|
    }
 | 
						|
    styleTemplate = styleTemplate.replace(/}[ \t\n]+\./g, `}\n\n.${uuidID} .`);
 | 
						|
    styleTemplate = styleTemplate.replace(/}[ \t\n]+\*/g, `}\n\n.${uuidID} *`);
 | 
						|
    styleTemplate = styleTemplate.replace(/\(\[/g, `[`);
 | 
						|
    styleTemplate = styleTemplate.replace(/\]\)/g, `]`);
 | 
						|
    styleTemplate = styleTemplate.replace(/:host/g, `.${uuidID}`);
 | 
						|
    styleTemplate = styleTemplate.replace(/:host/g, `.${uuidID}`);
 | 
						|
    
 | 
						|
    styleTemplate = styleTemplate.replace(/{[ \t\n]+\./g, `{\n\n.${uuidID} .`);
 | 
						|
    styleTemplate = styleTemplate.replace(/}[ \t\n]+img/g, `}\n\n.${uuidID} img`);
 | 
						|
    styleTemplate = styleTemplate.replace(/}[ \t\n]+div/g, `}\n\n.${uuidID} div`);
 | 
						|
    return styleTemplate;
 | 
						|
  };
 | 
						|
 | 
						|
  function serializeNode(node: HTMLElement) {
 | 
						|
    if (!node.tagName.includes('-')) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    if (node.hasAttribute('smartssr')) {
 | 
						|
      console.log(`${node.tagName} is already serialized`);
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    node.setAttribute('smartssr', 'yes');
 | 
						|
    // lets handle the current node
 | 
						|
    const nodeUUID = uuidv4();
 | 
						|
 | 
						|
    try {
 | 
						|
      node.classList.add(nodeUUID);
 | 
						|
 | 
						|
      // lets modify the css
 | 
						|
      const children: HTMLElement[] = node.shadowRoot.children as any;
 | 
						|
      for (const childElement of children) {
 | 
						|
        if (childElement.tagName === 'STYLE') {
 | 
						|
          childElement.textContent = prependCss(nodeUUID, childElement.textContent);
 | 
						|
        }
 | 
						|
        serializeFunction(childElement);
 | 
						|
      }
 | 
						|
 | 
						|
      const templateDom = document.createElement('template');
 | 
						|
      templateDom.innerHTML = node.innerHTML;
 | 
						|
 | 
						|
      const slot = node.shadowRoot.querySelector('slot');
 | 
						|
      node.childNodes.forEach(lightNode => slot.parentNode.insertBefore(lightNode, slot));
 | 
						|
      // remove slot element
 | 
						|
      if (slot) {
 | 
						|
        slot.parentNode.removeChild(slot);
 | 
						|
      }
 | 
						|
 | 
						|
      // move shadowDom into root node
 | 
						|
      node.shadowRoot.childNodes.forEach(shadowNode => node.appendChild(shadowNode));
 | 
						|
 | 
						|
      // add original lightDom as template
 | 
						|
      if (templateDom.innerHTML !== '') {
 | 
						|
        node.appendChild(templateDom);
 | 
						|
      }
 | 
						|
    } catch (err) {
 | 
						|
      console.log('error:', err);
 | 
						|
      console.log(node.tagName);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  [...rootNode.querySelectorAll('*')]
 | 
						|
    .filter(element => /-/.test(element.nodeName))
 | 
						|
    .forEach(serializeNode);
 | 
						|
}
 |