OLD | NEW |
1 /** Internals to the tree builders. */ | 1 /** Internals to the tree builders. */ |
2 library treebuilder; | 2 library treebuilder; |
3 | 3 |
4 import 'dart:collection'; | 4 import 'dart:collection'; |
5 import 'package:html5lib/dom.dart'; | 5 import 'package:html5lib/dom.dart'; |
6 import 'package:source_maps/span.dart' show FileSpan; | 6 import 'package:source_maps/span.dart' show FileSpan; |
7 import 'constants.dart'; | 7 import 'constants.dart'; |
8 import 'list_proxy.dart'; | 8 import 'list_proxy.dart'; |
9 import 'token.dart'; | 9 import 'token.dart'; |
10 import 'utils.dart'; | 10 import 'utils.dart'; |
11 | 11 |
12 // The scope markers are inserted when entering object elements, | 12 // The scope markers are inserted when entering object elements, |
13 // marquees, table cells, and table captions, and are used to prevent formatting | 13 // marquees, table cells, and table captions, and are used to prevent formatting |
14 // from "leaking" into tables, object elements, and marquees. | 14 // from "leaking" into tables, object elements, and marquees. |
15 final Node Marker = null; | 15 const Node Marker = null; |
16 | 16 |
17 // TODO(jmesserly): this should extend ListBase<Node>, but my simple attempt | 17 // TODO(jmesserly): this should extend ListBase<Node>, but my simple attempt |
18 // didn't work. | 18 // didn't work. |
19 class ActiveFormattingElements extends ListProxy<Node> { | 19 class ActiveFormattingElements extends ListProxy<Node> { |
20 ActiveFormattingElements() : super(); | 20 ActiveFormattingElements() : super(); |
21 | 21 |
22 // Override the "add" method. | 22 // Override the "add" method. |
23 // TODO(jmesserly): I'd rather not override this; can we do this in the | 23 // TODO(jmesserly): I'd rather not override this; can we do this in the |
24 // calling code instead? | 24 // calling code instead? |
25 void add(Node node) { | 25 void add(Node node) { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 break; | 123 break; |
124 case "table": | 124 case "table": |
125 listElements1 = const [const Pair(Namespaces.html, "html"), | 125 listElements1 = const [const Pair(Namespaces.html, "html"), |
126 const Pair(Namespaces.html, "table")]; | 126 const Pair(Namespaces.html, "table")]; |
127 break; | 127 break; |
128 case "select": | 128 case "select": |
129 listElements1 = const [const Pair(Namespaces.html, "optgroup"), | 129 listElements1 = const [const Pair(Namespaces.html, "optgroup"), |
130 const Pair(Namespaces.html, "option")]; | 130 const Pair(Namespaces.html, "option")]; |
131 invert = true; | 131 invert = true; |
132 break; | 132 break; |
133 default: assert(false); break; | 133 default: |
| 134 throw new StateError('We should never reach this point'); |
134 } | 135 } |
135 } | 136 } |
136 | 137 |
137 for (Node node in openElements.reversed) { | 138 for (Node node in openElements.reversed) { |
138 if (node.tagName == target && !exactNode || | 139 if (node.tagName == target && !exactNode || |
139 node == target && exactNode) { | 140 node == target && exactNode) { |
140 return true; | 141 return true; |
141 } else if (invert != | 142 } else if (invert != |
142 (listElements1.contains(node.nameTuple) || | 143 (listElements1.contains(node.nameTuple) || |
143 listElements2.contains(node.nameTuple))) { | 144 listElements2.contains(node.nameTuple))) { |
144 return false; | 145 return false; |
145 } | 146 } |
146 } | 147 } |
147 | 148 |
148 assert(false); // We should never reach this point | 149 throw new StateError('We should never reach this point'); |
149 } | 150 } |
150 | 151 |
151 void reconstructActiveFormattingElements() { | 152 void reconstructActiveFormattingElements() { |
152 // Within this algorithm the order of steps described in the | 153 // Within this algorithm the order of steps described in the |
153 // specification is not quite the same as the order of steps in the | 154 // specification is not quite the same as the order of steps in the |
154 // code. It should still do the same though. | 155 // code. It should still do the same though. |
155 | 156 |
156 // Step 1: stop the algorithm when there's nothing to do. | 157 // Step 1: stop the algorithm when there's nothing to do. |
157 if (activeFormattingElements.length == 0) { | 158 if (activeFormattingElements.length == 0) { |
158 return; | 159 return; |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 Document getDocument() => document; | 392 Document getDocument() => document; |
392 | 393 |
393 /** Return the final fragment. */ | 394 /** Return the final fragment. */ |
394 DocumentFragment getFragment() { | 395 DocumentFragment getFragment() { |
395 //XXX assert innerHTML | 396 //XXX assert innerHTML |
396 var fragment = new DocumentFragment(); | 397 var fragment = new DocumentFragment(); |
397 openElements[0].reparentChildren(fragment); | 398 openElements[0].reparentChildren(fragment); |
398 return fragment; | 399 return fragment; |
399 } | 400 } |
400 } | 401 } |
OLD | NEW |