aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/msg/webdriver_msg.rs2
-rw-r--r--components/script/script_thread.rs2
-rw-r--r--components/script/webdriver_handlers.rs41
-rw-r--r--components/webdriver_server/lib.rs23
4 files changed, 67 insertions, 1 deletions
diff --git a/components/msg/webdriver_msg.rs b/components/msg/webdriver_msg.rs
index 94c4556b5f0..fb59de4a922 100644
--- a/components/msg/webdriver_msg.rs
+++ b/components/msg/webdriver_msg.rs
@@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use constellation_msg::{PipelineId, WindowSizeData};
+use euclid::rect::Rect;
use ipc_channel::ipc::IpcSender;
use rustc_serialize::json::{Json, ToJson};
use url::Url;
@@ -17,6 +18,7 @@ pub enum WebDriverScriptCommand {
GetActiveElement(IpcSender<Option<String>>),
GetElementAttribute(String, String, IpcSender<Result<Option<String>, ()>>),
GetElementCSS(String, String, IpcSender<Result<String, ()>>),
+ GetElementRect(String, IpcSender<Result<Rect<f64>, ()>>),
GetElementTagName(String, IpcSender<Result<String, ()>>),
GetElementText(String, IpcSender<Result<String, ()>>),
GetFrameId(WebDriverFrameId, IpcSender<Result<Option<PipelineId>, ()>>),
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index 1f4a82ec02d..ddf32f85406 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -1246,6 +1246,8 @@ impl ScriptThread {
webdriver_handlers::handle_get_attribute(&page, pipeline_id, node_id, name, reply),
WebDriverScriptCommand::GetElementCSS(node_id, name, reply) =>
webdriver_handlers::handle_get_css(&page, pipeline_id, node_id, name, reply),
+ WebDriverScriptCommand::GetElementRect(node_id, reply) =>
+ webdriver_handlers::handle_get_rect(&page, pipeline_id, node_id, reply),
WebDriverScriptCommand::GetElementText(node_id, reply) =>
webdriver_handlers::handle_get_text(&page, pipeline_id, node_id, reply),
WebDriverScriptCommand::GetFrameId(frame_id, reply) =>
diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs
index 0c9831bf3f6..1b1d92fc914 100644
--- a/components/script/webdriver_handlers.rs
+++ b/components/script/webdriver_handlers.rs
@@ -22,6 +22,9 @@ use dom::htmlinputelement::HTMLInputElement;
use dom::htmloptionelement::HTMLOptionElement;
use dom::node::Node;
use dom::window::ScriptHelpers;
+use euclid::point::Point2D;
+use euclid::rect::Rect;
+use euclid::size::Size2D;
use ipc_channel::ipc::IpcSender;
use js::jsapi::JSContext;
use js::jsapi::{HandleValue, RootedValue};
@@ -185,6 +188,44 @@ pub fn handle_get_title(page: &Rc<Page>, _pipeline: PipelineId, reply: IpcSender
reply.send(String::from(page.document().Title())).unwrap();
}
+pub fn handle_get_rect(page: &Rc<Page>,
+ pipeline: PipelineId,
+ element_id: String,
+ reply: IpcSender<Result<Rect<f64>, ()>>) {
+ reply.send(match find_node_by_unique_id(&*page, pipeline, element_id) {
+ Some(elem) => {
+ // https://w3c.github.io/webdriver/webdriver-spec.html#dfn-calculate-the-absolute-position
+ match elem.downcast::<HTMLElement>() {
+ Some(html_elem) => {
+ // Step 1
+ let mut x = 0;
+ let mut y = 0;
+
+ let mut offset_parent = html_elem.GetOffsetParent();
+
+ // Step 2
+ while let Some(element) = offset_parent {
+ offset_parent = match element.downcast::<HTMLElement>() {
+ Some(elem) => {
+ x += elem.OffsetLeft();
+ y += elem.OffsetTop();
+ elem.GetOffsetParent()
+ },
+ None => None
+ };
+ }
+ // Step 3
+ Ok(Rect::new(Point2D::new(x as f64, y as f64),
+ Size2D::new(html_elem.OffsetWidth() as f64,
+ html_elem.OffsetHeight() as f64)))
+ },
+ None => Err(())
+ }
+ },
+ None => Err(())
+ }).unwrap();
+}
+
pub fn handle_get_text(page: &Rc<Page>,
pipeline: PipelineId,
node_id: String,
diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs
index 2979609c295..aa1e6ae4135 100644
--- a/components/webdriver_server/lib.rs
+++ b/components/webdriver_server/lib.rs
@@ -51,7 +51,8 @@ use webdriver::command::{WebDriverCommand, WebDriverExtensionCommand, WebDriverM
use webdriver::common::{LocatorStrategy, WebElement};
use webdriver::error::{ErrorStatus, WebDriverError, WebDriverResult};
use webdriver::httpapi::{WebDriverExtensionRoute};
-use webdriver::response::{NewSessionResponse, ValueResponse, WebDriverResponse, WindowSizeResponse};
+use webdriver::response::{ElementRectResponse, NewSessionResponse, ValueResponse};
+use webdriver::response::{WebDriverResponse, WindowSizeResponse};
use webdriver::server::{self, Session, WebDriverHandler};
fn extension_routes() -> Vec<(Method, &'static str, ServoExtensionRoute)> {
@@ -540,6 +541,25 @@ impl Handler {
}
}
+ // https://w3c.github.io/webdriver/webdriver-spec.html#get-element-rect
+ fn handle_element_rect(&self, element: &WebElement) -> WebDriverResult<WebDriverResponse> {
+ let pipeline_id = try!(self.frame_pipeline());
+
+ let (sender, receiver) = ipc::channel().unwrap();
+ let cmd = WebDriverScriptCommand::GetElementRect(element.id.clone(), sender);
+ let cmd_msg = WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd);
+ self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
+ match receiver.recv().unwrap() {
+ Ok(rect) => {
+ let response = ElementRectResponse::new(rect.origin.x, rect.origin.y,
+ rect.size.width, rect.size.height);
+ Ok(WebDriverResponse::ElementRect(response))
+ },
+ Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference,
+ "Unable to find element in document"))
+ }
+ }
+
fn handle_element_text(&self, element: &WebElement) -> WebDriverResult<WebDriverResponse> {
let pipeline_id = try!(self.frame_pipeline());
@@ -798,6 +818,7 @@ impl WebDriverHandler<ServoExtensionRoute> for Handler {
WebDriverCommand::FindElement(ref parameters) => self.handle_find_element(parameters),
WebDriverCommand::FindElements(ref parameters) => self.handle_find_elements(parameters),
WebDriverCommand::GetActiveElement => self.handle_active_element(),
+ WebDriverCommand::GetElementRect(ref element) => self.handle_element_rect(element),
WebDriverCommand::GetElementText(ref element) => self.handle_element_text(element),
WebDriverCommand::GetElementTagName(ref element) => self.handle_element_tag_name(element),
WebDriverCommand::GetElementAttribute(ref element, ref name) =>