forked from mirrors/gecko-dev
		
	 1f4cc3131b
			
		
	
	
		1f4cc3131b
		
	
	
	
	
		
			
			<!-- Please describe your changes on the following line: --> This PR implements `window.parent` and `window.top` for dissimilar-origin windows. This PR builds on #15536, only the last commit is part of this PR. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #14996 and fix #11660. - [X] These changes do not require tests because there's already a parentage test in `mozilla/cross-origin-objects/cross-origin-objects.html`. <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: 0a3b373a6ae4fdd68ab9d2a7386733ab0bdebe4b --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : fd295f590845477a484bcaed149bac809d318a3a
		
			
				
	
	
		
			183 lines
		
	
	
	
		
			6.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			183 lines
		
	
	
	
		
			6.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * 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 dom::bindings::codegen::Bindings::DissimilarOriginWindowBinding;
 | |
| use dom::bindings::codegen::Bindings::DissimilarOriginWindowBinding::DissimilarOriginWindowMethods;
 | |
| use dom::bindings::error::{Error, ErrorResult};
 | |
| use dom::bindings::inheritance::Castable;
 | |
| use dom::bindings::js::{JS, MutNullableJS, Root};
 | |
| use dom::bindings::str::DOMString;
 | |
| use dom::bindings::structuredclone::StructuredCloneData;
 | |
| use dom::browsingcontext::BrowsingContext;
 | |
| use dom::dissimilaroriginlocation::DissimilarOriginLocation;
 | |
| use dom::globalscope::GlobalScope;
 | |
| use dom_struct::dom_struct;
 | |
| use ipc_channel::ipc;
 | |
| use js::jsapi::{JSContext, HandleValue};
 | |
| use js::jsval::{JSVal, UndefinedValue};
 | |
| use msg::constellation_msg::PipelineId;
 | |
| use script_traits::ScriptMsg as ConstellationMsg;
 | |
| use servo_url::ImmutableOrigin;
 | |
| use servo_url::ServoUrl;
 | |
| 
 | |
| /// Represents a dissimilar-origin `Window` that exists in another script thread.
 | |
| ///
 | |
| /// Since the `Window` is in a different script thread, we cannot access it
 | |
| /// directly, but some of its accessors (for example `window.parent`)
 | |
| /// still need to function.
 | |
| ///
 | |
| /// In `browsingcontext.rs`, we create a custom window proxy for these windows,
 | |
| /// that throws security exceptions for most accessors. This is not a replacement
 | |
| /// for XOWs, but provides belt-and-braces security.
 | |
| #[dom_struct]
 | |
| pub struct DissimilarOriginWindow {
 | |
|     /// The global for this window.
 | |
|     globalscope: GlobalScope,
 | |
| 
 | |
|     /// The browsing context this window is part of.
 | |
|     browsing_context: JS<BrowsingContext>,
 | |
| 
 | |
|     /// The location of this window, initialized lazily.
 | |
|     location: MutNullableJS<DissimilarOriginLocation>,
 | |
| }
 | |
| 
 | |
