Index: pkg/third_party/html5lib/lib/dom.dart |
diff --git a/pkg/third_party/html5lib/lib/dom.dart b/pkg/third_party/html5lib/lib/dom.dart |
index 12d6647902c3c335b4d51dfce04efde41b30c8a0..b81c1ff64030980f3283ccff0c64be630b23e9b2 100644 |
--- a/pkg/third_party/html5lib/lib/dom.dart |
+++ b/pkg/third_party/html5lib/lib/dom.dart |
@@ -75,9 +75,13 @@ abstract class Node { |
static const int PROCESSING_INSTRUCTION_NODE = 7; |
static const int TEXT_NODE = 3; |
- // TODO(jmesserly): this should be on Element |
- /// The tag name associated with the node. |
- final String tagName; |
+ /// Note: For now we use it to implement the deprecated tagName property. |
+ final String _tagName; |
+ |
+ /// *Deprecated* use [Element.localName] instead. |
+ /// Note: after removal, this will be replaced by a correct version that |
+ /// returns uppercase [as specified](http://dom.spec.whatwg.org/#dom-element-tagname). |
+ @deprecated String get tagName => _tagName; |
/// The parent of the current node (or null for the document node). |
Node parent; |
@@ -104,7 +108,10 @@ abstract class Node { |
LinkedHashMap<dynamic, FileSpan> _attributeSpans; |
LinkedHashMap<dynamic, FileSpan> _attributeValueSpans; |
- Node(this.tagName) { |
+ /// *Deprecated* use [new Element.tag] instead. |
+ @deprecated Node(String tagName) : this._(tagName); |
+ |
+ Node._([this._tagName]) { |
nodes._parent = this; |
} |
@@ -138,7 +145,8 @@ abstract class Node { |
/// name and attributes but with no parent or child nodes. |
Node clone(); |
- String get namespace => null; |
+ /// *Deprecated* use [Element.namespaceUri] instead. |
+ @deprecated String get namespace => null; |
int get nodeType; |
@@ -148,23 +156,31 @@ abstract class Node { |
/// *Deprecated* use [nodeType]. |
@deprecated int get $dom_nodeType => nodeType; |
- String get outerHtml { |
+ /// *Deprecated* use [Element.outerHtml] |
+ @deprecated String get outerHtml => _outerHtml; |
+ |
+ /// *Deprecated* use [Element.innerHtml] |
+ @deprecated String get innerHtml => _innerHtml; |
+ @deprecated set innerHtml(String value) { _innerHtml = value; } |
+ |
+ // http://domparsing.spec.whatwg.org/#extensions-to-the-element-interface |
+ String get _outerHtml { |
var str = new StringBuffer(); |
_addOuterHtml(str); |
return str.toString(); |
} |
- String get innerHtml { |
+ String get _innerHtml { |
var str = new StringBuffer(); |
_addInnerHtml(str); |
return str.toString(); |
} |
- set innerHtml(String value) { |
+ set _innerHtml(String value) { |
nodes.clear(); |
// TODO(jmesserly): should be able to get the same effect by adding the |
// fragment directly. |
- nodes.addAll(parseFragment(value, container: tagName).nodes); |
+ nodes.addAll(parseFragment(value, container: _tagName).nodes); |
} |
// Implemented per: http://dom.spec.whatwg.org/#dom-node-textcontent |
@@ -181,8 +197,6 @@ abstract class Node { |
for (Node child in nodes) child._addOuterHtml(str); |
} |
- String toString() => tagName; |
- |
Node remove() { |
// TODO(jmesserly): is parent == null an error? |
if (parent != null) { |
@@ -216,10 +230,9 @@ abstract class Node { |
/// Return true if the node has children or text. |
bool hasContent() => nodes.length > 0; |
- Pair<String, String> get nameTuple { |
- var ns = namespace != null ? namespace : Namespaces.html; |
- return new Pair(ns, tagName); |
- } |
+ /// *Deprecated* construct a pair using the namespaceUri and the name. |
+ @deprecated Pair<String, String> get nameTuple => |
+ this is Element ? getElementNameTuple(this) : null; |
/// Move all the children of the current node to [newParent]. |
/// This is needed so that trees that don't store text as nodes move the |
@@ -308,7 +321,7 @@ abstract class Node { |
Element _queryType(String tag) { |
for (var node in nodes) { |
if (node is! Element) continue; |
- if (node.tagName == tag) return node; |
+ if (node.localName == tag) return node; |
var result = node._queryType(tag); |
if (result != null) return result; |
} |
@@ -318,7 +331,7 @@ abstract class Node { |
void _queryAllType(String tag, List<Element> results) { |
for (var node in nodes) { |
if (node is! Element) continue; |
- if (node.tagName == tag) results.add(node); |
+ if (node.localName == tag) results.add(node); |
node._queryAllType(tag, results); |
} |
} |
@@ -353,7 +366,7 @@ abstract class Node { |
} |
class Document extends Node { |
- Document() : super(null); |
+ Document() : super._(); |
factory Document.html(String html) => parse(html); |
int get nodeType => Node.DOCUMENT_NODE; |
@@ -363,6 +376,14 @@ class Document extends Node { |
Element get head => documentElement.querySelector('head'); |
Element get body => documentElement.querySelector('body'); |
+ /// Returns a fragment of HTML or XML that represents the element and its |
+ /// contents. |
+ // TODO(jmesserly): this API is not specified in: |
+ // <http://domparsing.spec.whatwg.org/> nor is it in dart:html, instead |
+ // only Element has outerHtml. However it is quite useful. Should we move it |
+ // to dom_parsing, where we keep other custom APIs? |
+ String get outerHtml => _outerHtml; |
+ |
String toString() => "#document"; |
void _addOuterHtml(StringBuffer str) => _addInnerHtml(str); |
@@ -385,10 +406,13 @@ class DocumentFragment extends Document { |
} |
class DocumentType extends Node { |
+ final String name; |
final String publicId; |
final String systemId; |
- DocumentType(String name, this.publicId, this.systemId) : super(name); |
+ DocumentType(String name, this.publicId, this.systemId) |
+ // Note: once Node.tagName is removed, don't pass "name" to super |
+ : name = name, super._(name); |
int get nodeType => Node.DOCUMENT_TYPE_NODE; |
@@ -398,9 +422,9 @@ class DocumentType extends Node { |
// it seems useful, and the parser can handle it, so for now keeping it. |
var pid = publicId != null ? publicId : ''; |
var sid = systemId != null ? systemId : ''; |
- return '<!DOCTYPE $tagName "$pid" "$sid">'; |
+ return '<!DOCTYPE $name "$pid" "$sid">'; |
} else { |
- return '<!DOCTYPE $tagName>'; |
+ return '<!DOCTYPE $name>'; |
} |
} |
@@ -409,13 +433,13 @@ class DocumentType extends Node { |
str.write(toString()); |
} |
- DocumentType clone() => new DocumentType(tagName, publicId, systemId); |
+ DocumentType clone() => new DocumentType(name, publicId, systemId); |
} |
class Text extends Node { |
String data; |
- Text(this.data) : super(null); |
+ Text(this.data) : super._(); |
/// *Deprecated* use [data]. |
@deprecated String get value => data; |
@@ -425,15 +449,7 @@ class Text extends Node { |
String toString() => '"$data"'; |
- void _addOuterHtml(StringBuffer str) { |
- // Don't escape text for certain elements, notably <script>. |
- if (rcdataElements.contains(parent.tagName) || |
- parent.tagName == 'plaintext') { |
- str.write(data); |
- } else { |
- str.write(htmlSerializeEscape(data)); |
- } |
- } |
+ void _addOuterHtml(StringBuffer str) => writeTextNodeAsHtml(str, this); |
Text clone() => new Text(data); |
@@ -442,12 +458,19 @@ class Text extends Node { |
} |
class Element extends Node { |
- final String namespace; |
+ final String namespaceUri; |
- // TODO(jmesserly): deprecate in favor of Element.tag? Or rename? |
- Element(String name, [this.namespace]) : super(name); |
+ @deprecated String get namespace => namespaceUri; |
- Element.tag(String name) : namespace = null, super(name); |
+ /// The [local name](http://dom.spec.whatwg.org/#concept-element-local-name) |
+ /// of this element. |
+ String get localName => _tagName; |
+ |
+ // TODO(jmesserly): deprecate in favor of [Document.createElementNS]. |
+ // However we need every element to have a Document before this can work. |
+ Element(String name, [this.namespaceUri]) : super._(name); |
+ |
+ Element.tag(String name) : namespaceUri = null, super._(name); |
static final _START_TAG_REGEXP = new RegExp('<(\\w+)'); |
@@ -506,25 +529,37 @@ class Element extends Node { |
int get nodeType => Node.ELEMENT_NODE; |
String toString() { |
- if (namespace == null) return "<$tagName>"; |
- return "<${Namespaces.getPrefix(namespace)} $tagName>"; |
+ if (namespaceUri == null) return "<$localName>"; |
+ return "<${Namespaces.getPrefix(namespaceUri)} $localName>"; |
} |
String get text => _getText(this); |
set text(String value) => _setText(this, value); |
+ /// Returns a fragment of HTML or XML that represents the element and its |
+ /// contents. |
+ String get outerHtml => _outerHtml; |
+ |
+ /// Returns a fragment of HTML or XML that represents the element's contents. |
+ /// Can be set, to replace the contents of the element with nodes parsed from |
+ /// the given string. |
+ String get innerHtml => _innerHtml; |
+ // TODO(jmesserly): deprecate in favor of: |
+ // <https://api.dartlang.org/apidocs/channels/stable/#dart-dom-html.Element@id_setInnerHtml> |
+ set innerHtml(String value) { _innerHtml = value; } |
+ |
void _addOuterHtml(StringBuffer str) { |
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#serializing-html-fragments |
// Element is the most complicated one. |
- if (namespace == null || |
- namespace == Namespaces.html || |
- namespace == Namespaces.mathml || |
- namespace == Namespaces.svg) { |
- str.write('<$tagName'); |
+ if (namespaceUri == null || |
+ namespaceUri == Namespaces.html || |
+ namespaceUri == Namespaces.mathml || |
+ namespaceUri == Namespaces.svg) { |
+ str.write('<$localName'); |
} else { |
// TODO(jmesserly): the spec doesn't define "qualified name". |
// I'm not sure if this is correct, but it should parse reasonably. |
- str.write('<${Namespaces.getPrefix(namespace)}:$tagName'); |
+ str.write('<${Namespaces.getPrefix(namespaceUri)}:$localName'); |
} |
if (attributes.length > 0) { |
@@ -538,7 +573,8 @@ class Element extends Node { |
str.write('>'); |
if (nodes.length > 0) { |
- if (tagName == 'pre' || tagName == 'textarea' || tagName == 'listing') { |
+ if (localName == 'pre' || localName == 'textarea' || |
+ localName == 'listing') { |
final first = nodes[0]; |
if (first is Text && first.data.startsWith('\n')) { |
// These nodes will remove a leading \n at parse time, so if we still |
@@ -552,10 +588,10 @@ class Element extends Node { |
// void elements must not have an end tag |
// http://dev.w3.org/html5/markup/syntax.html#void-elements |
- if (!isVoidElement(tagName)) str.write('</$tagName>'); |
+ if (!isVoidElement(localName)) str.write('</$localName>'); |
} |
- Element clone() => new Element(tagName, namespace) |
+ Element clone() => new Element(localName, namespaceUri) |
..attributes = new LinkedHashMap.from(attributes); |
String get id { |
@@ -575,7 +611,7 @@ class Element extends Node { |
class Comment extends Node { |
String data; |
- Comment(this.data) : super(null); |
+ Comment(this.data) : super._(); |
int get nodeType => Node.COMMENT_NODE; |