aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/htmliframeelement.rs
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2015-07-20 16:15:13 -0400
committerJosh Matthews <josh@joshmatthews.net>2016-02-10 09:20:00 -0500
commite9b98ad5fa5380096700712839cc49edf46d2e93 (patch)
tree57ad73c327ffe952579de122df6baf5fd2658724 /components/script/dom/htmliframeelement.rs
parentfc3f93235e9264a6379e370b635ae8a98e41a1be (diff)
downloadservo-e9b98ad5fa5380096700712839cc49edf46d2e93.tar.gz
servo-e9b98ad5fa5380096700712839cc49edf46d2e93.zip
Make iframes block the enclosing document's load event. Fixes #6663.
Diffstat (limited to 'components/script/dom/htmliframeelement.rs')
-rw-r--r--components/script/dom/htmliframeelement.rs33
1 files changed, 31 insertions, 2 deletions
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs
index 2221147ecad..630b36e14e9 100644
--- a/components/script/dom/htmliframeelement.rs
+++ b/components/script/dom/htmliframeelement.rs
@@ -2,7 +2,9 @@
* 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 document_loader::{LoadType, LoadBlocker};
use dom::attr::{Attr, AttrValue};
+use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserElementIconChangeEventDetail;
use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserElementSecurityChangeDetail;
use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserShowModalPromptEventDetail;
@@ -21,7 +23,7 @@ use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
use dom::event::Event;
use dom::eventtarget::EventTarget;
use dom::htmlelement::HTMLElement;
-use dom::node::{Node, UnbindContext, window_from_node};
+use dom::node::{Node, UnbindContext, window_from_node, document_from_node};
use dom::urlhelper::UrlHelper;
use dom::virtualmethods::VirtualMethods;
use dom::window::{ReflowReason, Window};
@@ -64,6 +66,7 @@ pub struct HTMLIFrameElement {
subpage_id: Cell<Option<SubpageId>>,
containing_page_pipeline_id: Cell<Option<PipelineId>>,
sandbox: Cell<Option<u8>>,
+ load_blocker: DOMRefCell<Option<LoadBlocker>>,
}
impl HTMLIFrameElement {
@@ -101,6 +104,20 @@ impl HTMLIFrameElement {
IFrameUnsandboxed
};
+ let document = document_from_node(self);
+
+ let mut load_blocker = self.load_blocker.borrow_mut();
+ // Any oustanding load is finished from the point of view of the blocked
+ // document; the new navigation will continue blocking it.
+ LoadBlocker::terminate(&mut load_blocker);
+
+ //TODO(#9592): Deal with the case where an iframe is being reloaded so url is None.
+ // The iframe should always have access to the nested context's active
+ // document URL through the browsing context.
+ if let Some(ref url) = url {
+ *load_blocker = Some(LoadBlocker::new(&*document, LoadType::Subframe(url.clone())));
+ }
+
let window = window_from_node(self);
let window = window.r();
let (new_subpage_id, old_subpage_id) = self.generate_new_subpage_id();
@@ -173,6 +190,7 @@ impl HTMLIFrameElement {
subpage_id: Cell::new(None),
containing_page_pipeline_id: Cell::new(None),
sandbox: Cell::new(None),
+ load_blocker: DOMRefCell::new(None),
}
}
@@ -204,7 +222,11 @@ impl HTMLIFrameElement {
}
/// https://html.spec.whatwg.org/multipage/#iframe-load-event-steps steps 1-4
- pub fn iframe_load_event_steps(&self) {
+ 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().
+ assert_eq!(loaded_pipeline, self.pipeline().unwrap());
+
// TODO A cross-origin child document would not be easily accessible
// from this script thread. It's unclear how to implement
// steps 2, 3, and 5 efficiently in this case.
@@ -213,6 +235,10 @@ impl HTMLIFrameElement {
// Step 4
self.upcast::<EventTarget>().fire_simple_event("load");
+
+ let mut blocker = self.load_blocker.borrow_mut();
+ LoadBlocker::terminate(&mut blocker);
+
// TODO Step 5 - unset child document `mut iframe load` flag
let window = window_from_node(self);
@@ -510,6 +536,9 @@ impl VirtualMethods for HTMLIFrameElement {
fn unbind_from_tree(&self, context: &UnbindContext) {
self.super_type().unwrap().unbind_from_tree(context);
+ let mut blocker = self.load_blocker.borrow_mut();
+ LoadBlocker::terminate(&mut blocker);
+
// https://html.spec.whatwg.org/multipage/#a-browsing-context-is-discarded
if let Some(pipeline_id) = self.pipeline_id.get() {
let window = window_from_node(self);