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

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