Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(490)

Side by Side Diff: Source/web/WebFrameImpl.cpp

Issue 181013007: Introduce TextFinder class for decoupling WebFrameImpl and text finder. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@introduce-textfinder-class-new
Patch Set: Changed invalidateArea() function Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved. 2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 #include "config.h" 72 #include "config.h"
73 #include "WebFrameImpl.h" 73 #include "WebFrameImpl.h"
74 74
75 #include <algorithm> 75 #include <algorithm>
76 #include "AssociatedURLLoader.h" 76 #include "AssociatedURLLoader.h"
77 #include "EventListenerWrapper.h" 77 #include "EventListenerWrapper.h"
78 #include "FindInPageCoordinates.h" 78 #include "FindInPageCoordinates.h"
79 #include "HTMLNames.h" 79 #include "HTMLNames.h"
80 #include "PageOverlay.h" 80 #include "PageOverlay.h"
81 #include "SharedWorkerRepositoryClientImpl.h" 81 #include "SharedWorkerRepositoryClientImpl.h"
82 #include "TextFinder.h"
82 #include "WebConsoleMessage.h" 83 #include "WebConsoleMessage.h"
83 #include "WebDOMEvent.h" 84 #include "WebDOMEvent.h"
84 #include "WebDOMEventListener.h" 85 #include "WebDOMEventListener.h"
85 #include "WebDataSourceImpl.h" 86 #include "WebDataSourceImpl.h"
86 #include "WebDevToolsAgentPrivate.h" 87 #include "WebDevToolsAgentPrivate.h"
87 #include "WebDocument.h" 88 #include "WebDocument.h"
88 #include "WebFindOptions.h" 89 #include "WebFindOptions.h"
89 #include "WebFormElement.h" 90 #include "WebFormElement.h"
90 #include "WebFrameClient.h" 91 #include "WebFrameClient.h"
91 #include "WebHistoryItem.h" 92 #include "WebHistoryItem.h"
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 int m_pageCount; 443 int m_pageCount;
443 WebPrintParams m_printParams; 444 WebPrintParams m_printParams;
444 445
445 }; 446 };
446 447
447 static WebDataSource* DataSourceForDocLoader(DocumentLoader* loader) 448 static WebDataSource* DataSourceForDocLoader(DocumentLoader* loader)
448 { 449 {
449 return loader ? WebDataSourceImpl::fromDocumentLoader(loader) : 0; 450 return loader ? WebDataSourceImpl::fromDocumentLoader(loader) : 0;
450 } 451 }
451 452
452 WebFrameImpl::FindMatch::FindMatch(PassRefPtr<Range> range, int ordinal)
453 : m_range(range)
454 , m_ordinal(ordinal)
455 {
456 }
457
458 class WebFrameImpl::DeferredScopeStringMatches {
459 public:
460 DeferredScopeStringMatches(WebFrameImpl* webFrame, int identifier, const Web String& searchText, const WebFindOptions& options, bool reset)
461 : m_timer(this, &DeferredScopeStringMatches::doTimeout)
462 , m_webFrame(webFrame)
463 , m_identifier(identifier)
464 , m_searchText(searchText)
465 , m_options(options)
466 , m_reset(reset)
467 {
468 m_timer.startOneShot(0.0, FROM_HERE);
469 }
470
471 private:
472 void doTimeout(Timer<DeferredScopeStringMatches>*)
473 {
474 m_webFrame->callScopeStringMatches(this, m_identifier, m_searchText, m_o ptions, m_reset);
475 }
476
477 Timer<DeferredScopeStringMatches> m_timer;
478 RefPtr<WebFrameImpl> m_webFrame;
479 int m_identifier;
480 WebString m_searchText;
481 WebFindOptions m_options;
482 bool m_reset;
483 };
484
485 // WebFrame ------------------------------------------------------------------- 453 // WebFrame -------------------------------------------------------------------
486 454
487 int WebFrame::instanceCount() 455 int WebFrame::instanceCount()
488 { 456 {
489 return frameCount; 457 return frameCount;
490 } 458 }
491 459
492 WebLocalFrame* WebFrame::frameForCurrentContext() 460 WebLocalFrame* WebFrame::frameForCurrentContext()
493 { 461 {
494 v8::Handle<v8::Context> context = v8::Isolate::GetCurrent()->GetCurrentConte xt(); 462 v8::Handle<v8::Context> context = v8::Isolate::GetCurrent()->GetCurrentConte xt();
(...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 } 1428 }
1461 1429
1462 WebString WebFrameImpl::pageProperty(const WebString& propertyName, int pageInde x) 1430 WebString WebFrameImpl::pageProperty(const WebString& propertyName, int pageInde x)
1463 { 1431 {
1464 ASSERT(m_printContext); 1432 ASSERT(m_printContext);
1465 return m_printContext->pageProperty(frame(), propertyName.utf8().data(), pag eIndex); 1433 return m_printContext->pageProperty(frame(), propertyName.utf8().data(), pag eIndex);
1466 } 1434 }
1467 1435
1468 bool WebFrameImpl::find(int identifier, const WebString& searchText, const WebFi ndOptions& options, bool wrapWithinFrame, WebRect* selectionRect) 1436 bool WebFrameImpl::find(int identifier, const WebString& searchText, const WebFi ndOptions& options, bool wrapWithinFrame, WebRect* selectionRect)
1469 { 1437 {
1470 if (!frame() || !frame()->page()) 1438 return ensureTextFinder().find(identifier, searchText, options, wrapWithinFr ame, selectionRect);
1471 return false;
1472
1473 WebFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl();
1474
1475 if (!options.findNext)
1476 frame()->page()->unmarkAllTextMatches();
1477 else
1478 setMarkerActive(m_activeMatch.get(), false);
1479
1480 if (m_activeMatch && &m_activeMatch->ownerDocument() != frame()->document())
1481 m_activeMatch = nullptr;
1482
1483 // If the user has selected something since the last Find operation we want
1484 // to start from there. Otherwise, we start searching from where the last Fi nd
1485 // operation left off (either a Find or a FindNext operation).
1486 VisibleSelection selection(frame()->selection().selection());
1487 bool activeSelection = !selection.isNone();
1488 if (activeSelection) {
1489 m_activeMatch = selection.firstRange().get();
1490 frame()->selection().clear();
1491 }
1492
1493 ASSERT(frame() && frame()->view());
1494 const FindOptions findOptions = (options.forward ? 0 : Backwards)
1495 | (options.matchCase ? 0 : CaseInsensitive)
1496 | (wrapWithinFrame ? WrapAround : 0)
1497 | (options.wordStart ? AtWordStarts : 0)
1498 | (options.medialCapitalAsWordStart ? TreatMedialCapitalAsWordStart : 0)
1499 | (options.findNext ? 0 : StartInSelection);
1500 m_activeMatch = frame()->editor().findStringAndScrollToVisible(searchText, m _activeMatch.get(), findOptions);
1501
1502 if (!m_activeMatch) {
1503 // If we're finding next the next active match might not be in the curre nt frame.
1504 // In this case we don't want to clear the matches cache.
1505 if (!options.findNext)
1506 clearFindMatchesCache();
1507 invalidateArea(InvalidateAll);
1508 return false;
1509 }
1510
1511 #if OS(ANDROID)
1512 viewImpl()->zoomToFindInPageRect(frameView()->contentsToWindow(enclosingIntR ect(RenderObject::absoluteBoundingBoxRectForRange(m_activeMatch.get()))));
1513 #endif
1514
1515 setMarkerActive(m_activeMatch.get(), true);
1516 WebFrameImpl* oldActiveFrame = mainFrameImpl->m_currentActiveMatchFrame;
1517 mainFrameImpl->m_currentActiveMatchFrame = this;
1518
1519 // Make sure no node is focused. See http://crbug.com/38700.
1520 frame()->document()->setFocusedElement(nullptr);
1521
1522 if (!options.findNext || activeSelection) {
1523 // This is either a Find operation or a Find-next from a new start point
1524 // due to a selection, so we set the flag to ask the scoping effort
1525 // to find the active rect for us and report it back to the UI.
1526 m_locatingActiveRect = true;
1527 } else {
1528 if (oldActiveFrame != this) {
1529 if (options.forward)
1530 m_activeMatchIndexInCurrentFrame = 0;
1531 else
1532 m_activeMatchIndexInCurrentFrame = m_lastMatchCount - 1;
1533 } else {
1534 if (options.forward)
1535 ++m_activeMatchIndexInCurrentFrame;
1536 else
1537 --m_activeMatchIndexInCurrentFrame;
1538
1539 if (m_activeMatchIndexInCurrentFrame + 1 > m_lastMatchCount)
1540 m_activeMatchIndexInCurrentFrame = 0;
1541 if (m_activeMatchIndexInCurrentFrame == -1)
1542 m_activeMatchIndexInCurrentFrame = m_lastMatchCount - 1;
1543 }
1544 if (selectionRect) {
1545 *selectionRect = frameView()->contentsToWindow(m_activeMatch->boundi ngBox());
1546 reportFindInPageSelection(*selectionRect, m_activeMatchIndexInCurren tFrame + 1, identifier);
1547 }
1548 }
1549
1550 return true;
1551 } 1439 }
1552 1440
1553 void WebFrameImpl::stopFinding(bool clearSelection) 1441 void WebFrameImpl::stopFinding(bool clearSelection)
1554 { 1442 {
1555 if (!clearSelection) 1443 if (m_textFinder) {
1556 setFindEndstateFocusAndSelection(); 1444 if (!clearSelection)
1557 cancelPendingScopingEffort(); 1445 setFindEndstateFocusAndSelection();
1558 1446 m_textFinder->stopFindingAndClearSelection();
1559 // Remove all markers for matches found and turn off the highlighting. 1447 }
1560 frame()->document()->markers().removeMarkers(DocumentMarker::TextMatch);
1561 frame()->editor().setMarkedTextMatchesAreHighlighted(false);
1562 clearFindMatchesCache();
1563
1564 // Let the frame know that we don't want tickmarks or highlighting anymore.
1565 invalidateArea(InvalidateAll);
1566 } 1448 }
1567 1449
1568 void WebFrameImpl::scopeStringMatches(int identifier, const WebString& searchTex t, const WebFindOptions& options, bool reset) 1450 void WebFrameImpl::scopeStringMatches(int identifier, const WebString& searchTex t, const WebFindOptions& options, bool reset)
1569 { 1451 {
1570 if (reset) { 1452 ensureTextFinder().scopeStringMatches(identifier, searchText, options, reset );
1571 // This is a brand new search, so we need to reset everything.
1572 // Scoping is just about to begin.
1573 m_scopingInProgress = true;
1574
1575 // Need to keep the current identifier locally in order to finish the
1576 // request in case the frame is detached during the process.
1577 m_findRequestIdentifier = identifier;
1578
1579 // Clear highlighting for this frame.
1580 if (frame() && frame()->page() && frame()->editor().markedTextMatchesAre Highlighted())
1581 frame()->page()->unmarkAllTextMatches();
1582
1583 // Clear the tickmarks and results cache.
1584 clearFindMatchesCache();
1585
1586 // Clear the counters from last operation.
1587 m_lastMatchCount = 0;
1588 m_nextInvalidateAfter = 0;
1589
1590 m_resumeScopingFromRange = nullptr;
1591
1592 // The view might be null on detached frames.
1593 if (frame() && frame()->page())
1594 viewImpl()->mainFrameImpl()->m_framesScopingCount++;
1595
1596 // Now, defer scoping until later to allow find operation to finish quic kly.
1597 scopeStringMatchesSoon(identifier, searchText, options, false); // false means just reset, so don't do it again.
1598 return;
1599 }
1600
1601 if (!shouldScopeMatches(searchText)) {
1602 // Note that we want to defer the final update when resetting even if sh ouldScopeMatches returns false.
1603 // This is done in order to prevent sending a final message based only o n the results of the first frame
1604 // since m_framesScopingCount would be 0 as other frames have yet to res et.
1605 finishCurrentScopingEffort(identifier);
1606 return;
1607 }
1608
1609 WebFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl();
1610 RefPtr<Range> searchRange(rangeOfContents(frame()->document()));
1611
1612 Node* originalEndContainer = searchRange->endContainer();
1613 int originalEndOffset = searchRange->endOffset();
1614
1615 TrackExceptionState exceptionState, exceptionState2;
1616 if (m_resumeScopingFromRange) {
1617 // This is a continuation of a scoping operation that timed out and didn 't
1618 // complete last time around, so we should start from where we left off.
1619 searchRange->setStart(m_resumeScopingFromRange->startContainer(), m_resu meScopingFromRange->startOffset(exceptionState2) + 1, exceptionState);
1620 if (exceptionState.hadException() || exceptionState2.hadException()) {
1621 if (exceptionState2.hadException()) // A non-zero |exceptionState| h appens when navigating during search.
1622 ASSERT_NOT_REACHED();
1623 return;
1624 }
1625 }
1626
1627 // This timeout controls how long we scope before releasing control. This
1628 // value does not prevent us from running for longer than this, but it is
1629 // periodically checked to see if we have exceeded our allocated time.
1630 const double maxScopingDuration = 0.1; // seconds
1631
1632 int matchCount = 0;
1633 bool timedOut = false;
1634 double startTime = currentTime();
1635 do {
1636 // Find next occurrence of the search string.
1637 // FIXME: (http://b/1088245) This WebKit operation may run for longer
1638 // than the timeout value, and is not interruptible as it is currently
1639 // written. We may need to rewrite it with interruptibility in mind, or
1640 // find an alternative.
1641 RefPtr<Range> resultRange(findPlainText(searchRange.get(),
1642 searchText,
1643 options.matchCase ? 0 : CaseInse nsitive));
1644 if (resultRange->collapsed(exceptionState)) {
1645 if (!resultRange->startContainer()->isInShadowTree())
1646 break;
1647
1648 searchRange->setStartAfter(
1649 resultRange->startContainer()->deprecatedShadowAncestorNode(), e xceptionState);
1650 searchRange->setEnd(originalEndContainer, originalEndOffset, excepti onState);
1651 continue;
1652 }
1653
1654 ++matchCount;
1655
1656 // Catch a special case where Find found something but doesn't know what
1657 // the bounding box for it is. In this case we set the first match we fi nd
1658 // as the active rect.
1659 IntRect resultBounds = resultRange->boundingBox();
1660 IntRect activeSelectionRect;
1661 if (m_locatingActiveRect) {
1662 activeSelectionRect = m_activeMatch.get() ?
1663 m_activeMatch->boundingBox() : resultBounds;
1664 }
1665
1666 // If the Find function found a match it will have stored where the
1667 // match was found in m_activeSelectionRect on the current frame. If we
1668 // find this rect during scoping it means we have found the active
1669 // tickmark.
1670 bool foundActiveMatch = false;
1671 if (m_locatingActiveRect && (activeSelectionRect == resultBounds)) {
1672 // We have found the active tickmark frame.
1673 mainFrameImpl->m_currentActiveMatchFrame = this;
1674 foundActiveMatch = true;
1675 // We also know which tickmark is active now.
1676 m_activeMatchIndexInCurrentFrame = matchCount - 1;
1677 // To stop looking for the active tickmark, we set this flag.
1678 m_locatingActiveRect = false;
1679
1680 // Notify browser of new location for the selected rectangle.
1681 reportFindInPageSelection(
1682 frameView()->contentsToWindow(resultBounds),
1683 m_activeMatchIndexInCurrentFrame + 1,
1684 identifier);
1685 }
1686
1687 addMarker(resultRange.get(), foundActiveMatch);
1688
1689 m_findMatchesCache.append(FindMatch(resultRange.get(), m_lastMatchCount + matchCount));
1690
1691 // Set the new start for the search range to be the end of the previous
1692 // result range. There is no need to use a VisiblePosition here,
1693 // since findPlainText will use a TextIterator to go over the visible
1694 // text nodes.
1695 searchRange->setStart(resultRange->endContainer(exceptionState), resultR ange->endOffset(exceptionState), exceptionState);
1696
1697 Node* shadowTreeRoot = searchRange->shadowRoot();
1698 if (searchRange->collapsed(exceptionState) && shadowTreeRoot)
1699 searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->countChildren(), exceptionState);
1700
1701 m_resumeScopingFromRange = resultRange;
1702 timedOut = (currentTime() - startTime) >= maxScopingDuration;
1703 } while (!timedOut);
1704
1705 // Remember what we search for last time, so we can skip searching if more
1706 // letters are added to the search string (and last outcome was 0).
1707 m_lastSearchString = searchText;
1708
1709 if (matchCount > 0) {
1710 frame()->editor().setMarkedTextMatchesAreHighlighted(true);
1711
1712 m_lastMatchCount += matchCount;
1713
1714 // Let the mainframe know how much we found during this pass.
1715 mainFrameImpl->increaseMatchCount(matchCount, identifier);
1716 }
1717
1718 if (timedOut) {
1719 // If we found anything during this pass, we should redraw. However, we
1720 // don't want to spam too much if the page is extremely long, so if we
1721 // reach a certain point we start throttling the redraw requests.
1722 if (matchCount > 0)
1723 invalidateIfNecessary();
1724
1725 // Scoping effort ran out of time, lets ask for another time-slice.
1726 scopeStringMatchesSoon(
1727 identifier,
1728 searchText,
1729 options,
1730 false); // don't reset.
1731 return; // Done for now, resume work later.
1732 }
1733
1734 finishCurrentScopingEffort(identifier);
1735 }
1736
1737 void WebFrameImpl::flushCurrentScopingEffort(int identifier)
1738 {
1739 if (!frame() || !frame()->page())
1740 return;
1741
1742 WebFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl();
1743
1744 // This frame has no further scoping left, so it is done. Other frames might ,
1745 // of course, continue to scope matches.
1746 mainFrameImpl->m_framesScopingCount--;
1747
1748 // If this is the last frame to finish scoping we need to trigger the final
1749 // update to be sent.
1750 if (!mainFrameImpl->m_framesScopingCount)
1751 mainFrameImpl->increaseMatchCount(0, identifier);
1752 }
1753
1754 void WebFrameImpl::finishCurrentScopingEffort(int identifier)
1755 {
1756 flushCurrentScopingEffort(identifier);
1757
1758 m_scopingInProgress = false;
1759 m_lastFindRequestCompletedWithNoMatches = !m_lastMatchCount;
1760
1761 // This frame is done, so show any scrollbar tickmarks we haven't drawn yet.
1762 invalidateArea(InvalidateScrollbar);
1763 } 1453 }
1764 1454
1765 void WebFrameImpl::cancelPendingScopingEffort() 1455 void WebFrameImpl::cancelPendingScopingEffort()
1766 { 1456 {
1767 deleteAllValues(m_deferredScopingWork); 1457 if (m_textFinder)
1768 m_deferredScopingWork.clear(); 1458 m_textFinder->cancelPendingScopingEffort();
1769
1770 m_activeMatchIndexInCurrentFrame = -1;
1771
1772 // Last request didn't complete.
1773 if (m_scopingInProgress)
1774 m_lastFindRequestCompletedWithNoMatches = false;
1775
1776 m_scopingInProgress = false;
1777 } 1459 }
1778 1460
1779 void WebFrameImpl::increaseMatchCount(int count, int identifier) 1461 void WebFrameImpl::increaseMatchCount(int count, int identifier)
1780 { 1462 {
1781 // This function should only be called on the mainframe. 1463 // This function should only be called on the mainframe.
1782 ASSERT(!parent()); 1464 ASSERT(!parent());
1783 1465 ASSERT(m_textFinder);
1784 if (count) 1466 m_textFinder->increaseMatchCount(identifier, count);
1785 ++m_findMatchMarkersVersion;
1786
1787 m_totalMatchCount += count;
1788
1789 // Update the UI with the latest findings.
1790 if (client())
1791 client()->reportFindInPageMatchCount(identifier, m_totalMatchCount, !m_f ramesScopingCount);
1792 }
1793
1794 void WebFrameImpl::reportFindInPageSelection(const WebRect& selectionRect, int a ctiveMatchOrdinal, int identifier)
1795 {
1796 // Update the UI with the latest selection rect.
1797 if (client())
1798 client()->reportFindInPageSelection(identifier, ordinalOfFirstMatchForFr ame(this) + activeMatchOrdinal, selectionRect);
1799 } 1467 }
1800 1468
1801 void WebFrameImpl::resetMatchCount() 1469 void WebFrameImpl::resetMatchCount()
1802 { 1470 {
1803 if (m_totalMatchCount > 0) 1471 ASSERT(m_textFinder);
1804 ++m_findMatchMarkersVersion; 1472 m_textFinder->resetMatchCount();
1805
1806 m_totalMatchCount = 0;
1807 m_framesScopingCount = 0;
1808 } 1473 }
1809 1474
1810 void WebFrameImpl::sendOrientationChangeEvent(int orientation) 1475 void WebFrameImpl::sendOrientationChangeEvent(int orientation)
1811 { 1476 {
1812 if (frame()) 1477 if (frame())
1813 frame()->sendOrientationChangeEvent(orientation); 1478 frame()->sendOrientationChangeEvent(orientation);
1814 } 1479 }
1815 1480
1816 void WebFrameImpl::dispatchMessageEventWithOriginCheck(const WebSecurityOrigin& intendedTargetOrigin, const WebDOMEvent& event) 1481 void WebFrameImpl::dispatchMessageEventWithOriginCheck(const WebSecurityOrigin& intendedTargetOrigin, const WebDOMEvent& event)
1817 { 1482 {
1818 ASSERT(!event.isNull()); 1483 ASSERT(!event.isNull());
1819 frame()->domWindow()->dispatchMessageEventWithOriginCheck(intendedTargetOrig in.get(), event, nullptr); 1484 frame()->domWindow()->dispatchMessageEventWithOriginCheck(intendedTargetOrig in.get(), event, nullptr);
1820 } 1485 }
1821 1486
1822 int WebFrameImpl::findMatchMarkersVersion() const 1487 int WebFrameImpl::findMatchMarkersVersion() const
1823 { 1488 {
1824 ASSERT(!parent()); 1489 ASSERT(!parent());
1825 return m_findMatchMarkersVersion; 1490
1491 if (m_textFinder)
1492 return m_textFinder->findMatchMarkersVersion();
1493 return 0;
1826 } 1494 }
1827 1495
1828 void WebFrameImpl::clearFindMatchesCache() 1496 int WebFrameImpl::selectNearestFindMatch(const WebFloatPoint& point, WebRect* se lectionRect)
1829 { 1497 {
1830 if (!m_findMatchesCache.isEmpty()) 1498 ASSERT(!parent());
1831 viewImpl()->mainFrameImpl()->m_findMatchMarkersVersion++; 1499 ASSERT(m_textFinder);
1832 1500 return m_textFinder->selectNearestFindMatch(point, selectionRect);
1833 m_findMatchesCache.clear();
1834 m_findMatchRectsAreValid = false;
1835 }
1836
1837 bool WebFrameImpl::isActiveMatchFrameValid() const
1838 {
1839 WebFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl();
1840 WebFrameImpl* activeMatchFrame = mainFrameImpl->activeMatchFrame();
1841 return activeMatchFrame && activeMatchFrame->m_activeMatch && activeMatchFra me->frame()->tree().isDescendantOf(mainFrameImpl->frame());
1842 }
1843
1844 void WebFrameImpl::updateFindMatchRects()
1845 {
1846 IntSize currentContentsSize = contentsSize();
1847 if (m_contentsSizeForCurrentFindMatchRects != currentContentsSize) {
1848 m_contentsSizeForCurrentFindMatchRects = currentContentsSize;
1849 m_findMatchRectsAreValid = false;
1850 }
1851
1852 size_t deadMatches = 0;
1853 for (Vector<FindMatch>::iterator it = m_findMatchesCache.begin(); it != m_fi ndMatchesCache.end(); ++it) {
1854 if (!it->m_range->boundaryPointsValid() || !it->m_range->startContainer( )->inDocument())
1855 it->m_rect = FloatRect();
1856 else if (!m_findMatchRectsAreValid)
1857 it->m_rect = findInPageRectFromRange(it->m_range.get());
1858
1859 if (it->m_rect.isEmpty())
1860 ++deadMatches;
1861 }
1862
1863 // Remove any invalid matches from the cache.
1864 if (deadMatches) {
1865 Vector<FindMatch> filteredMatches;
1866 filteredMatches.reserveCapacity(m_findMatchesCache.size() - deadMatches) ;
1867
1868 for (Vector<FindMatch>::const_iterator it = m_findMatchesCache.begin(); it != m_findMatchesCache.end(); ++it)
1869 if (!it->m_rect.isEmpty())
1870 filteredMatches.append(*it);
1871
1872 m_findMatchesCache.swap(filteredMatches);
1873 }
1874
1875 // Invalidate the rects in child frames. Will be updated later during traver sal.
1876 if (!m_findMatchRectsAreValid)
1877 for (WebFrame* child = firstChild(); child; child = child->nextSibling() )
1878 toWebFrameImpl(child)->m_findMatchRectsAreValid = false;
1879
1880 m_findMatchRectsAreValid = true;
1881 } 1501 }
1882 1502
1883 WebFloatRect WebFrameImpl::activeFindMatchRect() 1503 WebFloatRect WebFrameImpl::activeFindMatchRect()
1884 { 1504 {
1885 ASSERT(!parent()); 1505 ASSERT(!parent());
1886 1506
1887 if (!isActiveMatchFrameValid()) 1507 if (m_textFinder)
1888 return WebFloatRect(); 1508 return m_textFinder->activeFindMatchRect();
1889 1509 return WebFloatRect();
1890 return WebFloatRect(findInPageRectFromRange(m_currentActiveMatchFrame->m_act iveMatch.get()));
1891 } 1510 }
1892 1511
1893 void WebFrameImpl::findMatchRects(WebVector<WebFloatRect>& outputRects) 1512 void WebFrameImpl::findMatchRects(WebVector<WebFloatRect>& outputRects)
1894 { 1513 {
1895 ASSERT(!parent()); 1514 ASSERT(!parent());
1896 1515 ASSERT(m_textFinder);
1897 Vector<WebFloatRect> matchRects; 1516 m_textFinder->findMatchRects(outputRects);
1898 for (WebFrameImpl* frame = this; frame; frame = toWebFrameImpl(frame->traver seNext(false)))
1899 frame->appendFindMatchRects(matchRects);
1900
1901 outputRects = matchRects;
1902 }
1903
1904 void WebFrameImpl::appendFindMatchRects(Vector<WebFloatRect>& frameRects)
1905 {
1906 updateFindMatchRects();
1907 frameRects.reserveCapacity(frameRects.size() + m_findMatchesCache.size());
1908 for (Vector<FindMatch>::const_iterator it = m_findMatchesCache.begin(); it ! = m_findMatchesCache.end(); ++it) {
1909 ASSERT(!it->m_rect.isEmpty());
1910 frameRects.append(it->m_rect);
1911 }
1912 }
1913
1914 int WebFrameImpl::selectNearestFindMatch(const WebFloatPoint& point, WebRect* se lectionRect)
1915 {
1916 ASSERT(!parent());
1917
1918 WebFrameImpl* bestFrame = 0;
1919 int indexInBestFrame = -1;
1920 float distanceInBestFrame = FLT_MAX;
1921
1922 for (WebFrameImpl* frame = this; frame; frame = toWebFrameImpl(frame->traver seNext(false))) {
1923 float distanceInFrame;
1924 int indexInFrame = frame->nearestFindMatch(point, distanceInFrame);
1925 if (distanceInFrame < distanceInBestFrame) {
1926 bestFrame = frame;
1927 indexInBestFrame = indexInFrame;
1928 distanceInBestFrame = distanceInFrame;
1929 }
1930 }
1931
1932 if (indexInBestFrame != -1)
1933 return bestFrame->selectFindMatch(static_cast<unsigned>(indexInBestFrame ), selectionRect);
1934
1935 return -1;
1936 } 1517 }
1937 1518
1938 void WebFrameImpl::setTickmarks(const WebVector<WebRect>& tickmarks) 1519 void WebFrameImpl::setTickmarks(const WebVector<WebRect>& tickmarks)
1939 { 1520 {
1940 if (frameView()) { 1521 if (frameView()) {
1941 Vector<IntRect> tickmarksConverted(tickmarks.size()); 1522 Vector<IntRect> tickmarksConverted(tickmarks.size());
1942 for (size_t i = 0; i < tickmarks.size(); ++i) 1523 for (size_t i = 0; i < tickmarks.size(); ++i)
1943 tickmarksConverted[i] = tickmarks[i]; 1524 tickmarksConverted[i] = tickmarks[i];
1944 frameView()->setTickmarks(tickmarksConverted); 1525 frameView()->setTickmarks(tickmarksConverted);
1945 invalidateArea(InvalidateScrollbar); 1526 invalidateScrollbar();
1946 } 1527 }
1947 } 1528 }
1948 1529
1949 int WebFrameImpl::nearestFindMatch(const FloatPoint& point, float& distanceSquar ed)
1950 {
1951 updateFindMatchRects();
1952
1953 int nearest = -1;
1954 distanceSquared = FLT_MAX;
1955 for (size_t i = 0; i < m_findMatchesCache.size(); ++i) {
1956 ASSERT(!m_findMatchesCache[i].m_rect.isEmpty());
1957 FloatSize offset = point - m_findMatchesCache[i].m_rect.center();
1958 float width = offset.width();
1959 float height = offset.height();
1960 float currentDistanceSquared = width * width + height * height;
1961 if (currentDistanceSquared < distanceSquared) {
1962 nearest = i;
1963 distanceSquared = currentDistanceSquared;
1964 }
1965 }
1966 return nearest;
1967 }
1968
1969 int WebFrameImpl::selectFindMatch(unsigned index, WebRect* selectionRect)
1970 {
1971 ASSERT_WITH_SECURITY_IMPLICATION(index < m_findMatchesCache.size());
1972
1973 RefPtr<Range> range = m_findMatchesCache[index].m_range;
1974 if (!range->boundaryPointsValid() || !range->startContainer()->inDocument())
1975 return -1;
1976
1977 // Check if the match is already selected.
1978 WebFrameImpl* activeMatchFrame = viewImpl()->mainFrameImpl()->m_currentActiv eMatchFrame;
1979 if (this != activeMatchFrame || !m_activeMatch || !areRangesEqual(m_activeMa tch.get(), range.get())) {
1980 if (isActiveMatchFrameValid())
1981 activeMatchFrame->setMarkerActive(activeMatchFrame->m_activeMatch.ge t(), false);
1982
1983 m_activeMatchIndexInCurrentFrame = m_findMatchesCache[index].m_ordinal - 1;
1984
1985 // Set this frame as the active frame (the one with the active highlight ).
1986 viewImpl()->mainFrameImpl()->m_currentActiveMatchFrame = this;
1987 viewImpl()->setFocusedFrame(this);
1988
1989 m_activeMatch = range.release();
1990 setMarkerActive(m_activeMatch.get(), true);
1991
1992 // Clear any user selection, to make sure Find Next continues on from th e match we just activated.
1993 frame()->selection().clear();
1994
1995 // Make sure no node is focused. See http://crbug.com/38700.
1996 frame()->document()->setFocusedElement(nullptr);
1997 }
1998
1999 IntRect activeMatchRect;
2000 IntRect activeMatchBoundingBox = enclosingIntRect(RenderObject::absoluteBoun dingBoxRectForRange(m_activeMatch.get()));
2001
2002 if (!activeMatchBoundingBox.isEmpty()) {
2003 if (m_activeMatch->firstNode() && m_activeMatch->firstNode()->renderer() )
2004 m_activeMatch->firstNode()->renderer()->scrollRectToVisible(activeMa tchBoundingBox,
2005 ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::align CenterIfNeeded);
2006
2007 // Zoom to the active match.
2008 activeMatchRect = frameView()->contentsToWindow(activeMatchBoundingBox);
2009 viewImpl()->zoomToFindInPageRect(activeMatchRect);
2010 }
2011
2012 if (selectionRect)
2013 *selectionRect = activeMatchRect;
2014
2015 return ordinalOfFirstMatchForFrame(this) + m_activeMatchIndexInCurrentFrame + 1;
2016 }
2017
2018 WebString WebFrameImpl::contentAsText(size_t maxChars) const 1530 WebString WebFrameImpl::contentAsText(size_t maxChars) const
2019 { 1531 {
2020 if (!frame()) 1532 if (!frame())
2021 return WebString(); 1533 return WebString();
2022 StringBuilder text; 1534 StringBuilder text;
2023 frameContentAsPlainText(maxChars, frame(), text); 1535 frameContentAsPlainText(maxChars, frame(), text);
2024 return text.toString(); 1536 return text.toString();
2025 } 1537 }
2026 1538
2027 WebString WebFrameImpl::contentAsMarkup() const 1539 WebString WebFrameImpl::contentAsMarkup() const
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2094 WebFrameImpl::WebFrameImpl(WebFrameClient* client) 1606 WebFrameImpl::WebFrameImpl(WebFrameClient* client)
2095 : m_frameLoaderClientImpl(this) 1607 : m_frameLoaderClientImpl(this)
2096 , m_parent(0) 1608 , m_parent(0)
2097 , m_previousSibling(0) 1609 , m_previousSibling(0)
2098 , m_nextSibling(0) 1610 , m_nextSibling(0)
2099 , m_firstChild(0) 1611 , m_firstChild(0)
2100 , m_lastChild(0) 1612 , m_lastChild(0)
2101 , m_opener(0) 1613 , m_opener(0)
2102 , m_client(client) 1614 , m_client(client)
2103 , m_permissionClient(0) 1615 , m_permissionClient(0)
2104 , m_currentActiveMatchFrame(0)
2105 , m_activeMatchIndexInCurrentFrame(-1)
2106 , m_locatingActiveRect(false)
2107 , m_resumeScopingFromRange(nullptr)
2108 , m_lastMatchCount(-1)
2109 , m_totalMatchCount(-1)
2110 , m_framesScopingCount(-1)
2111 , m_findRequestIdentifier(-1)
2112 , m_scopingInProgress(false)
2113 , m_lastFindRequestCompletedWithNoMatches(false)
2114 , m_nextInvalidateAfter(0)
2115 , m_findMatchMarkersVersion(0)
2116 , m_findMatchRectsAreValid(false)
2117 , m_inputEventsScaleFactorForEmulation(1) 1616 , m_inputEventsScaleFactorForEmulation(1)
2118 { 1617 {
2119 blink::Platform::current()->incrementStatsCounter(webFrameActiveCount); 1618 blink::Platform::current()->incrementStatsCounter(webFrameActiveCount);
2120 frameCount++; 1619 frameCount++;
2121 } 1620 }
2122 1621
2123 WebFrameImpl::~WebFrameImpl() 1622 WebFrameImpl::~WebFrameImpl()
2124 { 1623 {
2125 HashSet<WebFrameImpl*>::iterator end = m_openedFrames.end(); 1624 HashSet<WebFrameImpl*>::iterator end = m_openedFrames.end();
2126 for (HashSet<WebFrameImpl*>::iterator it = m_openedFrames.begin(); it != end ; ++it) 1625 for (HashSet<WebFrameImpl*>::iterator it = m_openedFrames.begin(); it != end ; ++it)
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2190 // NOTE: m_client will be null if this frame has been detached. 1689 // NOTE: m_client will be null if this frame has been detached.
2191 if (!childFrame->tree().parent()) 1690 if (!childFrame->tree().parent())
2192 return nullptr; 1691 return nullptr;
2193 1692
2194 return childFrame.release(); 1693 return childFrame.release();
2195 } 1694 }
2196 1695
2197 void WebFrameImpl::didChangeContentsSize(const IntSize& size) 1696 void WebFrameImpl::didChangeContentsSize(const IntSize& size)
2198 { 1697 {
2199 // This is only possible on the main frame. 1698 // This is only possible on the main frame.
2200 if (m_totalMatchCount > 0) { 1699 if (m_textFinder && m_textFinder->totalMatchCount() > 0) {
2201 ASSERT(!parent()); 1700 ASSERT(!parent());
2202 ++m_findMatchMarkersVersion; 1701 m_textFinder->increaseMarkerVersion();
2203 } 1702 }
2204 } 1703 }
2205 1704
2206 void WebFrameImpl::createFrameView() 1705 void WebFrameImpl::createFrameView()
2207 { 1706 {
2208 TRACE_EVENT0("webkit", "WebFrameImpl::createFrameView"); 1707 TRACE_EVENT0("webkit", "WebFrameImpl::createFrameView");
2209 1708
2210 ASSERT(frame()); // If frame() doesn't exist, we probably didn't init proper ly. 1709 ASSERT(frame()); // If frame() doesn't exist, we probably didn't init proper ly.
2211 1710
2212 WebViewImpl* webView = viewImpl(); 1711 WebViewImpl* webView = viewImpl();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2256 1755
2257 WebDataSourceImpl* WebFrameImpl::provisionalDataSourceImpl() const 1756 WebDataSourceImpl* WebFrameImpl::provisionalDataSourceImpl() const
2258 { 1757 {
2259 return static_cast<WebDataSourceImpl*>(provisionalDataSource()); 1758 return static_cast<WebDataSourceImpl*>(provisionalDataSource());
2260 } 1759 }
2261 1760
2262 void WebFrameImpl::setFindEndstateFocusAndSelection() 1761 void WebFrameImpl::setFindEndstateFocusAndSelection()
2263 { 1762 {
2264 WebFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl(); 1763 WebFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl();
2265 1764
2266 if (this == mainFrameImpl->activeMatchFrame() && m_activeMatch.get()) { 1765 if (this != mainFrameImpl->activeMatchFrame())
1766 return;
1767
1768 if (Range* activeMatch = m_textFinder->activeMatch()) {
2267 // If the user has set the selection since the match was found, we 1769 // If the user has set the selection since the match was found, we
2268 // don't focus anything. 1770 // don't focus anything.
2269 VisibleSelection selection(frame()->selection().selection()); 1771 VisibleSelection selection(frame()->selection().selection());
2270 if (!selection.isNone()) 1772 if (!selection.isNone())
2271 return; 1773 return;
2272 1774
2273 // Try to find the first focusable node up the chain, which will, for 1775 // Try to find the first focusable node up the chain, which will, for
2274 // example, focus links if we have found text within the link. 1776 // example, focus links if we have found text within the link.
2275 Node* node = m_activeMatch->firstNode(); 1777 Node* node = activeMatch->firstNode();
2276 if (node && node->isInShadowTree()) { 1778 if (node && node->isInShadowTree()) {
2277 if (Node* host = node->shadowHost()) { 1779 if (Node* host = node->shadowHost()) {
2278 if (isHTMLInputElement(*host) || isHTMLTextAreaElement(*host)) 1780 if (isHTMLInputElement(*host) || isHTMLTextAreaElement(*host))
2279 node = host; 1781 node = host;
2280 } 1782 }
2281 } 1783 }
2282 for (; node; node = node->parentNode()) { 1784 for (; node; node = node->parentNode()) {
2283 if (!node->isElementNode()) 1785 if (!node->isElementNode())
2284 continue; 1786 continue;
2285 Element* element = toElement(node); 1787 Element* element = toElement(node);
2286 if (element->isFocusable()) { 1788 if (element->isFocusable()) {
2287 // Found a focusable parent node. Set the active match as the 1789 // Found a focusable parent node. Set the active match as the
2288 // selection and focus to the focusable node. 1790 // selection and focus to the focusable node.
2289 frame()->selection().setSelection(VisibleSelection(m_activeMatch .get())); 1791 frame()->selection().setSelection(VisibleSelection(activeMatch)) ;
2290 frame()->document()->setFocusedElement(element); 1792 frame()->document()->setFocusedElement(element);
2291 return; 1793 return;
2292 } 1794 }
2293 } 1795 }
2294 1796
2295 // Iterate over all the nodes in the range until we find a focusable nod e. 1797 // Iterate over all the nodes in the range until we find a focusable nod e.
2296 // This, for example, sets focus to the first link if you search for 1798 // This, for example, sets focus to the first link if you search for
2297 // text and text that is within one or more links. 1799 // text and text that is within one or more links.
2298 node = m_activeMatch->firstNode(); 1800 node = activeMatch->firstNode();
2299 for (; node && node != m_activeMatch->pastLastNode(); node = NodeTravers al::next(*node)) { 1801 for (; node && node != activeMatch->pastLastNode(); node = NodeTraversal ::next(*node)) {
2300 if (!node->isElementNode()) 1802 if (!node->isElementNode())
2301 continue; 1803 continue;
2302 Element* element = toElement(node); 1804 Element* element = toElement(node);
2303 if (element->isFocusable()) { 1805 if (element->isFocusable()) {
2304 frame()->document()->setFocusedElement(element); 1806 frame()->document()->setFocusedElement(element);
2305 return; 1807 return;
2306 } 1808 }
2307 } 1809 }
2308 1810
2309 // No node related to the active match was focusable, so set the 1811 // No node related to the active match was focusable, so set the
2310 // active match as the selection (so that when you end the Find session, 1812 // active match as the selection (so that when you end the Find session,
2311 // you'll have the last thing you found highlighted) and make sure that 1813 // you'll have the last thing you found highlighted) and make sure that
2312 // we have nothing focused (otherwise you might have text selected but 1814 // we have nothing focused (otherwise you might have text selected but
2313 // a link focused, which is weird). 1815 // a link focused, which is weird).
2314 frame()->selection().setSelection(VisibleSelection(m_activeMatch.get())) ; 1816 frame()->selection().setSelection(VisibleSelection(activeMatch));
2315 frame()->document()->setFocusedElement(nullptr); 1817 frame()->document()->setFocusedElement(nullptr);
2316 1818
2317 // Finally clear the active match, for two reasons: 1819 // Finally clear the active match, for two reasons:
2318 // We just finished the find 'session' and we don't want future (potenti ally 1820 // We just finished the find 'session' and we don't want future (potenti ally
2319 // unrelated) find 'sessions' operations to start at the same place. 1821 // unrelated) find 'sessions' operations to start at the same place.
2320 // The WebFrameImpl could get reused and the m_activeMatch could end up pointing 1822 // The WebFrameImpl could get reused and the activeMatch could end up po inting
2321 // to a document that is no longer valid. Keeping an invalid reference a round 1823 // to a document that is no longer valid. Keeping an invalid reference a round
2322 // is just asking for trouble. 1824 // is just asking for trouble.
2323 m_activeMatch = nullptr; 1825 m_textFinder->resetActiveMatch();
2324 } 1826 }
2325 } 1827 }
2326 1828
2327 void WebFrameImpl::didFail(const ResourceError& error, bool wasProvisional) 1829 void WebFrameImpl::didFail(const ResourceError& error, bool wasProvisional)
2328 { 1830 {
2329 if (!client()) 1831 if (!client())
2330 return; 1832 return;
2331 WebURLError webError = error; 1833 WebURLError webError = error;
2332 if (wasProvisional) 1834 if (wasProvisional)
2333 client()->didFailProvisionalLoad(this, webError); 1835 client()->didFailProvisionalLoad(this, webError);
2334 else 1836 else
2335 client()->didFailLoad(this, webError); 1837 client()->didFailLoad(this, webError);
2336 } 1838 }
2337 1839
2338 void WebFrameImpl::setCanHaveScrollbars(bool canHaveScrollbars) 1840 void WebFrameImpl::setCanHaveScrollbars(bool canHaveScrollbars)
2339 { 1841 {
2340 frame()->view()->setCanHaveScrollbars(canHaveScrollbars); 1842 frame()->view()->setCanHaveScrollbars(canHaveScrollbars);
2341 } 1843 }
2342 1844
2343 void WebFrameImpl::setInputEventsTransformForEmulation(const IntSize& offset, fl oat contentScaleFactor) 1845 void WebFrameImpl::setInputEventsTransformForEmulation(const IntSize& offset, fl oat contentScaleFactor)
2344 { 1846 {
2345 m_inputEventsOffsetForEmulation = offset; 1847 m_inputEventsOffsetForEmulation = offset;
2346 m_inputEventsScaleFactorForEmulation = contentScaleFactor; 1848 m_inputEventsScaleFactorForEmulation = contentScaleFactor;
2347 if (frame()->view()) 1849 if (frame()->view())
2348 frame()->view()->setInputEventsTransformForEmulation(m_inputEventsOffset ForEmulation, m_inputEventsScaleFactorForEmulation); 1850 frame()->view()->setInputEventsTransformForEmulation(m_inputEventsOffset ForEmulation, m_inputEventsScaleFactorForEmulation);
2349 } 1851 }
2350 1852
2351 void WebFrameImpl::invalidateArea(AreaToInvalidate area)
2352 {
2353 ASSERT(frame() && frame()->view());
2354 FrameView* view = frame()->view();
2355
2356 if ((area & InvalidateAll) == InvalidateAll)
2357 view->invalidateRect(view->frameRect());
2358 else {
2359 if ((area & InvalidateContentArea) == InvalidateContentArea) {
2360 IntRect contentArea(
2361 view->x(), view->y(), view->visibleWidth(), view->visibleHeight( ));
2362 IntRect frameRect = view->frameRect();
2363 contentArea.move(-frameRect.x(), -frameRect.y());
2364 view->invalidateRect(contentArea);
2365 }
2366 }
2367
2368 if ((area & InvalidateScrollbar) == InvalidateScrollbar) {
2369 // Invalidate the vertical scroll bar region for the view.
2370 Scrollbar* scrollbar = view->verticalScrollbar();
2371 if (scrollbar)
2372 scrollbar->invalidate();
2373 }
2374 }
2375
2376 void WebFrameImpl::addMarker(Range* range, bool activeMatch)
2377 {
2378 frame()->document()->markers().addTextMatchMarker(range, activeMatch);
2379 }
2380
2381 void WebFrameImpl::setMarkerActive(Range* range, bool active)
2382 {
2383 if (!range || range->collapsed(IGNORE_EXCEPTION))
2384 return;
2385 frame()->document()->markers().setMarkersActive(range, active);
2386 }
2387
2388 int WebFrameImpl::ordinalOfFirstMatchForFrame(WebFrameImpl* frame) const
2389 {
2390 int ordinal = 0;
2391 WebFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl();
2392 // Iterate from the main frame up to (but not including) |frame| and
2393 // add up the number of matches found so far.
2394 for (WebFrameImpl* it = mainFrameImpl; it != frame; it = toWebFrameImpl(it-> traverseNext(true))) {
2395 if (it->m_lastMatchCount > 0)
2396 ordinal += it->m_lastMatchCount;
2397 }
2398 return ordinal;
2399 }
2400
2401 bool WebFrameImpl::shouldScopeMatches(const String& searchText)
2402 {
2403 // Don't scope if we can't find a frame or a view.
2404 // The user may have closed the tab/application, so abort.
2405 // Also ignore detached frames, as many find operations report to the main f rame.
2406 if (!frame() || !frame()->view() || !frame()->page() || !hasVisibleContent() )
2407 return false;
2408
2409 ASSERT(frame()->document() && frame()->view());
2410
2411 // If the frame completed the scoping operation and found 0 matches the last
2412 // time it was searched, then we don't have to search it again if the user i s
2413 // just adding to the search string or sending the same search string again.
2414 if (m_lastFindRequestCompletedWithNoMatches && !m_lastSearchString.isEmpty() ) {
2415 // Check to see if the search string prefixes match.
2416 String previousSearchPrefix =
2417 searchText.substring(0, m_lastSearchString.length());
2418
2419 if (previousSearchPrefix == m_lastSearchString)
2420 return false; // Don't search this frame, it will be fruitless.
2421 }
2422
2423 return true;
2424 }
2425
2426 void WebFrameImpl::scopeStringMatchesSoon(int identifier, const WebString& searc hText, const WebFindOptions& options, bool reset)
2427 {
2428 m_deferredScopingWork.append(new DeferredScopeStringMatches(this, identifier , searchText, options, reset));
2429 }
2430
2431 void WebFrameImpl::callScopeStringMatches(DeferredScopeStringMatches* caller, in t identifier, const WebString& searchText, const WebFindOptions& options, bool r eset)
2432 {
2433 m_deferredScopingWork.remove(m_deferredScopingWork.find(caller));
2434 scopeStringMatches(identifier, searchText, options, reset);
2435
2436 // This needs to happen last since searchText is passed by reference.
2437 delete caller;
2438 }
2439
2440 void WebFrameImpl::invalidateIfNecessary()
2441 {
2442 if (m_lastMatchCount <= m_nextInvalidateAfter)
2443 return;
2444
2445 // FIXME: (http://b/1088165) Optimize the drawing of the tickmarks and
2446 // remove this. This calculation sets a milestone for when next to
2447 // invalidate the scrollbar and the content area. We do this so that we
2448 // don't spend too much time drawing the scrollbar over and over again.
2449 // Basically, up until the first 500 matches there is no throttle.
2450 // After the first 500 matches, we set set the milestone further and
2451 // further out (750, 1125, 1688, 2K, 3K).
2452 static const int startSlowingDownAfter = 500;
2453 static const int slowdown = 750;
2454
2455 int i = m_lastMatchCount / startSlowingDownAfter;
2456 m_nextInvalidateAfter += i * slowdown;
2457 invalidateArea(InvalidateScrollbar);
2458 }
2459
2460 void WebFrameImpl::loadJavaScriptURL(const KURL& url) 1853 void WebFrameImpl::loadJavaScriptURL(const KURL& url)
2461 { 1854 {
2462 // This is copied from ScriptController::executeScriptIfJavaScriptURL. 1855 // This is copied from ScriptController::executeScriptIfJavaScriptURL.
2463 // Unfortunately, we cannot just use that method since it is private, and 1856 // Unfortunately, we cannot just use that method since it is private, and
2464 // it also doesn't quite behave as we require it to for bookmarklets. The 1857 // it also doesn't quite behave as we require it to for bookmarklets. The
2465 // key difference is that we need to suppress loading the string result 1858 // key difference is that we need to suppress loading the string result
2466 // from evaluating the JS URL if executing the JS URL resulted in a 1859 // from evaluating the JS URL if executing the JS URL resulted in a
2467 // location change. We also allow a JS URL to be loaded even if scripts on 1860 // location change. We also allow a JS URL to be loaded even if scripts on
2468 // the page are otherwise disabled. 1861 // the page are otherwise disabled.
2469 1862
(...skipping 15 matching lines...) Expand all
2485 return; 1878 return;
2486 1879
2487 if (!frame()->navigationScheduler().locationChangePending()) 1880 if (!frame()->navigationScheduler().locationChangePending())
2488 frame()->document()->loader()->replaceDocument(scriptResult, ownerDocume nt.get()); 1881 frame()->document()->loader()->replaceDocument(scriptResult, ownerDocume nt.get());
2489 } 1882 }
2490 1883
2491 void WebFrameImpl::willDetachParent() 1884 void WebFrameImpl::willDetachParent()
2492 { 1885 {
2493 // Do not expect string scoping results from any frames that got detached 1886 // Do not expect string scoping results from any frames that got detached
2494 // in the middle of the operation. 1887 // in the middle of the operation.
2495 if (m_scopingInProgress) { 1888 if (m_textFinder && m_textFinder->scopingInProgress()) {
2496 1889
2497 // There is a possibility that the frame being detached was the only 1890 // There is a possibility that the frame being detached was the only
2498 // pending one. We need to make sure final replies can be sent. 1891 // pending one. We need to make sure final replies can be sent.
2499 flushCurrentScopingEffort(m_findRequestIdentifier); 1892 m_textFinder->flushCurrentScoping();
2500 1893
2501 cancelPendingScopingEffort(); 1894 m_textFinder->cancelPendingScopingEffort();
2502 } 1895 }
2503 } 1896 }
2504 1897
1898 WebFrameImpl* WebFrameImpl::activeMatchFrame() const
1899 {
1900 ASSERT(!parent());
1901
1902 if (m_textFinder)
1903 return m_textFinder->activeMatchFrame();
1904 return nullptr;
1905 }
1906
1907 WebCore::Range* WebFrameImpl::activeMatch() const
1908 {
1909 if (m_textFinder)
1910 return m_textFinder->activeMatch();
1911 return nullptr;
1912 }
1913
1914 TextFinder& WebFrameImpl::ensureTextFinder()
1915 {
1916 if (!m_textFinder)
1917 m_textFinder = TextFinder::create(*this);
1918
1919 return *m_textFinder;
1920 }
1921
1922 void WebFrameImpl::invalidateScrollbar() const
1923 {
1924 ASSERT(frame() && frame()->view());
1925 FrameView* view = frame()->view();
1926 // Invalidate the vertical scroll bar region for the view.
1927 Scrollbar* scrollbar = view->verticalScrollbar();
1928 if (scrollbar)
1929 scrollbar->invalidate();
1930 }
1931
1932 void WebFrameImpl::invalidateAll() const
1933 {
1934 ASSERT(frame() && frame()->view());
1935 FrameView* view = frame()->view();
1936 view->invalidateRect(view->frameRect());
1937 invalidateScrollbar();
Andrey Kraynov 2014/03/24 16:34:07 invalidateAll function calls invalidateScrollbar i
1938 }
1939
2505 } // namespace blink 1940 } // namespace blink
OLDNEW
« Source/web/WebFrameImpl.h ('K') | « Source/web/WebFrameImpl.h ('k') | Source/web/web.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698