servo: Merge #11179 - Implemented webdriver SetWindowSize (from asajeffrey:webdriver-resize-window); r=jgraham

Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data:
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #10467 (github issue number if applicable).

Either:
- [ ] There are tests for these changes OR
- [X] These changes do not require tests because the new tests are in https://github.com/w3c/web-platform-tests/pull/3024

Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process.

Source-Repo: https://github.com/servo/servo
Source-Revision: 2063bde0a4dc512494e6548a036448ded3056762
This commit is contained in:
Alan Jeffrey 2016-05-23 02:53:48 -07:00
Родитель d77fd07ddc
Коммит 796b631fca
9 изменённых файлов: 61 добавлений и 26 удалений

Просмотреть файл

@ -292,13 +292,15 @@ impl<'a> Iterator for FrameTreeIterator<'a> {
}
struct WebDriverData {
load_channel: Option<(PipelineId, IpcSender<webdriver_msg::LoadStatus>)>
load_channel: Option<(PipelineId, IpcSender<webdriver_msg::LoadStatus>)>,
resize_channel: Option<IpcSender<WindowSizeData>>,
}
impl WebDriverData {
fn new() -> WebDriverData {
WebDriverData {
load_channel: None
load_channel: None,
resize_channel: None,
}
}
}
@ -1484,6 +1486,13 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
// Find the script channel for the given parent pipeline,
// and pass the event to that script thread.
match msg {
WebDriverCommandMsg::GetWindowSize(_, reply) => {
let _ = reply.send(self.window_size);
},
WebDriverCommandMsg::SetWindowSize(_, size, reply) => {
self.webdriver.resize_channel = Some(reply);
self.compositor_proxy.send(ToCompositorMsg::ResizeTo(size));
},
WebDriverCommandMsg::LoadUrl(pipeline_id, load_data, reply) => {
self.load_url_for_webdriver(pipeline_id, load_data, reply);
},
@ -1703,6 +1712,10 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
}
}
if let Some(resize_channel) = self.webdriver.resize_channel.take() {
let _ = resize_channel.send(new_size);
}
self.window_size = new_size;
}

Просмотреть файл

