Yelp phone number highlights often disappear
[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/Range.h>
34 #include <WebCore/Timer.h>
35 #include <wtf/RefCounted.h>
36
37 typedef void* DDHighlightRef;
38
39 namespace WebCore {
40 class LayoutRect;
41
42 struct GapRects;
43 }
44
45 namespace WebKit {
46
47 class WebPage;
48
49 class ServicesOverlayController : private PageOverlay::Client {
50 public:
51     ServicesOverlayController(WebPage&);
52     ~ServicesOverlayController();
53
54     void selectedTelephoneNumberRangesChanged();
55     void selectionRectsDidChange(const Vector<WebCore::LayoutRect>&, const Vector<WebCore::GapRects>&, bool isTextOnly);
56
57 private:
58     class Highlight : public RefCounted<Highlight> {
59         WTF_MAKE_NONCOPYABLE(Highlight);
60     public:
61         static PassRefPtr<Highlight> createForSelection(RetainPtr<DDHighlightRef>);
62         static PassRefPtr<Highlight> createForTelephoneNumber(RetainPtr<DDHighlightRef>, PassRefPtr<WebCore::Range>);
63
64         DDHighlightRef ddHighlight() const { return m_ddHighlight.get(); }
65         WebCore::Range* range() const { return m_range.get(); }
66
67         enum class Type {
68             TelephoneNumber,
69             Selection
70         };
71         Type type() const { return m_type; }
72
73     private:
74         explicit Highlight(Type type, RetainPtr<DDHighlightRef> ddHighlight, PassRefPtr<WebCore::Range> range)
75             : m_ddHighlight(ddHighlight)
76             , m_range(range)
77             , m_type(type)
78         {
79             ASSERT(m_ddHighlight);
80             ASSERT(type != Type::TelephoneNumber || m_range);
81         }
82
83         RetainPtr<DDHighlightRef> m_ddHighlight;
84         RefPtr<WebCore::Range> m_range;
85         Type m_type;
86     };
87
88     // PageOverlay::Client
89     virtual void pageOverlayDestroyed(PageOverlay*) override;
90     virtual void willMoveToWebPage(PageOverlay*, WebPage*) override;
91     virtual void didMoveToWebPage(PageOverlay*, WebPage*) override;
92     virtual void drawRect(PageOverlay*, WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) override;
93     virtual bool mouseEvent(PageOverlay*, const WebMouseEvent&) override;
94
95     void createOverlayIfNeeded();
96     void handleClick(const WebCore::IntPoint&, Highlight&);
97
98     void drawHighlight(Highlight&, WebCore::GraphicsContext&);
99
100     void removeAllPotentialHighlightsOfType(Highlight::Type);
101     void buildPhoneNumberHighlights();
102     void buildSelectionHighlight();
103     void didRebuildPotentialHighlights();
104
105     void determineActiveHighlight(bool& mouseIsOverButton);
106     void clearActiveHighlight();
107
108     bool hasRelevantSelectionServices();
109
110     bool mouseIsOverHighlight(Highlight&, bool& mouseIsOverButton) const;
111     std::chrono::milliseconds remainingTimeUntilHighlightShouldBeShown() const;
112     void repaintHighlightTimerFired(WebCore::Timer<ServicesOverlayController>&);
113
114     static bool highlightsAreEquivalent(const Highlight* a, const Highlight* b);
115
116     Vector<RefPtr<WebCore::Range>> telephoneNumberRangesForFocusedFrame();
117
118     WebPage& m_webPage;
119     PageOverlay* m_servicesOverlay;
120
121     RefPtr<Highlight> m_activeHighlight;
122     HashSet<RefPtr<Highlight>> m_potentialHighlights;
123
124     Vector<WebCore::LayoutRect> m_currentSelectionRects;
125     bool m_isTextOnly;
126
127     std::chrono::steady_clock::time_point m_lastSelectionChangeTime;
128     std::chrono::steady_clock::time_point m_lastActiveHighlightChangeTime;
129
130     RefPtr<Highlight> m_currentMouseDownOnButtonHighlight;
131     WebCore::IntPoint m_mousePosition;
132
133     WebCore::Timer<ServicesOverlayController> m_repaintHighlightTimer;
134 };
135
136 } // namespace WebKit
137
138 #endif // ENABLE(SERVICE_CONTROLS) && ENABLE(TELEPHONE_NUMBER_DETECTION)
139 #endif // ServicesOverlayController_h