⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 185778 in webkit


Ignore:
Timestamp:
Jun 19, 2015, 4:40:32 PM (11 years ago)
Author:
timothy_horton@apple.com
Message:

Selection services cannot be invoked when force click is enabled
https://bugs.webkit.org/show_bug.cgi?id=146166
<rdar://problem/21468362>

Reviewed by Darin Adler.

  • page/mac/ServicesOverlayController.h:

Turn Highlight::Type into something we can use for dirty flags.

  • page/mac/ServicesOverlayController.mm:

(WebCore::ServicesOverlayController::Highlight::createForSelection):
(WebCore::ServicesOverlayController::Highlight::createForTelephoneNumber):
(WebCore::ServicesOverlayController::ServicesOverlayController):
(WebCore::ServicesOverlayController::selectionRectsDidChange):
(WebCore::ServicesOverlayController::selectedTelephoneNumberRangesChanged):
(WebCore::ServicesOverlayController::invalidateHighlightsOfType):
(WebCore::ServicesOverlayController::buildPotentialHighlightsIfNeeded):
(WebCore::ServicesOverlayController::remainingTimeUntilHighlightShouldBeShown):
(WebCore::ServicesOverlayController::buildPhoneNumberHighlights):
(WebCore::ServicesOverlayController::buildSelectionHighlight):
(WebCore::ServicesOverlayController::findTelephoneNumberHighlightContainingSelectionHighlight):
(WebCore::ServicesOverlayController::determineActiveHighlight):
(WebCore::ServicesOverlayController::didScrollFrame):
(WebCore::ServicesOverlayController::handleClick):
Coalesce highlight rebuilding so that things (like TextIndicator creation)
that change the selection and then reset it immediately don't cause us
to lose the active highlight.

This also means that if the selection changes multiple times in a runloop
(easily possible from script), we won't waste a lot of time rebuilding highlights.

