Index: mojo/examples/html_viewer/html_document_view.cc |
diff --git a/mojo/examples/html_viewer/html_document_view.cc b/mojo/examples/html_viewer/html_document_view.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..868230c2d26dbd229f2dc2863e67b26c858903da |
--- /dev/null |
+++ b/mojo/examples/html_viewer/html_document_view.cc |
@@ -0,0 +1,140 @@ |
+// Copyright 2014 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 "mojo/examples/html_viewer/html_document_view.h" |
+ |
+#include "base/bind.h" |
+#include "base/location.h" |
+#include "base/single_thread_task_runner.h" |
+#include "base/thread_task_runner_handle.h" |
+#include "mojo/services/public/cpp/view_manager/node.h" |
+#include "mojo/services/public/cpp/view_manager/view.h" |
+#include "skia/ext/refptr.h" |
+#include "third_party/WebKit/public/web/WebConsoleMessage.h" |
+#include "third_party/WebKit/public/web/WebDocument.h" |
+#include "third_party/WebKit/public/web/WebElement.h" |
+#include "third_party/WebKit/public/web/WebLocalFrame.h" |
+#include "third_party/WebKit/public/web/WebScriptSource.h" |
+#include "third_party/WebKit/public/web/WebSettings.h" |
+#include "third_party/WebKit/public/web/WebView.h" |
+#include "third_party/skia/include/core/SkCanvas.h" |
+#include "third_party/skia/include/core/SkColor.h" |
+#include "third_party/skia/include/core/SkDevice.h" |
+ |
+namespace mojo { |
+namespace examples { |
+namespace { |
+ |
+blink::WebData CopyToWebData(DataPipeConsumerHandle handle) { |
+ std::vector<char> data; |
+ for (;;) { |
+ char buf[4096]; |
+ uint32_t num_bytes = sizeof(buf); |
+ MojoResult result = ReadDataRaw( |
+ handle, |
+ buf, |
+ &num_bytes, |
+ MOJO_READ_DATA_FLAG_NONE); |
+ if (result == MOJO_RESULT_SHOULD_WAIT) { |
+ Wait(handle, |
+ MOJO_HANDLE_SIGNAL_READABLE, |
+ MOJO_DEADLINE_INDEFINITE); |
+ } else if (result == MOJO_RESULT_OK) { |
+ data.insert(data.end(), buf, buf + num_bytes); |
+ } else { |
+ break; |
+ } |
+ } |
+ return blink::WebData(data); |
+} |
+ |
+void ConfigureSettings(blink::WebSettings* settings) { |
+ settings->setAcceleratedCompositingEnabled(false); |
+ settings->setLoadsImagesAutomatically(true); |
+ settings->setJavaScriptEnabled(true); |
+} |
+ |
+} // namespace |
+ |
+HTMLDocumentView::HTMLDocumentView(view_manager::ViewManager* view_manager) |
+ : view_manager_(view_manager), |
+ view_(view_manager::View::Create(view_manager_)), |
+ web_view_(NULL), |
+ repaint_pending_(false), |
+ weak_factory_(this) { |
+} |
+ |
+HTMLDocumentView::~HTMLDocumentView() { |
+ if (web_view_) |
+ web_view_->close(); |
+} |
+ |
+void HTMLDocumentView::AttachToNode(view_manager::Node* node) { |
+ node->SetActiveView(view_); |
+ view_->SetColor(SK_ColorCYAN); // Dummy background color. |
+ |
+ web_view_ = blink::WebView::create(this); |
+ ConfigureSettings(web_view_->settings()); |
+ web_view_->setMainFrame(blink::WebLocalFrame::create(this)); |
+ |
+ // TODO(darin): Track size of view_manager::Node. |
+ web_view_->resize(gfx::Size(800, 600)); |
+} |
+ |
+void HTMLDocumentView::Load(URLResponsePtr response, |
+ ScopedDataPipeConsumerHandle response_body_stream) { |
+ DCHECK(web_view_); |
+ |
+ // TODO(darin): A better solution would be to use loadRequest, but intercept |
+ // the network request and connect it to the response we already have. |
+ blink::WebData data = CopyToWebData(response_body_stream.get()); |
+ web_view_->mainFrame()->loadHTMLString( |
+ data, GURL(response->url), GURL(response->url)); |
+} |
+ |
+void HTMLDocumentView::didInvalidateRect(const blink::WebRect& rect) { |
+ if (!repaint_pending_) { |
+ repaint_pending_ = true; |
+ base::ThreadTaskRunnerHandle::Get()->PostTask( |
+ FROM_HERE, |
+ base::Bind(&HTMLDocumentView::Repaint, weak_factory_.GetWeakPtr())); |
+ } |
+} |
+ |
+bool HTMLDocumentView::allowsBrokenNullLayerTreeView() const { |
+ // TODO(darin): Switch to using compositor bindings. |
+ // |
+ // NOTE: Note to Blink maintainers, feel free to just break this code if it |
+ // is the last using compositor bindings and you want to delete the old path. |
+ // |
+ return true; |
+} |
+ |
+void HTMLDocumentView::didAddMessageToConsole( |
+ const blink::WebConsoleMessage& message, |
+ const blink::WebString& source_name, |
+ unsigned source_line, |
+ const blink::WebString& stack_trace) { |
+ printf("### console: %s\n", std::string(message.text.utf8()).c_str()); |
+} |
+ |
+void HTMLDocumentView::Repaint() { |
+ repaint_pending_ = false; |
+ |
+ web_view_->animate(0.0); |
+ web_view_->layout(); |
+ |
+ int width = web_view_->size().width; |
+ int height = web_view_->size().height; |
+ |
+ skia::RefPtr<SkCanvas> canvas = skia::AdoptRef(SkCanvas::NewRaster( |
+ SkImageInfo::MakeN32(width, height, kOpaque_SkAlphaType))); |
+ |
+ web_view_->paint(canvas.get(), gfx::Rect(0, 0, width, height)); |
+ |
+ view_->SetContents(canvas->getDevice()->accessBitmap(false)); |
+} |
+ |
+} // namespace examples |
+} // namespace mojo |