diff options
author | Alan Jeffrey <ajeffrey@mozilla.com> | 2016-10-07 15:52:49 -0500 |
---|---|---|
committer | Alan Jeffrey <ajeffrey@mozilla.com> | 2016-11-08 10:48:58 -0600 |
commit | 90e9c910f4338adb01c322034a2cd3230e7e9b8c (patch) | |
tree | 72f56740559e86e4d900329680d1cd221a58b5b0 /components/script/dom | |
parent | dae007fd1634bcf1545e67abaa7746fa95f10e94 (diff) | |
download | servo-90e9c910f4338adb01c322034a2cd3230e7e9b8c.tar.gz servo-90e9c910f4338adb01c322034a2cd3230e7e9b8c.zip |
Replace script thread root browsing context by a collection of documents.
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/browsingcontext.rs | 83 | ||||
-rw-r--r-- | components/script/dom/htmliframeelement.rs | 18 | ||||
-rw-r--r-- | components/script/dom/nodelist.rs | 22 | ||||
-rw-r--r-- | components/script/dom/storage.rs | 19 |
4 files changed, 49 insertions, 93 deletions
diff --git a/components/script/dom/browsingcontext.rs b/components/script/dom/browsingcontext.rs index 2ea6a1b78bd..1409c9c5dcf 100644 --- a/components/script/dom/browsingcontext.rs +++ b/components/script/dom/browsingcontext.rs @@ -2,7 +2,6 @@ * 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::cell::DOMRefCell; use dom::bindings::conversions::{ToJSValConvertible, root_from_handleobject}; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference}; @@ -37,15 +36,9 @@ use std::cell::Cell; pub struct BrowsingContext { reflector: Reflector, - /// Pipeline id associated with this context. - id: PipelineId, - /// Indicates if reflow is required when reloading. needs_reflow: Cell<bool>, - /// Stores the child browsing contexts (ex. iframe browsing context) - children: DOMRefCell<Vec<JS<BrowsingContext>>>, - /// The current active document. /// Note that the session history is stored in the constellation, /// in the script thread we just track the current active document. @@ -56,19 +49,17 @@ pub struct BrowsingContext { } impl BrowsingContext { - pub fn new_inherited(frame_element: Option<&Element>, id: PipelineId) -> BrowsingContext { + pub fn new_inherited(frame_element: Option<&Element>) -> BrowsingContext { BrowsingContext { reflector: Reflector::new(), - id: id, needs_reflow: Cell::new(true), - children: DOMRefCell::new(vec![]), active_document: Default::default(), frame_element: frame_element.map(JS::from_ref), } } #[allow(unsafe_code)] - pub fn new(window: &Window, frame_element: Option<&Element>, id: PipelineId) -> Root<BrowsingContext> { + pub fn new(window: &Window, frame_element: Option<&Element>) -> Root<BrowsingContext> { unsafe { let WindowProxyHandler(handler) = window.windowproxy_handler(); assert!(!handler.is_null()); @@ -81,7 +72,7 @@ impl BrowsingContext { rooted!(in(cx) let window_proxy = NewWindowProxy(cx, parent, handler)); assert!(!window_proxy.is_null()); - let object = box BrowsingContext::new_inherited(frame_element, id); + let object = box BrowsingContext::new_inherited(frame_element); let raw = Box::into_raw(object); SetProxyExtra(window_proxy.get(), 0, &PrivateValue(raw as *const _)); @@ -118,82 +109,20 @@ impl BrowsingContext { window_proxy.get() } - pub fn remove(&self, id: PipelineId) -> Option<Root<BrowsingContext>> { - let remove_idx = self.children - .borrow() - .iter() - .position(|context| context.id == id); - match remove_idx { - Some(idx) => Some(Root::from_ref(&*self.children.borrow_mut().remove(idx))), - None => { - self.children - .borrow_mut() - .iter_mut() - .filter_map(|context| context.remove(id)) - .next() - } - } - } - pub fn set_reflow_status(&self, status: bool) -> bool { let old = self.needs_reflow.get(); self.needs_reflow.set(status); old } - pub fn pipeline_id(&self) -> PipelineId { - self.id - } - - pub fn push_child_context(&self, context: &BrowsingContext) { - self.children.borrow_mut().push(JS::from_ref(&context)); - } - - pub fn find_child_by_id(&self, pipeline_id: PipelineId) -> Option<Root<Window>> { - self.children.borrow().iter().find(|context| { - let window = context.active_window(); - window.upcast::<GlobalScope>().pipeline_id() == pipeline_id - }).map(|context| context.active_window()) + pub fn active_pipeline_id(&self) -> Option<PipelineId> { + self.active_document.get() + .map(|doc| doc.window().upcast::<GlobalScope>().pipeline_id()) } pub fn unset_active_document(&self) { self.active_document.set(None) } - - pub fn iter(&self) -> ContextIterator { - ContextIterator { - stack: vec!(Root::from_ref(self)), - } - } - - pub fn find(&self, id: PipelineId) -> Option<Root<BrowsingContext>> { - if self.id == id { - return Some(Root::from_ref(self)); - } - - self.children.borrow() - .iter() - .filter_map(|c| c.find(id)) - .next() - } -} - -pub struct ContextIterator { - stack: Vec<Root<BrowsingContext>>, -} - -impl Iterator for ContextIterator { - type Item = Root<BrowsingContext>; - - fn next(&mut self) -> Option<Root<BrowsingContext>> { - let popped = self.stack.pop(); - if let Some(ref context) = popped { - self.stack.extend(context.children.borrow() - .iter() - .map(|c| Root::from_ref(&**c))); - } - popped - } } #[allow(unsafe_code)] diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 2b56b9d697c..0430a0f7d26 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -42,6 +42,7 @@ use js::jsval::{NullValue, UndefinedValue}; use msg::constellation_msg::{FrameType, FrameId, PipelineId, TraversalDirection}; use net_traits::response::HttpsState; use script_layout_interface::message::ReflowQueryType; +use script_thread::ScriptThread; use script_traits::{IFrameLoadInfo, LoadData, MozBrowserEvent, ScriptMsg as ConstellationMsg}; use script_traits::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed}; use servo_atoms::Atom; @@ -235,7 +236,7 @@ impl HTMLIFrameElement { pub fn iframe_load_event_steps(&self, loaded_pipeline: PipelineId) { // TODO(#9592): assert that the load blocker is present at all times when we // can guarantee that it's created for the case of iframe.reload(). - assert_eq!(loaded_pipeline, self.pipeline_id().unwrap()); + if Some(loaded_pipeline) != self.pipeline_id() { return; } // TODO A cross-origin child document would not be easily accessible // from this script thread. It's unclear how to implement @@ -268,13 +269,16 @@ impl HTMLIFrameElement { } pub fn get_content_window(&self) -> Option<Root<Window>> { - self.pipeline_id.get().and_then(|pipeline_id| { - let window = window_from_node(self); - let browsing_context = window.browsing_context(); - browsing_context.find_child_by_id(pipeline_id) - }) + self.pipeline_id.get() + .and_then(|pipeline_id| ScriptThread::find_document(pipeline_id)) + .and_then(|document| { + if self.global().get_url().origin() == document.global().get_url().origin() { + Some(Root::from_ref(document.window())) + } else { + None + } + }) } - } pub trait HTMLIFrameElementLayoutMethods { diff --git a/components/script/dom/nodelist.rs b/components/script/dom/nodelist.rs index 3810f16b22c..391d21d5865 100644 --- a/components/script/dom/nodelist.rs +++ b/components/script/dom/nodelist.rs @@ -97,6 +97,13 @@ impl NodeList { panic!("called as_simple_list() on a children node list") } } + + pub fn iter(&self) -> NodeListIterator { + NodeListIterator { + nodes: self, + offset: 0, + } + } } #[derive(JSTraceable, HeapSizeOf)] @@ -277,3 +284,18 @@ impl ChildrenList { self.last_index.set(0u32); } } + +pub struct NodeListIterator<'a> { + nodes: &'a NodeList, + offset: u32, +} + +impl<'a> Iterator for NodeListIterator<'a> { + type Item = Root<Node>; + + fn next(&mut self) -> Option<Root<Node>> { + let result = self.nodes.Item(self.offset); + self.offset = self.offset + 1; + result + } +} diff --git a/components/script/dom/storage.rs b/components/script/dom/storage.rs index 3441f57a7e7..099c6c04fea 100644 --- a/components/script/dom/storage.rs +++ b/components/script/dom/storage.rs @@ -13,7 +13,6 @@ use dom::bindings::str::DOMString; use dom::event::{Event, EventBubbles, EventCancelable}; use dom::globalscope::GlobalScope; use dom::storageevent::StorageEvent; -use dom::urlhelper::UrlHelper; use ipc_channel::ipc::{self, IpcSender}; use net_traits::IpcSend; use net_traits::storage_thread::{StorageThreadMsg, StorageType}; @@ -193,14 +192,16 @@ impl Runnable for StorageEventRunnable { Some(&storage) ); - let root_context = script_thread.root_browsing_context(); - for it_context in root_context.iter() { - let it_window = it_context.active_window(); - assert!(UrlHelper::SameOrigin(&ev_url, &it_window.get_url())); - // TODO: Such a Document object is not necessarily fully active, but events fired on such - // objects are ignored by the event loop until the Document becomes fully active again. - if global.pipeline_id() != it_window.upcast::<GlobalScope>().pipeline_id() { - storage_event.upcast::<Event>().fire(it_window.upcast()); + // TODO: This is only iterating over documents in the current script + // thread, so we are not firing events to other script threads. + // NOTE: once that is fixed, we can remove borrow_documents from ScriptThread. + for (id, document) in script_thread.borrow_documents().iter() { + if ev_url.origin() == document.window().get_url().origin() { + // TODO: Such a Document object is not necessarily fully active, but events fired on such + // objects are ignored by the event loop until the Document becomes fully active again. + if global.pipeline_id() != id { + storage_event.upcast::<Event>().fire(document.window().upcast()); + } } } } |