diff --git a/data/test/ignore b/data/test/ignore index 7d61a75e..8b137891 100644 --- a/data/test/ignore +++ b/data/test/ignore @@ -1,4 +1 @@ -tb: tests20.dat-34 -tb: tests20.dat-35 -tb: tests20.dat-36 -tb: tests20.dat-37 + diff --git a/src/rcdom.rs b/src/rcdom.rs index 6dbd1ce2..b3ca08f8 100644 --- a/src/rcdom.rs +++ b/src/rcdom.rs @@ -12,6 +12,7 @@ //! This is sufficient as a static parse tree, but don't build a //! web browser using it. :) +use std::ascii::AsciiExt; use std::cell::RefCell; use std::collections::HashSet; use std::default::Default; @@ -32,7 +33,7 @@ use serialize::TraversalScope; use serialize::TraversalScope::{IncludeNode, ChildrenOnly}; use driver::ParseResult; -pub use self::ElementEnum::{Normal, Script, Template}; +pub use self::ElementEnum::{AnnotationXml, Normal, Script, Template}; pub use self::NodeEnum::{Document, Doctype, Text, Comment, Element}; /// The different kinds of elements in the DOM. @@ -45,6 +46,11 @@ pub enum ElementEnum { /// A template element and its template contents. /// https://html.spec.whatwg.org/multipage/#template-contents Template(Handle), + /// An annotation-xml element in the MathML namespace whose start tag token had an attribute + /// with the name "encoding" whose value was an ASCII case-insensitive match for the string + /// "text/html" or "application/xhtml+xml" + /// https://html.spec.whatwg.org/multipage/embedded-content.html#math:annotation-xml + AnnotationXml(bool), } /// The different kinds of nodes in the DOM. @@ -198,6 +204,14 @@ impl TreeSink for RcDom { let info = match name { qualname!(html, "script") => Script(false), qualname!(html, "template") => Template(new_node(Document)), + qualname!(mathml, "annotation-xml") => { + AnnotationXml(attrs.iter().find(|attr| attr.name == qualname!("", "encoding")) + .map_or(false, + |attr| attr.value + .eq_ignore_ascii_case("text/html") || + attr.value + .eq_ignore_ascii_case("application/xhtml+xml"))) + }, _ => Normal, }; new_node(Element(name, info, attrs)) @@ -303,6 +317,13 @@ impl TreeSink for RcDom { panic!("not a script element!"); } } + + fn is_mathml_annotation_xml_integration_point(&self, handle: Self::Handle) -> bool { + match (**handle).borrow().node { + Element(_, AnnotationXml(ret), _) => ret, + _ => unreachable!(), + } + } } impl Default for RcDom { diff --git a/src/tree_builder/actions.rs b/src/tree_builder/actions.rs index 60556a05..8f304c6b 100644 --- a/src/tree_builder/actions.rs +++ b/src/tree_builder/actions.rs @@ -899,13 +899,7 @@ impl TreeBuilderActions } } - if let qualname!(mathml, "annotation-xml") = name { - if let TagToken(Tag { kind: StartTag, name: atom!("svg"), .. }) = *token { - return false; - } - } - - if html_integration_point(name.clone()) { + if svg_html_integration_point(name.clone()) { match *token { CharacterTokens(..) | NullCharacterToken => return false, TagToken(Tag { kind: StartTag, .. }) => return false, @@ -913,6 +907,17 @@ impl TreeBuilderActions } } + if let qualname!(mathml, "annotation-xml") = name { + match *token { + TagToken(Tag { kind: StartTag, name: atom!("svg"), .. }) => return false, + CharacterTokens(..) | NullCharacterToken | + TagToken(Tag { kind: StartTag, .. }) => { + return !self.sink.is_mathml_annotation_xml_integration_point(self.adjusted_current_node()) + } + _ => {} + }; + } + true } //ยง END @@ -1106,7 +1111,7 @@ impl TreeBuilderActions self.pop(); while !self.current_node_in(|n| { n.ns == ns!(html) || mathml_text_integration_point(n.clone()) - || html_integration_point(n) + || svg_html_integration_point(n) }) { self.pop(); } diff --git a/src/tree_builder/interface.rs b/src/tree_builder/interface.rs index 49a28955..e0808ee4 100644 --- a/src/tree_builder/interface.rs +++ b/src/tree_builder/interface.rs @@ -133,6 +133,12 @@ pub trait TreeSink { fn complete_script(&mut self, _node: Self::Handle) -> NextParserState { NextParserState::Continue } + + // Returns true if the adjusted current node is an HTML integration point + // and the token is a start tag + fn is_mathml_annotation_xml_integration_point(&self, handle: Self::Handle) -> bool { + false + } } /// Trace hooks for a garbage-collected DOM. diff --git a/src/tree_builder/tag_sets.rs b/src/tree_builder/tag_sets.rs index 37e6be95..35a4268c 100644 --- a/src/tree_builder/tag_sets.rs +++ b/src/tree_builder/tag_sets.rs @@ -52,7 +52,7 @@ declare_tag_set!(pub html_default_scope = #[inline(always)] pub fn default_scope(name: QualName) -> bool { html_default_scope(name.clone()) || mathml_text_integration_point(name.clone()) || - html_integration_point(name) + svg_html_integration_point(name) } declare_tag_set!(pub list_item_scope = [default_scope] + "ol" "ul"); @@ -87,8 +87,9 @@ pub fn mathml_text_integration_point(p: QualName) -> bool { | qualname!(mathml, "ms") | qualname!(mathml, "mtext")) } -pub fn html_integration_point(p: QualName) -> bool { - // FIXME(#119): HTML integration points in MathML +/// https://html.spec.whatwg.org/multipage/#html-integration-point +pub fn svg_html_integration_point(p: QualName) -> bool { + // annotation-xml are handle in another place matches!(p, qualname!(svg, "foreignObject") | qualname!(svg, "desc") | qualname!(svg, "title")) }