Skip to content

Commit

Permalink
Document roots fix
Browse files Browse the repository at this point in the history
  • Loading branch information
Lcfvs committed Dec 10, 2020
1 parent 4c458bb commit ee0dbee
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 34 deletions.
98 changes: 66 additions & 32 deletions lib/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,14 @@ function filler (template, node) {
}

function fill (template) {
const { [symbols.node]: node, [symbols.window]: window } = template
const { document, Node } = window
const {
[symbols.node]: node,
[symbols.window]: window
} = template
const {
document,
Node
} = window
const value = node.nodeType === Node.TEXT_NODE
? resolve(node.textContent, template)
: node.nodeValue.replace(identifier, content => resolve(content, template))
Expand All @@ -53,18 +59,24 @@ function filter (node) {
}

function find (templates, template) {
const { [symbols.node]: node, [symbols.window]: window } = template
const {
[symbols.node]: node,
[symbols.window]: window
} = template
const { nodeType } = node
const { Node } = window
const { attributes = [], childNodes = [] } = node
const {
attributes = [],
childNodes = []
} = node

return [
...templates,
...nodeType === Node.TEXT_NODE
? [node].filter(filter)
: [
...[...attributes].filter(filter),
...[...childNodes].map(map, template).reduce(find, [])
...attributes.filter(filter),
...childNodes.map(map, template).reduce(find, [])
]
]
}
Expand All @@ -81,9 +93,15 @@ function map (node) {
}

function replace (template) {
const { [symbols.node]: node, [symbols.window]: window } = template
const {
[symbols.node]: node,
[symbols.window]: window
} = template
const { document } = window
const { parentNode, textContent } = node
const {
parentNode,
textContent
} = node
const container = document.createDocumentFragment()
const matches = textContent.match(identifier)

Expand Down Expand Up @@ -114,10 +132,6 @@ function resolve (content, template) {
}, template)
}

function content (fragment) {
return fragment.childNodes[0].content
}

function render (template) {
const { [symbols.node]: node } = template
const clone = from(template, node.cloneNode(true))
Expand All @@ -130,17 +144,14 @@ function wrap (source) {
return `<template>${source}</template>`
}

function parse (document, source) {
return document
.createRange()
.createContextualFragment(source)
}

function tree (fragment) {
const [...templates] = fragment.querySelectorAll('template')

templates.forEach(template => {
const { content, parentNode } = template
const {
content,
parentNode
} = template

tree(content)
parentNode.replaceChild(content, template)
Expand All @@ -149,44 +160,68 @@ function tree (fragment) {
return fragment
}

function rewrite (source, match) {//console.log(source)
function rewrite (source, match) {
return source.replace(match, wrap(match))
}

function dom ({ document, NodeFilter }, source) {
function parse (parser, doctype, contents) {
const document = parser.parseFromString(`${doctype}${contents}`, 'text/html')

if (doctype.length) {
document.write(contents)

return document.documentElement
} else {
return document.createRange()
.createContextualFragment(contents)
}
}

function dom ({
DOMParser,
NodeFilter
}, source) {
let [, doctype, contents] = source.match(parts)
const fragment = parse(document, contents)
const walker = document.createTreeWalker(fragment, NodeFilter.SHOW_TEXT)
const parser = new DOMParser()
const fragment = parse(parser, doctype, contents)
const { ownerDocument } = fragment
const walker = ownerDocument.createTreeWalker(fragment, NodeFilter.SHOW_TEXT)

while (true) {
const node = walker.nextNode()

if (!node) {
if (!node || node.parentNode.nodeName === 'TITLE') {
break
}

const { nodeValue } = node
const matches = nodeValue.match(identifier) || []
const matches = node.nodeValue.match(identifier) || []

contents = matches.reduce(rewrite, contents)
}

if (!doctype.length) {
contents = wrap(contents)
}

return {
doctype,
template: tree(parse(document, wrap(contents)))
node: tree(parse(parser, doctype, contents))
}
}

export function template (window, source = '', { ...data } = {}) {
const { doctype, template } = dom(window, source)
const {
doctype,
node
} = dom(window, source)

return from({
...data,
...proto,
[symbols.doctype]: doctype,
[symbols.source]: source,
[symbols.window]: window
}, template)
}, node)
}

export function serialize (template) {
Expand All @@ -195,7 +230,6 @@ export function serialize (template) {
[symbols.window]: { XMLSerializer }
} = template

const source = new XMLSerializer().serializeToString(render(template))

return `${doctype}${source}`
return new XMLSerializer()
.serializeToString(`${doctype}${render(template)}`)
}
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lcf.vs/dom-engine",
"version": "1.1.0",
"version": "1.1.1",
"description": "A composable DOM based template engine",
"type": "module",
"main": "lib/engine.js",
Expand Down

0 comments on commit ee0dbee

Please sign in to comment.