1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/test/chromedriver/chrome/dom_tracker.h" 6 7#include <utility> 8 9#include "base/json/json_writer.h" 10#include "base/values.h" 11#include "chrome/test/chromedriver/chrome/devtools_client.h" 12#include "chrome/test/chromedriver/chrome/status.h" 13 14DomTracker::DomTracker(DevToolsClient* client) { 15 client->AddListener(this); 16} 17 18DomTracker::~DomTracker() {} 19 20Status DomTracker::GetFrameIdForNode( 21 int node_id, std::string* frame_id) { 22 if (node_to_frame_map_.count(node_id) == 0) 23 return Status(kNoSuchFrame, "element is not a frame"); 24 *frame_id = node_to_frame_map_[node_id]; 25 return Status(kOk); 26} 27 28Status DomTracker::OnConnected(DevToolsClient* client) { 29 node_to_frame_map_.clear(); 30 // Fetch the root document node so that Inspector will push DOM node 31 // information to the client. 32 base::DictionaryValue params; 33 return client->SendCommand("DOM.getDocument", params); 34} 35 36Status DomTracker::OnEvent(DevToolsClient* client, 37 const std::string& method, 38 const base::DictionaryValue& params) { 39 if (method == "DOM.setChildNodes") { 40 const base::Value* nodes; 41 if (!params.Get("nodes", &nodes)) 42 return Status(kUnknownError, "DOM.setChildNodes missing 'nodes'"); 43 44 if (!ProcessNodeList(nodes)) { 45 std::string json; 46 base::JSONWriter::Write(nodes, &json); 47 return Status(kUnknownError, 48 "DOM.setChildNodes has invalid 'nodes': " + json); 49 } 50 } else if (method == "DOM.childNodeInserted") { 51 const base::Value* node; 52 if (!params.Get("node", &node)) 53 return Status(kUnknownError, "DOM.childNodeInserted missing 'node'"); 54 55 if (!ProcessNode(node)) { 56 std::string json; 57 base::JSONWriter::Write(node, &json); 58 return Status(kUnknownError, 59 "DOM.childNodeInserted has invalid 'node': " + json); 60 } 61 } else if (method == "DOM.documentUpdated") { 62 node_to_frame_map_.clear(); 63 base::DictionaryValue params; 64 client->SendCommand("DOM.getDocument", params); 65 } 66 return Status(kOk); 67} 68 69bool DomTracker::ProcessNodeList(const base::Value* nodes) { 70 const base::ListValue* nodes_list; 71 if (!nodes->GetAsList(&nodes_list)) 72 return false; 73 for (size_t i = 0; i < nodes_list->GetSize(); ++i) { 74 const base::Value* node; 75 if (!nodes_list->Get(i, &node)) 76 return false; 77 if (!ProcessNode(node)) 78 return false; 79 } 80 return true; 81} 82 83bool DomTracker::ProcessNode(const base::Value* node) { 84 const base::DictionaryValue* dict; 85 if (!node->GetAsDictionary(&dict)) 86 return false; 87 int node_id; 88 if (!dict->GetInteger("nodeId", &node_id)) 89 return false; 90 std::string frame_id; 91 if (dict->GetString("frameId", &frame_id)) 92 node_to_frame_map_.insert(std::make_pair(node_id, frame_id)); 93 94 const base::Value* children; 95 if (dict->Get("children", &children)) 96 return ProcessNodeList(children); 97 return true; 98} 99