@ -6,7 +6,7 @@
//! reduce coupling between these two components.
use euclid::scale_factor::ScaleFactor;
use euclid::size::TypedSize2D;
use euclid::size::{Size2D, TypedSize2D};
use hyper::header::Headers;
use hyper::method::Method;
use ipc_channel::ipc::{IpcSender, IpcSharedMemory};
@ -188,10 +188,12 @@ bitflags! {
#[derive(Deserialize, Serialize)]
pub enum WebDriverCommandMsg {
GetWindowSize(PipelineId, IpcSender<WindowSizeData>),
LoadUrl(PipelineId, LoadData, IpcSender<LoadStatus>),
Refresh(PipelineId, IpcSender<LoadStatus>),
ScriptCommand(PipelineId, WebDriverScriptCommand),
SendKeys(PipelineId, Vec<(Key, KeyModifiers, KeyState)>),
SetWindowSize(PipelineId, Size2D<u32>, IpcSender<WindowSizeData>),
TakeScreenshot(PipelineId, IpcSender<Option<Image>>),
}

Просмотреть файл

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use constellation_msg::{PipelineId, WindowSizeData};
use constellation_msg::PipelineId;
use euclid::rect::Rect;
use ipc_channel::ipc::IpcSender;
use rustc_serialize::json::{Json, ToJson};
@ -23,7 +23,6 @@ pub enum WebDriverScriptCommand {
GetElementText(String, IpcSender<Result<String, ()>>),
GetFrameId(WebDriverFrameId, IpcSender<Result<Option<PipelineId>, ()>>),
GetUrl(IpcSender<Url>),
GetWindowSize(IpcSender<Option<WindowSizeData>>),
IsEnabled(String, IpcSender<Result<bool, ()>>),
IsSelected(String, IpcSender<Result<bool, ()>>),
GetTitle(IpcSender<String>)

Просмотреть файл

@ -1045,8 +1045,6 @@ impl ScriptThread {
webdriver_handlers::handle_get_frame_id(&context, pipeline_id, frame_id, reply),
WebDriverScriptCommand::GetUrl(reply) =>
webdriver_handlers::handle_get_url(&context, pipeline_id, reply),
WebDriverScriptCommand::GetWindowSize(reply) =>
webdriver_handlers::handle_get_window_size(&context, pipeline_id, reply),
WebDriverScriptCommand::IsEnabled(element_id, reply) =>
webdriver_handlers::handle_is_enabled(&context, pipeline_id, element_id, reply),
WebDriverScriptCommand::IsSelected(element_id, reply) =>

Просмотреть файл

@ -30,7 +30,7 @@ use ipc_channel::ipc::IpcSender;
use js::jsapi::JSContext;
use js::jsapi::{HandleValue, RootedValue};
use js::jsval::UndefinedValue;
use msg::constellation_msg::{PipelineId, WindowSizeData};
use msg::constellation_msg::PipelineId;
use msg::webdriver_msg::{WebDriverFrameId, WebDriverJSError, WebDriverJSResult, WebDriverJSValue};
use script_thread::get_browsing_context;
use url::Url;
@ -282,14 +282,6 @@ pub fn handle_get_url(context: &BrowsingContext,
reply.send((*url).clone()).unwrap();
}
pub fn handle_get_window_size(context: &BrowsingContext,
_pipeline: PipelineId,
reply: IpcSender<Option<WindowSizeData>>) {
let window = context.active_window();
let size = window.window_size();
reply.send(size).unwrap();
}
pub fn handle_is_enabled(context: &BrowsingContext,
pipeline: PipelineId,
element_id: String,

1
servo/components/servo/Cargo.lock сгенерированный
Просмотреть файл

@ -2483,6 +2483,7 @@ name = "webdriver_server"
version = "0.0.1"
dependencies = [
"compositing 0.0.1",
"euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",

Просмотреть файл

@ -13,6 +13,7 @@ compositing = {path = "../compositing"}
msg = {path = "../msg"}
plugins = {path = "../plugins"}
util = {path = "../util"}
euclid = {version = "0.6.4", features = ["plugins"]}
ipc-channel = {git = "https://github.com/servo/ipc-channel"}
image = "0.10"
log = "0.3.5"

Просмотреть файл

@ -11,6 +11,7 @@
#![deny(unsafe_code)]
extern crate compositing;
extern crate euclid;
extern crate hyper;
extern crate image;
extern crate ipc_channel;
@ -25,6 +26,7 @@ extern crate webdriver;
mod keys;
use compositing::CompositorMsg as ConstellationMsg;
use euclid::Size2D;
use hyper::method::Method::{self, Post};
use image::{DynamicImage, ImageFormat, RgbImage};
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
@ -46,7 +48,8 @@ use util::prefs::{get_pref, reset_all_prefs, reset_pref, set_pref, PrefValue};
use util::thread::spawn_named;
use uuid::Uuid;
use webdriver::command::{GetParameters, JavascriptCommandParameters, LocatorParameters};
use webdriver::command::{Parameters, SendKeysParameters, SwitchToFrameParameters, TimeoutsParameters};
use webdriver::command::{Parameters, SendKeysParameters, SwitchToFrameParameters};
use webdriver::command::{TimeoutsParameters, WindowSizeParameters};
use webdriver::command::{WebDriverCommand, WebDriverExtensionCommand, WebDriverMessage};
use webdriver::common::{LocatorStrategy, WebElement};
use webdriver::error::{ErrorStatus, WebDriverError, WebDriverResult};
@ -80,6 +83,7 @@ struct Handler {
constellation_chan: Sender<ConstellationMsg>,
script_timeout: u32,
load_timeout: u32,
resize_timeout: u32,
implicit_wait_timeout: u32
}
@ -219,6 +223,7 @@ impl Handler {
constellation_chan: constellation_chan,
script_timeout: 30_000,
load_timeout: 300_000,
resize_timeout: 500,
implicit_wait_timeout: 0
}
}
@ -354,17 +359,39 @@ impl Handler {
fn handle_window_size(&self) -> WebDriverResult<WebDriverResponse> {
let (sender, receiver) = ipc::channel().unwrap();
let pipeline_id = try!(self.root_pipeline());
let cmd_msg = WebDriverCommandMsg::GetWindowSize(pipeline_id, sender);
try!(self.root_script_command(WebDriverScriptCommand::GetWindowSize(sender)));
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
match receiver.recv().unwrap() {
Some(window_size) => {
let vp = window_size.visible_viewport;
let window_size_response = WindowSizeResponse::new(vp.width.get() as u64, vp.height.get() as u64);
Ok(WebDriverResponse::WindowSize(window_size_response))
},
None => Err(WebDriverError::new(ErrorStatus::NoSuchWindow, "Unable to determine window size"))
}
let window_size = receiver.recv().unwrap();
let vp = window_size.visible_viewport;
let window_size_response = WindowSizeResponse::new(vp.width.get() as u64, vp.height.get() as u64);
Ok(WebDriverResponse::WindowSize(window_size_response))
}
fn handle_set_window_size(&self, params: &WindowSizeParameters) -> WebDriverResult<WebDriverResponse> {
let (sender, receiver) = ipc::channel().unwrap();
let size = Size2D::new(params.width as u32, params.height as u32);
let pipeline_id = try!(self.root_pipeline());
let cmd_msg = WebDriverCommandMsg::SetWindowSize(pipeline_id, size, sender.clone());
self.constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
let timeout = self.resize_timeout;
let constellation_chan = self.constellation_chan.clone();
thread::spawn(move || {
// On timeout, we send a GetWindowSize message to the constellation,
// which will give the current window size.
thread::sleep(Duration::from_millis(timeout as u64));
let cmd_msg = WebDriverCommandMsg::GetWindowSize(pipeline_id, sender);
constellation_chan.send(ConstellationMsg::WebDriverCommand(cmd_msg)).unwrap();
});
let window_size = receiver.recv().unwrap();
let vp = window_size.visible_viewport;
let window_size_response = WindowSizeResponse::new(vp.width.get() as u64, vp.height.get() as u64);
Ok(WebDriverResponse::WindowSize(window_size_response))
}
fn handle_is_enabled(&self, element: &WebElement) -> WebDriverResult<WebDriverResponse> {
@ -767,6 +794,7 @@ impl WebDriverHandler<ServoExtensionRoute> for Handler {
WebDriverCommand::Get(ref parameters) => self.handle_get(parameters),
WebDriverCommand::GetCurrentUrl => self.handle_current_url(),
WebDriverCommand::GetWindowSize => self.handle_window_size(),
WebDriverCommand::SetWindowSize(ref size) => self.handle_set_window_size(size),
WebDriverCommand::IsEnabled(ref element) => self.handle_is_enabled(element),
WebDriverCommand::IsSelected(ref element) => self.handle_is_selected(element),
WebDriverCommand::GoBack => self.handle_go_back(),

1
servo/ports/cef/Cargo.lock сгенерированный
Просмотреть файл

@ -2344,6 +2344,7 @@ name = "webdriver_server"
version = "0.0.1"
dependencies = [
"compositing 0.0.1",
"euclid 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",