Skip to content
This repository was archived by the owner on Mar 13, 2018. It is now read-only.

Commit 3d48070

Browse files
committed
Merge pull request #368 from azakus/text-normalize
Text normalize
2 parents c87e879 + 7ed4c13 commit 3d48070

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

src/wrappers/Node.js

+44
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,13 @@
228228
return p && p.invalidateShadowRenderer();
229229
}
230230

231+
function cleanupNodes(nodes) {
232+
for (var i = 0, n; i < nodes.length; i++) {
233+
n = nodes[i];
234+
n.parentNode.removeChild(n);
235+
}
236+
}
237+
231238
var OriginalNode = window.Node;
232239

233240
/**
@@ -629,6 +636,43 @@
629636
// This only wraps, it therefore only operates on the composed DOM and not
630637
// the logical DOM.
631638
return originalCompareDocumentPosition.call(this.impl, unwrap(otherNode));
639+
},
640+
641+
normalize: function() {
642+
var nodes = snapshotNodeList(this.childNodes);
643+
var remNodes = [];
644+
var s = '';
645+
var modNode;
646+
647+
for (var i = 0, n; i < nodes.length; i++) {
648+
n = nodes[i];
649+
if (n.nodeType === Node.TEXT_NODE) {
650+
if (!modNode && !n.data.length)
651+
this.removeNode(n);
652+
else if (!modNode)
653+
modNode = n;
654+
else {
655+
s += n.data;
656+
remNodes.push(n);
657+
}
658+
} else {
659+
if (modNode && remNodes.length) {
660+
modNode.data += s;
661+
cleanUpNodes(remNodes);
662+
}
663+
remNodes = [];
664+
s = '';
665+
modNode = null;
666+
if (n.childNodes.length)
667+
n.normalize();
668+
}
669+
}
670+
671+
// handle case where >1 text nodes are the last children
672+
if (modNode && remNodes.length) {
673+
modNode.data += s;
674+
cleanupNodes(remNodes);
675+
}
632676
}
633677
});
634678

test/js/Node.js

+44
Original file line numberDiff line numberDiff line change
@@ -315,4 +315,48 @@ suite('Node', function() {
315315
assert.equal(div.textContent, 'abef');
316316
});
317317

318+
test('normalize', function() {
319+
var div = document.createElement('div');
320+
div.appendChild(document.createTextNode('foo\n'));
321+
var span = document.createElement('span');
322+
span.appendChild(document.createTextNode('buzz'));
323+
span.appendChild(document.createTextNode('quux'));
324+
div.appendChild(span);
325+
div.appendChild(document.createTextNode('bar\n'));
326+
assert.equal(div.textContent, 'foo\nbuzzquuxbar\n');
327+
328+
div.normalize();
329+
330+
assert.equal(div.textContent, 'foo\nbuzzquuxbar\n');
331+
assert.equal(div.childNodes.length, 3);
332+
assert.equal(div.firstChild.textContent, 'foo\n');
333+
assert.equal(div.firstChild.nextSibling, span);
334+
assert.equal(span.childNodes.length, 1);
335+
assert.equal(span.firstChild.textContent, 'buzzquux');
336+
assert.equal(span.nextSibling, div.lastChild);
337+
assert.equal(div.lastChild.textContent, 'bar\n');
338+
339+
});
340+
341+
test('normalize with shadowroot', function() {
342+
var div = document.createElement('div');
343+
div.appendChild(document.createTextNode('foo\n'));
344+
var sr = div.createShadowRoot();
345+
sr.appendChild(document.createTextNode('buzz'));
346+
sr.appendChild(document.createTextNode('quux'));
347+
div.appendChild(document.createTextNode('bar\n'));
348+
assert.equal(div.textContent, 'foo\nbar\n');
349+
assert.equal(sr.textContent, 'buzzquux');
350+
351+
div.normalize();
352+
353+
assert.equal(div.textContent, 'foo\nbar\n');
354+
assert.equal(sr.textContent, 'buzzquux');
355+
assert.equal(div.childNodes.length, 1);
356+
assert.equal(div.firstChild.textContent, 'foo\nbar\n');
357+
assert.equal(sr.childNodes.length, 2);
358+
assert.equal(sr.firstChild.textContent, 'buzz');
359+
assert.equal(sr.firstChild.nextSibling.textContent, 'quux');
360+
});
361+
318362
});

0 commit comments

Comments
 (0)