mirror of
https://github.com/servo/servo.git
synced 2025-07-26 00:30:22 +01:00
Implement dissimilar-origin window.parent and window.top.
This commit is contained in:
parent
0b590aeed7
commit
6bcb5f68be
9 changed files with 207 additions and 87 deletions
|
@ -1092,7 +1092,18 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
FromScriptMsg::TouchEventProcessed(result) => {
|
FromScriptMsg::TouchEventProcessed(result) => {
|
||||||
self.compositor_proxy.send(ToCompositorMsg::TouchEventProcessed(result))
|
self.compositor_proxy.send(ToCompositorMsg::TouchEventProcessed(result))
|
||||||
}
|
}
|
||||||
|
FromScriptMsg::GetFrameId(pipeline_id, sender) => {
|
||||||
|
let result = self.pipelines.get(&pipeline_id).map(|pipeline| pipeline.frame_id);
|
||||||
|
if let Err(e) = sender.send(result) {
|
||||||
|
warn!("Sending reply to get frame id failed ({:?}).", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FromScriptMsg::GetParentInfo(pipeline_id, sender) => {
|
||||||
|
let result = self.pipelines.get(&pipeline_id).and_then(|pipeline| pipeline.parent_info);
|
||||||
|
if let Err(e) = sender.send(result) {
|
||||||
|
warn!("Sending reply to get parent info failed ({:?}).", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
FromScriptMsg::RegisterServiceWorker(scope_things, scope) => {
|
FromScriptMsg::RegisterServiceWorker(scope_things, scope) => {
|
||||||
debug!("constellation got store registration scope message");
|
debug!("constellation got store registration scope message");
|
||||||
self.handle_register_serviceworker(scope_things, scope);
|
self.handle_register_serviceworker(scope_things, scope);
|
||||||
|
|
|
@ -63,25 +63,35 @@ pub struct BrowsingContext {
|
||||||
|
|
||||||
/// The containing iframe element, if this is a same-origin iframe
|
/// The containing iframe element, if this is a same-origin iframe
|
||||||
frame_element: Option<JS<Element>>,
|
frame_element: Option<JS<Element>>,
|
||||||
|
|
||||||
|
/// The parent browsing context, if this is a nested browsing context
|
||||||
|
parent: Option<JS<BrowsingContext>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BrowsingContext {
|
impl BrowsingContext {
|
||||||
pub fn new_inherited(frame_id: FrameId,
|
pub fn new_inherited(frame_id: FrameId,
|
||||||
currently_active: PipelineId,
|
currently_active: Option<PipelineId>,
|
||||||
frame_element: Option<&Element>)
|
frame_element: Option<&Element>,
|
||||||
|
parent: Option<&BrowsingContext>)
|
||||||
-> BrowsingContext
|
-> BrowsingContext
|
||||||
{
|
{
|
||||||
BrowsingContext {
|
BrowsingContext {
|
||||||
reflector: Reflector::new(),
|
reflector: Reflector::new(),
|
||||||
frame_id: frame_id,
|
frame_id: frame_id,
|
||||||
currently_active: Cell::new(Some(currently_active)),
|
currently_active: Cell::new(currently_active),
|
||||||
discarded: Cell::new(false),
|
discarded: Cell::new(false),
|
||||||
frame_element: frame_element.map(JS::from_ref),
|
frame_element: frame_element.map(JS::from_ref),
|
||||||
|
parent: parent.map(JS::from_ref),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub fn new(window: &Window, frame_id: FrameId, frame_element: Option<&Element>) -> Root<BrowsingContext> {
|
pub fn new(window: &Window,
|
||||||
|
frame_id: FrameId,
|
||||||
|
frame_element: Option<&Element>,
|
||||||
|
parent: Option<&BrowsingContext>)
|
||||||
|
-> Root<BrowsingContext>
|
||||||
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let WindowProxyHandler(handler) = window.windowproxy_handler();
|
let WindowProxyHandler(handler) = window.windowproxy_handler();
|
||||||
assert!(!handler.is_null());
|
assert!(!handler.is_null());
|
||||||
|
@ -97,8 +107,48 @@ impl BrowsingContext {
|
||||||
assert!(!window_proxy.is_null());
|
assert!(!window_proxy.is_null());
|
||||||
|
|
||||||
// Create a new browsing context.
|
// Create a new browsing context.
|
||||||
let currently_active = window.global().pipeline_id();
|
let current = Some(window.global().pipeline_id());
|
||||||
let mut browsing_context = box BrowsingContext::new_inherited(frame_id, currently_active, frame_element);
|
let mut browsing_context = box BrowsingContext::new_inherited(frame_id, current, frame_element, parent);
|
||||||
|
|
||||||
|
// The window proxy owns the browsing context.
|
||||||
|
// When we finalize the window proxy, it drops the browsing context it owns.
|
||||||
|
SetProxyExtra(window_proxy.get(), 0, &PrivateValue(&*browsing_context as *const _ as *const _));
|
||||||
|
|
||||||
|
// Notify the JS engine about the new window proxy binding.
|
||||||
|
SetWindowProxy(cx, window_jsobject, window_proxy.handle());
|
||||||
|
|
||||||
|
// Set the reflector.
|
||||||
|
debug!("Initializing reflector of {:p} to {:p}.", browsing_context, window_proxy.get());
|
||||||
|
browsing_context.reflector.set_jsobject(window_proxy.get());
|
||||||
|
Root::from_ref(&*Box::into_raw(browsing_context))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
pub fn new_dissimilar_origin(global_to_clone_from: &GlobalScope,
|
||||||
|
frame_id: FrameId,
|
||||||
|
parent: Option<&BrowsingContext>)
|
||||||
|
-> Root<BrowsingContext>
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
let handler = CreateWrapperProxyHandler(&XORIGIN_PROXY_HANDLER);
|
||||||
|
assert!(!handler.is_null());
|
||||||
|
|
||||||
|
let cx = global_to_clone_from.get_cx();
|
||||||
|
|
||||||
|
// Create a new browsing context.
|
||||||
|
let mut browsing_context = box BrowsingContext::new_inherited(frame_id, None, None, parent);
|
||||||
|
|
||||||
|
// Create a new dissimilar-origin window.
|
||||||
|
let window = DissimilarOriginWindow::new(global_to_clone_from, &*browsing_context);
|
||||||
|
let window_jsobject = window.reflector().get_jsobject();
|
||||||
|
assert!(!window_jsobject.get().is_null());
|
||||||
|
assert!(((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL) != 0);
|
||||||
|
let _ac = JSAutoCompartment::new(cx, window_jsobject.get());
|
||||||
|
|
||||||
|
// Create a new window proxy.
|
||||||
|
rooted!(in(cx) let window_proxy = NewWindowProxy(cx, window_jsobject, handler));
|
||||||
|
assert!(!window_proxy.is_null());
|
||||||
|
|
||||||
// The window proxy owns the browsing context.
|
// The window proxy owns the browsing context.
|
||||||
// When we finalize the window proxy, it drops the browsing context it owns.
|
// When we finalize the window proxy, it drops the browsing context it owns.
|
||||||
|
@ -130,6 +180,18 @@ impl BrowsingContext {
|
||||||
self.frame_element.r()
|
self.frame_element.r()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parent(&self) -> Option<&BrowsingContext> {
|
||||||
|
self.parent.r()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn top(&self) -> &BrowsingContext {
|
||||||
|
let mut result = self;
|
||||||
|
while let Some(parent) = result.parent() {
|
||||||
|
result = parent;
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
/// Change the Window that this browsing context's WindowProxy resolves to.
|
/// Change the Window that this browsing context's WindowProxy resolves to.
|
||||||
// TODO: support setting the window proxy to a dummy value,
|
// TODO: support setting the window proxy to a dummy value,
|
||||||
|
@ -181,7 +243,8 @@ impl BrowsingContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unset_currently_active(&self) {
|
pub fn unset_currently_active(&self) {
|
||||||
let window = DissimilarOriginWindow::new(self);
|
let globalscope = self.global();
|
||||||
|
let window = DissimilarOriginWindow::new(&*globalscope, self);
|
||||||
self.set_window_proxy(&*window.upcast(), &XORIGIN_PROXY_HANDLER);
|
self.set_window_proxy(&*window.upcast(), &XORIGIN_PROXY_HANDLER);
|
||||||
self.currently_active.set(None);
|
self.currently_active.set(None);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ use dom::bindings::codegen::Bindings::DissimilarOriginWindowBinding::DissimilarO
|
||||||
use dom::bindings::error::{Error, ErrorResult};
|
use dom::bindings::error::{Error, ErrorResult};
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::js::{JS, MutNullableJS, Root};
|
use dom::bindings::js::{JS, MutNullableJS, Root};
|
||||||
use dom::bindings::reflector::DomObject;
|
|
||||||
use dom::bindings::str::DOMString;
|
use dom::bindings::str::DOMString;
|
||||||
use dom::bindings::structuredclone::StructuredCloneData;
|
use dom::bindings::structuredclone::StructuredCloneData;
|
||||||
use dom::browsingcontext::BrowsingContext;
|
use dom::browsingcontext::BrowsingContext;
|
||||||
|
@ -45,19 +44,18 @@ pub struct DissimilarOriginWindow {
|
||||||
|
|
||||||
impl DissimilarOriginWindow {
|
impl DissimilarOriginWindow {
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub fn new(browsing_context: &BrowsingContext) -> Root<DissimilarOriginWindow> {
|
pub fn new(global_to_clone_from: &GlobalScope, browsing_context: &BrowsingContext) -> Root<DissimilarOriginWindow> {
|
||||||
let globalscope = browsing_context.global();
|
let cx = global_to_clone_from.get_cx();
|
||||||
let cx = globalscope.get_cx();
|
|
||||||
// Any timer events fired on this window are ignored.
|
// Any timer events fired on this window are ignored.
|
||||||
let (timer_event_chan, _) = ipc::channel().unwrap();
|
let (timer_event_chan, _) = ipc::channel().unwrap();
|
||||||
let win = box DissimilarOriginWindow {
|
let win = box DissimilarOriginWindow {
|
||||||
globalscope: GlobalScope::new_inherited(PipelineId::new(),
|
globalscope: GlobalScope::new_inherited(PipelineId::new(),
|
||||||
globalscope.devtools_chan().cloned(),
|
global_to_clone_from.devtools_chan().cloned(),
|
||||||
globalscope.mem_profiler_chan().clone(),
|
global_to_clone_from.mem_profiler_chan().clone(),
|
||||||
globalscope.time_profiler_chan().clone(),
|
global_to_clone_from.time_profiler_chan().clone(),
|
||||||
globalscope.constellation_chan().clone(),
|
global_to_clone_from.constellation_chan().clone(),
|
||||||
globalscope.scheduler_chan().clone(),
|
global_to_clone_from.scheduler_chan().clone(),
|
||||||
globalscope.resource_threads().clone(),
|
global_to_clone_from.resource_threads().clone(),
|
||||||
timer_event_chan),
|
timer_event_chan),
|
||||||
browsing_context: JS::from_ref(browsing_context),
|
browsing_context: JS::from_ref(browsing_context),
|
||||||
location: MutNullableJS::new(None),
|
location: MutNullableJS::new(None),
|
||||||
|
@ -84,14 +82,26 @@ impl DissimilarOriginWindowMethods for DissimilarOriginWindow {
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-parent
|
// https://html.spec.whatwg.org/multipage/#dom-parent
|
||||||
fn GetParent(&self) -> Option<Root<BrowsingContext>> {
|
fn GetParent(&self) -> Option<Root<BrowsingContext>> {
|
||||||
// TODO: implement window.parent correctly for x-origin windows.
|
// Steps 1-3.
|
||||||
|
if self.browsing_context.is_discarded() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
// Step 4.
|
||||||
|
if let Some(parent) = self.browsing_context.parent() {
|
||||||
|
return Some(Root::from_ref(parent));
|
||||||
|
}
|
||||||
|
// Step 5.
|
||||||
Some(Root::from_ref(&*self.browsing_context))
|
Some(Root::from_ref(&*self.browsing_context))
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-top
|
// https://html.spec.whatwg.org/multipage/#dom-top
|
||||||
fn GetTop(&self) -> Option<Root<BrowsingContext>> {
|
fn GetTop(&self) -> Option<Root<BrowsingContext>> {
|
||||||
// TODO: implement window.top correctly for x-origin windows.
|
// Steps 1-3.
|
||||||
Some(Root::from_ref(&*self.browsing_context))
|
if self.browsing_context.is_discarded() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
// Steps 4-5.
|
||||||
|
Some(Root::from_ref(self.browsing_context.top()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-length
|
// https://html.spec.whatwg.org/multipage/#dom-length
|
||||||
|
|
|
@ -42,7 +42,7 @@ use dom::location::Location;
|
||||||
use dom::mediaquerylist::{MediaQueryList, WeakMediaQueryListVec};
|
use dom::mediaquerylist::{MediaQueryList, WeakMediaQueryListVec};
|
||||||
use dom::messageevent::MessageEvent;
|
use dom::messageevent::MessageEvent;
|
||||||
use dom::navigator::Navigator;
|
use dom::navigator::Navigator;
|
||||||
use dom::node::{Node, NodeDamage, document_from_node, from_untrusted_node_address, window_from_node};
|
use dom::node::{Node, NodeDamage, document_from_node, from_untrusted_node_address};
|
||||||
use dom::performance::Performance;
|
use dom::performance::Performance;
|
||||||
use dom::promise::Promise;
|
use dom::promise::Promise;
|
||||||
use dom::screen::Screen;
|
use dom::screen::Screen;
|
||||||
|
@ -631,31 +631,35 @@ impl WindowMethods for Window {
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-parent
|
// https://html.spec.whatwg.org/multipage/#dom-parent
|
||||||
fn GetParent(&self) -> Option<Root<BrowsingContext>> {
|
fn GetParent(&self) -> Option<Root<BrowsingContext>> {
|
||||||
// Steps 1. and 2.
|
// Steps 1-3.
|
||||||
if self.maybe_browsing_context().map_or(true, |c| c.is_discarded()) {
|
let context = match self.maybe_browsing_context() {
|
||||||
|
Some(context) => context,
|
||||||
|
None => return None,
|
||||||
|
};
|
||||||
|
if context.is_discarded() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
match self.parent() {
|
// Step 4.
|
||||||
// Step 4.
|
if let Some(parent) = context.parent() {
|
||||||
Some(parent) => Some(parent.Window()),
|
return Some(Root::from_ref(parent));
|
||||||
// Step 5.
|
|
||||||
None => Some(self.Window())
|
|
||||||
}
|
}
|
||||||
}
|
// Step 5.
|
||||||
|
Some(context)
|
||||||
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-top
|
// https://html.spec.whatwg.org/multipage/#dom-top
|
||||||
fn GetTop(&self) -> Option<Root<BrowsingContext>> {
|
fn GetTop(&self) -> Option<Root<BrowsingContext>> {
|
||||||
// Steps 1. and 2.
|
// Steps 1-3.
|
||||||
if self.maybe_browsing_context().map_or(true, |c| c.is_discarded()) {
|
let context = match self.maybe_browsing_context() {
|
||||||
|
Some(context) => context,
|
||||||
|
None => return None,
|
||||||
|
};
|
||||||
|
if context.is_discarded() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// Step 5.
|
// Steps 4-5.
|
||||||
let mut window = Root::from_ref(self);
|
Some(Root::from_ref(context.top()))
|
||||||
while let Some(parent) = window.parent() {
|
}
|
||||||
window = parent;
|
|
||||||
}
|
|
||||||
Some(window.Window())
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/
|
// https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/
|
||||||
// NavigationTiming/Overview.html#sec-window.performance-attribute
|
// NavigationTiming/Overview.html#sec-window.performance-attribute
|
||||||
|
@ -1657,16 +1661,6 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#parent-browsing-context
|
|
||||||
pub fn parent(&self) -> Option<Root<Window>> {
|
|
||||||
if self.is_top_level() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.browsing_context().frame_element()
|
|
||||||
.map(|frame_element| window_from_node(frame_element))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns whether this window is mozbrowser.
|
/// Returns whether this window is mozbrowser.
|
||||||
pub fn is_mozbrowser(&self) -> bool {
|
pub fn is_mozbrowser(&self) -> bool {
|
||||||
PREFS.is_mozbrowser_enabled() && self.parent_info().is_none()
|
PREFS.is_mozbrowser_enabled() && self.parent_info().is_none()
|
||||||
|
|
|
@ -1650,6 +1650,77 @@ impl ScriptThread {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn ask_constellation_for_frame_id(&self, pipeline_id: PipelineId) -> Option<FrameId> {
|
||||||
|
let (result_sender, result_receiver) = ipc::channel().unwrap();
|
||||||
|
let msg = ConstellationMsg::GetFrameId(pipeline_id, result_sender);
|
||||||
|
self.constellation_chan.send(msg).expect("Failed to send to constellation.");
|
||||||
|
result_receiver.recv().expect("Failed to get frame id from constellation.")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ask_constellation_for_parent_info(&self, pipeline_id: PipelineId) -> Option<(PipelineId, FrameType)> {
|
||||||
|
let (result_sender, result_receiver) = ipc::channel().unwrap();
|
||||||
|
let msg = ConstellationMsg::GetParentInfo(pipeline_id, result_sender);
|
||||||
|
self.constellation_chan.send(msg).expect("Failed to send to constellation.");
|
||||||
|
result_receiver.recv().expect("Failed to get frame id from constellation.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the browsing context for a pipeline that may exist in another
|
||||||
|
// script thread. If the browsing context already exists in the
|
||||||
|
// `browsing_contexts` map, we return it, otherwise we recursively
|
||||||
|
// get the browsing context for the parent if there is one,
|
||||||
|
// construct a new dissimilar-origin browsing context, add it
|
||||||
|
// to the `browsing_contexts` map, and return it.
|
||||||
|
fn remote_browsing_context(&self,
|
||||||
|
global_to_clone: &GlobalScope,
|
||||||
|
pipeline_id: PipelineId)
|
||||||
|
-> Option<Root<BrowsingContext>>
|
||||||
|
{
|
||||||
|
let frame_id = match self.ask_constellation_for_frame_id(pipeline_id) {
|
||||||
|
Some(frame_id) => frame_id,
|
||||||
|
None => return None,
|
||||||
|
};
|
||||||
|
if let Some(browsing_context) = self.browsing_contexts.borrow().get(&frame_id) {
|
||||||
|
return Some(Root::from_ref(browsing_context));
|
||||||
|
}
|
||||||
|
let parent = match self.ask_constellation_for_parent_info(pipeline_id) {
|
||||||
|
Some((parent_id, FrameType::IFrame)) => self.remote_browsing_context(global_to_clone, parent_id),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
let browsing_context = BrowsingContext::new_dissimilar_origin(global_to_clone, frame_id, parent.r());
|
||||||
|
self.browsing_contexts.borrow_mut().insert(frame_id, JS::from_ref(&*browsing_context));
|
||||||
|
Some(browsing_context)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the browsing context for a pipeline that exists in this
|
||||||
|
// script thread. If the browsing context already exists in the
|
||||||
|
// `browsing_contexts` map, we return it, otherwise we recursively
|
||||||
|
// get the browsing context for the parent if there is one,
|
||||||
|
// construct a new similar-origin browsing context, add it
|
||||||
|
// to the `browsing_contexts` map, and return it.
|
||||||
|
fn local_browsing_context(&self,
|
||||||
|
window: &Window,
|
||||||
|
frame_id: FrameId,
|
||||||
|
parent_info: Option<(PipelineId, FrameType)>)
|
||||||
|
-> Root<BrowsingContext>
|
||||||
|
{
|
||||||
|
if let Some(browsing_context) = self.browsing_contexts.borrow().get(&frame_id) {
|
||||||
|
browsing_context.set_currently_active(&*window);
|
||||||
|
return Root::from_ref(browsing_context);
|
||||||
|
}
|
||||||
|
let iframe = match parent_info {
|
||||||
|
Some((parent_id, FrameType::IFrame)) => self.documents.borrow().find_iframe(parent_id, frame_id),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
let parent = match (parent_info, iframe.as_ref()) {
|
||||||
|
(_, Some(iframe)) => Some(window_from_node(&**iframe).browsing_context()),
|
||||||
|
(Some((parent_id, FrameType::IFrame)), _) => self.remote_browsing_context(window.upcast(), parent_id),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
let browsing_context = BrowsingContext::new(&window, frame_id, iframe.r().map(Castable::upcast), parent.r());
|
||||||
|
self.browsing_contexts.borrow_mut().insert(frame_id, JS::from_ref(&*browsing_context));
|
||||||
|
browsing_context
|
||||||
|
}
|
||||||
|
|
||||||
/// The entry point to document loading. Defines bindings, sets up the window and document
|
/// The entry point to document loading. Defines bindings, sets up the window and document
|
||||||
/// objects, parses HTML and CSS, and kicks off initial layout.
|
/// objects, parses HTML and CSS, and kicks off initial layout.
|
||||||
fn load(&self, metadata: Metadata, incomplete: InProgressLoad) -> Root<ServoParser> {
|
fn load(&self, metadata: Metadata, incomplete: InProgressLoad) -> Root<ServoParser> {
|
||||||
|
@ -1667,17 +1738,6 @@ impl ScriptThread {
|
||||||
}
|
}
|
||||||
debug!("ScriptThread: loading {} on pipeline {:?}", incomplete.url, incomplete.pipeline_id);
|
debug!("ScriptThread: loading {} on pipeline {:?}", incomplete.url, incomplete.pipeline_id);
|
||||||
|
|
||||||
let frame_element = incomplete.parent_info.and_then(|(parent_id, _)|
|
|
||||||
// In the case a parent id exists but the matching context
|
|
||||||
// cannot be found, this means the context exists in a different
|
|
||||||
// script thread (due to origin) so it shouldn't be returned.
|
|
||||||
// TODO: window.parent will continue to return self in that
|
|
||||||
// case, which is wrong. We should be returning an object that
|
|
||||||
// denies access to most properties (per
|
|
||||||
// https://github.com/servo/servo/issues/3939#issuecomment-62287025).
|
|
||||||
self.documents.borrow().find_iframe(parent_id, incomplete.frame_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
let MainThreadScriptChan(ref sender) = self.chan;
|
let MainThreadScriptChan(ref sender) = self.chan;
|
||||||
let DOMManipulationTaskSource(ref dom_sender) = self.dom_manipulation_task_source;
|
let DOMManipulationTaskSource(ref dom_sender) = self.dom_manipulation_task_source;
|
||||||
let UserInteractionTaskSource(ref user_sender) = self.user_interaction_task_source;
|
let UserInteractionTaskSource(ref user_sender) = self.user_interaction_task_source;
|
||||||
|
@ -1711,20 +1771,10 @@ impl ScriptThread {
|
||||||
incomplete.parent_info,
|
incomplete.parent_info,
|
||||||
incomplete.window_size,
|
incomplete.window_size,
|
||||||
self.webvr_thread.clone());
|
self.webvr_thread.clone());
|
||||||
let frame_element = frame_element.r().map(Castable::upcast);
|
|
||||||
|
|
||||||
match self.browsing_contexts.borrow_mut().entry(incomplete.frame_id) {
|
// Initialize the browsing context for the window.
|
||||||
hash_map::Entry::Vacant(entry) => {
|
let browsing_context = self.local_browsing_context(&window, incomplete.frame_id, incomplete.parent_info);
|
||||||
let browsing_context = BrowsingContext::new(&window, incomplete.frame_id, frame_element);
|
window.init_browsing_context(&browsing_context);
|
||||||
entry.insert(JS::from_ref(&*browsing_context));
|
|
||||||
window.init_browsing_context(&browsing_context);
|
|
||||||
},
|
|
||||||
hash_map::Entry::Occupied(entry) => {
|
|
||||||
let browsing_context = entry.get();
|
|
||||||
browsing_context.set_currently_active(&*window);
|
|
||||||
window.init_browsing_context(browsing_context);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
let last_modified = metadata.headers.as_ref().and_then(|headers| {
|
let last_modified = metadata.headers.as_ref().and_then(|headers| {
|
||||||
headers.get().map(|&LastModified(HttpDate(ref tm))| dom_last_modified(tm))
|
headers.get().map(|&LastModified(HttpDate(ref tm))| dom_last_modified(tm))
|
||||||
|
|
|
@ -18,7 +18,7 @@ use euclid::point::Point2D;
|
||||||
use euclid::size::{Size2D, TypedSize2D};
|
use euclid::size::{Size2D, TypedSize2D};
|
||||||
use gfx_traits::ScrollRootId;
|
use gfx_traits::ScrollRootId;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
use msg::constellation_msg::{FrameId, PipelineId, TraversalDirection};
|
use msg::constellation_msg::{FrameId, FrameType, PipelineId, TraversalDirection};
|
||||||
use msg::constellation_msg::{Key, KeyModifiers, KeyState};
|
use msg::constellation_msg::{Key, KeyModifiers, KeyState};
|
||||||
use net_traits::CoreResourceMsg;
|
use net_traits::CoreResourceMsg;
|
||||||
use net_traits::storage_thread::StorageType;
|
use net_traits::storage_thread::StorageType;
|
||||||
|
@ -86,6 +86,10 @@ pub enum ScriptMsg {
|
||||||
ForwardEvent(PipelineId, CompositorEvent),
|
ForwardEvent(PipelineId, CompositorEvent),
|
||||||
/// Requests that the constellation retrieve the current contents of the clipboard
|
/// Requests that the constellation retrieve the current contents of the clipboard
|
||||||
GetClipboardContents(IpcSender<String>),
|
GetClipboardContents(IpcSender<String>),
|
||||||
|
/// Get the frame id for a given pipeline.
|
||||||
|
GetFrameId(PipelineId, IpcSender<Option<FrameId>>),
|
||||||
|
/// Get the parent info for a given pipeline.
|
||||||
|
GetParentInfo(PipelineId, IpcSender<Option<(PipelineId, FrameType)>>),
|
||||||
/// <head> tag finished parsing
|
/// <head> tag finished parsing
|
||||||
HeadParsed,
|
HeadParsed,
|
||||||
/// All pending loads are complete, and the `load` event for this pipeline
|
/// All pending loads are complete, and the `load` event for this pipeline
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
[navigation_unload_data_url.html]
|
|
||||||
type: testharness
|
|
||||||
expected: TIMEOUT
|
|
||||||
[Same-origin navigation started from unload handler]
|
|
||||||
expected: TIMEOUT
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
[origin-of-data-document.html]
|
[origin-of-data-document.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
expected: TIMEOUT
|
|
||||||
[The origin of a 'data:' document in a frame is opaque.]
|
[The origin of a 'data:' document in a frame is opaque.]
|
||||||
expected: TIMEOUT
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[cross-origin-objects.html]
|
|
||||||
type: testharness
|
|
||||||
[Parentage of cross-origin windows]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue