diff options
-rw-r--r-- | components/devtools/Cargo.toml | 1 | ||||
-rw-r--r-- | components/devtools/actors/inspector.rs | 106 | ||||
-rw-r--r-- | components/devtools/lib.rs | 2 | ||||
-rw-r--r-- | components/devtools_traits/lib.rs | 29 | ||||
-rw-r--r-- | components/layout/layout_thread.rs | 16 | ||||
-rw-r--r-- | components/layout/query.rs | 22 | ||||
-rw-r--r-- | components/script/devtools.rs | 49 | ||||
-rw-r--r-- | components/script/dom/node.rs | 1 | ||||
-rw-r--r-- | components/script/dom/window.rs | 10 | ||||
-rw-r--r-- | components/script/layout_interface.rs | 22 | ||||
-rw-r--r-- | components/servo/Cargo.lock | 1 | ||||
-rw-r--r-- | ports/cef/Cargo.lock | 1 | ||||
-rw-r--r-- | ports/gonk/Cargo.lock | 1 |
13 files changed, 222 insertions, 39 deletions
diff --git a/components/devtools/Cargo.toml b/components/devtools/Cargo.toml index 36567380d14..9d4f910dfe1 100644 --- a/components/devtools/Cargo.toml +++ b/components/devtools/Cargo.toml @@ -27,5 +27,6 @@ hyper = { version = "0.7", features = [ "serde-serialization" ] } log = "0.3" rustc-serialize = "0.3" serde = "0.6" +serde_json = "0.6" serde_macros = "0.6" time = "0.1" diff --git a/components/devtools/actors/inspector.rs b/components/devtools/actors/inspector.rs index 7dd5def34cf..1bf72d96e64 100644 --- a/components/devtools/actors/inspector.rs +++ b/components/devtools/actors/inspector.rs @@ -12,7 +12,8 @@ use devtools_traits::{ComputedNodeLayout, DevtoolScriptControlMsg, NodeInfo}; use ipc_channel::ipc::{self, IpcSender}; use msg::constellation_msg::PipelineId; use protocol::JsonPacketStream; -use rustc_serialize::json::{self, Json, ToJson}; +use rustc_serialize::json::{self, Json}; +use serde_json; use std::cell::RefCell; use std::collections::BTreeMap; use std::net::TcpStream; @@ -397,21 +398,49 @@ struct AppliedSheet { ruleCount: usize, } -#[derive(RustcEncodable)] +#[derive(Serialize)] struct GetLayoutReply { - width: i32, - height: i32, - autoMargins: Json, from: String, -} -#[derive(RustcEncodable)] -#[allow(dead_code)] -struct AutoMargins { - top: String, - bottom: String, - left: String, - right: String, + display: String, + position: String, + #[serde(rename = "z-index")] + zIndex: String, + #[serde(rename = "box-sizing")] + boxSizing: String, + + // Would be nice to use a proper struct, blocked by + // https://github.com/serde-rs/serde/issues/43 + autoMargins: serde_json::value::Value, + #[serde(rename = "margin-top")] + marginTop: String, + #[serde(rename = "margin-right")] + marginRight: String, + #[serde(rename = "margin-bottom")] + marginBottom: String, + #[serde(rename = "margin-left")] + marginLeft: String, + + #[serde(rename = "border-top-width")] + borderTopWidth: String, + #[serde(rename = "border-right-width")] + borderRightWidth: String, + #[serde(rename = "border-bottom-width")] + borderBottomWidth: String, + #[serde(rename = "border-left-width")] + borderLeftWidth: String, + + #[serde(rename = "padding-top")] + paddingTop: String, + #[serde(rename = "padding-right")] + paddingRight: String, + #[serde(rename = "padding-bottom")] + paddingBottom: String, + #[serde(rename = "padding-left")] + paddingLeft: String, + + width: f32, + height: f32, } impl Actor for PageStyleActor { @@ -455,31 +484,52 @@ impl Actor for PageStyleActor { registry.actor_to_script(target.to_owned()), tx)) .unwrap(); - let ComputedNodeLayout { width, height } = rx.recv().unwrap(); + let ComputedNodeLayout { + display, position, zIndex, boxSizing, + autoMargins, marginTop, marginRight, marginBottom, marginLeft, + borderTopWidth, borderRightWidth, borderBottomWidth, borderLeftWidth, + paddingTop, paddingRight, paddingBottom, paddingLeft, + width, height, + } = rx.recv().unwrap(); let auto_margins = msg.get("autoMargins") .and_then(&Json::as_boolean).unwrap_or(false); - //TODO: the remaining layout properties (margin, border, padding, position) - // as specified in getLayout in - // http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/styles.js + // http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/styles.js let msg = GetLayoutReply { - width: width.round() as i32, - height: height.round() as i32, + from: self.name(), + display: display, + position: position, + zIndex: zIndex, + boxSizing: boxSizing, autoMargins: if auto_margins { - //TODO: real values like processMargins in - // http://mxr.mozilla.org/mozilla-central/source/toolkit/devtools/server/actors/styles.js let mut m = BTreeMap::new(); - m.insert("top".to_owned(), "auto".to_owned().to_json()); - m.insert("bottom".to_owned(), "auto".to_owned().to_json()); - m.insert("left".to_owned(), "auto".to_owned().to_json()); - m.insert("right".to_owned(), "auto".to_owned().to_json()); - Json::Object(m) + let auto = serde_json::value::Value::String("auto".to_owned()); + if autoMargins.top { m.insert("top".to_owned(), auto.clone()); } + if autoMargins.right { m.insert("right".to_owned(), auto.clone()); } + if autoMargins.bottom { m.insert("bottom".to_owned(), auto.clone()); } + if autoMargins.left { m.insert("left".to_owned(), auto.clone()); } + serde_json::value::Value::Object(m) } else { - Json::Null + serde_json::value::Value::Null }, - from: self.name(), + marginTop: marginTop, + marginRight: marginRight, + marginBottom: marginBottom, + marginLeft: marginLeft, + borderTopWidth: borderTopWidth, + borderRightWidth: borderRightWidth, + borderBottomWidth: borderBottomWidth, + borderLeftWidth: borderLeftWidth, + paddingTop: paddingTop, + paddingRight: paddingRight, + paddingBottom: paddingBottom, + paddingLeft: paddingLeft, + width: width, + height: height, }; + let msg = &serde_json::to_string(&msg).unwrap(); + let msg = Json::from_str(msg).unwrap(); stream.write_json_packet(&msg); ActorMessageStatus::Processed } diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs index 1d96c932389..3ee14422d53 100644 --- a/components/devtools/lib.rs +++ b/components/devtools/lib.rs @@ -11,6 +11,7 @@ #![crate_type = "rlib"] #![feature(box_syntax)] +#![feature(custom_attribute)] #![feature(custom_derive)] #![feature(plugin)] #![plugin(serde_macros)] @@ -27,6 +28,7 @@ extern crate log; extern crate msg; extern crate rustc_serialize; extern crate serde; +extern crate serde_json; extern crate time; extern crate util; diff --git a/components/devtools_traits/lib.rs b/components/devtools_traits/lib.rs index 38d9f65d9c5..44a55001a0e 100644 --- a/components/devtools_traits/lib.rs +++ b/components/devtools_traits/lib.rs @@ -157,10 +157,39 @@ pub enum TimelineMarkerType { /// The properties of a DOM node as computed by layout. #[derive(Deserialize, Serialize)] pub struct ComputedNodeLayout { + pub display: String, + pub position: String, + pub zIndex: String, + pub boxSizing: String, + + pub autoMargins: AutoMargins, + pub marginTop: String, + pub marginRight: String, + pub marginBottom: String, + pub marginLeft: String, + + pub borderTopWidth: String, + pub borderRightWidth: String, + pub borderBottomWidth: String, + pub borderLeftWidth: String, + + pub paddingTop: String, + pub paddingRight: String, + pub paddingBottom: String, + pub paddingLeft: String, + pub width: f32, pub height: f32, } +#[derive(Deserialize, Serialize)] +pub struct AutoMargins { + pub top: bool, + pub right: bool, + pub bottom: bool, + pub left: bool, +} + /// Messages to process in a particular script thread, as instructed by a devtools client. #[derive(Deserialize, Serialize)] pub enum DevtoolScriptControlMsg { diff --git a/components/layout/layout_thread.rs b/components/layout/layout_thread.rs index fbc1cd26daf..e1e163acb39 100644 --- a/components/layout/layout_thread.rs +++ b/components/layout/layout_thread.rs @@ -42,9 +42,10 @@ use profile_traits::mem::{self, Report, ReportKind, ReportsChan}; use profile_traits::time::{TimerMetadataFrameType, TimerMetadataReflowType}; use profile_traits::time::{self, TimerMetadata, profile}; use query::{LayoutRPCImpl, process_content_box_request, process_content_boxes_request}; -use query::{process_node_geometry_request, process_offset_parent_query, process_resolved_style_request}; +use query::{process_node_geometry_request, process_offset_parent_query}; +use query::{process_resolved_style_request, process_margin_style_query}; use script::dom::node::OpaqueStyleAndLayoutData; -use script::layout_interface::{LayoutRPC, OffsetParentResponse}; +use script::layout_interface::{LayoutRPC, OffsetParentResponse, MarginStyleResponse}; use script::layout_interface::{Msg, NewLayoutThreadInfo, Reflow, ReflowQueryType}; use script::layout_interface::{ScriptLayoutChan, ScriptReflow}; use script::reporter::CSSErrorReporter; @@ -117,6 +118,9 @@ pub struct LayoutThreadData { /// A queued response for the offset parent/rect of a node. pub offset_parent_response: OffsetParentResponse, + + /// A queued response for the offset parent/rect of a node. + pub margin_style_response: MarginStyleResponse, } /// Information needed by the layout thread. @@ -455,6 +459,7 @@ impl LayoutThread { client_rect_response: Rect::zero(), resolved_style_response: None, offset_parent_response: OffsetParentResponse::empty(), + margin_style_response: MarginStyleResponse::empty(), })), error_reporter: CSSErrorReporter { pipelineid: id, @@ -986,6 +991,9 @@ impl LayoutThread { ReflowQueryType::OffsetParentQuery(_) => { rw_data.offset_parent_response = OffsetParentResponse::empty(); }, + ReflowQueryType::MarginStyleQuery(_) => { + rw_data.margin_style_response = MarginStyleResponse::empty(); + }, ReflowQueryType::NoQuery => {} } return; @@ -1129,6 +1137,10 @@ impl LayoutThread { let node = unsafe { ServoLayoutNode::new(&node) }; rw_data.offset_parent_response = process_offset_parent_query(node, &mut root_flow); }, + ReflowQueryType::MarginStyleQuery(node) => { + let node = unsafe { ServoLayoutNode::new(&node) }; + rw_data.margin_style_response = process_margin_style_query(node); + }, ReflowQueryType::NoQuery => {} } } diff --git a/components/layout/query.rs b/components/layout/query.rs index af2dbdd9724..0a66a135919 100644 --- a/components/layout/query.rs +++ b/components/layout/query.rs @@ -17,7 +17,7 @@ use msg::constellation_msg::ConstellationChan; use opaque_node::OpaqueNodeMethods; use script::layout_interface::{ContentBoxResponse, ContentBoxesResponse, NodeGeometryResponse}; use script::layout_interface::{HitTestResponse, LayoutRPC, MouseOverResponse, OffsetParentResponse}; -use script::layout_interface::{ResolvedStyleResponse, ScriptLayoutChan}; +use script::layout_interface::{ResolvedStyleResponse, ScriptLayoutChan, MarginStyleResponse}; use script_traits::LayoutMsg as ConstellationMsg; use sequential; use std::ops::Deref; @@ -131,6 +131,12 @@ impl LayoutRPC for LayoutRPCImpl { let rw_data = rw_data.lock().unwrap(); rw_data.offset_parent_response.clone() } + + fn margin_style(&self) -> MarginStyleResponse { + let &LayoutRPCImpl(ref rw_data) = self; + let rw_data = rw_data.lock().unwrap(); + rw_data.margin_style_response.clone() + } } struct UnioningFragmentBorderBoxIterator { @@ -575,3 +581,17 @@ pub fn process_offset_parent_query<'ln, N: LayoutNode<'ln>>(requested_node: N, l } } } + +pub fn process_margin_style_query<'ln, N: LayoutNode<'ln>>(requested_node: N) + -> MarginStyleResponse { + let layout_node = requested_node.to_threadsafe(); + let style = &*layout_node.style(); + let margin = style.get_margin(); + + MarginStyleResponse { + top: margin.margin_top, + right: margin.margin_right, + bottom: margin.margin_bottom, + left: margin.margin_left, + } +} diff --git a/components/script/devtools.rs b/components/script/devtools.rs index 668c4554722..f0ec814cdc2 100644 --- a/components/script/devtools.rs +++ b/components/script/devtools.rs @@ -2,18 +2,22 @@ * 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 devtools_traits::{CONSOLE_API, CachedConsoleMessage, CachedConsoleMessageTypes, PAGE_ERROR}; +use devtools_traits::TimelineMarkerType; +use devtools_traits::{AutoMargins, CONSOLE_API, CachedConsoleMessage, CachedConsoleMessageTypes}; use devtools_traits::{ComputedNodeLayout, ConsoleAPI, PageError, ScriptToDevtoolsControlMsg}; -use devtools_traits::{EvaluateJSReply, Modification, NodeInfo, TimelineMarker, TimelineMarkerType}; +use devtools_traits::{EvaluateJSReply, Modification, NodeInfo, PAGE_ERROR, TimelineMarker}; +use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::CSSStyleDeclarationMethods; use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods; use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods; +use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::conversions::{FromJSValConvertible, jsstring_to_str}; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; use dom::bindings::js::Root; use dom::element::Element; use dom::node::Node; +use dom::window::Window; use ipc_channel::ipc::IpcSender; use js::jsapi::{ObjectClassName, RootedObject, RootedValue}; use js::jsval::UndefinedValue; @@ -23,6 +27,7 @@ use script_thread::get_page; use std::ffi::CStr; use std::rc::Rc; use std::str; +use style::properties::longhands::{margin_top, margin_right, margin_bottom, margin_left}; use util::str::DOMString; use uuid::Uuid; @@ -110,15 +115,47 @@ pub fn handle_get_layout(page: &Rc<Page>, node_id: String, reply: IpcSender<ComputedNodeLayout>) { let node = find_node_by_unique_id(&*page, pipeline, node_id); + let elem = node.downcast::<Element>().expect("should be getting layout of element"); let rect = elem.GetBoundingClientRect(); let width = rect.Width() as f32; let height = rect.Height() as f32; + + let window = page.window(); + let elem = node.downcast::<Element>().expect("should be getting layout of element"); + let computed_style = window.r().GetComputedStyle(elem, None); + reply.send(ComputedNodeLayout { - width: width, - height: height, - }) - .unwrap(); + display: String::from(computed_style.Display()), + position: String::from(computed_style.Position()), + zIndex: String::from(computed_style.ZIndex()), + boxSizing: String::from(computed_style.BoxSizing()), + autoMargins: determine_auto_margins(&window, &*node), + marginTop: String::from(computed_style.MarginTop()), + marginRight: String::from(computed_style.MarginRight()), + marginBottom: String::from(computed_style.MarginBottom()), + marginLeft: String::from(computed_style.MarginLeft()), + borderTopWidth: String::from(computed_style.BorderTopWidth()), + borderRightWidth: String::from(computed_style.BorderRightWidth()), + borderBottomWidth: String::from(computed_style.BorderBottomWidth()), + borderLeftWidth: String::from(computed_style.BorderLeftWidth()), + paddingTop: String::from(computed_style.PaddingTop()), + paddingRight: String::from(computed_style.PaddingRight()), + paddingBottom: String::from(computed_style.PaddingBottom()), + paddingLeft: String::from(computed_style.PaddingLeft()), + width: width, + height: height, + }).unwrap(); +} + +fn determine_auto_margins(window: &Window, node: &Node) -> AutoMargins { + let margin = window.margin_style_query(node.to_trusted_node_address()); + AutoMargins { + top: margin.top == margin_top::computed_value::T::Auto, + right: margin.right == margin_right::computed_value::T::Auto, + bottom: margin.bottom == margin_bottom::computed_value::T::Auto, + left: margin.left == margin_left::computed_value::T::Auto, + } } pub fn handle_get_cached_messages(_pipeline_id: PipelineId, diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index f1ebf6f9965..c82fbb49e88 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -185,7 +185,6 @@ unsafe impl Send for OpaqueStyleAndLayoutData {} no_jsmanaged_fields!(OpaqueStyleAndLayoutData); - impl OpaqueStyleAndLayoutData { /// Sends the style and layout data, if any, back to the layout thread to be destroyed. pub fn dispose(self, node: &Node) { diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 908d3dffd2c..0869423c55b 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -41,7 +41,7 @@ use js::jsapi::{JSAutoCompartment, JSAutoRequest, JS_GC, JS_GetRuntime}; use js::rust::CompileOptionsWrapper; use js::rust::Runtime; use layout_interface::{ContentBoxResponse, ContentBoxesResponse, ResolvedStyleResponse, ScriptReflow}; -use layout_interface::{LayoutChan, LayoutRPC, Msg, Reflow, ReflowQueryType}; +use layout_interface::{LayoutChan, LayoutRPC, Msg, Reflow, ReflowQueryType, MarginStyleResponse}; use libc; use msg::constellation_msg::{ConstellationChan, LoadData, PipelineId, SubpageId, WindowSizeData}; use msg::webdriver_msg::{WebDriverJSError, WebDriverJSResult}; @@ -1099,6 +1099,13 @@ impl Window { (element, response.rect) } + pub fn margin_style_query(&self, node: TrustedNodeAddress) -> MarginStyleResponse { + self.reflow(ReflowGoal::ForScriptQuery, + ReflowQueryType::MarginStyleQuery(node), + ReflowReason::Query); + self.layout_rpc.margin_style() + } + pub fn init_browsing_context(&self, browsing_context: &BrowsingContext) { assert!(self.browsing_context.get().is_none()); self.browsing_context.set(Some(&browsing_context)); @@ -1420,6 +1427,7 @@ fn debug_reflow_events(goal: &ReflowGoal, query_type: &ReflowQueryType, reason: ReflowQueryType::NodeGeometryQuery(_n) => "\tNodeGeometryQuery", ReflowQueryType::ResolvedStyleQuery(_, _, _) => "\tResolvedStyleQuery", ReflowQueryType::OffsetParentQuery(_n) => "\tOffsetParentQuery", + ReflowQueryType::MarginStyleQuery(_n) => "\tMarginStyleQuery", }); debug_msg.push_str(match *reason { diff --git a/components/script/layout_interface.rs b/components/script/layout_interface.rs index 831c04a9516..17f553d43e8 100644 --- a/components/script/layout_interface.rs +++ b/components/script/layout_interface.rs @@ -23,6 +23,7 @@ use std::sync::Arc; use std::sync::mpsc::{Receiver, Sender, channel}; use string_cache::Atom; use style::context::ReflowGoal; +use style::properties::longhands::{margin_top, margin_right, margin_bottom, margin_left}; use style::selector_impl::PseudoElement; use style::servo::Stylesheet; use url::Url; @@ -109,8 +110,28 @@ pub trait LayoutRPC { /// Query layout for the resolved value of a given CSS property fn resolved_style(&self) -> ResolvedStyleResponse; fn offset_parent(&self) -> OffsetParentResponse; + /// Query layout for the resolve values of the margin properties for an element. + fn margin_style(&self) -> MarginStyleResponse; } +#[derive(Clone)] +pub struct MarginStyleResponse { + pub top: margin_top::computed_value::T, + pub right: margin_right::computed_value::T, + pub bottom: margin_bottom::computed_value::T, + pub left: margin_left::computed_value::T, +} + +impl MarginStyleResponse { + pub fn empty() -> MarginStyleResponse { + MarginStyleResponse { + top: margin_top::computed_value::T::Auto, + right: margin_right::computed_value::T::Auto, + bottom: margin_bottom::computed_value::T::Auto, + left: margin_left::computed_value::T::Auto, + } + } +} pub struct ContentBoxResponse(pub Rect<Au>); pub struct ContentBoxesResponse(pub Vec<Rect<Au>>); @@ -145,6 +166,7 @@ pub enum ReflowQueryType { NodeGeometryQuery(TrustedNodeAddress), ResolvedStyleQuery(TrustedNodeAddress, Option<PseudoElement>, Atom), OffsetParentQuery(TrustedNodeAddress), + MarginStyleQuery(TrustedNodeAddress), } /// Information needed for a reflow. diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 59c4c094747..3513e593952 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -386,6 +386,7 @@ dependencies = [ "plugins 0.0.1", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index 846618da32b..fd72d6fc145 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -358,6 +358,7 @@ dependencies = [ "plugins 0.0.1", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock index 0ef2a176773..4202bb74279 100644 --- a/ports/gonk/Cargo.lock +++ b/ports/gonk/Cargo.lock @@ -350,6 +350,7 @@ dependencies = [ "plugins 0.0.1", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_macros 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", "util 0.0.1", |