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

Side by Side Diff: Source/core/editing/FrameSelection.cpp

Issue 431983005: FrameSelection::updateApperance for caret should not cause layout. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Let FrameSelection rember the previous rect. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2008, 2009, 2010 Apple 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 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 { 89 {
90 return !frame || frame->editor().behavior().shouldConsiderSelectionAsDirecti onal(); 90 return !frame || frame->editor().behavior().shouldConsiderSelectionAsDirecti onal();
91 } 91 }
92 92
93 FrameSelection::FrameSelection(LocalFrame* frame) 93 FrameSelection::FrameSelection(LocalFrame* frame)
94 : m_frame(frame) 94 : m_frame(frame)
95 , m_xPosForVerticalArrowNavigation(NoXPosForVerticalArrowNavigation()) 95 , m_xPosForVerticalArrowNavigation(NoXPosForVerticalArrowNavigation())
96 , m_observingVisibleSelection(false) 96 , m_observingVisibleSelection(false)
97 , m_granularity(CharacterGranularity) 97 , m_granularity(CharacterGranularity)
98 , m_caretBlinkTimer(this, &FrameSelection::caretBlinkTimerFired) 98 , m_caretBlinkTimer(this, &FrameSelection::caretBlinkTimerFired)
99 , m_absCaretBoundsDirty(true) 99 , m_caretRectDirty(true)
100 , m_caretPaint(true) 100 , m_caretPaint(true)
101 , m_isCaretBlinkingSuspended(false) 101 , m_isCaretBlinkingSuspended(false)
102 , m_focused(frame && frame->page() && frame->page()->focusController().focus edFrame() == frame) 102 , m_focused(frame && frame->page() && frame->page()->focusController().focus edFrame() == frame)
103 , m_shouldShowBlockCursor(false) 103 , m_shouldShowBlockCursor(false)
104 { 104 {
105 if (shouldAlwaysUseDirectionalSelection(m_frame)) 105 if (shouldAlwaysUseDirectionalSelection(m_frame))
106 m_selection.setIsDirectional(true); 106 m_selection.setIsDirectional(true);
107 } 107 }
108 108
109 FrameSelection::~FrameSelection() 109 FrameSelection::~FrameSelection()
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 265
266 VisibleSelection oldSelection = m_selection; 266 VisibleSelection oldSelection = m_selection;
267 267
268 m_selection = s; 268 m_selection = s;
269 setCaretRectNeedsUpdate(); 269 setCaretRectNeedsUpdate();
270 270
271 if (!s.isNone() && !(options & DoNotSetFocus)) 271 if (!s.isNone() && !(options & DoNotSetFocus))
272 setFocusedNodeIfNeeded(); 272 setFocusedNodeIfNeeded();
273 273
274 if (!(options & DoNotUpdateAppearance)) { 274 if (!(options & DoNotUpdateAppearance)) {
275 m_frame->document()->updateLayoutIgnorePendingStylesheets();
276
277 // Hits in compositing/overflow/do-not-paint-outline-into-composited-scr olling-contents.html 275 // Hits in compositing/overflow/do-not-paint-outline-into-composited-scr olling-contents.html
278 DisableCompositingQueryAsserts disabler; 276 DisableCompositingQueryAsserts disabler;
279 updateAppearance(); 277 updateAppearance(ResetCaretBlink);
280 } 278 }
281 279
282 // Always clear the x position used for vertical arrow navigation. 280 // Always clear the x position used for vertical arrow navigation.
283 // It will be restored by the vertical arrow navigation code if necessary. 281 // It will be restored by the vertical arrow navigation code if necessary.
284 m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation(); 282 m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation();
285 selectFrameElementInParentIfFullySelected(); 283 selectFrameElementInParentIfFullySelected();
286 notifyRendererOfSelectionChange(userTriggered); 284 notifyRendererOfSelectionChange(userTriggered);
287 m_frame->editor().respondToChangedSelection(oldSelection, options); 285 m_frame->editor().respondToChangedSelection(oldSelection, options);
288 if (userTriggered == UserTriggered) { 286 if (userTriggered == UserTriggered) {
289 ScrollAlignment alignment; 287 ScrollAlignment alignment;
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 static bool isNonOrphanedCaret(const VisibleSelection& selection) 1221 static bool isNonOrphanedCaret(const VisibleSelection& selection)
1224 { 1222 {
1225 return selection.isCaret() && !selection.start().isOrphan() && !selection.en d().isOrphan(); 1223 return selection.isCaret() && !selection.start().isOrphan() && !selection.en d().isOrphan();
1226 } 1224 }
1227 1225
1228 static bool isTextFormControl(const VisibleSelection& selection) 1226 static bool isTextFormControl(const VisibleSelection& selection)
1229 { 1227 {
1230 return enclosingTextFormControl(selection.start()); 1228 return enclosingTextFormControl(selection.start());
1231 } 1229 }
1232 1230
1233 LayoutRect FrameSelection::localCaretRect()
1234 {
1235 if (shouldUpdateCaretRect()) {
1236 if (!isNonOrphanedCaret(m_selection))
1237 clearCaretRect();
1238 else if (isTextFormControl(m_selection))
1239 m_absCaretBoundsDirty |= updateCaretRect(m_frame->document(), Positi onWithAffinity(m_selection.start().isCandidate() ? m_selection.start() : Positio n(), m_selection.affinity()));
1240 else
1241 m_absCaretBoundsDirty |= updateCaretRect(m_frame->document(), Visibl ePosition(m_selection.start(), m_selection.affinity()));
1242 }
1243
1244 return localCaretRectWithoutUpdate();
1245 }
1246
1247 IntRect FrameSelection::absoluteCaretBounds() 1231 IntRect FrameSelection::absoluteCaretBounds()
1248 { 1232 {
1249 recomputeCaretRect(); 1233 if (!isNonOrphanedCaret(m_selection)) {
1250 return m_absCaretBounds; 1234 clearCaretRect();
1235 } else {
1236 m_frame->document()->updateLayoutIgnorePendingStylesheets();
1237 if (isTextFormControl(m_selection))
1238 updateCaretRect(m_frame->document(), PositionWithAffinity(m_selectio n.start().isCandidate() ? m_selection.start() : Position(), m_selection.affinity ()));
1239 else
1240 updateCaretRect(m_frame->document(), VisiblePosition(m_selection.sta rt(), m_selection.affinity()));
1241 }
1242 return absoluteBoundsForLocalRect(m_selection.start().deprecatedNode(), loca lCaretRectWithoutUpdate());
1251 } 1243 }
1252 1244
1253 bool FrameSelection::recomputeCaretRect() 1245 static LayoutRect localCaretRect(const VisibleSelection& m_selection, const Posi tionWithAffinity& caretPosition, RenderObject*& renderer)
1254 { 1246 {
1255 if (!shouldUpdateCaretRect()) 1247 renderer = nullptr;
1256 return false; 1248 if (!isNonOrphanedCaret(m_selection))
1249 return LayoutRect();
1257 1250
1258 if (!m_frame || !m_frame->document()->view()) 1251 return localCaretRectOfPosition(caretPosition, renderer);
1259 return false; 1252 }
1260 1253
1261 LayoutRect oldRect = localCaretRectWithoutUpdate(); 1254 static void invalidateLocalCaretRect(RenderObject* renderer, const LayoutRect& c aretRect)
1262 LayoutRect newRect = localCaretRect(); 1255 {
1263 if (oldRect == newRect && !m_absCaretBoundsDirty) 1256 // FIXME: Need to over-paint 1 pixel to workaround some rounding problems.
1264 return false; 1257 // https://bugs.webkit.org/show_bug.cgi?id=108283
1265 1258 LayoutRect inflatedRect = caretRect;
1266 IntRect oldAbsCaretBounds = m_absCaretBounds; 1259 inflatedRect.inflate(1);
1267 m_absCaretBounds = absoluteBoundsForLocalRect(m_selection.start().deprecated Node(), localCaretRectWithoutUpdate()); 1260 renderer->invalidatePaintRectangle(inflatedRect);
1268 m_absCaretBoundsDirty = false;
1269
1270 if (oldAbsCaretBounds == m_absCaretBounds)
1271 return false;
1272
1273 if (RenderView* view = m_frame->document()->renderView()) {
1274 if (m_previousCaretNode && shouldRepaintCaret(view, m_previousCaretNode- >isContentEditable()))
1275 repaintCaretForLocalRect(m_previousCaretNode.get(), oldRect);
1276 Node* node = m_selection.start().deprecatedNode();
1277 m_previousCaretNode = node;
1278 if (shouldRepaintCaret(view, isContentEditable()))
1279 repaintCaretForLocalRect(node, newRect);
1280 }
1281
1282 return true;
1283 } 1261 }
1284 1262
1285 void FrameSelection::invalidateCaretRect() 1263 void FrameSelection::invalidateCaretRect()
1286 { 1264 {
1287 if (!isCaret()) 1265 if (!m_caretRectDirty)
1266 return;
1267 m_caretRectDirty = false;
1268
1269 RenderObject* renderer;
abarth-chromium 2014/08/13 20:42:44 = 0
yoichio 2014/08/13 21:43:32 Done.
1270 LayoutRect newRect = localCaretRect(m_selection, PositionWithAffinity(m_sele ction.start(), m_selection.affinity()), renderer);
1271 Node* newNode = renderer ? renderer->node() : nullptr;
1272
1273 if (!m_caretBlinkTimer.isActive() && newNode == m_previousCaretNode && newRe ct == m_previousCaretRect)
1288 return; 1274 return;
1289 1275
1290 CaretBase::invalidateCaretRect(m_selection.start().deprecatedNode(), recompu teCaretRect()); 1276 RenderView* view = m_frame->document()->renderView();
1277 ASSERT(m_frame->document()->renderView());
abarth-chromium 2014/08/13 20:42:44 There no need for this ASSERT
yoichio 2014/08/13 21:43:32 Done.
1278 if (m_previousCaretNode && shouldRepaintCaret(view, m_previousCaretNode->isC ontentEditable()))
1279 invalidateLocalCaretRect(m_previousCaretNode->renderer(), m_previousCare tRect);
1280 if (newNode && shouldRepaintCaret(view, newNode->isContentEditable()))
1281 invalidateLocalCaretRect(newNode->renderer(), newRect);
1282
1283 m_previousCaretNode = newNode;
1284 m_previousCaretRect = newRect;
1291 } 1285 }
1292 1286
1293 void FrameSelection::paintCaret(GraphicsContext* context, const LayoutPoint& pai ntOffset, const LayoutRect& clipRect) 1287 void FrameSelection::paintCaret(GraphicsContext* context, const LayoutPoint& pai ntOffset, const LayoutRect& clipRect)
1294 { 1288 {
1295 if (m_selection.isCaret() && m_caretPaint) 1289 if (m_selection.isCaret() && m_caretPaint)
1296 CaretBase::paintCaret(m_selection.start().deprecatedNode(), context, pai ntOffset, clipRect); 1290 CaretBase::paintCaret(m_selection.start().deprecatedNode(), context, pai ntOffset, clipRect);
1297 } 1291 }
1298 1292
1299 bool FrameSelection::contains(const LayoutPoint& point) 1293 bool FrameSelection::contains(const LayoutPoint& point)
1300 { 1294 {
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1458 if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache()) 1452 if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache())
1459 cache->selectionChanged(m_selection.start().containerNode()); 1453 cache->selectionChanged(m_selection.start().containerNode());
1460 } 1454 }
1461 } 1455 }
1462 1456
1463 void FrameSelection::notifyCompositorForSelectionChange() 1457 void FrameSelection::notifyCompositorForSelectionChange()
1464 { 1458 {
1465 if (!RuntimeEnabledFeatures::compositedSelectionUpdatesEnabled()) 1459 if (!RuntimeEnabledFeatures::compositedSelectionUpdatesEnabled())
1466 return; 1460 return;
1467 1461
1468 if (Page* page = m_frame->page()) 1462 scheduleVisualUpdate();
1469 page->animator().scheduleVisualUpdate();
1470 } 1463 }
1471 1464
1472 void FrameSelection::focusedOrActiveStateChanged() 1465 void FrameSelection::focusedOrActiveStateChanged()
1473 { 1466 {
1474 bool activeAndFocused = isFocusedAndActive(); 1467 bool activeAndFocused = isFocusedAndActive();
1475 1468
1476 RefPtrWillBeRawPtr<Document> document = m_frame->document(); 1469 RefPtrWillBeRawPtr<Document> document = m_frame->document();
1477 document->updateRenderTreeIfNeeded(); 1470 document->updateRenderTreeIfNeeded();
1478 1471
1479 // Because RenderObject::selectionBackgroundColor() and 1472 // Because RenderObject::selectionBackgroundColor() and
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1533 bool FrameSelection::isFocusedAndActive() const 1526 bool FrameSelection::isFocusedAndActive() const
1534 { 1527 {
1535 return m_focused && m_frame->page() && m_frame->page()->focusController().is Active(); 1528 return m_focused && m_frame->page() && m_frame->page()->focusController().is Active();
1536 } 1529 }
1537 1530
1538 inline static bool shouldStopBlinkingDueToTypingCommand(LocalFrame* frame) 1531 inline static bool shouldStopBlinkingDueToTypingCommand(LocalFrame* frame)
1539 { 1532 {
1540 return frame->editor().lastEditCommand() && frame->editor().lastEditCommand( )->shouldStopCaretBlinking(); 1533 return frame->editor().lastEditCommand() && frame->editor().lastEditCommand( )->shouldStopCaretBlinking();
1541 } 1534 }
1542 1535
1543 void FrameSelection::updateAppearance() 1536 void FrameSelection::updateAppearance(UpdateAppearanceOption option)
1544 { 1537 {
1545 // Paint a block cursor instead of a caret in overtype mode unless the caret is at the end of a line (in this case 1538 // Paint a block cursor instead of a caret in overtype mode unless the caret is at the end of a line (in this case
1546 // the FrameSelection will paint a blinking caret as usual). 1539 // the FrameSelection will paint a blinking caret as usual).
1547 bool paintBlockCursor = m_shouldShowBlockCursor && m_selection.isCaret() && !isLogicalEndOfLine(m_selection.visibleEnd()); 1540 bool paintBlockCursor = m_shouldShowBlockCursor && m_selection.isCaret() && !isLogicalEndOfLine(m_selection.visibleEnd());
1548 1541
1549 bool caretRectChangedOrCleared = recomputeCaretRect();
1550 bool shouldBlink = !paintBlockCursor && shouldBlinkCaret(); 1542 bool shouldBlink = !paintBlockCursor && shouldBlinkCaret();
1551 1543
1552 // If the caret moved, stop the blink timer so we can restart with a 1544 // If the caret moved, stop the blink timer so we can restart with a
1553 // black caret in the new location. 1545 // black caret in the new location.
1554 if (caretRectChangedOrCleared || !shouldBlink || shouldStopBlinkingDueToTypi ngCommand(m_frame)) { 1546 if (option == ResetCaretBlink || !shouldBlink || shouldStopBlinkingDueToTypi ngCommand(m_frame)) {
1555 m_caretBlinkTimer.stop(); 1547 m_caretBlinkTimer.stop();
1556 if (!shouldBlink && m_caretPaint) { 1548
1557 m_caretPaint = false; 1549 m_caretPaint = false;
1558 invalidateCaretRect(); 1550 m_caretRectDirty = true;
1559 }
1560 } 1551 }
1561 1552
1562 // Start blinking with a black caret. Be sure not to restart if we're 1553 // Start blinking with a black caret. Be sure not to restart if we're
1563 // already blinking in the right location. 1554 // already blinking in the right location.
1564 if (shouldBlink && !m_caretBlinkTimer.isActive()) { 1555 if (shouldBlink && !m_caretBlinkTimer.isActive()) {
1565 if (double blinkInterval = RenderTheme::theme().caretBlinkInterval()) 1556 if (double blinkInterval = RenderTheme::theme().caretBlinkInterval())
1566 m_caretBlinkTimer.startRepeating(blinkInterval, FROM_HERE); 1557 m_caretBlinkTimer.startRepeating(blinkInterval, FROM_HERE);
1567 1558
1568 if (!m_caretPaint) { 1559 m_caretPaint = true;
1569 m_caretPaint = true; 1560 m_caretRectDirty = true;
1570 invalidateCaretRect();
1571 }
1572 } 1561 }
1573 1562
1563 if (m_caretRectDirty)
abarth-chromium 2014/08/13 20:42:44 How can m_caretRectDirty become true without calli
yoichio 2014/08/13 21:43:32 Done.
1564 scheduleVisualUpdate();
1565
1574 RenderView* view = m_frame->contentRenderer(); 1566 RenderView* view = m_frame->contentRenderer();
1575 if (!view) 1567 if (!view)
1576 return; 1568 return;
1577 1569
1578 // Construct a new VisibleSolution, since m_selection is not necessarily val id, and the following steps 1570 // Construct a new VisibleSolution, since m_selection is not necessarily val id, and the following steps
1579 // assume a valid selection. See <https://bugs.webkit.org/show_bug.cgi?id=69 563> and <rdar://problem/10232866>. 1571 // assume a valid selection. See <https://bugs.webkit.org/show_bug.cgi?id=69 563> and <rdar://problem/10232866>.
1580 VisiblePosition endVisiblePosition = paintBlockCursor ? modifyExtendingForwa rd(CharacterGranularity) : m_selection.visibleEnd(); 1572
1581 VisibleSelection selection(m_selection.visibleStart(), endVisiblePosition); 1573 VisibleSelection selection;
1574 if (isTextFormControl(m_selection)) {
1575 Position endPosition = paintBlockCursor ? m_selection.extent().next() : m_selection.end();
1576 selection.setWithoutValidation(m_selection.start(), endPosition);
1577 } else {
1578 VisiblePosition endVisiblePosition = paintBlockCursor ? modifyExtendingF orward(CharacterGranularity) : m_selection.visibleEnd();
1579 selection = VisibleSelection(m_selection.visibleStart(), endVisiblePosit ion);
1580 }
1582 1581
1583 if (!selection.isRange()) { 1582 if (!selection.isRange()) {
1584 view->clearSelection(); 1583 view->clearSelection();
1585 return; 1584 return;
1586 } 1585 }
1587 1586
1588 // Use the rightmost candidate for the start of the selection, and the leftm ost candidate for the end of the selection. 1587 // Use the rightmost candidate for the start of the selection, and the leftm ost candidate for the end of the selection.
1589 // Example: foo <a>bar</a>. Imagine that a line wrap occurs after 'foo', an d that 'bar' is selected. If we pass [foo, 3] 1588 // Example: foo <a>bar</a>. Imagine that a line wrap occurs after 'foo', an d that 'bar' is selected. If we pass [foo, 3]
1590 // as the start of the selection, the selection painting code will think tha t content on the line containing 'foo' is selected 1589 // as the start of the selection, the selection painting code will think tha t content on the line containing 'foo' is selected
1591 // and will fill the gap before 'bar'. 1590 // and will fill the gap before 'bar'.
(...skipping 14 matching lines...) Expand all
1606 if (startRenderer->view() == view && endRenderer->view() == view) 1605 if (startRenderer->view() == view && endRenderer->view() == view)
1607 view->setSelection(startRenderer, startPos.deprecatedEditingOffset() , endRenderer, endPos.deprecatedEditingOffset()); 1606 view->setSelection(startRenderer, startPos.deprecatedEditingOffset() , endRenderer, endPos.deprecatedEditingOffset());
1608 } 1607 }
1609 } 1608 }
1610 1609
1611 void FrameSelection::setCaretVisibility(CaretVisibility visibility) 1610 void FrameSelection::setCaretVisibility(CaretVisibility visibility)
1612 { 1611 {
1613 if (caretVisibility() == visibility) 1612 if (caretVisibility() == visibility)
1614 return; 1613 return;
1615 1614
1616 m_frame->document()->updateLayoutIgnorePendingStylesheets(); 1615 m_frame->document()->updateLayoutIgnorePendingStylesheets();
abarth-chromium 2014/08/13 20:42:44 Why is this call necessary?
abarth-chromium 2014/08/13 20:42:44 Why is this call necessary?
yoichio 2014/08/13 21:43:32 Done.
1617 if (m_caretPaint) { 1616 if (m_caretPaint) {
1618 m_caretPaint = false; 1617 m_caretPaint = false;
1619 invalidateCaretRect(); 1618 m_caretRectDirty = true;
1620 } 1619 }
yoichio 2014/08/13 21:43:32 Remove these lines because we check if we paint or
1621 CaretBase::setCaretVisibility(visibility); 1620 CaretBase::setCaretVisibility(visibility);
1622 1621
1623 updateAppearance(); 1622 updateAppearance();
1624 } 1623 }
1625 1624
1626 bool FrameSelection::shouldBlinkCaret() const 1625 bool FrameSelection::shouldBlinkCaret() const
1627 { 1626 {
1628 if (!caretIsVisible() || !isCaret()) 1627 if (!caretIsVisible() || !isCaret())
1629 return false; 1628 return false;
1630 1629
(...skipping 11 matching lines...) Expand all
1642 return focusedElement->containsIncludingShadowDOM(m_selection.start().anchor Node()); 1641 return focusedElement->containsIncludingShadowDOM(m_selection.start().anchor Node());
1643 } 1642 }
1644 1643
1645 void FrameSelection::caretBlinkTimerFired(Timer<FrameSelection>*) 1644 void FrameSelection::caretBlinkTimerFired(Timer<FrameSelection>*)
1646 { 1645 {
1647 ASSERT(caretIsVisible()); 1646 ASSERT(caretIsVisible());
1648 ASSERT(isCaret()); 1647 ASSERT(isCaret());
1649 if (isCaretBlinkingSuspended() && m_caretPaint) 1648 if (isCaretBlinkingSuspended() && m_caretPaint)
1650 return; 1649 return;
1651 m_caretPaint = !m_caretPaint; 1650 m_caretPaint = !m_caretPaint;
1652 invalidateCaretRect(); 1651 setCaretRectNeedsUpdate();
1653 } 1652 }
1654 1653
1655 void FrameSelection::notifyRendererOfSelectionChange(EUserTriggered userTriggere d) 1654 void FrameSelection::notifyRendererOfSelectionChange(EUserTriggered userTriggere d)
1656 { 1655 {
1657 m_frame->document()->updateRenderTreeIfNeeded();
1658
1659 if (HTMLTextFormControlElement* textControl = enclosingTextFormControl(start ())) 1656 if (HTMLTextFormControlElement* textControl = enclosingTextFormControl(start ()))
1660 textControl->selectionChanged(userTriggered == UserTriggered); 1657 textControl->selectionChanged(userTriggered == UserTriggered);
1661 } 1658 }
1662 1659
1663 // Helper function that tells whether a particular node is an element that has a n entire 1660 // Helper function that tells whether a particular node is an element that has a n entire
1664 // LocalFrame and FrameView, a <frame>, <iframe>, or <object>. 1661 // LocalFrame and FrameView, a <frame>, <iframe>, or <object>.
1665 static bool isFrameElement(const Node* n) 1662 static bool isFrameElement(const Node* n)
1666 { 1663 {
1667 if (!n) 1664 if (!n)
1668 return false; 1665 return false;
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1908 void FrameSelection::trace(Visitor* visitor) 1905 void FrameSelection::trace(Visitor* visitor)
1909 { 1906 {
1910 visitor->trace(m_selection); 1907 visitor->trace(m_selection);
1911 visitor->trace(m_originalBase); 1908 visitor->trace(m_originalBase);
1912 visitor->trace(m_logicalRange); 1909 visitor->trace(m_logicalRange);
1913 visitor->trace(m_previousCaretNode); 1910 visitor->trace(m_previousCaretNode);
1914 visitor->trace(m_typingStyle); 1911 visitor->trace(m_typingStyle);
1915 VisibleSelection::ChangeObserver::trace(visitor); 1912 VisibleSelection::ChangeObserver::trace(visitor);
1916 } 1913 }
1917 1914
1915 void FrameSelection::setCaretRectNeedsUpdate()
1916 {
1917 m_caretRectDirty = true;
1918 scheduleVisualUpdate();
1919 }
1920
1921 void FrameSelection::scheduleVisualUpdate() const
1922 {
1923 if (!m_frame)
1924 return;
1925
1926 if (Page* page = m_frame->page())
1927 page->animator().scheduleVisualUpdate();
1928 }
1929
1918 } 1930 }
1919 1931
1920 #ifndef NDEBUG 1932 #ifndef NDEBUG
1921 1933
1922 void showTree(const blink::FrameSelection& sel) 1934 void showTree(const blink::FrameSelection& sel)
1923 { 1935 {
1924 sel.showTreeForThis(); 1936 sel.showTreeForThis();
1925 } 1937 }
1926 1938
1927 void showTree(const blink::FrameSelection* sel) 1939 void showTree(const blink::FrameSelection* sel)
1928 { 1940 {
1929 if (sel) 1941 if (sel)
1930 sel->showTreeForThis(); 1942 sel->showTreeForThis();
1931 } 1943 }
1932 1944
1933 #endif 1945 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698