From 6623c580a37cab63da3b7323b46db5e087c5edf1 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 1 Nov 2013 12:13:30 +0100 Subject: [PATCH] Implement restrictions on the children of Document nodes. --- src/components/script/dom/node.rs | 83 ++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index 43178101e01..e9ab3aa1d4f 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -763,7 +763,88 @@ impl Node { } // Step 6. - // XXX #838 + match parent.type_id() { + DocumentNodeTypeId(_) => { + fn inclusively_followed_by_doctype(child: Option>) -> bool{ + match child { + Some(child) if child.is_doctype() => true, + Some(child) => { + let mut iter = child; + loop { + match iter.next_sibling() { + Some(sibling) => { + if sibling.is_doctype() { + return true; + } + iter = sibling; + }, + None => return false, + } + } + }, + None => false, + } + } + + match node.type_id() { + // Step 6.1 + DocumentFragmentNodeTypeId => { + // Step 6.1.1(b) + if node.children().any(|c| c.is_text()) { + return Err(HierarchyRequest); + } + match node.children().count(|c| c.is_element()) { + 0 => (), + // Step 6.1.2 + 1 => { + if parent.children().any(|c| c.is_element()) { + return Err(HierarchyRequest); + } + if inclusively_followed_by_doctype(child) { + return Err(HierarchyRequest); + } + }, + // Step 6.1.1(a) + _ => return Err(HierarchyRequest), + } + }, + // Step 6.2 + ElementNodeTypeId(_) => { + if parent.children().any(|c| c.is_element()) { + return Err(HierarchyRequest); + } + if inclusively_followed_by_doctype(child) { + return Err(HierarchyRequest); + } + }, + // Step 6.3 + DoctypeNodeTypeId => { + if parent.children().any(|c| c.is_doctype()) { + return Err(HierarchyRequest); + } + match child { + Some(child) => { + if parent.children() + .take_while(|&c| c != child) + .any(|c| c.is_element()) { + return Err(HierarchyRequest); + } + }, + None => { + if parent.children().any(|c| c.is_element()) { + return Err(HierarchyRequest); + } + }, + } + }, + TextNodeTypeId | + // ProcessingInstructionNodeTypeId | + CommentNodeTypeId => (), + DocumentNodeTypeId(_) => unreachable!(), + } + }, + _ => (), + } // Step 7-8. let referenceChild = if child != Some(node) {