aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script/html/hubbub_html_parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/script/html/hubbub_html_parser.rs')
-rw-r--r--src/components/script/html/hubbub_html_parser.rs117
1 files changed, 66 insertions, 51 deletions
diff --git a/src/components/script/html/hubbub_html_parser.rs b/src/components/script/html/hubbub_html_parser.rs
index 18945f9062a..8cebc7326e6 100644
--- a/src/components/script/html/hubbub_html_parser.rs
+++ b/src/components/script/html/hubbub_html_parser.rs
@@ -2,17 +2,18 @@
* 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::attr::AttrMethods;
use dom::bindings::codegen::InheritTypes::{NodeBase, NodeCast, TextCast, ElementCast};
use dom::bindings::codegen::InheritTypes::HTMLIFrameElementCast;
-use dom::bindings::js::JS;
+use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable, Root};
use dom::bindings::utils::Reflectable;
-use dom::document::Document;
+use dom::document::{Document, DocumentHelpers};
use dom::element::{AttributeHandlers, HTMLLinkElementTypeId, HTMLIFrameElementTypeId};
use dom::htmlelement::HTMLElement;
use dom::htmlheadingelement::{Heading1, Heading2, Heading3, Heading4, Heading5, Heading6};
-use dom::htmliframeelement::IFrameSize;
+use dom::htmliframeelement::{IFrameSize, HTMLIFrameElementHelpers};
use dom::htmlformelement::HTMLFormElement;
-use dom::node::{ElementNodeTypeId, INode, NodeHelpers};
+use dom::node::{ElementNodeTypeId, NodeHelpers, NodeMethods};
use dom::types::*;
use html::cssparse::{StylesheetProvenance, UrlProvenance, spawn_css_parser};
use script_task::Page;
@@ -39,7 +40,7 @@ macro_rules! handle_element(
$ctor: ident
$(, $arg:expr )*) => (
if $string == $localName {
- return ElementCast::from(&$ctor::new($localName, $document $(, $arg)*));
+ return ElementCast::from_unrooted($ctor::new($localName, $document $(, $arg)*));
}
)
)
@@ -74,20 +75,20 @@ pub struct HtmlParserResult {
pub discovery_port: Receiver<HtmlDiscoveryMessage>,
}
-trait NodeWrapping {
+trait NodeWrapping<T> {
unsafe fn to_hubbub_node(&self) -> hubbub::NodeDataPtr;
- unsafe fn from_hubbub_node(n: hubbub::NodeDataPtr) -> Self;
}
-impl<T: NodeBase+Reflectable> NodeWrapping for JS<T> {
+impl<'a, T: NodeBase+Reflectable> NodeWrapping<T> for JSRef<'a, T> {
unsafe fn to_hubbub_node(&self) -> hubbub::NodeDataPtr {
- cast::transmute(self.get())
- }
- unsafe fn from_hubbub_node(n: hubbub::NodeDataPtr) -> JS<T> {
- JS::from_raw(cast::transmute(n))
+ cast::transmute(self.deref())
}
}
+unsafe fn from_hubbub_node<T: Reflectable>(n: hubbub::NodeDataPtr) -> Temporary<T> {
+ Temporary::new(JS::from_raw(cast::transmute(n)))
+}
+
/**
Runs a task that coordinates parsing links to css stylesheets.
@@ -160,7 +161,7 @@ fn js_script_listener(to_parent: Sender<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(tag: DOMString, document: &JS<Document>) -> JS<Element> {
+pub fn build_element_from_tag(tag: DOMString, document: &JSRef<Document>) -> Temporary<Element> {
// TODO (Issue #85): use atoms
handle_element!(document, tag, "a", HTMLAnchorElement);
handle_element!(document, tag, "applet", HTMLAppletElement);
@@ -242,11 +243,11 @@ pub fn build_element_from_tag(tag: DOMString, document: &JS<Document>) -> JS<Ele
handle_element!(document, tag, "ul", HTMLUListElement);
handle_element!(document, tag, "video", HTMLVideoElement);
- return ElementCast::from(&HTMLUnknownElement::new(tag, document));
+ return ElementCast::from_unrooted(HTMLUnknownElement::new(tag, document));
}
pub fn parse_html(page: &Page,
- document: &mut JS<Document>,
+ document: &mut JSRef<Document>,
url: Url,
resource_task: ResourceTask)
-> HtmlParserResult {
@@ -308,8 +309,9 @@ pub fn parse_html(page: &Page,
// NOTE: tmp vars are workaround for lifetime issues. Both required.
let tmp_borrow = doc_cell.borrow();
let tmp = &*tmp_borrow;
- let comment: JS<Node> = NodeCast::from(&Comment::new(data, *tmp));
- unsafe { comment.to_hubbub_node() }
+ let comment = Comment::new(data, *tmp).root();
+ let comment: &JSRef<Node> = NodeCast::from_ref(&*comment);
+ unsafe { comment.to_hubbub_node() }
},
create_doctype: |doctype: ~hubbub::Doctype| {
debug!("create doctype");
@@ -320,17 +322,17 @@ pub fn parse_html(page: &Page,
// NOTE: tmp vars are workaround for lifetime issues. Both required.
let tmp_borrow = doc_cell.borrow();
let tmp = &*tmp_borrow;
- let doctype_node = DocumentType::new(name, public_id, system_id, *tmp);
+ let doctype_node = DocumentType::new(name, public_id, system_id, *tmp).root();
unsafe {
- doctype_node.to_hubbub_node()
+ doctype_node.deref().to_hubbub_node()
}
},
create_element: |tag: ~hubbub::Tag| {
- debug!("create element");
+ debug!("create element {:?}", tag.name.clone());
// NOTE: tmp vars are workaround for lifetime issues. Both required.
let tmp_borrow = doc_cell.borrow();
let tmp = &*tmp_borrow;
- let mut element = build_element_from_tag(tag.name.clone(), *tmp);
+ let mut element = build_element_from_tag(tag.name.clone(), *tmp).root();
debug!("-- attach attrs");
for attr in tag.attributes.iter() {
@@ -340,21 +342,36 @@ pub fn parse_html(page: &Page,
attr.value.clone()).is_ok());
}
+ //FIXME: workaround for https://github.com/mozilla/rust/issues/13246;
+ // we get unrooting order failures if these are inside the match.
+ let rel = {
+ let rel = element.get_attribute(Null, "rel").root();
+ rel.map(|a| a.deref().Value())
+ };
+ let href = {
+ let href= element.get_attribute(Null, "href").root();
+ href.map(|a| a.deref().Value())
+ };
+ let src_opt = {
+ let src_opt = element.get_attribute(Null, "src").root();
+ src_opt.map(|a| a.deref().Value())
+ };
+
// Spawn additional parsing, network loads, etc. from tag and attrs
- match element.get().node.type_id {
+ let type_id = {
+ let node: &JSRef<Node> = NodeCast::from_ref(&*element);
+ node.type_id()
+ };
+ match type_id {
// Handle CSS style sheets from <link> elements
ElementNodeTypeId(HTMLLinkElementTypeId) => {
- match (element.get_attribute(Null, "rel"),
- element.get_attribute(Null, "href")) {
- (Some(ref rel), Some(ref href)) if rel.get()
- .value_ref()
- .split(HTML_SPACE_CHARACTERS.
- as_slice())
+ match (rel, href) {
+ (Some(ref rel), Some(ref href)) if rel.split(HTML_SPACE_CHARACTERS.as_slice())
.any(|s| {
s.eq_ignore_ascii_case("stylesheet")
}) => {
- debug!("found CSS stylesheet: {:s}", href.get().value_ref());
- let url = parse_url(href.get().value_ref(), Some(url2.clone()));
+ debug!("found CSS stylesheet: {:s}", *href);
+ let url = parse_url(href.as_slice(), Some(url2.clone()));
css_chan2.send(CSSTaskNewFile(UrlProvenance(url, resource_task.clone())));
}
_ => {}
@@ -363,21 +380,19 @@ pub fn parse_html(page: &Page,
ElementNodeTypeId(HTMLIFrameElementTypeId) => {
let iframe_chan = discovery_chan.clone();
- let mut iframe_element: JS<HTMLIFrameElement> =
- HTMLIFrameElementCast::to(&element).unwrap();
- let sandboxed = iframe_element.get().is_sandboxed();
- let elem: JS<Element> = ElementCast::from(&iframe_element);
- let src_opt = elem.get_attribute(Null, "src").map(|x| x.get().Value());
+ let iframe_element: &mut JSRef<HTMLIFrameElement> =
+ HTMLIFrameElementCast::to_mut_ref(&mut *element).unwrap();
+ let sandboxed = iframe_element.is_sandboxed();
for src in src_opt.iter() {
let iframe_url = parse_url(*src, Some(url2.clone()));
- iframe_element.get_mut().set_frame(iframe_url.clone());
+ iframe_element.set_frame(iframe_url.clone());
// Subpage Id
let subpage_id = *next_subpage_id.borrow();
let SubpageId(id_num) = subpage_id;
*next_subpage_id.borrow_mut() = SubpageId(id_num + 1);
- iframe_element.get_mut().size = Some(IFrameSize {
+ iframe_element.deref_mut().size = Some(IFrameSize {
pipeline_id: pipeline_id,
subpage_id: subpage_id,
});
@@ -396,17 +411,17 @@ pub fn parse_html(page: &Page,
// NOTE: tmp vars are workaround for lifetime issues. Both required.
let tmp_borrow = doc_cell.borrow();
let tmp = &*tmp_borrow;
- let text = Text::new(data, *tmp);
- unsafe { text.to_hubbub_node() }
+ let text = Text::new(data, *tmp).root();
+ unsafe { text.deref().to_hubbub_node() }
},
ref_node: |_| {},
unref_node: |_| {},
append_child: |parent: hubbub::NodeDataPtr, child: hubbub::NodeDataPtr| {
unsafe {
debug!("append child {:x} {:x}", parent, child);
- let mut parent: JS<Node> = NodeWrapping::from_hubbub_node(parent);
- let mut child: JS<Node> = NodeWrapping::from_hubbub_node(child);
- assert!(parent.AppendChild(&mut child).is_ok());
+ let mut child = from_hubbub_node(child).root();
+ let mut parent: Root<Node> = from_hubbub_node(parent).root();
+ assert!(parent.AppendChild(&mut *child).is_ok());
}
child
},
@@ -446,32 +461,32 @@ pub fn parse_html(page: &Page,
// NOTE: tmp vars are workaround for lifetime issues. Both required.
let mut tmp_borrow = doc_cell.borrow_mut();
let tmp = &mut *tmp_borrow;
- tmp.get_mut().set_quirks_mode(mode);
+ tmp.set_quirks_mode(mode);
},
encoding_change: |encname| {
debug!("encoding change");
// NOTE: tmp vars are workaround for lifetime issues. Both required.
let mut tmp_borrow = doc_cell.borrow_mut();
let tmp = &mut *tmp_borrow;
- tmp.get_mut().set_encoding_name(encname);
+ tmp.set_encoding_name(encname);
},
complete_script: |script| {
unsafe {
- let script: JS<Element> = NodeWrapping::from_hubbub_node(script);
- match script.get_attribute(Null, "src") {
+ let script: &JSRef<Element> = &*from_hubbub_node(script).root();
+ match script.get_attribute(Null, "src").root() {
Some(src) => {
- debug!("found script: {:s}", src.get().Value());
- let new_url = parse_url(src.get().value_ref(), Some(url3.clone()));
+ debug!("found script: {:s}", src.deref().Value());
+ let new_url = parse_url(src.deref().value_ref(), Some(url3.clone()));
js_chan2.send(JSTaskNewFile(new_url));
}
None => {
let mut data = vec!();
- let scriptnode: JS<Node> = NodeCast::from(&script);
+ let scriptnode: &JSRef<Node> = NodeCast::from_ref(script);
debug!("iterating over children {:?}", scriptnode.first_child());
for child in scriptnode.children() {
debug!("child = {:?}", child);
- let text: JS<Text> = TextCast::to(&child).unwrap();
- data.push(text.get().characterdata.data.to_str()); // FIXME: Bad copy.
+ let text: &JSRef<Text> = TextCast::to_ref(&child).unwrap();
+ data.push(text.deref().characterdata.data.to_str()); // FIXME: Bad copy.
}
debug!("script data = {:?}", data);