165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch/*
265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Copyright (C) 2010 Apple Inc. All rights reserved.
365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *
465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Redistribution and use in source and binary forms, with or without
565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * modification, are permitted provided that the following conditions
665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * are met:
765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 1. Redistributions of source code must retain the above copyright
865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *    notice, this list of conditions and the following disclaimer.
965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 2. Redistributions in binary form must reproduce the above copyright
1065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *    notice, this list of conditions and the following disclaimer in the
1165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *    documentation and/or other materials provided with the distribution.
1265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *
1365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
1465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
1565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
1765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THE POSSIBILITY OF SUCH DAMAGE.
2465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch */
2565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "config.h"
2765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "FindController.h"
2865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "ShareableBitmap.h"
3065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "WKPage.h"
3165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "WebCoreArgumentCoders.h"
3265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "WebPage.h"
3365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "WebPageProxyMessages.h"
3465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "WebProcess.h"
3565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <WebCore/DocumentMarkerController.h>
3665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <WebCore/Frame.h>
3765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <WebCore/FrameView.h>
3865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <WebCore/GraphicsContext.h>
3965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <WebCore/Page.h>
4065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochusing namespace std;
4265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochusing namespace WebCore;
4365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochnamespace WebKit {
4565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic WebCore::FindOptions core(FindOptions options)
4765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
4865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return (options & FindOptionsCaseInsensitive ? CaseInsensitive : 0)
4965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        | (options & FindOptionsAtWordStarts ? AtWordStarts : 0)
5065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        | (options & FindOptionsTreatMedialCapitalAsWordStart ? TreatMedialCapitalAsWordStart : 0)
5165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        | (options & FindOptionsBackwards ? Backwards : 0)
5265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        | (options & FindOptionsWrapAround ? WrapAround : 0);
5365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
5465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben MurdochFindController::FindController(WebPage* webPage)
5665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    : m_webPage(webPage)
5765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    , m_findPageOverlay(0)
5865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    , m_isShowingFindIndicator(false)
5965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
6065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
6165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
6265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben MurdochFindController::~FindController()
6365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
6465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
6565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
6665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid FindController::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
6765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (maxMatchCount == numeric_limits<unsigned>::max())
692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        --maxMatchCount;
702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, core(options), false, maxMatchCount + 1);
7265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_webPage->corePage()->unmarkAllTextMatches();
7365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Check if we have more matches than allowed.
752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (matchCount > maxMatchCount)
762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        matchCount = static_cast<unsigned>(kWKMoreThanMaximumMatchCount);
772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
7865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_webPage->send(Messages::WebPageProxy::DidCountStringMatches(string, matchCount));
7965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
8065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
8165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic Frame* frameWithSelection(Page* page)
8265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
8365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
8465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (frame->selection()->isRange())
8565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return frame;
8665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
8765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
8865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return 0;
8965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
9065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
9165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid FindController::findString(const String& string, FindOptions options, unsigned maxMatchCount)
9265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
9365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_webPage->corePage()->unmarkAllTextMatches();
9465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
9565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool found = m_webPage->corePage()->findString(string, core(options));
9665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
9765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Frame* selectedFrame = frameWithSelection(m_webPage->corePage());
9865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
9965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool shouldShowOverlay = false;
10065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
10165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!found) {
10265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // Clear the selection.
10365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (selectedFrame)
10465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            selectedFrame->selection()->clear();
10565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
10665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        hideFindIndicator();
10765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
10865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        m_webPage->send(Messages::WebPageProxy::DidFailToFindString(string));
10965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    } else {
11065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        shouldShowOverlay = options & FindOptionsShowOverlay;
11165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
11265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (shouldShowOverlay) {
1132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (maxMatchCount == numeric_limits<unsigned>::max())
1142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                --maxMatchCount;
1152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
11665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, core(options), false, maxMatchCount + 1);
11765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
11865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            // Check if we have more matches than allowed.
11965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            if (matchCount > maxMatchCount) {
12065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                shouldShowOverlay = false;
12165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                matchCount = static_cast<unsigned>(kWKMoreThanMaximumMatchCount);
12265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            }
12365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
12465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            m_webPage->send(Messages::WebPageProxy::DidFindString(string, matchCount));
12565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
12665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
12765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!(options & FindOptionsShowFindIndicator) || !updateFindIndicator(selectedFrame, shouldShowOverlay)) {
12865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            // Either we shouldn't show the find indicator, or we couldn't update it.
12965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            hideFindIndicator();
13065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
13165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
13265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
13365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!shouldShowOverlay) {
13465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (m_findPageOverlay) {
13565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            // Get rid of the overlay.
1362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            m_webPage->uninstallPageOverlay(m_findPageOverlay, false);
13765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
13865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
13965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        ASSERT(!m_findPageOverlay);
14065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
14165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
14265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
14365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!m_findPageOverlay) {
14465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        RefPtr<PageOverlay> findPageOverlay = PageOverlay::create(this);
14565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        m_findPageOverlay = findPageOverlay.get();
14665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        m_webPage->installPageOverlay(findPageOverlay.release());
14765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    } else {
14865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // The page overlay needs to be repainted.
14965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        m_findPageOverlay->setNeedsDisplay();
15065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
15165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
15265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
15365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid FindController::hideFindUI()
15465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
15565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (m_findPageOverlay)
1562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_webPage->uninstallPageOverlay(m_findPageOverlay, true);
15765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
15865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    hideFindIndicator();
15965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
16065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
16165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochbool FindController::updateFindIndicator(Frame* selectedFrame, bool isShowingOverlay)
16265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
16365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!selectedFrame)
16465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
16565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
1662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    IntRect selectionRect = enclosingIntRect(selectedFrame->selection()->bounds());
1672bde8e466a4451c7319e3a072d118917957d6554Steve Block
1682bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Selection rect can be empty for matches that are currently obscured from view.
1692bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (selectionRect.isEmpty())
1702bde8e466a4451c7319e3a072d118917957d6554Steve Block        return false;
1712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
17265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // We want the selection rect in window coordinates.
1732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    IntRect selectionRectInWindowCoordinates = selectedFrame->view()->contentsToWindow(selectionRect);
17465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
17565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Vector<FloatRect> textRects;
17665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    selectedFrame->selection()->getClippedVisibleTextRectangles(textRects);
17765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
17865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // Create a backing store and paint the find indicator text into it.
1792bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<ShareableBitmap> findIndicatorTextBackingStore = ShareableBitmap::createShareable(selectionRect.size(), ShareableBitmap::SupportsAlpha);
1802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!findIndicatorTextBackingStore)
1812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return false;
1822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
18365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    OwnPtr<GraphicsContext> graphicsContext = findIndicatorTextBackingStore->createGraphicsContext();
18465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
1852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    IntRect paintRect = selectionRect;
1862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    paintRect.move(selectedFrame->view()->frameRect().x(), selectedFrame->view()->frameRect().y());
1872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    paintRect.move(-selectedFrame->view()->scrollOffset());
1882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    graphicsContext->translate(-paintRect.x(), -paintRect.y());
19065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    selectedFrame->view()->setPaintBehavior(PaintBehaviorSelectionOnly | PaintBehaviorForceBlackText | PaintBehaviorFlattenCompositingLayers);
19165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    selectedFrame->document()->updateLayout();
19265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
1932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    selectedFrame->view()->paint(graphicsContext.get(), paintRect);
19465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    selectedFrame->view()->setPaintBehavior(PaintBehaviorNormal);
19565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
1962bde8e466a4451c7319e3a072d118917957d6554Steve Block    ShareableBitmap::Handle handle;
19765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!findIndicatorTextBackingStore->createHandle(handle))
19865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
19965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
20065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // We want the text rects in selection rect coordinates.
20165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Vector<FloatRect> textRectsInSelectionRectCoordinates;
20265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
20365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    for (size_t i = 0; i < textRects.size(); ++i) {
20465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        IntRect textRectInSelectionRectCoordinates = selectedFrame->view()->contentsToWindow(enclosingIntRect(textRects[i]));
20565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        textRectInSelectionRectCoordinates.move(-selectionRectInWindowCoordinates.x(), -selectionRectInWindowCoordinates.y());
20665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
20765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        textRectsInSelectionRectCoordinates.append(textRectInSelectionRectCoordinates);
20865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
20965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
21065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_webPage->send(Messages::WebPageProxy::SetFindIndicator(selectionRectInWindowCoordinates, textRectsInSelectionRectCoordinates, handle, !isShowingOverlay));
21165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_isShowingFindIndicator = true;
21265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
21365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return true;
21465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
21565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
21665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid FindController::hideFindIndicator()
21765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
21865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!m_isShowingFindIndicator)
21965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
22065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2212bde8e466a4451c7319e3a072d118917957d6554Steve Block    ShareableBitmap::Handle handle;
22265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_webPage->send(Messages::WebPageProxy::SetFindIndicator(FloatRect(), Vector<FloatRect>(), handle, false));
22365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_isShowingFindIndicator = false;
22465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
22565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
22665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben MurdochVector<IntRect> FindController::rectsForTextMatches()
22765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
22865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Vector<IntRect> rects;
22965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
23065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    for (Frame* frame = m_webPage->corePage()->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
23165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        Document* document = frame->document();
23265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (!document)
23365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            continue;
23465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
23565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        IntRect visibleRect = frame->view()->visibleContentRect();
23665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        Vector<IntRect> frameRects = document->markers()->renderedRectsForMarkers(DocumentMarker::TextMatch);
23765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        IntPoint frameOffset(-frame->view()->scrollOffset().width(), -frame->view()->scrollOffset().height());
23865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        frameOffset = frame->view()->convertToContainingWindow(frameOffset);
23965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
24065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        for (Vector<IntRect>::iterator it = frameRects.begin(), end = frameRects.end(); it != end; ++it) {
24165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            it->intersect(visibleRect);
24265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            it->move(frameOffset.x(), frameOffset.y());
24365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            rects.append(*it);
24465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
24565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
24665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
24765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return rects;
24865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
24965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
25065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid FindController::pageOverlayDestroyed(PageOverlay*)
25165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
25265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
25365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
25465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid FindController::willMoveToWebPage(PageOverlay*, WebPage* webPage)
25565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
25665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (webPage)
25765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
25865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
25965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // The page overlay is moving away from the web page, reset it.
26065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    ASSERT(m_findPageOverlay);
26165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_findPageOverlay = 0;
26265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
26365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
26465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid FindController::didMoveToWebPage(PageOverlay*, WebPage*)
26565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
26665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
26765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
26865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic const float shadowOffsetX = 0.0;
26965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic const float shadowOffsetY = 1.0;
27065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic const float shadowBlurRadius = 2.0;
27165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic const float whiteFrameThickness = 1.0;
27265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const float overlayBackgroundRed = 0.1;
2742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const float overlayBackgroundGreen = 0.1;
2752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const float overlayBackgroundBlue = 0.1;
2762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic const float overlayBackgroundAlpha = 0.25;
2772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic Color overlayBackgroundColor(float fractionFadedIn)
2792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
2802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return Color(overlayBackgroundRed, overlayBackgroundGreen, overlayBackgroundBlue, overlayBackgroundAlpha * fractionFadedIn);
2812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
28265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic Color holeShadowColor(float fractionFadedIn)
28465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
2852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return Color(0.0f, 0.0f, 0.0f, fractionFadedIn);
28665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
28765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic Color holeFillColor(float fractionFadedIn)
28965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
2902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return Color(1.0f, 1.0f, 1.0f, fractionFadedIn);
2912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
2922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid FindController::drawRect(PageOverlay* pageOverlay, GraphicsContext& graphicsContext, const IntRect& dirtyRect)
2942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
2952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    float fractionFadedIn = pageOverlay->fractionFadedIn();
2962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
29765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Vector<IntRect> rects = rectsForTextMatches();
29865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
29965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // Draw the background.
3002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    graphicsContext.fillRect(dirtyRect, overlayBackgroundColor(fractionFadedIn), ColorSpaceSRGB);
30165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
30265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    graphicsContext.save();
3032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, holeShadowColor(fractionFadedIn), ColorSpaceSRGB);
30465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    graphicsContext.setFillColor(holeFillColor(fractionFadedIn), ColorSpaceSRGB);
30665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
30765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // Draw white frames around the holes.
30865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    for (size_t i = 0; i < rects.size(); ++i) {
30965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        IntRect whiteFrameRect = rects[i];
31065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        whiteFrameRect.inflate(1);
31165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
31265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        graphicsContext.fillRect(whiteFrameRect);
31365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
31465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
31565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    graphicsContext.restore();
31665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
31765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    graphicsContext.setFillColor(Color::transparent, ColorSpaceSRGB);
31865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
31965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // Clear out the holes.
32065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    for (size_t i = 0; i < rects.size(); ++i)
32165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        graphicsContext.fillRect(rects[i]);
32265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
32365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
32465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochbool FindController::mouseEvent(PageOverlay* pageOverlay, const WebMouseEvent& mouseEvent)
32565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
32665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // If we get a mouse down event inside the page overlay we should hide the find UI.
32765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (mouseEvent.type() == WebEvent::MouseDown) {
32865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // Dismiss the overlay.
32965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        hideFindUI();
33065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
33165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
33265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return false;
33365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
33465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
33565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} // namespace WebKit
336