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/GraphicsLayerClient.h> 34#include <WebCore/Range.h> 35#include <WebCore/Timer.h> 36#include <wtf/RefCounted.h> 37 38typedef void* DDHighlightRef; 39 40namespace WebCore { 41class LayoutRect; 42 43struct GapRects; 44} 45 46namespace WebKit { 47 48class WebPage; 49 50class ServicesOverlayController : private PageOverlay::Client { 51public: 52 ServicesOverlayController(WebPage&); 53 ~ServicesOverlayController(); 54 55 void selectedTelephoneNumberRangesChanged(); 56 void selectionRectsDidChange(const Vector<WebCore::LayoutRect>&, const Vector<WebCore::GapRects>&, bool isTextOnly); 57 58private: 59 class Highlight : public RefCounted<Highlight>, private WebCore::GraphicsLayerClient { 60 WTF_MAKE_NONCOPYABLE(Highlight); 61 public: 62 static PassRefPtr<Highlight> createForSelection(ServicesOverlayController&, RetainPtr<DDHighlightRef>, PassRefPtr<WebCore::Range>); 63 static PassRefPtr<Highlight> createForTelephoneNumber(ServicesOverlayController&, RetainPtr<DDHighlightRef>, PassRefPtr<WebCore::Range>); 64 ~Highlight(); 65 66 void invalidate(); 67 68 DDHighlightRef ddHighlight() const { return m_ddHighlight.get(); } 69 WebCore::Range* range() const { return m_range.get(); } 70 WebCore::GraphicsLayer* layer() const { return m_graphicsLayer.get(); } 71 72 enum class Type { 73 TelephoneNumber, 74 Selection 75 }; 76 Type type() const { return m_type; } 77 78 void fadeIn(); 79 void fadeOut(); 80 81 void setDDHighlight(DDHighlightRef); 82 83 private: 84 explicit Highlight(ServicesOverlayController&, Type, RetainPtr<DDHighlightRef>, PassRefPtr<WebCore::Range>); 85 86 // GraphicsLayerClient 87 virtual void notifyAnimationStarted(const WebCore::GraphicsLayer*, double time) override { } 88 virtual void notifyFlushRequired(const WebCore::GraphicsLayer*) override; 89 virtual void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::FloatRect& inClip) override; 90 virtual float deviceScaleFactor() const override; 91 92 void didFinishFadeOutAnimation(); 93 94 RetainPtr<DDHighlightRef> m_ddHighlight; 95 RefPtr<WebCore::Range> m_range; 96 std::unique_ptr<WebCore::GraphicsLayer> m_graphicsLayer; 97 Type m_type; 98 ServicesOverlayController* m_controller; 99 }; 100 101 // PageOverlay::Client 102 virtual void pageOverlayDestroyed(PageOverlay*) override; 103 virtual void willMoveToWebPage(PageOverlay*, WebPage*) override; 104 virtual void didMoveToWebPage(PageOverlay*, WebPage*) override; 105 virtual void drawRect(PageOverlay*, WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) override; 106 virtual bool mouseEvent(PageOverlay*, const WebMouseEvent&) override; 107 virtual void didScrollFrame(PageOverlay*, WebCore::Frame*) override; 108 109 void createOverlayIfNeeded(); 110 void handleClick(const WebCore::IntPoint&, Highlight&); 111 112 void drawHighlight(Highlight&, WebCore::GraphicsContext&); 113 114 void replaceHighlightsOfTypePreservingEquivalentHighlights(HashSet<RefPtr<Highlight>>&, Highlight::Type); 115 void removeAllPotentialHighlightsOfType(Highlight::Type); 116 void buildPhoneNumberHighlights(); 117 void buildSelectionHighlight(); 118 void didRebuildPotentialHighlights(); 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(WebCore::Timer<ServicesOverlayController>&); 131 132 static bool highlightsAreEquivalent(const Highlight* a, const Highlight* b); 133 134 Vector<RefPtr<WebCore::Range>> telephoneNumberRangesForFocusedFrame(); 135 136 void didCreateHighlight(Highlight*); 137 void willDestroyHighlight(Highlight*); 138 void didFinishFadingOutHighlight(Highlight*); 139 140 WebPage& webPage() const { return m_webPage; } 141 142 WebPage& m_webPage; 143 PageOverlay* m_servicesOverlay; 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<WebCore::LayoutRect> m_currentSelectionRects; 154 bool m_isTextOnly; 155 156 std::chrono::steady_clock::time_point m_lastSelectionChangeTime; 157 std::chrono::steady_clock::time_point m_nextActiveHighlightChangeTime; 158 std::chrono::steady_clock::time_point m_lastMouseUpTime; 159 160 RefPtr<Highlight> m_currentMouseDownOnButtonHighlight; 161 WebCore::IntPoint m_mousePosition; 162 163 WebCore::Timer<ServicesOverlayController> m_determineActiveHighlightTimer; 164}; 165 166} // namespace WebKit 167 168#endif // ENABLE(SERVICE_CONTROLS) && ENABLE(TELEPHONE_NUMBER_DETECTION) 169#endif // ServicesOverlayController_h 170