aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/window.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/window.rs')
-rw-r--r--components/script/dom/window.rs59
1 files changed, 55 insertions, 4 deletions
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index d7a9e9f243a..ba86c85b3ac 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::EventHandlerBinding::{OnErrorEventHandlerN
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
use dom::bindings::codegen::Bindings::FunctionBinding::Function;
use dom::bindings::codegen::Bindings::WindowBinding::{self, WindowMethods, FrameRequestCallback};
-use dom::bindings::codegen::InheritTypes::{NodeCast, EventTargetCast};
+use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast, EventTargetCast, WindowDerived};
use dom::bindings::global::global_object_for_js_object;
use dom::bindings::error::{report_pending_exception, Fallible};
use dom::bindings::error::Error::InvalidCharacter;
@@ -27,7 +27,7 @@ use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::location::Location;
use dom::navigator::Navigator;
-use dom::node::{window_from_node, TrustedNodeAddress, NodeHelpers};
+use dom::node::{window_from_node, TrustedNodeAddress, NodeHelpers, from_untrusted_node_address};
use dom::performance::Performance;
use dom::screen::Screen;
use dom::storage::Storage;
@@ -72,6 +72,7 @@ use std::cell::{Cell, Ref, RefMut, RefCell};
use std::collections::HashSet;
use std::default::Default;
use std::ffi::CString;
+use std::io::{stdout, Write};
use std::mem as std_mem;
use std::rc::Rc;
use std::sync::Arc;
@@ -80,7 +81,7 @@ use std::sync::mpsc::{channel, Receiver};
use time;
/// Current state of the window object
-#[derive(JSTraceable, Copy, Clone, Debug, PartialEq)]
+#[derive(JSTraceable, Copy, Clone, Debug, PartialEq, HeapSizeOf)]
enum WindowState {
Alive,
Zombie, // Pipeline is closed, but the window hasn't been GCed yet.
@@ -105,15 +106,21 @@ pub enum ReflowReason {
}
#[dom_struct]
+#[derive(HeapSizeOf)]
pub struct Window {
eventtarget: EventTarget,
+ #[ignore_heap_size_of = "trait objects are hard"]
script_chan: Box<ScriptChan+Send>,
+ #[ignore_heap_size_of = "channels are hard"]
control_chan: ScriptControlChan,
console: MutNullableHeap<JS<Console>>,
crypto: MutNullableHeap<JS<Crypto>>,
navigator: MutNullableHeap<JS<Navigator>>,
+ #[ignore_heap_size_of = "channels are hard"]
image_cache_task: ImageCacheTask,
+ #[ignore_heap_size_of = "channels are hard"]
image_cache_chan: ImageCacheChan,
+ #[ignore_heap_size_of = "TODO(#6911) newtypes containing unmeasurable types are hard"]
compositor: DOMRefCell<ScriptListener>,
browsing_context: DOMRefCell<Option<BrowsingContext>>,
page: Rc<Page>,
@@ -128,13 +135,17 @@ pub struct Window {
next_worker_id: Cell<WorkerId>,
/// For sending messages to the memory profiler.
+ #[ignore_heap_size_of = "channels are hard"]
mem_profiler_chan: mem::ProfilerChan,
/// For providing instructions to an optional devtools server.
+ #[ignore_heap_size_of = "channels are hard"]
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
/// For sending timeline markers. Will be ignored if
/// no devtools server
+ #[ignore_heap_size_of = "TODO(#6909) need to measure HashSet"]
devtools_markers: RefCell<HashSet<TimelineMarkerType>>,
+ #[ignore_heap_size_of = "channels are hard"]
devtools_marker_sender: RefCell<Option<IpcSender<TimelineMarker>>>,
/// A flag to indicate whether the developer tools have requested live updates of
@@ -159,27 +170,34 @@ pub struct Window {
dom_static: GlobalStaticData,
/// The JavaScript runtime.
+ #[ignore_heap_size_of = "Rc<T> is hard"]
js_runtime: DOMRefCell<Option<Rc<Runtime>>>,
/// A handle for communicating messages to the layout task.
+ #[ignore_heap_size_of = "channels are hard"]
layout_chan: LayoutChan,
/// A handle to perform RPC calls into the layout, quickly.
+ #[ignore_heap_size_of = "trait objects are hard"]
layout_rpc: Box<LayoutRPC+'static>,
/// The port that we will use to join layout. If this is `None`, then layout is not running.
+ #[ignore_heap_size_of = "channels are hard"]
layout_join_port: DOMRefCell<Option<Receiver<()>>>,
/// The current size of the window, in pixels.
window_size: Cell<Option<WindowSizeData>>,
/// Associated resource task for use by DOM objects like XMLHttpRequest
+ #[ignore_heap_size_of = "channels are hard"]
resource_task: Arc<ResourceTask>,
/// A handle for communicating messages to the storage task.
+ #[ignore_heap_size_of = "channels are hard"]
storage_task: StorageTask,
/// A handle for communicating messages to the constellation task.
+ #[ignore_heap_size_of = "channels are hard"]
constellation_chan: ConstellationChan,
/// Pending scroll to fragment event, if any
@@ -193,6 +211,7 @@ pub struct Window {
pending_reflow_count: Cell<u32>,
/// A channel for communicating results of async scripts back to the webdriver server
+ #[ignore_heap_size_of = "channels are hard"]
webdriver_script_chan: RefCell<Option<IpcSender<WebDriverJSResult>>>,
/// The current state of the window object
@@ -342,7 +361,10 @@ impl<'a> WindowMethods for &'a Window {
// https://html.spec.whatwg.org/#dom-alert
fn Alert(self, s: DOMString) {
// Right now, just print to the console
- println!("ALERT: {}", s);
+ let stdout = stdout();
+ let mut stdout = stdout.lock();
+ writeln!(&mut stdout, "ALERT: {}", s).unwrap();
+ stdout.flush().unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-window-close
@@ -578,6 +600,7 @@ pub trait WindowHelpers {
fn client_rect_query(self, node_geometry_request: TrustedNodeAddress) -> Rect<i32>;
fn resolved_style_query(self, element: TrustedNodeAddress,
pseudo: Option<PseudoElement>, property: &Atom) -> Option<String>;
+ fn offset_parent_query(self, node: TrustedNodeAddress) -> (Option<Root<Element>>, Rect<Au>);
fn handle_reflow_complete_msg(self, reflow_id: u32);
fn set_fragment_name(self, fragment: Option<String>);
fn steal_fragment_name(self) -> Option<String>;
@@ -827,6 +850,27 @@ impl<'a> WindowHelpers for &'a Window {
resolved
}
+ fn offset_parent_query(self, node: TrustedNodeAddress) -> (Option<Root<Element>>, Rect<Au>) {
+ self.reflow(ReflowGoal::ForScriptQuery,
+ ReflowQueryType::OffsetParentQuery(node),
+ ReflowReason::Query);
+ let response = self.layout_rpc.offset_parent();
+ let js_runtime = self.js_runtime.borrow();
+ let js_runtime = js_runtime.as_ref().unwrap();
+ let element = match response.node_address {
+ Some(parent_node_address) => {
+ let node = from_untrusted_node_address(js_runtime.rt(),
+ parent_node_address);
+ let element = ElementCast::to_ref(node.r());
+ element.map(Root::from_ref)
+ }
+ None => {
+ None
+ }
+ };
+ (element, response.rect)
+ }
+
fn handle_reflow_complete_msg(self, reflow_id: u32) {
let last_reflow_id = self.last_reflow_id.get();
if last_reflow_id == reflow_id {
@@ -1135,6 +1179,7 @@ fn debug_reflow_events(goal: &ReflowGoal, query_type: &ReflowQueryType, reason:
ReflowQueryType::ContentBoxesQuery(_n) => "\tContentBoxesQuery",
ReflowQueryType::NodeGeometryQuery(_n) => "\tNodeGeometryQuery",
ReflowQueryType::ResolvedStyleQuery(_, _, _) => "\tResolvedStyleQuery",
+ ReflowQueryType::OffsetParentQuery(_n) => "\tOffsetParentQuery",
});
debug_msg.push_str(match *reason {
@@ -1155,3 +1200,9 @@ fn debug_reflow_events(goal: &ReflowGoal, query_type: &ReflowQueryType, reason:
println!("{}", debug_msg);
}
+
+impl WindowDerived for EventTarget {
+ fn is_window(&self) -> bool {
+ self.type_id() == &EventTargetTypeId::Window
+ }
+}