| impl DissimilarOriginWindow {
 | |
|     #[allow(unsafe_code)]
 | |
|     pub fn new(global_to_clone_from: &GlobalScope, browsing_context: &BrowsingContext) -> Root<DissimilarOriginWindow> {
 | |
|         let cx = global_to_clone_from.get_cx();
 | |
|         // Any timer events fired on this window are ignored.
 | |
|         let (timer_event_chan, _) = ipc::channel().unwrap();
 | |
|         let win = box DissimilarOriginWindow {
 | |
|             globalscope: GlobalScope::new_inherited(PipelineId::new(),
 | |
|                                                     global_to_clone_from.devtools_chan().cloned(),
 | |
|                                                     global_to_clone_from.mem_profiler_chan().clone(),
 | |
|                                                     global_to_clone_from.time_profiler_chan().clone(),
 | |
|                                                     global_to_clone_from.constellation_chan().clone(),
 | |
|                                                     global_to_clone_from.scheduler_chan().clone(),
 | |
|                                                     global_to_clone_from.resource_threads().clone(),
 | |
|                                                     timer_event_chan),
 | |
|             browsing_context: JS::from_ref(browsing_context),
 | |
|             location: MutNullableJS::new(None),
 | |
|         };
 | |
|         unsafe { DissimilarOriginWindowBinding::Wrap(cx, win) }
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl DissimilarOriginWindowMethods for DissimilarOriginWindow {
 | |
|     // https://html.spec.whatwg.org/multipage/#dom-window
 | |
|     fn Window(&self) -> Root<BrowsingContext> {
 | |
|         Root::from_ref(&*self.browsing_context)
 | |
|     }
 | |
| 
 | |
|     // https://html.spec.whatwg.org/multipage/#dom-self
 | |
|     fn Self_(&self) -> Root<BrowsingContext> {
 | |
|         Root::from_ref(&*self.browsing_context)
 | |
|     }
 | |
| 
 | |
|     // https://html.spec.whatwg.org/multipage/#dom-frames
 | |
|     fn Frames(&self) -> Root<BrowsingContext> {
 | |
|         Root::from_ref(&*self.browsing_context)
 | |
|     }
 | |
| 
 | |
|     // https://html.spec.whatwg.org/multipage/#dom-parent
 | |
|     fn GetParent(&self) -> Option<Root<BrowsingContext>> {
 | |
|         // 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))
 | |
|     }
 | |
| 
 | |
|     // https://html.spec.whatwg.org/multipage/#dom-top
 | |
|     fn GetTop(&self) -> Option<Root<BrowsingContext>> {
 | |
|         // Steps 1-3.
 | |
|         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
 | |
|     fn Length(&self) -> u32 {
 | |
|         // TODO: Implement x-origin length
 | |
|         0
 | |
|     }
 | |
| 
 | |
|     // https://html.spec.whatwg.org/multipage/#dom-window-close
 | |
|     fn Close(&self) {
 | |
|         // TODO: Implement x-origin close
 | |
|     }
 | |
| 
 | |
|     // https://html.spec.whatwg.org/multipage/#dom-window-closed
 | |
|     fn Closed(&self) -> bool {
 | |
|         // TODO: Implement x-origin close
 | |
|         false
 | |
|     }
 | |
| 
 | |
|     #[allow(unsafe_code)]
 | |
|     // https://html.spec.whatwg.org/multipage/#dom-window-postmessage
 | |
|     unsafe fn PostMessage(&self, cx: *mut JSContext, message: HandleValue, origin: DOMString) -> ErrorResult {
 | |
|         // Step 3-5.
 | |
|         let origin = match &origin[..] {
 | |
|             "*" => None,
 | |
|             "/" => {
 | |
|                 // TODO: Should be the origin of the incumbent settings object.
 | |
|                 None
 | |
|             },
 | |
|             url => match ServoUrl::parse(&url) {
 | |
|                 Ok(url) => Some(url.origin()),
 | |
|                 Err(_) => return Err(Error::Syntax),
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         // Step 1-2, 6-8.
 | |
|         // TODO(#12717): Should implement the `transfer` argument.
 | |
|         let data = try!(StructuredCloneData::write(cx, message));
 | |
| 
 | |
|         // Step 9.
 | |
|         self.post_message(origin, data);
 | |
|         Ok(())
 | |
|     }
 | |
| 
 | |
|     #[allow(unsafe_code)]
 | |
|     // https://html.spec.whatwg.org/multipage/#dom-opener
 | |
|     unsafe fn Opener(&self, _: *mut JSContext) -> JSVal {
 | |
|         // TODO: Implement x-origin opener
 | |
|         UndefinedValue()
 | |
|     }
 | |
| 
 | |
|     #[allow(unsafe_code)]
 | |
|     // https://html.spec.whatwg.org/multipage/#dom-opener
 | |
|     unsafe fn SetOpener(&self, _: *mut JSContext, _: HandleValue) {
 | |
|         // TODO: Implement x-origin opener
 | |
|     }
 | |
| 
 | |
|     // https://html.spec.whatwg.org/multipage/#dom-window-blur
 | |
|     fn Blur(&self) {
 | |
|         // TODO: Implement x-origin blur
 | |
|     }
 | |
| 
 | |
|     // https://html.spec.whatwg.org/multipage/#dom-focus
 | |
|     fn Focus(&self) {
 | |
|         // TODO: Implement x-origin focus
 | |
|     }
 | |
| 
 | |
|     // https://html.spec.whatwg.org/multipage/#dom-location
 | |
|     fn Location(&self) -> Root<DissimilarOriginLocation> {
 | |
|         self.location.or_init(|| DissimilarOriginLocation::new(self))
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl DissimilarOriginWindow {
 | |
|     pub fn post_message(&self, origin: Option<ImmutableOrigin>, data: StructuredCloneData) {
 | |
|         let msg = ConstellationMsg::PostMessage(self.browsing_context.frame_id(), origin, data.move_to_arraybuffer());
 | |
|         let _ = self.upcast::<GlobalScope>().constellation_chan().send(msg);
 | |
|     }
 | |
| }
 |