diff options
Diffstat (limited to 'components/script/dom/htmliframeelement.rs')
-rw-r--r-- | components/script/dom/htmliframeelement.rs | 193 |
1 files changed, 126 insertions, 67 deletions
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 658961a1725..3c37c97af4c 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -88,20 +88,24 @@ impl HTMLIFrameElement { /// step 1. fn get_url(&self) -> ServoUrl { let element = self.upcast::<Element>(); - element.get_attribute(&ns!(), &local_name!("src")).and_then(|src| { - let url = src.value(); - if url.is_empty() { - None - } else { - document_from_node(self).base_url().join(&url).ok() - } - }).unwrap_or_else(|| ServoUrl::parse("about:blank").unwrap()) + element + .get_attribute(&ns!(), &local_name!("src")) + .and_then(|src| { + let url = src.value(); + if url.is_empty() { + None + } else { + document_from_node(self).base_url().join(&url).ok() + } + }).unwrap_or_else(|| ServoUrl::parse("about:blank").unwrap()) } - pub fn navigate_or_reload_child_browsing_context(&self, - mut load_data: Option<LoadData>, - nav_type: NavigationType, - replace: bool) { + pub fn navigate_or_reload_child_browsing_context( + &self, + mut load_data: Option<LoadData>, + nav_type: NavigationType, + replace: bool, + ) { let sandboxed = if self.is_sandboxed() { IFrameSandboxed } else { @@ -142,8 +146,11 @@ impl HTMLIFrameElement { match load_data.js_eval_result { Some(JsEvalResult::NoContent) => (), _ => { - *load_blocker = Some(LoadBlocker::new(&*document, LoadType::Subframe(load_data.url.clone()))); - } + *load_blocker = Some(LoadBlocker::new( + &*document, + LoadType::Subframe(load_data.url.clone()), + )); + }, }; } @@ -197,10 +204,10 @@ impl HTMLIFrameElement { sandbox: sandboxed, }; global_scope - .script_to_constellation_chan() - .send(ScriptMsg::ScriptLoadedURLInIFrame(load_info)) - .unwrap(); - } + .script_to_constellation_chan() + .send(ScriptMsg::ScriptLoadedURLInIFrame(load_info)) + .unwrap(); + }, } } @@ -211,7 +218,9 @@ impl HTMLIFrameElement { let window = window_from_node(self); // https://github.com/whatwg/html/issues/490 - if mode == ProcessingMode::FirstTime && !self.upcast::<Element>().has_attribute(&local_name!("src")) { + if mode == ProcessingMode::FirstTime && + !self.upcast::<Element>().has_attribute(&local_name!("src")) + { let this = Trusted::new(self); let pipeline_id = self.pipeline_id().unwrap(); // FIXME(nox): Why are errors silenced here? @@ -245,12 +254,21 @@ impl HTMLIFrameElement { }; let document = document_from_node(self); - let load_data = LoadData::new(url, creator_pipeline_id, document.get_referrer_policy(), Some(document.url())); + let load_data = LoadData::new( + url, + creator_pipeline_id, + document.get_referrer_policy(), + Some(document.url()), + ); let pipeline_id = self.pipeline_id(); // If the initial `about:blank` page is the current page, load with replacement enabled. let replace = pipeline_id.is_some() && pipeline_id == self.about_blank_pipeline_id.get(); - self.navigate_or_reload_child_browsing_context(Some(load_data), NavigationType::Regular, replace); + self.navigate_or_reload_child_browsing_context( + Some(load_data), + NavigationType::Regular, + replace, + ); } fn create_nested_browsing_context(&self) { @@ -259,14 +277,24 @@ impl HTMLIFrameElement { let document = document_from_node(self); let window = window_from_node(self); let pipeline_id = Some(window.upcast::<GlobalScope>().pipeline_id()); - let load_data = LoadData::new(url, pipeline_id, document.get_referrer_policy(), Some(document.url().clone())); + let load_data = LoadData::new( + url, + pipeline_id, + document.get_referrer_policy(), + Some(document.url().clone()), + ); let browsing_context_id = BrowsingContextId::new(); let top_level_browsing_context_id = window.window_proxy().top_level_browsing_context_id(); self.pipeline_id.set(None); self.pending_pipeline_id.set(None); - self.top_level_browsing_context_id.set(Some(top_level_browsing_context_id)); + self.top_level_browsing_context_id + .set(Some(top_level_browsing_context_id)); self.browsing_context_id.set(Some(browsing_context_id)); - self.navigate_or_reload_child_browsing_context(Some(load_data), NavigationType::InitialAboutBlank, false); + self.navigate_or_reload_child_browsing_context( + Some(load_data), + NavigationType::InitialAboutBlank, + false, + ); } fn destroy_nested_browsing_context(&self) { @@ -278,7 +306,9 @@ impl HTMLIFrameElement { } pub fn update_pipeline_id(&self, new_pipeline_id: PipelineId, reason: UpdatePipelineIdReason) { - if self.pending_pipeline_id.get() != Some(new_pipeline_id) && reason == UpdatePipelineIdReason::Navigation { + if self.pending_pipeline_id.get() != Some(new_pipeline_id) && + reason == UpdatePipelineIdReason::Navigation + { return; } @@ -296,9 +326,11 @@ impl HTMLIFrameElement { window.reflow(ReflowGoal::Full, ReflowReason::FramedContentChanged); } - fn new_inherited(local_name: LocalName, - prefix: Option<Prefix>, - document: &Document) -> HTMLIFrameElement { + fn new_inherited( + local_name: LocalName, + prefix: Option<Prefix>, + document: &Document, + ) -> HTMLIFrameElement { HTMLIFrameElement { htmlelement: HTMLElement::new_inherited(local_name, prefix, document), browsing_context_id: Cell::new(None), @@ -310,17 +342,23 @@ impl HTMLIFrameElement { sandbox_allowance: Cell::new(None), load_blocker: DomRefCell::new(None), visibility: Cell::new(true), - name: DomRefCell::new(DOMString::new()) + name: DomRefCell::new(DOMString::new()), } } #[allow(unrooted_must_root)] - pub fn new(local_name: LocalName, - prefix: Option<Prefix>, - document: &Document) -> DomRoot<HTMLIFrameElement> { - Node::reflect_node(Box::new(HTMLIFrameElement::new_inherited(local_name, prefix, document)), - document, - HTMLIFrameElementBinding::Wrap) + pub fn new( + local_name: LocalName, + prefix: Option<Prefix>, + document: &Document, + ) -> DomRoot<HTMLIFrameElement> { + Node::reflect_node( + Box::new(HTMLIFrameElement::new_inherited( + local_name, prefix, document, + )), + document, + HTMLIFrameElementBinding::Wrap, + ) } #[inline] @@ -347,14 +385,20 @@ impl HTMLIFrameElement { pub fn set_visible(&self, visible: bool) { let msg = ScriptMsg::SetVisible(visible); let window = window_from_node(self); - window.upcast::<GlobalScope>().script_to_constellation_chan().send(msg).unwrap(); + window + .upcast::<GlobalScope>() + .script_to_constellation_chan() + .send(msg) + .unwrap(); } /// https://html.spec.whatwg.org/multipage/#iframe-load-event-steps steps 1-4 pub fn iframe_load_event_steps(&self, loaded_pipeline: PipelineId) { // TODO(#9592): assert that the load blocker is present at all times when we // can guarantee that it's created for the case of iframe.reload(). - if Some(loaded_pipeline) != self.pending_pipeline_id.get() { return; } + if Some(loaded_pipeline) != self.pending_pipeline_id.get() { + return; + } // TODO A cross-origin child document would not be easily accessible // from this script thread. It's unclear how to implement @@ -386,20 +430,15 @@ impl HTMLIFrameElementLayoutMethods for LayoutDom<HTMLIFrameElement> { #[inline] #[allow(unsafe_code)] fn pipeline_id(&self) -> Option<PipelineId> { - unsafe { - (*self.unsafe_get()).pipeline_id.get() - } + unsafe { (*self.unsafe_get()).pipeline_id.get() } } #[inline] #[allow(unsafe_code)] fn browsing_context_id(&self) -> Option<BrowsingContextId> { - unsafe { - (*self.unsafe_get()).browsing_context_id.get() - } + unsafe { (*self.unsafe_get()).browsing_context_id.get() } } - #[allow(unsafe_code)] fn get_width(&self) -> LengthOrPercentageOrAuto { unsafe { @@ -432,12 +471,14 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement { // https://html.spec.whatwg.org/multipage/#dom-iframe-sandbox fn Sandbox(&self) -> DomRoot<DOMTokenList> { - self.sandbox.or_init(|| DOMTokenList::new(self.upcast::<Element>(), &local_name!("sandbox"))) + self.sandbox + .or_init(|| DOMTokenList::new(self.upcast::<Element>(), &local_name!("sandbox"))) } // https://html.spec.whatwg.org/multipage/#dom-iframe-contentwindow fn GetContentWindow(&self) -> Option<DomRoot<WindowProxy>> { - self.browsing_context_id.get() + self.browsing_context_id + .get() .and_then(|browsing_context_id| ScriptThread::find_window_proxy(browsing_context_id)) } @@ -453,7 +494,10 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement { let document = ScriptThread::find_document(pipeline_id)?; // Step 4. - let current = GlobalScope::current().expect("No current global object").as_window().Document(); + let current = GlobalScope::current() + .expect("No current global object") + .as_window() + .Document(); if !current.origin().same_origin_domain(document.origin()) { return None; } @@ -508,21 +552,22 @@ impl VirtualMethods for HTMLIFrameElement { self.super_type().unwrap().attribute_mutated(attr, mutation); match attr.local_name() { &local_name!("sandbox") => { - self.sandbox_allowance.set(mutation.new_value(attr).map(|value| { - let mut modes = SandboxAllowance::ALLOW_NOTHING; - for token in value.as_tokens() { - modes |= match &*token.to_ascii_lowercase() { - "allow-same-origin" => SandboxAllowance::ALLOW_SAME_ORIGIN, - "allow-forms" => SandboxAllowance::ALLOW_FORMS, - "allow-pointer-lock" => SandboxAllowance::ALLOW_POINTER_LOCK, - "allow-popups" => SandboxAllowance::ALLOW_POPUPS, - "allow-scripts" => SandboxAllowance::ALLOW_SCRIPTS, - "allow-top-navigation" => SandboxAllowance::ALLOW_TOP_NAVIGATION, - _ => SandboxAllowance::ALLOW_NOTHING - }; - } - modes - })); + self.sandbox_allowance + .set(mutation.new_value(attr).map(|value| { + let mut modes = SandboxAllowance::ALLOW_NOTHING; + for token in value.as_tokens() { + modes |= match &*token.to_ascii_lowercase() { + "allow-same-origin" => SandboxAllowance::ALLOW_SAME_ORIGIN, + "allow-forms" => SandboxAllowance::ALLOW_FORMS, + "allow-pointer-lock" => SandboxAllowance::ALLOW_POINTER_LOCK, + "allow-popups" => SandboxAllowance::ALLOW_POPUPS, + "allow-scripts" => SandboxAllowance::ALLOW_SCRIPTS, + "allow-top-navigation" => SandboxAllowance::ALLOW_TOP_NAVIGATION, + _ => SandboxAllowance::ALLOW_NOTHING, + }; + } + modes + })); }, &local_name!("src") => { // https://html.spec.whatwg.org/multipage/#the-iframe-element @@ -552,7 +597,10 @@ impl VirtualMethods for HTMLIFrameElement { &local_name!("sandbox") => AttrValue::from_serialized_tokenlist(value.into()), &local_name!("width") => AttrValue::from_dimension(value.into()), &local_name!("height") => AttrValue::from_dimension(value.into()), - _ => self.super_type().unwrap().parse_plain_attribute(name, value), + _ => self + .super_type() + .unwrap() + .parse_plain_attribute(name, value), } } @@ -583,7 +631,8 @@ impl VirtualMethods for HTMLIFrameElement { // https://html.spec.whatwg.org/multipage/#a-browsing-context-is-discarded let window = window_from_node(self); - let (sender, receiver) = ProfiledIpc::channel(self.global().time_profiler_chan().clone()).unwrap(); + let (sender, receiver) = + ProfiledIpc::channel(self.global().time_profiler_chan().clone()).unwrap(); // Ask the constellation to remove the iframe, and tell us the // pipeline ids of the closed pipelines. @@ -594,7 +643,11 @@ impl VirtualMethods for HTMLIFrameElement { debug!("Unbinding frame {}.", browsing_context_id); let msg = ScriptMsg::RemoveIFrame(browsing_context_id, sender); - window.upcast::<GlobalScope>().script_to_constellation_chan().send(msg).unwrap(); + window + .upcast::<GlobalScope>() + .script_to_constellation_chan() + .send(msg) + .unwrap(); let exited_pipeline_ids = receiver.recv().unwrap(); // The spec for discarding is synchronous, @@ -602,8 +655,14 @@ impl VirtualMethods for HTMLIFrameElement { // when the `PipelineExit` message arrives. for exited_pipeline_id in exited_pipeline_ids { if let Some(exited_document) = ScriptThread::find_document(exited_pipeline_id) { - debug!("Discarding browsing context for pipeline {}", exited_pipeline_id); - exited_document.window().window_proxy().discard_browsing_context(); + debug!( + "Discarding browsing context for pipeline {}", + exited_pipeline_id + ); + exited_document + .window() + .window_proxy() + .discard_browsing_context(); for exited_iframe in exited_document.iter_iframes() { debug!("Discarding nested browsing context"); exited_iframe.destroy_nested_browsing_context(); |