mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Make iframes block the enclosing document's load event. Fixes #6663.
This commit is contained in:
parent
fc3f93235e
commit
e9b98ad5fa
17 changed files with 2054 additions and 19 deletions
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue