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

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

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

Powered by Google App Engine
This is Rietveld 408576698