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

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

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

Powered by Google App Engine
This is Rietveld 408576698