1/*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
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
13 * distribution.
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.
17 *
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.
29 */
30
31#ifndef WebViewImpl_h
32#define WebViewImpl_h
33
34#include "WebNavigationPolicy.h"
35#include "WebPoint.h"
36#include "WebRect.h"
37#include "WebSize.h"
38#include "WebString.h"
39#include "WebView.h"
40
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"
48#include "IntRect.h"
49#include "LayerRendererChromium.h"
50#include "NotificationPresenterImpl.h"
51#include <wtf/OwnPtr.h>
52#include <wtf/RefCounted.h>
53
54namespace WebCore {
55class ChromiumDataObject;
56class DocumentLoader;
57class Frame;
58class HistoryItem;
59class HitTestResult;
60class KeyboardEvent;
61class Page;
62class PlatformKeyboardEvent;
63class PopupContainer;
64class PopupMenuClient;
65class Range;
66class RenderTheme;
67class Widget;
68}
69
70namespace WebKit {
71class AutocompletePopupMenuClient;
72class AutoFillPopupMenuClient;
73class ContextMenuClientImpl;
74class DeviceOrientationClientProxy;
75class DragScrollTimer;
76class GeolocationClientProxy;
77class SpeechInputClientImpl;
78class WebAccessibilityObject;
79class WebDevToolsAgentClient;
80class WebDevToolsAgentPrivate;
81class WebFrameImpl;
82class WebImage;
83class WebKeyboardEvent;
84class WebMouseEvent;
85class WebMouseWheelEvent;
86class WebSettingsImpl;
87class WebTouchEvent;
88
89class WebViewImpl : public WebView, public RefCounted<WebViewImpl> {
90public:
91    // WebWidget methods:
92    virtual void close();
93    virtual WebSize size() { return m_size; }
94    virtual void resize(const WebSize&);
95    virtual void animate();
96    virtual void layout();
97    virtual void paint(WebCanvas*, const WebRect&);
98    virtual void themeChanged();
99    virtual void composite(bool finish);
100    virtual bool handleInputEvent(const WebInputEvent&);
101    virtual void mouseCaptureLost();
102    virtual void setFocus(bool enable);
103    virtual bool setComposition(
104        const WebString& text,
105        const WebVector<WebCompositionUnderline>& underlines,
106        int selectionStart,
107        int selectionEnd);
108    virtual bool confirmComposition();
109    virtual bool confirmComposition(const WebString& text);
110    virtual WebTextInputType textInputType();
111    virtual WebRect caretOrSelectionBounds();
112    virtual bool selectionRange(WebPoint& start, WebPoint& end) const;
113    virtual void setTextDirection(WebTextDirection direction);
114    virtual bool isAcceleratedCompositingActive() const;
115
116    // WebView methods:
117    virtual void initializeMainFrame(WebFrameClient*);
118    virtual void setDevToolsAgentClient(WebDevToolsAgentClient*);
119    virtual void setAutoFillClient(WebAutoFillClient*);
120    virtual void setSpellCheckClient(WebSpellCheckClient*);
121    virtual WebSettings* settings();
122    virtual WebString pageEncoding() const;
123    virtual void setPageEncoding(const WebString& encoding);
124    virtual bool isTransparent() const;
125    virtual void setIsTransparent(bool value);
126    virtual bool tabsToLinks() const;
127    virtual void setTabsToLinks(bool value);
128    virtual bool tabKeyCyclesThroughElements() const;
129    virtual void setTabKeyCyclesThroughElements(bool value);
130    virtual bool isActive() const;
131    virtual void setIsActive(bool value);
132    virtual void setDomainRelaxationForbidden(bool, const WebString& scheme);
133    virtual bool dispatchBeforeUnloadEvent();
134    virtual void dispatchUnloadEvent();
135    virtual WebFrame* mainFrame();
136    virtual WebFrame* findFrameByName(
137        const WebString& name, WebFrame* relativeToFrame);
138    virtual WebFrame* focusedFrame();
139    virtual void setFocusedFrame(WebFrame* frame);
140    virtual void setInitialFocus(bool reverse);
141    virtual void clearFocusedNode();
142    virtual void scrollFocusedNodeIntoView();
143    virtual double zoomLevel();
144    virtual double setZoomLevel(bool textOnly, double zoomLevel);
145    virtual void zoomLimitsChanged(double minimumZoomLevel,
146                                   double maximumZoomLevel);
147    virtual void performMediaPlayerAction(
148        const WebMediaPlayerAction& action,
149        const WebPoint& location);
150    virtual void copyImageAt(const WebPoint& point);
151    virtual void dragSourceEndedAt(
152        const WebPoint& clientPoint,
153        const WebPoint& screenPoint,
154        WebDragOperation operation);
155    virtual void dragSourceMovedTo(
156        const WebPoint& clientPoint,
157        const WebPoint& screenPoint,
158        WebDragOperation operation);
159    virtual void dragSourceSystemDragEnded();
160    virtual WebDragOperation dragTargetDragEnter(
161        const WebDragData&,
162        const WebPoint& clientPoint,
163        const WebPoint& screenPoint,
164        WebDragOperationsMask operationsAllowed);
165    virtual WebDragOperation dragTargetDragOver(
166        const WebPoint& clientPoint,
167        const WebPoint& screenPoint,
168        WebDragOperationsMask operationsAllowed);
169    virtual void dragTargetDragLeave();
170    virtual void dragTargetDrop(
171        const WebPoint& clientPoint,
172        const WebPoint& screenPoint);
173    virtual unsigned long createUniqueIdentifierForRequest();
174    virtual void inspectElementAt(const WebPoint& point);
175    virtual WebString inspectorSettings() const;
176    virtual void setInspectorSettings(const WebString& settings);
177    virtual bool inspectorSetting(const WebString& key, WebString* value) const;
178    virtual void setInspectorSetting(const WebString& key,
179                                     const WebString& value);
180    virtual WebDevToolsAgent* devToolsAgent();
181    virtual WebAccessibilityObject accessibilityObject();
182    virtual void applyAutoFillSuggestions(
183        const WebNode&,
184        const WebVector<WebString>& names,
185        const WebVector<WebString>& labels,
186        const WebVector<WebString>& icons,
187        const WebVector<int>& uniqueIDs,
188        int separatorIndex);
189    virtual void hidePopups();
190    virtual void setScrollbarColors(unsigned inactiveColor,
191                                    unsigned activeColor,
192                                    unsigned trackColor);
193    virtual void setSelectionColors(unsigned activeBackgroundColor,
194                                    unsigned activeForegroundColor,
195                                    unsigned inactiveBackgroundColor,
196                                    unsigned inactiveForegroundColor);
197    virtual void performCustomContextMenuAction(unsigned action);
198
199    // WebViewImpl
200
201    void setIgnoreInputEvents(bool newValue);
202    WebDevToolsAgentPrivate* devToolsAgentPrivate() { return m_devToolsAgent.get(); }
203
204    const WebPoint& lastMouseDownPoint() const
205    {
206        return m_lastMouseDownPoint;
207    }
208
209    WebCore::Frame* focusedWebCoreFrame() const;
210
211    // Returns the currently focused Node or null if no node has focus.
212    WebCore::Node* focusedWebCoreNode();
213
214    static WebViewImpl* fromPage(WebCore::Page*);
215
216    WebViewClient* client()
217    {
218        return m_client;
219    }
220
221    WebAutoFillClient* autoFillClient()
222    {
223        return m_autoFillClient;
224    }
225
226    WebSpellCheckClient* spellCheckClient()
227    {
228        return m_spellCheckClient;
229    }
230
231    // Returns the page object associated with this view. This may be null when
232    // the page is shutting down, but will be valid at all other times.
233    WebCore::Page* page() const
234    {
235        return m_page.get();
236    }
237
238    WebCore::RenderTheme* theme() const;
239
240    // Returns the main frame associated with this view. This may be null when
241    // the page is shutting down, but will be valid at all other times.
242    WebFrameImpl* mainFrameImpl();
243
244    // History related methods:
245    void observeNewNavigation();
246
247    // Event related methods:
248    void mouseMove(const WebMouseEvent&);
249    void mouseLeave(const WebMouseEvent&);
250    void mouseDown(const WebMouseEvent&);
251    void mouseUp(const WebMouseEvent&);
252    void mouseContextMenu(const WebMouseEvent&);
253    void mouseDoubleClick(const WebMouseEvent&);
254    bool mouseWheel(const WebMouseWheelEvent&);
255    bool keyEvent(const WebKeyboardEvent&);
256    bool charEvent(const WebKeyboardEvent&);
257    bool touchEvent(const WebTouchEvent&);
258
259    // Handles context menu events orignated via the the keyboard. These
260    // include the VK_APPS virtual key and the Shift+F10 combine. Code is
261    // based on the Webkit function bool WebView::handleContextMenuEvent(WPARAM
262    // wParam, LPARAM lParam) in webkit\webkit\win\WebView.cpp. The only
263    // significant change in this function is the code to convert from a
264    // Keyboard event to the Right Mouse button down event.
265    bool sendContextMenuEvent(const WebKeyboardEvent&);
266
267    // Notifies the WebView that a load has been committed. isNewNavigation
268    // will be true if a new session history item should be created for that
269    // load.
270    void didCommitLoad(bool* isNewNavigation);
271
272    // Returns true if popup menus should be rendered by the browser, false if
273    // they should be rendered by WebKit (which is the default).
274    static bool useExternalPopupMenus();
275
276    bool contextMenuAllowed() const
277    {
278        return m_contextMenuAllowed;
279    }
280
281    // Set the disposition for how this webview is to be initially shown.
282    void setInitialNavigationPolicy(WebNavigationPolicy policy)
283    {
284        m_initialNavigationPolicy = policy;
285    }
286    WebNavigationPolicy initialNavigationPolicy() const
287    {
288        return m_initialNavigationPolicy;
289    }
290
291    // Determines whether a page should e.g. be opened in a background tab.
292    // Returns false if it has no opinion, in which case it doesn't set *policy.
293    static bool navigationPolicyFromMouseEvent(
294        unsigned short button,
295        bool ctrl,
296        bool shift,
297        bool alt,
298        bool meta,
299        WebNavigationPolicy*);
300
301    // Start a system drag and drop operation.
302    void startDragging(
303        const WebDragData& dragData,
304        WebDragOperationsMask mask,
305        const WebImage& dragImage,
306        const WebPoint& dragImageOffset);
307
308    void autoFillPopupDidHide()
309    {
310        m_autoFillPopupShowing = false;
311    }
312
313#if ENABLE(NOTIFICATIONS)
314    // Returns the provider of desktop notifications.
315    NotificationPresenterImpl* notificationPresenterImpl();
316#endif
317
318    // Tries to scroll a frame or any parent of a frame. Returns true if the view
319    // was scrolled.
320    bool propagateScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity);
321
322    // Notification that a popup was opened/closed.
323    void popupOpened(WebCore::PopupContainer* popupContainer);
324    void popupClosed(WebCore::PopupContainer* popupContainer);
325
326    void hideAutoFillPopup();
327
328    // Returns the input event we're currently processing. This is used in some
329    // cases where the WebCore DOM event doesn't have the information we need.
330    static const WebInputEvent* currentInputEvent()
331    {
332        return m_currentInputEvent;
333    }
334
335#if USE(ACCELERATED_COMPOSITING)
336    bool allowsAcceleratedCompositing();
337    bool pageHasRTLStyle() const;
338    void setRootGraphicsLayer(WebCore::PlatformLayer*);
339    void setRootLayerNeedsDisplay();
340    void scrollRootLayerRect(const WebCore::IntSize& scrollDelta, const WebCore::IntRect& clipRect);
341    void invalidateRootLayerRect(const WebCore::IntRect&);
342#endif
343
344    // Returns the onscreen 3D context used by the compositor. This is
345    // used by the renderer's code to set up resource sharing between
346    // the compositor's context and subordinate contexts for APIs like
347    // WebGL. Returns 0 if compositing support is not compiled in.
348    virtual WebGraphicsContext3D* graphicsContext3D();
349
350    WebCore::PopupContainer* selectPopup() const { return m_selectPopup.get(); }
351
352    // Returns true if the event leads to scrolling.
353    static bool mapKeyCodeForScroll(int keyCode,
354                                   WebCore::ScrollDirection* scrollDirection,
355                                   WebCore::ScrollGranularity* scrollGranularity);
356
357    // Called by a full frame plugin inside this view to inform it that its
358    // zoom level has been updated.  The plugin should only call this function
359    // if the zoom change was triggered by the browser, it's only needed in case
360    // a plugin can update its own zoom, say because of its own UI.
361    void fullFramePluginZoomLevelChanged(double zoomLevel);
362
363private:
364    friend class WebView;  // So WebView::Create can call our constructor
365    friend class WTF::RefCounted<WebViewImpl>;
366
367    enum DragAction {
368      DragEnter,
369      DragOver
370    };
371
372    WebViewImpl(WebViewClient*);
373    ~WebViewImpl();
374
375    // Returns true if the event was actually processed.
376    bool keyEventDefault(const WebKeyboardEvent&);
377
378    // Returns true if the select popup has consumed the event.
379    bool selectPopupHandleKeyEvent(const WebKeyboardEvent&);
380
381    // Returns true if the autocomple has consumed the event.
382    bool autocompleteHandleKeyEvent(const WebKeyboardEvent&);
383
384    // Repaints the AutoFill popup. Should be called when the suggestions
385    // have changed. Note that this should only be called when the AutoFill
386    // popup is showing.
387    void refreshAutoFillPopup();
388
389    // Returns true if the view was scrolled.
390    bool scrollViewWithKeyboard(int keyCode, int modifiers);
391
392    void hideSelectPopup();
393
394    // Converts |pos| from window coordinates to contents coordinates and gets
395    // the HitTestResult for it.
396    WebCore::HitTestResult hitTestResultForWindowPos(const WebCore::IntPoint&);
397
398    // Consolidate some common code between starting a drag over a target and
399    // updating a drag over a target. If we're starting a drag, |isEntering|
400    // should be true.
401    WebDragOperation dragTargetDragEnterOrOver(const WebPoint& clientPoint,
402                                               const WebPoint& screenPoint,
403                                               DragAction);
404
405#if USE(ACCELERATED_COMPOSITING)
406    void setIsAcceleratedCompositingActive(bool);
407    void doComposite();
408    void doPixelReadbackToCanvas(WebCanvas*, const WebCore::IntRect&);
409    void reallocateRenderer();
410    void updateLayerRendererViewport();
411#endif
412
413    WebViewClient* m_client;
414    WebAutoFillClient* m_autoFillClient;
415    WebSpellCheckClient* m_spellCheckClient;
416
417    ChromeClientImpl m_chromeClientImpl;
418    ContextMenuClientImpl m_contextMenuClientImpl;
419    DragClientImpl m_dragClientImpl;
420    EditorClientImpl m_editorClientImpl;
421    InspectorClientImpl m_inspectorClientImpl;
422
423    WebSize m_size;
424
425    WebPoint m_lastMousePosition;
426    OwnPtr<WebCore::Page> m_page;
427
428    // This flag is set when a new navigation is detected. It is used to satisfy
429    // the corresponding argument to WebFrameClient::didCommitProvisionalLoad.
430    bool m_observedNewNavigation;
431#ifndef NDEBUG
432    // Used to assert that the new navigation we observed is the same navigation
433    // when we make use of m_observedNewNavigation.
434    const WebCore::DocumentLoader* m_newNavigationLoader;
435#endif
436
437    // An object that can be used to manipulate m_page->settings() without linking
438    // against WebCore. This is lazily allocated the first time GetWebSettings()
439    // is called.
440    OwnPtr<WebSettingsImpl> m_webSettings;
441
442    // A copy of the web drop data object we received from the browser.
443    RefPtr<WebCore::ChromiumDataObject> m_currentDragData;
444
445    // The point relative to the client area where the mouse was last pressed
446    // down. This is used by the drag client to determine what was under the
447    // mouse when the drag was initiated. We need to track this here in
448    // WebViewImpl since DragClient::startDrag does not pass the position the
449    // mouse was at when the drag was initiated, only the current point, which
450    // can be misleading as it is usually not over the element the user actually
451    // dragged by the time a drag is initiated.
452    WebPoint m_lastMouseDownPoint;
453
454    // Keeps track of the current zoom level. 0 means no zoom, positive numbers
455    // mean zoom in, negative numbers mean zoom out.
456    double m_zoomLevel;
457
458    double m_minimumZoomLevel;
459
460    double m_maximumZoomLevel;
461
462    bool m_contextMenuAllowed;
463
464    bool m_doingDragAndDrop;
465
466    bool m_ignoreInputEvents;
467
468    // Webkit expects keyPress events to be suppressed if the associated keyDown
469    // event was handled. Safari implements this behavior by peeking out the
470    // associated WM_CHAR event if the keydown was handled. We emulate
471    // this behavior by setting this flag if the keyDown was handled.
472    bool m_suppressNextKeypressEvent;
473
474    // The policy for how this webview is to be initially shown.
475    WebNavigationPolicy m_initialNavigationPolicy;
476
477    // Represents whether or not this object should process incoming IME events.
478    bool m_imeAcceptEvents;
479
480    // The available drag operations (copy, move link...) allowed by the source.
481    WebDragOperation m_operationsAllowed;
482
483    // The current drag operation as negotiated by the source and destination.
484    // When not equal to DragOperationNone, the drag data can be dropped onto the
485    // current drop target in this WebView (the drop target can accept the drop).
486    WebDragOperation m_dragOperation;
487
488    // Whether an AutoFill popup is currently showing.
489    bool m_autoFillPopupShowing;
490
491    // The AutoFill popup client.
492    OwnPtr<AutoFillPopupMenuClient> m_autoFillPopupClient;
493
494    // The AutoFill popup.
495    RefPtr<WebCore::PopupContainer> m_autoFillPopup;
496
497    // The popup associated with a select element.
498    RefPtr<WebCore::PopupContainer> m_selectPopup;
499
500    OwnPtr<WebDevToolsAgentPrivate> m_devToolsAgent;
501
502    // Whether the webview is rendering transparently.
503    bool m_isTransparent;
504
505    // Whether the user can press tab to focus links.
506    bool m_tabsToLinks;
507
508    // Inspector settings.
509    WebString m_inspectorSettings;
510
511    typedef HashMap<WTF::String, WTF::String> SettingsMap;
512    OwnPtr<SettingsMap> m_inspectorSettingsMap;
513    OwnPtr<DragScrollTimer> m_dragScrollTimer;
514
515#if ENABLE(NOTIFICATIONS)
516    // The provider of desktop notifications;
517    NotificationPresenterImpl m_notificationPresenter;
518#endif
519
520    // If set, the (plugin) node which has mouse capture.
521    RefPtr<WebCore::Node> m_mouseCaptureNode;
522
523#if USE(ACCELERATED_COMPOSITING)
524    WebCore::IntRect m_rootLayerScrollDamage;
525    RefPtr<WebCore::LayerRendererChromium> m_layerRenderer;
526    bool m_isAcceleratedCompositingActive;
527    bool m_compositorCreationFailed;
528    // If true, the graphics context is being restored.
529    bool m_recreatingGraphicsContext;
530#endif
531    static const WebInputEvent* m_currentInputEvent;
532
533#if ENABLE(INPUT_SPEECH)
534    OwnPtr<SpeechInputClientImpl> m_speechInputClient;
535#endif
536    // If we attempt to fetch the on-screen GraphicsContext3D before
537    // the compositor has been turned on, we need to instantiate it
538    // early. This member holds on to the GC3D in this case.
539    RefPtr<WebCore::GraphicsContext3D> m_temporaryOnscreenGraphicsContext3D;
540    OwnPtr<DeviceOrientationClientProxy> m_deviceOrientationClientProxy;
541    OwnPtr<GeolocationClientProxy> m_geolocationClientProxy;
542};
543
544} // namespace WebKit
545
546#endif
547