Skip to content

Commit 5a38298

Browse files
committed
Implement synchronous about:blank loading.
Based on initial work by jdm in <#8600>.
1 parent 6cf69c8 commit 5a38298

File tree

9 files changed

+264
-51
lines changed

9 files changed

+264
-51
lines changed

components/constellation/constellation.rs

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use rand::{Rng, SeedableRng, StdRng, random};
4040
use script_traits::{AnimationState, AnimationTickType, CompositorEvent};
4141
use script_traits::{ConstellationControlMsg, ConstellationMsg as FromCompositorMsg};
4242
use script_traits::{DocumentState, LayoutControlMsg, LoadData};
43-
use script_traits::{IFrameLoadInfo, IFrameSandboxState, TimerEventRequest};
43+
use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, IFrameSandboxState, TimerEventRequest};
4444
use script_traits::{LayoutMsg as FromLayoutMsg, ScriptMsg as FromScriptMsg, ScriptThreadFactory};
4545
use script_traits::{LogEntry, ServiceWorkerMsg, webdriver_msg};
4646
use script_traits::{MozBrowserErrorType, MozBrowserEvent, WebDriverCommandMsg, WindowSizeData};
@@ -824,11 +824,17 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
824824
}
825825
FromScriptMsg::ScriptLoadedURLInIFrame(load_info) => {
826826
debug!("constellation got iframe URL load message {:?} {:?} {:?}",
827-
load_info.parent_pipeline_id,
827+
load_info.info.parent_pipeline_id,
828828
load_info.old_pipeline_id,
829-
load_info.new_pipeline_id);
829+
load_info.info.new_pipeline_id);
830830
self.handle_script_loaded_url_in_iframe_msg(load_info);
831831
}
832+
FromScriptMsg::ScriptDidLoadURLInIFrame(load_info, sc, lc) => {
833+
debug!("constellation got did load iframe URL message {:?} {:?}",
834+
load_info.parent_pipeline_id,
835+
load_info.new_pipeline_id);
836+
self.handle_script_did_load_url_in_iframe_msg(load_info, sc, lc);
837+
}
832838
FromScriptMsg::ChangeRunningAnimationsState(pipeline_id, animation_state) => {
833839
self.handle_change_running_animations_state(pipeline_id, animation_state)
834840
}
@@ -1233,14 +1239,14 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
12331239
// will result in a new pipeline being spawned and a frame tree being added to
12341240
// parent_pipeline_id's frame tree's children. This message is never the result of a
12351241
// page navigation.
1236-
fn handle_script_loaded_url_in_iframe_msg(&mut self, load_info: IFrameLoadInfo) {
1242+
fn handle_script_loaded_url_in_iframe_msg(&mut self, load_info: IFrameLoadInfoWithData) {
12371243
let (load_data, script_chan, window_size, is_private) = {
12381244
let old_pipeline = load_info.old_pipeline_id
12391245
.and_then(|old_pipeline_id| self.pipelines.get(&old_pipeline_id));
12401246

1241-
let source_pipeline = match self.pipelines.get(&load_info.parent_pipeline_id) {
1247+
let source_pipeline = match self.pipelines.get(&load_info.info.parent_pipeline_id) {
12421248
Some(source_pipeline) => source_pipeline,
1243-
None => return warn!("Script loaded url in closed iframe {}.", load_info.parent_pipeline_id),
1249+
None => return warn!("Script loaded url in closed iframe {}.", load_info.info.parent_pipeline_id),
12441250
};
12451251

12461252
// If no url is specified, reload.
@@ -1258,7 +1264,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
12581264
// then reuse the script thread in creating the new pipeline
12591265
let source_url = &source_pipeline.url;
12601266

1261-
let is_private = load_info.is_private || source_pipeline.is_private;
1267+
let is_private = load_info.info.is_private || source_pipeline.is_private;
12621268

12631269
// FIXME(#10968): this should probably match the origin check in
12641270
// HTMLIFrameElement::contentDocument.
@@ -1287,23 +1293,66 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
12871293
(load_data, script_chan, window_size, is_private)
12881294
};
12891295

1290-
12911296
// Create the new pipeline, attached to the parent and push to pending frames
1292-
self.new_pipeline(load_info.new_pipeline_id,
1293-
load_info.frame_id,
1294-
Some((load_info.parent_pipeline_id, load_info.frame_type)),
1297+
self.new_pipeline(load_info.info.new_pipeline_id,
1298+
load_info.info.frame_id,
1299+
Some((load_info.info.parent_pipeline_id, load_info.info.frame_type)),
12951300
load_info.old_pipeline_id,
12961301
window_size,
12971302
script_chan,
12981303
load_data,
12991304
is_private);
13001305

13011306
self.pending_frames.push(FrameChange {
1302-
frame_id: load_info.frame_id,
1307+
frame_id: load_info.info.frame_id,
13031308
old_pipeline_id: load_info.old_pipeline_id,
1304-
new_pipeline_id: load_info.new_pipeline_id,
1309+
new_pipeline_id: load_info.info.new_pipeline_id,
1310+
document_ready: false,
1311+
replace: load_info.info.replace,
1312+
});
1313+
}
1314+
1315+
fn handle_script_did_load_url_in_iframe_msg(&mut self,
1316+
load_info: IFrameLoadInfo,
1317+
script_sender: IpcSender<ConstellationControlMsg>,
1318+
layout_sender: IpcSender<LayoutControlMsg>) {
1319+
let IFrameLoadInfo {
1320+
parent_pipeline_id,
1321+
new_pipeline_id,
1322+
frame_type,
1323+
replace,
1324+
frame_id,
1325+
is_private,
1326+
} = load_info;
1327+
1328+
let pipeline = {
1329+
let parent_pipeline = match self.pipelines.get(&parent_pipeline_id) {
1330+
Some(parent_pipeline) => parent_pipeline,
1331+
None => return warn!("Script loaded url in closed iframe {}.", parent_pipeline_id),
1332+
};
1333+
1334+
let url = Url::parse("about:blank").expect("infallible");
1335+
Pipeline::spawned(new_pipeline_id,
1336+
frame_id,
1337+
Some((parent_pipeline_id, frame_type)),
1338+
script_sender,
1339+
layout_sender,
1340+
self.compositor_proxy.clone_compositor_proxy(),
1341+
is_private || parent_pipeline.is_private,
1342+
url,
1343+
None,
1344+
parent_pipeline.visible)
1345+
};
1346+
1347+
assert!(!self.pipelines.contains_key(&new_pipeline_id));
1348+
self.pipelines.insert(new_pipeline_id, pipeline);
1349+
1350+
self.pending_frames.push(FrameChange {
1351+
frame_id: frame_id,
1352+
old_pipeline_id: None,
1353+
new_pipeline_id: new_pipeline_id,
13051354
document_ready: false,
1306-
replace: load_info.replace,
1355+
replace: replace,
13071356
});
13081357
}
13091358

components/constellation/pipeline.rs

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,7 @@ impl Pipeline {
155155
frame_type: frame_type,
156156
load_data: state.load_data.clone(),
157157
pipeline_port: pipeline_port,
158-
layout_to_constellation_chan: state.layout_to_constellation_chan.clone(),
159-
content_process_shutdown_chan: layout_content_process_shutdown_chan.clone(),
158+
content_process_shutdown_chan: Some(layout_content_process_shutdown_chan.clone()),
160159
layout_threads: PREFS.get("layout.threads").as_u64().expect("count") as usize,
161160
};
162161

@@ -256,6 +255,35 @@ impl Pipeline {
256255
Ok((pipeline, child_process))
257256
}
258257

258+
/// Creates a `Pipeline` for a layout thread that was spawned from an
259+
/// existing script thread.
260+
pub fn spawned(id: PipelineId,
261+
frame_id: FrameId,
262+
parent_info: Option<(PipelineId, FrameType)>,
263+
script_chan: IpcSender<ConstellationControlMsg>,
264+
layout_chan: IpcSender<LayoutControlMsg>,
265+
compositor_proxy: Box<CompositorProxy + 'static + Send>,
266+
is_private: bool,
267+
url: Url,
268+
size: Option<TypedSize2D<f32, PagePx>>,
269+
visible: bool)
270+
-> Pipeline {
271+
let pipeline = Pipeline::new(id,
272+
frame_id,
273+
parent_info,
274+
script_chan,
275+
layout_chan,
276+
compositor_proxy,
277+
is_private,
278+
url,
279+
size,
280+
visible);
281+
282+
pipeline.notify_visibility();
283+
284+
pipeline
285+
}
286+
259287
fn new(id: PipelineId,
260288
frame_id: FrameId,
261289
parent_info: Option<(PipelineId, FrameType)>,
@@ -418,6 +446,7 @@ impl UnprivilegedPipelineContent {
418446
control_chan: self.script_chan.clone(),
419447
control_port: self.script_port,
420448
constellation_chan: self.constellation_chan,
449+
layout_to_constellation_chan: self.layout_to_constellation_chan.clone(),
421450
scheduler_chan: self.scheduler_chan,
422451
bluetooth_thread: self.bluetooth_thread,
423452
resource_threads: self.resource_threads,
@@ -441,7 +470,7 @@ impl UnprivilegedPipelineContent {
441470
self.font_cache_thread,
442471
self.time_profiler_chan,
443472
self.mem_profiler_chan,
444-
self.layout_content_process_shutdown_chan,
473+
Some(self.layout_content_process_shutdown_chan),
445474
self.webrender_api_sender,
446475
self.prefs.get("layout.threads").expect("exists").value()
447476
.as_u64().expect("count") as usize);

components/layout_thread/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ impl LayoutThreadFactory for LayoutThread {
250250
font_cache_thread: FontCacheThread,
251251
time_profiler_chan: time::ProfilerChan,
252252
mem_profiler_chan: mem::ProfilerChan,
253-
content_process_shutdown_chan: IpcSender<()>,
253+
content_process_shutdown_chan: Option<IpcSender<()>>,
254254
webrender_api_sender: webrender_traits::RenderApiSender,
255255
layout_threads: usize) {
256256
thread::spawn_named(format!("LayoutThread {:?}", id),
@@ -278,7 +278,9 @@ impl LayoutThreadFactory for LayoutThread {
278278
layout.start();
279279
}, reporter_name, sender, Msg::CollectReports);
280280
}
281-
let _ = content_process_shutdown_chan.send(());
281+
if let Some(content_process_shutdown_chan) = content_process_shutdown_chan {
282+
let _ = content_process_shutdown_chan.send(());
283+
}
282284
});
283285
}
284286
}

components/layout_traits/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub trait LayoutThreadFactory {
4343
font_cache_thread: FontCacheThread,
4444
time_profiler_chan: time::ProfilerChan,
4545
mem_profiler_chan: mem::ProfilerChan,
46-
content_process_shutdown_chan: IpcSender<()>,
46+
content_process_shutdown_chan: Option<IpcSender<()>>,
4747
webrender_api_sender: webrender_traits::RenderApiSender,
4848
layout_threads: usize);
4949
}

0 commit comments

Comments
 (0)