diff --git a/servo/Cargo.lock b/servo/Cargo.lock index b6feed22ff00..564a43c64d94 100644 --- a/servo/Cargo.lock +++ b/servo/Cargo.lock @@ -2110,6 +2110,11 @@ dependencies = [ "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ref_filter_map" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "ref_slice" version = "1.1.0" @@ -2200,6 +2205,7 @@ dependencies = [ "profile_traits 0.0.1", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "range 0.0.1", + "ref_filter_map 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "ref_slice 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.1.76 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3356,6 +3362,7 @@ dependencies = [ "checksum quote 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1e0c9bc6bfb0a60d539aab6e338207c1a5456e62f5bd5375132cee119aa4b3" "checksum rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5" "checksum rayon 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b6a6e05e0e6b703e9f2ad266eb63f3712e693a17a2702b95a23de14ce8defa9" +"checksum ref_filter_map 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b5ceb840e4009da4841ed22a15eb49f64fdd00a2138945c5beacf506b2fb5ed" "checksum ref_slice 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "546bb4aa91c85f232732cc5b3c8097ea97ae9a77304f9ab4df8b203ff7672dad" "checksum regex 0.1.76 (registry+https://github.com/rust-lang/crates.io-index)" = "63b49f873f36ddc838d773972511e5fed2ef7350885af07d58e2f48ce8073dcd" "checksum regex-syntax 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279401017ae31cf4e15344aa3f085d0e2e5c1e70067289ef906906fdbe92c8fd" diff --git a/servo/components/script/Cargo.toml b/servo/components/script/Cargo.toml index 57fd56261951..293c2aefe02f 100644 --- a/servo/components/script/Cargo.toml +++ b/servo/components/script/Cargo.toml @@ -61,6 +61,7 @@ plugins = {path = "../plugins"} profile_traits = {path = "../profile_traits"} rand = "0.3" range = {path = "../range"} +ref_filter_map = "1.0.1" ref_slice = "1.0" regex = "0.1.43" rustc-serialize = "0.3" diff --git a/servo/components/script/dom/attr.rs b/servo/components/script/dom/attr.rs index 2aae65af9206..8b9587c9151f 100644 --- a/servo/components/script/dom/attr.rs +++ b/servo/components/script/dom/attr.rs @@ -81,8 +81,8 @@ impl Attr { } #[inline] - pub fn prefix(&self) -> &Option { - &self.identifier.prefix + pub fn prefix(&self) -> Option<&Prefix> { + self.identifier.prefix.as_ref() } } @@ -153,7 +153,7 @@ impl AttrMethods for Attr { // https://dom.spec.whatwg.org/#dom-attr-prefix fn GetPrefix(&self) -> Option { // FIXME(ajeffrey): convert directly from LocalName to DOMString - self.prefix().as_ref().map(|p| DOMString::from(&**p)) + self.prefix().map(|p| DOMString::from(&**p)) } // https://dom.spec.whatwg.org/#dom-attr-ownerelement diff --git a/servo/components/script/dom/csskeyframesrule.rs b/servo/components/script/dom/csskeyframesrule.rs index f5e322664afe..259819189a9b 100644 --- a/servo/components/script/dom/csskeyframesrule.rs +++ b/servo/components/script/dom/csskeyframesrule.rs @@ -80,7 +80,6 @@ impl CSSKeyframesRuleMethods for CSSKeyframesRule { // https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-appendrule fn AppendRule(&self, rule: DOMString) { - let global = self.global(); let rule = Keyframe::parse(&rule, self.cssrule.parent_stylesheet().style_stylesheet(), ParserContextExtraData::default()); if let Ok(rule) = rule { diff --git a/servo/components/script/dom/document.rs b/servo/components/script/dom/document.rs index 844bc2300436..8b66d2db75d3 100644 --- a/servo/components/script/dom/document.rs +++ b/servo/components/script/dom/document.rs @@ -136,7 +136,7 @@ pub enum TouchEventResult { Forwarded, } -#[derive(JSTraceable, PartialEq, HeapSizeOf)] +#[derive(Clone, Copy, Debug, HeapSizeOf, JSTraceable, PartialEq)] pub enum IsHTMLDocument { HTMLDocument, NonHTMLDocument, diff --git a/servo/components/script/dom/element.rs b/servo/components/script/dom/element.rs index d8f0dd601a71..c384001e33ad 100644 --- a/servo/components/script/dom/element.rs +++ b/servo/components/script/dom/element.rs @@ -30,6 +30,7 @@ use dom::bindings::xmlname::XMLName::InvalidXMLName; use dom::characterdata::CharacterData; use dom::create::create_element; use dom::document::{Document, LayoutDocumentHelpers}; +use dom::documentfragment::DocumentFragment; use dom::domrect::DOMRect; use dom::domrectlist::DOMRectList; use dom::domtokenlist::DOMTokenList; @@ -61,6 +62,7 @@ use dom::node::{CLICK_IN_PROGRESS, ChildrenMutation, LayoutNodeHelpers, Node}; use dom::node::{NodeDamage, SEQUENTIALLY_FOCUSABLE, UnbindContext}; use dom::node::{document_from_node, window_from_node}; use dom::nodelist::NodeList; +use dom::servoparser::ServoParser; use dom::text::Text; use dom::validation::Validatable; use dom::virtualmethods::{VirtualMethods, vtable_for}; @@ -71,6 +73,7 @@ use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode}; use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks}; use html5ever_atoms::{Prefix, LocalName, Namespace, QualName}; use parking_lot::RwLock; +use ref_filter_map::ref_filter_map; use selectors::matching::{ElementFlags, MatchingReason, matches}; use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS}; use selectors::parser::{AttrSelector, NamespaceConstraint}; @@ -712,12 +715,52 @@ impl Element { &self.namespace } - pub fn prefix(&self) -> &Option { - &self.prefix + pub fn prefix(&self) -> Option<&DOMString> { + self.prefix.as_ref() } - pub fn attrs(&self) -> Ref>> { - self.attrs.borrow() + pub fn attrs(&self) -> Ref<[JS]> { + Ref::map(self.attrs.borrow(), |attrs| &**attrs) + } + + // Element branch of https://dom.spec.whatwg.org/#locate-a-namespace + pub fn locate_namespace(&self, prefix: Option) -> Namespace { + let prefix = prefix.map(String::from).map(LocalName::from); + + let inclusive_ancestor_elements = + self.upcast::() + .inclusive_ancestors() + .filter_map(Root::downcast::); + + // Steps 3-4. + for element in inclusive_ancestor_elements { + // Step 1. + if element.namespace() != &ns!() && element.prefix().map(|p| &**p) == prefix.as_ref().map(|p| &**p) { + return element.namespace().clone(); + } + + // Step 2. + let attr = ref_filter_map(self.attrs(), |attrs| { + attrs.iter().find(|attr| { + if attr.namespace() != &ns!(xmlns) { + return false; + } + match (attr.prefix(), prefix.as_ref()) { + (Some(&namespace_prefix!("xmlns")), Some(prefix)) => { + attr.local_name() == prefix + }, + (None, None) => attr.local_name() == &local_name!("xmlns"), + _ => false, + } + }) + }); + + if let Some(attr) = attr { + return (**attr.value()).into(); + } + } + + ns!() } pub fn style_attribute(&self) -> &DOMRefCell>>> { @@ -818,7 +861,7 @@ impl Element { // Step 2. for attr in element.attrs.borrow().iter() { - if *attr.prefix() == Some(namespace_prefix!("xmlns")) && + if attr.prefix() == Some(&namespace_prefix!("xmlns")) && **attr.value() == *namespace { return Some(attr.LocalName()); } @@ -1230,6 +1273,33 @@ impl Element { // Step 11 win.scroll_node(node.to_trusted_node_address(), x, y, behavior); } + + // https://w3c.github.io/DOM-Parsing/#parsing + pub fn parse_fragment(&self, markup: DOMString) -> Fallible> { + // Steps 1-2. + let context_document = document_from_node(self); + // TODO(#11995): XML case. + let new_children = ServoParser::parse_html_fragment(self, markup); + // Step 3. + let fragment = DocumentFragment::new(&context_document); + // Step 4. + for child in new_children { + fragment.upcast::().AppendChild(&child).unwrap(); + } + // Step 5. + Ok(fragment) + } + + pub fn fragment_parsing_context(owner_doc: &Document, element: Option<&Self>) -> Root { + match element { + Some(elem) if elem.local_name() != &local_name!("html") || !elem.html_element_in_html_document() => { + Root::from_ref(elem) + }, + _ => { + Root::upcast(HTMLBodyElement::new(local_name!("body"), None, owner_doc)) + } + } + } } impl ElementMethods for Element { @@ -1757,15 +1827,14 @@ impl ElementMethods for Element { /// https://w3c.github.io/DOM-Parsing/#widl-Element-innerHTML fn SetInnerHTML(&self, value: DOMString) -> ErrorResult { - let context_node = self.upcast::(); // Step 1. - let frag = try!(context_node.parse_fragment(value)); + let frag = try!(self.parse_fragment(value)); // Step 2. // https://github.com/w3c/DOM-Parsing/issues/1 let target = if let Some(template) = self.downcast::() { Root::upcast(template.Content()) } else { - Root::from_ref(context_node) + Root::from_ref(self.upcast()) }; Node::replace_all(Some(frag.upcast()), &target); Ok(()) @@ -1776,7 +1845,7 @@ impl ElementMethods for Element { self.serialize(IncludeNode) } - // https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#widl-Element-outerHTML + // https://w3c.github.io/DOM-Parsing/#dom-element-outerhtml fn SetOuterHTML(&self, value: DOMString) -> ErrorResult { let context_document = document_from_node(self); let context_node = self.upcast::(); @@ -1800,7 +1869,7 @@ impl ElementMethods for Element { ElementCreator::ScriptCreated); Root::upcast(body_elem) }, - _ => context_node.GetParentNode().unwrap() + _ => context_node.GetParentElement().unwrap() }; // Step 5. @@ -1957,14 +2026,11 @@ impl ElementMethods for Element { }; // Step 2. - let context = match context.downcast::() { - Some(elem) if elem.local_name() != &local_name!("html") || - !elem.html_element_in_html_document() => Root::from_ref(elem), - _ => Root::upcast(HTMLBodyElement::new(local_name!("body"), None, &*context.owner_doc())), - }; + let context = Element::fragment_parsing_context( + &context.owner_doc(), context.downcast::()); // Step 3. - let fragment = try!(context.upcast::().parse_fragment(text)); + let fragment = try!(context.parse_fragment(text)); // Step 4. self.insert_adjacent(position, fragment.upcast()).map(|_| ()) diff --git a/servo/components/script/dom/htmlcollection.rs b/servo/components/script/dom/htmlcollection.rs index 71fc6a1ecf16..959265e82e06 100644 --- a/servo/components/script/dom/htmlcollection.rs +++ b/servo/components/script/dom/htmlcollection.rs @@ -151,11 +151,11 @@ impl HTMLCollection { } fn match_element(elem: &Element, qualified_name: &LocalName) -> bool { - match *elem.prefix() { + match elem.prefix() { None => elem.local_name() == qualified_name, - Some(ref prefix) => qualified_name.starts_with(prefix as &str) && - qualified_name.find(":") == Some((prefix as &str).len()) && - qualified_name.ends_with(elem.local_name() as &str), + Some(prefix) => qualified_name.starts_with(&**prefix) && + qualified_name.find(":") == Some(prefix.len()) && + qualified_name.ends_with(&**elem.local_name()), } } diff --git a/servo/components/script/dom/node.rs b/servo/components/script/dom/node.rs index 983e2e8d403a..f08b1480eef5 100644 --- a/servo/components/script/dom/node.rs +++ b/servo/components/script/dom/node.rs @@ -7,8 +7,6 @@ use app_units::Au; use devtools_traits::NodeInfo; use document_loader::DocumentLoader; -use dom::attr::Attr; -use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods; use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods; use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods; @@ -51,7 +49,6 @@ use dom::htmltextareaelement::{HTMLTextAreaElement, LayoutHTMLTextAreaElementHel use dom::nodelist::NodeList; use dom::processinginstruction::ProcessingInstruction; use dom::range::WeakRangeVec; -use dom::servoparser::ServoParser; use dom::svgsvgelement::{SVGSVGElement, LayoutSVGSVGElementHelpers}; use dom::text::Text; use dom::virtualmethods::{VirtualMethods, vtable_for}; @@ -61,7 +58,7 @@ use euclid::rect::Rect; use euclid::size::Size2D; use heapsize::{HeapSizeOf, heap_size_of}; use html5ever::tree_builder::QuirksMode; -use html5ever_atoms::{Prefix, LocalName, Namespace, QualName}; +use html5ever_atoms::{Prefix, Namespace, QualName}; use js::jsapi::{JSContext, JSObject, JSRuntime}; use libc::{self, c_void, uintptr_t}; use msg::constellation_msg::PipelineId; @@ -799,19 +796,6 @@ impl Node { } } - // https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#dfn-concept-parse-fragment - pub fn parse_fragment(&self, markup: DOMString) -> Fallible> { - let context_document = document_from_node(self); - let fragment = DocumentFragment::new(&context_document); - if context_document.is_html_document() { - ServoParser::parse_html_fragment(self.upcast(), markup, fragment.upcast()); - } else { - // FIXME: XML case - unimplemented!(); - } - Ok(fragment) - } - /// Used by `HTMLTableSectionElement::InsertRow` and `HTMLTableRowElement::InsertCell` pub fn insert_cell_or_row(&self, index: i32, get_items: F, new_child: G) -> Fallible> where F: Fn() -> Root, @@ -1752,7 +1736,7 @@ impl Node { local: element.local_name().clone() }; let element = Element::create(name, - element.prefix().as_ref().map(|p| Prefix::from(&**p)), + element.prefix().map(|p| Prefix::from(&**p)), &document, ElementCreator::ScriptCreated); Root::upcast::(element) }, @@ -1782,7 +1766,7 @@ impl Node { attr.value().clone(), attr.name().clone(), attr.namespace().clone(), - attr.prefix().clone()); + attr.prefix().cloned()); } }, _ => () @@ -1825,68 +1809,20 @@ impl Node { // https://dom.spec.whatwg.org/#locate-a-namespace pub fn locate_namespace(node: &Node, prefix: Option) -> Namespace { - fn attr_defines_namespace(attr: &Attr, - defined_prefix: &Option) -> bool { - *attr.namespace() == ns!(xmlns) && - match (attr.prefix(), defined_prefix) { - (&Some(ref attr_prefix), &Some(ref defined_prefix)) => - attr_prefix == &namespace_prefix!("xmlns") && - attr.local_name() == defined_prefix, - (&None, &None) => *attr.local_name() == local_name!("xmlns"), - _ => false - } - } - match node.type_id() { NodeTypeId::Element(_) => { - let element = node.downcast::().unwrap(); - // Step 1. - if *element.namespace() != ns!() && *element.prefix() == prefix { - return element.namespace().clone() - } - - // Even though this is conceptually a namespace prefix, - // in the `xmlns:foo="https://example.net/namespace" declaration - // it is a local name. - // FIXME(ajeffrey): directly convert DOMString to LocalName - let prefix_atom = prefix.as_ref().map(|s| LocalName::from(&**s)); - - // Step 2. - let attrs = element.attrs(); - let namespace_attr = attrs.iter().find(|attr| { - attr_defines_namespace(attr, &prefix_atom) - }); - - // Steps 2.1-2. - if let Some(attr) = namespace_attr { - return namespace_from_domstring(Some(attr.Value())); - } - - match node.GetParentElement() { - // Step 3. - None => ns!(), - // Step 4. - Some(parent) => Node::locate_namespace(parent.upcast(), prefix) - } + node.downcast::().unwrap().locate_namespace(prefix) }, NodeTypeId::Document(_) => { - match node.downcast::().unwrap().GetDocumentElement().r() { - // Step 1. - None => ns!(), - // Step 2. - Some(document_element) => { - Node::locate_namespace(document_element.upcast(), prefix) - } - } + node.downcast::().unwrap() + .GetDocumentElement().as_ref() + .map_or(ns!(), |elem| elem.locate_namespace(prefix)) }, - NodeTypeId::DocumentType => ns!(), - NodeTypeId::DocumentFragment => ns!(), - _ => match node.GetParentElement() { - // Step 1. - None => ns!(), - // Step 2. - Some(parent) => Node::locate_namespace(parent.upcast(), prefix) - } + NodeTypeId::DocumentType | NodeTypeId::DocumentFragment => ns!(), + _ => { + node.GetParentElement().as_ref() + .map_or(ns!(), |elem| elem.locate_namespace(prefix)) + } } } } @@ -2250,7 +2186,7 @@ impl NodeMethods for Node { let element = node.downcast::().unwrap(); let other_element = other.downcast::().unwrap(); (*element.namespace() == *other_element.namespace()) && - (*element.prefix() == *other_element.prefix()) && + (element.prefix() == other_element.prefix()) && (*element.local_name() == *other_element.local_name()) && (element.attrs().len() == other_element.attrs().len()) } diff --git a/servo/components/script/dom/range.rs b/servo/components/script/dom/range.rs index 0a5ab7a66dff..b2507aeab3b0 100644 --- a/servo/components/script/dom/range.rs +++ b/servo/components/script/dom/range.rs @@ -22,7 +22,6 @@ use dom::characterdata::CharacterData; use dom::document::Document; use dom::documentfragment::DocumentFragment; use dom::element::Element; -use dom::htmlbodyelement::HTMLBodyElement; use dom::htmlscriptelement::HTMLScriptElement; use dom::node::{Node, UnbindContext}; use dom::text::Text; @@ -901,6 +900,7 @@ impl RangeMethods for Range { fn CreateContextualFragment(&self, fragment: DOMString) -> Fallible> { // Step 1. let node = self.StartContainer(); + let owner_doc = node.owner_doc(); let element = match node.type_id() { NodeTypeId::Document(_) | NodeTypeId::DocumentFragment => None, NodeTypeId::Element(_) => Some(Root::downcast::(node).unwrap()), @@ -911,15 +911,7 @@ impl RangeMethods for Range { }; // Step 2. - let should_create_body = element.as_ref().map_or(true, |elem| { - let elem = elem.downcast::().unwrap(); - elem.local_name() == &local_name!("html") && elem.html_element_in_html_document() - }); - let element: Root = if should_create_body { - Root::upcast(HTMLBodyElement::new(local_name!("body"), None, &self.StartContainer().owner_doc())) - } else { - Root::upcast(element.unwrap()) - }; + let element = Element::fragment_parsing_context(&owner_doc, element.r()); // Step 3. let fragment_node = try!(element.parse_fragment(fragment)); diff --git a/servo/components/script/dom/servoparser/mod.rs b/servo/components/script/dom/servoparser/mod.rs index ff90674c1d2f..c6f4364925b2 100644 --- a/servo/components/script/dom/servoparser/mod.rs +++ b/servo/components/script/dom/servoparser/mod.rs @@ -14,11 +14,12 @@ use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::document::{Document, DocumentSource, IsHTMLDocument}; +use dom::element::Element; use dom::globalscope::GlobalScope; use dom::htmlformelement::HTMLFormElement; use dom::htmlimageelement::HTMLImageElement; use dom::htmlscriptelement::HTMLScriptElement; -use dom::node::{Node, document_from_node, window_from_node}; +use dom::node::{Node, NodeSiblingIterator}; use encoding::all::UTF_8; use encoding::types::{DecoderTrap, Encoding}; use html5ever::tokenizer::buffer_queue::BufferQueue; @@ -96,17 +97,15 @@ impl ServoParser { } // https://html.spec.whatwg.org/multipage/#parsing-html-fragments - pub fn parse_html_fragment( - context_node: &Node, - input: DOMString, - output: &Node) { - let window = window_from_node(context_node); - let context_document = document_from_node(context_node); + pub fn parse_html_fragment(context: &Element, input: DOMString) -> FragmentParsingResult { + let context_node = context.upcast::(); + let context_document = context_node.owner_doc(); + let window = context_document.window(); let url = context_document.url(); // Step 1. let loader = DocumentLoader::new(&*context_document.loader()); - let document = Document::new(&window, None, Some(url.clone()), + let document = Document::new(window, None, Some(url.clone()), IsHTMLDocument::HTMLDocument, None, None, DocumentSource::FromParser, @@ -134,9 +133,7 @@ impl ServoParser { // Step 14. let root_element = document.GetDocumentElement().expect("no document element"); - for child in root_element.upcast::().children() { - output.AppendChild(&child).unwrap(); - } + FragmentParsingResult { inner: root_element.upcast::().children() } } pub fn parse_xml_document( @@ -349,6 +346,23 @@ impl ServoParser { } } +pub struct FragmentParsingResult { + inner: NodeSiblingIterator, +} + +impl Iterator for FragmentParsingResult { + type Item = Root; + + fn next(&mut self) -> Option> { + let next = match self.inner.next() { + Some(next) => next, + None => return None, + }; + next.remove_self(); + Some(next) + } +} + #[derive(HeapSizeOf, JSTraceable)] #[must_root] enum Tokenizer { diff --git a/servo/components/script/dom/servoparser/xml.rs b/servo/components/script/dom/servoparser/xml.rs index 4f233bd80ec5..9d527ce21d18 100644 --- a/servo/components/script/dom/servoparser/xml.rs +++ b/servo/components/script/dom/servoparser/xml.rs @@ -114,7 +114,7 @@ impl<'a> TreeSink for Sink { let elem = target.downcast::() .expect("tried to get name of non-Element in XML parsing"); QName { - prefix: elem.prefix().as_ref().map_or(namespace_prefix!(""), |p| Prefix::from(&**p)), + prefix: elem.prefix().map_or(namespace_prefix!(""), |p| Prefix::from(&**p)), namespace_url: elem.namespace().clone(), local: elem.local_name().clone(), } diff --git a/servo/components/script/lib.rs b/servo/components/script/lib.rs index 0d726a723af1..cf3aadf16580 100644 --- a/servo/components/script/lib.rs +++ b/servo/components/script/lib.rs @@ -74,6 +74,7 @@ extern crate phf; extern crate profile_traits; extern crate rand; extern crate range; +extern crate ref_filter_map; extern crate ref_slice; extern crate regex; extern crate rustc_serialize; diff --git a/servo/components/script/script_thread.rs b/servo/components/script/script_thread.rs index 140d57ec7547..983d6fc8e368 100644 --- a/servo/components/script/script_thread.rs +++ b/servo/components/script/script_thread.rs @@ -1751,9 +1751,12 @@ impl ScriptThread { Some(incomplete.url.clone())); let is_html_document = match metadata.content_type { + Some(Serde(ContentType(Mime(TopLevel::Application, SubLevel::Ext(ref sub_level), _)))) + if sub_level.ends_with("+xml") => IsHTMLDocument::NonHTMLDocument, + Some(Serde(ContentType(Mime(TopLevel::Application, SubLevel::Xml, _)))) | - Some(Serde(ContentType(Mime(TopLevel::Text, SubLevel::Xml, _)))) => - IsHTMLDocument::NonHTMLDocument, + Some(Serde(ContentType(Mime(TopLevel::Text, SubLevel::Xml, _)))) => IsHTMLDocument::NonHTMLDocument, + _ => IsHTMLDocument::HTMLDocument, }; @@ -1844,17 +1847,7 @@ impl ScriptThread { document.set_https_state(metadata.https_state); - let is_xml = match metadata.content_type { - Some(Serde(ContentType(Mime(TopLevel::Application, SubLevel::Ext(ref sub_level), _)))) - if sub_level.ends_with("+xml") => true, - - Some(Serde(ContentType(Mime(TopLevel::Application, SubLevel::Xml, _)))) | - Some(Serde(ContentType(Mime(TopLevel::Text, SubLevel::Xml, _)))) => true, - - _ => false, - }; - - if is_xml { + if is_html_document == IsHTMLDocument::NonHTMLDocument { ServoParser::parse_xml_document( &document, parse_input,