2 * Copyright (C) 2010 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "WebNavigationPolicy.h"
38 #include "WebString.h"
41 #include "ChromeClientImpl.h"
42 #include "ContextMenuClientImpl.h"
43 #include "DragClientImpl.h"
44 #include "EditorClientImpl.h"
45 #include "GraphicsContext3D.h"
46 #include "GraphicsLayer.h"
47 #include "InspectorClientImpl.h"
49 #include "NotificationPresenterImpl.h"
50 #include "PageOverlay.h"
51 #include "UserMediaClientImpl.h"
52 #include "cc/CCLayerTreeHost.h"
53 #include <wtf/OwnPtr.h>
54 #include <wtf/RefCounted.h>
57 class ChromiumDataObject;
60 class GraphicsContext3D;
64 class NonCompositedContentHost;
66 class PlatformKeyboardEvent;
68 class PopupMenuClient;
72 #if ENABLE(GESTURE_RECOGNIZER)
73 class PlatformGestureRecognizer;
78 class AutocompletePopupMenuClient;
79 class AutofillPopupMenuClient;
80 class ContextMenuClientImpl;
81 class DeviceOrientationClientProxy;
82 class DragScrollTimer;
83 class GeolocationClientProxy;
84 class SpeechInputClientImpl;
85 class UserMediaClientImpl;
86 class WebAccessibilityObject;
87 class WebCompositorImpl;
88 class WebDevToolsAgentClient;
89 class WebDevToolsAgentPrivate;
91 class WebGestureEvent;
93 class WebKeyboardEvent;
95 class WebMouseWheelEvent;
96 class WebSettingsImpl;
99 class WebViewImpl : public WebView, public WebCore::CCLayerTreeHostClient, public RefCounted<WebViewImpl> {
101 // WebWidget methods:
102 virtual void close();
103 virtual WebSize size() { return m_size; }
104 virtual void willStartLiveResize();
105 virtual void resize(const WebSize&);
106 virtual void willEndLiveResize();
107 virtual void willEnterFullScreen();
108 virtual void didEnterFullScreen();
109 virtual void willExitFullScreen();
110 virtual void didExitFullScreen();
111 virtual void animate(double frameBeginTime);
112 virtual void layout();
113 virtual void paint(WebCanvas*, const WebRect&);
114 virtual void themeChanged();
115 virtual void composite(bool finish);
116 virtual bool handleInputEvent(const WebInputEvent&);
117 virtual void mouseCaptureLost();
118 virtual void setFocus(bool enable);
119 virtual bool setComposition(
120 const WebString& text,
121 const WebVector<WebCompositionUnderline>& underlines,
124 virtual bool confirmComposition();
125 virtual bool confirmComposition(const WebString& text);
126 virtual bool compositionRange(size_t* location, size_t* length);
127 virtual WebTextInputType textInputType();
128 virtual bool selectionBounds(WebRect& start, WebRect& end) const;
129 virtual bool caretOrSelectionRange(size_t* location, size_t* length);
130 virtual void setTextDirection(WebTextDirection direction);
131 virtual bool isAcceleratedCompositingActive() const;
134 virtual void initializeMainFrame(WebFrameClient*);
135 virtual void setAutofillClient(WebAutofillClient*);
136 virtual void setDevToolsAgentClient(WebDevToolsAgentClient*);
137 virtual void setPermissionClient(WebPermissionClient*);
138 virtual void setSpellCheckClient(WebSpellCheckClient*);
139 virtual WebSettings* settings();
140 virtual WebString pageEncoding() const;
141 virtual void setPageEncoding(const WebString& encoding);
142 virtual bool isTransparent() const;
143 virtual void setIsTransparent(bool value);
144 virtual bool tabsToLinks() const;
145 virtual void setTabsToLinks(bool value);
146 virtual bool tabKeyCyclesThroughElements() const;
147 virtual void setTabKeyCyclesThroughElements(bool value);
148 virtual bool isActive() const;
149 virtual void setIsActive(bool value);
150 virtual void setDomainRelaxationForbidden(bool, const WebString& scheme);
151 virtual bool dispatchBeforeUnloadEvent();
152 virtual void dispatchUnloadEvent();
153 virtual WebFrame* mainFrame();
154 virtual WebFrame* findFrameByName(
155 const WebString& name, WebFrame* relativeToFrame);
156 virtual WebFrame* focusedFrame();
157 virtual void setFocusedFrame(WebFrame* frame);
158 virtual void setInitialFocus(bool reverse);
159 virtual void clearFocusedNode();
160 virtual void scrollFocusedNodeIntoView();
161 virtual void scrollFocusedNodeIntoRect(const WebRect&);
162 virtual double zoomLevel();
163 virtual double setZoomLevel(bool textOnly, double zoomLevel);
164 virtual void zoomLimitsChanged(double minimumZoomLevel,
165 double maximumZoomLevel);
166 virtual float pageScaleFactor() const;
167 virtual void setPageScaleFactorPreservingScrollOffset(float);
168 virtual void setPageScaleFactor(float scaleFactor, const WebPoint& origin);
169 virtual void setPageScaleFactorLimits(float minPageScale, float maxPageScale);
170 virtual float minimumPageScaleFactor() const;
171 virtual float maximumPageScaleFactor() const;
173 virtual float deviceScaleFactor() const;
174 virtual void setDeviceScaleFactor(float);
175 virtual bool isFixedLayoutModeEnabled() const;
176 virtual void enableFixedLayoutMode(bool enable);
177 virtual WebSize fixedLayoutSize() const;
178 virtual void setFixedLayoutSize(const WebSize&);
179 virtual void performMediaPlayerAction(
180 const WebMediaPlayerAction& action,
181 const WebPoint& location);
182 virtual void copyImageAt(const WebPoint& point);
183 virtual void dragSourceEndedAt(
184 const WebPoint& clientPoint,
185 const WebPoint& screenPoint,
186 WebDragOperation operation);
187 virtual void dragSourceMovedTo(
188 const WebPoint& clientPoint,
189 const WebPoint& screenPoint,
190 WebDragOperation operation);
191 virtual void dragSourceSystemDragEnded();
192 virtual WebDragOperation dragTargetDragEnter(
194 const WebPoint& clientPoint,
195 const WebPoint& screenPoint,
196 WebDragOperationsMask operationsAllowed);
197 virtual WebDragOperation dragTargetDragOver(
198 const WebPoint& clientPoint,
199 const WebPoint& screenPoint,
200 WebDragOperationsMask operationsAllowed);
201 virtual void dragTargetDragLeave();
202 virtual void dragTargetDrop(
203 const WebPoint& clientPoint,
204 const WebPoint& screenPoint);
205 virtual unsigned long createUniqueIdentifierForRequest();
206 virtual void inspectElementAt(const WebPoint& point);
207 virtual WebString inspectorSettings() const;
208 virtual void setInspectorSettings(const WebString& settings);
209 virtual bool inspectorSetting(const WebString& key, WebString* value) const;
210 virtual void setInspectorSetting(const WebString& key,
211 const WebString& value);
212 virtual WebDevToolsAgent* devToolsAgent();
213 virtual WebAccessibilityObject accessibilityObject();
214 virtual void applyAutofillSuggestions(
216 const WebVector<WebString>& names,
217 const WebVector<WebString>& labels,
218 const WebVector<WebString>& icons,
219 const WebVector<int>& uniqueIDs,
221 virtual void hidePopups();
222 virtual void setScrollbarColors(unsigned inactiveColor,
223 unsigned activeColor,
224 unsigned trackColor);
225 virtual void setSelectionColors(unsigned activeBackgroundColor,
226 unsigned activeForegroundColor,
227 unsigned inactiveBackgroundColor,
228 unsigned inactiveForegroundColor);
229 virtual void performCustomContextMenuAction(unsigned action);
231 // CCLayerTreeHostClient
232 virtual void animateAndLayout(double frameBeginTime);
233 virtual void applyScrollAndScale(const WebCore::IntSize&, float);
234 virtual PassRefPtr<WebCore::GraphicsContext3D> createLayerTreeHostContext3D();
235 virtual void didCommitAndDrawFrame();
236 virtual void didCompleteSwapBuffers();
237 virtual void didRecreateGraphicsContext(bool success);
238 virtual void scheduleComposite();
242 void setIgnoreInputEvents(bool newValue);
243 WebDevToolsAgentPrivate* devToolsAgentPrivate() { return m_devToolsAgent.get(); }
245 PageOverlay* pageOverlay() const { return m_pageOverlay.get(); }
246 void setPageOverlayClient(PageOverlay::PageOverlayClient*);
248 void setOverlayLayer(WebCore::GraphicsLayer*);
250 const WebPoint& lastMouseDownPoint() const
252 return m_lastMouseDownPoint;
255 WebCore::Frame* focusedWebCoreFrame() const;
257 // Returns the currently focused Node or null if no node has focus.
258 WebCore::Node* focusedWebCoreNode();
260 static WebViewImpl* fromPage(WebCore::Page*);
262 WebViewClient* client()
267 WebAutofillClient* autofillClient()
269 return m_autofillClient;
272 WebPermissionClient* permissionClient()
274 return m_permissionClient;
277 WebSpellCheckClient* spellCheckClient()
279 return m_spellCheckClient;
282 // Returns the page object associated with this view. This may be null when
283 // the page is shutting down, but will be valid at all other times.
284 WebCore::Page* page() const
289 WebCore::RenderTheme* theme() const;
291 // Returns the main frame associated with this view. This may be null when
292 // the page is shutting down, but will be valid at all other times.
293 WebFrameImpl* mainFrameImpl();
295 // History related methods:
296 void observeNewNavigation();
298 // Event related methods:
299 void mouseMove(const WebMouseEvent&);
300 void mouseLeave(const WebMouseEvent&);
301 void mouseDown(const WebMouseEvent&);
302 void mouseUp(const WebMouseEvent&);
303 void mouseContextMenu(const WebMouseEvent&);
304 void mouseDoubleClick(const WebMouseEvent&);
305 bool mouseWheel(const WebMouseWheelEvent&);
306 bool gestureEvent(const WebGestureEvent&);
307 bool keyEvent(const WebKeyboardEvent&);
308 bool charEvent(const WebKeyboardEvent&);
309 bool touchEvent(const WebTouchEvent&);
311 void numberOfWheelEventHandlersChanged(unsigned);
313 // Handles context menu events orignated via the the keyboard. These
314 // include the VK_APPS virtual key and the Shift+F10 combine. Code is
315 // based on the Webkit function bool WebView::handleContextMenuEvent(WPARAM
316 // wParam, LPARAM lParam) in webkit\webkit\win\WebView.cpp. The only
317 // significant change in this function is the code to convert from a
318 // Keyboard event to the Right Mouse button down event.
319 bool sendContextMenuEvent(const WebKeyboardEvent&);
321 // Notifies the WebView that a load has been committed. isNewNavigation
322 // will be true if a new session history item should be created for that
324 void didCommitLoad(bool* isNewNavigation);
326 // Returns true if popup menus should be rendered by the browser, false if
327 // they should be rendered by WebKit (which is the default).
328 static bool useExternalPopupMenus();
330 bool contextMenuAllowed() const
332 return m_contextMenuAllowed;
335 // Set the disposition for how this webview is to be initially shown.
336 void setInitialNavigationPolicy(WebNavigationPolicy policy)
338 m_initialNavigationPolicy = policy;
340 WebNavigationPolicy initialNavigationPolicy() const
342 return m_initialNavigationPolicy;
345 // Determines whether a page should e.g. be opened in a background tab.
346 // Returns false if it has no opinion, in which case it doesn't set *policy.
347 static bool navigationPolicyFromMouseEvent(
348 unsigned short button,
353 WebNavigationPolicy*);
355 // Start a system drag and drop operation.
357 const WebDragData& dragData,
358 WebDragOperationsMask mask,
359 const WebImage& dragImage,
360 const WebPoint& dragImageOffset);
362 void autofillPopupDidHide()
364 m_autofillPopupShowing = false;
367 #if ENABLE(NOTIFICATIONS)
368 // Returns the provider of desktop notifications.
369 NotificationPresenterImpl* notificationPresenterImpl();
372 // Tries to scroll a frame or any parent of a frame. Returns true if the view
374 bool propagateScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity);
376 // Notification that a popup was opened/closed.
377 void popupOpened(WebCore::PopupContainer* popupContainer);
378 void popupClosed(WebCore::PopupContainer* popupContainer);
380 void hideAutofillPopup();
382 // Returns the input event we're currently processing. This is used in some
383 // cases where the WebCore DOM event doesn't have the information we need.
384 static const WebInputEvent* currentInputEvent()
386 return m_currentInputEvent;
389 #if USE(ACCELERATED_COMPOSITING)
390 bool allowsAcceleratedCompositing();
391 bool pageHasRTLStyle() const;
392 void setRootGraphicsLayer(WebCore::GraphicsLayer*);
393 void setRootLayerNeedsDisplay();
394 void scrollRootLayerRect(const WebCore::IntSize& scrollDelta, const WebCore::IntRect& clipRect);
395 void invalidateRootLayerRect(const WebCore::IntRect&);
396 WebCore::NonCompositedContentHost* nonCompositedContentHost();
398 #if ENABLE(REQUEST_ANIMATION_FRAME)
399 void scheduleAnimation();
402 // Returns the onscreen 3D context used by the compositor. This is
403 // used by the renderer's code to set up resource sharing between
404 // the compositor's context and subordinate contexts for APIs like
405 // WebGL. Returns 0 if compositing support is not compiled in.
406 virtual WebGraphicsContext3D* graphicsContext3D();
408 virtual void setVisibilityState(WebPageVisibilityState, bool);
410 WebCore::PopupContainer* selectPopup() const { return m_selectPopup.get(); }
412 // Returns true if the event leads to scrolling.
413 static bool mapKeyCodeForScroll(int keyCode,
414 WebCore::ScrollDirection* scrollDirection,
415 WebCore::ScrollGranularity* scrollGranularity);
417 // Called by a full frame plugin inside this view to inform it that its
418 // zoom level has been updated. The plugin should only call this function
419 // if the zoom change was triggered by the browser, it's only needed in case
420 // a plugin can update its own zoom, say because of its own UI.
421 void fullFramePluginZoomLevelChanged(double zoomLevel);
423 #if ENABLE(GESTURE_RECOGNIZER)
424 void resetGestureRecognizer();
427 void loseCompositorContext(int numTimes);
429 void enterFullScreenForElement(WebCore::Element*);
430 void exitFullScreenForElement(WebCore::Element*);
433 float computePageScaleFactorWithinLimits(float scale);
434 WebPoint clampOffsetAtScale(const WebPoint& offset, float scale);
436 friend class WebView; // So WebView::Create can call our constructor
437 friend class WTF::RefCounted<WebViewImpl>;
444 WebViewImpl(WebViewClient*);
445 virtual ~WebViewImpl();
447 // Returns true if the event was actually processed.
448 bool keyEventDefault(const WebKeyboardEvent&);
450 // Returns true if the autocomple has consumed the event.
451 bool autocompleteHandleKeyEvent(const WebKeyboardEvent&);
453 // Repaints the Autofill popup. Should be called when the suggestions
454 // have changed. Note that this should only be called when the Autofill
456 void refreshAutofillPopup();
458 // Returns true if the view was scrolled.
459 bool scrollViewWithKeyboard(int keyCode, int modifiers);
461 void hideSelectPopup();
463 // Converts |pos| from window coordinates to contents coordinates and gets
464 // the HitTestResult for it.
465 WebCore::HitTestResult hitTestResultForWindowPos(const WebCore::IntPoint&);
467 // Consolidate some common code between starting a drag over a target and
468 // updating a drag over a target. If we're starting a drag, |isEntering|
470 WebDragOperation dragTargetDragEnterOrOver(const WebPoint& clientPoint,
471 const WebPoint& screenPoint,
474 #if USE(ACCELERATED_COMPOSITING)
475 void setIsAcceleratedCompositingActive(bool);
477 void doPixelReadbackToCanvas(WebCanvas*, const WebCore::IntRect&);
478 void reallocateRenderer();
479 void updateLayerTreeViewport();
482 WebViewClient* m_client;
483 WebAutofillClient* m_autofillClient;
484 WebPermissionClient* m_permissionClient;
485 WebSpellCheckClient* m_spellCheckClient;
487 ChromeClientImpl m_chromeClientImpl;
488 ContextMenuClientImpl m_contextMenuClientImpl;
489 DragClientImpl m_dragClientImpl;
490 EditorClientImpl m_editorClientImpl;
491 InspectorClientImpl m_inspectorClientImpl;
495 WebPoint m_lastMousePosition;
496 OwnPtr<WebCore::Page> m_page;
498 // This flag is set when a new navigation is detected. It is used to satisfy
499 // the corresponding argument to WebFrameClient::didCommitProvisionalLoad.
500 bool m_observedNewNavigation;
502 // Used to assert that the new navigation we observed is the same navigation
503 // when we make use of m_observedNewNavigation.
504 const WebCore::DocumentLoader* m_newNavigationLoader;
507 // An object that can be used to manipulate m_page->settings() without linking
508 // against WebCore. This is lazily allocated the first time GetWebSettings()
510 OwnPtr<WebSettingsImpl> m_webSettings;
512 // A copy of the web drop data object we received from the browser.
513 RefPtr<WebCore::ChromiumDataObject> m_currentDragData;
515 // The point relative to the client area where the mouse was last pressed
516 // down. This is used by the drag client to determine what was under the
517 // mouse when the drag was initiated. We need to track this here in
518 // WebViewImpl since DragClient::startDrag does not pass the position the
519 // mouse was at when the drag was initiated, only the current point, which
520 // can be misleading as it is usually not over the element the user actually
521 // dragged by the time a drag is initiated.
522 WebPoint m_lastMouseDownPoint;
524 // Keeps track of the current zoom level. 0 means no zoom, positive numbers
525 // mean zoom in, negative numbers mean zoom out.
528 double m_minimumZoomLevel;
530 double m_maximumZoomLevel;
532 float m_minimumPageScaleFactor;
534 float m_maximumPageScaleFactor;
536 bool m_contextMenuAllowed;
538 bool m_doingDragAndDrop;
540 bool m_ignoreInputEvents;
542 // Webkit expects keyPress events to be suppressed if the associated keyDown
543 // event was handled. Safari implements this behavior by peeking out the
544 // associated WM_CHAR event if the keydown was handled. We emulate
545 // this behavior by setting this flag if the keyDown was handled.
546 bool m_suppressNextKeypressEvent;
548 // The policy for how this webview is to be initially shown.
549 WebNavigationPolicy m_initialNavigationPolicy;
551 // Represents whether or not this object should process incoming IME events.
552 bool m_imeAcceptEvents;
554 // The available drag operations (copy, move link...) allowed by the source.
555 WebDragOperation m_operationsAllowed;
557 // The current drag operation as negotiated by the source and destination.
558 // When not equal to DragOperationNone, the drag data can be dropped onto the
559 // current drop target in this WebView (the drop target can accept the drop).
560 WebDragOperation m_dragOperation;
562 // Whether an Autofill popup is currently showing.
563 bool m_autofillPopupShowing;
565 // The Autofill popup client.
566 OwnPtr<AutofillPopupMenuClient> m_autofillPopupClient;
568 // The Autofill popup.
569 RefPtr<WebCore::PopupContainer> m_autofillPopup;
571 // The popup associated with a select element.
572 RefPtr<WebCore::PopupContainer> m_selectPopup;
574 OwnPtr<WebDevToolsAgentPrivate> m_devToolsAgent;
575 OwnPtr<PageOverlay> m_pageOverlay;
577 // Whether the webview is rendering transparently.
578 bool m_isTransparent;
580 // Whether the user can press tab to focus links.
583 // Inspector settings.
584 WebString m_inspectorSettings;
586 typedef HashMap<WTF::String, WTF::String> SettingsMap;
587 OwnPtr<SettingsMap> m_inspectorSettingsMap;
588 OwnPtr<DragScrollTimer> m_dragScrollTimer;
590 #if ENABLE(NOTIFICATIONS)
591 // The provider of desktop notifications;
592 NotificationPresenterImpl m_notificationPresenter;
595 // If set, the (plugin) node which has mouse capture.
596 RefPtr<WebCore::Node> m_mouseCaptureNode;
598 // If set, the WebView is transitioning to fullscreen for this element.
599 RefPtr<WebCore::Element> m_provisionalFullScreenElement;
601 // If set, the WebView is in fullscreen mode for an element in this frame.
602 RefPtr<WebCore::Frame> m_fullScreenFrame;
604 #if USE(ACCELERATED_COMPOSITING)
605 WebCore::IntRect m_rootLayerScrollDamage;
606 OwnPtr<WebCore::NonCompositedContentHost> m_nonCompositedContentHost;
607 RefPtr<WebCore::CCLayerTreeHost> m_layerTreeHost;
608 WebCore::GraphicsLayer* m_rootGraphicsLayer;
609 bool m_isAcceleratedCompositingActive;
610 bool m_compositorCreationFailed;
611 // If true, the graphics context is being restored.
612 bool m_recreatingGraphicsContext;
614 bool m_haveWheelEventHandlers;
615 static const WebInputEvent* m_currentInputEvent;
617 #if ENABLE(INPUT_SPEECH)
618 OwnPtr<SpeechInputClientImpl> m_speechInputClient;
620 // If we attempt to fetch the on-screen GraphicsContext3D before
621 // the compositor has been turned on, we need to instantiate it
622 // early. This member holds on to the GC3D in this case.
623 RefPtr<WebCore::GraphicsContext3D> m_temporaryOnscreenGraphicsContext3D;
624 OwnPtr<DeviceOrientationClientProxy> m_deviceOrientationClientProxy;
625 OwnPtr<GeolocationClientProxy> m_geolocationClientProxy;
627 #if ENABLE(GESTURE_RECOGNIZER)
628 OwnPtr<WebCore::PlatformGestureRecognizer> m_gestureRecognizer;
631 #if ENABLE(MEDIA_STREAM)
632 UserMediaClientImpl m_userMediaClientImpl;
636 } // namespace WebKit