aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
authorAlan Jeffrey <ajeffrey@mozilla.com>2016-10-07 15:52:49 -0500
committerAlan Jeffrey <ajeffrey@mozilla.com>2016-11-08 10:48:58 -0600
commit90e9c910f4338adb01c322034a2cd3230e7e9b8c (patch)
tree72f56740559e86e4d900329680d1cd221a58b5b0 /components/script/dom
parentdae007fd1634bcf1545e67abaa7746fa95f10e94 (diff)
downloadservo-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.rs83
-rw-r--r--components/script/dom/htmliframeelement.rs18
-rw-r--r--components/script/dom/nodelist.rs22
-rw-r--r--components/script/dom/storage.rs19
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());
+ }
}
}
}