fad43a85f524549862af9a0e716369c44ad3fbd1
[WebKit-https.git] / Source / WebCore / page / mac / ServicesOverlayController.h
1 /*
2  * Copyright (C) 2014-2017 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 #pragma once
27
28 #if (ENABLE(SERVICE_CONTROLS) || ENABLE(TELEPHONE_NUMBER_DETECTION)) && PLATFORM(MAC)
29
30 #include "GraphicsLayerClient.h"
31 #include "PageOverlay.h"
32 #include "Range.h"
33 #include "Timer.h"
34 #include <wtf/MonotonicTime.h>
35
36 typedef struct __DDHighlight *DDHighlightRef;
37
38 namespace WebCore {
39     
40 class LayoutRect;
41 class Page;
42
43 struct GapRects;
44
45 class ServicesOverlayController : private PageOverlay::Client {
46     WTF_MAKE_FAST_ALLOCATED;
47 public:
48     explicit ServicesOverlayController(Page&);
49     ~ServicesOverlayController();
50
51     void selectedTelephoneNumberRangesChanged();
52     void selectionRectsDidChange(const Vector<LayoutRect>&, const Vector<GapRects>&, bool isTextOnly);
53
54 private:
55     class Highlight : public RefCounted<Highlight>, private GraphicsLayerClient {
56         WTF_MAKE_NONCOPYABLE(Highlight);
57     public:
58         static Ref<Highlight> createForSelection(ServicesOverlayController&, RetainPtr<DDHighlightRef>, Ref<Range>&&);
59         static Ref<Highlight> createForTelephoneNumber(ServicesOverlayController&, RetainPtr<DDHighlightRef>, Ref<Range>&&);
60         ~Highlight();
61
62         void invalidate();
63
64         DDHighlightRef ddHighlight() const { return m_ddHighlight.get(); }
65         Range& range() const { return m_range.get(); }
66         GraphicsLayer* layer() const { return m_graphicsLayer.get(); }
67
68         enum {
69             TelephoneNumberType = 1 << 0,
70             SelectionType = 1 << 1,
71         };
72         typedef uint8_t Type;
73         Type type() const { return m_type; }
74
75         void fadeIn();
76         void fadeOut();
77
78         void setDDHighlight(DDHighlightRef);
79
80     private:
81         Highlight(ServicesOverlayController&, Type, RetainPtr<DDHighlightRef>, Ref<Range>&&);
82
83         // GraphicsLayerClient
84         void notifyFlushRequired(const GraphicsLayer*) override;
85         void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const FloatRect& inClip, GraphicsLayerPaintBehavior) override;
86         float deviceScaleFactor() const override;
87
88         void didFinishFadeOutAnimation();
89
90         RetainPtr<DDHighlightRef> m_ddHighlight;
91         Ref<Range> m_range;
92         std::unique_ptr<GraphicsLayer> m_graphicsLayer;
93         Type m_type;
94         ServicesOverlayController* m_controller;
95     };
96
97     // PageOverlay::Client
98     void willMoveToPage(PageOverlay&, Page*) override;
99     void didMoveToPage(PageOverlay&, Page*) override;
100     void drawRect(PageOverlay&, GraphicsContext&, const IntRect& dirtyRect) override;
101     bool mouseEvent(PageOverlay&, const PlatformMouseEvent&) override;
102     void didScrollFrame(PageOverlay&, Frame&) override;
103
104     void createOverlayIfNeeded();
105     void handleClick(const IntPoint&, Highlight&);
106
107     void drawHighlight(Highlight&, GraphicsContext&);
108
109     void invalidateHighlightsOfType(Highlight::Type);
110     void buildPotentialHighlightsIfNeeded();
111
112     void replaceHighlightsOfTypePreservingEquivalentHighlights(HashSet<RefPtr<Highlight>>&, Highlight::Type);
113     void removeAllPotentialHighlightsOfType(Highlight::Type);
114     void buildPhoneNumberHighlights();
115     void buildSelectionHighlight();
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     Seconds 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     Frame& mainFrame() const;
138     Page& page() const { return m_page; }
139
140     Page& m_page;
141     PageOverlay* m_servicesOverlay { nullptr };
142
143     RefPtr<Highlight> m_activeHighlight;
144     RefPtr<Highlight> m_nextActiveHighlight;
145     HashSet<RefPtr<Highlight>> m_potentialHighlights;
146     HashSet<RefPtr<Highlight>> m_animatingHighlights;
147
148     HashSet<Highlight*> m_highlights;
149
150     // FIXME: These should move onto Highlight.
151     Vector<LayoutRect> m_currentSelectionRects;
152     bool m_isTextOnly { false };
153
154     Highlight::Type m_dirtyHighlightTypes { 0 };
155
156     MonotonicTime m_lastSelectionChangeTime;
157     MonotonicTime m_nextActiveHighlightChangeTime;
158     MonotonicTime m_lastMouseUpTime;
159
160     RefPtr<Highlight> m_currentMouseDownOnButtonHighlight;
161     IntPoint m_mousePosition;
162
163     Timer m_determineActiveHighlightTimer;
164     Timer m_buildHighlightsTimer;
165 };
166
167 } // namespace WebCore
168
169 #endif // (ENABLE(SERVICE_CONTROLS) || ENABLE(TELEPHONE_NUMBER_DETECTION)) && PLATFORM(MAC)