8aaf912e03256899af9ed766ad1205d2a68150a2
[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 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 public:
49     explicit ServicesOverlayController(MainFrame&);
50     ~ServicesOverlayController();
51
52     void selectedTelephoneNumberRangesChanged();
53     void selectionRectsDidChange(const Vector<LayoutRect>&, const Vector<GapRects>&, bool isTextOnly);
54
55 private:
56     class Highlight : public RefCounted<Highlight>, private GraphicsLayerClient {
57         WTF_MAKE_NONCOPYABLE(Highlight);
58     public:
59         static PassRefPtr<Highlight> createForSelection(ServicesOverlayController&, RetainPtr<DDHighlightRef>, PassRefPtr<Range>);
60         static PassRefPtr<Highlight> createForTelephoneNumber(ServicesOverlayController&, RetainPtr<DDHighlightRef>, PassRefPtr<Range>);
61         ~Highlight();
62
63         void invalidate();
64
65         DDHighlightRef ddHighlight() const { return m_ddHighlight.get(); }
66         Range* range() const { return m_range.get(); }
67         GraphicsLayer* layer() const { return m_graphicsLayer.get(); }
68
69         enum class Type {
70             TelephoneNumber,
71             Selection
72         };
73         Type type() const { return m_type; }
74
75         void fadeIn();
76         void fadeOut();
77
78         void setDDHighlight(DDHighlightRef);
79
80     private:
81         explicit Highlight(ServicesOverlayController&, Type, RetainPtr<DDHighlightRef>, PassRefPtr<Range>);
82
83         // GraphicsLayerClient
84         virtual void notifyFlushRequired(const GraphicsLayer*) override;
85         virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const FloatRect& inClip) override;
86         virtual float deviceScaleFactor() const override;
87
88         void didFinishFadeOutAnimation();
89
90         RetainPtr<DDHighlightRef> m_ddHighlight;
91         RefPtr<Range> m_range;
92         std::unique_ptr<GraphicsLayer> m_graphicsLayer;
93         Type m_type;
94         ServicesOverlayController* m_controller;
95     };
96
97     // PageOverlay::Client
98     virtual void pageOverlayDestroyed(PageOverlay&) override;
99     virtual void willMoveToPage(PageOverlay&, Page*) override;
100     virtual void didMoveToPage(PageOverlay&, Page*) override;
101     virtual void drawRect(PageOverlay&, GraphicsContext&, const IntRect& dirtyRect) override;
102     virtual bool mouseEvent(PageOverlay&, const PlatformMouseEvent&) override;
103     virtual void didScrollFrame(PageOverlay&, Frame&) override;
104
105     void createOverlayIfNeeded();
106     void handleClick(const IntPoint&, Highlight&);
107
108     void drawHighlight(Highlight&, GraphicsContext&);
109
110     void replaceHighlightsOfTypePreservingEquivalentHighlights(HashSet<RefPtr<Highlight>>&, Highlight::Type);
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(Timer&);
127
128     static bool highlightsAreEquivalent(const Highlight* a, const Highlight* b);
129
130     Vector<RefPtr<Range>> telephoneNumberRangesForFocusedFrame();
131
132     void didCreateHighlight(Highlight*);
133     void willDestroyHighlight(Highlight*);
134     void didFinishFadingOutHighlight(Highlight*);
135
136     MainFrame& mainFrame() const { return m_mainFrame; }
137
138     MainFrame& m_mainFrame;
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<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     IntPoint m_mousePosition;
158
159     Timer m_determineActiveHighlightTimer;
160 };
161
162 } // namespace WebKit
163
164 #endif // (ENABLE(SERVICE_CONTROLS) || ENABLE(TELEPHONE_NUMBER_DETECTION)) && PLATFORM(MAC)
165 #endif // ServicesOverlayController_h