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.message);
|
|
console.log(node.tagName);
|
|
}
|
|
}
|
|
|
|
[...rootNode.querySelectorAll('*')]
|
|
.filter(element => /-/.test(element.nodeName))
|
|
.forEach(serializeNode);
|
|
}
|