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

Conversation

@dlrobertson
Copy link
Contributor

dlrobertson commented Feb 20, 2016

Implement the webdriver Get Element Rect command. Originally I wrote out the algorithm for Step 7 and then I found GetBoundingClientRect, and i thought it was probably best to use it instead.

As always, feedback is very welcomed!
#8623

Review on Reviewable

@highfive
Copy link

highfive commented Feb 20, 2016

warning Warning warning

  • These commits modify script code, but no tests are modified. Please consider adding a test!
@@ -816,7 +834,7 @@ impl WebDriverHandler<ServoExtensionRoute> for Handler {
ServoExtensionCommand::SetPrefs(ref x) => self.handle_set_prefs(x),
ServoExtensionCommand::ResetPrefs(ref x) => self.handle_reset_prefs(x),
}
}
},

This comment has been minimized.

Copy link
@KiChjang

KiChjang Feb 20, 2016

Member

The comma here isn't necessary when the match-arm uses braces.

@dlrobertson dlrobertson force-pushed the dlrobertson:i8623 branch from 80fb8e0 to 65d7483 Feb 20, 2016
@jdm
Copy link
Member

jdm commented Feb 20, 2016

If we fixed #9651, GetBoundingClientRect would become inappropriate for this, I believe.

@dlrobertson
Copy link
Contributor Author

dlrobertson commented Feb 20, 2016

If we fixed #9651, GetBoundingClientRect would become inappropriate for this, I believe.

Ah, I see... So would it be better to go back to the written out algorithm?

@jdm
Copy link
Member

jdm commented Feb 20, 2016

I think so, yes.

@dlrobertson dlrobertson force-pushed the dlrobertson:i8623 branch from 65d7483 to 25967ab Feb 20, 2016
@dlrobertson
Copy link
Contributor Author

dlrobertson commented Feb 20, 2016

As stated in #9709, I think I'm wrong on my implementation of find_element_by_element_id. Step 3 in the spec mentions that the element should be found by UUID, so I think I should be using find_node_by_unique_id


Review status: 0 of 4 files reviewed at latest revision, 2 unresolved discussions.


components/script/webdriver_handlers.rs, line 227 [r2] (raw file):
webdriver::ElementRectResponse uses f64, so I just make the conversion here.


components/webdriver_server/lib.rs, line 837 [r1] (raw file):
Fixed. Thanks!


Comments from the review on Reviewable.io

