diff options
author | Kristian Monsen <kristianm@google.com> | 2010-10-27 13:27:14 +0100 |
---|---|---|
committer | Kristian Monsen <kristianm@google.com> | 2010-10-27 13:27:14 +0100 |
commit | bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293 (patch) | |
tree | e6c803134a90c4535df4b3d8d1c1d8f03405e462 /chrome/browser/renderer_host | |
parent | 026dcf071380a81f0213473bab11c7db9f367bce (diff) | |
download | external_chromium-bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293.zip external_chromium-bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293.tar.gz external_chromium-bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293.tar.bz2 |
Adding missing files to chrome/browser
These are not used, but added to easier sync with chromium
Change-Id: I54e6f2f49677e29736fd502758a438b2e3d685d8
Diffstat (limited to 'chrome/browser/renderer_host')
7 files changed, 615 insertions, 0 deletions
diff --git a/chrome/browser/renderer_host/blob_dispatcher_host.cc b/chrome/browser/renderer_host/blob_dispatcher_host.cc new file mode 100644 index 0000000..8fdafe5 --- /dev/null +++ b/chrome/browser/renderer_host/blob_dispatcher_host.cc @@ -0,0 +1,88 @@ +// Copyright (c) 2010 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 "chrome/browser/renderer_host/blob_dispatcher_host.h" + +#include "chrome/browser/child_process_security_policy.h" +#include "chrome/browser/chrome_blob_storage_context.h" +#include "chrome/browser/chrome_thread.h" +#include "chrome/common/render_messages.h" +#include "googleurl/src/gurl.h" +#include "ipc/ipc_message.h" +#include "webkit/blob/blob_data.h" +#include "webkit/blob/blob_storage_controller.h" + +BlobDispatcherHost::BlobDispatcherHost( + int process_id, + ChromeBlobStorageContext* blob_storage_context) + : process_id_(process_id), + blob_storage_context_(blob_storage_context) { +} + +BlobDispatcherHost::~BlobDispatcherHost() { +} + +void BlobDispatcherHost::Shutdown() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + + // Unregister all the blob URLs that are previously registered in this + // process. + for (base::hash_set<std::string>::const_iterator iter = blob_urls_.begin(); + iter != blob_urls_.end(); ++iter) { + blob_storage_context_->controller()->UnregisterBlobUrl(GURL(*iter)); + } +} + +bool BlobDispatcherHost::OnMessageReceived(const IPC::Message& message, + bool* msg_is_ok) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + + *msg_is_ok = true; + bool handled = true; + IPC_BEGIN_MESSAGE_MAP_EX(BlobDispatcherHost, message, *msg_is_ok) + IPC_MESSAGE_HANDLER(ViewHostMsg_RegisterBlobUrl, OnRegisterBlobUrl) + IPC_MESSAGE_HANDLER(ViewHostMsg_RegisterBlobUrlFrom, OnRegisterBlobUrlFrom) + IPC_MESSAGE_HANDLER(ViewHostMsg_UnregisterBlobUrl, OnUnregisterBlobUrl) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +// Check if the child process has been granted permission to register the files. +bool BlobDispatcherHost::CheckPermission( + webkit_blob::BlobData* blob_data) const { + ChildProcessSecurityPolicy* policy = + ChildProcessSecurityPolicy::GetInstance(); + for (std::vector<webkit_blob::BlobData::Item>::const_iterator iter = + blob_data->items().begin(); + iter != blob_data->items().end(); ++iter) { + if (iter->type() == webkit_blob::BlobData::TYPE_FILE) { + if (!policy->CanReadFile(process_id_, iter->file_path())) + return false; + } + } + return true; +} + +void BlobDispatcherHost::OnRegisterBlobUrl( + const GURL& url, const scoped_refptr<webkit_blob::BlobData>& blob_data) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + if (!CheckPermission(blob_data.get())) + return; + blob_storage_context_->controller()->RegisterBlobUrl(url, blob_data); + blob_urls_.insert(url.spec()); +} + +void BlobDispatcherHost::OnRegisterBlobUrlFrom( + const GURL& url, const GURL& src_url) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + blob_storage_context_->controller()->RegisterBlobUrlFrom(url, src_url); + blob_urls_.insert(src_url.spec()); +} + +void BlobDispatcherHost::OnUnregisterBlobUrl(const GURL& url) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + blob_storage_context_->controller()->UnregisterBlobUrl(url); + blob_urls_.erase(url.spec()); +} diff --git a/chrome/browser/renderer_host/blob_dispatcher_host.h b/chrome/browser/renderer_host/blob_dispatcher_host.h new file mode 100644 index 0000000..8ba95ff --- /dev/null +++ b/chrome/browser/renderer_host/blob_dispatcher_host.h @@ -0,0 +1,49 @@ +// Copyright (c) 2010 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. + +#ifndef CHROME_BROWSER_RENDERER_HOST_BLOB_DISPATCHER_HOST_H_ +#define CHROME_BROWSER_RENDERER_HOST_BLOB_DISPATCHER_HOST_H_ + +#include "base/hash_tables.h" +#include "base/ref_counted.h" + +class ChromeBlobStorageContext; +class GURL; + +namespace IPC { +class Message; +} + +namespace webkit_blob { +class BlobData; +} + +class BlobDispatcherHost { + public: + BlobDispatcherHost(int process_id, + ChromeBlobStorageContext* blob_storage_context); + ~BlobDispatcherHost(); + + void Shutdown(); + bool OnMessageReceived(const IPC::Message& message, bool* msg_is_ok); + + private: + void OnRegisterBlobUrl(const GURL& url, + const scoped_refptr<webkit_blob::BlobData>& blob_data); + void OnRegisterBlobUrlFrom(const GURL& url, const GURL& src_url); + void OnUnregisterBlobUrl(const GURL& url); + + bool CheckPermission(webkit_blob::BlobData* blob_data) const; + + int process_id_; + scoped_refptr<ChromeBlobStorageContext> blob_storage_context_; + + // Keep track of blob URLs registered in this process. Need to unregister + // all of them when the renderer process dies. + base::hash_set<std::string> blob_urls_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(BlobDispatcherHost); +}; + +#endif // CHROME_BROWSER_RENDERER_HOST_BLOB_DISPATCHER_HOST_H_ diff --git a/chrome/browser/renderer_host/redirect_to_file_resource_handler.cc b/chrome/browser/renderer_host/redirect_to_file_resource_handler.cc new file mode 100644 index 0000000..94a5c77 --- /dev/null +++ b/chrome/browser/renderer_host/redirect_to_file_resource_handler.cc @@ -0,0 +1,222 @@ +// Copyright (c) 2010 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 "chrome/browser/renderer_host/redirect_to_file_resource_handler.h" + +#include "base/file_util.h" +#include "base/file_util_proxy.h" +#include "base/logging.h" +#include "base/platform_file.h" +#include "base/task.h" +#include "chrome/browser/child_process_security_policy.h" +#include "chrome/browser/renderer_host/resource_dispatcher_host.h" +#include "chrome/common/resource_response.h" +#include "net/base/file_stream.h" +#include "net/base/io_buffer.h" +#include "net/base/mime_sniffer.h" +#include "net/base/net_errors.h" +#include "webkit/blob/deletable_file_reference.h" + +using webkit_blob::DeletableFileReference; + +// TODO(darin): Use the buffer sizing algorithm from AsyncResourceHandler. +static const int kReadBufSize = 32768; + +RedirectToFileResourceHandler::RedirectToFileResourceHandler( + ResourceHandler* next_handler, + int process_id, + ResourceDispatcherHost* host) + : callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), + host_(host), + next_handler_(next_handler), + process_id_(process_id), + request_id_(-1), + buf_(new net::GrowableIOBuffer()), + buf_write_pending_(false), + write_cursor_(0), + write_callback_(ALLOW_THIS_IN_INITIALIZER_LIST(this), + &RedirectToFileResourceHandler::DidWriteToFile), + write_callback_pending_(false) { +} + +bool RedirectToFileResourceHandler::OnUploadProgress(int request_id, + uint64 position, + uint64 size) { + return next_handler_->OnUploadProgress(request_id, position, size); +} + +bool RedirectToFileResourceHandler::OnRequestRedirected( + int request_id, + const GURL& new_url, + ResourceResponse* response, + bool* defer) { + return next_handler_->OnRequestRedirected(request_id, new_url, response, + defer); +} + +bool RedirectToFileResourceHandler::OnResponseStarted( + int request_id, + ResourceResponse* response) { + if (response->response_head.status.is_success()) { + DCHECK(deletable_file_ && !deletable_file_->path().empty()); + response->response_head.download_file_path = deletable_file_->path(); + } + return next_handler_->OnResponseStarted(request_id, response); +} + +bool RedirectToFileResourceHandler::OnWillStart(int request_id, + const GURL& url, + bool* defer) { + request_id_ = request_id; + if (!deletable_file_) { + // Defer starting the request until we have created the temporary file. + // TODO(darin): This is sub-optimal. We should not delay starting the + // network request like this. + *defer = true; + base::FileUtilProxy::CreateTemporary( + ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE), + callback_factory_.NewCallback( + &RedirectToFileResourceHandler::DidCreateTemporaryFile)); + return true; + } + return next_handler_->OnWillStart(request_id, url, defer); +} + +bool RedirectToFileResourceHandler::OnWillRead(int request_id, + net::IOBuffer** buf, + int* buf_size, + int min_size) { + DCHECK(min_size == -1); + + if (!buf_->capacity()) + buf_->SetCapacity(kReadBufSize); + + // We should have paused this network request already if the buffer is full. + DCHECK(!BufIsFull()); + + *buf = buf_; + *buf_size = buf_->RemainingCapacity(); + + buf_write_pending_ = true; + return true; +} + +bool RedirectToFileResourceHandler::OnReadCompleted(int request_id, + int* bytes_read) { + if (!buf_write_pending_) { + // Ignore spurious OnReadCompleted! PauseRequest(true) called from within + // OnReadCompleted tells the ResourceDispatcherHost that we did not consume + // the data. PauseRequest(false) then repeats the last OnReadCompleted + // call. We pause the request so that we can copy our buffer to disk, so + // we need to consume the data now. The ResourceDispatcherHost pause + // mechanism does not fit our use case very well. + // TODO(darin): Fix the ResourceDispatcherHost to avoid this hack! + return true; + } + + buf_write_pending_ = false; + + // We use the buffer's offset field to record the end of the buffer. + + int new_offset = buf_->offset() + *bytes_read; + DCHECK(new_offset <= buf_->capacity()); + buf_->set_offset(new_offset); + + if (BufIsFull()) + host_->PauseRequest(process_id_, request_id, true); + + if (*bytes_read > 0) + next_handler_->OnDataDownloaded(request_id, *bytes_read); + + return WriteMore(); +} + +bool RedirectToFileResourceHandler::OnResponseCompleted( + int request_id, + const URLRequestStatus& status, + const std::string& security_info) { + return next_handler_->OnResponseCompleted(request_id, status, security_info); +} + +void RedirectToFileResourceHandler::OnRequestClosed() { + // We require this explicit call to Close since file_stream_ was constructed + // directly from a PlatformFile. + file_stream_->Close(); + file_stream_.reset(); + deletable_file_ = NULL; + + next_handler_->OnRequestClosed(); +} + +RedirectToFileResourceHandler::~RedirectToFileResourceHandler() { + DCHECK(!file_stream_.get()); +} + +void RedirectToFileResourceHandler::DidCreateTemporaryFile( + base::PlatformFileError /*error_code*/, + base::PassPlatformFile file_handle, + FilePath file_path) { + deletable_file_ = DeletableFileReference::GetOrCreate( + file_path, + ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE)); + file_stream_.reset(new net::FileStream(file_handle.ReleaseValue(), + base::PLATFORM_FILE_WRITE | + base::PLATFORM_FILE_ASYNC)); + host_->RegisterDownloadedTempFile( + process_id_, request_id_, deletable_file_.get()); + host_->StartDeferredRequest(process_id_, request_id_); +} + +void RedirectToFileResourceHandler::DidWriteToFile(int result) { + write_callback_pending_ = false; + + bool failed = false; + if (result > 0) { + write_cursor_ += result; + failed = !WriteMore(); + } else { + failed = true; + } + + if (failed) + host_->CancelRequest(process_id_, request_id_, false); +} + +bool RedirectToFileResourceHandler::WriteMore() { + DCHECK(file_stream_.get()); + for (;;) { + if (write_cursor_ == buf_->offset()) { + // We've caught up to the network load, but it may be in the process of + // appending more data to the buffer. + if (!buf_write_pending_) { + if (BufIsFull()) + host_->PauseRequest(process_id_, request_id_, false); + buf_->set_offset(0); + write_cursor_ = 0; + } + return true; + } + if (write_callback_pending_) + return true; + DCHECK(write_cursor_ < buf_->offset()); + int rv = file_stream_->Write(buf_->StartOfBuffer() + write_cursor_, + buf_->offset() - write_cursor_, + &write_callback_); + if (rv == net::ERR_IO_PENDING) { + write_callback_pending_ = true; + return true; + } + if (rv < 0) + return false; + write_cursor_ += rv; + } +} + +bool RedirectToFileResourceHandler::BufIsFull() const { + // This is a hack to workaround BufferedResourceHandler's inability to + // deal with a ResourceHandler that returns a buffer size of less than + // 2 * net::kMaxBytesToSniff from its OnWillRead method. + // TODO(darin): Fix this retardation! + return buf_->RemainingCapacity() <= (2 * net::kMaxBytesToSniff); +} diff --git a/chrome/browser/renderer_host/redirect_to_file_resource_handler.h b/chrome/browser/renderer_host/redirect_to_file_resource_handler.h new file mode 100644 index 0000000..4929711 --- /dev/null +++ b/chrome/browser/renderer_host/redirect_to_file_resource_handler.h @@ -0,0 +1,89 @@ +// Copyright (c) 2006-2008 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. + +#ifndef CHROME_BROWSER_RENDERER_HOST_REDIRECT_TO_FILE_RESOURCE_HANDLER_H_ +#define CHROME_BROWSER_RENDERER_HOST_REDIRECT_TO_FILE_RESOURCE_HANDLER_H_ + +#include "base/file_path.h" +#include "base/platform_file.h" +#include "base/ref_counted.h" +#include "base/scoped_callback_factory.h" +#include "base/scoped_ptr.h" +#include "chrome/browser/renderer_host/resource_handler.h" +#include "net/base/completion_callback.h" + +class RefCountedPlatformFile; +class ResourceDispatcherHost; + +namespace net { +class FileStream; +class GrowableIOBuffer; +} + +namespace webkit_blob { +class DeletableFileReference; +} + +// Redirects network data to a file. This is intended to be layered in front +// of either the AsyncResourceHandler or the SyncResourceHandler. +class RedirectToFileResourceHandler : public ResourceHandler { + public: + RedirectToFileResourceHandler( + ResourceHandler* next_handler, + int process_id, + ResourceDispatcherHost* resource_dispatcher_host); + + // ResourceHandler implementation: + bool OnUploadProgress(int request_id, uint64 position, uint64 size); + bool OnRequestRedirected(int request_id, const GURL& new_url, + ResourceResponse* response, bool* defer); + bool OnResponseStarted(int request_id, ResourceResponse* response); + bool OnWillStart(int request_id, const GURL& url, bool* defer); + bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, + int min_size); + bool OnReadCompleted(int request_id, int* bytes_read); + bool OnResponseCompleted(int request_id, + const URLRequestStatus& status, + const std::string& security_info); + void OnRequestClosed(); + + private: + virtual ~RedirectToFileResourceHandler(); + void DidCreateTemporaryFile(base::PlatformFileError error_code, + base::PassPlatformFile file_handle, + FilePath file_path); + void DidWriteToFile(int result); + bool WriteMore(); + bool BufIsFull() const; + + base::ScopedCallbackFactory<RedirectToFileResourceHandler> callback_factory_; + + ResourceDispatcherHost* host_; + scoped_refptr<ResourceHandler> next_handler_; + int process_id_; + int request_id_; + + // We allocate a single, fixed-size IO buffer (buf_) used to read from the + // network (buf_write_pending_ is true while the system is copying data into + // buf_), and then write this buffer out to disk (write_callback_pending_ is + // true while writing to disk). Reading from the network is suspended while + // the buffer is full (BufIsFull returns true). The write_cursor_ member + // tracks the offset into buf_ that we are writing to disk. + + scoped_refptr<net::GrowableIOBuffer> buf_; + bool buf_write_pending_; + int write_cursor_; + + scoped_ptr<net::FileStream> file_stream_; + net::CompletionCallbackImpl<RedirectToFileResourceHandler> write_callback_; + bool write_callback_pending_; + + // We create a DeletableFileReference for the temp file created as + // a result of the download. + scoped_refptr<webkit_blob::DeletableFileReference> deletable_file_; + + DISALLOW_COPY_AND_ASSIGN(RedirectToFileResourceHandler); +}; + +#endif // CHROME_BROWSER_RENDERER_HOST_REDIRECT_TO_FILE_RESOURCE_HANDLER_H_ diff --git a/chrome/browser/renderer_host/render_widget_fullscreen_host.cc b/chrome/browser/renderer_host/render_widget_fullscreen_host.cc new file mode 100644 index 0000000..c3ee786 --- /dev/null +++ b/chrome/browser/renderer_host/render_widget_fullscreen_host.cc @@ -0,0 +1,10 @@ +// Copyright (c) 2010 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 "chrome/browser/renderer_host/render_widget_fullscreen_host.h" + +RenderWidgetFullscreenHost::RenderWidgetFullscreenHost( + RenderProcessHost* process, int routing_id) + : RenderWidgetHost(process, routing_id) { +} diff --git a/chrome/browser/renderer_host/render_widget_fullscreen_host.h b/chrome/browser/renderer_host/render_widget_fullscreen_host.h new file mode 100644 index 0000000..1906b4b --- /dev/null +++ b/chrome/browser/renderer_host/render_widget_fullscreen_host.h @@ -0,0 +1,15 @@ +// Copyright (c) 2010 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. + +#ifndef CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_FULLSCREEN_HOST_H_ +#define CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_FULLSCREEN_HOST_H_ + +#include "chrome/browser/renderer_host/render_widget_host.h" + +class RenderWidgetFullscreenHost : public RenderWidgetHost { + public: + RenderWidgetFullscreenHost(RenderProcessHost* process, int routing_id); +}; + +#endif // CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_FULLSCREEN_HOST_H_ diff --git a/chrome/browser/renderer_host/test/renderer_accessibility_browsertest.cc b/chrome/browser/renderer_host/test/renderer_accessibility_browsertest.cc new file mode 100644 index 0000000..b12c6a7 --- /dev/null +++ b/chrome/browser/renderer_host/test/renderer_accessibility_browsertest.cc @@ -0,0 +1,142 @@ +// Copyright (c) 2010 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 <string> +#include <vector> + +#include "base/utf_string_conversions.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/browser_window.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/renderer_host/render_widget_host.h" +#include "chrome/browser/renderer_host/render_widget_host_view.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/common/render_messages.h" +#include "chrome/common/notification_type.h" +#include "chrome/test/in_process_browser_test.h" +#include "chrome/test/ui_test_utils.h" + +#if defined(OS_WIN) +#include <atlbase.h> +#include <atlcom.h> +#endif + +using webkit_glue::WebAccessibility; + +namespace { + +class RendererAccessibilityBrowserTest : public InProcessBrowserTest { + public: + RendererAccessibilityBrowserTest() {} + + // InProcessBrowserTest + void SetUpInProcessBrowserTestFixture(); + void TearDownInProcessBrowserTestFixture(); + + protected: + std::string GetAttr(const WebAccessibility& node, + const WebAccessibility::Attribute attr); +}; + +void RendererAccessibilityBrowserTest::SetUpInProcessBrowserTestFixture() { +#if defined(OS_WIN) + // ATL needs a pointer to a COM module. + static CComModule module; + _pAtlModule = &module; + + // Make sure COM is initialized for this thread; it's safe to call twice. + ::CoInitialize(NULL); +#endif +} + +void RendererAccessibilityBrowserTest::TearDownInProcessBrowserTestFixture() { +#if defined(OS_WIN) + ::CoUninitialize(); +#endif +} +// Convenience method to get the value of a particular WebAccessibility +// node attribute as a UTF-8 const char*. +std::string RendererAccessibilityBrowserTest::GetAttr( + const WebAccessibility& node, const WebAccessibility::Attribute attr) { + std::map<int32, string16>::const_iterator iter = node.attributes.find(attr); + if (iter != node.attributes.end()) + return UTF16ToUTF8(iter->second); + else + return ""; +} + +IN_PROC_BROWSER_TEST_F(RendererAccessibilityBrowserTest, + TestCrossPlatformAccessibilityTree) { + // Create a data url and load it. + const char url_str[] = + "data:text/html," + "<!doctype html>" + "<html><head><title>Accessibility Test</title></head>" + "<body><input type='button' value='push' /><input type='checkbox' />" + "</body></html>"; + GURL url(url_str); + browser()->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED); + + // Tell the renderer to send an accessibility tree, then wait for the + // notification that it's been received. + RenderWidgetHostView* host_view = + browser()->GetSelectedTabContents()->GetRenderWidgetHostView(); + RenderWidgetHost* host = host_view->GetRenderWidgetHost(); + RenderViewHost* view_host = static_cast<RenderViewHost*>(host); + view_host->set_save_accessibility_tree_for_testing(true); + view_host->EnableRendererAccessibility(); + ui_test_utils::WaitForNotification( + NotificationType::RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED); + + // Check properties of the root element of the tree. + const WebAccessibility& tree = view_host->accessibility_tree(); + EXPECT_STREQ(url_str, GetAttr(tree, WebAccessibility::ATTR_DOC_URL).c_str()); + EXPECT_STREQ( + "Accessibility Test", + GetAttr(tree, WebAccessibility::ATTR_DOC_TITLE).c_str()); + EXPECT_STREQ( + "html", GetAttr(tree, WebAccessibility::ATTR_DOC_DOCTYPE).c_str()); + EXPECT_STREQ( + "text/html", GetAttr(tree, WebAccessibility::ATTR_DOC_MIMETYPE).c_str()); + EXPECT_STREQ("Accessibility Test", UTF16ToUTF8(tree.name).c_str()); + EXPECT_EQ(WebAccessibility::ROLE_WEB_AREA, tree.role); + + // Check properites of the BODY element. + ASSERT_EQ(1U, tree.children.size()); + const WebAccessibility& body = tree.children[0]; + EXPECT_EQ(WebAccessibility::ROLE_GROUP, body.role); + EXPECT_STREQ("body", GetAttr(body, WebAccessibility::ATTR_HTML_TAG).c_str()); + EXPECT_STREQ("block", GetAttr(body, WebAccessibility::ATTR_DISPLAY).c_str()); + + // Check properties of the two children of the BODY element. + ASSERT_EQ(2U, body.children.size()); + + const WebAccessibility& button = body.children[0]; + EXPECT_EQ(WebAccessibility::ROLE_BUTTON, button.role); + EXPECT_STREQ( + "input", GetAttr(button, WebAccessibility::ATTR_HTML_TAG).c_str()); + EXPECT_STREQ("push", UTF16ToUTF8(button.name).c_str()); + EXPECT_STREQ( + "inline-block", GetAttr(button, WebAccessibility::ATTR_DISPLAY).c_str()); + ASSERT_EQ(2U, button.html_attributes.size()); + EXPECT_STREQ("type", UTF16ToUTF8(button.html_attributes[0].first).c_str()); + EXPECT_STREQ("button", UTF16ToUTF8(button.html_attributes[0].second).c_str()); + EXPECT_STREQ("value", UTF16ToUTF8(button.html_attributes[1].first).c_str()); + EXPECT_STREQ("push", UTF16ToUTF8(button.html_attributes[1].second).c_str()); + + const WebAccessibility& checkbox = body.children[1]; + EXPECT_EQ(WebAccessibility::ROLE_CHECKBOX, checkbox.role); + EXPECT_STREQ( + "input", GetAttr(checkbox, WebAccessibility::ATTR_HTML_TAG).c_str()); + EXPECT_STREQ( + "inline-block", + GetAttr(checkbox, WebAccessibility::ATTR_DISPLAY).c_str()); + ASSERT_EQ(1U, checkbox.html_attributes.size()); + EXPECT_STREQ( + "type", UTF16ToUTF8(checkbox.html_attributes[0].first).c_str()); + EXPECT_STREQ( + "checkbox", UTF16ToUTF8(checkbox.html_attributes[0].second).c_str()); +} + +} // namespace |