Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Window.open and related infrastructure #20678

Merged
merged 7 commits into from Aug 11, 2018
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

implement opener, disowning

  • Loading branch information
gterzian committed Aug 10, 2018
commit 21bf5a3a4b6398cd7c20449ba9110499feca7d6b
@@ -690,6 +690,7 @@ where
browsing_context_id: BrowsingContextId,
top_level_browsing_context_id: TopLevelBrowsingContextId,
parent_info: Option<PipelineId>,
opener: Option<BrowsingContextId>,
initial_window_size: Option<TypedSize2D<f32, CSSPixel>>,
// TODO: we have to provide ownership of the LoadData
// here, because it will be send on an ipc channel,
@@ -764,6 +765,7 @@ where
browsing_context_id,
top_level_browsing_context_id,
parent_info,
opener,
script_to_constellation_chan: ScriptToConstellationChan {
sender: self.script_sender.clone(),
pipeline_id: pipeline_id,
@@ -1256,6 +1258,13 @@ where
warn!("Sending reply to get parent info failed ({:?}).", e);
}
},
FromScriptMsg::GetTopForBrowsingContext(browsing_context_id, sender) => {
let result = self.browsing_contexts.get(&browsing_context_id)
.and_then(|bc| Some(bc.top_level_id));
if let Err(e) = sender.send(result) {
warn!("Sending reply to get top for browsing context info failed ({:?}).", e);
}
},
FromScriptMsg::GetChildBrowsingContextId(browsing_context_id, index, sender) => {
let result = self
.browsing_contexts
@@ -1547,11 +1556,12 @@ where
(window_size, pipeline_id)
};

