mirror of
https://github.com/servo/servo.git
synced 2025-08-01 11:40:30 +01:00
implement window.stop, improve aborting document load
This commit is contained in:
parent
aab335e543
commit
ff62ca7c01
10 changed files with 49 additions and 18 deletions
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
use dom::bindings::root::Dom;
|
use dom::bindings::root::Dom;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
|
use fetch::FetchCanceller;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
use net_traits::{CoreResourceMsg, FetchChannels, FetchResponseMsg};
|
use net_traits::{CoreResourceMsg, FetchChannels, FetchResponseMsg};
|
||||||
use net_traits::{ResourceThreads, IpcSend};
|
use net_traits::{ResourceThreads, IpcSend};
|
||||||
|
@ -87,6 +88,7 @@ pub struct DocumentLoader {
|
||||||
resource_threads: ResourceThreads,
|
resource_threads: ResourceThreads,
|
||||||
blocking_loads: Vec<LoadType>,
|
blocking_loads: Vec<LoadType>,
|
||||||
events_inhibited: bool,
|
events_inhibited: bool,
|
||||||
|
cancellers: Vec<FetchCanceller>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DocumentLoader {
|
impl DocumentLoader {
|
||||||
|
@ -103,9 +105,17 @@ impl DocumentLoader {
|
||||||
resource_threads: resource_threads,
|
resource_threads: resource_threads,
|
||||||
blocking_loads: initial_loads,
|
blocking_loads: initial_loads,
|
||||||
events_inhibited: false,
|
events_inhibited: false,
|
||||||
|
cancellers: Vec::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cancel_all_loads(&mut self) -> bool {
|
||||||
|
let canceled_any = !self.cancellers.is_empty();
|
||||||
|
// Associated fetches will be canceled when dropping the canceller.
|
||||||
|
self.cancellers.clear();
|
||||||
|
canceled_any
|
||||||
|
}
|
||||||
|
|
||||||
/// Add a load to the list of blocking loads.
|
/// Add a load to the list of blocking loads.
|
||||||
fn add_blocking_load(&mut self, load: LoadType) {
|
fn add_blocking_load(&mut self, load: LoadType) {
|
||||||
debug!("Adding blocking load {:?} ({}).", load, self.blocking_loads.len());
|
debug!("Adding blocking load {:?} ({}).", load, self.blocking_loads.len());
|
||||||
|
@ -122,11 +132,14 @@ impl DocumentLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initiate a new fetch that does not block the document load event.
|
/// Initiate a new fetch that does not block the document load event.
|
||||||
pub fn fetch_async_background(&self,
|
pub fn fetch_async_background(&mut self,
|
||||||
request: RequestInit,
|
request: RequestInit,
|
||||||
fetch_target: IpcSender<FetchResponseMsg>) {
|
fetch_target: IpcSender<FetchResponseMsg>) {
|
||||||
|
let mut canceller = FetchCanceller::new();
|
||||||
|
let cancel_receiver = canceller.initialize();
|
||||||
|
self.cancellers.push(canceller);
|
||||||
self.resource_threads.sender().send(
|
self.resource_threads.sender().send(
|
||||||
CoreResourceMsg::Fetch(request, FetchChannels::ResponseMsg(fetch_target, None))).unwrap();
|
CoreResourceMsg::Fetch(request, FetchChannels::ResponseMsg(fetch_target, Some(cancel_receiver)))).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark an in-progress network request complete.
|
/// Mark an in-progress network request complete.
|
||||||
|
|
|
@ -141,7 +141,7 @@ use style::shared_lock::{SharedRwLock as StyleSharedRwLock, SharedRwLockReadGuar
|
||||||
use style::str::{split_html_space_chars, str_join};
|
use style::str::{split_html_space_chars, str_join};
|
||||||
use style::stylesheet_set::DocumentStylesheetSet;
|
use style::stylesheet_set::DocumentStylesheetSet;
|
||||||
use style::stylesheets::{CssRule, Stylesheet, Origin, OriginSet};
|
use style::stylesheets::{CssRule, Stylesheet, Origin, OriginSet};
|
||||||
use task_source::TaskSource;
|
use task_source::{TaskSource, TaskSourceName};
|
||||||
use time;
|
use time;
|
||||||
use timers::OneshotTimerCallback;
|
use timers::OneshotTimerCallback;
|
||||||
use url::Host;
|
use url::Host;
|
||||||
|
@ -2010,7 +2010,7 @@ impl Document {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#abort-a-document
|
// https://html.spec.whatwg.org/multipage/#abort-a-document
|
||||||
fn abort(&self) {
|
pub fn abort(&self) {
|
||||||
// We need to inhibit the loader before anything else.
|
// We need to inhibit the loader before anything else.
|
||||||
self.loader.borrow_mut().inhibit_events();
|
self.loader.borrow_mut().inhibit_events();
|
||||||
|
|
||||||
|
@ -2029,14 +2029,21 @@ impl Document {
|
||||||
*self.asap_scripts_set.borrow_mut() = vec![];
|
*self.asap_scripts_set.borrow_mut() = vec![];
|
||||||
self.asap_in_order_scripts_list.clear();
|
self.asap_in_order_scripts_list.clear();
|
||||||
self.deferred_scripts.clear();
|
self.deferred_scripts.clear();
|
||||||
|
if self.loader.borrow_mut().cancel_all_loads() {
|
||||||
|
// If any loads were canceled.
|
||||||
|
self.salvageable.set(false);
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: https://github.com/servo/servo/issues/15236
|
// Also Step 2.
|
||||||
self.window.cancel_all_tasks();
|
// Note: the spec says to discard any tasks queued for fetch.
|
||||||
|
// This cancels all tasks on the networking task source, which might be too broad.
|
||||||
|
// See https://github.com/whatwg/html/issues/3837
|
||||||
|
self.window.cancel_all_tasks_from_source(TaskSourceName::Networking);
|
||||||
|
|
||||||
// Step 3.
|
// Step 3.
|
||||||
if let Some(parser) = self.get_current_parser() {
|
if let Some(parser) = self.get_current_parser() {
|
||||||
parser.abort();
|
parser.abort();
|
||||||
// TODO: salvageable flag.
|
self.salvageable.set(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -268,7 +268,7 @@ impl HTMLImageElement {
|
||||||
|
|
||||||
// This is a background load because the load blocker already fulfills the
|
// This is a background load because the load blocker already fulfills the
|
||||||
// purpose of delaying the document's load event.
|
// purpose of delaying the document's load event.
|
||||||
document.loader().fetch_async_background(request, action_sender);
|
document.loader_mut().fetch_async_background(request, action_sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Step 14 of https://html.spec.whatwg.org/multipage/#update-the-image-data
|
/// Step 14 of https://html.spec.whatwg.org/multipage/#update-the-image-data
|
||||||
|
|
|
@ -613,7 +613,7 @@ impl HTMLMediaElement {
|
||||||
ROUTER.add_route(action_receiver.to_opaque(), Box::new(move |message| {
|
ROUTER.add_route(action_receiver.to_opaque(), Box::new(move |message| {
|
||||||
listener.notify_fetch(message.to().unwrap());
|
listener.notify_fetch(message.to().unwrap());
|
||||||
}));
|
}));
|
||||||
document.loader().fetch_async_background(request, action_sender);
|
document.loader_mut().fetch_async_background(request, action_sender);
|
||||||
},
|
},
|
||||||
Resource::Object => {
|
Resource::Object => {
|
||||||
// FIXME(nox): Actually do something with the object.
|
// FIXME(nox): Actually do something with the object.
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
attribute DOMString status;
|
attribute DOMString status;
|
||||||
void close();
|
void close();
|
||||||
readonly attribute boolean closed;
|
readonly attribute boolean closed;
|
||||||
//void stop();
|
void stop();
|
||||||
//void focus();
|
//void focus();
|
||||||
//void blur();
|
//void blur();
|
||||||
|
|
||||||
|
|
|
@ -552,6 +552,13 @@ impl WindowMethods for Window {
|
||||||
receiver.recv().unwrap();
|
receiver.recv().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/#dom-window-stop
|
||||||
|
fn Stop(&self) {
|
||||||
|
// TODO: Cancel ongoing navigation.
|
||||||
|
let doc = self.Document();
|
||||||
|
doc.abort();
|
||||||
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-window-closed
|
// https://html.spec.whatwg.org/multipage/#dom-window-closed
|
||||||
fn Closed(&self) -> bool {
|
fn Closed(&self) -> bool {
|
||||||
self.window_proxy.get()
|
self.window_proxy.get()
|
||||||
|
@ -1110,6 +1117,16 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Cancels all the tasks from a given task source.
|
||||||
|
/// This sets the current sentinel value to
|
||||||
|
/// `true` and replaces it with a brand new one for future tasks.
|
||||||
|
pub fn cancel_all_tasks_from_source(&self, task_source_name: TaskSourceName) {
|
||||||
|
let mut ignore_flags = self.ignore_further_async_events.borrow_mut();
|
||||||
|
let flag = ignore_flags.entry(task_source_name).or_insert(Default::default());
|
||||||
|
let cancelled = mem::replace(&mut *flag, Default::default());
|
||||||
|
cancelled.store(true, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn clear_js_runtime(&self) {
|
pub fn clear_js_runtime(&self) {
|
||||||
// We tear down the active document, which causes all the attached
|
// We tear down the active document, which causes all the attached
|
||||||
// nodes to dispose of their layout data. This messages the layout
|
// nodes to dispose of their layout data. This messages the layout
|
||||||
|
|
|
@ -78,5 +78,5 @@ pub fn fetch_image_for_layout(url: ServoUrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Layout image loads do not delay the document load event.
|
// Layout image loads do not delay the document load event.
|
||||||
document.loader().fetch_async_background(request, action_sender);
|
document.loader_mut().fetch_async_background(request, action_sender);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
[window-properties.https.html]
|
[window-properties.https.html]
|
||||||
[Window method: stop]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Window method: focus]
|
[Window method: focus]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
[script-onerror-insertion-point-2.html]
|
|
||||||
type: testharness
|
|
||||||
expected: TIMEOUT
|
|
Loading…
Add table
Add a link
Reference in a new issue