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

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

Powered by Google App Engine
This is Rietveld 408576698