From 00c3ffb7a4ec3cef22b2b30e0a00b5e69988619d Mon Sep 17 00:00:00 2001 From: Junyoung Cho Date: Wed, 31 Jul 2013 17:32:23 +0900 Subject: [PATCH] Add a getter of 'document.head' according to HTML spec. Add a getter and a setter of 'document.title' according to HTML spec. Modify the test file. --- src/components/script/dom/document.rs | 79 ++++++++++++++++++++--- src/components/script/dom/htmldocument.rs | 13 +++- src/components/script/dom/node.rs | 7 ++ src/test/html/test_bindings.html | 2 + src/test/html/test_bindings.js | 5 ++ 5 files changed, 95 insertions(+), 11 deletions(-) diff --git a/src/components/script/dom/document.rs b/src/components/script/dom/document.rs index 7c41a58134f..e338eee5dae 100644 --- a/src/components/script/dom/document.rs +++ b/src/components/script/dom/document.rs @@ -5,12 +5,12 @@ use dom::bindings::codegen::DocumentBinding; use dom::bindings::utils::{DOMString, WrapperCache, ErrorResult, null_string, str}; use dom::bindings::utils::{BindingObject, CacheableWrapper, rust_box, DerivedWrapper}; -use dom::element::{HTMLHtmlElement, HTMLHtmlElementTypeId}; +use dom::element::{HTMLHtmlElement, HTMLTitleElement, HTMLHtmlElementTypeId, HTMLHeadElementTypeId, HTMLTitleElementTypeId}; use dom::event::Event; use dom::htmlcollection::HTMLCollection; use dom::htmldocument::HTMLDocument; use dom::htmlelement::HTMLElement; -use dom::node::{AbstractNode, ScriptView, Node}; +use dom::node::{AbstractNode, ScriptView, Node, ElementNodeTypeId, Text}; use dom::window::Window; use dom::windowproxy::WindowProxy; @@ -274,14 +274,77 @@ impl Document { } pub fn Title(&self) -> DOMString { - str(self.title.clone()) + let mut title = ~""; + match self.doctype { + SVG => { + fail!("no SVG document yet") + }, + _ => { + let _ = for self.root.traverse_preorder |node| { + if node.type_id() != ElementNodeTypeId(HTMLTitleElementTypeId) { + loop; + } + for node.children().advance |child| { + if child.is_text() { + do child.with_imm_text() |text| { + let s = text.parent.Data(); + title = title + s.to_str(); + } + } + } + break; + }; + } + } + let v: ~[&str] = title.word_iter().collect(); + title = v.connect(" "); + title = title.trim().to_owned(); + str(title) } - pub fn SetTitle(&mut self, title: &DOMString, _rv: &mut ErrorResult) { - self.title = match title { - &str(ref s) => s.clone(), - &null_string => ~"" - }; + pub fn SetTitle(&self, title: &DOMString, _rv: &mut ErrorResult) { + match self.doctype { + SVG => { + fail!("no SVG document yet") + }, + _ => { + let (_scope, cx) = self.get_scope_and_cx(); + let _ = for self.root.traverse_preorder |node| { + if node.type_id() != ElementNodeTypeId(HTMLHeadElementTypeId) { + loop; + } + let mut has_title = false; + for node.children().advance |child| { + if child.type_id() != ElementNodeTypeId(HTMLTitleElementTypeId) { + loop; + } + has_title = true; + for child.children().advance |title_child| { + child.remove_child(title_child); + } + let new_text = unsafe { + Node::as_abstract_node(cx, @Text::new(title.to_str())) + }; + child.add_child(new_text); + break; + } + if !has_title { + let new_title = @HTMLTitleElement { + parent: HTMLElement::new(HTMLTitleElementTypeId, ~"title") + }; + let new_title = unsafe { + Node::as_abstract_node(cx, new_title) + }; + let new_text = unsafe { + Node::as_abstract_node(cx, @Text::new(title.to_str())) + }; + new_title.add_child(new_text); + node.add_child(new_title); + } + break; + }; + } + } } pub fn Dir(&self) -> DOMString { diff --git a/src/components/script/dom/htmldocument.rs b/src/components/script/dom/htmldocument.rs index 619390352f8..a102fd8aa81 100644 --- a/src/components/script/dom/htmldocument.rs +++ b/src/components/script/dom/htmldocument.rs @@ -6,9 +6,9 @@ use dom::bindings::codegen::HTMLDocumentBinding; use dom::bindings::utils::{DOMString, ErrorResult, null_string}; use dom::bindings::utils::{CacheableWrapper, BindingObject, WrapperCache}; use dom::document::{AbstractDocument, Document, WrappableDocument, HTML}; -use dom::element::Element; +use dom::element::{Element, HTMLHeadElementTypeId}; use dom::htmlcollection::HTMLCollection; -use dom::node::{AbstractNode, ScriptView}; +use dom::node::{AbstractNode, ScriptView, ElementNodeTypeId}; use dom::window::Window; use js::jsapi::{JSObject, JSContext}; @@ -68,7 +68,14 @@ impl HTMLDocument { } pub fn GetHead(&self) -> Option> { - None + let mut headNode: Option> = None; + let _ = for self.parent.root.traverse_preorder |child| { + if child.type_id() == ElementNodeTypeId(HTMLHeadElementTypeId) { + headNode = Some(child); + break; + } + }; + headNode } pub fn Images(&self) -> @mut HTMLCollection { diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index 6e94d2f8ef0..7bf7e53b7ac 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -349,6 +349,13 @@ impl<'self, View> AbstractNode { self.transmute(f) } + pub fn with_mut_text(self, f: &fn(&mut Text) -> R) -> R { + if !self.is_text() { + fail!(~"node is not text"); + } + self.transmute_mut(f) + } + pub fn is_element(self) -> bool { match self.type_id() { ElementNodeTypeId(*) => true, diff --git a/src/test/html/test_bindings.html b/src/test/html/test_bindings.html index 60744cafcf1..5d9a0be0d3e 100644 --- a/src/test/html/test_bindings.html +++ b/src/test/html/test_bindings.html @@ -2,6 +2,8 @@ + test_binding + page diff --git a/src/test/html/test_bindings.js b/src/test/html/test_bindings.js index 0d62dba7ec4..d50e77b9bbd 100644 --- a/src/test/html/test_bindings.js +++ b/src/test/html/test_bindings.js @@ -96,6 +96,11 @@ window.alert(tags.length); window.alert(tags[0]); window.alert(tags[0].tagName); +window.alert("Document:"); +let head = document.head; +window.alert(head); +window.alert(head.tagName); + window.alert("DOMParser:"); window.alert(DOMParser); let parser = new DOMParser();