07e362f58c0f80768b548d913fbe9bc213154aaf
[WebKit-https.git] / Source / WebCore / page / mac / 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)) && PLATFORM(MAC)
30
31 #include "GraphicsLayerClient.h"
32 #include "PageOverlay.h"
33 #include "Range.h"
34 #include "Timer.h"
35 #include <wtf/RefCounted.h>
36
37 typedef struct __DDHighlight *DDHighlightRef;
38
39 namespace WebCore {
40 class LayoutRect;
41 class MainFrame;
42 struct GapRects;
43 }
44
45 namespace WebCore {
46
47 class ServicesOverlayController : private PageOverlay::Client {
48     WTF_MAKE_FAST_ALLOCATED;
49 public:
50     explicit ServicesOverlayController(MainFrame&);
51     ~ServicesOverlayController();
52
53     void selectedTelephoneNumberRangesChanged();
54     void selectionRectsDidChange(const Vector<LayoutRect>&, const Vector<GapRects>&, bool isTextOnly);
55
56 private:
57     class Highlight : public RefCounted<Highlight>, private GraphicsLayerClient {
58         WTF_MAKE_NONCOPYABLE(Highlight);
59     public:
60         static Ref<Highlight> createForSelection(ServicesOverlayController&, RetainPtr<DDHighlightRef>, PassRefPtr<Range>);
61         static Ref<Highlight> createForTelephoneNumber(ServicesOverlayController&, RetainPtr<DDHighlightRef>, PassRefPtr<Range>);
62         ~Highlight();
63
64         void invalidate();
65
66         DDHighlightRef ddHighlight() const { return m_ddHighlight.get(); }
67         Range* range() const { return m_range.get(); }
68         GraphicsLayer* layer() const { return m_graphicsLayer.get(); }
69
70         enum class Type {
71             TelephoneNumber,
72             Selection
73         };
74         Type type() const { return m_type; }
75
76         void fadeIn();
77         void fadeOut();
78
79         void setDDHighlight(DDHighlightRef);
80
81     private:
82         explicit Highlight(ServicesOverlayController&, Type, RetainPtr<DDHighlightRef>, PassRefPtr<Range>);
83
84         // GraphicsLayerClient
85         virtual void notifyFlushRequired(const GraphicsLayer*) override;
86         virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const FloatRect& inClip) override;
87         virtual float deviceScaleFactor() const override;
88
89         void didFinishFadeOutAnimation();
90
91         RetainPtr<DDHighlightRef> m_ddHighlight;
92         RefPtr<Range> m_range;
93         std::unique_ptr<GraphicsLayer> m_graphicsLayer;
94         Type m_type;
95         ServicesOverlayController* m_controller;
96     };
97
98     // PageOverlay::Client
99     virtual void pageOverlayDestroyed(PageOverlay&) override;
100     virtual void willMoveToPage(PageOverlay&, Page*) override;
101     virtual void didMoveToPage(PageOverlay&, Page*) override;
102     virtual void drawRect(PageOverlay&, GraphicsContext&, const IntRect& dirtyRect) override;
103     virtual bool mouseEvent(PageOverlay&, const PlatformMouseEvent&) override;
104     virtual void didScrollFrame(PageOverlay&, Frame&) override;
105
106     void createOverlayIfNeeded();
107     void handleClick(const IntPoint&, Highlight&);
108
109     void drawHighlight(Highlight&, GraphicsContext&);
110
111     void replaceHighlightsOfTypePreservingEquivalentHighlights(HashSet<RefPtr<Highlight>>&, Highlight::Type);
112     void removeAllPotentialHighlightsOfType(Highlight::Type);
113     void buildPhoneNumberHighlights();
114     void buildSelectionHighlight();
115     void didRebuildPotentialHighlights();
116
117     void determineActiveHighlight(bool& mouseIsOverButton);
118     void clearActiveHighlight();
119     Highlight* activeHighlight() const { return m_activeHighlight.get(); }
120
121     Highlight* findTelephoneNumberHighlightContainingSelectionHighlight(Highlight&);
122
123     bool hasRelevantSelectionServices();
124
125     bool mouseIsOverHighlight(Highlight&, bool& mouseIsOverButton) const;
126     std::chrono::milliseconds remainingTimeUntilHighlightShouldBeShown(Highlight*) const;
127     void determineActiveHighlightTimerFired();
128
129     static bool highlightsAreEquivalent(const Highlight* a, const Highlight* b);
130
131     Vector<RefPtr<Range>> telephoneNumberRangesForFocusedFrame();
132
133     void didCreateHighlight(Highlight*);
134     void willDestroyHighlight(Highlight*);
135     void didFinishFadingOutHighlight(Highlight*);
136
137     MainFrame& mainFrame() const { return m_mainFrame; }
138
139     MainFrame& m_mainFrame;
140     PageOverlay* m_servicesOverlay;
141
142     RefPtr<Highlight> m_activeHighlight;
143     RefPtr<Highlight> m_nextActiveHighlight;
144     HashSet<RefPtr<Highlight>> m_potentialHighlights;
145     HashSet<RefPtr<Highlight>> m_animatingHighlights;
146
147     HashSet<Highlight*> m_highlights;
148
149     // FIXME: These should move onto Highlight.
150     Vector<LayoutRect> m_currentSelectionRects;
151     bool m_isTextOnly;
152
153     std::chrono::steady_clock::time_point m_lastSelectionChangeTime;
154     std::chrono::steady_clock::time_point m_nextActiveHighlightChangeTime;
155     std::chrono::steady_clock::time_point m_lastMouseUpTime;
156
157     RefPtr<Highlight> m_currentMouseDownOnButtonHighlight;
158     IntPoint m_mousePosition;
159
160     Timer m_determineActiveHighlightTimer;
161 };
162
163 } // namespace WebKit
164
165 #endif // (ENABLE(SERVICE_CONTROLS) || ENABLE(TELEPHONE_NUMBER_DETECTION)) && PLATFORM(MAC)
166 #endif // ServicesOverlayController_h