web_view_impl.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/web_view_impl.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/files/file_path.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_writer.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/string_util.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stringprintf.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/threading/platform_thread.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/time.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/devtools_client_impl.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/dom_tracker.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/frame_tracker.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/geolocation_override_manager.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/javascript_dialog_manager.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/js.h" 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/log.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/navigation_tracker.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/status.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/ui_events.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status GetContextIdForFrame(FrameTracker* tracker, 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& frame, 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* context_id) { 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (frame.empty()) { 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *context_id = 0; 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = tracker->GetContextIdForFrame(frame, context_id); 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* GetAsString(MouseEventType type) { 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kPressedMouseEventType: 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "mousePressed"; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kReleasedMouseEventType: 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "mouseReleased"; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kMovedMouseEventType: 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "mouseMoved"; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ""; 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* GetAsString(MouseButton button) { 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (button) { 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kLeftMouseButton: 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "left"; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kMiddleMouseButton: 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "middle"; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kRightMouseButton: 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "right"; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kNoneMouseButton: 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "none"; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ""; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char* GetAsString(KeyEventType type) { 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kKeyDownEventType: 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "keyDown"; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kKeyUpEventType: 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "keyUp"; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kRawKeyDownEventType: 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "rawKeyDown"; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kCharEventType: 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "char"; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ""; 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebViewImpl::WebViewImpl(const std::string& id, 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<DevToolsClient> client, 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Log* log) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : id_(id), 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dom_tracker_(new DomTracker(client.get())), 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame_tracker_(new FrameTracker(client.get())), 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) navigation_tracker_(new NavigationTracker(client.get())), 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dialog_manager_(new JavaScriptDialogManager(client.get())), 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) geolocation_override_manager_( 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new GeolocationOverrideManager(client.get())), 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) client_(client.release()), 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) log_(log) {} 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebViewImpl::~WebViewImpl() {} 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string WebViewImpl::GetId() { 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return id_; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::ConnectIfNecessary() { 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->ConnectIfNecessary(); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)DevToolsClient* WebViewImpl::GetDevToolsClient() { 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return client_.get(); 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::Load(const std::string& url) { 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Javascript URLs will cause a hang while waiting for the page to stop 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // loading, so just disallow. 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (StartsWithASCII(url, "javascript:", false)) 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Status(kUnknownError, "unsupported protocol"); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("url", url); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->SendCommand("Page.navigate", params); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::Reload() { 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetBoolean("ignoreCache", false); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->SendCommand("Page.reload", params); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::EvaluateScript(const std::string& frame, 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id; 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = GetContextIdForFrame(frame_tracker_.get(), frame, 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &context_id); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return internal::EvaluateScriptAndGetValue( 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_.get(), context_id, expression, result); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::CallFunction(const std::string& frame, 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& function, 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue& args, 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string json; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::JSONWriter::Write(&args, &json); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string expression = base::StringPrintf( 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "(%s).apply(null, [%s, %s])", 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kCallFunctionScript, 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function.c_str(), 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) json.c_str()); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> temp_result; 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = EvaluateScript(frame, expression, &temp_result); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return internal::ParseCallFunctionResult(*temp_result, result); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::CallAsyncFunction(const std::string& frame, 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& function, 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue& args, 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::TimeDelta& timeout, 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value>* result) { 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return CallAsyncFunctionInternal( 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame, function, args, false, timeout, result); 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::CallUserAsyncFunction(const std::string& frame, 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& function, 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue& args, 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::TimeDelta& timeout, 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value>* result) { 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return CallAsyncFunctionInternal( 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame, function, args, true, timeout, result); 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::GetFrameByFunction(const std::string& frame, 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& function, 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue& args, 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* out_frame) { 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = GetContextIdForFrame(frame_tracker_.get(), frame, 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &context_id); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool found_node; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int node_id; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status = internal::GetNodeIdFromFunction( 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_.get(), context_id, function, args, &found_node, &node_id); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!found_node) 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kNoSuchFrame); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dom_tracker_->GetFrameIdForNode(node_id, out_frame); 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::DispatchMouseEvents(const std::list<MouseEvent>& events) { 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::list<MouseEvent>::const_iterator it = events.begin(); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != events.end(); ++it) { 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("type", GetAsString(it->type)); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("x", it->x); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("y", it->y); 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.SetInteger("modifiers", it->modifiers); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("button", GetAsString(it->button)); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("clickCount", it->click_count); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommand("Input.dispatchMouseEvent", params); 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::DispatchKeyEvents(const std::list<KeyEvent>& events) { 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::list<KeyEvent>::const_iterator it = events.begin(); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != events.end(); ++it) { 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("type", GetAsString(it->type)); 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it->modifiers & kNumLockKeyModifierMask) { 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetBoolean("isKeypad", true); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("modifiers", 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it->modifiers & ~kNumLockKeyModifierMask); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("modifiers", it->modifiers); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("text", it->modified_text); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("unmodifiedText", it->unmodified_text); 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("nativeVirtualKeyCode", it->key_code); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("windowsVirtualKeyCode", it->key_code); 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommand("Input.dispatchKeyEvent", params); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::GetCookies(scoped_ptr<base::ListValue>* cookies) { 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> result; 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommandAndGetResult( 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Page.getCookies", params, &result); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* cookies_tmp; 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result->GetList("cookies", &cookies_tmp)) 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "DevTools didn't return cookies"); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cookies->reset(cookies_tmp->DeepCopy()); 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::DeleteCookie(const std::string& name, 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& url) { 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("cookieName", name); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("url", url); 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->SendCommand("Page.deleteCookie", params); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::WaitForPendingNavigations(const std::string& frame_id) { 26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) log_->AddEntry(Log::kLog, "waiting for pending navigations"); 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Status status = client_->HandleEventsUntil( 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&WebViewImpl::IsNotPendingNavigation, base::Unretained(this), 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) frame_id)); 26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) log_->AddEntry(Log::kLog, "done waiting for pending navigations"); 26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return status; 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::IsPendingNavigation(const std::string& frame_id, 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* is_pending) { 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return navigation_tracker_->IsPendingNavigation(frame_id, is_pending); 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)JavaScriptDialogManager* WebViewImpl::GetJavaScriptDialogManager() { 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dialog_manager_.get(); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::OverrideGeolocation(const Geoposition& geoposition) { 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return geolocation_override_manager_->OverrideGeolocation(geoposition); 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::CaptureScreenshot(std::string* screenshot) { 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> result; 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommandAndGetResult( 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Page.captureScreenshot", params, &result); 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result->GetString("data", screenshot)) 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "expected string 'data' in response"); 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::SetFileInputFiles( 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& frame, 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue& element, 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::vector<base::FilePath>& files) { 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue file_list; 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < files.size(); ++i) { 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!files[i].IsAbsolute()) { 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "path is not absolute: " + files[i].AsUTF8Unsafe()); 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (files[i].ReferencesParent()) { 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "path is not canonical: " + files[i].AsUTF8Unsafe()); 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_list.AppendString(files[i].value()); 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int context_id; 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = GetContextIdForFrame(frame_tracker_.get(), frame, 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &context_id); 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue args; 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args.Append(element.DeepCopy()); 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool found_node; 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int node_id; 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) status = internal::GetNodeIdFromFunction( 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_.get(), context_id, "function(element) { return element; }", 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args, &found_node, &node_id); 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!found_node) 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "no node ID for file input"); 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue params; 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.SetInteger("nodeId", node_id); 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.Set("files", file_list.DeepCopy()); 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return client_->SendCommand("DOM.setFileInputFiles", params); 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::CallAsyncFunctionInternal(const std::string& frame, 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& function, 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue& args, 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_user_supplied, 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::TimeDelta& timeout, 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value>* result) { 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue async_args; 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.AppendString("return (" + function + ").apply(null, arguments);"); 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.Append(args.DeepCopy()); 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.AppendBoolean(is_user_supplied); 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.AppendInteger(timeout.InMilliseconds()); 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value> tmp; 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = CallFunction( 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame, kExecuteAsyncScriptScript, async_args, &tmp); 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* kDocUnloadError = "document unloaded while waiting for result"; 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string kQueryResult = base::StringPrintf( 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "function() {" 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " var info = document.$chrome_asyncScriptInfo;" 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " if (!info)" 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " return {status: %d, value: '%s'};" 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " var result = info.result;" 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " if (!result)" 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " return {status: 0};" 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " delete info.result;" 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " return result;" 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "}", 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kJavaScriptError, 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kDocUnloadError); 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (true) { 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue no_args; 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value> query_value; 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = CallFunction(frame, kQueryResult, no_args, &query_value); 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) { 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.code() == kNoSuchFrame) 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kJavaScriptError, kDocUnloadError); 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* result_info = NULL; 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!query_value->GetAsDictionary(&result_info)) 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "async result info is not a dictionary"); 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int status_code; 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!result_info->GetInteger("status", &status_code)) 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "async result info has no int 'status'"); 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status_code != kOk) { 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string message; 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result_info->GetString("value", &message); 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(static_cast<StatusCode>(status_code), message); 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Value* value = NULL; 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (result_info->Get("value", &value)) { 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result->reset(value->DeepCopy()); 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 39890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Status WebViewImpl::IsNotPendingNavigation(const std::string& frame_id, 39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool* is_not_pending) { 40090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool is_pending; 40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Status status = 40290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) navigation_tracker_->IsPendingNavigation(frame_id, &is_pending); 40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (status.IsError()) 40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return status; 40590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // An alert may block the pending navigation. 40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (is_pending && dialog_manager_->IsDialogOpen()) 40790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Status(kUnexpectedAlertOpen); 40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 40990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *is_not_pending = !is_pending; 41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Status(kOk); 41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 41290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace internal { 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status EvaluateScript(DevToolsClient* client, 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EvaluateScriptReturnType return_type, 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue>* result) { 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("expression", expression); 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (context_id) 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("contextId", context_id); 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetBoolean("returnByValue", return_type == ReturnByValue); 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> cmd_result; 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client->SendCommandAndGetResult( 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Runtime.evaluate", params, &cmd_result); 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool was_thrown; 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cmd_result->GetBoolean("wasThrown", &was_thrown)) 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "Runtime.evaluate missing 'wasThrown'"); 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (was_thrown) { 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string description = "unknown"; 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cmd_result->GetString("result.description", &description); 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Runtime.evaluate threw exception: " + description); 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* unscoped_result; 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cmd_result->GetDictionary("result", &unscoped_result)) 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "evaluate missing dictionary 'result'"); 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(unscoped_result->DeepCopy()); 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status EvaluateScriptAndGetObject(DevToolsClient* client, 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool* got_object, 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* object_id) { 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> result; 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = EvaluateScript(client, context_id, expression, ReturnByObject, 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &result); 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!result->HasKey("objectId")) { 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *got_object = false; 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result->GetString("objectId", object_id)) 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "evaluate has invalid 'objectId'"); 464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *got_object = true; 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status EvaluateScriptAndGetValue(DevToolsClient* client, 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> temp_result; 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = EvaluateScript(client, context_id, expression, ReturnByValue, 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &temp_result); 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string type; 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!temp_result->GetString("type", &type)) 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "Runtime.evaluate missing string 'type'"); 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (type == "undefined") { 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(base::Value::CreateNullValue()); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value* value; 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!temp_result->Get("value", &value)) 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "Runtime.evaluate missing 'value'"); 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(value->DeepCopy()); 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ParseCallFunctionResult(const base::Value& temp_result, 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue* dict; 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!temp_result.GetAsDictionary(&dict)) 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "call function result must be a dictionary"); 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int status_code; 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dict->GetInteger("status", &status_code)) { 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "call function result missing int 'status'"); 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status_code != kOk) { 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string message; 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict->GetString("value", &message); 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(static_cast<StatusCode>(status_code), message); 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Value* unscoped_value; 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dict->Get("value", &unscoped_value)) { 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "call function result missing 'value'"); 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(unscoped_value->DeepCopy()); 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status GetNodeIdFromFunction(DevToolsClient* client, 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& function, 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue& args, 521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool* found_node, 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* node_id) { 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string json; 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::JSONWriter::Write(&args, &json); 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string expression = base::StringPrintf( 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "(%s).apply(null, [%s, %s, true])", 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kCallFunctionScript, 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function.c_str(), 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) json.c_str()); 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool got_object; 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string element_id; 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = internal::EvaluateScriptAndGetObject( 534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client, context_id, expression, &got_object, &element_id); 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!got_object) { 538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *found_node = false; 539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> cmd_result; 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("objectId", element_id); 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status = client->SendCommandAndGetResult( 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "DOM.requestNode", params, &cmd_result); 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Release the remote object before doing anything else. 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("objectId", element_id); 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status release_status = 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client->SendCommand("Runtime.releaseObject", params); 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (release_status.IsError()) { 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Failed to release remote object: " 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << release_status.message(); 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cmd_result->GetInteger("nodeId", node_id)) 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "DOM.requestNode missing int 'nodeId'"); 565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *found_node = true; 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace internal 570