Add support for switching frames with the webdriver API.

This moves webdriver_traits into msg to avoid a circular dependency.
This commit is contained in:
James Graham 2015-05-11 14:47:10 +01:00
parent c724444ccb
commit 49f1b13ad9
20 changed files with 273 additions and 122 deletions

View file

@ -45,9 +45,6 @@ path = "../canvas"
[dependencies.canvas_traits]
path = "../canvas_traits"
[dependencies.webdriver_traits]
path = "../webdriver_traits"
[dependencies.selectors]
git = "https://github.com/servo/rust-selectors"

View file

@ -38,9 +38,9 @@ use timers::{IsInterval, TimerId, TimerManager, TimerCallback};
use webdriver_handlers::jsval_to_webdriver;
use devtools_traits::{DevtoolsControlChan, TimelineMarker, TimelineMarkerType, TracingMetadata};
use webdriver_traits::{WebDriverJSError, WebDriverJSResult};
use msg::compositor_msg::ScriptListener;
use msg::constellation_msg::{LoadData, PipelineId, SubpageId, ConstellationChan, WindowSizeData, WorkerId};
use msg::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
use net_traits::ResourceTask;
use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask};
use net_traits::storage_task::{StorageTask, StorageType};
@ -437,17 +437,7 @@ impl<'a> WindowMethods for JSRef<'a, Window> {
// https://html.spec.whatwg.org/multipage/#dom-parent
fn Parent(self) -> Temporary<Window> {
let browser_context = self.browser_context();
let browser_context = browser_context.as_ref().unwrap();
browser_context.frame_element().map_or(self.Window(), |fe| {
let frame_element = fe.root();
let window = window_from_node(frame_element.r()).root();
// FIXME(https://github.com/rust-lang/rust/issues/23338)
let r = window.r();
let context = r.browser_context();
context.as_ref().unwrap().active_window()
})
self.parent().unwrap_or(self.Window())
}
fn Performance(self) -> Temporary<Performance> {
@ -558,6 +548,7 @@ pub trait WindowHelpers {
fn drop_devtools_timeline_markers(self);
fn set_webdriver_script_chan(self, chan: Option<Sender<WebDriverJSResult>>);
fn is_alive(self) -> bool;
fn parent(self) -> Option<Temporary<Window>>;
}
pub trait ScriptHelpers {
@ -939,6 +930,20 @@ impl<'a> WindowHelpers for JSRef<'a, Window> {
fn is_alive(self) -> bool {
self.current_state.get() == WindowState::Alive
}
fn parent(self) -> Option<Temporary<Window>> {
let browser_context = self.browser_context();
let browser_context = browser_context.as_ref().unwrap();
browser_context.frame_element().map(|fe| {
let frame_element = fe.root();
let window = window_from_node(frame_element.r()).root();
// FIXME(https://github.com/rust-lang/rust/issues/23338)
let r = window.r();
let context = r.browser_context();
context.as_ref().unwrap().active_window()
})
}
}
impl Window {

View file

@ -52,7 +52,6 @@ extern crate unicase;
extern crate url;
extern crate uuid;
extern crate string_cache;
extern crate webdriver_traits;
extern crate offscreen_gl_context;
pub mod cors;

View file

@ -62,12 +62,12 @@ use script_traits::CompositorEvent::{MouseMoveEvent, KeyEvent};
use script_traits::{NewLayoutInfo, OpaqueScriptLayoutChannel};
use script_traits::{ConstellationControlMsg, ScriptControlChan};
use script_traits::{ScriptState, ScriptTaskFactory};
use webdriver_traits::WebDriverScriptCommand;
use msg::compositor_msg::{LayerId, ScriptListener};
use msg::constellation_msg::{ConstellationChan, FocusType};
use msg::constellation_msg::{LoadData, PipelineId, SubpageId, MozBrowserEvent, WorkerId};
use msg::constellation_msg::{Failure, WindowSizeData, PipelineExitType};
use msg::constellation_msg::Msg as ConstellationMsg;
use msg::webdriver_msg::WebDriverScriptCommand;
use net_traits::{ResourceTask, LoadConsumer, ControlMsg, Metadata};
use net_traits::LoadData as NetLoadData;
use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask, ImageCacheResult};
@ -835,6 +835,8 @@ impl ScriptTask {
webdriver_handlers::handle_get_name(&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) =>
webdriver_handlers::handle_get_frame_id(&page, pipeline_id, frame_id, reply),
WebDriverScriptCommand::GetTitle(reply) =>
webdriver_handlers::handle_get_title(&page, pipeline_id, reply),
WebDriverScriptCommand::ExecuteAsyncScript(script, reply) =>

View file

@ -2,12 +2,12 @@
* 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 webdriver_traits::{WebDriverJSValue, WebDriverJSError, WebDriverJSResult};
use dom::bindings::conversions::FromJSValConvertible;
use dom::bindings::conversions::StringificationBehavior;
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast};
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast, HTMLIFrameElementCast};
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods;
use dom::bindings::js::{OptionalRootable, Rootable, Temporary};
@ -17,7 +17,8 @@ use dom::document::DocumentHelpers;
use js::jsapi::JSContext;
use js::jsval::JSVal;
use page::Page;
use msg::constellation_msg::PipelineId;
use msg::constellation_msg::{PipelineId, SubpageId};
use msg::webdriver_msg::{WebDriverJSValue, WebDriverJSError, WebDriverJSResult, WebDriverFrameId};
use script_task::get_page;
use std::rc::Rc;
@ -73,6 +74,36 @@ pub fn handle_execute_async_script(page: &Rc<Page>, pipeline: PipelineId, eval:
window.r().evaluate_js_on_global_with_result(&eval);
}
pub fn handle_get_frame_id(page: &Rc<Page>,
pipeline: PipelineId,
webdriver_frame_id: WebDriverFrameId,
reply: Sender<Result<Option<(PipelineId, SubpageId)>, ()>>) {
let window = match webdriver_frame_id {
WebDriverFrameId::Short(_) => {
// This isn't supported yet
Ok(None)
},
WebDriverFrameId::Element(x) => {
match find_node_by_unique_id(page, pipeline, x) {
Some(ref node) => {
match HTMLIFrameElementCast::to_ref(node.root().r()) {
Some(ref elem) => Ok(elem.GetContentWindow()),
None => Err(())
}
},
None => Err(())
}
},
WebDriverFrameId::Parent => {
let window = page.window();
Ok(window.root().r().parent())
}
};
let frame_id = window.map(|x| x.and_then(|x| x.root().r().parent_info()));
reply.send(frame_id).unwrap()
}
pub fn handle_find_element_css(page: &Rc<Page>, _pipeline: PipelineId, selector: String,
reply: Sender<Result<Option<String>, ()>>) {
reply.send(match page.document().root().r().QuerySelector(selector.clone()) {