Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(314)

Unified Diff: treebuilders/base.dart

Issue 10916294: switch html5lib to new pkg layout (Closed) Base URL: https://github.com/dart-lang/html5lib.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tokenizer.dart ('k') | treebuilders/simpletree.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: treebuilders/base.dart
diff --git a/treebuilders/base.dart b/treebuilders/base.dart
deleted file mode 100644
index 9806c5a7cd04f05a69f4b3a5e969504dd90a1293..0000000000000000000000000000000000000000
--- a/treebuilders/base.dart
+++ /dev/null
@@ -1,363 +0,0 @@
-/** Internals to the tree builders. */
-#library('base');
-
-#import('../lib/constants.dart');
-#import('../lib/list_proxy.dart');
-#import('../lib/token.dart');
-#import('../lib/utils.dart');
-#import('simpletree.dart');
-
-// The scope markers are inserted when entering object elements,
-// marquees, table cells, and table captions, and are used to prevent formatting
-// from "leaking" into tables, object elements, and marquees.
-final Node Marker = null;
-
-class ActiveFormattingElements extends ListProxy<Node> {
- ActiveFormattingElements() : super();
-
- void addLast(Node node) => add(node);
- void add(Node node) {
- int equalCount = 0;
- if (node != Marker) {
- for (Node element in reversed(this)) {
- if (element == Marker) {
- break;
- }
- if (_nodesEqual(element, node)) {
- equalCount += 1;
- }
- if (equalCount == 3) {
- removeFromList(this, element);
- break;
- }
- }
- }
- super.add(node);
- }
-}
-
-// TODO(jmesserly): this should exist in corelib...
-bool _mapEquals(Map a, Map b) {
- if (a.length != b.length) return false;
- if (a.length == 0) return true;
-
- for (var keyA in a.getKeys()) {
- var valB = b[keyA];
- if (valB == null && !b.containsKey(keyA)) {
- return false;
- }
-
- if (a[keyA] != valB) {
- return false;
- }
- }
- return true;
-}
-
-
-bool _nodesEqual(Node node1, Node node2) {
- return node1.nameTuple == node2.nameTuple &&
- _mapEquals(node1.attributes, node2.attributes);
-}
-
-/** Basic treebuilder implementation. */
-class TreeBuilder {
- final String defaultNamespace;
-
- Document document;
-
- final List<Node> openElements;
-
- final ActiveFormattingElements activeFormattingElements;
-
- Node headPointer;
-
- Node formPointer;
-
- /**
- * Switch the function used to insert an element from the
- * normal one to the misnested table one and back again
- */
- bool insertFromTable;
-
- TreeBuilder(bool namespaceHTMLElements)
- : defaultNamespace = namespaceHTMLElements ? Namespaces.html : null,
- openElements = <Node>[],
- activeFormattingElements = new ActiveFormattingElements() {
- reset();
- }
-
- void reset() {
- openElements.clear();
- activeFormattingElements.clear();
-
- //XXX - rename these to headElement, formElement
- headPointer = null;
- formPointer = null;
-
- insertFromTable = false;
-
- document = new Document();
- }
-
- bool elementInScope(target, [String variant]) {
- //If we pass a node in we match that. if we pass a string
- //match any node with that name
- bool exactNode = target is Node && target.nameTuple != null;
-
- List listElements1 = scopingElements;
- List listElements2 = const [];
- bool invert = false;
- if (variant != null) {
- switch (variant) {
- case "button":
- listElements2 = const [const Pair(Namespaces.html, "button")];
- break;
- case "list":
- listElements2 = const [const Pair(Namespaces.html, "ol"),
- const Pair(Namespaces.html, "ul")];
- break;
- case "table":
- listElements1 = const [const Pair(Namespaces.html, "html"),
- const Pair(Namespaces.html, "table")];
- break;
- case "select":
- listElements1 = const [const Pair(Namespaces.html, "optgroup"),
- const Pair(Namespaces.html, "option")];
- invert = true;
- break;
- default: assert(false);
- }
- }
-
- for (Node node in reversed(openElements)) {
- if (node.tagName == target && !exactNode ||
- node == target && exactNode) {
- return true;
- } else if (invert !=
- (listElements1.indexOf(node.nameTuple) >= 0 ||
- listElements2.indexOf(node.nameTuple) >= 0)) {
- return false;
- }
- }
-
- assert(false); // We should never reach this point
- }
-
- void reconstructActiveFormattingElements() {
- // Within this algorithm the order of steps described in the
- // specification is not quite the same as the order of steps in the
- // code. It should still do the same though.
-
- // Step 1: stop the algorithm when there's nothing to do.
- if (activeFormattingElements.length == 0) {
- return;
- }
-
- // Step 2 and step 3: we start with the last element. So i is -1.
- int i = activeFormattingElements.length - 1;
- var entry = activeFormattingElements[i];
- if (entry == Marker || openElements.indexOf(entry) >= 0) {
- return;
- }
-
- // Step 6
- while (entry != Marker && openElements.indexOf(entry) == -1) {
- if (i == 0) {
- //This will be reset to 0 below
- i = -1;
- break;
- }
- i -= 1;
- // Step 5: let entry be one earlier in the list.
- entry = activeFormattingElements[i];
- }
-
- while (true) {
- // Step 7
- i += 1;
-
- // Step 8
- entry = activeFormattingElements[i];
- var clone = entry.clone(); // Mainly to get a new copy of the attributes
-
- // Step 9
- var element = insertElement(new StartTagToken(clone.tagName,
- namespace: clone.namespace, data: clone.attributes));
-
- // Step 10
- activeFormattingElements[i] = element;
-
- // Step 11
- if (element == activeFormattingElements.last()) {
- break;
- }
- }
- }
-
- void clearActiveFormattingElements() {
- var entry = activeFormattingElements.removeLast();
- while (activeFormattingElements.length > 0 && entry != Marker) {
- entry = activeFormattingElements.removeLast();
- }
- }
-
- /**
- * Check if an element exists between the end of the active
- * formatting elements and the last marker. If it does, return it, else
- * return null
- */
- Node elementInActiveFormattingElements(String name) {
- for (Node item in reversed(activeFormattingElements)) {
- // Check for Marker first because if it's a Marker it doesn't have a
- // name attribute.
- if (item == Marker) {
- break;
- } else if (item.tagName == name) {
- return item;
- }
- }
- return null;
- }
-
- void insertRoot(Token token) {
- var element = createElement(token);
- openElements.add(element);
- document.$dom_appendChild(element);
- }
-
- void insertDoctype(DoctypeToken token) {
- var doctype = new DocumentType(token.name, token.publicId, token.systemId);
- document.$dom_appendChild(doctype);
- }
-
- void insertComment(Token token, [Node parent]) {
- if (parent == null) {
- parent = openElements.last();
- }
- parent.$dom_appendChild(new Comment(token.data));
- }
-
- /** Create an element but don't insert it anywhere */
- Element createElement(StartTagToken token) {
- var name = token.name;
- var namespace = token.namespace;
- if (namespace == null) namespace = defaultNamespace;
- var element = new Element(name, namespace);
- element.attributes = token.data;
- return element;
- }
-
- Element insertElement(StartTagToken token) {
- if (insertFromTable) return insertElementTable(token);
- return insertElementNormal(token);
- }
-
- Element insertElementNormal(StartTagToken token) {
- var name = token.name;
- var namespace = token.namespace;
- if (namespace == null) namespace = defaultNamespace;
- Element element = new Element(name, namespace);
- element.attributes = token.data;
- openElements.last().$dom_appendChild(element);
- openElements.add(element);
- return element;
- }
-
- Element insertElementTable(token) {
- /** Create an element and insert it into the tree */
- var element = createElement(token);
- if (tableInsertModeElements.indexOf(openElements.last().tagName) == -1) {
- return insertElementNormal(token);
- } else {
- // We should be in the InTable mode. This means we want to do
- // special magic element rearranging
- var nodePos = getTableMisnestedNodePosition();
- if (nodePos[1] == null) {
- nodePos[0].appendChild(element);
- } else {
- nodePos[0].insertBefore(element, nodePos[1]);
- }
- openElements.add(element);
- }
- return element;
- }
-
- /** Insert text data. */
- void insertText(String data, [Node parent]) {
- if (parent == null) parent = openElements.last();
-
- if (!insertFromTable || insertFromTable &&
- tableInsertModeElements.indexOf(openElements.last().tagName) == -1) {
- parent.insertText(data);
- } else {
- // We should be in the InTable mode. This means we want to do
- // special magic element rearranging
- var nodePos = getTableMisnestedNodePosition();
- nodePos[0].insertText(data, nodePos[1]);
- }
- }
-
- /**
- * Get the foster parent element, and sibling to insert before
- * (or null) when inserting a misnested table node
- */
- List getTableMisnestedNodePosition() {
- // The foster parent element is the one which comes before the most
- // recently opened table element
- // XXX - this is really inelegant
- var lastTable = null;
- var fosterParent = null;
- var insertBefore = null;
- for (Node elm in reversed(openElements)) {
- if (elm.tagName == "table") {
- lastTable = elm;
- break;
- }
- }
- if (lastTable != null) {
- // XXX - we should really check that this parent is actually a
- // node here
- if (lastTable.parent != null) {
- fosterParent = lastTable.parent;
- insertBefore = lastTable;
- } else {
- fosterParent = openElements[openElements.indexOf(lastTable) - 1];
- }
- } else {
- fosterParent = openElements[0];
- }
- return [fosterParent, insertBefore];
- }
-
- void generateImpliedEndTags([String exclude]) {
- var name = openElements.last().tagName;
- // XXX td, th and tr are not actually needed
- if (name != exclude && const ["dd", "dt", "li", "option", "optgroup", "p",
- "rp", "rt"].indexOf(name) >= 0) {
- openElements.removeLast();
- // XXX This is not entirely what the specification says. We should
- // investigate it more closely.
- generateImpliedEndTags(exclude);
- }
- }
-
- /** Return the final tree. */
- Document getDocument() => document;
-
- /** Return the final fragment. */
- DocumentFragment getFragment() {
- //XXX assert innerHTML
- var fragment = new DocumentFragment();
- openElements[0].reparentChildren(fragment);
- return fragment;
- }
-
- /**
- * Serialize the subtree of node in the format required by unit tests
- * node - the node from which to start serializing
- */
- String testSerializer(node) {
- throw const NotImplementedException();
- }
-}
« no previous file with comments | « tokenizer.dart ('k') | treebuilders/simpletree.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698