Skip to content
Permalink
Browse files

Implement GetElementRect webdriver command

Implement the webdriver Get Element Rect command
  • Loading branch information...
dlrobertson committed Feb 20, 2016
1 parent 875f1e9 commit 83b2388ef4deb6eaa3d26088d0e78c07bca4e7cf
@@ -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>, ()>>),
@@ -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) =>
@@ -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,
@@ -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) =>

0 comments on commit 83b2388

Please sign in to comment.
You can’t perform that action at this time.