flutter_flutter/framework/dom-serializer.sky
Elliott Sprehn 0275d42ac7 Add the <t> element and ignore whitespace outside it.
We now only preserve the whitespace inside a <t> element inside
the parser. This removes the known n^2 from reattaching whitespace
which should make parsing and appending nodes faster. I also
removed the dead WhitespaceMode code from the parser, and made
the dom-seralizer.sky auto indent the markup so the test output
would be readable.

R=abarth@chromium.org

Review URL: https://codereview.chromium.org/867963006
2015-01-23 16:50:00 -08:00

95 lines
2.4 KiB
Plaintext

<script>
const kEntityMap = new Map([
['\u00a0', '&nbsp;'],
['&', '&amp;'],
['<', '&lt;'],
['>', '&gt;'],
['"', '&quot;'],
]);
const kTextEscapePattern = /&|<|>|"|\u00a0/g;
const kAttributeEscapePattern = /&|>|"|\u00a0/g;
const kIndent = ' ';
function escapeText(value, pattern) {
return (value || '').replace(pattern, function(match) {
return kEntityMap.get(match);
});
}
function serializeAttributes(element) {
var buffer = '';
var attributes = element.getAttributes();
for (var i = 0; i < attributes.length; ++i) {
var attribute = attributes[i];
buffer += ' ';
buffer += attribute.name;
buffer += '="';
buffer += escapeText(attribute.value, kAttributeEscapePattern);
buffer += '"';
}
return buffer;
}
function getFirstChild(node) {
if (node.localName === 'template')
return node.content.firstChild;
return node.firstChild;
}
function getLastChild(node) {
if (node.localName === 'template')
return node.content.lastChild;
return node.lastChild;
}
function serializeChildren(node, depth) {
var buffer = '';
var firstChild = getFirstChild(node);
var lastChild = getLastChild(node);
if (firstChild instanceof Element && depth)
buffer += '\n' + kIndent.repeat(depth);
for (var child = firstChild; child; child = child.nextSibling) {
buffer += serializeNode(child, depth);
if (child instanceof Element && child.nextSibling instanceof Element)
buffer += '\n' + kIndent.repeat(depth);
}
if (lastChild instanceof Element) {
buffer += '\n';
if (depth)
buffer += kIndent.repeat(depth - 1);
}
return buffer;
}
function serializeElement(element, depth) {
var buffer = '<' + element.tagName + serializeAttributes(element) + '>';
buffer += serializeChildren(element, depth + 1);
buffer += '</' + element.tagName + '>';
return buffer;
}
function serializeText(node) {
var parent = node.parentNode;
if (parent && (parent.tagName == 'script' || parent.tagName == 'style'))
return node.data;
return escapeText(node.data, kTextEscapePattern);
}
function serializeNode(node, depth) {
if (node instanceof Text)
return serializeText(node);
if (node instanceof Element)
return serializeElement(node, depth || 0);
if (node instanceof Document || node instanceof ShadowRoot)
return serializeChildren(node, depth || 0);
throw new Error('Cannot serialize node');
}
module.exports = {
serializeNode: serializeNode,
};
</script>