let mut y: i32 = 0;
// Step 2
let mut offset_parent = html_elem.GetOffsetParent();
while offset_parent.is_some() {

This comment has been minimized.

Copy link
@KiChjang

KiChjang Feb 21, 2016

Member

This can be while let Some(element) = offset_parent {.

// Step 2
let mut offset_parent = html_elem.GetOffsetParent();
while offset_parent.is_some() {
offset_parent = match offset_parent.unwrap().downcast::<HTMLElement>() {

This comment has been minimized.

Copy link
@KiChjang

KiChjang Feb 21, 2016

Member

offset_parent = offset_parent.downcast::<HTMLElement>().map(|elem| {

@dlrobertson
Copy link
Contributor Author

dlrobertson commented Feb 21, 2016

Review status: 0 of 4 files reviewed at latest revision, 4 unresolved discussions.


components/script/webdriver_handlers.rs, line 210 [r2] (raw file):
Much cleaner 😄 i don't know why i didn't do that.


components/script/webdriver_handlers.rs, line 211 [r2] (raw file):
Nice!


Comments from the review on Reviewable.io

@dlrobertson dlrobertson force-pushed the dlrobertson:i8623 branch from 25967ab to 80aeb2f Feb 21, 2016
@dlrobertson
Copy link
Contributor Author

dlrobertson commented Feb 21, 2016

Review status: 0 of 4 files reviewed at latest revision, 5 unresolved discussions.


components/script/webdriver_handlers.rs, line 40 [r4] (raw file):
After looking at this it seemed like this should use find. So I changed this in a separate commit


Comments from the review on Reviewable.io

x += elem.OffsetLeft();
y += elem.OffsetTop();
elem.GetOffsetParent()
}).unwrap_or(None);

This comment has been minimized.

Copy link
@KiChjang

KiChjang Feb 21, 2016

Member

Why is an unwrap_or still necessary?

@dlrobertson
Copy link
Contributor Author

dlrobertson commented Feb 21, 2016

Review status: 0 of 4 files reviewed at latest revision, 6 unresolved discussions.


components/script/webdriver_handlers.rs, line 209 [r4] (raw file):
Great question! Map will return an Option<T> and GetOffsetParent will return a Option<Root<Element>>, so unless I'm mistaken object.downcast<T>().map(...) should return an Option<Option<HTMLElement>> while offset_parent is an Option<HTMLElement>, so I used unwrap_or to unwrap the inner Option. I'll double check to see if it compiles without it, but I don't think it will.

Also if you know a better way around this let me know!


Comments from the review on Reviewable.io

@dlrobertson dlrobertson force-pushed the dlrobertson:i8623 branch from f421d16 to 568c505 Feb 21, 2016
@@ -52,6 +53,14 @@ pub enum WebDriverFrameId {
Parent
}

#[derive(Clone, Copy, Deserialize, Serialize)]
pub struct WebDriverElementRect {

This comment has been minimized.

Copy link
@Ms2ger

Ms2ger Feb 21, 2016

Contributor

Why not a Rect from Euclid?

This comment has been minimized.

Copy link
@dlrobertson

dlrobertson Feb 21, 2016

Author Contributor

Great point, didn't see that it impl'd Serialize. I'll make the change in the update.

page.document().upcast::<Node>().traverse_preorder().find(|x| match x.downcast::<Element>() {
Some(elem) => elem.Id() == &*element_id,
None => false
}).map(|x| Root::from_ref(x.downcast::<Element>().unwrap()))

This comment has been minimized.

Copy link
@Ms2ger

Ms2ger Feb 21, 2016

Contributor

GetElementById should be a lot faster.

This comment has been minimized.

Copy link
@dlrobertson

dlrobertson Feb 21, 2016

Author Contributor

Good point, but I think I'm wrong here. See Step 3 of the spec. I think I'm supposed to find by UUID or Node::unique_id.

while let Some(element) = offset_parent {
offset_parent = element.downcast::<HTMLElement>().and_then(|elem| {
x += elem.OffsetLeft();
y += elem.OffsetTop();

This comment has been minimized.

Copy link
@Ms2ger

Ms2ger Feb 21, 2016

Contributor

Using and_then with a callback that mutates closed-over state us poor practice

This comment has been minimized.

Copy link
@dlrobertson

dlrobertson Feb 21, 2016

Author Contributor
  • Is there documentation for this?
  • Is this the case for all iterator adapters or just the Option<T> methods that take a FnOnce or just and_then?

Ideally I'd like to create a OffsetParentIterator struct, impl Iterator, and use fold, but this seems to be the only case where this would be used. Without an iterator as far as I know we're pretty much stuck to a while loop and mutating x and y. Let me know if I'm missing anything. Thanks for the comments!

@dlrobertson dlrobertson force-pushed the dlrobertson:i8623 branch from 568c505 to 0bb9143 Feb 22, 2016
}
},
None => Err(())
}).unwrap()

This comment has been minimized.

Copy link
@KiChjang

KiChjang Feb 24, 2016

Member

This function doesn't look like it has a return value. Perhaps you're missing a semi-colon here?

Some(html_elem) => {
// Step 1
let mut x: i32 = 0;
let mut y: i32 = 0;

This comment has been minimized.

Copy link
@KiChjang

KiChjang Feb 24, 2016

Member

nit: Instead of specifying the type of x and y, specify the type of the 0 constant instead (i.e. use 0i32 instead of 0).

@dlrobertson dlrobertson force-pushed the dlrobertson:i8623 branch from db9a24b to 99bfd76 Feb 24, 2016
@@ -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.

Copy link
@KiChjang

KiChjang Feb 24, 2016

Member

Are these imports necessary?

This comment has been minimized.

Copy link
@KiChjang

KiChjang Feb 24, 2016

Member

Wait, sorry, nevermind.

@@ -540,6 +541,24 @@ impl Handler {
}
}

fn handle_element_rect(&self, element: &WebElement) -> WebDriverResult<WebDriverResponse> {

This comment has been minimized.

Copy link
@KiChjang

KiChjang Feb 24, 2016

Member

Is there a spec link for this?

This comment has been minimized.

Copy link
@dlrobertson

dlrobertson Feb 24, 2016

Author Contributor

Good point. The update has the spec listed

This comment has been minimized.

Copy link
@KiChjang

KiChjang Feb 24, 2016

Member

How about this function?

@dlrobertson dlrobertson force-pushed the dlrobertson:i8623 branch 2 times, most recently from 8d2320a to a640955 Feb 24, 2016
// 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.

Copy link
@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.

dlrobertson added 2 commits Feb 20, 2016
Implement the webdriver Get Element Rect command
find_node_by_unique_id should use find instead of for-loop
@dlrobertson dlrobertson force-pushed the dlrobertson:i8623 branch from 826469a to cad3115 Feb 24, 2016
@KiChjang
Copy link
Member

KiChjang commented Feb 24, 2016

@bors-servo r+

Thanks for working on this!

@bors-servo
Copy link
Contributor

bors-servo commented Feb 24, 2016

📌 Commit cad3115 has been approved by KiChjang

@bors-servo
Copy link
Contributor

bors-servo commented Feb 25, 2016

Testing commit cad3115 with merge e5f3c5b...

bors-servo added a commit that referenced this pull request Feb 25, 2016
Implement GetElementRect webdriver command: #8623

Implement the webdriver Get Element Rect command. Originally I wrote out the algorithm for [Step 7](https://w3c.github.io/webdriver/webdriver-spec.html#dfn-calculate-the-absolute-position) and then I found `GetBoundingClientRect`, and i thought it was probably best to use it instead.

As always, feedback is very welcomed!

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.svg" height="40" alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9708)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

bors-servo commented Feb 25, 2016

@bors-servo bors-servo merged commit cad3115 into servo:master Feb 25, 2016
2 checks passed
2 checks passed
continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
@dlrobertson dlrobertson deleted the dlrobertson:i8623 branch Feb 25, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

6 participants
You can’t perform that action at this time.