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 all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -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};
@@ -37,15 +40,7 @@ use util::str::DOMString;
fn find_node_by_unique_id(page: &Rc<Page>, pipeline: PipelineId, node_id: String) -> Option<Root<Node>> {
let page = get_page(&*page, pipeline);
let document = page.document();
let node = document.upcast::<Node>();

for candidate in node.traverse_preorder() {
if candidate.get_unique_id() == node_id {
return Some(candidate);
}
}

None
document.upcast::<Node>().traverse_preorder().find(|candidate| candidate.get_unique_id() == node_id)
}

#[allow(unsafe_code)]
@@ -185,6 +180,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> {
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.