Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / renderer_host / chrome_render_widget_host_view_mac_delegate.mm
blobcc65b42384cbcaed398edd4f08bc56b0a78fa77a
1 // Copyright (c) 2012 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.
5 #import "chrome/browser/renderer_host/chrome_render_widget_host_view_mac_delegate.h"
7 #include <cmath>
9 #include "base/prefs/pref_service.h"
10 #include "base/strings/sys_string_conversions.h"
11 #include "chrome/browser/devtools/devtools_window.h"
12 #include "chrome/browser/profiles/profile.h"
13 #import "chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.h"
14 #include "chrome/browser/spellchecker/spellcheck_platform_mac.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/browser_commands.h"
17 #include "chrome/browser/ui/browser_finder.h"
18 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
19 #import "chrome/browser/ui/cocoa/view_id_util.h"
20 #include "chrome/common/pref_names.h"
21 #include "chrome/common/spellcheck_messages.h"
22 #include "chrome/common/url_constants.h"
23 #include "content/public/browser/render_process_host.h"
24 #include "content/public/browser/render_view_host.h"
25 #include "content/public/browser/render_widget_host.h"
26 #include "content/public/browser/render_widget_host_view.h"
27 #include "content/public/browser/web_contents.h"
28 #include "content/public/browser/web_contents_observer.h"
30 using content::RenderViewHost;
32 @interface ChromeRenderWidgetHostViewMacDelegate () <HistorySwiperDelegate>
33 - (void)spellCheckEnabled:(BOOL)enabled checked:(BOOL)checked;
34 @end
36 namespace ChromeRenderWidgetHostViewMacDelegateInternal {
38 // Filters the message sent by the renderer to know if spellchecking is enabled
39 // or not for the currently focused element.
40 class SpellCheckObserver : public content::WebContentsObserver {
41  public:
42   SpellCheckObserver(
43       RenderViewHost* host,
44       ChromeRenderWidgetHostViewMacDelegate* view_delegate)
45       : content::WebContentsObserver(
46             content::WebContents::FromRenderViewHost(host)),
47         view_delegate_(view_delegate) {
48   }
50   virtual ~SpellCheckObserver() {
51   }
53  private:
54   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
55     bool handled = true;
56     IPC_BEGIN_MESSAGE_MAP(SpellCheckObserver, message)
57       IPC_MESSAGE_HANDLER(SpellCheckHostMsg_ToggleSpellCheck,
58                           OnToggleSpellCheck)
59       IPC_MESSAGE_UNHANDLED(handled = false)
60     IPC_END_MESSAGE_MAP()
61     return handled;
62   }
64   void OnToggleSpellCheck(bool enabled, bool checked) {
65     [view_delegate_ spellCheckEnabled:enabled checked:checked];
66   }
68   ChromeRenderWidgetHostViewMacDelegate* view_delegate_;
71 }  // namespace ChromeRenderWidgetHostViewMacDelegateInternal
73 @implementation ChromeRenderWidgetHostViewMacDelegate
75 - (id)initWithRenderWidgetHost:(content::RenderWidgetHost*)renderWidgetHost {
76   self = [super init];
77   if (self) {
78     renderWidgetHost_ = renderWidgetHost;
79     NSView* nativeView = renderWidgetHost_->GetView()->GetNativeView();
80     view_id_util::SetID(nativeView, VIEW_ID_TAB_CONTAINER);
82     if (renderWidgetHost_->IsRenderView()) {
83       spellingObserver_.reset(
84           new ChromeRenderWidgetHostViewMacDelegateInternal::SpellCheckObserver(
85               RenderViewHost::From(renderWidgetHost_), self));
86     }
88     historySwiper_.reset([[HistorySwiper alloc] initWithDelegate:self]);
89   }
90   return self;
93 - (void)dealloc {
94   [historySwiper_ setDelegate:nil];
95   [super dealloc];
98 - (void)viewGone:(NSView*)view {
99   view_id_util::UnsetID(view);
100   [self autorelease];
103 // Handle an event. All incoming key and mouse events flow through this
104 // delegate method if implemented. Return YES if the event is fully handled, or
105 // NO if normal processing should take place.
106 - (BOOL)handleEvent:(NSEvent*)event {
107   return [historySwiper_ handleEvent:event];
110 // Notification that a wheel event was unhandled.
111 - (void)gotUnhandledWheelEvent {
112   [historySwiper_ gotUnhandledWheelEvent];
115 // Notification of scroll offset pinning.
116 - (void)scrollOffsetPinnedToLeft:(BOOL)left toRight:(BOOL)right {
117   [historySwiper_ scrollOffsetPinnedToLeft:left toRight:right];
120 // Notification of whether the view has a horizontal scrollbar.
121 - (void)setHasHorizontalScrollbar:(BOOL)has_horizontal_scrollbar {
122   [historySwiper_ setHasHorizontalScrollbar:has_horizontal_scrollbar];
125 // NSWindow events.
127 - (void)beginGestureWithEvent:(NSEvent*)event {
128   [historySwiper_ beginGestureWithEvent:event];
131 - (void)endGestureWithEvent:(NSEvent*)event {
132   [historySwiper_ endGestureWithEvent:event];
135 // This is a low level API which provides touches associated with an event.
136 // It is used in conjunction with gestures to determine finger placement
137 // on the trackpad.
138 - (void)touchesMovedWithEvent:(NSEvent*)event {
139   [historySwiper_ touchesMovedWithEvent:event];
142 - (void)touchesBeganWithEvent:(NSEvent*)event {
143   [historySwiper_ touchesBeganWithEvent:event];
146 - (void)touchesCancelledWithEvent:(NSEvent*)event {
147   [historySwiper_ touchesCancelledWithEvent:event];
150 - (void)touchesEndedWithEvent:(NSEvent*)event {
151   [historySwiper_ touchesEndedWithEvent:event];
154 // HistorySwiperDelegate methods
156 - (BOOL)shouldAllowHistorySwiping {
157   if (!renderWidgetHost_ || !renderWidgetHost_->IsRenderView())
158     return NO;
159   if (DevToolsWindow::IsDevToolsWindow(
160       RenderViewHost::From(renderWidgetHost_))) {
161     return NO;
162   }
164   return YES;
167 - (NSView*)viewThatWantsHistoryOverlay {
168   return renderWidgetHost_->GetView()->GetNativeView();
171 - (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item
172                       isValidItem:(BOOL*)valid {
173   SEL action = [item action];
175   // For now, this action is always enabled for render view;
176   // this is sub-optimal.
177   // TODO(suzhe): Plumb the "can*" methods up from WebCore.
178   if (action == @selector(checkSpelling:)) {
179     *valid = renderWidgetHost_->IsRenderView();
180     return YES;
181   }
183   // TODO(groby): Clarify who sends this and if toggleContinuousSpellChecking:
184   // is still necessary.
185   if (action == @selector(toggleContinuousSpellChecking:)) {
186     if ([(id)item respondsToSelector:@selector(setState:)]) {
187       content::RenderProcessHost* host = renderWidgetHost_->GetProcess();
188       Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext());
189       DCHECK(profile);
190       spellcheckChecked_ =
191           profile->GetPrefs()->GetBoolean(prefs::kEnableContinuousSpellcheck);
192       NSCellStateValue checkedState =
193           spellcheckChecked_ ? NSOnState : NSOffState;
194       [(id)item setState:checkedState];
195     }
196     *valid = spellcheckEnabled_;
197     return YES;
198   }
200   return NO;
203 // Spellchecking methods
204 // The next five methods are implemented here since this class is the first
205 // responder for anything in the browser.
207 // This message is sent whenever the user specifies that a word should be
208 // changed from the spellChecker.
209 - (void)changeSpelling:(id)sender {
210   // Grab the currently selected word from the spell panel, as this is the word
211   // that we want to replace the selected word in the text with.
212   NSString* newWord = [[sender selectedCell] stringValue];
213   if (newWord != nil) {
214     renderWidgetHost_->Replace(base::SysNSStringToUTF16(newWord));
215   }
218 // This message is sent by NSSpellChecker whenever the next word should be
219 // advanced to, either after a correction or clicking the "Find Next" button.
220 // This isn't documented anywhere useful, like in NSSpellProtocol.h with the
221 // other spelling panel methods. This is probably because Apple assumes that the
222 // the spelling panel will be used with an NSText, which will automatically
223 // catch this and advance to the next word for you. Thanks Apple.
224 // This is also called from the Edit -> Spelling -> Check Spelling menu item.
225 - (void)checkSpelling:(id)sender {
226   renderWidgetHost_->Send(new SpellCheckMsg_AdvanceToNextMisspelling(
227       renderWidgetHost_->GetRoutingID()));
230 // This message is sent by the spelling panel whenever a word is ignored.
231 - (void)ignoreSpelling:(id)sender {
232   // Ideally, we would ask the current RenderView for its tag, but that would
233   // mean making a blocking IPC call from the browser. Instead,
234   // spellcheck_mac::CheckSpelling remembers the last tag and
235   // spellcheck_mac::IgnoreWord assumes that is the correct tag.
236   NSString* wordToIgnore = [sender stringValue];
237   if (wordToIgnore != nil)
238     spellcheck_mac::IgnoreWord(base::SysNSStringToUTF16(wordToIgnore));
241 - (void)showGuessPanel:(id)sender {
242   renderWidgetHost_->Send(new SpellCheckMsg_ToggleSpellPanel(
243       renderWidgetHost_->GetRoutingID(),
244       spellcheck_mac::SpellingPanelVisible()));
247 - (void)toggleContinuousSpellChecking:(id)sender {
248   content::RenderProcessHost* host = renderWidgetHost_->GetProcess();
249   Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext());
250   DCHECK(profile);
251   PrefService* pref = profile->GetPrefs();
252   pref->SetBoolean(prefs::kEnableContinuousSpellcheck,
253                    !pref->GetBoolean(prefs::kEnableContinuousSpellcheck));
256 - (void)spellCheckEnabled:(BOOL)enabled checked:(BOOL)checked {
257   spellcheckEnabled_ = enabled;
258   spellcheckChecked_ = checked;
261 // END Spellchecking methods
263 @end