diff options
author | Ms2ger <ms2ger@gmail.com> | 2013-10-08 21:12:02 +0200 |
---|---|---|
committer | Ms2ger <ms2ger@gmail.com> | 2013-10-10 10:57:38 +0200 |
commit | 04319fdb684e37bcb29cad7e096da2298dc027a5 (patch) | |
tree | 27f8d1465fa5557e1e12f933edbb36246c732d92 | |
parent | 59d2d345c82974d686692d16570828046866488a (diff) | |
download | servo-04319fdb684e37bcb29cad7e096da2298dc027a5.tar.gz servo-04319fdb684e37bcb29cad7e096da2298dc027a5.zip |
Issue #888 - Node's owner document should never be None.
-rw-r--r-- | src/components/script/dom/bindings/codegen/Bindings.conf | 3 | ||||
-rw-r--r-- | src/components/script/dom/characterdata.rs | 5 | ||||
-rw-r--r-- | src/components/script/dom/comment.rs | 7 | ||||
-rw-r--r-- | src/components/script/dom/document.rs | 32 | ||||
-rw-r--r-- | src/components/script/dom/documenttype.rs | 6 | ||||
-rw-r--r-- | src/components/script/dom/domparser.rs | 2 | ||||
-rw-r--r-- | src/components/script/dom/element.rs | 18 | ||||
-rw-r--r-- | src/components/script/dom/htmldatalistelement.rs | 2 | ||||
-rw-r--r-- | src/components/script/dom/htmlelement.rs | 5 | ||||
-rw-r--r-- | src/components/script/dom/htmlfieldsetelement.rs | 2 | ||||
-rw-r--r-- | src/components/script/dom/htmlformelement.rs | 2 | ||||
-rw-r--r-- | src/components/script/dom/htmlimageelement.rs | 58 | ||||
-rw-r--r-- | src/components/script/dom/htmlmapelement.rs | 2 | ||||
-rw-r--r-- | src/components/script/dom/htmlmediaelement.rs | 5 | ||||
-rw-r--r-- | src/components/script/dom/node.rs | 90 | ||||
-rw-r--r-- | src/components/script/dom/text.rs | 7 | ||||
-rw-r--r-- | src/components/script/html/hubbub_html_parser.rs | 23 | ||||
-rw-r--r-- | src/components/script/script_task.rs | 10 |
18 files changed, 144 insertions, 135 deletions
diff --git a/src/components/script/dom/bindings/codegen/Bindings.conf b/src/components/script/dom/bindings/codegen/Bindings.conf index 9d55b8e6038..5d50be2ecd0 100644 --- a/src/components/script/dom/bindings/codegen/Bindings.conf +++ b/src/components/script/dom/bindings/codegen/Bindings.conf @@ -143,7 +143,8 @@ DOMInterfaces = { 'Document': { 'nativeType': 'AbstractDocument', 'pointerType': '', - 'customTrace': 'trace' + 'customTrace': 'trace', + 'needsAbstract': ['title', 'createElement', 'createTextNode'], }, 'DOMParser': { diff --git a/src/components/script/dom/characterdata.rs b/src/components/script/dom/characterdata.rs index 42340e4bff3..b1953dbaaae 100644 --- a/src/components/script/dom/characterdata.rs +++ b/src/components/script/dom/characterdata.rs @@ -6,6 +6,7 @@ use dom::bindings::utils::{DOMString, ErrorResult, Fallible}; use dom::bindings::utils::{BindingObject, Reflectable, Reflector}; +use dom::document::AbstractDocument; use dom::node::{Node, NodeTypeId, ScriptView}; use js::jsapi::{JSObject, JSContext}; @@ -15,9 +16,9 @@ pub struct CharacterData { } impl CharacterData { - pub fn new(id: NodeTypeId, data: ~str) -> CharacterData { + pub fn new(id: NodeTypeId, data: ~str, document: AbstractDocument) -> CharacterData { CharacterData { - node: Node::new(id), + node: Node::new(id, document), data: data } } diff --git a/src/components/script/dom/comment.rs b/src/components/script/dom/comment.rs index 89b18bf8422..51140177f95 100644 --- a/src/components/script/dom/comment.rs +++ b/src/components/script/dom/comment.rs @@ -4,6 +4,7 @@ use dom::bindings::utils::{DOMString, Fallible, null_str_as_empty}; use dom::characterdata::CharacterData; +use dom::document::AbstractDocument; use dom::node::{AbstractNode, ScriptView, CommentNodeTypeId, Node}; use dom::window::Window; @@ -14,16 +15,16 @@ pub struct Comment { impl Comment { /// Creates a new HTML comment. - pub fn new(text: ~str) -> Comment { + pub fn new(text: ~str, document: AbstractDocument) -> Comment { Comment { - element: CharacterData::new(CommentNodeTypeId, text) + element: CharacterData::new(CommentNodeTypeId, text, document) } } pub fn Constructor(owner: @mut Window, data: &DOMString) -> Fallible<AbstractNode<ScriptView>> { let s = null_str_as_empty(data); let cx = (*owner.page).js_info.get_ref().js_compartment.cx.ptr; - let comment = @Comment::new(s); + let comment = @Comment::new(s, owner.Document()); Ok(unsafe { Node::as_abstract_node(cx, comment) }) } } diff --git a/src/components/script/dom/document.rs b/src/components/script/dom/document.rs index 851b219a573..0d928282d92 100644 --- a/src/components/script/dom/document.rs +++ b/src/components/script/dom/document.rs @@ -77,9 +77,21 @@ impl AbstractDocument { } } + pub fn from_box<T>(ptr: *mut Box<T>) -> AbstractDocument { + AbstractDocument { + document: ptr as *Document + } + } + pub fn set_root(&self, root: AbstractNode<ScriptView>) { + assert!(root.traverse_preorder().all(|node| { + do node.with_base |node| { + node.owner_doc == *self + } + })); self.with_mut_base(|document| { document.root = Some(root); + document.content_changed(); }); } } @@ -116,7 +128,7 @@ impl Document { let document = AbstractDocument::as_abstract(cx, @mut Document::new(None, XML)); let root = @HTMLHtmlElement { - htmlelement: HTMLElement::new(HTMLHtmlElementTypeId, ~"html") + htmlelement: HTMLElement::new(HTMLHtmlElementTypeId, ~"html", document) }; let root = unsafe { Node::as_abstract_node(cx, root) }; document.set_root(root); @@ -248,23 +260,23 @@ impl Document { None } - pub fn CreateElement(&self, local_name: &DOMString) -> Fallible<AbstractNode<ScriptView>> { + pub fn CreateElement(&self, abstract_self: AbstractDocument, local_name: &DOMString) -> Fallible<AbstractNode<ScriptView>> { let cx = self.get_cx(); let local_name = null_str_as_empty(local_name); if !is_valid_element_name(local_name) { return Err(InvalidCharacter); } let local_name = local_name.to_ascii_lower(); - Ok(build_element_from_tag(cx, local_name)) + Ok(build_element_from_tag(cx, local_name, abstract_self)) } pub fn CreateElementNS(&self, _namespace: &DOMString, _qualified_name: &DOMString) -> Fallible<AbstractNode<ScriptView>> { fail!("stub") } - pub fn CreateTextNode(&self, data: &DOMString) -> AbstractNode<ScriptView> { + pub fn CreateTextNode(&self, abstract_self: AbstractDocument, data: &DOMString) -> AbstractNode<ScriptView> { let cx = self.get_cx(); - let text = @Text::new(null_str_as_empty(data)); + let text = @Text::new(null_str_as_empty(data), abstract_self); unsafe { Node::as_abstract_node(cx, text) } } @@ -288,7 +300,7 @@ impl Document { None } - pub fn Title(&self) -> DOMString { + pub fn Title(&self, _: AbstractDocument) -> DOMString { let mut title = ~""; match self.doctype { SVG => { @@ -322,7 +334,7 @@ impl Document { Some(title) } - pub fn SetTitle(&self, title: &DOMString) -> ErrorResult { + pub fn SetTitle(&self, abstract_self: AbstractDocument, title: &DOMString) -> ErrorResult { match self.doctype { SVG => { fail!("no SVG document yet") @@ -345,17 +357,17 @@ impl Document { for title_child in child.children() { child.remove_child(title_child); } - child.add_child(self.CreateTextNode(title)); + child.add_child(self.CreateTextNode(abstract_self, title)); break; } if !has_title { let new_title = @HTMLTitleElement { - htmlelement: HTMLElement::new(HTMLTitleElementTypeId, ~"title") + htmlelement: HTMLElement::new(HTMLTitleElementTypeId, ~"title", abstract_self) }; let new_title = unsafe { Node::as_abstract_node(cx, new_title) }; - new_title.add_child(self.CreateTextNode(title)); + new_title.add_child(self.CreateTextNode(abstract_self, title)); node.add_child(new_title); } break; diff --git a/src/components/script/dom/documenttype.rs b/src/components/script/dom/documenttype.rs index d1f38b75039..976d6e9dd09 100644 --- a/src/components/script/dom/documenttype.rs +++ b/src/components/script/dom/documenttype.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::utils::DOMString; +use dom::document::AbstractDocument; use dom::node::{ScriptView, Node, DoctypeNodeTypeId}; /// The `DOCTYPE` tag. @@ -19,10 +20,11 @@ impl DocumentType<ScriptView> { pub fn new(name: ~str, public_id: Option<~str>, system_id: Option<~str>, - force_quirks: bool) + force_quirks: bool, + document: AbstractDocument) -> DocumentType<ScriptView> { DocumentType { - node: Node::new(DoctypeNodeTypeId), + node: Node::new(DoctypeNodeTypeId, document), name: name, public_id: public_id, system_id: system_id, diff --git a/src/components/script/dom/domparser.rs b/src/components/script/dom/domparser.rs index 3c317d09437..749e1cea002 100644 --- a/src/components/script/dom/domparser.rs +++ b/src/components/script/dom/domparser.rs @@ -54,7 +54,7 @@ impl DOMParser { }; let root = @HTMLHtmlElement { - htmlelement: HTMLElement::new(HTMLHtmlElementTypeId, ~"html") + htmlelement: HTMLElement::new(HTMLHtmlElementTypeId, ~"html", document) }; let root = unsafe { Node::as_abstract_node(cx, root) }; document.set_root(root); diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index deb99f1fd26..b1ea94914e1 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -9,6 +9,7 @@ use dom::bindings::utils::{null_str_as_empty, null_str_as_empty_ref}; use dom::htmlcollection::HTMLCollection; use dom::clientrect::ClientRect; use dom::clientrectlist::ClientRectList; +use dom::document::AbstractDocument; use dom::node::{ElementNodeTypeId, Node, ScriptView, AbstractNode}; use layout_interface::{ContentBoxQuery, ContentBoxResponse, ContentBoxesQuery}; use layout_interface::{ContentBoxesResponse}; @@ -119,9 +120,9 @@ pub enum ElementTypeId { // impl<'self> Element { - pub fn new(type_id: ElementTypeId, tag_name: ~str) -> Element { + pub fn new(type_id: ElementTypeId, tag_name: ~str, document: AbstractDocument) -> Element { Element { - node: Node::new(ElementNodeTypeId(type_id)), + node: Node::new(ElementNodeTypeId(type_id), document), tag_name: tag_name, attrs: ~[], style_attribute: None, @@ -181,14 +182,15 @@ impl<'self> Element { _ => () } - match self.node.owner_doc { - Some(owner) => do owner.with_base |owner| { owner.content_changed() }, - None => {} + if abstract_self.is_in_doc() { + do self.node.owner_doc.with_base |owner| { + owner.content_changed(); + } } } fn get_scope_and_cx(&self) -> (*JSObject, *JSContext) { - let doc = self.node.owner_doc.unwrap(); + let doc = self.node.owner_doc; let win = doc.with_base(|doc| doc.window.unwrap()); let cx = win.page.js_info.get_ref().js_compartment.cx.ptr; let scope = win.reflector().get_jsobject(); @@ -276,7 +278,7 @@ impl Element { } pub fn GetClientRects(&self, abstract_self: AbstractNode<ScriptView>) -> @mut ClientRectList { - let document = self.node.owner_doc.expect("no document"); + let document = self.node.owner_doc; let win = document.with_base(|doc| doc.window).expect("no window"); let node = abstract_self; assert!(node.is_element()); @@ -304,7 +306,7 @@ impl Element { } pub fn GetBoundingClientRect(&self, abstract_self: AbstractNode<ScriptView>) -> @mut ClientRect { - let document = self.node.owner_doc.expect("no document"); + let document = self.node.owner_doc; let win = document.with_base(|doc| doc.window).expect("no window"); let page = win.page; let node = abstract_self; diff --git a/src/components/script/dom/htmldatalistelement.rs b/src/components/script/dom/htmldatalistelement.rs index b24f2712adb..7123e4d6229 100644 --- a/src/components/script/dom/htmldatalistelement.rs +++ b/src/components/script/dom/htmldatalistelement.rs @@ -14,7 +14,7 @@ pub struct HTMLDataListElement { impl HTMLDataListElement { fn get_scope_and_cx(&self) -> (*JSObject, *JSContext) { - let doc = self.htmlelement.element.node.owner_doc.unwrap(); + let doc = self.htmlelement.element.node.owner_doc; let win = doc.with_base(|doc| doc.window.unwrap()); let cx = win.page.js_info.get_ref().js_compartment.cx.ptr; let scope = win.reflector().get_jsobject(); diff --git a/src/components/script/dom/htmlelement.rs b/src/components/script/dom/htmlelement.rs index 612b7f414ee..e84ec55cf12 100644 --- a/src/components/script/dom/htmlelement.rs +++ b/src/components/script/dom/htmlelement.rs @@ -5,6 +5,7 @@ use dom::bindings::codegen::HTMLElementBinding; use dom::bindings::utils::{DOMString, ErrorResult, Fallible}; use dom::bindings::utils::{Reflectable, BindingObject, Reflector}; +use dom::document::AbstractDocument; use dom::element::{Element, ElementTypeId}; use dom::node::{AbstractNode, ScriptView}; use js::jsapi::{JSObject, JSContext, JSVal}; @@ -15,9 +16,9 @@ pub struct HTMLElement { } impl HTMLElement { - pub fn new(type_id: ElementTypeId, tag_name: ~str) -> HTMLElement { + pub fn new(type_id: ElementTypeId, tag_name: ~str, document: AbstractDocument) -> HTMLElement { HTMLElement { - element: Element::new(type_id, tag_name) + element: Element::new(type_id, tag_name, document) } } } diff --git a/src/components/script/dom/htmlfieldsetelement.rs b/src/components/script/dom/htmlfieldsetelement.rs index 84b5a1166a1..9a9d543fdef 100644 --- a/src/components/script/dom/htmlfieldsetelement.rs +++ b/src/components/script/dom/htmlfieldsetelement.rs @@ -40,7 +40,7 @@ impl HTMLFieldSetElement { } fn get_scope_and_cx(&self) -> (*JSObject, *JSContext) { - let doc = self.htmlelement.element.node.owner_doc.unwrap(); + let doc = self.htmlelement.element.node.owner_doc; let win = doc.with_base(|doc| doc.window.unwrap()); let cx = win.page.js_info.get_ref().js_compartment.cx.ptr; let scope = win.reflector().get_jsobject(); diff --git a/src/components/script/dom/htmlformelement.rs b/src/components/script/dom/htmlformelement.rs index e75640da248..eba85672a6e 100644 --- a/src/components/script/dom/htmlformelement.rs +++ b/src/components/script/dom/htmlformelement.rs @@ -15,7 +15,7 @@ pub struct HTMLFormElement { impl HTMLFormElement { fn get_scope_and_cx(&self) -> (*JSObject, *JSContext) { - let doc = self.htmlelement.element.node.owner_doc.unwrap(); + let doc = self.htmlelement.element.node.owner_doc; let win = doc.with_base(|doc| doc.window.unwrap()); let cx = win.page.js_info.get_ref().js_compartment.cx.ptr; let scope = win.reflector().get_jsobject(); diff --git a/src/components/script/dom/htmlimageelement.rs b/src/components/script/dom/htmlimageelement.rs index 26e13826bce..6903120a09e 100644 --- a/src/components/script/dom/htmlimageelement.rs +++ b/src/components/script/dom/htmlimageelement.rs @@ -43,12 +43,10 @@ impl HTMLImageElement { let name = null_str_as_empty(name); if "src" == name { let doc = self.htmlelement.element.node.owner_doc; - for doc in doc.iter() { - do doc.with_base |doc| { - for window in doc.window.iter() { - let url = window.page.url.map(|&(ref url, _)| url.clone()); - self.update_image(window.image_cache_task.clone(), url); - } + do doc.with_base |doc| { + for window in doc.window.iter() { + let url = window.page.url.map(|&(ref url, _)| url.clone()); + self.update_image(window.image_cache_task.clone(), url); } } } @@ -102,26 +100,18 @@ impl HTMLImageElement { pub fn Width(&self, abstract_self: AbstractNode<ScriptView>) -> u32 { let node = &self.htmlelement.element.node; - match node.owner_doc { - Some(doc) => { - match doc.with_base(|doc| doc.window) { - Some(win) => { - let page = win.page; - let (port, chan) = stream(); - match page.query_layout(ContentBoxQuery(abstract_self, chan), port) { - ContentBoxResponse(rect) => { - to_px(rect.size.width) as u32 - } - } - } - None => { - debug!("no window"); - 0 + match node.owner_doc.with_base(|doc| doc.window) { + Some(win) => { + let page = win.page; + let (port, chan) = stream(); + match page.query_layout(ContentBoxQuery(abstract_self, chan), port) { + ContentBoxResponse(rect) => { + to_px(rect.size.width) as u32 } } } None => { - debug!("no document"); + debug!("no window"); 0 } } @@ -139,26 +129,18 @@ impl HTMLImageElement { pub fn Height(&self, abstract_self: AbstractNode<ScriptView>) -> u32 { let node = &self.htmlelement.element.node; - match node.owner_doc { - Some(doc) => { - match doc.with_base(|doc| doc.window) { - Some(win) => { - let page = win.page; - let (port, chan) = stream(); - match page.query_layout(ContentBoxQuery(abstract_self, chan), port) { - ContentBoxResponse(rect) => { - to_px(rect.size.height) as u32 - } - } - } - None => { - debug!("no window"); - 0 + match node.owner_doc.with_base(|doc| doc.window) { + Some(win) => { + let page = win.page; + let (port, chan) = stream(); + match page.query_layout(ContentBoxQuery(abstract_self, chan), port) { + ContentBoxResponse(rect) => { + to_px(rect.size.height) as u32 } } } None => { - debug!("no document"); + debug!("no window"); 0 } } diff --git a/src/components/script/dom/htmlmapelement.rs b/src/components/script/dom/htmlmapelement.rs index 9e33141d205..4a924e96a0b 100644 --- a/src/components/script/dom/htmlmapelement.rs +++ b/src/components/script/dom/htmlmapelement.rs @@ -21,7 +21,7 @@ impl HTMLMapElement { } fn get_scope_and_cx(&self) -> (*JSObject, *JSContext) { - let doc = self.htmlelement.element.node.owner_doc.unwrap(); + let doc = self.htmlelement.element.node.owner_doc; let win = doc.with_base(|doc| doc.window.unwrap()); let cx = win.page.js_info.get_ref().js_compartment.cx.ptr; let scope = win.reflector().get_jsobject(); diff --git a/src/components/script/dom/htmlmediaelement.rs b/src/components/script/dom/htmlmediaelement.rs index b7317367dc9..d415515de10 100644 --- a/src/components/script/dom/htmlmediaelement.rs +++ b/src/components/script/dom/htmlmediaelement.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::utils::{DOMString, ErrorResult}; +use dom::document::AbstractDocument; use dom::element::ElementTypeId; use dom::htmlelement::HTMLElement; @@ -11,9 +12,9 @@ pub struct HTMLMediaElement { } impl HTMLMediaElement { - pub fn new(type_id: ElementTypeId, tag_name: ~str) -> HTMLMediaElement { + pub fn new(type_id: ElementTypeId, tag_name: ~str, document: AbstractDocument) -> HTMLMediaElement { HTMLMediaElement { - htmlelement: HTMLElement::new(type_id, tag_name) + htmlelement: HTMLElement::new(type_id, tag_name, document) } } } diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index d3797200503..f9ac7b42dbc 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -86,7 +86,7 @@ pub struct Node<View> { prev_sibling: Option<AbstractNode<View>>, /// The document that this node belongs to. - owner_doc: Option<AbstractDocument>, + owner_doc: AbstractDocument, /// Layout information. Only the layout task may touch this data. priv layout_data: LayoutData, @@ -393,6 +393,32 @@ impl<'self, View> AbstractNode<View> { current_node: self.first_child(), } } + + pub fn is_in_doc(&self) -> bool { + do self.with_base |node| { + do node.owner_doc.with_base |document| { + match document.root { + None => false, + Some(root) => { + let mut node = *self; + let mut in_doc; + loop { + match node.parent_node() { + Some(parent) => { + node = parent; + }, + None => { + in_doc = unsafe { node.raw_object() as uint == root.raw_object() as uint }; + break; + } + } + } + in_doc + } + } + } + } + } } impl<View> Iterator<AbstractNode<View>> for AbstractNodeChildrenIterator<View> { @@ -415,23 +441,22 @@ impl Node<ScriptView> { pub fn add_to_doc(&mut self, doc: AbstractDocument) { let old_doc = self.owner_doc; - self.owner_doc = Some(doc); + self.owner_doc = doc; let mut cur_node = self.first_child; while cur_node.is_some() { for node in cur_node.unwrap().traverse_preorder() { do node.with_mut_base |node_base| { - node_base.owner_doc = Some(doc); + node_base.owner_doc = doc; } }; cur_node = cur_node.unwrap().next_sibling(); } // Signal the old document that it needs to update its display - match old_doc { - Some(old_doc) if old_doc != doc => do old_doc.with_base |old_doc| { + if old_doc != doc { + do old_doc.with_base |old_doc| { old_doc.content_changed(); - }, - _ => () + } } // Signal the new document that it needs to update its display @@ -440,30 +465,14 @@ impl Node<ScriptView> { } } - pub fn remove_from_doc(&mut self) { - let old_doc = self.owner_doc; - self.owner_doc = None; - - let mut cur_node = self.first_child; - while cur_node.is_some() { - for node in cur_node.unwrap().traverse_preorder() { - do node.with_mut_base |node_base| { - node_base.owner_doc = None; - } - }; - cur_node = cur_node.unwrap().next_sibling(); - } - - // Signal the old document that it needs to update its display - match old_doc { - Some(doc) => do doc.with_base |doc| { - doc.content_changed(); - }, - None => () + pub fn remove_from_doc(&self) { + // Signal the document that it needs to update its display. + do self.owner_doc.with_base |doc| { + doc.content_changed(); } } - pub fn new(type_id: NodeTypeId) -> Node<ScriptView> { + pub fn new(type_id: NodeTypeId, doc: AbstractDocument) -> Node<ScriptView> { Node { reflector_: Reflector::new(), type_id: type_id, @@ -476,7 +485,7 @@ impl Node<ScriptView> { next_sibling: None, prev_sibling: None, - owner_doc: None, + owner_doc: doc, layout_data: LayoutData::new(), } @@ -616,8 +625,8 @@ impl Node<ScriptView> { let node = if is_empty { None } else { - let text_node = do self.owner_doc.unwrap().with_base |document| { - document.CreateTextNode(value) + let text_node = do self.owner_doc.with_base |document| { + document.CreateTextNode(self.owner_doc, value) }; Some(text_node) }; @@ -630,10 +639,8 @@ impl Node<ScriptView> { characterdata.data = null_str_as_empty(value); // Notify the document that the content of this node is different - for doc in self.owner_doc.iter() { - do doc.with_base |doc| { - doc.content_changed(); - } + do self.owner_doc.with_base |doc| { + doc.content_changed(); } } } @@ -647,10 +654,8 @@ impl Node<ScriptView> { } fn wait_until_safe_to_modify_dom(&self) { - for doc in self.owner_doc.iter() { - do doc.with_base |doc| { - doc.wait_until_safe_to_modify_dom(); - } + do self.owner_doc.with_base |doc| { + doc.wait_until_safe_to_modify_dom(); } } @@ -689,11 +694,8 @@ impl Node<ScriptView> { // If the node already exists it is removed from current parent node. node.parent_node().map(|parent| parent.remove_child(node)); abstract_self.add_child(node); - match self.owner_doc { - Some(doc) => do node.with_mut_base |node| { - node.add_to_doc(doc); - }, - None => () + do node.with_mut_base |node| { + node.add_to_doc(self.owner_doc); } Ok(node) } diff --git a/src/components/script/dom/text.rs b/src/components/script/dom/text.rs index 955b64bf712..793ee18f000 100644 --- a/src/components/script/dom/text.rs +++ b/src/components/script/dom/text.rs @@ -4,6 +4,7 @@ use dom::bindings::utils::{DOMString, Fallible, null_str_as_empty}; use dom::characterdata::CharacterData; +use dom::document::AbstractDocument; use dom::node::{AbstractNode, ScriptView, Node, TextNodeTypeId}; use dom::window::Window; @@ -14,15 +15,15 @@ pub struct Text { impl Text { /// Creates a new HTML text node. - pub fn new(text: ~str) -> Text { + pub fn new(text: ~str, document: AbstractDocument) -> Text { Text { - element: CharacterData::new(TextNodeTypeId, text) + element: CharacterData::new(TextNodeTypeId, text, document) } } pub fn Constructor(owner: @mut Window, text: &DOMString) -> Fallible<AbstractNode<ScriptView>> { let cx = owner.page.js_info.get_ref().js_compartment.cx.ptr; - let text = @Text::new(null_str_as_empty(text)); + let text = @Text::new(null_str_as_empty(text), owner.Document()); Ok(unsafe { Node::as_abstract_node(cx, text) }) } diff --git a/src/components/script/html/hubbub_html_parser.rs b/src/components/script/html/hubbub_html_parser.rs index 3df574c6f00..5a078175d00 100644 --- a/src/components/script/html/hubbub_html_parser.rs +++ b/src/components/script/html/hubbub_html_parser.rs @@ -2,6 +2,7 @@ * 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::document::AbstractDocument; use dom::element::*; use dom::htmlelement::HTMLElement; use dom::htmlheadingelement::{Heading1, Heading2, Heading3, Heading4, Heading5, Heading6}; @@ -35,7 +36,7 @@ macro_rules! handle_element( ($cx: expr, $tag:expr, $string:expr, $type_id:expr, $ctor:ident, [ $(($field:ident : $field_init:expr)),* ]) => ( if eq_slice($tag, $string) { let _element = @$ctor { - htmlelement: HTMLElement::new($type_id, ($tag).to_str()), + htmlelement: HTMLElement::new($type_id, ($tag).to_str(), document), $( $field: $field_init, )* @@ -49,7 +50,7 @@ macro_rules! handle_element( macro_rules! handle_htmlelement( ($cx: expr, $tag:expr, $string:expr, $type_id:expr, $ctor:ident) => ( if eq_slice($tag, $string) { - let _element = @HTMLElement::new($type_id, ($tag).to_str()); + let _element = @HTMLElement::new($type_id, ($tag).to_str(), document); unsafe { return Node::as_abstract_node(cx, _element); } @@ -60,7 +61,7 @@ macro_rules! handle_htmlmediaelement( ($cx: expr, $tag:expr, $string:expr, $type_id:expr, $ctor:ident) => ( if eq_slice($tag, $string) { let _element = @$ctor { - htmlelement: HTMLMediaElement::new($type_id, ($tag).to_str()) + htmlelement: HTMLMediaElement::new($type_id, ($tag).to_str(), document) }; unsafe { return Node::as_abstract_node(cx, _element); @@ -209,7 +210,7 @@ fn js_script_listener(to_parent: SharedChan<HtmlDiscoveryMessage>, // Silly macros to handle constructing DOM nodes. This produces bad code and should be optimized // via atomization (issue #85). -pub fn build_element_from_tag(cx: *JSContext, tag: &str) -> AbstractNode<ScriptView> { +pub fn build_element_from_tag(cx: *JSContext, tag: &str, document: AbstractDocument) -> AbstractNode<ScriptView> { // TODO (Issue #85): use atoms handle_element!(cx, tag, "a", HTMLAnchorElementTypeId, HTMLAnchorElement, []); handle_element!(cx, tag, "applet", HTMLAppletElementTypeId, HTMLAppletElement, []); @@ -292,12 +293,13 @@ pub fn build_element_from_tag(cx: *JSContext, tag: &str) -> AbstractNode<ScriptV handle_htmlmediaelement!(cx, tag, "video", HTMLVideoElementTypeId, HTMLVideoElement); let element = @HTMLUnknownElement { - htmlelement: HTMLElement::new(HTMLUnknownElementTypeId, tag.to_str()) + htmlelement: HTMLElement::new(HTMLUnknownElementTypeId, tag.to_str(), document) }; unsafe { Node::as_abstract_node(cx, element) } } pub fn parse_html(cx: *JSContext, + document: AbstractDocument, url: Url, resource_task: ResourceTask, image_cache_task: ImageCacheTask, @@ -350,7 +352,7 @@ pub fn parse_html(cx: *JSContext, let url3 = final_url.clone(); // Build the root node. - let root = @HTMLHtmlElement { htmlelement: HTMLElement::new(HTMLHtmlElementTypeId, ~"html") }; + let root = @HTMLHtmlElement { htmlelement: HTMLElement::new(HTMLHtmlElementTypeId, ~"html", document) }; let root = unsafe { Node::as_abstract_node(cx, root) }; debug!("created new node"); let mut parser = hubbub::Parser("UTF-8", false); @@ -365,7 +367,7 @@ pub fn parse_html(cx: *JSContext, parser.set_tree_handler(~hubbub::TreeHandler { create_comment: |data: ~str| { debug!("create comment"); - let comment = @Comment::new(data); + let comment = @Comment::new(data, document); unsafe { Node::as_abstract_node(cx, comment).to_hubbub_node() } @@ -379,14 +381,15 @@ pub fn parse_html(cx: *JSContext, let node = @DocumentType::new(name, public_id, system_id, - force_quirks); + force_quirks, + document); unsafe { Node::as_abstract_node(cx, node).to_hubbub_node() } }, create_element: |tag: ~hubbub::Tag| { debug!("create element"); - let node = build_element_from_tag(cx, tag.name); + let node = build_element_from_tag(cx, tag.name, document); debug!("-- attach attrs"); do node.as_mut_element |element| { @@ -465,7 +468,7 @@ pub fn parse_html(cx: *JSContext, }, create_text: |data: ~str| { debug!("create text"); - let text = @Text::new(data); + let text = @Text::new(data, document); unsafe { Node::as_abstract_node(cx, text).to_hubbub_node() } }, ref_node: |_| {}, diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index 69509d3a648..c29a2d3c599 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -715,17 +715,18 @@ impl ScriptTask { // Parse HTML. // // Note: We can parse the next document in parallel with any previous documents. + let document = HTMLDocument::new(Some(window)); + let html_parsing_result = hubbub_html_parser::parse_html(cx.ptr, + document, url.clone(), self.resource_task.clone(), self.image_cache_task.clone(), page.next_subpage_id.clone(), self.constellation_chan.clone()); - let document = HTMLDocument::new(Some(window)); let HtmlParserResult {root, discovery_port, url: final_url} = html_parsing_result; - document.set_root(root); // Create the root frame. page.frame = Some(Frame { @@ -770,9 +771,8 @@ impl ScriptTask { // of the page. // FIXME: We have no way to ensure that the first reflow performed is a // ReflowForDisplay operation. - do root.with_mut_base |base| { - base.add_to_doc(document) - } + document.set_root(root); + // No more reflow required page.url = Some((url, false)); |