Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: headless/app/headless_browser_main.cc

Issue 1430673002: Headless demo (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 "headless/app/headless_browser_main.h"
6
7 #include "base/thread_task_runner_handle.h"
8 #include "content/public/browser/render_frame_host.h"
9 #include "content/public/browser/browser_main_runner.h"
10 #include "content/public/browser/web_contents.h"
11 #include "content/public/renderer/render_frame.h"
12 #include "content/shell/browser/shell.h"
13 #include "content/shell/browser/shell_browser_context.h"
14 #include "content/shell/browser/shell_content_browser_client.h"
15 #include "url/gurl.h"
16
17 #include "base/json/json_writer.h"
18
19 #include "third_party/WebKit/public/web/WebLocalFrame.h"
20 #include "third_party/WebKit/public/web/WebNodeList.h"
21 #include "third_party/WebKit/public/web/WebDocument.h"
22 #include "base/threading/thread.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "third_party/WebKit/public/platform/WebThread.h"
25 #include "third_party/WebKit/public/platform/Platform.h"
26 #include "third_party/WebKit/public/platform/WebTraceLocation.h"
27 #include "third_party/WebKit/public/platform/WebTaskRunner.h"
28 #include "third_party/WebKit/public/web/WebElement.h"
29 #include "base/command_line.h"
30
31 #include <iostream>
32 #include <fstream>
33
34 class Task : public blink::WebTaskRunner::Task {
35 public:
36 Task(std::function<void(void)> function_to_run): function_to_run_(function_t o_run) { };
37 ~Task() { };
38
39 void run() override {
40 function_to_run_();
41 }
42 private:
43 std::function<void(void)> function_to_run_;
44 };
45
46 class Observer : public content::WebContentsObserver {
47 public:
48 Observer(content::WebContents* web_contents)
49 : WebContentsObserver(web_contents),
50 web_contents_(web_contents)
51 {
52 };
53
54 void DidStopLoading() override {
55 DumpDOMTree();
56 }
57
58 void DumpDOMTree() {
59 content::RenderFrame* render_frame =
60 content::RenderFrame::FromRoutingID(web_contents_->GetMainFrame()->Get RoutingID());
61 blink::WebFrame* web_frame = render_frame->GetWebFrame();
62
63 blink::Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FRO M_HERE,
64 new Task([this, web_frame]() {
65 auto dumped_tree = DumpNode(web_frame->document());
66
67 std::string dumped_string;
68 base::JSONWriter::WriteWithOptions(
69 *dumped_tree,
70 base::JSONWriter::OPTIONS_PRETTY_PRINT,
71 &dumped_string);
72
73 std::cerr << dumped_string << std::endl;
74
75 shutDownGraciously();
76 }));
77 }
78
79 static std::string NodeType(const blink::WebNode& node) {
80 if (node.isLink()) {
81 return "link";
82 } else if (node.isDocumentNode()) {
83 return "document";
84 } else if (node.isCommentNode()) {
85 return "comment";
86 } else if (node.isTextNode()) {
87 return "text";
88 } else if (node.isElementNode()) {
89 return "element";
90 } else {
91 return "unknown";
92 }
93 }
94
95 static void DumpElementNode(const blink::WebElement& element, base::Dictiona ryValue* output) {
96 output->SetString("tag", element.tagName());
97
98 output->Set("attributes", new base::DictionaryValue());
99 base::DictionaryValue* attributes;
100 output->GetDictionary("attributes", &attributes);
101
102 for (size_t i = 0; i < element.attributeCount(); ++i) {
103 attributes->SetString(
104 element.attributeLocalName(i).utf8(),
105 element.attributeValue(i).utf8());
106 }
107 }
108
109 void DumpBoundingBox(const blink::WebNode& node, base::DictionaryValue* outp ut) {
110 output->Set("bounding_box", new base::DictionaryValue());
111 base::DictionaryValue* bounding_box;
112 output->GetDictionary("bounding_box", &bounding_box);
113
114 bounding_box->SetInteger("minX", node.boundingBox().minX);
115 bounding_box->SetInteger("maxX", node.boundingBox().maxX);
116 bounding_box->SetInteger("minY", node.boundingBox().minY);
117 bounding_box->SetInteger("maxY", node.boundingBox().maxY);
118 }
119
120 scoped_ptr<base::DictionaryValue> DumpNode(const blink::WebNode& node) {
121 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
122 value->SetString("type", NodeType(node));
123 value->SetString("name", node.nodeName());
124 value->SetString("value", node.nodeValue());
125
126 DumpBoundingBox(node, value.get());
127
128 if (node.isElementNode()) {
129 DumpElementNode(static_cast<const blink::WebElement&>(node), value.get() );
130 }
131
132 if (node.hasChildNodes()) {
133 value->Set("children", new base::ListValue());
134
135 base::ListValue* children;
136 value->GetList("children", &children);
137
138 for (size_t i = 0; i < node.childNodes().length(); ++i) {
139 children->Append(DumpNode(node.childNodes().item(i)));
140 }
141 }
142
143 return value;
144 }
145
146
147 void shutDownGraciously() {
148 content::BrowserThread::PostTask(
149 content::BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitWhenIdle Closure());
150 }
151 private:
152 content::WebContents* web_contents_;
153 };
154
155 int HeadlessBrowserMain(
156 const content::MainFunctionParams& parameters,
157 const scoped_ptr<content::BrowserMainRunner>& main_runner) {
158 int exit_code = main_runner->Initialize(parameters);
159
160 DCHECK_LT(exit_code, 0)
161 << "BrowserMainRunner::Initialize failed in HeadlessBrowserMain";
162
163 if (exit_code >= 0)
164 return exit_code;
165
166 content::Shell* main_window = content::Shell::CreateNewWindow(
167 content::ShellContentBrowserClient::Get()->browser_context(),
168 GURL(),
169 NULL,
170 gfx::Size(700, 700));
171
172 base::CommandLine::StringVector args =
173 base::CommandLine::ForCurrentProcess()->GetArgs();
174 if (args.empty()) {
175 std::cerr << "Provide url to open" << std::endl;
176 return 666;
177 }
178 GURL url(args[0]);
179
180 Observer observer(main_window->web_contents());
181
182 main_window->LoadURL(url);
183
184 main_runner->Run();
185
186 main_runner->Shutdown();
187
188 return exit_code;
189 }
190
191
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698