diff options
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/blob.rs | 3 | ||||
-rw-r--r-- | components/script/dom/comment.rs | 3 | ||||
-rw-r--r-- | components/script/dom/element.rs | 2 | ||||
-rw-r--r-- | components/script/dom/htmliframeelement.rs | 57 | ||||
-rw-r--r-- | components/script/dom/htmllinkelement.rs | 66 | ||||
-rw-r--r-- | components/script/dom/htmlstyleelement.rs | 4 | ||||
-rw-r--r-- | components/script/dom/node.rs | 10 | ||||
-rw-r--r-- | components/script/dom/window.rs | 25 |
8 files changed, 125 insertions, 45 deletions
diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index 0bbdca9f93d..1266cce96b9 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -41,9 +41,6 @@ impl Blob { } } -pub trait BlobMethods { -} - impl Reflectable for Blob { fn reflector<'a>(&'a self) -> &'a Reflector { &self.reflector_ diff --git a/components/script/dom/comment.rs b/components/script/dom/comment.rs index dd070df87ac..5e82dae3716 100644 --- a/components/script/dom/comment.rs +++ b/components/script/dom/comment.rs @@ -46,9 +46,6 @@ impl Comment { } } -pub trait CommentMethods { -} - impl Reflectable for Comment { fn reflector<'a>(&'a self) -> &'a Reflector { self.characterdata.reflector() diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index ff7e4e1e925..953036788f4 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -806,7 +806,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> { Err(()) => Err(Syntax), Ok(ref selectors) => { let root: &JSRef<Node> = NodeCast::from_ref(self); - Ok(matches(selectors, root)) + Ok(matches(selectors, root, &mut None)) } } } diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index a731d0820b6..a5c83002327 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -76,36 +76,41 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> { fn get_url(&self) -> Option<Url> { let element: &JSRef<Element> = ElementCast::from_ref(self); element.get_attribute(Null, "src").root().and_then(|src| { - let window = window_from_node(self).root(); - UrlParser::new().base_url(&window.deref().page().get_url()) - .parse(src.deref().value().as_slice()).ok() + let url = src.deref().value(); + if url.as_slice().is_empty() { + None + } else { + let window = window_from_node(self).root(); + UrlParser::new().base_url(&window.deref().page().get_url()) + .parse(url.as_slice()).ok() + } }) } fn process_the_iframe_attributes(&self) { - match self.get_url() { - Some(url) => { - let sandboxed = if self.is_sandboxed() { - IFrameSandboxed - } else { - IFrameUnsandboxed - }; - - // Subpage Id - let window = window_from_node(self).root(); - let page = window.deref().page(); - let subpage_id = page.get_next_subpage_id(); - - self.deref().size.deref().set(Some(IFrameSize { - pipeline_id: page.id, - subpage_id: subpage_id, - })); - - let ConstellationChan(ref chan) = *page.constellation_chan.deref(); - chan.send(LoadIframeUrlMsg(url, page.id, subpage_id, sandboxed)); - } - _ => () - } + let url = match self.get_url() { + Some(url) => url.clone(), + None => Url::parse("about:blank").unwrap(), + }; + + let sandboxed = if self.is_sandboxed() { + IFrameSandboxed + } else { + IFrameUnsandboxed + }; + + // Subpage Id + let window = window_from_node(self).root(); + let page = window.deref().page(); + let subpage_id = page.get_next_subpage_id(); + + self.deref().size.deref().set(Some(IFrameSize { + pipeline_id: page.id, + subpage_id: subpage_id, + })); + + let ConstellationChan(ref chan) = *page.constellation_chan.deref(); + chan.send(LoadIframeUrlMsg(url, page.id, subpage_id, sandboxed)); } } diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index d8389033bd1..3c44a9cba8b 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -2,20 +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::attr::AttrHelpers; use dom::bindings::codegen::Bindings::HTMLLinkElementBinding; use dom::bindings::codegen::InheritTypes::HTMLLinkElementDerived; -use dom::bindings::codegen::InheritTypes::{HTMLElementCast, NodeCast}; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, NodeCast}; +use dom::bindings::js::{JSRef, Temporary, OptionalRootable}; use dom::bindings::utils::{Reflectable, Reflector}; use dom::document::Document; -use dom::element::HTMLLinkElementTypeId; +use dom::element::{AttributeHandlers, Element, HTMLLinkElementTypeId}; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{Node, NodeHelpers, ElementNodeTypeId}; +use dom::node::{Node, NodeHelpers, ElementNodeTypeId, window_from_node}; use dom::virtualmethods::VirtualMethods; - +use layout_interface::{LayoutChan, LoadStylesheetMsg}; use servo_util::atom::Atom; -use servo_util::str::DOMString; +use servo_util::str::{DOMString, HTML_SPACE_CHARACTERS}; +use servo_util::namespace::Null; + +use std::ascii::StrAsciiExt; +use url::UrlParser; #[deriving(Encodable)] #[must_root] @@ -74,6 +79,55 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLLinkElement> { _ => () } } + + fn bind_to_tree(&self, tree_in_doc: bool) { + match self.super_type() { + Some(ref s) => s.bind_to_tree(tree_in_doc), + _ => () + } + + if tree_in_doc { + let element: &JSRef<Element> = ElementCast::from_ref(self); + + // 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(|rel| rel.deref().value().as_slice().to_string()) + }; + let href = { + let href = element.get_attribute(Null, "href").root(); + href.map(|href| href.deref().value().as_slice().to_string()) + }; + + match (rel, href) { + (Some(ref rel), Some(ref href)) => { + if rel.as_slice().split(HTML_SPACE_CHARACTERS.as_slice()) + .any(|s| s.as_slice().eq_ignore_ascii_case("stylesheet")) { + self.handle_stylesheet_url(href.as_slice()); + } + } + _ => {} + } + } + } +} + +trait PrivateHTMLLinkElementHelpers { + fn handle_stylesheet_url(&self, href: &str); +} + +impl<'a> PrivateHTMLLinkElementHelpers for JSRef<'a, HTMLLinkElement> { + fn handle_stylesheet_url(&self, href: &str) { + let window = window_from_node(self).root(); + match UrlParser::new().base_url(&window.deref().page().get_url()).parse(href) { + Ok(url) => { + let LayoutChan(ref layout_chan) = *window.deref().page().layout_chan; + layout_chan.send(LoadStylesheetMsg(url)); + } + Err(e) => debug!("Parsing url {:s} failed: {:?}", href, e) + } + } } impl Reflectable for HTMLLinkElement { diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs index 30aa81f15f1..d968c3bc6ee 100644 --- a/components/script/dom/htmlstyleelement.rs +++ b/components/script/dom/htmlstyleelement.rs @@ -13,9 +13,9 @@ use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; use dom::node::{Node, NodeHelpers, ElementNodeTypeId, window_from_node}; use dom::virtualmethods::VirtualMethods; -use html::cssparse::parse_inline_css; use layout_interface::{AddStylesheetMsg, LayoutChan}; use servo_util::str::DOMString; +use style::Stylesheet; #[deriving(Encodable)] #[must_root] @@ -56,7 +56,7 @@ impl<'a> StyleElementHelpers for JSRef<'a, HTMLStyleElement> { let url = win.deref().page().get_url(); let data = node.GetTextContent().expect("Element.textContent must be a string"); - let sheet = parse_inline_css(url, data); + let sheet = Stylesheet::from_str(data.as_slice(), url); let LayoutChan(ref layout_chan) = *win.deref().page().layout_chan; layout_chan.send(AddStylesheetMsg(sheet)); } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index b46adc488fd..9e1b73feb12 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -611,7 +611,7 @@ impl<'m, 'n> NodeHelpers<'m, 'n> for JSRef<'n, Node> { Ok(ref selectors) => { let root = self.ancestors().last().unwrap_or(self.clone()); for node in root.traverse_preorder() { - if node.is_element() && matches(selectors, &node) { + if node.is_element() && matches(selectors, &node, &mut None) { let elem: &JSRef<Element> = ElementCast::to_ref(&node).unwrap(); return Ok(Some(Temporary::from_rooted(elem))); } @@ -632,7 +632,9 @@ impl<'m, 'n> NodeHelpers<'m, 'n> for JSRef<'n, Node> { // Step 3. Ok(ref selectors) => { nodes = root.traverse_preorder().filter( - |node| node.is_element() && matches(selectors, node)).collect() + // TODO(cgaebel): Is it worth it to build a bloom filter here + // (instead of passing `None`)? Probably. + |node| node.is_element() && matches(selectors, node, &mut None)).collect() } } let window = window_from_node(self).root(); @@ -1990,6 +1992,10 @@ impl<'a> style::TNode<JSRef<'a, Element>> for JSRef<'a, Node> { (self as &NodeHelpers).parent_node().map(|node| *node.root()) } + fn tnode_first_child(&self) -> Option<JSRef<'a, Node>> { + (self as &NodeHelpers).first_child().map(|node| *node.root()) + } + fn prev_sibling(&self) -> Option<JSRef<'a, Node>> { (self as &NodeHelpers).prev_sibling().map(|node| *node.root()) } diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index d9c9cd5c6c6..75f1aaea79b 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -29,14 +29,15 @@ use servo_net::image_cache_task::ImageCacheTask; use servo_util::str::{DOMString,HTML_SPACE_CHARACTERS}; use servo_util::task::{spawn_named}; -use js::jsapi::JS_CallFunctionValue; +use js::jsapi::{JS_CallFunctionValue, JS_EvaluateUCScript}; use js::jsapi::JSContext; use js::jsapi::{JS_GC, JS_GetRuntime}; use js::jsval::JSVal; -use js::jsval::NullValue; +use js::jsval::{UndefinedValue, NullValue}; use js::rust::with_compartment; use url::{Url, UrlParser}; +use libc; use serialize::base64::{FromBase64, ToBase64, STANDARD}; use std::collections::hashmap::HashMap; use std::cell::{Cell, RefCell}; @@ -359,6 +360,7 @@ pub trait WindowHelpers { fn init_browser_context(&self, doc: &JSRef<Document>); fn load_url(&self, href: DOMString); fn handle_fire_timer(&self, timer_id: TimerId, cx: *mut JSContext); + fn evaluate_js_with_result(&self, code: &str) -> JSVal; } trait PrivateWindowHelpers { @@ -366,6 +368,25 @@ trait PrivateWindowHelpers { } impl<'a> WindowHelpers for JSRef<'a, Window> { + fn evaluate_js_with_result(&self, code: &str) -> JSVal { + let global = self.reflector().get_jsobject(); + let code: Vec<u16> = code.as_slice().utf16_units().collect(); + let mut rval = UndefinedValue(); + let filename = "".to_c_str(); + let cx = self.get_cx(); + + with_compartment(cx, global, || { + unsafe { + if JS_EvaluateUCScript(cx, global, code.as_ptr(), + code.len() as libc::c_uint, + filename.as_ptr(), 1, &mut rval) == 0 { + debug!("error evaluating JS string"); + } + rval + } + }) + } + fn damage_and_reflow(&self, damage: DocumentDamageLevel) { // FIXME This should probably be ReflowForQuery, not Display. All queries currently // currently rely on the display list, which means we can't destroy it by |