web_view_impl.cc revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
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" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/threading/platform_thread.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/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, 88ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int build_no, 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<DevToolsClient> client, 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Log* log) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : id_(id), 92ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch build_no_(build_no), 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dom_tracker_(new DomTracker(client.get())), 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame_tracker_(new FrameTracker(client.get())), 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) navigation_tracker_(new NavigationTracker(client.get())), 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dialog_manager_(new JavaScriptDialogManager(client.get())), 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) geolocation_override_manager_( 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new GeolocationOverrideManager(client.get())), 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) client_(client.release()), 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) log_(log) {} 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebViewImpl::~WebViewImpl() {} 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string WebViewImpl::GetId() { 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return id_; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::ConnectIfNecessary() { 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->ConnectIfNecessary(); 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Status WebViewImpl::HandleReceivedEvents() { 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return client_->HandleReceivedEvents(); 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::Load(const std::string& url) { 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Javascript URLs will cause a hang while waiting for the page to stop 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // loading, so just disallow. 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (StartsWithASCII(url, "javascript:", false)) 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Status(kUnknownError, "unsupported protocol"); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("url", url); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->SendCommand("Page.navigate", params); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::Reload() { 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetBoolean("ignoreCache", false); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->SendCommand("Page.reload", params); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::EvaluateScript(const std::string& frame, 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = GetContextIdForFrame(frame_tracker_.get(), frame, 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &context_id); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return internal::EvaluateScriptAndGetValue( 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_.get(), context_id, expression, result); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::CallFunction(const std::string& frame, 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& function, 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue& args, 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string json; 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::JSONWriter::Write(&args, &json); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string expression = base::StringPrintf( 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "(%s).apply(null, [%s, %s])", 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kCallFunctionScript, 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function.c_str(), 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) json.c_str()); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> temp_result; 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = EvaluateScript(frame, expression, &temp_result); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return internal::ParseCallFunctionResult(*temp_result, result); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::CallAsyncFunction(const std::string& frame, 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& function, 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue& args, 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::TimeDelta& timeout, 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value>* result) { 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return CallAsyncFunctionInternal( 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame, function, args, false, timeout, result); 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::CallUserAsyncFunction(const std::string& frame, 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& function, 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue& args, 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::TimeDelta& timeout, 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value>* result) { 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return CallAsyncFunctionInternal( 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame, function, args, true, timeout, result); 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::GetFrameByFunction(const std::string& frame, 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& function, 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue& args, 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* out_frame) { 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id; 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = GetContextIdForFrame(frame_tracker_.get(), frame, 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &context_id); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool found_node; 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int node_id; 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status = internal::GetNodeIdFromFunction( 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_.get(), context_id, function, args, &found_node, &node_id); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!found_node) 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kNoSuchFrame); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dom_tracker_->GetFrameIdForNode(node_id, out_frame); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 201ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochStatus WebViewImpl::DispatchMouseEvents(const std::list<MouseEvent>& events, 202ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& frame) { 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::list<MouseEvent>::const_iterator it = events.begin(); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != events.end(); ++it) { 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("type", GetAsString(it->type)); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("x", it->x); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("y", it->y); 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.SetInteger("modifiers", it->modifiers); 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("button", GetAsString(it->button)); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("clickCount", it->click_count); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommand("Input.dispatchMouseEvent", params); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 215ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (build_no_ < 1569 && it->button == kRightMouseButton && 216ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch it->type == kReleasedMouseEventType) { 217ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::ListValue args; 218ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch args.AppendInteger(it->x); 219ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch args.AppendInteger(it->y); 220ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch args.AppendInteger(it->modifiers); 221ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<base::Value> result; 222ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch status = CallFunction( 223ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch frame, kDispatchContextMenuEventScript, args, &result); 224ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (status.IsError()) 225ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return status; 226ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::DispatchKeyEvents(const std::list<KeyEvent>& events) { 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::list<KeyEvent>::const_iterator it = events.begin(); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != events.end(); ++it) { 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("type", GetAsString(it->type)); 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it->modifiers & kNumLockKeyModifierMask) { 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetBoolean("isKeypad", true); 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("modifiers", 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it->modifiers & ~kNumLockKeyModifierMask); 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("modifiers", it->modifiers); 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("text", it->modified_text); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("unmodifiedText", it->unmodified_text); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("nativeVirtualKeyCode", it->key_code); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("windowsVirtualKeyCode", it->key_code); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommand("Input.dispatchKeyEvent", params); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::GetCookies(scoped_ptr<base::ListValue>* cookies) { 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> result; 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommandAndGetResult( 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Page.getCookies", params, &result); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* cookies_tmp; 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result->GetList("cookies", &cookies_tmp)) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "DevTools didn't return cookies"); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cookies->reset(cookies_tmp->DeepCopy()); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::DeleteCookie(const std::string& name, 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& url) { 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("cookieName", name); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("url", url); 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_->SendCommand("Page.deleteCookie", params); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Status WebViewImpl::WaitForPendingNavigations(const std::string& frame_id, 277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int timeout) { 278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) log_->AddEntry(Log::kLog, "waiting for pending navigations..."); 27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Status status = client_->HandleEventsUntil( 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&WebViewImpl::IsNotPendingNavigation, base::Unretained(this), 281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) frame_id), 282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::TimeDelta::FromMilliseconds(timeout)); 283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (status.code() == kTimeout) { 284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) log_->AddEntry(Log::kLog, "timed out. stopping navigations..."); 285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<base::Value> unused_value; 286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EvaluateScript(std::string(), "window.stop();", &unused_value); 287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Status new_status = client_->HandleEventsUntil( 288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&WebViewImpl::IsNotPendingNavigation, base::Unretained(this), 289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) frame_id), 290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::TimeDelta::FromSeconds(10)); 291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (new_status.IsError()) 292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) status = new_status; 293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) log_->AddEntry(Log::kLog, "done waiting for pending navigations"); 29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return status; 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::IsPendingNavigation(const std::string& frame_id, 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* is_pending) { 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return navigation_tracker_->IsPendingNavigation(frame_id, is_pending); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)JavaScriptDialogManager* WebViewImpl::GetJavaScriptDialogManager() { 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dialog_manager_.get(); 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::OverrideGeolocation(const Geoposition& geoposition) { 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return geolocation_override_manager_->OverrideGeolocation(geoposition); 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status WebViewImpl::CaptureScreenshot(std::string* screenshot) { 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> result; 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client_->SendCommandAndGetResult( 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Page.captureScreenshot", params, &result); 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result->GetString("data", screenshot)) 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "expected string 'data' in response"); 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::SetFileInputFiles( 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& frame, 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue& element, 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::vector<base::FilePath>& files) { 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue file_list; 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < files.size(); ++i) { 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!files[i].IsAbsolute()) { 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "path is not absolute: " + files[i].AsUTF8Unsafe()); 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (files[i].ReferencesParent()) { 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "path is not canonical: " + files[i].AsUTF8Unsafe()); 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_list.AppendString(files[i].value()); 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int context_id; 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = GetContextIdForFrame(frame_tracker_.get(), frame, 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &context_id); 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue args; 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args.Append(element.DeepCopy()); 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool found_node; 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int node_id; 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) status = internal::GetNodeIdFromFunction( 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_.get(), context_id, "function(element) { return element; }", 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args, &found_node, &node_id); 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!found_node) 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "no node ID for file input"); 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue params; 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.SetInteger("nodeId", node_id); 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params.Set("files", file_list.DeepCopy()); 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return client_->SendCommand("DOM.setFileInputFiles", params); 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status WebViewImpl::CallAsyncFunctionInternal(const std::string& frame, 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& function, 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue& args, 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_user_supplied, 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::TimeDelta& timeout, 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value>* result) { 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue async_args; 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.AppendString("return (" + function + ").apply(null, arguments);"); 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.Append(args.DeepCopy()); 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.AppendBoolean(is_user_supplied); 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_args.AppendInteger(timeout.InMilliseconds()); 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value> tmp; 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = CallFunction( 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) frame, kExecuteAsyncScriptScript, async_args, &tmp); 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* kDocUnloadError = "document unloaded while waiting for result"; 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string kQueryResult = base::StringPrintf( 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "function() {" 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " var info = document.$chrome_asyncScriptInfo;" 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " if (!info)" 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " return {status: %d, value: '%s'};" 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " var result = info.result;" 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " if (!result)" 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " return {status: 0};" 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " delete info.result;" 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " return result;" 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "}", 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kJavaScriptError, 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kDocUnloadError); 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (true) { 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ListValue no_args; 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value> query_value; 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = CallFunction(frame, kQueryResult, no_args, &query_value); 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) { 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.code() == kNoSuchFrame) 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kJavaScriptError, kDocUnloadError); 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue* result_info = NULL; 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!query_value->GetAsDictionary(&result_info)) 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "async result info is not a dictionary"); 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int status_code; 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!result_info->GetInteger("status", &status_code)) 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "async result info has no int 'status'"); 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status_code != kOk) { 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string message; 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result_info->GetString("value", &message); 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(static_cast<StatusCode>(status_code), message); 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Value* value = NULL; 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (result_info->Get("value", &value)) { 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result->reset(value->DeepCopy()); 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 42690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Status WebViewImpl::IsNotPendingNavigation(const std::string& frame_id, 42790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool* is_not_pending) { 42890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool is_pending; 42990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Status status = 43090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) navigation_tracker_->IsPendingNavigation(frame_id, &is_pending); 43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (status.IsError()) 43290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return status; 43390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // An alert may block the pending navigation. 43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (is_pending && dialog_manager_->IsDialogOpen()) 43590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Status(kUnexpectedAlertOpen); 43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *is_not_pending = !is_pending; 43890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return Status(kOk); 43990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 44090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace internal { 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status EvaluateScript(DevToolsClient* client, 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EvaluateScriptReturnType return_type, 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue>* result) { 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("expression", expression); 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (context_id) 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetInteger("contextId", context_id); 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetBoolean("returnByValue", return_type == ReturnByValue); 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> cmd_result; 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = client->SendCommandAndGetResult( 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Runtime.evaluate", params, &cmd_result); 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool was_thrown; 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cmd_result->GetBoolean("wasThrown", &was_thrown)) 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "Runtime.evaluate missing 'wasThrown'"); 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (was_thrown) { 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string description = "unknown"; 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cmd_result->GetString("result.description", &description); 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Runtime.evaluate threw exception: " + description); 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* unscoped_result; 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cmd_result->GetDictionary("result", &unscoped_result)) 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "evaluate missing dictionary 'result'"); 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(unscoped_result->DeepCopy()); 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status EvaluateScriptAndGetObject(DevToolsClient* client, 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool* got_object, 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string* object_id) { 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> result; 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = EvaluateScript(client, context_id, expression, ReturnByObject, 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &result); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!result->HasKey("objectId")) { 487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *got_object = false; 488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result->GetString("objectId", object_id)) 491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "evaluate has invalid 'objectId'"); 492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *got_object = true; 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status EvaluateScriptAndGetValue(DevToolsClient* client, 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& expression, 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> temp_result; 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = EvaluateScript(client, context_id, expression, ReturnByValue, 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &temp_result); 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string type; 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!temp_result->GetString("type", &type)) 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "Runtime.evaluate missing string 'type'"); 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (type == "undefined") { 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(base::Value::CreateNullValue()); 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value* value; 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!temp_result->Get("value", &value)) 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "Runtime.evaluate missing 'value'"); 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(value->DeepCopy()); 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ParseCallFunctionResult(const base::Value& temp_result, 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* result) { 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue* dict; 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!temp_result.GetAsDictionary(&dict)) 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "call function result must be a dictionary"); 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int status_code; 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dict->GetInteger("status", &status_code)) { 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "call function result missing int 'status'"); 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status_code != kOk) { 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string message; 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict->GetString("value", &message); 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(static_cast<StatusCode>(status_code), message); 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Value* unscoped_value; 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dict->Get("value", &unscoped_value)) { 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "call function result missing 'value'"); 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->reset(unscoped_value->DeepCopy()); 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status GetNodeIdFromFunction(DevToolsClient* client, 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int context_id, 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& function, 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue& args, 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool* found_node, 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* node_id) { 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string json; 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::JSONWriter::Write(&args, &json); 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string expression = base::StringPrintf( 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "(%s).apply(null, [%s, %s, true])", 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kCallFunctionScript, 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function.c_str(), 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) json.c_str()); 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool got_object; 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string element_id; 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = internal::EvaluateScriptAndGetObject( 562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client, context_id, expression, &got_object, &element_id); 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!got_object) { 566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *found_node = false; 567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> cmd_result; 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("objectId", element_id); 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status = client->SendCommandAndGetResult( 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "DOM.requestNode", params, &cmd_result); 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Release the remote object before doing anything else. 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue params; 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.SetString("objectId", element_id); 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status release_status = 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client->SendCommand("Runtime.releaseObject", params); 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (release_status.IsError()) { 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Failed to release remote object: " 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << release_status.message(); 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cmd_result->GetInteger("nodeId", node_id)) 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "DOM.requestNode missing int 'nodeId'"); 593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *found_node = true; 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace internal 598