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

Unified 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, 2 months 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 side-by-side diff with in-line comments
Download patch
Index: headless/app/headless_browser_main.cc
diff --git a/headless/app/headless_browser_main.cc b/headless/app/headless_browser_main.cc
new file mode 100644
index 0000000000000000000000000000000000000000..209d1735cd86d5d15d37e13e50a6aab6d185a01e
--- /dev/null
+++ b/headless/app/headless_browser_main.cc
@@ -0,0 +1,191 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "headless/app/headless_browser_main.h"
+
+#include "base/thread_task_runner_handle.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/browser_main_runner.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/renderer/render_frame.h"
+#include "content/shell/browser/shell.h"
+#include "content/shell/browser/shell_browser_context.h"
+#include "content/shell/browser/shell_content_browser_client.h"
+#include "url/gurl.h"
+
+#include "base/json/json_writer.h"
+
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
+#include "third_party/WebKit/public/web/WebNodeList.h"
+#include "third_party/WebKit/public/web/WebDocument.h"
+#include "base/threading/thread.h"
+#include "content/public/browser/browser_thread.h"
+#include "third_party/WebKit/public/platform/WebThread.h"
+#include "third_party/WebKit/public/platform/Platform.h"
+#include "third_party/WebKit/public/platform/WebTraceLocation.h"
+#include "third_party/WebKit/public/platform/WebTaskRunner.h"
+#include "third_party/WebKit/public/web/WebElement.h"
+#include "base/command_line.h"
+
+#include <iostream>
+#include <fstream>
+
+class Task : public blink::WebTaskRunner::Task {
+ public:
+ Task(std::function<void(void)> function_to_run): function_to_run_(function_to_run) { };
+ ~Task() { };
+
+ void run() override {
+ function_to_run_();
+ }
+ private:
+ std::function<void(void)> function_to_run_;
+};
+
+class Observer : public content::WebContentsObserver {
+ public:
+ Observer(content::WebContents* web_contents)
+ : WebContentsObserver(web_contents),
+ web_contents_(web_contents)
+ {
+ };
+
+ void DidStopLoading() override {
+ DumpDOMTree();
+ }
+
+ void DumpDOMTree() {
+ content::RenderFrame* render_frame =
+ content::RenderFrame::FromRoutingID(web_contents_->GetMainFrame()->GetRoutingID());
+ blink::WebFrame* web_frame = render_frame->GetWebFrame();
+
+ blink::Platform::current()->mainThread()->taskRunner()->postTask(BLINK_FROM_HERE,
+ new Task([this, web_frame]() {
+ auto dumped_tree = DumpNode(web_frame->document());
+
+ std::string dumped_string;
+ base::JSONWriter::WriteWithOptions(
+ *dumped_tree,
+ base::JSONWriter::OPTIONS_PRETTY_PRINT,
+ &dumped_string);
+
+ std::cerr << dumped_string << std::endl;
+
+ shutDownGraciously();
+ }));
+ }
+
+ static std::string NodeType(const blink::WebNode& node) {
+ if (node.isLink()) {
+ return "link";
+ } else if (node.isDocumentNode()) {
+ return "document";
+ } else if (node.isCommentNode()) {
+ return "comment";
+ } else if (node.isTextNode()) {
+ return "text";
+ } else if (node.isElementNode()) {
+ return "element";
+ } else {
+ return "unknown";
+ }
+ }
+
+ static void DumpElementNode(const blink::WebElement& element, base::DictionaryValue* output) {
+ output->SetString("tag", element.tagName());
+
+ output->Set("attributes", new base::DictionaryValue());
+ base::DictionaryValue* attributes;
+ output->GetDictionary("attributes", &attributes);
+
+ for (size_t i = 0; i < element.attributeCount(); ++i) {
+ attributes->SetString(
+ element.attributeLocalName(i).utf8(),
+ element.attributeValue(i).utf8());
+ }
+ }
+
+ void DumpBoundingBox(const blink::WebNode& node, base::DictionaryValue* output) {
+ output->Set("bounding_box", new base::DictionaryValue());
+ base::DictionaryValue* bounding_box;
+ output->GetDictionary("bounding_box", &bounding_box);
+
+ bounding_box->SetInteger("minX", node.boundingBox().minX);
+ bounding_box->SetInteger("maxX", node.boundingBox().maxX);
+ bounding_box->SetInteger("minY", node.boundingBox().minY);
+ bounding_box->SetInteger("maxY", node.boundingBox().maxY);
+ }
+
+ scoped_ptr<base::DictionaryValue> DumpNode(const blink::WebNode& node) {
+ scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
+ value->SetString("type", NodeType(node));
+ value->SetString("name", node.nodeName());
+ value->SetString("value", node.nodeValue());
+
+ DumpBoundingBox(node, value.get());
+
+ if (node.isElementNode()) {
+ DumpElementNode(static_cast<const blink::WebElement&>(node), value.get());
+ }
+
+ if (node.hasChildNodes()) {
+ value->Set("children", new base::ListValue());
+
+ base::ListValue* children;
+ value->GetList("children", &children);
+
+ for (size_t i = 0; i < node.childNodes().length(); ++i) {
+ children->Append(DumpNode(node.childNodes().item(i)));
+ }
+ }
+
+ return value;
+ }
+
+
+ void shutDownGraciously() {
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
+ }
+ private:
+ content::WebContents* web_contents_;
+};
+
+int HeadlessBrowserMain(
+ const content::MainFunctionParams& parameters,
+ const scoped_ptr<content::BrowserMainRunner>& main_runner) {
+ int exit_code = main_runner->Initialize(parameters);
+
+ DCHECK_LT(exit_code, 0)
+ << "BrowserMainRunner::Initialize failed in HeadlessBrowserMain";
+
+ if (exit_code >= 0)
+ return exit_code;
+
+ content::Shell* main_window = content::Shell::CreateNewWindow(
+ content::ShellContentBrowserClient::Get()->browser_context(),
+ GURL(),
+ NULL,
+ gfx::Size(700, 700));
+
+ base::CommandLine::StringVector args =
+ base::CommandLine::ForCurrentProcess()->GetArgs();
+ if (args.empty()) {
+ std::cerr << "Provide url to open" << std::endl;
+ return 666;
+ }
+ GURL url(args[0]);
+
+ Observer observer(main_window->web_contents());
+
+ main_window->LoadURL(url);
+
+ main_runner->Run();
+
+ main_runner->Shutdown();
+
+ return exit_code;
+}
+
+

Powered by Google App Engine
This is Rietveld 408576698