Skip to content

Commit 35a1b94

Browse files
author
Steven Orvell
committed
Add support for strip-whitespace. Should fix #2511.
1 parent f7d86e9 commit 35a1b94

File tree

3 files changed

+167
-13
lines changed

3 files changed

+167
-13
lines changed

src/lib/annotations/annotations.html

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,18 @@
7575
parseAnnotations: function(template) {
7676
var list = [];
7777
var content = template._content || template.content;
78-
this._parseNodeAnnotations(content, list);
78+
this._parseNodeAnnotations(content, list,
79+
template.hasAttribute('strip-whitespace'));
7980
return list;
8081
},
8182

8283
// add annotations gleaned from subtree at `node` to `list`
83-
_parseNodeAnnotations: function(node, list) {
84+
_parseNodeAnnotations: function(node, list, stripWhiteSpace) {
8485
return node.nodeType === Node.TEXT_NODE ?
8586
this._parseTextNodeAnnotation(node, list) :
8687
// TODO(sjmiles): are there other nodes we may encounter
8788
// that are not TEXT_NODE but also not ELEMENT?
88-
this._parseElementAnnotations(node, list);
89+
this._parseElementAnnotations(node, list, stripWhiteSpace);
8990
},
9091

9192
_bindingRegex: /([^{[]*)({{|\[\[)([^}\]]*)(?:]]|}})/g,
@@ -181,15 +182,15 @@
181182
},
182183