let (pipeline_url, parent_info) = {
let (pipeline_url, parent_info, opener) = {
let pipeline = pipeline_id.and_then(|id| self.pipelines.get(&id));
let pipeline_url = pipeline.map(|pipeline| pipeline.url.clone());
let parent_info = pipeline.and_then(|pipeline| pipeline.parent_info);
(pipeline_url, parent_info)
let opener = pipeline.and_then(|pipeline| pipeline.opener);
(pipeline_url, parent_info, opener)
};

self.close_browsing_context_children(
@@ -1578,6 +1588,7 @@ where
browsing_context_id,
top_level_browsing_context_id,
parent_info,
opener,
window_size,
load_data.clone(),
sandbox,
@@ -1672,6 +1683,7 @@ where
browsing_context_id,
top_level_browsing_context_id,
None,
None,
Some(window_size),
load_data.clone(),
sandbox,
@@ -1805,6 +1817,7 @@ where
load_info.info.browsing_context_id,
load_info.info.top_level_browsing_context_id,
Some(load_info.info.parent_pipeline_id),
None,
window_size,
load_data.clone(),
load_info.sandbox,
@@ -1850,6 +1863,7 @@ where
browsing_context_id,
top_level_browsing_context_id,
Some(parent_pipeline_id),
None,
script_sender,
layout_sender,
self.compositor_proxy.clone(),
@@ -1887,8 +1901,8 @@ where
let load_data = LoadData::new(url.clone(), None, None, None);

let pipeline = {
let opener_pipeline = match self.pipelines.get(&opener_pipeline_id) {
Some(parent_pipeline) => parent_pipeline,
let (opener_pipeline, opener_id) = match self.pipelines.get(&opener_pipeline_id) {
Some(opener_pipeline) => (opener_pipeline, opener_pipeline.browsing_context_id),
None => return warn!("Auxiliary loaded url in closed pipeline {}.", opener_pipeline_id),
};
let opener_host = match reg_host(&opener_pipeline.url) {
@@ -1907,6 +1921,7 @@ where
new_browsing_context_id,
new_top_level_browsing_context_id,
None,
Some(opener_id),
script_sender,
layout_sender,
self.compositor_proxy.clone(),
@@ -2010,8 +2025,8 @@ where
// requested change so it can update its internal state.
//
// If replace is true, the current entry is replaced instead of a new entry being added.
let (browsing_context_id, parent_info) = match self.pipelines.get(&source_id) {
Some(pipeline) => (pipeline.browsing_context_id, pipeline.parent_info),
let (browsing_context_id, parent_info, opener) = match self.pipelines.get(&source_id) {
Some(pipeline) => (pipeline.browsing_context_id, pipeline.parent_info, pipeline.opener),
None => {
warn!("Pipeline {} loaded after closure.", source_id);
return None;
@@ -2088,6 +2103,7 @@ where
browsing_context_id,
top_level_id,
None,
opener,
window_size,
load_data.clone(),
sandbox,
@@ -2372,19 +2388,21 @@ where
// TODO: Save the sandbox state so it can be restored here.
let sandbox = IFrameSandboxState::IFrameUnsandboxed;
let new_pipeline_id = PipelineId::new();
let (top_level_id, parent_info, window_size, is_private) =
let (top_level_id, parent_info, opener, window_size, is_private) =
match self.browsing_contexts.get(&browsing_context_id) {
Some(browsing_context) => {
match self.pipelines.get(&browsing_context.pipeline_id) {
Some(pipeline) => (
browsing_context.top_level_id,
pipeline.parent_info,
pipeline.opener,
browsing_context.size,
pipeline.is_private,
),
None => (
browsing_context.top_level_id,
None,
None,
browsing_context.size,
false,
),
@@ -2397,6 +2415,7 @@ where
browsing_context_id,
top_level_id,
parent_info,
opener,
window_size,
load_data.clone(),
sandbox,
@@ -62,6 +62,8 @@ pub struct Pipeline {
/// TODO: move this field to `BrowsingContext`.
pub parent_info: Option<PipelineId>,

pub opener: Option<BrowsingContextId>,

/// The event loop handling this pipeline.
pub event_loop: Rc<EventLoop>,

@@ -119,6 +121,8 @@ pub struct InitialPipelineState {
/// If `None`, this is the root.
pub parent_info: Option<PipelineId>,

pub opener: Option<BrowsingContextId>,

/// A channel to the associated constellation.
pub script_to_constellation_chan: ScriptToConstellationChan,

@@ -216,6 +220,7 @@ impl Pipeline {
new_pipeline_id: state.id,
browsing_context_id: state.browsing_context_id,
top_level_browsing_context_id: state.top_level_browsing_context_id,
opener: state.opener,
load_data: state.load_data.clone(),
window_size: window_size,
pipeline_port: pipeline_port,
@@ -266,6 +271,7 @@ impl Pipeline {
browsing_context_id: state.browsing_context_id,
top_level_browsing_context_id: state.top_level_browsing_context_id,
parent_info: state.parent_info,
opener: state.opener,
script_to_constellation_chan: state.script_to_constellation_chan.clone(),
scheduler_chan: state.scheduler_chan,
devtools_chan: script_to_devtools_chan,
@@ -312,6 +318,7 @@ impl Pipeline {
state.browsing_context_id,
state.top_level_browsing_context_id,
state.parent_info,
state.opener,
script_chan,
pipeline_chan,
state.compositor_proxy,
@@ -329,6 +336,7 @@ impl Pipeline {
browsing_context_id: BrowsingContextId,
top_level_browsing_context_id: TopLevelBrowsingContextId,
parent_info: Option<PipelineId>,
opener: Option<BrowsingContextId>,
event_loop: Rc<EventLoop>,
layout_chan: IpcSender<LayoutControlMsg>,
compositor_proxy: CompositorProxy,
@@ -342,6 +350,7 @@ impl Pipeline {
browsing_context_id: browsing_context_id,
top_level_browsing_context_id: top_level_browsing_context_id,
parent_info: parent_info,
opener: opener,
event_loop: event_loop,
layout_chan: layout_chan,
compositor_proxy: compositor_proxy,
@@ -469,6 +478,7 @@ pub struct UnprivilegedPipelineContent {
top_level_browsing_context_id: TopLevelBrowsingContextId,
browsing_context_id: BrowsingContextId,
parent_info: Option<PipelineId>,
opener: Option<BrowsingContextId>,
script_to_constellation_chan: ScriptToConstellationChan,
layout_to_constellation_chan: IpcSender<LayoutMsg>,
scheduler_chan: IpcSender<TimerSchedulerMsg>,
@@ -517,6 +527,7 @@ impl UnprivilegedPipelineContent {
browsing_context_id: self.browsing_context_id,
top_level_browsing_context_id: self.top_level_browsing_context_id,
parent_info: self.parent_info,
opener: self.opener,
control_chan: self.script_chan.clone(),
control_port: self.script_port,
script_to_constellation_chan: self.script_to_constellation_chan.clone(),
@@ -177,6 +177,7 @@ impl HTMLIFrameElement {
new_pipeline_id: new_pipeline_id,
browsing_context_id: browsing_context_id,
top_level_browsing_context_id: top_level_browsing_context_id,
opener: None,
load_data: load_data.unwrap(),
pipeline_port: pipeline_receiver,
content_process_shutdown_chan: None,
@@ -35,7 +35,7 @@
// Note that this can return null in the case that the browsing context has been discarded.
// https://github.com/whatwg/html/issues/2115
[Unforgeable] readonly attribute WindowProxy? top;
// attribute any opener;
attribute any opener;
// Note that this can return null in the case that the browsing context has been discarded.
// https://github.com/whatwg/html/issues/2115
[Replaceable] readonly attribute WindowProxy? parent;
@@ -61,10 +61,12 @@ use fetch;
use ipc_channel::ipc::IpcSender;
use ipc_channel::router::ROUTER;
use js::jsapi::{JSAutoCompartment, JSContext};
use js::jsapi::{JS_GC, JS_GetRuntime};
use js::jsval::UndefinedValue;
use js::jsapi::{JS_GC, JS_GetRuntime, JSPROP_ENUMERATE};
use js::jsval::{JSVal, UndefinedValue};
use js::rust::HandleValue;
use js::rust::wrappers::JS_DefineProperty;
use layout_image::fetch_image_for_layout;
use libc;
use microtask::MicrotaskQueue;
use msg::constellation_msg::PipelineId;
use net_traits::{ResourceThreads, ReferrerPolicy};
@@ -574,6 +576,30 @@ impl WindowMethods for Window {
self.window_proxy().open(url, target, features)
}

#[allow(unsafe_code)]
// https://html.spec.whatwg.org/multipage/#dom-opener
unsafe fn Opener(&self, cx: *mut JSContext) -> JSVal {
self.window_proxy().opener(cx)
}

#[allow(unsafe_code)]
// https://html.spec.whatwg.org/multipage/#dom-opener
unsafe fn SetOpener(&self, cx: *mut JSContext, value: HandleValue) {
// Step 1.
if value.is_null() {
return self.window_proxy().disown();
}
// Step 2.
let obj = self.reflector().get_jsobject();
assert!(JS_DefineProperty(cx,
obj,
"opener\0".as_ptr() as *const libc::c_char,
value,
JSPROP_ENUMERATE,
None,
None));
}

// https://html.spec.whatwg.org/multipage/#dom-window-closed
fn Closed(&self) -> bool {
self.window_proxy.get()
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.