Selection services cannot be invoked when force click is enabled
[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 {
71             TelephoneNumberType = 1 << 0,
72             SelectionType = 1 << 1,
73         };
74         typedef uint8_t Type;
75         Type type() const { return m_type; }
76
77         void fadeIn();
78         void fadeOut();
79
80         void setDDHighlight(DDHighlightRef);
81
82     private:
83         explicit Highlight(ServicesOverlayController&, Type, RetainPtr<DDHighlightRef>, PassRefPtr<Range>);
84
85         // GraphicsLayerClient
86         virtual void notifyFlushRequired(const GraphicsLayer*) override;
87         virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const FloatRect& inClip) override;
88         virtual float deviceScaleFactor() const override;
89
90         void didFinishFadeOutAnimation();
91
92         RetainPtr<DDHighlightRef> m_ddHighlight;
93         RefPtr<Range> m_range;
94         std::unique_ptr<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 willMoveToPage(PageOverlay&, Page*) override;
102     virtual void didMoveToPage(PageOverlay&, Page*) override;
103     virtual void drawRect(PageOverlay&, GraphicsContext&, const IntRect& dirtyRect) override;
104     virtual bool mouseEvent(PageOverlay&, const PlatformMouseEvent&) override;
105     virtual void didScrollFrame(PageOverlay&, Frame&) override;
106
107     void createOverlayIfNeeded();
108     void handleClick(const IntPoint&, Highlight&);
109
110     void drawHighlight(Highlight&, GraphicsContext&);
111
112     void invalidateHighlightsOfType(Highlight::Type);
113     void buildPotentialHighlightsIfNeeded();
114
115     void replaceHighlightsOfTypePreservingEquivalentHighlights(HashSet<RefPtr<Highlight>>&, Highlight::Type);
116     void removeAllPotentialHighlightsOfType(Highlight::Type);
117     void buildPhoneNumberHighlights();
118     void buildSelectionHighlight();
119
120     void determineActiveHighlight(bool& mouseIsOverButton);
121     void clearActiveHighlight();
122     Highlight* activeHighlight() const { return m_activeHighlight.get(); }
123
124     Highlight* findTelephoneNumberHighlightContainingSelectionHighlight(Highlight&);
125
126     bool hasRelevantSelectionServices();
127
128     bool mouseIsOverHighlight(Highlight&, bool& mouseIsOverButton) const;
129     std::chrono::milliseconds remainingTimeUntilHighlightShouldBeShown(Highlight*) const;
130     void determineActiveHighlightTimerFired();
131
132     static bool highlightsAreEquivalent(const Highlight* a, const Highlight* b);
133
134     Vector<RefPtr<Range>> telephoneNumberRangesForFocusedFrame();
135
136     void didCreateHighlight(Highlight*);
137     void willDestroyHighlight(Highlight*);
138     void didFinishFadingOutHighlight(Highlight*);
139
140     MainFrame& mainFrame() const { return m_mainFrame; }
141
142     MainFrame& m_mainFrame;
143     PageOverlay* m_servicesOverlay { nullptr };
144
145     RefPtr<Highlight> m_activeHighlight;
146     RefPtr<Highlight> m_nextActiveHighlight;
147     HashSet<RefPtr<Highlight>> m_potentialHighlights;
148     HashSet<RefPtr<Highlight>> m_animatingHighlights;
149
150     HashSet<Highlight*> m_highlights;
151
152     // FIXME: These should move onto Highlight.
153     Vector<LayoutRect> m_currentSelectionRects;
154     bool m_isTextOnly { false };
155
156     Highlight::Type m_dirtyHighlightTypes { 0 };
157
158     std::chrono::steady_clock::time_point m_lastSelectionChangeTime;
159     std::chrono::steady_clock::time_point m_nextActiveHighlightChangeTime;
160     std::chrono::steady_clock::time_point m_lastMouseUpTime;
161
162     RefPtr<Highlight> m_currentMouseDownOnButtonHighlight;
163     IntPoint m_mousePosition;
164
165     Timer m_determineActiveHighlightTimer;
166     Timer m_buildHighlightsTimer;
167 };
168
169 } // namespace WebKit
170
171 #endif // (ENABLE(SERVICE_CONTROLS) || ENABLE(TELEPHONE_NUMBER_DETECTION)) && PLATFORM(MAC)
172 #endif // ServicesOverlayController_h