1 // Copyright 2014 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.
6 #include "chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.h"
8 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
9 #include "chrome/browser/favicon/favicon_tab_helper.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
12 #include "chrome/browser/ui/pdf/chrome_pdf_web_contents_helper_client.h"
13 #include "chrome/common/chrome_version_info.h"
14 #include "components/pdf/browser/pdf_web_contents_helper.h"
15 #include "components/renderer_context_menu/context_menu_delegate.h"
16 #include "extensions/browser/api/web_request/web_request_api.h"
17 #include "extensions/browser/guest_view/web_view/web_view_constants.h"
19 #if defined(ENABLE_PRINTING)
20 #if defined(ENABLE_PRINT_PREVIEW)
21 #include "chrome/browser/printing/print_preview_message_handler.h"
22 #include "chrome/browser/printing/print_view_manager.h"
24 #include "chrome/browser/printing/print_view_manager_basic.h"
25 #endif // defined(ENABLE_PRINT_PREVIEW)
26 #endif // defined(ENABLE_PRINTING)
28 namespace extensions
{
30 ChromeWebViewGuestDelegate::ChromeWebViewGuestDelegate(
31 WebViewGuest
* web_view_guest
)
32 : pending_context_menu_request_id_(0),
33 chromevox_injected_(false),
34 web_view_guest_(web_view_guest
),
35 weak_ptr_factory_(this) {
38 ChromeWebViewGuestDelegate::~ChromeWebViewGuestDelegate() {
41 bool ChromeWebViewGuestDelegate::HandleContextMenu(
42 const content::ContextMenuParams
& params
) {
43 ContextMenuDelegate
* menu_delegate
=
44 ContextMenuDelegate::FromWebContents(guest_web_contents());
45 DCHECK(menu_delegate
);
47 pending_menu_
= menu_delegate
->BuildMenu(guest_web_contents(), params
);
49 // Pass it to embedder.
50 int request_id
= ++pending_context_menu_request_id_
;
51 scoped_ptr
<base::DictionaryValue
> args(new base::DictionaryValue());
52 scoped_ptr
<base::ListValue
> items
=
53 MenuModelToValue(pending_menu_
->menu_model());
54 args
->Set(webview::kContextMenuItems
, items
.release());
55 args
->SetInteger(webview::kRequestId
, request_id
);
56 web_view_guest()->DispatchEventToView(
57 new GuestViewBase::Event(webview::kEventContextMenu
, args
.Pass()));
61 // TODO(hanxi) Investigate which of these observers should move to the
62 // extension module in the future.
63 void ChromeWebViewGuestDelegate::OnAttachWebViewHelpers(
64 content::WebContents
* contents
) {
65 FaviconTabHelper::CreateForWebContents(contents
);
66 ChromeExtensionWebContentsObserver::CreateForWebContents(contents
);
67 #if defined(ENABLE_PRINTING)
68 #if defined(ENABLE_PRINT_PREVIEW)
69 printing::PrintViewManager::CreateForWebContents(contents
);
70 printing::PrintPreviewMessageHandler::CreateForWebContents(contents
);
72 printing::PrintViewManagerBasic::CreateForWebContents(contents
);
73 #endif // defined(ENABLE_PRINT_PREVIEW)
74 #endif // defined(ENABLE_PRINTING)
75 pdf::PDFWebContentsHelper::CreateForWebContentsWithClient(
77 scoped_ptr
<pdf::PDFWebContentsHelperClient
>(
78 new ChromePDFWebContentsHelperClient()));
81 void ChromeWebViewGuestDelegate::OnDidCommitProvisionalLoadForFrame(
84 chromevox_injected_
= false;
87 void ChromeWebViewGuestDelegate::OnDidInitialize() {
88 #if defined(OS_CHROMEOS)
89 chromeos::AccessibilityManager
* accessibility_manager
=
90 chromeos::AccessibilityManager::Get();
91 CHECK(accessibility_manager
);
92 accessibility_subscription_
= accessibility_manager
->RegisterCallback(
93 base::Bind(&ChromeWebViewGuestDelegate::OnAccessibilityStatusChanged
,
94 weak_ptr_factory_
.GetWeakPtr()));
98 void ChromeWebViewGuestDelegate::OnDocumentLoadedInFrame(
99 content::RenderFrameHost
* render_frame_host
) {
100 if (!render_frame_host
->GetParent())
101 InjectChromeVoxIfNeeded(render_frame_host
->GetRenderViewHost());
104 void ChromeWebViewGuestDelegate::OnGuestDestroyed() {
105 // Clean up custom context menu items for this guest.
106 MenuManager
* menu_manager
= MenuManager::Get(
107 Profile::FromBrowserContext(web_view_guest()->browser_context()));
108 menu_manager
->RemoveAllContextItems(MenuItem::ExtensionKey(
109 web_view_guest()->owner_extension_id(),
110 web_view_guest()->view_instance_id()));
114 scoped_ptr
<base::ListValue
> ChromeWebViewGuestDelegate::MenuModelToValue(
115 const ui::SimpleMenuModel
& menu_model
) {
116 scoped_ptr
<base::ListValue
> items(new base::ListValue());
117 for (int i
= 0; i
< menu_model
.GetItemCount(); ++i
) {
118 base::DictionaryValue
* item_value
= new base::DictionaryValue();
119 // TODO(lazyboy): We need to expose some kind of enum equivalent of
120 // |command_id| instead of plain integers.
121 item_value
->SetInteger(webview::kMenuItemCommandId
,
122 menu_model
.GetCommandIdAt(i
));
123 item_value
->SetString(webview::kMenuItemLabel
, menu_model
.GetLabelAt(i
));
124 items
->Append(item_value
);
129 void ChromeWebViewGuestDelegate::OnShowContextMenu(
131 const MenuItemVector
* items
) {
132 if (!pending_menu_
.get())
135 // Make sure this was the correct request.
136 if (request_id
!= pending_context_menu_request_id_
)
139 // TODO(lazyboy): Implement.
142 ContextMenuDelegate
* menu_delegate
=
143 ContextMenuDelegate::FromWebContents(guest_web_contents());
144 menu_delegate
->ShowMenu(pending_menu_
.Pass());
147 void ChromeWebViewGuestDelegate::InjectChromeVoxIfNeeded(
148 content::RenderViewHost
* render_view_host
) {
149 #if defined(OS_CHROMEOS)
150 if (!chromevox_injected_
) {
151 chromeos::AccessibilityManager
* manager
=
152 chromeos::AccessibilityManager::Get();
153 if (manager
&& manager
->IsSpokenFeedbackEnabled()) {
154 manager
->InjectChromeVox(render_view_host
);
155 chromevox_injected_
= true;
161 #if defined(OS_CHROMEOS)
162 void ChromeWebViewGuestDelegate::OnAccessibilityStatusChanged(
163 const chromeos::AccessibilityStatusEventDetails
& details
) {
164 if (details
.notification_type
== chromeos::ACCESSIBILITY_MANAGER_SHUTDOWN
) {
165 accessibility_subscription_
.reset();
166 } else if (details
.notification_type
==
167 chromeos::ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK
) {
169 InjectChromeVoxIfNeeded(guest_web_contents()->GetRenderViewHost());
171 chromevox_injected_
= false;
176 } // namespace extensions