diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index fb85cdb980b..9f443e1aaaf 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -155,6 +155,9 @@ pub struct Document { reflow_timeout: Cell>, /// The cached first `base` element with an `href` attribute. base_element: MutNullableHeap>, + /// This field is set to the document itself for inert documents. + /// https://html.spec.whatwg.org/multipage/#appropriate-template-contents-owner-document + appropriate_template_contents_owner_document: MutNullableHeap>, } impl PartialEq for Document { @@ -1058,6 +1061,7 @@ impl Document { current_parser: Default::default(), reflow_timeout: Cell::new(None), base_element: Default::default(), + appropriate_template_contents_owner_document: Default::default(), } } @@ -1106,6 +1110,23 @@ impl Document { .and_then(HTMLHtmlElementCast::to_ref) .map(Root::from_ref) } + + /// https://html.spec.whatwg.org/multipage/#appropriate-template-contents-owner-document + pub fn appropriate_template_contents_owner_document(&self) -> Root { + self.appropriate_template_contents_owner_document.or_init(|| { + let doctype = if self.is_html_document { + IsHTMLDocument::HTMLDocument + } else { + IsHTMLDocument::NonHTMLDocument + }; + let new_doc = Document::new( + &*self.window(), None, doctype, None, None, + DocumentSource::NotFromParser, DocumentLoader::new(&self.loader())); + new_doc.appropriate_template_contents_owner_document.set( + Some(JS::from_ref(&*new_doc))); + new_doc + }) + } } diff --git a/components/script/dom/htmltemplateelement.rs b/components/script/dom/htmltemplateelement.rs index 86e69b31a64..e18166c8074 100644 --- a/components/script/dom/htmltemplateelement.rs +++ b/components/script/dom/htmltemplateelement.rs @@ -2,19 +2,25 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use dom::bindings::codegen::Bindings::HTMLTemplateElementBinding; +use dom::bindings::codegen::Bindings::HTMLTemplateElementBinding::HTMLTemplateElementMethods; use dom::bindings::codegen::InheritTypes::HTMLTemplateElementDerived; -use dom::bindings::js::Root; +use dom::bindings::js::{JS, MutNullableHeap, Root}; use dom::document::Document; +use dom::documentfragment::DocumentFragment; use dom::element::ElementTypeId; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::htmlelement::{HTMLElement, HTMLElementTypeId}; -use dom::node::{Node, NodeTypeId}; +use dom::node::{Node, NodeTypeId, document_from_node}; use util::str::DOMString; #[dom_struct] pub struct HTMLTemplateElement { htmlelement: HTMLElement, + + /// https://html.spec.whatwg.org/multipage/#template-contents + contents: MutNullableHeap>, } impl HTMLTemplateElementDerived for EventTarget { @@ -31,7 +37,8 @@ impl HTMLTemplateElement { document: &Document) -> HTMLTemplateElement { HTMLTemplateElement { htmlelement: - HTMLElement::new_inherited(HTMLElementTypeId::HTMLTemplateElement, localName, prefix, document) + HTMLElement::new_inherited(HTMLElementTypeId::HTMLTemplateElement, localName, prefix, document), + contents: MutNullableHeap::new(None), } } @@ -43,3 +50,13 @@ impl HTMLTemplateElement { Node::reflect_node(box element, document, HTMLTemplateElementBinding::Wrap) } } + +impl HTMLTemplateElementMethods for HTMLTemplateElement { + /// https://html.spec.whatwg.org/multipage/#dom-template-content + fn Content(&self) -> Root { + self.contents.or_init(|| { + let doc = document_from_node(self); + doc.appropriate_template_contents_owner_document().CreateDocumentFragment() + }) + } +} diff --git a/components/script/dom/webidls/HTMLTemplateElement.webidl b/components/script/dom/webidls/HTMLTemplateElement.webidl index 66a1dd6ef62..fc497ea9f15 100644 --- a/components/script/dom/webidls/HTMLTemplateElement.webidl +++ b/components/script/dom/webidls/HTMLTemplateElement.webidl @@ -5,5 +5,5 @@ // https://www.whatwg.org/html/#htmltemplateelement interface HTMLTemplateElement : HTMLElement { - //readonly attribute DocumentFragment content; + readonly attribute DocumentFragment content; }; diff --git a/components/script/parse/html.rs b/components/script/parse/html.rs index a2dd0109ed1..d7e1535e487 100644 --- a/components/script/parse/html.rs +++ b/components/script/parse/html.rs @@ -6,11 +6,12 @@ use document_loader::DocumentLoader; use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; +use dom::bindings::codegen::Bindings::HTMLTemplateElementBinding::HTMLTemplateElementMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; -use dom::bindings::codegen::InheritTypes::ProcessingInstructionCast; use dom::bindings::codegen::InheritTypes::{CharacterDataCast, DocumentTypeCast}; -use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLScriptElementCast}; -use dom::bindings::codegen::InheritTypes::{HTMLFormElementDerived, NodeCast}; +use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLFormElementDerived}; +use dom::bindings::codegen::InheritTypes::{HTMLScriptElementCast, HTMLTemplateElementCast}; +use dom::bindings::codegen::InheritTypes::{NodeCast, ProcessingInstructionCast}; use dom::bindings::js::{JS, Root}; use dom::bindings::js::{RootedReference}; use dom::characterdata::CharacterDataTypeId; @@ -43,12 +44,20 @@ use util::str::DOMString; impl<'a> TreeSink for servohtmlparser::Sink { type Handle = JS; + fn get_document(&mut self) -> JS { let doc = self.document.root(); let node = NodeCast::from_ref(doc.r()); JS::from_ref(node) } + fn get_template_contents(&self, target: JS) -> JS { + let target = target.root(); + let template = HTMLTemplateElementCast::to_ref(&*target) + .expect("tried to get template contents of non-HTMLTemplateElement in HTML parsing"); + JS::from_ref(NodeCast::from_ref(&*template.Content())) + } + fn same_node(&self, x: JS, y: JS) -> bool { x == y } diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index b29e113ceae..57c0f95c4d7 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -750,7 +750,7 @@ dependencies = [ [[package]] name = "html5ever" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "html5ever_macros 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1375,7 +1375,7 @@ dependencies = [ "encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "html5ever 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "html5ever 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "js 0.1.0 (git+https://github.com/servo/rust-mozjs)", @@ -1718,7 +1718,7 @@ dependencies = [ "cssparser 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "html5ever 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "html5ever 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "js 0.1.0 (git+https://github.com/servo/rust-mozjs)", diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index e5c8682377c..58aec2d174b 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -735,7 +735,7 @@ dependencies = [ [[package]] name = "html5ever" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "html5ever_macros 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1345,7 +1345,7 @@ dependencies = [ "encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "html5ever 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "html5ever 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "js 0.1.0 (git+https://github.com/servo/rust-mozjs)", @@ -1699,7 +1699,7 @@ dependencies = [ "cssparser 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "html5ever 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "html5ever 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "js 0.1.0 (git+https://github.com/servo/rust-mozjs)", diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock index 18697ebb98f..1d4b264cb9e 100644 --- a/ports/gonk/Cargo.lock +++ b/ports/gonk/Cargo.lock @@ -619,7 +619,7 @@ dependencies = [ [[package]] name = "html5ever" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "html5ever_macros 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1211,7 +1211,7 @@ dependencies = [ "encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "html5ever 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "html5ever 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "js 0.1.0 (git+https://github.com/servo/rust-mozjs)", @@ -1534,7 +1534,7 @@ dependencies = [ "cssparser 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "html5ever 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "html5ever 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)", "js 0.1.0 (git+https://github.com/servo/rust-mozjs)", diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index 080c6d4e7d5..d8df33b0711 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -6333,9 +6333,6 @@ [HTMLTemplateElement interface: existence and properties of interface object] expected: FAIL - [HTMLTemplateElement interface: attribute content] - expected: FAIL - [HTMLCanvasElement interface: existence and properties of interface object] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini index 6dedfeadca1..7748cf097bb 100644 --- a/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini +++ b/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini @@ -267,3 +267,6 @@ [] expected: FAIL + [] + expected: FAIL + diff --git a/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/template-clone-children.html.ini b/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/template-clone-children.html.ini index 813c256bd5e..2901b20f25f 100644 --- a/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/template-clone-children.html.ini +++ b/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/template-clone-children.html.ini @@ -3,9 +3,3 @@ [Clone template node. Test call to cloneNode(true)] expected: FAIL - [Clone template node. Test call to cloneNode() with the default parameter (false by default)] - expected: FAIL - - [Clone template node. Test call to cloneNode(false)] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/templates-copy-document-owner.html.ini b/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/templates-copy-document-owner.html.ini index 63a48a34573..60fb06a98d4 100644 --- a/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/templates-copy-document-owner.html.ini +++ b/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/templates-copy-document-owner.html.ini @@ -1,3 +1,17 @@ [templates-copy-document-owner.html] type: testharness - expected: CRASH + [ownerDocument of cloned template content is set to template content owner. Test cloning with children] + expected: FAIL + + [ownerDocument of cloned template content is set to template content owner. Test cloning without children] + expected: FAIL + + [ownerDocument of cloned template content is set to template content owner. Test cloneNode() with no arguments (false by default)] + expected: FAIL + + [ownerDocument of cloned template content is set to template content owner. Test cloning nested template] + expected: FAIL + + [ownerDocument of cloned template content is set to template content owner. Test loading HTML document from file] + expected: FAIL + diff --git a/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-001.html.ini b/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-001.html.ini deleted file mode 100644 index 7885c2bf8b6..00000000000 --- a/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-001.html.ini +++ /dev/null @@ -1,8 +0,0 @@ -[template-contents-owner-test-001.html] - type: testharness - [Test the template contents owner document when enclosing document has no browsing content. Template element is created by createElement()] - expected: FAIL - - [Test the template contents owner document when enclosing document has no browsing content. Template element is created by innerHTML] - expected: FAIL - diff --git a/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/definitions/template-contents.html.ini b/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/definitions/template-contents.html.ini index d3aad41ed24..aa1e06b4138 100644 --- a/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/definitions/template-contents.html.ini +++ b/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/definitions/template-contents.html.ini @@ -1,3 +1,17 @@ [template-contents.html] type: testharness - expected: CRASH + [The template contents must be a DocumentFragment (nested template containing a text node)] + expected: FAIL + + [The template contents must be a DocumentFragment (the empty template tag inside HTML file loaded in iframe)] + expected: FAIL + + [The template contents must be a DocumentFragment (non empty template tag inside HTML file loaded in iframe)] + expected: FAIL + + [The template contents must be a DocumentFragment (the template tag with some text inside HTML file loaded in iframe)] + expected: FAIL + + [The template contents must be a DocumentFragment (the template tag with nested template tag inside HTML file loaded in iframe)] + expected: FAIL + diff --git a/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/template-element/content-attribute.html.ini b/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/template-element/content-attribute.html.ini index f1120d234a7..5a2af5e1653 100644 --- a/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/template-element/content-attribute.html.ini +++ b/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/template-element/content-attribute.html.ini @@ -1,20 +1,5 @@ [content-attribute.html] type: testharness - [Content attribute of template element is read-only. Test empty template] - expected: FAIL - - [Content attribute of template element is read-only. Test not empty template populated by appendchild()] - expected: FAIL - - [Content attribute of template element is read-only. Test not empty template populated by innerHTML] - expected: FAIL - - [Content attribute of template element is read-only. Test that custom content attribute named 'content' doesn't make content IDL attribute writable] - expected: FAIL - - [Content attribute of template element is read-only. Test that custom content attribute named 'content' doesn't affect content IDL attribute] - expected: FAIL - [Content attribute of template element is read-only. Text value of content attribute of template tag should be ignored, when loading document from a file] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/template-element/node-document-changes.html.ini b/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/template-element/node-document-changes.html.ini index c610f76fff4..b5f147962e2 100644 --- a/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/template-element/node-document-changes.html.ini +++ b/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/template-element/node-document-changes.html.ini @@ -1,3 +1,20 @@ [node-document-changes.html] type: testharness - expected: CRASH + [Changing of template element's node document. Test that ownerDocument of an empty template and its content changes] + expected: FAIL + + [Changing of template element's node document. Test that ownerDocument of a not empty template and its content changes] + expected: FAIL + + [Changing of template element's node document. Test that ownerDocument of nested template and its content changes] + expected: FAIL + + [Changing of template element's node document. Test document loaded from a file] + expected: FAIL + + [Changing of template element's node document. Adobt template element into a document that has a browsing context] + expected: FAIL + + [Changing of template element's node document. Test the case when both old and new owner documents of template element have browsing context] + expected: FAIL + diff --git a/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/template-element/template-content-node-document.html.ini b/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/template-element/template-content-node-document.html.ini index 5f8b37bcbb8..ac620e1efbd 100644 --- a/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/template-element/template-content-node-document.html.ini +++ b/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/template-element/template-content-node-document.html.ini @@ -1,3 +1,5 @@ [template-content-node-document.html] type: testharness - expected: CRASH + [Node document of the template content attribute must be template contents owner. Load HTML file with multiple template elements] + expected: FAIL + diff --git a/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/template-element/template-content.html.ini b/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/template-element/template-content.html.ini deleted file mode 100644 index 77e6aa44d9c..00000000000 --- a/tests/wpt/metadata/html/semantics/scripting-1/the-template-element/template-element/template-content.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[template-content.html] - type: testharness - expected: TIMEOUT