183184
// add annotations gleaned from Element `node` to `list`
184-
_parseElementAnnotations: function(element, list) {
185+
_parseElementAnnotations: function(element, list, stripWhiteSpace) {
185186
var annote = {
186187
bindings: [],
187188
events: []
188189
};
189190
if (element.localName === 'content') {
190191
list._hasContent = true;
191192
}
192-
this._parseChildNodesAnnotations(element, annote, list);
193+
this._parseChildNodesAnnotations(element, annote, list, stripWhiteSpace);
193194
// TODO(sjmiles): is this for non-ELEMENT nodes? If so, we should
194195
// change the contract of this method, or filter these out above.
195196
if (element.attributes) {
@@ -210,9 +211,12 @@
210211

211212
// add annotations gleaned from children of `root` to `list`, `root`'s
212213
// `annote` is supplied as it is the annote.parent of added annotations
213-
_parseChildNodesAnnotations: function(root, annote, list, callback) {
214+
_parseChildNodesAnnotations: function(root, annote, list, stripWhiteSpace) {
214215
if (root.firstChild) {
215-
for (var i=0, node=root.firstChild; node; node=node.nextSibling, i++) {
216+
var node = root.firstChild;
217+
var i = 0;
218+
while (node) {
219+
var next = node.nextSibling;
216220
if (node.localName === 'template' &&
217221
!node.hasAttribute('preserve-content')) {
218222
this._parseTemplate(node, i, list, annote);
@@ -222,18 +226,29 @@
222226
// note that root.normalize() should work but does not so we do this
223227
// manually.
224228
if (node.nodeType === Node.TEXT_NODE) {
225-
var n = node.nextSibling;
229+
var n = next;
226230
while (n && (n.nodeType === Node.TEXT_NODE)) {
227231
node.textContent += n.textContent;
232+
next = n.nextSibling;
228233
root.removeChild(n);
229-
n = n.nextSibling;
234+
n = next;
235+
}
236+
// optionally strip whitespace
237+
if (stripWhiteSpace && !node.textContent.trim()) {
238+
root.removeChild(node);
230239
}
231240
}
232-
var childAnnotation = this._parseNodeAnnotations(node, list, callback);
233-
if (childAnnotation) {
234-
childAnnotation.parent = annote;
235-
childAnnotation.index = i;
241+
// if this node didn't get evacipated, parse it.
242+
if (node.parentNode) {
243+
var childAnnotation = this._parseNodeAnnotations(node, list,
244+
stripWhiteSpace);
245+
if (childAnnotation) {
246+
childAnnotation.parent = annote;
247+
childAnnotation.index = i;
248+
}
236249
}
250+
node = next;
251+
i++;
237252
}
238253
}
239254
},

test/runner.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
'unit/async.html',
2626
'unit/behaviors.html',
2727
'unit/template.html',
28+
'unit/template-whitespace.html',
2829
'unit/ready.html',
2930
'unit/ready-shadow.html',
3031
'unit/attached-style.html',

test/unit/template-whitespace.html

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
<!doctype html>
2+
<!--
3+
@license
4+
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
5+
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
6+
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
7+
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
8+
Code distributed by Google as part of the polymer project is also
9+
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
10+
-->
11+
<html>
12+
<head>
13+
<meta charset="utf-8">
14+
<script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
15+
<script src="../../../web-component-tester/browser.js"></script>
16+
<link rel="import" href="../../polymer.html">
17+
</head>
18+
<body>
19+
20+
<dom-module id="has-whitespace">
21+
22+
<template> <div>A</div> <div>B</div> </template>
23+
24+
<script>
25+
HTMLImports.whenReady(function() {
26+
Polymer({
27+
is: 'has-whitespace'
28+
});
29+
});
30+
</script>
31+
32+
</dom-module>
33+
34+
35+
36+
<dom-module id="no-whitespace">
37+
38+
<template strip-whitespace>
39+
<div>A</div>
40+
<div>A</div>
41+
<div>B</div>
42+
</template>
43+
44+
<script>
45+
HTMLImports.whenReady(function() {
46+
Polymer({
47+
is: 'no-whitespace'
48+
});
49+
});
50+
</script>
51+
52+
</dom-module>
53+
54+
55+
56+
<dom-module id="no-whitespace-style">
57+
58+
<template strip-whitespace>
59+
<style>
60+
:host {
61+
display: block;
62+
}
63+
</style>
64+
<div>A</div>
65+
<div>B</div>
66+
</template>
67+
68+
<script>
69+
HTMLImports.whenReady(function() {
70+
Polymer({
71+
is: 'no-whitespace-style'
72+
});
73+
});
74+
</script>
75+
76+
</dom-module>
77+
78+
<dom-module id="no-whitespace-nested">
79+
80+
<template strip-whitespace>
81+
<div>
82+
<div>A</div>
83+
</div>
84+
<div>
85+
<div>B</div>
86+
</div>
87+
</template>
88+
89+
<script>
90+
HTMLImports.whenReady(function() {
91+
Polymer({
92+
is: 'no-whitespace-nested'
93+
});
94+
});
95+
</script>
96+
97+
</dom-module>
98+
99+
100+
101+
<script>
102+
103+
suite('polymer: template whitespace', function() {
104+
105+
test('template stamped with whitespace preserved', function() {
106+
var el = document.createElement('has-whitespace');
107+
assert.equal(Polymer.dom(el.root).childNodes.length, 5);
108+
assert.equal(Polymer.dom(el.root).childNodes[0].nodeType, Node.TEXT_NODE);
109+
});
110+
111+
test('template stamped without whitespace when strip-template is used', function() {
112+
var el = document.createElement('no-whitespace');
113+
document.body.appendChild(el);
114+
assert.equal(Polymer.dom(el.root).childNodes.length, 3);
115+
assert.equal(Polymer.dom(el.root).childNodes.length, Polymer.dom(el.root).children.length);
116+
});
117+
118+
test('template including style stamped without whitespace when strip-template is used', function() {
119+
var el = document.createElement('no-whitespace-style');
120+
document.body.appendChild(el);
121+
assert.equal(Polymer.dom(el.root).childNodes.length, 2);
122+
assert.equal(Polymer.dom(el.root).childNodes.length, Polymer.dom(el.root).children.length);
123+
});
124+
125+
test('template with nested content stamped without whitespace when strip-template is used', function() {
126+
var el = document.createElement('no-whitespace-nested');
127+
document.body.appendChild(el);
128+
assert.equal(Polymer.dom(el.root).childNodes.length, 2);
129+
assert.equal(Polymer.dom(el.root).childNodes.length, Polymer.dom(el.root).children.length);
130+
assert.equal(Polymer.dom(el.root).childNodes[0].childNodes.length, Polymer.dom(el.root).childNodes[0].children.length);
131+
assert.equal(Polymer.dom(el.root).childNodes[1].childNodes.length, Polymer.dom(el.root).childNodes[1].children.length);
132+
});
133+
134+
});
135+
136+
</script>
137+
</body>
138+
</html>

0 commit comments

Comments
 (0)