43b86ab0d1f6807be35f5decde94bc44a2679514
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebPage / ServicesOverlayController.h
1 /*
2  * Copyright (C) 2014 Apple 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
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef ServicesOverlayController_h
27 #define ServicesOverlayController_h
28
29 #if ENABLE(SERVICE_CONTROLS) || ENABLE(TELEPHONE_NUMBER_DETECTION)
30
31 #include "PageOverlay.h"
32 #include "WebFrame.h"
33 #include <WebCore/GraphicsLayerClient.h>
34 #include <WebCore/Range.h>
35 #include <WebCore/Timer.h>
36 #include <wtf/RefCounted.h>
37
38 typedef void* DDHighlightRef;
39
40 namespace WebCore {
41 class LayoutRect;
42
43 struct GapRects;
44 }
45
46 namespace WebKit {
47
48 class WebPage;
49
50 class ServicesOverlayController : private PageOverlay::Client {
51 public:
52     ServicesOverlayController(WebPage&);
53     ~ServicesOverlayController();
54
55     void selectedTelephoneNumberRangesChanged();
56     void selectionRectsDidChange(const Vector<WebCore::LayoutRect>&, const Vector<WebCore::GapRects>&, bool isTextOnly);
57
58 private:
59     class Highlight : public RefCounted<Highlight>, private WebCore::GraphicsLayerClient {
60         WTF_MAKE_NONCOPYABLE(Highlight);
61     public:
62         static PassRefPtr<Highlight> createForSelection(ServicesOverlayController&, RetainPtr<DDHighlightRef>);
63         static PassRefPtr<Highlight> createForTelephoneNumber(ServicesOverlayController&, RetainPtr<DDHighlightRef>, PassRefPtr<WebCore::Range>);
64         ~Highlight();
65
66         void invalidate();
67
68         DDHighlightRef ddHighlight() const { return m_ddHighlight.get(); }
69         WebCore::Range* range() const { return m_range.get(); }
70         WebCore::GraphicsLayer* layer() const { return m_graphicsLayer.get(); }
71
72         enum class Type {
73             TelephoneNumber,
74             Selection
75         };
76         Type type() const { return m_type; }
77
78         void fadeIn();
79         void fadeOut();
80
81     private:
82         explicit Highlight(ServicesOverlayController&, Type, RetainPtr<DDHighlightRef>, PassRefPtr<WebCore::Range>);
83
84         // GraphicsLayerClient
85         virtual void notifyAnimationStarted(const WebCore::GraphicsLayer*, double time) override { }
86         virtual void notifyFlushRequired(const WebCore::GraphicsLayer*) override;
87         virtual void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::FloatRect& inClip) override;
88         virtual float deviceScaleFactor() const override;
89
90         void didFinishFadeOutAnimation();
91
92         RetainPtr<DDHighlightRef> m_ddHighlight;
93         RefPtr<WebCore::Range> m_range;
94         std::unique_ptr<WebCore::GraphicsLayer> m_graphicsLayer;
95         Type m_type;
96         ServicesOverlayController* m_controller;
97     };
98
99     // PageOverlay::Client
100     virtual void pageOverlayDestroyed(PageOverlay*) override;
101     virtual void willMoveToWebPage(PageOverlay*, WebPage*) override;
102     virtual void didMoveToWebPage(PageOverlay*, WebPage*) override;
103     virtual void drawRect(PageOverlay*, WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) override;
104     virtual bool mouseEvent(PageOverlay*, const WebMouseEvent&) override;
105
106     void createOverlayIfNeeded();
107     void handleClick(const WebCore::IntPoint&, Highlight&);
108
109     void drawHighlight(Highlight&, WebCore::GraphicsContext&);
110
111     void removeAllPotentialHighlightsOfType(Highlight::Type);
112     void buildPhoneNumberHighlights();
113     void buildSelectionHighlight();
114     void didRebuildPotentialHighlights();
115
116     void determineActiveHighlight(bool& mouseIsOverButton);
117     void clearActiveHighlight();
118     Highlight* activeHighlight() const { return m_activeHighlight.get(); }
119
120     Highlight* findTelephoneNumberHighlightContainingSelectionHighlight(Highlight&);
121
122     bool hasRelevantSelectionServices();
123
124     bool mouseIsOverHighlight(Highlight&, bool& mouseIsOverButton) const;
125     std::chrono::milliseconds remainingTimeUntilHighlightShouldBeShown(Highlight*) const;
126     void determineActiveHighlightTimerFired(WebCore::Timer<ServicesOverlayController>&);
127
128     static bool highlightsAreEquivalent(const Highlight* a, const Highlight* b);
129
130     Vector<RefPtr<WebCore::Range>> telephoneNumberRangesForFocusedFrame();
131
132     void didCreateHighlight(Highlight*);
133     void willDestroyHighlight(Highlight*);
134     void didFinishFadingOutHighlight(Highlight*);
135
136     WebPage& webPage() const { return m_webPage; }
137
138     WebPage& m_webPage;
139     PageOverlay* m_servicesOverlay;
140
141     RefPtr<Highlight> m_activeHighlight;
142     RefPtr<Highlight> m_nextActiveHighlight;
143     HashSet<RefPtr<Highlight>> m_potentialHighlights;
144     HashSet<RefPtr<Highlight>> m_animatingHighlights;
145
146     HashSet<Highlight*> m_highlights;
147
148     // FIXME: These should move onto Highlight.
149     Vector<WebCore::LayoutRect> m_currentSelectionRects;
150     bool m_isTextOnly;
151
152     std::chrono::steady_clock::time_point m_lastSelectionChangeTime;
153     std::chrono::steady_clock::time_point m_nextActiveHighlightChangeTime;
154     std::chrono::steady_clock::time_point m_lastMouseUpTime;
155
156     RefPtr<Highlight> m_currentMouseDownOnButtonHighlight;
157     WebCore::IntPoint m_mousePosition;
158
159     WebCore::Timer<ServicesOverlayController> m_determineActiveHighlightTimer;
160 };
161
162 } // namespace WebKit
163
164 #endif // ENABLE(SERVICE_CONTROLS) && ENABLE(TELEPHONE_NUMBER_DETECTION)
165 #endif // ServicesOverlayController_h