Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement GetElementRect webdriver command: #8623 #9708

Merged
merged 2 commits into from Feb 25, 2016
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Next

Implement GetElementRect webdriver command

Implement the webdriver Get Element Rect command
  • Loading branch information
dlrobertson committed Feb 24, 2016
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;

This comment has been minimized.

@KiChjang

KiChjang Feb 24, 2016

Member

Are these imports necessary?

This comment has been minimized.

@KiChjang

KiChjang Feb 24, 2016

Member

Wait, sorry, nevermind.

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

This comment has been minimized.

@KiChjang

KiChjang Feb 24, 2016

Member

This will definitely confuse people as to which spec this step is following. I think this should only link to the absolute position spec.

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> {

This comment has been minimized.

@KiChjang

KiChjang Feb 24, 2016

Member

Is there a spec link for this?

This comment has been minimized.

@dlrobertson

dlrobertson Feb 24, 2016

Author Contributor

Good point. The update has the spec listed

This comment has been minimized.

@KiChjang

KiChjang Feb 24, 2016

Member

How about this function?

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) =>
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.