OLD | NEW |
1 /** | 1 /** |
2 * This library has a parser for HTML5 documents, that lets you parse HTML | 2 * This library has a parser for HTML5 documents, that lets you parse HTML |
3 * easily from a script or server side application: | 3 * easily from a script or server side application: |
4 * | 4 * |
5 * import 'package:html5lib/parser.dart' show parse; | 5 * import 'package:html5lib/parser.dart' show parse; |
6 * import 'package:html5lib/dom.dart'; | 6 * import 'package:html5lib/dom.dart'; |
7 * main() { | 7 * main() { |
8 * var document = parse( | 8 * var document = parse( |
9 * '<body>Hello world! <a href="www.html5rocks.com">HTML5 rocks!'); | 9 * '<body>Hello world! <a href="www.html5rocks.com">HTML5 rocks!'); |
10 * print(document.outerHTML); | 10 * print(document.outerHTML); |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 } | 265 } |
266 | 266 |
267 bool isMathMLTextIntegrationPoint(Node element) { | 267 bool isMathMLTextIntegrationPoint(Node element) { |
268 return mathmlTextIntegrationPointElements.contains( | 268 return mathmlTextIntegrationPointElements.contains( |
269 new Pair(element.namespace, element.tagName)); | 269 new Pair(element.namespace, element.tagName)); |
270 } | 270 } |
271 | 271 |
272 bool inForeignContent(Token token, int type) { | 272 bool inForeignContent(Token token, int type) { |
273 if (tree.openElements.length == 0) return false; | 273 if (tree.openElements.length == 0) return false; |
274 | 274 |
275 var node = tree.openElements.last(); | 275 var node = tree.openElements.last; |
276 if (node.namespace == tree.defaultNamespace) return false; | 276 if (node.namespace == tree.defaultNamespace) return false; |
277 | 277 |
278 if (isMathMLTextIntegrationPoint(node)) { | 278 if (isMathMLTextIntegrationPoint(node)) { |
279 if (type == TokenKind.startTag && | 279 if (type == TokenKind.startTag && |
280 (token as StartTagToken).name != "mglyph" && | 280 (token as StartTagToken).name != "mglyph" && |
281 (token as StartTagToken).name != "malignmark") { | 281 (token as StartTagToken).name != "malignmark") { |
282 return false; | 282 return false; |
283 } | 283 } |
284 if (type == TokenKind.characters || type == TokenKind.spaceCharacters) { | 284 if (type == TokenKind.characters || type == TokenKind.spaceCharacters) { |
285 return false; | 285 return false; |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 "tablevalues":"tableValues", | 458 "tablevalues":"tableValues", |
459 "targetx":"targetX", | 459 "targetx":"targetX", |
460 "targety":"targetY", | 460 "targety":"targetY", |
461 "textlength":"textLength", | 461 "textlength":"textLength", |
462 "viewbox":"viewBox", | 462 "viewbox":"viewBox", |
463 "viewtarget":"viewTarget", | 463 "viewtarget":"viewTarget", |
464 "xchannelselector":"xChannelSelector", | 464 "xchannelselector":"xChannelSelector", |
465 "ychannelselector":"yChannelSelector", | 465 "ychannelselector":"yChannelSelector", |
466 "zoomandpan":"zoomAndPan" | 466 "zoomandpan":"zoomAndPan" |
467 }; | 467 }; |
468 for (var originalName in token.data.getKeys()) { | 468 for (var originalName in token.data.keys) { |
469 var svgName = replacements[originalName]; | 469 var svgName = replacements[originalName]; |
470 if (svgName != null) { | 470 if (svgName != null) { |
471 token.data[svgName] = token.data.remove(originalName); | 471 token.data[svgName] = token.data.remove(originalName); |
472 } | 472 } |
473 } | 473 } |
474 } | 474 } |
475 | 475 |
476 void adjustForeignAttributes(Token token) { | 476 void adjustForeignAttributes(Token token) { |
477 // TODO(jmesserly): I don't like mixing non-string objects with strings in | 477 // TODO(jmesserly): I don't like mixing non-string objects with strings in |
478 // the Node.attributes Map. Is there another solution? | 478 // the Node.attributes Map. Is there another solution? |
479 final replacements = const { | 479 final replacements = const { |
480 "xlink:actuate": const AttributeName("xlink", "actuate", | 480 "xlink:actuate": const AttributeName("xlink", "actuate", |
481 Namespaces.xlink), | 481 Namespaces.xlink), |
482 "xlink:arcrole": const AttributeName("xlink", "arcrole", | 482 "xlink:arcrole": const AttributeName("xlink", "arcrole", |
483 Namespaces.xlink), | 483 Namespaces.xlink), |
484 "xlink:href": const AttributeName("xlink", "href", Namespaces.xlink), | 484 "xlink:href": const AttributeName("xlink", "href", Namespaces.xlink), |
485 "xlink:role": const AttributeName("xlink", "role", Namespaces.xlink), | 485 "xlink:role": const AttributeName("xlink", "role", Namespaces.xlink), |
486 "xlink:show": const AttributeName("xlink", "show", Namespaces.xlink), | 486 "xlink:show": const AttributeName("xlink", "show", Namespaces.xlink), |
487 "xlink:title": const AttributeName("xlink", "title", Namespaces.xlink), | 487 "xlink:title": const AttributeName("xlink", "title", Namespaces.xlink), |
488 "xlink:type": const AttributeName("xlink", "type", Namespaces.xlink), | 488 "xlink:type": const AttributeName("xlink", "type", Namespaces.xlink), |
489 "xml:base": const AttributeName("xml", "base", Namespaces.xml), | 489 "xml:base": const AttributeName("xml", "base", Namespaces.xml), |
490 "xml:lang": const AttributeName("xml", "lang", Namespaces.xml), | 490 "xml:lang": const AttributeName("xml", "lang", Namespaces.xml), |
491 "xml:space": const AttributeName("xml", "space", Namespaces.xml), | 491 "xml:space": const AttributeName("xml", "space", Namespaces.xml), |
492 "xmlns": const AttributeName(null, "xmlns", Namespaces.xmlns), | 492 "xmlns": const AttributeName(null, "xmlns", Namespaces.xmlns), |
493 "xmlns:xlink": const AttributeName("xmlns", "xlink", Namespaces.xmlns) | 493 "xmlns:xlink": const AttributeName("xmlns", "xlink", Namespaces.xmlns) |
494 }; | 494 }; |
495 | 495 |
496 for (var originalName in token.data.getKeys()) { | 496 for (var originalName in token.data.keys) { |
497 var foreignName = replacements[originalName]; | 497 var foreignName = replacements[originalName]; |
498 if (foreignName != null) { | 498 if (foreignName != null) { |
499 token.data[foreignName] = token.data.remove(originalName); | 499 token.data[foreignName] = token.data.remove(originalName); |
500 } | 500 } |
501 } | 501 } |
502 } | 502 } |
503 | 503 |
504 void resetInsertionMode() { | 504 void resetInsertionMode() { |
505 // The name of this method is mostly historical. (It's also used in the | 505 // The name of this method is mostly historical. (It's also used in the |
506 // specification.) | 506 // specification.) |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 | 581 |
582 Phase(HtmlParser parser) : parser = parser, tree = parser.tree; | 582 Phase(HtmlParser parser) : parser = parser, tree = parser.tree; |
583 | 583 |
584 bool processEOF() { | 584 bool processEOF() { |
585 throw const NotImplementedException(); | 585 throw const NotImplementedException(); |
586 } | 586 } |
587 | 587 |
588 Token processComment(CommentToken token) { | 588 Token processComment(CommentToken token) { |
589 // For most phases the following is correct. Where it's not it will be | 589 // For most phases the following is correct. Where it's not it will be |
590 // overridden. | 590 // overridden. |
591 tree.insertComment(token, tree.openElements.last()); | 591 tree.insertComment(token, tree.openElements.last); |
592 } | 592 } |
593 | 593 |
594 Token processDoctype(DoctypeToken token) { | 594 Token processDoctype(DoctypeToken token) { |
595 parser.parseError(token.span, "unexpected-doctype"); | 595 parser.parseError(token.span, "unexpected-doctype"); |
596 } | 596 } |
597 | 597 |
598 Token processCharacters(CharactersToken token) { | 598 Token processCharacters(CharactersToken token) { |
599 tree.insertText(token.data, token.span); | 599 tree.insertText(token.data, token.span); |
600 } | 600 } |
601 | 601 |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
855 startTagHead(new StartTagToken("head", data: {})); | 855 startTagHead(new StartTagToken("head", data: {})); |
856 return token; | 856 return token; |
857 } | 857 } |
858 | 858 |
859 Token startTagHtml(StartTagToken token) { | 859 Token startTagHtml(StartTagToken token) { |
860 return parser._inBodyPhase.processStartTag(token); | 860 return parser._inBodyPhase.processStartTag(token); |
861 } | 861 } |
862 | 862 |
863 void startTagHead(StartTagToken token) { | 863 void startTagHead(StartTagToken token) { |
864 tree.insertElement(token); | 864 tree.insertElement(token); |
865 tree.headPointer = tree.openElements.last(); | 865 tree.headPointer = tree.openElements.last; |
866 parser.phase = parser._inHeadPhase; | 866 parser.phase = parser._inHeadPhase; |
867 } | 867 } |
868 | 868 |
869 Token startTagOther(StartTagToken token) { | 869 Token startTagOther(StartTagToken token) { |
870 startTagHead(new StartTagToken("head", data: {})); | 870 startTagHead(new StartTagToken("head", data: {})); |
871 return token; | 871 return token; |
872 } | 872 } |
873 | 873 |
874 Token endTagImplyHead(EndTagToken token) { | 874 Token endTagImplyHead(EndTagToken token) { |
875 startTagHead(new StartTagToken("head", data: {})); | 875 startTagHead(new StartTagToken("head", data: {})); |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1199 default: return endTagOther(token); | 1199 default: return endTagOther(token); |
1200 } | 1200 } |
1201 } | 1201 } |
1202 | 1202 |
1203 bool isMatchingFormattingElement(Node node1, Node node2) { | 1203 bool isMatchingFormattingElement(Node node1, Node node2) { |
1204 if (node1.tagName != node2.tagName || node1.namespace != node2.namespace) { | 1204 if (node1.tagName != node2.tagName || node1.namespace != node2.namespace) { |
1205 return false; | 1205 return false; |
1206 } else if (node1.attributes.length != node2.attributes.length) { | 1206 } else if (node1.attributes.length != node2.attributes.length) { |
1207 return false; | 1207 return false; |
1208 } else { | 1208 } else { |
1209 for (var key in node1.attributes.getKeys()) { | 1209 for (var key in node1.attributes.keys) { |
1210 if (node1.attributes[key] != node2.attributes[key]) { | 1210 if (node1.attributes[key] != node2.attributes[key]) { |
1211 return false; | 1211 return false; |
1212 } | 1212 } |
1213 } | 1213 } |
1214 } | 1214 } |
1215 return true; | 1215 return true; |
1216 } | 1216 } |
1217 | 1217 |
1218 // helper | 1218 // helper |
1219 void addFormattingElement(token) { | 1219 void addFormattingElement(token) { |
1220 tree.insertElement(token); | 1220 tree.insertElement(token); |
1221 var element = tree.openElements.last(); | 1221 var element = tree.openElements.last; |
1222 | 1222 |
1223 var matchingElements = []; | 1223 var matchingElements = []; |
1224 for (Node node in reversed(tree.activeFormattingElements)) { | 1224 for (Node node in reversed(tree.activeFormattingElements)) { |
1225 if (node === Marker) { | 1225 if (node === Marker) { |
1226 break; | 1226 break; |
1227 } else if (isMatchingFormattingElement(node, element)) { | 1227 } else if (isMatchingFormattingElement(node, element)) { |
1228 matchingElements.add(node); | 1228 matchingElements.add(node); |
1229 } | 1229 } |
1230 } | 1230 } |
1231 | 1231 |
1232 assert(matchingElements.length <= 3); | 1232 assert(matchingElements.length <= 3); |
1233 if (matchingElements.length == 3) { | 1233 if (matchingElements.length == 3) { |
1234 tree.activeFormattingElements.remove(matchingElements.last()); | 1234 tree.activeFormattingElements.remove(matchingElements.last); |
1235 } | 1235 } |
1236 tree.activeFormattingElements.add(element); | 1236 tree.activeFormattingElements.add(element); |
1237 } | 1237 } |
1238 | 1238 |
1239 // the real deal | 1239 // the real deal |
1240 bool processEOF() { | 1240 bool processEOF() { |
1241 for (Node node in reversed(tree.openElements)) { | 1241 for (Node node in reversed(tree.openElements)) { |
1242 switch (node.tagName) { | 1242 switch (node.tagName) { |
1243 case "dd": case "dt": case "li": case "p": case "tbody": case "td": | 1243 case "dd": case "dt": case "li": case "p": case "tbody": case "td": |
1244 case "tfoot": case "th": case "thead": case "tr": case "body": | 1244 case "tfoot": case "th": case "thead": case "tr": case "body": |
1245 case "html": | 1245 case "html": |
1246 continue; | 1246 continue; |
1247 } | 1247 } |
1248 parser.parseError(node.span, "expected-closing-tag-but-got-eof"); | 1248 parser.parseError(node.span, "expected-closing-tag-but-got-eof"); |
1249 break; | 1249 break; |
1250 } | 1250 } |
1251 //Stop parsing | 1251 //Stop parsing |
1252 return false; | 1252 return false; |
1253 } | 1253 } |
1254 | 1254 |
1255 void processSpaceCharactersDropNewline(Token token) { | 1255 void processSpaceCharactersDropNewline(Token token) { |
1256 // Sometimes (start of <pre>, <listing>, and <textarea> blocks) we | 1256 // Sometimes (start of <pre>, <listing>, and <textarea> blocks) we |
1257 // want to drop leading newlines | 1257 // want to drop leading newlines |
1258 var data = token.data; | 1258 var data = token.data; |
1259 dropNewline = false; | 1259 dropNewline = false; |
1260 if (data.startsWith("\n")) { | 1260 if (data.startsWith("\n")) { |
1261 var lastOpen = tree.openElements.last(); | 1261 var lastOpen = tree.openElements.last; |
1262 if (const ["pre", "listing", "textarea"].contains(lastOpen.tagName) | 1262 if (const ["pre", "listing", "textarea"].contains(lastOpen.tagName) |
1263 && !lastOpen.hasContent()) { | 1263 && !lastOpen.hasContent()) { |
1264 data = data.substring(1); | 1264 data = data.substring(1); |
1265 } | 1265 } |
1266 } | 1266 } |
1267 if (data.length > 0) { | 1267 if (data.length > 0) { |
1268 tree.reconstructActiveFormattingElements(); | 1268 tree.reconstructActiveFormattingElements(); |
1269 tree.insertText(data, token.span); | 1269 tree.insertText(data, token.span); |
1270 } | 1270 } |
1271 } | 1271 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1312 | 1312 |
1313 void startTagFrameset(StartTagToken token) { | 1313 void startTagFrameset(StartTagToken token) { |
1314 parser.parseError(token.span, "unexpected-start-tag", {"name": "frameset"}); | 1314 parser.parseError(token.span, "unexpected-start-tag", {"name": "frameset"}); |
1315 if ((tree.openElements.length == 1 || | 1315 if ((tree.openElements.length == 1 || |
1316 tree.openElements[1].tagName != "body")) { | 1316 tree.openElements[1].tagName != "body")) { |
1317 assert(parser.innerHTMLMode); | 1317 assert(parser.innerHTMLMode); |
1318 } else if (parser.framesetOK) { | 1318 } else if (parser.framesetOK) { |
1319 if (tree.openElements[1].parent != null) { | 1319 if (tree.openElements[1].parent != null) { |
1320 tree.openElements[1].parent.nodes.remove(tree.openElements[1]); | 1320 tree.openElements[1].parent.nodes.remove(tree.openElements[1]); |
1321 } | 1321 } |
1322 while (tree.openElements.last().tagName != "html") { | 1322 while (tree.openElements.last.tagName != "html") { |
1323 tree.openElements.removeLast(); | 1323 tree.openElements.removeLast(); |
1324 } | 1324 } |
1325 tree.insertElement(token); | 1325 tree.insertElement(token); |
1326 parser.phase = parser._inFramesetPhase; | 1326 parser.phase = parser._inFramesetPhase; |
1327 } | 1327 } |
1328 } | 1328 } |
1329 | 1329 |
1330 void startTagCloseP(StartTagToken token) { | 1330 void startTagCloseP(StartTagToken token) { |
1331 if (tree.elementInScope("p", variant: "button")) { | 1331 if (tree.elementInScope("p", variant: "button")) { |
1332 endTagP(new EndTagToken("p", data: {})); | 1332 endTagP(new EndTagToken("p", data: {})); |
(...skipping 11 matching lines...) Expand all Loading... |
1344 } | 1344 } |
1345 | 1345 |
1346 void startTagForm(StartTagToken token) { | 1346 void startTagForm(StartTagToken token) { |
1347 if (tree.formPointer != null) { | 1347 if (tree.formPointer != null) { |
1348 parser.parseError(token.span, "unexpected-start-tag", {"name": "form"}); | 1348 parser.parseError(token.span, "unexpected-start-tag", {"name": "form"}); |
1349 } else { | 1349 } else { |
1350 if (tree.elementInScope("p", variant: "button")) { | 1350 if (tree.elementInScope("p", variant: "button")) { |
1351 endTagP(new EndTagToken("p", data: {})); | 1351 endTagP(new EndTagToken("p", data: {})); |
1352 } | 1352 } |
1353 tree.insertElement(token); | 1353 tree.insertElement(token); |
1354 tree.formPointer = tree.openElements.last(); | 1354 tree.formPointer = tree.openElements.last; |
1355 } | 1355 } |
1356 } | 1356 } |
1357 | 1357 |
1358 void startTagListItem(StartTagToken token) { | 1358 void startTagListItem(StartTagToken token) { |
1359 parser.framesetOK = false; | 1359 parser.framesetOK = false; |
1360 | 1360 |
1361 final stopNamesMap = const {"li": const ["li"], | 1361 final stopNamesMap = const {"li": const ["li"], |
1362 "dt": const ["dt", "dd"], | 1362 "dt": const ["dt", "dd"], |
1363 "dd": const ["dt", "dd"]}; | 1363 "dd": const ["dt", "dd"]}; |
1364 var stopNames = stopNamesMap[token.name]; | 1364 var stopNames = stopNamesMap[token.name]; |
(...skipping 20 matching lines...) Expand all Loading... |
1385 endTagP(new EndTagToken("p", data: {})); | 1385 endTagP(new EndTagToken("p", data: {})); |
1386 } | 1386 } |
1387 tree.insertElement(token); | 1387 tree.insertElement(token); |
1388 parser.tokenizer.state = parser.tokenizer.plaintextState; | 1388 parser.tokenizer.state = parser.tokenizer.plaintextState; |
1389 } | 1389 } |
1390 | 1390 |
1391 void startTagHeading(StartTagToken token) { | 1391 void startTagHeading(StartTagToken token) { |
1392 if (tree.elementInScope("p", variant: "button")) { | 1392 if (tree.elementInScope("p", variant: "button")) { |
1393 endTagP(new EndTagToken("p", data: {})); | 1393 endTagP(new EndTagToken("p", data: {})); |
1394 } | 1394 } |
1395 if (headingElements.contains(tree.openElements.last().tagName)) { | 1395 if (headingElements.contains(tree.openElements.last.tagName)) { |
1396 parser.parseError(token.span, "unexpected-start-tag", | 1396 parser.parseError(token.span, "unexpected-start-tag", |
1397 {"name": token.name}); | 1397 {"name": token.name}); |
1398 tree.openElements.removeLast(); | 1398 tree.openElements.removeLast(); |
1399 } | 1399 } |
1400 tree.insertElement(token); | 1400 tree.insertElement(token); |
1401 } | 1401 } |
1402 | 1402 |
1403 void startTagA(StartTagToken token) { | 1403 void startTagA(StartTagToken token) { |
1404 var afeAElement = tree.elementInActiveFormattingElements("a"); | 1404 var afeAElement = tree.elementInActiveFormattingElements("a"); |
1405 if (afeAElement != null) { | 1405 if (afeAElement != null) { |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1552 parser.framesetOK = false; | 1552 parser.framesetOK = false; |
1553 startTagRawtext(token); | 1553 startTagRawtext(token); |
1554 } | 1554 } |
1555 | 1555 |
1556 /** iframe, noembed noframes, noscript(if scripting enabled). */ | 1556 /** iframe, noembed noframes, noscript(if scripting enabled). */ |
1557 void startTagRawtext(StartTagToken token) { | 1557 void startTagRawtext(StartTagToken token) { |
1558 parser.parseRCDataRawtext(token, "RAWTEXT"); | 1558 parser.parseRCDataRawtext(token, "RAWTEXT"); |
1559 } | 1559 } |
1560 | 1560 |
1561 void startTagOpt(StartTagToken token) { | 1561 void startTagOpt(StartTagToken token) { |
1562 if (tree.openElements.last().tagName == "option") { | 1562 if (tree.openElements.last.tagName == "option") { |
1563 parser.phase.processEndTag(new EndTagToken("option", data: {})); | 1563 parser.phase.processEndTag(new EndTagToken("option", data: {})); |
1564 } | 1564 } |
1565 tree.reconstructActiveFormattingElements(); | 1565 tree.reconstructActiveFormattingElements(); |
1566 parser.tree.insertElement(token); | 1566 parser.tree.insertElement(token); |
1567 } | 1567 } |
1568 | 1568 |
1569 void startTagSelect(StartTagToken token) { | 1569 void startTagSelect(StartTagToken token) { |
1570 tree.reconstructActiveFormattingElements(); | 1570 tree.reconstructActiveFormattingElements(); |
1571 tree.insertElement(token); | 1571 tree.insertElement(token); |
1572 parser.framesetOK = false; | 1572 parser.framesetOK = false; |
1573 | 1573 |
1574 if (parser._inTablePhase == parser.phase || | 1574 if (parser._inTablePhase == parser.phase || |
1575 parser._inCaptionPhase == parser.phase || | 1575 parser._inCaptionPhase == parser.phase || |
1576 parser._inColumnGroupPhase == parser.phase || | 1576 parser._inColumnGroupPhase == parser.phase || |
1577 parser._inTableBodyPhase == parser.phase || | 1577 parser._inTableBodyPhase == parser.phase || |
1578 parser._inRowPhase == parser.phase || | 1578 parser._inRowPhase == parser.phase || |
1579 parser._inCellPhase == parser.phase) { | 1579 parser._inCellPhase == parser.phase) { |
1580 parser.phase = parser._inSelectInTablePhase; | 1580 parser.phase = parser._inSelectInTablePhase; |
1581 } else { | 1581 } else { |
1582 parser.phase = parser._inSelectPhase; | 1582 parser.phase = parser._inSelectPhase; |
1583 } | 1583 } |
1584 } | 1584 } |
1585 | 1585 |
1586 void startTagRpRt(StartTagToken token) { | 1586 void startTagRpRt(StartTagToken token) { |
1587 if (tree.elementInScope("ruby")) { | 1587 if (tree.elementInScope("ruby")) { |
1588 tree.generateImpliedEndTags(); | 1588 tree.generateImpliedEndTags(); |
1589 var last = tree.openElements.last(); | 1589 var last = tree.openElements.last; |
1590 if (last.tagName != "ruby") { | 1590 if (last.tagName != "ruby") { |
1591 parser.parseError(last.span, 'undefined-error'); | 1591 parser.parseError(last.span, 'undefined-error'); |
1592 } | 1592 } |
1593 } | 1593 } |
1594 tree.insertElement(token); | 1594 tree.insertElement(token); |
1595 } | 1595 } |
1596 | 1596 |
1597 void startTagMath(StartTagToken token) { | 1597 void startTagMath(StartTagToken token) { |
1598 tree.reconstructActiveFormattingElements(); | 1598 tree.reconstructActiveFormattingElements(); |
1599 parser.adjustMathMLAttributes(token); | 1599 parser.adjustMathMLAttributes(token); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1639 tree.insertElement(token); | 1639 tree.insertElement(token); |
1640 } | 1640 } |
1641 | 1641 |
1642 void endTagP(EndTagToken token) { | 1642 void endTagP(EndTagToken token) { |
1643 if (!tree.elementInScope("p", variant: "button")) { | 1643 if (!tree.elementInScope("p", variant: "button")) { |
1644 startTagCloseP(new StartTagToken("p", data: {})); | 1644 startTagCloseP(new StartTagToken("p", data: {})); |
1645 parser.parseError(token.span, "unexpected-end-tag", {"name": "p"}); | 1645 parser.parseError(token.span, "unexpected-end-tag", {"name": "p"}); |
1646 endTagP(new EndTagToken("p", data: {})); | 1646 endTagP(new EndTagToken("p", data: {})); |
1647 } else { | 1647 } else { |
1648 tree.generateImpliedEndTags("p"); | 1648 tree.generateImpliedEndTags("p"); |
1649 if (tree.openElements.last().tagName != "p") { | 1649 if (tree.openElements.last.tagName != "p") { |
1650 parser.parseError(token.span, "unexpected-end-tag", {"name": "p"}); | 1650 parser.parseError(token.span, "unexpected-end-tag", {"name": "p"}); |
1651 } | 1651 } |
1652 popOpenElementsUntil("p"); | 1652 popOpenElementsUntil("p"); |
1653 } | 1653 } |
1654 } | 1654 } |
1655 | 1655 |
1656 void endTagBody(EndTagToken token) { | 1656 void endTagBody(EndTagToken token) { |
1657 if (!tree.elementInScope("body")) { | 1657 if (!tree.elementInScope("body")) { |
1658 parser.parseError(token.span, 'undefined-error'); | 1658 parser.parseError(token.span, 'undefined-error'); |
1659 return; | 1659 return; |
1660 } else if (tree.openElements.last().tagName != "body") { | 1660 } else if (tree.openElements.last.tagName != "body") { |
1661 for (Node node in slice(tree.openElements, 2)) { | 1661 for (Node node in slice(tree.openElements, 2)) { |
1662 switch (node.tagName) { | 1662 switch (node.tagName) { |
1663 case "dd": case "dt": case "li": case "optgroup": case "option": | 1663 case "dd": case "dt": case "li": case "optgroup": case "option": |
1664 case "p": case "rp": case "rt": case "tbody": case "td": case "tfoot": | 1664 case "p": case "rp": case "rt": case "tbody": case "td": case "tfoot": |
1665 case "th": case "thead": case "tr": case "body": case "html": | 1665 case "th": case "thead": case "tr": case "body": case "html": |
1666 continue; | 1666 continue; |
1667 } | 1667 } |
1668 // Not sure this is the correct name for the parse error | 1668 // Not sure this is the correct name for the parse error |
1669 parser.parseError(token.span, "expected-one-end-tag-but-got-another", | 1669 parser.parseError(token.span, "expected-one-end-tag-but-got-another", |
1670 {"expectedName": "body", "gotName": node.tagName}); | 1670 {"expectedName": "body", "gotName": node.tagName}); |
(...skipping 13 matching lines...) Expand all Loading... |
1684 | 1684 |
1685 void endTagBlock(EndTagToken token) { | 1685 void endTagBlock(EndTagToken token) { |
1686 //Put us back in the right whitespace handling mode | 1686 //Put us back in the right whitespace handling mode |
1687 if (token.name == "pre") { | 1687 if (token.name == "pre") { |
1688 dropNewline = false; | 1688 dropNewline = false; |
1689 } | 1689 } |
1690 var inScope = tree.elementInScope(token.name); | 1690 var inScope = tree.elementInScope(token.name); |
1691 if (inScope) { | 1691 if (inScope) { |
1692 tree.generateImpliedEndTags(); | 1692 tree.generateImpliedEndTags(); |
1693 } | 1693 } |
1694 if (tree.openElements.last().tagName != token.name) { | 1694 if (tree.openElements.last.tagName != token.name) { |
1695 parser.parseError(token.span, "end-tag-too-early", {"name": token.name}); | 1695 parser.parseError(token.span, "end-tag-too-early", {"name": token.name}); |
1696 } | 1696 } |
1697 if (inScope) { | 1697 if (inScope) { |
1698 popOpenElementsUntil(token.name); | 1698 popOpenElementsUntil(token.name); |
1699 } | 1699 } |
1700 } | 1700 } |
1701 | 1701 |
1702 void endTagForm(EndTagToken token) { | 1702 void endTagForm(EndTagToken token) { |
1703 var node = tree.formPointer; | 1703 var node = tree.formPointer; |
1704 tree.formPointer = null; | 1704 tree.formPointer = null; |
1705 if (node === null || !tree.elementInScope(node)) { | 1705 if (node === null || !tree.elementInScope(node)) { |
1706 parser.parseError(token.span, "unexpected-end-tag", {"name": "form"}); | 1706 parser.parseError(token.span, "unexpected-end-tag", {"name": "form"}); |
1707 } else { | 1707 } else { |
1708 tree.generateImpliedEndTags(); | 1708 tree.generateImpliedEndTags(); |
1709 if (tree.openElements.last() != node) { | 1709 if (tree.openElements.last != node) { |
1710 parser.parseError(token.span, "end-tag-too-early-ignored", {"name": "for
m"}); | 1710 parser.parseError(token.span, "end-tag-too-early-ignored", {"name": "for
m"}); |
1711 } | 1711 } |
1712 tree.openElements.remove(node); | 1712 tree.openElements.remove(node); |
1713 } | 1713 } |
1714 } | 1714 } |
1715 | 1715 |
1716 void endTagListItem(EndTagToken token) { | 1716 void endTagListItem(EndTagToken token) { |
1717 var variant; | 1717 var variant; |
1718 if (token.name == "li") { | 1718 if (token.name == "li") { |
1719 variant = "list"; | 1719 variant = "list"; |
1720 } else { | 1720 } else { |
1721 variant = null; | 1721 variant = null; |
1722 } | 1722 } |
1723 if (!tree.elementInScope(token.name, variant: variant)) { | 1723 if (!tree.elementInScope(token.name, variant: variant)) { |
1724 parser.parseError(token.span, "unexpected-end-tag", {"name": token.name}); | 1724 parser.parseError(token.span, "unexpected-end-tag", {"name": token.name}); |
1725 } else { | 1725 } else { |
1726 tree.generateImpliedEndTags(token.name); | 1726 tree.generateImpliedEndTags(token.name); |
1727 if (tree.openElements.last().tagName != token.name) { | 1727 if (tree.openElements.last.tagName != token.name) { |
1728 parser.parseError(token.span, "end-tag-too-early", {"name": token.name})
; | 1728 parser.parseError(token.span, "end-tag-too-early", {"name": token.name})
; |
1729 } | 1729 } |
1730 popOpenElementsUntil(token.name); | 1730 popOpenElementsUntil(token.name); |
1731 } | 1731 } |
1732 } | 1732 } |
1733 | 1733 |
1734 void endTagHeading(EndTagToken token) { | 1734 void endTagHeading(EndTagToken token) { |
1735 for (var item in headingElements) { | 1735 for (var item in headingElements) { |
1736 if (tree.elementInScope(item)) { | 1736 if (tree.elementInScope(item)) { |
1737 tree.generateImpliedEndTags(); | 1737 tree.generateImpliedEndTags(); |
1738 break; | 1738 break; |
1739 } | 1739 } |
1740 } | 1740 } |
1741 if (tree.openElements.last().tagName != token.name) { | 1741 if (tree.openElements.last.tagName != token.name) { |
1742 parser.parseError(token.span, "end-tag-too-early", {"name": token.name}); | 1742 parser.parseError(token.span, "end-tag-too-early", {"name": token.name}); |
1743 } | 1743 } |
1744 | 1744 |
1745 for (var item in headingElements) { | 1745 for (var item in headingElements) { |
1746 if (tree.elementInScope(item)) { | 1746 if (tree.elementInScope(item)) { |
1747 item = tree.openElements.removeLast(); | 1747 item = tree.openElements.removeLast(); |
1748 while (!headingElements.contains(item.tagName)) { | 1748 while (!headingElements.contains(item.tagName)) { |
1749 item = tree.openElements.removeLast(); | 1749 item = tree.openElements.removeLast(); |
1750 } | 1750 } |
1751 break; | 1751 break; |
(...skipping 23 matching lines...) Expand all Loading... |
1775 return; | 1775 return; |
1776 // Step 1 paragraph 2 | 1776 // Step 1 paragraph 2 |
1777 } else if (!tree.openElements.contains(formattingElement)) { | 1777 } else if (!tree.openElements.contains(formattingElement)) { |
1778 parser.parseError(token.span, "adoption-agency-1.2", | 1778 parser.parseError(token.span, "adoption-agency-1.2", |
1779 {"name": token.name}); | 1779 {"name": token.name}); |
1780 tree.activeFormattingElements.remove(formattingElement); | 1780 tree.activeFormattingElements.remove(formattingElement); |
1781 return; | 1781 return; |
1782 } | 1782 } |
1783 | 1783 |
1784 // Step 1 paragraph 3 | 1784 // Step 1 paragraph 3 |
1785 if (formattingElement != tree.openElements.last()) { | 1785 if (formattingElement != tree.openElements.last) { |
1786 parser.parseError(token.span, "adoption-agency-1.3", | 1786 parser.parseError(token.span, "adoption-agency-1.3", |
1787 {"name": token.name}); | 1787 {"name": token.name}); |
1788 } | 1788 } |
1789 | 1789 |
1790 // Step 2 | 1790 // Step 2 |
1791 // Start of the adoption agency algorithm proper | 1791 // Start of the adoption agency algorithm proper |
1792 var afeIndex = tree.openElements.indexOf(formattingElement); | 1792 var afeIndex = tree.openElements.indexOf(formattingElement); |
1793 Node furthestBlock = null; | 1793 Node furthestBlock = null; |
1794 for (Node element in slice(tree.openElements, afeIndex)) { | 1794 for (Node element in slice(tree.openElements, afeIndex)) { |
1795 if (specialElements.contains(element.nameTuple)) { | 1795 if (specialElements.contains(element.nameTuple)) { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1894 tree.openElements.remove(formattingElement); | 1894 tree.openElements.remove(formattingElement); |
1895 tree.openElements.insertRange( | 1895 tree.openElements.insertRange( |
1896 tree.openElements.indexOf(furthestBlock) + 1, 1, clone); | 1896 tree.openElements.indexOf(furthestBlock) + 1, 1, clone); |
1897 } | 1897 } |
1898 } | 1898 } |
1899 | 1899 |
1900 void endTagAppletMarqueeObject(EndTagToken token) { | 1900 void endTagAppletMarqueeObject(EndTagToken token) { |
1901 if (tree.elementInScope(token.name)) { | 1901 if (tree.elementInScope(token.name)) { |
1902 tree.generateImpliedEndTags(); | 1902 tree.generateImpliedEndTags(); |
1903 } | 1903 } |
1904 if (tree.openElements.last().tagName != token.name) { | 1904 if (tree.openElements.last.tagName != token.name) { |
1905 parser.parseError(token.span, "end-tag-too-early", {"name": token.name}); | 1905 parser.parseError(token.span, "end-tag-too-early", {"name": token.name}); |
1906 } | 1906 } |
1907 if (tree.elementInScope(token.name)) { | 1907 if (tree.elementInScope(token.name)) { |
1908 popOpenElementsUntil(token.name); | 1908 popOpenElementsUntil(token.name); |
1909 tree.clearActiveFormattingElements(); | 1909 tree.clearActiveFormattingElements(); |
1910 } | 1910 } |
1911 } | 1911 } |
1912 | 1912 |
1913 void endTagBr(EndTagToken token) { | 1913 void endTagBr(EndTagToken token) { |
1914 parser.parseError(token.span, "unexpected-end-tag-treated-as", | 1914 parser.parseError(token.span, "unexpected-end-tag-treated-as", |
1915 {"originalName": "br", "newName": "br element"}); | 1915 {"originalName": "br", "newName": "br element"}); |
1916 tree.reconstructActiveFormattingElements(); | 1916 tree.reconstructActiveFormattingElements(); |
1917 tree.insertElement(new StartTagToken("br", data: {})); | 1917 tree.insertElement(new StartTagToken("br", data: {})); |
1918 tree.openElements.removeLast(); | 1918 tree.openElements.removeLast(); |
1919 } | 1919 } |
1920 | 1920 |
1921 void endTagOther(EndTagToken token) { | 1921 void endTagOther(EndTagToken token) { |
1922 for (Node node in reversed(tree.openElements)) { | 1922 for (Node node in reversed(tree.openElements)) { |
1923 if (node.tagName == token.name) { | 1923 if (node.tagName == token.name) { |
1924 tree.generateImpliedEndTags(token.name); | 1924 tree.generateImpliedEndTags(token.name); |
1925 if (tree.openElements.last().tagName != token.name) { | 1925 if (tree.openElements.last.tagName != token.name) { |
1926 parser.parseError(token.span, "unexpected-end-tag", | 1926 parser.parseError(token.span, "unexpected-end-tag", |
1927 {"name": token.name}); | 1927 {"name": token.name}); |
1928 } | 1928 } |
1929 while (tree.openElements.removeLast() != node); | 1929 while (tree.openElements.removeLast() != node); |
1930 break; | 1930 break; |
1931 } else { | 1931 } else { |
1932 if (specialElements.contains(node.nameTuple)) { | 1932 if (specialElements.contains(node.nameTuple)) { |
1933 parser.parseError(token.span, "unexpected-end-tag", | 1933 parser.parseError(token.span, "unexpected-end-tag", |
1934 {"name": token.name}); | 1934 {"name": token.name}); |
1935 break; | 1935 break; |
(...skipping 13 matching lines...) Expand all Loading... |
1949 processEndTag(EndTagToken token) { | 1949 processEndTag(EndTagToken token) { |
1950 if (token.name == 'script') return endTagScript(token); | 1950 if (token.name == 'script') return endTagScript(token); |
1951 return endTagOther(token); | 1951 return endTagOther(token); |
1952 } | 1952 } |
1953 | 1953 |
1954 Token processCharacters(CharactersToken token) { | 1954 Token processCharacters(CharactersToken token) { |
1955 tree.insertText(token.data, token.span); | 1955 tree.insertText(token.data, token.span); |
1956 } | 1956 } |
1957 | 1957 |
1958 bool processEOF() { | 1958 bool processEOF() { |
1959 var last = tree.openElements.last(); | 1959 var last = tree.openElements.last; |
1960 parser.parseError(last.span, "expected-named-closing-tag-but-got-eof", | 1960 parser.parseError(last.span, "expected-named-closing-tag-but-got-eof", |
1961 {'name': last.tagName}); | 1961 {'name': last.tagName}); |
1962 tree.openElements.removeLast(); | 1962 tree.openElements.removeLast(); |
1963 parser.phase = parser.originalPhase; | 1963 parser.phase = parser.originalPhase; |
1964 return true; | 1964 return true; |
1965 } | 1965 } |
1966 | 1966 |
1967 void endTagScript(EndTagToken token) { | 1967 void endTagScript(EndTagToken token) { |
1968 var node = tree.openElements.removeLast(); | 1968 var node = tree.openElements.removeLast(); |
1969 assert(node.tagName == "script"); | 1969 assert(node.tagName == "script"); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2004 case "body": case "caption": case "col": case "colgroup": case "html": | 2004 case "body": case "caption": case "col": case "colgroup": case "html": |
2005 case "tbody": case "td": case "tfoot": case "th": case "thead": case "tr": | 2005 case "tbody": case "td": case "tfoot": case "th": case "thead": case "tr": |
2006 return endTagIgnore(token); | 2006 return endTagIgnore(token); |
2007 default: return endTagOther(token); | 2007 default: return endTagOther(token); |
2008 } | 2008 } |
2009 } | 2009 } |
2010 | 2010 |
2011 // helper methods | 2011 // helper methods |
2012 void clearStackToTableContext() { | 2012 void clearStackToTableContext() { |
2013 // "clear the stack back to a table context" | 2013 // "clear the stack back to a table context" |
2014 while (tree.openElements.last().tagName != "table" && | 2014 while (tree.openElements.last.tagName != "table" && |
2015 tree.openElements.last().tagName != "html") { | 2015 tree.openElements.last.tagName != "html") { |
2016 //parser.parseError(token.span, "unexpected-implied-end-tag-in-table", | 2016 //parser.parseError(token.span, "unexpected-implied-end-tag-in-table", |
2017 // {"name": tree.openElements.last().name}) | 2017 // {"name": tree.openElements.last.name}) |
2018 tree.openElements.removeLast(); | 2018 tree.openElements.removeLast(); |
2019 } | 2019 } |
2020 // When the current node is <html> it's an innerHTML case | 2020 // When the current node is <html> it's an innerHTML case |
2021 } | 2021 } |
2022 | 2022 |
2023 // processing methods | 2023 // processing methods |
2024 bool processEOF() { | 2024 bool processEOF() { |
2025 var last = tree.openElements.last(); | 2025 var last = tree.openElements.last; |
2026 if (last.tagName != "html") { | 2026 if (last.tagName != "html") { |
2027 parser.parseError(last.span, "eof-in-table"); | 2027 parser.parseError(last.span, "eof-in-table"); |
2028 } else { | 2028 } else { |
2029 assert(parser.innerHTMLMode); | 2029 assert(parser.innerHTMLMode); |
2030 } | 2030 } |
2031 //Stop parsing | 2031 //Stop parsing |
2032 return false; | 2032 return false; |
2033 } | 2033 } |
2034 | 2034 |
2035 Token processSpaceCharacters(SpaceCharactersToken token) { | 2035 Token processSpaceCharacters(SpaceCharactersToken token) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2104 tree.openElements.removeLast(); | 2104 tree.openElements.removeLast(); |
2105 } else { | 2105 } else { |
2106 startTagOther(token); | 2106 startTagOther(token); |
2107 } | 2107 } |
2108 } | 2108 } |
2109 | 2109 |
2110 void startTagForm(StartTagToken token) { | 2110 void startTagForm(StartTagToken token) { |
2111 parser.parseError(token.span, "unexpected-form-in-table"); | 2111 parser.parseError(token.span, "unexpected-form-in-table"); |
2112 if (tree.formPointer === null) { | 2112 if (tree.formPointer === null) { |
2113 tree.insertElement(token); | 2113 tree.insertElement(token); |
2114 tree.formPointer = tree.openElements.last(); | 2114 tree.formPointer = tree.openElements.last; |
2115 tree.openElements.removeLast(); | 2115 tree.openElements.removeLast(); |
2116 } | 2116 } |
2117 } | 2117 } |
2118 | 2118 |
2119 void startTagOther(StartTagToken token) { | 2119 void startTagOther(StartTagToken token) { |
2120 parser.parseError(token.span, "unexpected-start-tag-implies-table-voodoo", | 2120 parser.parseError(token.span, "unexpected-start-tag-implies-table-voodoo", |
2121 {"name": token.name}); | 2121 {"name": token.name}); |
2122 // Do the table magic! | 2122 // Do the table magic! |
2123 tree.insertFromTable = true; | 2123 tree.insertFromTable = true; |
2124 parser._inBodyPhase.processStartTag(token); | 2124 parser._inBodyPhase.processStartTag(token); |
2125 tree.insertFromTable = false; | 2125 tree.insertFromTable = false; |
2126 } | 2126 } |
2127 | 2127 |
2128 void endTagTable(EndTagToken token) { | 2128 void endTagTable(EndTagToken token) { |
2129 if (tree.elementInScope("table", variant: "table")) { | 2129 if (tree.elementInScope("table", variant: "table")) { |
2130 tree.generateImpliedEndTags(); | 2130 tree.generateImpliedEndTags(); |
2131 var last = tree.openElements.last(); | 2131 var last = tree.openElements.last; |
2132 if (last.tagName != "table") { | 2132 if (last.tagName != "table") { |
2133 parser.parseError(token.span, "end-tag-too-early-named", | 2133 parser.parseError(token.span, "end-tag-too-early-named", |
2134 {"gotName": "table", "expectedName": last.tagName}); | 2134 {"gotName": "table", "expectedName": last.tagName}); |
2135 } | 2135 } |
2136 while (tree.openElements.last().tagName != "table") { | 2136 while (tree.openElements.last.tagName != "table") { |
2137 tree.openElements.removeLast(); | 2137 tree.openElements.removeLast(); |
2138 } | 2138 } |
2139 tree.openElements.removeLast(); | 2139 tree.openElements.removeLast(); |
2140 parser.resetInsertionMode(); | 2140 parser.resetInsertionMode(); |
2141 } else { | 2141 } else { |
2142 // innerHTML case | 2142 // innerHTML case |
2143 assert(parser.innerHTMLMode); | 2143 assert(parser.innerHTMLMode); |
2144 parser.parseError(token.span, "undefined-error"); | 2144 parser.parseError(token.span, "undefined-error"); |
2145 } | 2145 } |
2146 } | 2146 } |
(...skipping 22 matching lines...) Expand all Loading... |
2169 | 2169 |
2170 void flushCharacters() { | 2170 void flushCharacters() { |
2171 if (characterTokens.length == 0) return; | 2171 if (characterTokens.length == 0) return; |
2172 | 2172 |
2173 var data = joinStr(characterTokens.map((t) => t.data)); | 2173 var data = joinStr(characterTokens.map((t) => t.data)); |
2174 var span = null; | 2174 var span = null; |
2175 | 2175 |
2176 if (parser.generateSpans) { | 2176 if (parser.generateSpans) { |
2177 span = new SourceSpan.union( | 2177 span = new SourceSpan.union( |
2178 characterTokens[0].span, | 2178 characterTokens[0].span, |
2179 characterTokens.last().span); | 2179 characterTokens.last.span); |
2180 } | 2180 } |
2181 | 2181 |
2182 if (!allWhitespace(data)) { | 2182 if (!allWhitespace(data)) { |
2183 parser._inTablePhase.insertText(new CharactersToken(data)..span = span); | 2183 parser._inTablePhase.insertText(new CharactersToken(data)..span = span); |
2184 } else if (data.length > 0) { | 2184 } else if (data.length > 0) { |
2185 tree.insertText(data, span); | 2185 tree.insertText(data, span); |
2186 } | 2186 } |
2187 characterTokens = <StringToken>[]; | 2187 characterTokens = <StringToken>[]; |
2188 } | 2188 } |
2189 | 2189 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2276 } | 2276 } |
2277 | 2277 |
2278 Token startTagOther(StartTagToken token) { | 2278 Token startTagOther(StartTagToken token) { |
2279 return parser._inBodyPhase.processStartTag(token); | 2279 return parser._inBodyPhase.processStartTag(token); |
2280 } | 2280 } |
2281 | 2281 |
2282 void endTagCaption(EndTagToken token) { | 2282 void endTagCaption(EndTagToken token) { |
2283 if (!ignoreEndTagCaption()) { | 2283 if (!ignoreEndTagCaption()) { |
2284 // AT this code is quite similar to endTagTable in "InTable" | 2284 // AT this code is quite similar to endTagTable in "InTable" |
2285 tree.generateImpliedEndTags(); | 2285 tree.generateImpliedEndTags(); |
2286 if (tree.openElements.last().tagName != "caption") { | 2286 if (tree.openElements.last.tagName != "caption") { |
2287 parser.parseError(token.span, "expected-one-end-tag-but-got-another", | 2287 parser.parseError(token.span, "expected-one-end-tag-but-got-another", |
2288 {"gotName": "caption", | 2288 {"gotName": "caption", |
2289 "expectedName": tree.openElements.last().tagName}); | 2289 "expectedName": tree.openElements.last.tagName}); |
2290 } | 2290 } |
2291 while (tree.openElements.last().tagName != "caption") { | 2291 while (tree.openElements.last.tagName != "caption") { |
2292 tree.openElements.removeLast(); | 2292 tree.openElements.removeLast(); |
2293 } | 2293 } |
2294 tree.openElements.removeLast(); | 2294 tree.openElements.removeLast(); |
2295 tree.clearActiveFormattingElements(); | 2295 tree.clearActiveFormattingElements(); |
2296 parser.phase = parser._inTablePhase; | 2296 parser.phase = parser._inTablePhase; |
2297 } else { | 2297 } else { |
2298 // innerHTML case | 2298 // innerHTML case |
2299 assert(parser.innerHTMLMode); | 2299 assert(parser.innerHTMLMode); |
2300 parser.parseError(token.span, "undefined-error"); | 2300 parser.parseError(token.span, "undefined-error"); |
2301 } | 2301 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2335 | 2335 |
2336 processEndTag(EndTagToken token) { | 2336 processEndTag(EndTagToken token) { |
2337 switch (token.name) { | 2337 switch (token.name) { |
2338 case "colgroup": return endTagColgroup(token); | 2338 case "colgroup": return endTagColgroup(token); |
2339 case "col": return endTagCol(token); | 2339 case "col": return endTagCol(token); |
2340 default: return endTagOther(token); | 2340 default: return endTagOther(token); |
2341 } | 2341 } |
2342 } | 2342 } |
2343 | 2343 |
2344 bool ignoreEndTagColgroup() { | 2344 bool ignoreEndTagColgroup() { |
2345 return tree.openElements.last().tagName == "html"; | 2345 return tree.openElements.last.tagName == "html"; |
2346 } | 2346 } |
2347 | 2347 |
2348 bool processEOF() { | 2348 bool processEOF() { |
2349 var ignoreEndTag = ignoreEndTagColgroup(); | 2349 var ignoreEndTag = ignoreEndTagColgroup(); |
2350 if (ignoreEndTag) { | 2350 if (ignoreEndTag) { |
2351 assert(parser.innerHTMLMode); | 2351 assert(parser.innerHTMLMode); |
2352 return false; | 2352 return false; |
2353 } else { | 2353 } else { |
2354 endTagColgroup(new EndTagToken("colgroup", data: {})); | 2354 endTagColgroup(new EndTagToken("colgroup", data: {})); |
2355 return true; | 2355 return true; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2420 case "body": case "caption": case "col": case "colgroup": case "html": | 2420 case "body": case "caption": case "col": case "colgroup": case "html": |
2421 case "td": case "th": case "tr": | 2421 case "td": case "th": case "tr": |
2422 return endTagIgnore(token); | 2422 return endTagIgnore(token); |
2423 default: return endTagOther(token); | 2423 default: return endTagOther(token); |
2424 } | 2424 } |
2425 } | 2425 } |
2426 | 2426 |
2427 // helper methods | 2427 // helper methods |
2428 void clearStackToTableBodyContext() { | 2428 void clearStackToTableBodyContext() { |
2429 var tableTags = const ["tbody", "tfoot", "thead", "html"]; | 2429 var tableTags = const ["tbody", "tfoot", "thead", "html"]; |
2430 while (!tableTags.contains(tree.openElements.last().tagName)) { | 2430 while (!tableTags.contains(tree.openElements.last.tagName)) { |
2431 //XXX parser.parseError(token.span, "unexpected-implied-end-tag-in-table", | 2431 //XXX parser.parseError(token.span, "unexpected-implied-end-tag-in-table", |
2432 // {"name": tree.openElements.last().name}) | 2432 // {"name": tree.openElements.last.name}) |
2433 tree.openElements.removeLast(); | 2433 tree.openElements.removeLast(); |
2434 } | 2434 } |
2435 if (tree.openElements.last().tagName == "html") { | 2435 if (tree.openElements.last.tagName == "html") { |
2436 assert(parser.innerHTMLMode); | 2436 assert(parser.innerHTMLMode); |
2437 } | 2437 } |
2438 } | 2438 } |
2439 | 2439 |
2440 // the rest | 2440 // the rest |
2441 bool processEOF() { | 2441 bool processEOF() { |
2442 parser._inTablePhase.processEOF(); | 2442 parser._inTablePhase.processEOF(); |
2443 return false; | 2443 return false; |
2444 } | 2444 } |
2445 | 2445 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2481 } | 2481 } |
2482 } | 2482 } |
2483 | 2483 |
2484 Token endTagTable(TagToken token) { | 2484 Token endTagTable(TagToken token) { |
2485 // XXX AT Any ideas on how to share this with endTagTable? | 2485 // XXX AT Any ideas on how to share this with endTagTable? |
2486 if (tree.elementInScope("tbody", variant: "table") || | 2486 if (tree.elementInScope("tbody", variant: "table") || |
2487 tree.elementInScope("thead", variant: "table") || | 2487 tree.elementInScope("thead", variant: "table") || |
2488 tree.elementInScope("tfoot", variant: "table")) { | 2488 tree.elementInScope("tfoot", variant: "table")) { |
2489 clearStackToTableBodyContext(); | 2489 clearStackToTableBodyContext(); |
2490 endTagTableRowGroup( | 2490 endTagTableRowGroup( |
2491 new EndTagToken(tree.openElements.last().tagName, data: {})); | 2491 new EndTagToken(tree.openElements.last.tagName, data: {})); |
2492 return token; | 2492 return token; |
2493 } else { | 2493 } else { |
2494 // innerHTML case | 2494 // innerHTML case |
2495 assert(parser.innerHTMLMode); | 2495 assert(parser.innerHTMLMode); |
2496 parser.parseError(token.span, "undefined-error"); | 2496 parser.parseError(token.span, "undefined-error"); |
2497 } | 2497 } |
2498 return null; | 2498 return null; |
2499 } | 2499 } |
2500 | 2500 |
2501 void endTagIgnore(EndTagToken token) { | 2501 void endTagIgnore(EndTagToken token) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2533 case "body": case "caption": case "col": case "colgroup": case "html": | 2533 case "body": case "caption": case "col": case "colgroup": case "html": |
2534 case "td": case "th": | 2534 case "td": case "th": |
2535 return endTagIgnore(token); | 2535 return endTagIgnore(token); |
2536 default: return endTagOther(token); | 2536 default: return endTagOther(token); |
2537 } | 2537 } |
2538 } | 2538 } |
2539 | 2539 |
2540 // helper methods (XXX unify this with other table helper methods) | 2540 // helper methods (XXX unify this with other table helper methods) |
2541 void clearStackToTableRowContext() { | 2541 void clearStackToTableRowContext() { |
2542 while (true) { | 2542 while (true) { |
2543 var last = tree.openElements.last(); | 2543 var last = tree.openElements.last; |
2544 if (last.tagName == "tr" || last.tagName == "html") break; | 2544 if (last.tagName == "tr" || last.tagName == "html") break; |
2545 | 2545 |
2546 parser.parseError(last.span, "unexpected-implied-end-tag-in-table-row", | 2546 parser.parseError(last.span, "unexpected-implied-end-tag-in-table-row", |
2547 {"name": tree.openElements.last().tagName}); | 2547 {"name": tree.openElements.last.tagName}); |
2548 tree.openElements.removeLast(); | 2548 tree.openElements.removeLast(); |
2549 } | 2549 } |
2550 } | 2550 } |
2551 | 2551 |
2552 bool ignoreEndTagTr() { | 2552 bool ignoreEndTagTr() { |
2553 return !tree.elementInScope("tr", variant: "table"); | 2553 return !tree.elementInScope("tr", variant: "table"); |
2554 } | 2554 } |
2555 | 2555 |
2556 // the rest | 2556 // the rest |
2557 bool processEOF() { | 2557 bool processEOF() { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2682 } | 2682 } |
2683 } | 2683 } |
2684 | 2684 |
2685 Token startTagOther(StartTagToken token) { | 2685 Token startTagOther(StartTagToken token) { |
2686 return parser._inBodyPhase.processStartTag(token); | 2686 return parser._inBodyPhase.processStartTag(token); |
2687 } | 2687 } |
2688 | 2688 |
2689 void endTagTableCell(EndTagToken token) { | 2689 void endTagTableCell(EndTagToken token) { |
2690 if (tree.elementInScope(token.name, variant: "table")) { | 2690 if (tree.elementInScope(token.name, variant: "table")) { |
2691 tree.generateImpliedEndTags(token.name); | 2691 tree.generateImpliedEndTags(token.name); |
2692 if (tree.openElements.last().tagName != token.name) { | 2692 if (tree.openElements.last.tagName != token.name) { |
2693 parser.parseError(token.span, "unexpected-cell-end-tag", | 2693 parser.parseError(token.span, "unexpected-cell-end-tag", |
2694 {"name": token.name}); | 2694 {"name": token.name}); |
2695 popOpenElementsUntil(token.name); | 2695 popOpenElementsUntil(token.name); |
2696 } else { | 2696 } else { |
2697 tree.openElements.removeLast(); | 2697 tree.openElements.removeLast(); |
2698 } | 2698 } |
2699 tree.clearActiveFormattingElements(); | 2699 tree.clearActiveFormattingElements(); |
2700 parser.phase = parser._inRowPhase; | 2700 parser.phase = parser._inRowPhase; |
2701 } else { | 2701 } else { |
2702 parser.parseError(token.span, "unexpected-end-tag", {"name": token.name}); | 2702 parser.parseError(token.span, "unexpected-end-tag", {"name": token.name}); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2742 switch (token.name) { | 2742 switch (token.name) { |
2743 case "option": return endTagOption(token); | 2743 case "option": return endTagOption(token); |
2744 case "optgroup": return endTagOptgroup(token); | 2744 case "optgroup": return endTagOptgroup(token); |
2745 case "select": return endTagSelect(token); | 2745 case "select": return endTagSelect(token); |
2746 default: return endTagOther(token); | 2746 default: return endTagOther(token); |
2747 } | 2747 } |
2748 } | 2748 } |
2749 | 2749 |
2750 // http://www.whatwg.org/specs/web-apps/current-work///in-select | 2750 // http://www.whatwg.org/specs/web-apps/current-work///in-select |
2751 bool processEOF() { | 2751 bool processEOF() { |
2752 var last = tree.openElements.last(); | 2752 var last = tree.openElements.last; |
2753 if (last.tagName != "html") { | 2753 if (last.tagName != "html") { |
2754 parser.parseError(last.span, "eof-in-select"); | 2754 parser.parseError(last.span, "eof-in-select"); |
2755 } else { | 2755 } else { |
2756 assert(parser.innerHTMLMode); | 2756 assert(parser.innerHTMLMode); |
2757 } | 2757 } |
2758 return false; | 2758 return false; |
2759 } | 2759 } |
2760 | 2760 |
2761 Token processCharacters(CharactersToken token) { | 2761 Token processCharacters(CharactersToken token) { |
2762 if (token.data == "\u0000") { | 2762 if (token.data == "\u0000") { |
2763 return null; | 2763 return null; |
2764 } | 2764 } |
2765 tree.insertText(token.data, token.span); | 2765 tree.insertText(token.data, token.span); |
2766 } | 2766 } |
2767 | 2767 |
2768 void startTagOption(StartTagToken token) { | 2768 void startTagOption(StartTagToken token) { |
2769 // We need to imply </option> if <option> is the current node. | 2769 // We need to imply </option> if <option> is the current node. |
2770 if (tree.openElements.last().tagName == "option") { | 2770 if (tree.openElements.last.tagName == "option") { |
2771 tree.openElements.removeLast(); | 2771 tree.openElements.removeLast(); |
2772 } | 2772 } |
2773 tree.insertElement(token); | 2773 tree.insertElement(token); |
2774 } | 2774 } |
2775 | 2775 |
2776 void startTagOptgroup(StartTagToken token) { | 2776 void startTagOptgroup(StartTagToken token) { |
2777 if (tree.openElements.last().tagName == "option") { | 2777 if (tree.openElements.last.tagName == "option") { |
2778 tree.openElements.removeLast(); | 2778 tree.openElements.removeLast(); |
2779 } | 2779 } |
2780 if (tree.openElements.last().tagName == "optgroup") { | 2780 if (tree.openElements.last.tagName == "optgroup") { |
2781 tree.openElements.removeLast(); | 2781 tree.openElements.removeLast(); |
2782 } | 2782 } |
2783 tree.insertElement(token); | 2783 tree.insertElement(token); |
2784 } | 2784 } |
2785 | 2785 |
2786 void startTagSelect(StartTagToken token) { | 2786 void startTagSelect(StartTagToken token) { |
2787 parser.parseError(token.span, "unexpected-select-in-select"); | 2787 parser.parseError(token.span, "unexpected-select-in-select"); |
2788 endTagSelect(new EndTagToken("select", data: {})); | 2788 endTagSelect(new EndTagToken("select", data: {})); |
2789 } | 2789 } |
2790 | 2790 |
(...skipping 10 matching lines...) Expand all Loading... |
2801 Token startTagScript(StartTagToken token) { | 2801 Token startTagScript(StartTagToken token) { |
2802 return parser._inHeadPhase.processStartTag(token); | 2802 return parser._inHeadPhase.processStartTag(token); |
2803 } | 2803 } |
2804 | 2804 |
2805 Token startTagOther(StartTagToken token) { | 2805 Token startTagOther(StartTagToken token) { |
2806 parser.parseError(token.span, "unexpected-start-tag-in-select", | 2806 parser.parseError(token.span, "unexpected-start-tag-in-select", |
2807 {"name": token.name}); | 2807 {"name": token.name}); |
2808 } | 2808 } |
2809 | 2809 |
2810 void endTagOption(EndTagToken token) { | 2810 void endTagOption(EndTagToken token) { |
2811 if (tree.openElements.last().tagName == "option") { | 2811 if (tree.openElements.last.tagName == "option") { |
2812 tree.openElements.removeLast(); | 2812 tree.openElements.removeLast(); |
2813 } else { | 2813 } else { |
2814 parser.parseError(token.span, "unexpected-end-tag-in-select", | 2814 parser.parseError(token.span, "unexpected-end-tag-in-select", |
2815 {"name": "option"}); | 2815 {"name": "option"}); |
2816 } | 2816 } |
2817 } | 2817 } |
2818 | 2818 |
2819 void endTagOptgroup(EndTagToken token) { | 2819 void endTagOptgroup(EndTagToken token) { |
2820 // </optgroup> implicitly closes <option> | 2820 // </optgroup> implicitly closes <option> |
2821 if (tree.openElements.last().tagName == "option" && | 2821 if (tree.openElements.last.tagName == "option" && |
2822 tree.openElements[tree.openElements.length - 2].tagName == "optgroup") { | 2822 tree.openElements[tree.openElements.length - 2].tagName == "optgroup") { |
2823 tree.openElements.removeLast(); | 2823 tree.openElements.removeLast(); |
2824 } | 2824 } |
2825 // It also closes </optgroup> | 2825 // It also closes </optgroup> |
2826 if (tree.openElements.last().tagName == "optgroup") { | 2826 if (tree.openElements.last.tagName == "optgroup") { |
2827 tree.openElements.removeLast(); | 2827 tree.openElements.removeLast(); |
2828 // But nothing else | 2828 // But nothing else |
2829 } else { | 2829 } else { |
2830 parser.parseError(token.span, "unexpected-end-tag-in-select", | 2830 parser.parseError(token.span, "unexpected-end-tag-in-select", |
2831 {"name": "optgroup"}); | 2831 {"name": "optgroup"}); |
2832 } | 2832 } |
2833 } | 2833 } |
2834 | 2834 |
2835 void endTagSelect(EndTagToken token) { | 2835 void endTagSelect(EndTagToken token) { |
2836 if (tree.elementInScope("select", variant: "select")) { | 2836 if (tree.elementInScope("select", variant: "select")) { |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2969 Token processCharacters(CharactersToken token) { | 2969 Token processCharacters(CharactersToken token) { |
2970 if (token.data == "\u0000") { | 2970 if (token.data == "\u0000") { |
2971 token.data = "\uFFFD"; | 2971 token.data = "\uFFFD"; |
2972 } else if (parser.framesetOK && !allWhitespace(token.data)) { | 2972 } else if (parser.framesetOK && !allWhitespace(token.data)) { |
2973 parser.framesetOK = false; | 2973 parser.framesetOK = false; |
2974 } | 2974 } |
2975 super.processCharacters(token); | 2975 super.processCharacters(token); |
2976 } | 2976 } |
2977 | 2977 |
2978 Token processStartTag(StartTagToken token) { | 2978 Token processStartTag(StartTagToken token) { |
2979 var currentNode = tree.openElements.last(); | 2979 var currentNode = tree.openElements.last; |
2980 if (breakoutElements.contains(token.name) || | 2980 if (breakoutElements.contains(token.name) || |
2981 (token.name == "font" && | 2981 (token.name == "font" && |
2982 (token.data.containsKey("color") || | 2982 (token.data.containsKey("color") || |
2983 token.data.containsKey("face") || | 2983 token.data.containsKey("face") || |
2984 token.data.containsKey("size")))) { | 2984 token.data.containsKey("size")))) { |
2985 | 2985 |
2986 parser.parseError(token.span, | 2986 parser.parseError(token.span, |
2987 "unexpected-html-element-in-foreign-content", {'name': token.name}); | 2987 "unexpected-html-element-in-foreign-content", {'name': token.name}); |
2988 while (tree.openElements.last().namespace != | 2988 while (tree.openElements.last.namespace != |
2989 tree.defaultNamespace && | 2989 tree.defaultNamespace && |
2990 !parser.isHTMLIntegrationPoint(tree.openElements.last()) && | 2990 !parser.isHTMLIntegrationPoint(tree.openElements.last) && |
2991 !parser.isMathMLTextIntegrationPoint(tree.openElements.last())) { | 2991 !parser.isMathMLTextIntegrationPoint(tree.openElements.last)) { |
2992 tree.openElements.removeLast(); | 2992 tree.openElements.removeLast(); |
2993 } | 2993 } |
2994 return token; | 2994 return token; |
2995 | 2995 |
2996 } else { | 2996 } else { |
2997 if (currentNode.namespace == Namespaces.mathml) { | 2997 if (currentNode.namespace == Namespaces.mathml) { |
2998 parser.adjustMathMLAttributes(token); | 2998 parser.adjustMathMLAttributes(token); |
2999 } else if (currentNode.namespace == Namespaces.svg) { | 2999 } else if (currentNode.namespace == Namespaces.svg) { |
3000 adjustSVGTagNames(token); | 3000 adjustSVGTagNames(token); |
3001 parser.adjustSVGAttributes(token); | 3001 parser.adjustSVGAttributes(token); |
3002 } | 3002 } |
3003 parser.adjustForeignAttributes(token); | 3003 parser.adjustForeignAttributes(token); |
3004 token.namespace = currentNode.namespace; | 3004 token.namespace = currentNode.namespace; |
3005 tree.insertElement(token); | 3005 tree.insertElement(token); |
3006 if (token.selfClosing) { | 3006 if (token.selfClosing) { |
3007 tree.openElements.removeLast(); | 3007 tree.openElements.removeLast(); |
3008 token.selfClosingAcknowledged = true; | 3008 token.selfClosingAcknowledged = true; |
3009 } | 3009 } |
3010 } | 3010 } |
3011 } | 3011 } |
3012 | 3012 |
3013 Token processEndTag(EndTagToken token) { | 3013 Token processEndTag(EndTagToken token) { |
3014 var nodeIndex = tree.openElements.length - 1; | 3014 var nodeIndex = tree.openElements.length - 1; |
3015 var node = tree.openElements.last(); | 3015 var node = tree.openElements.last; |
3016 if (node.tagName != token.name) { | 3016 if (node.tagName != token.name) { |
3017 parser.parseError(token.span, "unexpected-end-tag", {"name": token.name}); | 3017 parser.parseError(token.span, "unexpected-end-tag", {"name": token.name}); |
3018 } | 3018 } |
3019 | 3019 |
3020 var newToken = null; | 3020 var newToken = null; |
3021 while (true) { | 3021 while (true) { |
3022 if (asciiUpper2Lower(node.tagName) == token.name) { | 3022 if (asciiUpper2Lower(node.tagName) == token.name) { |
3023 //XXX this isn't in the spec but it seems necessary | 3023 //XXX this isn't in the spec but it seems necessary |
3024 if (parser.phase == parser._inTableTextPhase) { | 3024 if (parser.phase == parser._inTableTextPhase) { |
3025 InTableTextPhase inTableText = parser.phase; | 3025 InTableTextPhase inTableText = parser.phase; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3117 } | 3117 } |
3118 | 3118 |
3119 processEndTag(EndTagToken token) { | 3119 processEndTag(EndTagToken token) { |
3120 switch (token.name) { | 3120 switch (token.name) { |
3121 case "frameset": return endTagFrameset(token); | 3121 case "frameset": return endTagFrameset(token); |
3122 default: return endTagOther(token); | 3122 default: return endTagOther(token); |
3123 } | 3123 } |
3124 } | 3124 } |
3125 | 3125 |
3126 bool processEOF() { | 3126 bool processEOF() { |
3127 var last = tree.openElements.last(); | 3127 var last = tree.openElements.last; |
3128 if (last.tagName != "html") { | 3128 if (last.tagName != "html") { |
3129 parser.parseError(last.span, "eof-in-frameset"); | 3129 parser.parseError(last.span, "eof-in-frameset"); |
3130 } else { | 3130 } else { |
3131 assert(parser.innerHTMLMode); | 3131 assert(parser.innerHTMLMode); |
3132 } | 3132 } |
3133 return false; | 3133 return false; |
3134 } | 3134 } |
3135 | 3135 |
3136 Token processCharacters(CharactersToken token) { | 3136 Token processCharacters(CharactersToken token) { |
3137 parser.parseError(token.span, "unexpected-char-in-frameset"); | 3137 parser.parseError(token.span, "unexpected-char-in-frameset"); |
(...skipping 11 matching lines...) Expand all Loading... |
3149 Token startTagNoframes(StartTagToken token) { | 3149 Token startTagNoframes(StartTagToken token) { |
3150 return parser._inBodyPhase.processStartTag(token); | 3150 return parser._inBodyPhase.processStartTag(token); |
3151 } | 3151 } |
3152 | 3152 |
3153 Token startTagOther(StartTagToken token) { | 3153 Token startTagOther(StartTagToken token) { |
3154 parser.parseError(token.span, "unexpected-start-tag-in-frameset", | 3154 parser.parseError(token.span, "unexpected-start-tag-in-frameset", |
3155 {"name": token.name}); | 3155 {"name": token.name}); |
3156 } | 3156 } |
3157 | 3157 |
3158 void endTagFrameset(EndTagToken token) { | 3158 void endTagFrameset(EndTagToken token) { |
3159 if (tree.openElements.last().tagName == "html") { | 3159 if (tree.openElements.last.tagName == "html") { |
3160 // innerHTML case | 3160 // innerHTML case |
3161 parser.parseError(token.span, | 3161 parser.parseError(token.span, |
3162 "unexpected-frameset-in-frameset-innerhtml"); | 3162 "unexpected-frameset-in-frameset-innerhtml"); |
3163 } else { | 3163 } else { |
3164 tree.openElements.removeLast(); | 3164 tree.openElements.removeLast(); |
3165 } | 3165 } |
3166 if (!parser.innerHTMLMode && tree.openElements.last().tagName != "frameset")
{ | 3166 if (!parser.innerHTMLMode && tree.openElements.last.tagName != "frameset") { |
3167 // If we're not in innerHTML mode and the the current node is not a | 3167 // If we're not in innerHTML mode and the the current node is not a |
3168 // "frameset" element (anymore) then switch. | 3168 // "frameset" element (anymore) then switch. |
3169 parser.phase = parser._afterFramesetPhase; | 3169 parser.phase = parser._afterFramesetPhase; |
3170 } | 3170 } |
3171 } | 3171 } |
3172 | 3172 |
3173 void endTagOther(EndTagToken token) { | 3173 void endTagOther(EndTagToken token) { |
3174 parser.parseError(token.span, "unexpected-end-tag-in-frameset", | 3174 parser.parseError(token.span, "unexpected-end-tag-in-frameset", |
3175 {"name": token.name}); | 3175 {"name": token.name}); |
3176 } | 3176 } |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3326 /** | 3326 /** |
3327 * Gets the human readable error message for this error. Does not include | 3327 * Gets the human readable error message for this error. Does not include |
3328 * any source span information, but you can use [span.getLocationMessage] | 3328 * any source span information, but you can use [span.getLocationMessage] |
3329 * if you want to provide a filename prefix, or [toString] if you want | 3329 * if you want to provide a filename prefix, or [toString] if you want |
3330 * "ParseError" to be the prefix. | 3330 * "ParseError" to be the prefix. |
3331 */ | 3331 */ |
3332 String get message => formatStr(errorMessages[errorCode], data); | 3332 String get message => formatStr(errorMessages[errorCode], data); |
3333 | 3333 |
3334 String toString() => span.getLocationMessage('ParseError', message); | 3334 String toString() => span.getLocationMessage('ParseError', message); |
3335 } | 3335 } |
OLD | NEW |