void FindController::updateFindUIAfterPageScroll(bool found, const String& string, FindOptions options, unsigned maxMatchCount) { Frame* selectedFrame = frameWithSelection(m_webPage->corePage()); bool shouldShowOverlay = false; if (!found) { // Clear the selection. if (selectedFrame) selectedFrame->selection()->clear(); hideFindIndicator(); m_webPage->send(Messages::WebPageProxy::DidFailToFindString(string)); } else { shouldShowOverlay = options & FindOptionsShowOverlay; bool shouldShowHighlight = options & FindOptionsShowHighlight; unsigned matchCount = 1; if (shouldShowOverlay || shouldShowHighlight) { if (maxMatchCount == numeric_limits<unsigned>::max()) --maxMatchCount; matchCount = m_webPage->corePage()->markAllMatchesForText(string, core(options), shouldShowHighlight, maxMatchCount + 1); // Check if we have more matches than allowed. if (matchCount > maxMatchCount) { shouldShowOverlay = false; matchCount = static_cast<unsigned>(kWKMoreThanMaximumMatchCount); } } m_webPage->send(Messages::WebPageProxy::DidFindString(string, matchCount)); if (!(options & FindOptionsShowFindIndicator) || !updateFindIndicator(selectedFrame, shouldShowOverlay)) { // Either we shouldn't show the find indicator, or we couldn't update it. hideFindIndicator(); } } if (!shouldShowOverlay) { if (m_findPageOverlay) { // Get rid of the overlay. m_webPage->uninstallPageOverlay(m_findPageOverlay, false); } ASSERT(!m_findPageOverlay); } else { if (!m_findPageOverlay) { RefPtr<PageOverlay> findPageOverlay = PageOverlay::create(this); m_findPageOverlay = findPageOverlay.get(); m_webPage->installPageOverlay(findPageOverlay.release()); } else { // The page overlay needs to be repainted. m_findPageOverlay->setNeedsDisplay(); } } }
void FindController::deviceScaleFactorDidChange() { ASSERT(isShowingOverlay()); Frame* selectedFrame = frameWithSelection(m_webPage->corePage()); if (!selectedFrame) return; updateFindIndicator(selectedFrame, true, false); }
void FindController::redraw() { if (!m_isShowingFindIndicator) return; Frame* selectedFrame = frameWithSelection(m_webPage->corePage()); if (!selectedFrame) return; updateFindIndicator(*selectedFrame, isShowingOverlay(), false); }
void FindController::findString(const String& string, FindOptions options, unsigned maxMatchCount) { PluginView* pluginView = pluginViewForFrame(m_webPage->mainFrame()); WebCore::FindOptions coreOptions = core(options); // iOS will reveal the selection through a different mechanism, and // we need to avoid sending the non-painted selection change to the UI process // so that it does not clear the selection out from under us. #if PLATFORM(IOS) coreOptions = static_cast<FindOptions>(coreOptions | DoNotRevealSelection); #endif willFindString(); bool foundStringStartsAfterSelection = false; if (!pluginView) { if (Frame* selectedFrame = frameWithSelection(m_webPage->corePage())) { FrameSelection& fs = selectedFrame->selection(); if (fs.selectionBounds().isEmpty()) { m_findMatches.clear(); int indexForSelection; m_webPage->corePage()->findStringMatchingRanges(string, core(options), maxMatchCount, m_findMatches, indexForSelection); m_foundStringMatchIndex = indexForSelection; foundStringStartsAfterSelection = true; } } } bool found; if (pluginView) found = pluginView->findString(string, coreOptions, maxMatchCount); else found = m_webPage->corePage()->findString(string, coreOptions); if (found) { didFindString(); if (!foundStringStartsAfterSelection) { if (options & FindOptionsBackwards) m_foundStringMatchIndex--; else m_foundStringMatchIndex++; } } RefPtr<WebPage> protectedWebPage = m_webPage; m_webPage->drawingArea()->dispatchAfterEnsuringUpdatedScrollPosition([protectedWebPage, found, string, options, maxMatchCount] () { protectedWebPage->findController().updateFindUIAfterPageScroll(found, string, options, maxMatchCount); }); }
void FindController::findString(const String& string, FindDirection findDirection, FindOptions findOptions, unsigned maxNumMatches) { TextCaseSensitivity caseSensitivity = findOptions & FindOptionsCaseInsensitive ? TextCaseInsensitive : TextCaseSensitive; bool found = m_webPage->corePage()->findString(string, caseSensitivity, findDirection == FindDirectionForward ? WebCore::FindDirectionForward : WebCore::FindDirectionBackward, findOptions & FindOptionsWrapAround); Frame* selectedFrame = frameWithSelection(m_webPage->corePage()); bool shouldShowOverlay = false; if (!found) { // We didn't find the string, clear all text matches. m_webPage->corePage()->unmarkAllTextMatches(); // And clear the selection. if (selectedFrame) selectedFrame->selection()->clear(); } else { shouldShowOverlay = findOptions & FindOptionsShowOverlay; if (shouldShowOverlay) { unsigned numMatches = m_webPage->corePage()->markAllMatchesForText(string, caseSensitivity, false, maxNumMatches); // Check if we have more matches than allowed. if (numMatches > maxNumMatches) shouldShowOverlay = false; } } if (!shouldShowOverlay) { if (m_findPageOverlay) { // Get rid of the overlay. m_webPage->uninstallPageOverlay(); } ASSERT(!m_findPageOverlay); return; } if (!m_findPageOverlay) { OwnPtr<FindPageOverlay> findPageOverlay = FindPageOverlay::create(this); m_findPageOverlay = findPageOverlay.get(); m_webPage->installPageOverlay(findPageOverlay.release()); } else { // The page overlay needs to be repainted. m_findPageOverlay->setNeedsDisplay(); } }
void FindController::drawRect(PageOverlay* pageOverlay, GraphicsContext& graphicsContext, const IntRect& dirtyRect) { float fractionFadedIn = pageOverlay->fractionFadedIn(); Vector<IntRect> rects = rectsForTextMatches(); // Draw the background. graphicsContext.fillRect(dirtyRect, overlayBackgroundColor(fractionFadedIn), ColorSpaceSRGB); { GraphicsContextStateSaver stateSaver(graphicsContext); graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, holeShadowColor(fractionFadedIn), ColorSpaceSRGB); graphicsContext.setFillColor(holeFillColor(fractionFadedIn), ColorSpaceSRGB); // Draw white frames around the holes. for (size_t i = 0; i < rects.size(); ++i) { IntRect whiteFrameRect = rects[i]; whiteFrameRect.inflate(1); graphicsContext.fillRect(whiteFrameRect); } } graphicsContext.setFillColor(Color::transparent, ColorSpaceSRGB); // Clear out the holes. for (size_t i = 0; i < rects.size(); ++i) graphicsContext.fillRect(rects[i]); if (!m_isShowingFindIndicator) return; if (Frame* selectedFrame = frameWithSelection(m_webPage->corePage())) { IntRect findIndicatorRect = selectedFrame->view()->contentsToWindow(enclosingIntRect(selectedFrame->selection()->bounds())); if (findIndicatorRect != m_findIndicatorRect) hideFindIndicator(); } }
void FindController::drawRect(PageOverlay*, GraphicsContext& graphicsContext, const IntRect& dirtyRect) { Color overlayBackgroundColor(0.1f, 0.1f, 0.1f, 0.25f); Vector<IntRect> rects = rectsForTextMatches(); // Draw the background. graphicsContext.fillRect(dirtyRect, overlayBackgroundColor, ColorSpaceSRGB); { GraphicsContextStateSaver stateSaver(graphicsContext); #if ENABLE(LEGACY_FIND_INDICATOR_STYLE) graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, Color::black, ColorSpaceSRGB); #endif graphicsContext.setFillColor(Color::white, ColorSpaceSRGB); // Draw white frames around the holes. for (auto& rect : rects) { IntRect whiteFrameRect = rect; whiteFrameRect.inflate(1); graphicsContext.fillRect(whiteFrameRect); } } // Clear out the holes. for (auto& rect : rects) graphicsContext.clearRect(rect); if (!m_isShowingFindIndicator) return; if (Frame* selectedFrame = frameWithSelection(m_webPage->corePage())) { IntRect findIndicatorRect = selectedFrame->view()->contentsToWindow(enclosingIntRect(selectedFrame->selection().selectionBounds())); if (findIndicatorRect != m_findIndicatorRect) hideFindIndicator(); } }
void FindController::updateFindUIAfterPageScroll(bool found, const String& string, FindOptions options, unsigned maxMatchCount) { Frame* selectedFrame = frameWithSelection(m_webPage->corePage()); PluginView* pluginView = pluginViewForFrame(m_webPage->mainFrame()); bool shouldShowOverlay = false; if (!found) { if (!pluginView) m_webPage->corePage()->unmarkAllTextMatches(); if (selectedFrame) selectedFrame->selection().clear(); hideFindIndicator(); m_webPage->send(Messages::WebPageProxy::DidFailToFindString(string)); } else { shouldShowOverlay = options & FindOptionsShowOverlay; bool shouldShowHighlight = options & FindOptionsShowHighlight; unsigned matchCount = 1; if (shouldShowOverlay || shouldShowHighlight) { if (maxMatchCount == std::numeric_limits<unsigned>::max()) --maxMatchCount; if (pluginView) { matchCount = pluginView->countFindMatches(string, core(options), maxMatchCount + 1); shouldShowOverlay = false; } else { m_webPage->corePage()->unmarkAllTextMatches(); matchCount = m_webPage->corePage()->markAllMatchesForText(string, core(options), shouldShowHighlight, maxMatchCount + 1); } // If we have a large number of matches, we don't want to take the time to paint the overlay. if (matchCount > maxMatchCount) { shouldShowOverlay = false; matchCount = static_cast<unsigned>(kWKMoreThanMaximumMatchCount); } } m_webPage->send(Messages::WebPageProxy::DidFindString(string, matchCount)); if (!(options & FindOptionsShowFindIndicator) || !updateFindIndicator(selectedFrame, shouldShowOverlay)) hideFindIndicator(); } if (!shouldShowOverlay) { if (m_findPageOverlay) m_webPage->uninstallPageOverlay(m_findPageOverlay, true); } else { if (!m_findPageOverlay) { RefPtr<PageOverlay> findPageOverlay = PageOverlay::create(this); m_findPageOverlay = findPageOverlay.get(); m_webPage->installPageOverlay(findPageOverlay.release(), true); m_findPageOverlay->setNeedsDisplay(); } else m_findPageOverlay->setNeedsDisplay(); } }