(WebCore::ServicesOverlayController::didRebuildPotentialHighlights):
Merged into buildPotentialHighlightsIfNeeded.

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r185777 r185778  
     12015-06-19  Tim Horton  <timothy_horton@apple.com>
     2
     3        Selection services cannot be invoked when force click is enabled
     4        https://bugs.webkit.org/show_bug.cgi?id=146166
     5        <rdar://problem/21468362>
     6
     7        Reviewed by Darin Adler.
     8
     9        * page/mac/ServicesOverlayController.h:
     10        Turn Highlight::Type into something we can use for dirty flags.
     11
     12        * page/mac/ServicesOverlayController.mm:
     13        (WebCore::ServicesOverlayController::Highlight::createForSelection):
     14        (WebCore::ServicesOverlayController::Highlight::createForTelephoneNumber):
     15        (WebCore::ServicesOverlayController::ServicesOverlayController):
     16        (WebCore::ServicesOverlayController::selectionRectsDidChange):
     17        (WebCore::ServicesOverlayController::selectedTelephoneNumberRangesChanged):
     18        (WebCore::ServicesOverlayController::invalidateHighlightsOfType):
     19        (WebCore::ServicesOverlayController::buildPotentialHighlightsIfNeeded):
     20        (WebCore::ServicesOverlayController::remainingTimeUntilHighlightShouldBeShown):
     21        (WebCore::ServicesOverlayController::buildPhoneNumberHighlights):
     22        (WebCore::ServicesOverlayController::buildSelectionHighlight):
     23        (WebCore::ServicesOverlayController::findTelephoneNumberHighlightContainingSelectionHighlight):
     24        (WebCore::ServicesOverlayController::determineActiveHighlight):
     25        (WebCore::ServicesOverlayController::didScrollFrame):
     26        (WebCore::ServicesOverlayController::handleClick):
     27        Coalesce highlight rebuilding so that things (like TextIndicator creation)
     28        that change the selection and then reset it immediately don't cause us
     29        to lose the active highlight.
     30
     31        This also means that if the selection changes multiple times in a runloop
     32        (easily possible from script), we won't waste a lot of time rebuilding highlights.
     33
     34        (WebCore::ServicesOverlayController::didRebuildPotentialHighlights):
     35        Merged into buildPotentialHighlightsIfNeeded.
     36
    1372015-06-19  Matt Baker  <mattbaker@apple.com>
    238
  • trunk/Source/WebCore/page/mac/ServicesOverlayController.h

    r184066 r185778  
    6868        GraphicsLayer* layer() const { return m_graphicsLayer.get(); }
    6969
    70         enum class Type {
    71             TelephoneNumber,
    72             Selection
     70        enum {
     71            TelephoneNumberType = 1 << 0,
     72            SelectionType = 1 << 1,
    7373        };
     74        typedef uint8_t Type;
    7475        Type type() const { return m_type; }
    7576
     
    109110    void drawHighlight(Highlight&, GraphicsContext&);
    110111
     112    void invalidateHighlightsOfType(Highlight::Type);
     113    void buildPotentialHighlightsIfNeeded();
     114
    111115    void replaceHighlightsOfTypePreservingEquivalentHighlights(HashSet<RefPtr<Highlight>>&, Highlight::Type);
    112116    void removeAllPotentialHighlightsOfType(Highlight::Type);
    113117    void buildPhoneNumberHighlights();
    114118    void buildSelectionHighlight();
    115     void didRebuildPotentialHighlights();
    116119
    117120    void determineActiveHighlight(bool& mouseIsOverButton);
     
    138141
    139142    MainFrame& m_mainFrame;
    140     PageOverlay* m_servicesOverlay;
     143    PageOverlay* m_servicesOverlay { nullptr };
    141144
    142145    RefPtr<Highlight> m_activeHighlight;
     
    149152    // FIXME: These should move onto Highlight.
    150153    Vector<LayoutRect> m_currentSelectionRects;
    151     bool m_isTextOnly;
     154    bool m_isTextOnly { false };
     155
     156    Highlight::Type m_dirtyHighlightTypes { 0 };
    152157
    153158    std::chrono::steady_clock::time_point m_lastSelectionChangeTime;
     
    159164
    160165    Timer m_determineActiveHighlightTimer;
     166    Timer m_buildHighlightsTimer;
    161167};
    162168
  • trunk/Source/WebCore/page/mac/ServicesOverlayController.mm

    r184066 r185778  
    5858Ref<ServicesOverlayController::Highlight> ServicesOverlayController::Highlight::createForSelection(ServicesOverlayController& controller, RetainPtr<DDHighlightRef> ddHighlight, PassRefPtr<Range> range)
    5959{
    60     return adoptRef(*new Highlight(controller, Type::Selection, ddHighlight, range));
     60    return adoptRef(*new Highlight(controller, Highlight::SelectionType, ddHighlight, range));
    6161}
    6262
    6363Ref<ServicesOverlayController::Highlight> ServicesOverlayController::Highlight::createForTelephoneNumber(ServicesOverlayController& controller, RetainPtr<DDHighlightRef> ddHighlight, PassRefPtr<Range> range)
    6464{
    65     return adoptRef(*new Highlight(controller, Type::TelephoneNumber, ddHighlight, range));
     65    return adoptRef(*new Highlight(controller, Highlight::TelephoneNumberType, ddHighlight, range));
    6666}
    6767
     
    205205ServicesOverlayController::ServicesOverlayController(MainFrame& mainFrame)
    206206    : m_mainFrame(mainFrame)
    207     , m_servicesOverlay(nullptr)
    208     , m_isTextOnly(false)
    209207    , m_determineActiveHighlightTimer(*this, &ServicesOverlayController::determineActiveHighlightTimerFired)
     208    , m_buildHighlightsTimer(*this, &ServicesOverlayController::buildPotentialHighlightsIfNeeded)
    210209{
    211210}
     
    380379
    381380    LOG(Services, "ServicesOverlayController - Selection rects changed - Now have %lu\n", rects.size());
    382 
    383     buildSelectionHighlight();
     381    invalidateHighlightsOfType(Highlight::SelectionType);
    384382#else
    385383    UNUSED_PARAM(rects);
     
    393391#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED > 1090
    394392    LOG(Services, "ServicesOverlayController - Telephone number ranges changed\n");
    395     buildPhoneNumberHighlights();
     393    invalidateHighlightsOfType(Highlight::TelephoneNumberType);
    396394#endif
     395}
     396
     397void ServicesOverlayController::invalidateHighlightsOfType(Highlight::Type type)
     398{
     399    if (!m_mainFrame.settings().serviceControlsEnabled())
     400        return;
     401
     402    m_dirtyHighlightTypes |= type;
     403    m_buildHighlightsTimer.startOneShot(0);
     404}
     405
     406void ServicesOverlayController::buildPotentialHighlightsIfNeeded()
     407{
     408    if (!m_dirtyHighlightTypes)
     409        return;
     410
     411    if (m_dirtyHighlightTypes & Highlight::TelephoneNumberType)
     412        buildPhoneNumberHighlights();
     413
     414    if (m_dirtyHighlightTypes & Highlight::SelectionType)
     415        buildSelectionHighlight();
     416
     417    m_dirtyHighlightTypes = 0;
     418
     419    if (m_potentialHighlights.isEmpty()) {
     420        if (m_servicesOverlay)
     421            m_mainFrame.pageOverlayController().uninstallPageOverlay(m_servicesOverlay, PageOverlay::FadeMode::DoNotFade);
     422        return;
     423    }
     424
     425    if (telephoneNumberRangesForFocusedFrame().isEmpty() && !hasRelevantSelectionServices())
     426        return;
     427
     428    createOverlayIfNeeded();
     429
     430    bool mouseIsOverButton;
     431    determineActiveHighlight(mouseIsOverButton);
    397432}
    398433
     
    420455    // by virtue of being expanded to include the entire telephone number. However, we will still avoid highlighting
    421456    // telephone numbers while the mouse is down.
    422     if (highlight->type() == Highlight::Type::TelephoneNumber)
     457    if (highlight->type() == Highlight::TelephoneNumberType)
    423458        return mousePressed ? minimumTimeUntilHighlightShouldBeShown : 0_ms;
    424459
     
    466501void ServicesOverlayController::buildPhoneNumberHighlights()
    467502{
    468     if (!m_mainFrame.settings().serviceControlsEnabled())
    469         return;
    470 
    471503    Vector<RefPtr<Range>> phoneNumberRanges;
    472504    for (Frame* frame = &m_mainFrame; frame; frame = frame->tree().traverseNext())
     
    474506
    475507    if (phoneNumberRanges.isEmpty()) {
    476         removeAllPotentialHighlightsOfType(Highlight::Type::TelephoneNumber);
    477         didRebuildPotentialHighlights();
     508        removeAllPotentialHighlightsOfType(Highlight::TelephoneNumberType);
    478509        return;
    479510    }
     
    506537    }
    507538
    508     replaceHighlightsOfTypePreservingEquivalentHighlights(newPotentialHighlights, Highlight::Type::TelephoneNumber);
    509 
    510     didRebuildPotentialHighlights();
     539    replaceHighlightsOfTypePreservingEquivalentHighlights(newPotentialHighlights, Highlight::TelephoneNumberType);
    511540}
    512541
    513542void ServicesOverlayController::buildSelectionHighlight()
    514543{
    515     if (!m_mainFrame.settings().serviceControlsEnabled())
    516         return;
    517 
    518544    if (m_currentSelectionRects.isEmpty()) {
    519         removeAllPotentialHighlightsOfType(Highlight::Type::Selection);
    520         didRebuildPotentialHighlights();
     545        removeAllPotentialHighlightsOfType(Highlight::SelectionType);
    521546        return;
    522547    }
     
    556581    }
    557582
    558     replaceHighlightsOfTypePreservingEquivalentHighlights(newPotentialHighlights, Highlight::Type::Selection);
    559 
    560     didRebuildPotentialHighlights();
     583    replaceHighlightsOfTypePreservingEquivalentHighlights(newPotentialHighlights, Highlight::SelectionType);
    561584}
    562585
     
    596619}
    597620
    598 void ServicesOverlayController::didRebuildPotentialHighlights()
    599 {
    600     if (m_potentialHighlights.isEmpty()) {
    601         if (m_servicesOverlay)
    602             m_mainFrame.pageOverlayController().uninstallPageOverlay(m_servicesOverlay, PageOverlay::FadeMode::DoNotFade);
    603         return;
    604     }
    605 
    606     if (telephoneNumberRangesForFocusedFrame().isEmpty() && !hasRelevantSelectionServices())
    607         return;
    608 
    609     createOverlayIfNeeded();
    610 
    611     bool mouseIsOverButton;
    612     determineActiveHighlight(mouseIsOverButton);
    613 }
    614 
    615621void ServicesOverlayController::createOverlayIfNeeded()
    616622{
     
    651657ServicesOverlayController::Highlight* ServicesOverlayController::findTelephoneNumberHighlightContainingSelectionHighlight(Highlight& selectionHighlight)
    652658{
    653     if (selectionHighlight.type() != Highlight::Type::Selection)
     659    if (selectionHighlight.type() != Highlight::SelectionType)
    654660        return nullptr;
    655661
     
    667673
    668674    for (auto& highlight : m_potentialHighlights) {
    669         if (highlight->type() != Highlight::Type::TelephoneNumber)
     675        if (highlight->type() != Highlight::TelephoneNumberType)
    670676            continue;
    671677
     
    679685void ServicesOverlayController::determineActiveHighlight(bool& mouseIsOverActiveHighlightButton)
    680686{
     687    buildPotentialHighlightsIfNeeded();
     688
    681689    mouseIsOverActiveHighlightButton = false;
    682690
     
    684692
    685693    for (auto& highlight : m_potentialHighlights) {
    686         if (highlight->type() == Highlight::Type::Selection) {
     694        if (highlight->type() == Highlight::SelectionType) {
    687695            // If we've already found a new active highlight, and it's
    688696            // a telephone number highlight, prefer that over this selection highlight.
    689             if (newActiveHighlight && newActiveHighlight->type() == Highlight::Type::TelephoneNumber)
     697            if (newActiveHighlight && newActiveHighlight->type() == Highlight::TelephoneNumberType)
    690698                continue;
    691699
     
    706714    // If our new active highlight is a selection highlight that is completely contained
    707715    // by one of the phone number highlights, we'll make the phone number highlight active even if it's not hovered.
    708     if (newActiveHighlight && newActiveHighlight->type() == Highlight::Type::Selection) {
     716    if (newActiveHighlight && newActiveHighlight->type() == Highlight::SelectionType) {
    709717        if (Highlight* containedTelephoneNumberHighlight = findTelephoneNumberHighlightContainingSelectionHighlight(*newActiveHighlight)) {
    710718            newActiveHighlight = containedTelephoneNumberHighlight;
     
    802810        return;
    803811
    804     buildPhoneNumberHighlights();
    805     buildSelectionHighlight();
     812    invalidateHighlightsOfType(Highlight::TelephoneNumberType);
     813    invalidateHighlightsOfType(Highlight::SelectionType);
     814    buildPotentialHighlightsIfNeeded();
    806815
    807816    bool mouseIsOverActiveHighlightButton;
     
    821830    IntPoint windowPoint = frameView->contentsToWindow(clickPoint);
    822831
    823     if (highlight.type() == Highlight::Type::Selection) {
     832    if (highlight.type() == Highlight::SelectionType) {
    824833        auto telephoneNumberRanges = telephoneNumberRangesForFocusedFrame();
    825834        Vector<String> selectedTelephoneNumbers;
     
    829838
    830839        page->chrome().client().handleSelectionServiceClick(page->focusController().focusedOrMainFrame().selection(), selectedTelephoneNumbers, windowPoint);
    831     } else if (highlight.type() == Highlight::Type::TelephoneNumber)
     840    } else if (highlight.type() == Highlight::TelephoneNumberType)
    832841        page->chrome().client().handleTelephoneNumberClick(highlight.range()->text(), windowPoint);
    833842}
Note: See TracChangeset for help on using the changeset viewer.