diff options
Diffstat (limited to 'src/components/script')
-rw-r--r-- | src/components/script/dom/element.rs | 16 | ||||
-rw-r--r-- | src/components/script/dom/htmliframeelement.rs | 49 | ||||
-rw-r--r-- | src/components/script/html/hubbub_html_parser.rs | 8 | ||||
-rw-r--r-- | src/components/script/script_task.rs | 12 |
4 files changed, 70 insertions, 15 deletions
diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index be475bd1d85..0bb776628c9 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -139,9 +139,9 @@ impl<'self> Element { return None; } - pub fn set_attr(&mut self, name: &DOMString, value: &DOMString) { - let name = name.to_str(); - let value_cell = Cell::new(value.to_str()); + pub fn set_attr(&mut self, raw_name: &DOMString, raw_value: &DOMString) { + let name = raw_name.to_str(); + let value_cell = Cell::new(raw_value.to_str()); let mut found = false; for attr in self.attrs.mut_iter() { if eq_slice(attr.name, name) { @@ -158,7 +158,15 @@ impl<'self> Element { self.style_attribute = Some( Stylesheet::from_attribute( FromStr::from_str("http://www.example.com/").unwrap(), - value.get_ref())); + raw_value.get_ref())); + } + + //XXXjdm We really need something like a vtable so we can call AfterSetAttr. + // This hardcoding is awful. + if self.parent.abstract.unwrap().is_iframe_element() { + do self.parent.abstract.unwrap().with_mut_iframe_element |iframe| { + iframe.AfterSetAttr(raw_name, raw_value); + } } match self.parent.owner_doc { diff --git a/src/components/script/dom/htmliframeelement.rs b/src/components/script/dom/htmliframeelement.rs index 288a988928a..4c45e570b54 100644 --- a/src/components/script/dom/htmliframeelement.rs +++ b/src/components/script/dom/htmliframeelement.rs @@ -2,7 +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::bindings::utils::{DOMString, null_string, ErrorResult}; +use dom::bindings::utils::{DOMString, null_string, ErrorResult, str}; use dom::document::AbstractDocument; use dom::htmlelement::HTMLElement; use dom::windowproxy::WindowProxy; @@ -11,14 +11,26 @@ use geom::rect::Rect; use servo_msg::constellation_msg::{ConstellationChan, FrameRectMsg, PipelineId, SubpageId}; +use std::ascii::StrAsciiExt; use std::comm::ChanOne; use extra::url::Url; use std::util::replace; +enum SandboxAllowance { + AllowNothing = 0x00, + AllowSameOrigin = 0x01, + AllowTopNavigation = 0x02, + AllowForms = 0x04, + AllowScripts = 0x08, + AllowPointerLock = 0x10, + AllowPopups = 0x20 +} + pub struct HTMLIFrameElement { parent: HTMLElement, frame: Option<Url>, size: Option<IFrameSize>, + sandbox: Option<u8> } struct IFrameSize { @@ -39,6 +51,11 @@ impl IFrameSize { } } +impl HTMLIFrameElement { + pub fn is_sandboxed(&self) -> bool { + self.sandbox.is_some() + } +} impl HTMLIFrameElement { pub fn Src(&self) -> DOMString { @@ -63,10 +80,32 @@ impl HTMLIFrameElement { } pub fn Sandbox(&self) -> DOMString { - null_string - } - - pub fn SetSandbox(&self, _sandbox: &DOMString) { + self.parent.parent.GetAttribute(&str(~"sandbox")) + } + + pub fn SetSandbox(&mut self, sandbox: &DOMString) { + let mut rv = Ok(()); + self.parent.parent.SetAttribute(&str(~"sandbox"), sandbox, &mut rv); + } + + pub fn AfterSetAttr(&mut self, name: &DOMString, value: &DOMString) { + let name = name.to_str(); + if "sandbox" == name { + let mut modes = AllowNothing as u8; + let words = value.to_str(); + for word in words.split_iter(' ') { + modes |= match word.to_ascii_lower().as_slice() { + "allow-same-origin" => AllowSameOrigin, + "allow-forms" => AllowForms, + "allow-pointer-lock" => AllowPointerLock, + "allow-popups" => AllowPopups, + "allow-scripts" => AllowScripts, + "allow-top-navigation" => AllowTopNavigation, + _ => AllowNothing + } as u8; + } + self.sandbox = Some(modes); + } } pub fn AllowFullscreen(&self) -> bool { diff --git a/src/components/script/html/hubbub_html_parser.rs b/src/components/script/html/hubbub_html_parser.rs index 64340a28b77..42c9e43cf48 100644 --- a/src/components/script/html/hubbub_html_parser.rs +++ b/src/components/script/html/hubbub_html_parser.rs @@ -93,7 +93,7 @@ enum JSMessage { /// Messages generated by the HTML parser upon discovery of additional resources pub enum HtmlDiscoveryMessage { HtmlDiscoveredStyle(Stylesheet), - HtmlDiscoveredIFrame((Url, SubpageId, Future<Size2D<uint>>)), + HtmlDiscoveredIFrame((Url, SubpageId, Future<Size2D<uint>>, bool)), HtmlDiscoveredScript(JSResult) } @@ -272,7 +272,7 @@ pub fn build_element_from_tag(cx: *JSContext, tag: &str) -> AbstractNode<ScriptV handle_element!(cx, tag, "ul", HTMLUListElementTypeId, HTMLUListElement, []); handle_element!(cx, tag, "img", HTMLImageElementTypeId, HTMLImageElement, [(image: None)]); - handle_element!(cx, tag, "iframe", HTMLIframeElementTypeId, HTMLIFrameElement, [(frame: None), (size: None)]); + handle_element!(cx, tag, "iframe", HTMLIframeElementTypeId, HTMLIFrameElement, [(frame: None), (size: None), (sandbox: None)]); handle_element!(cx, tag, "h1", HTMLHeadingElementTypeId, HTMLHeadingElement, [(level: Heading1)]); handle_element!(cx, tag, "h2", HTMLHeadingElementTypeId, HTMLHeadingElement, [(level: Heading2)]); @@ -401,6 +401,7 @@ pub fn parse_html(cx: *JSContext, let iframe_chan = Cell::new(discovery_chan.clone()); do node.with_mut_iframe_element |iframe_element| { let iframe_chan = iframe_chan.take(); + let sandboxed = iframe_element.is_sandboxed(); let elem = &mut iframe_element.parent.parent; let src_opt = elem.get_attr("src").map(|x| x.to_str()); for src in src_opt.iter() { @@ -427,7 +428,8 @@ pub fn parse_html(cx: *JSContext, future_chan: Some(chan), constellation_chan: constellation_chan.clone(), }); - iframe_chan.send(HtmlDiscoveredIFrame((iframe_url, subpage_id, size_future))); + iframe_chan.send(HtmlDiscoveredIFrame((iframe_url, subpage_id, + size_future, sandboxed))); } } } diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index 759d37a6dc4..9d45dc7d8dc 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -22,7 +22,7 @@ use layout_interface::ReflowMsg; use layout_interface; use servo_msg::constellation_msg::{ConstellationChan, LoadUrlMsg, NavigationDirection}; use servo_msg::constellation_msg::{PipelineId, SubpageId, RendererReadyMsg}; -use servo_msg::constellation_msg::{LoadIframeUrlMsg}; +use servo_msg::constellation_msg::{LoadIframeUrlMsg, IFrameSandboxed, IFrameUnsandboxed}; use servo_msg::constellation_msg; use std::cell::Cell; @@ -641,12 +641,18 @@ impl ScriptTask { Some(HtmlDiscoveredStyle(sheet)) => { page.layout_chan.send(AddStylesheetMsg(sheet)); } - Some(HtmlDiscoveredIFrame((iframe_url, subpage_id, size_future))) => { + Some(HtmlDiscoveredIFrame((iframe_url, subpage_id, size_future, sandboxed))) => { page.next_subpage_id = SubpageId(*subpage_id + 1); + let sandboxed = if sandboxed { + IFrameSandboxed + } else { + IFrameUnsandboxed + }; self.constellation_chan.send(LoadIframeUrlMsg(iframe_url, pipeline_id, subpage_id, - size_future)); + size_future, + sandboxed)); } None => break } |