Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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(); |
|
esprehn
2014/08/05 01:00:02
updateAppearance creates a VisiblePosition which i
yoichio
2014/08/05 05:56:38
Yes. We call layout to get right caret position in
| |
| 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 Loading... | |
| 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() | 1231 void FrameSelection::updateLocalCaretRect() |
| 1234 { | 1232 { |
| 1235 if (shouldUpdateCaretRect()) { | 1233 if (shouldUpdateCaretRect()) { |
| 1236 if (!isNonOrphanedCaret(m_selection)) | 1234 if (!isNonOrphanedCaret(m_selection)) { |
| 1237 clearCaretRect(); | 1235 clearCaretRect(); |
| 1238 else if (isTextFormControl(m_selection)) | 1236 } else if (isTextFormControl(m_selection)) { |
| 1237 m_frame->document()->updateLayoutIgnorePendingStylesheets(); | |
| 1239 m_absCaretBoundsDirty |= updateCaretRect(m_frame->document(), Positi onWithAffinity(m_selection.start().isCandidate() ? m_selection.start() : Positio n(), m_selection.affinity())); | 1238 m_absCaretBoundsDirty |= updateCaretRect(m_frame->document(), Positi onWithAffinity(m_selection.start().isCandidate() ? m_selection.start() : Positio n(), m_selection.affinity())); |
| 1240 else | 1239 } else { |
| 1241 m_absCaretBoundsDirty |= updateCaretRect(m_frame->document(), Visibl ePosition(m_selection.start(), m_selection.affinity())); | 1240 m_absCaretBoundsDirty |= updateCaretRect(m_frame->document(), Visibl ePosition(m_selection.start(), m_selection.affinity())); |
| 1241 } | |
| 1242 } | 1242 } |
| 1243 | |
| 1244 return localCaretRectWithoutUpdate(); | |
| 1245 } | 1243 } |
| 1246 | 1244 |
| 1247 IntRect FrameSelection::absoluteCaretBounds() | 1245 IntRect FrameSelection::absoluteCaretBounds() |
| 1248 { | 1246 { |
| 1249 recomputeCaretRect(); | 1247 recomputeCaretRect(); |
| 1250 return m_absCaretBounds; | 1248 return m_absCaretBounds; |
| 1251 } | 1249 } |
| 1252 | 1250 |
| 1253 bool FrameSelection::recomputeCaretRect() | 1251 bool FrameSelection::recomputeCaretRect() |
| 1254 { | 1252 { |
| 1255 if (!shouldUpdateCaretRect()) | 1253 if (!shouldUpdateCaretRect()) |
| 1256 return false; | 1254 return false; |
| 1257 | 1255 |
| 1258 if (!m_frame || !m_frame->document()->view()) | 1256 if (!m_frame || !m_frame->document()->view()) |
| 1259 return false; | 1257 return false; |
| 1260 | 1258 |
| 1261 LayoutRect oldRect = localCaretRectWithoutUpdate(); | 1259 LayoutRect oldRect = localCaretRectWithoutUpdate(); |
| 1262 LayoutRect newRect = localCaretRect(); | 1260 updateLocalCaretRect(); |
| 1261 LayoutRect newRect = localCaretRectWithoutUpdate(); | |
| 1263 if (oldRect == newRect && !m_absCaretBoundsDirty) | 1262 if (oldRect == newRect && !m_absCaretBoundsDirty) |
| 1264 return false; | 1263 return false; |
| 1265 | 1264 |
| 1266 IntRect oldAbsCaretBounds = m_absCaretBounds; | 1265 IntRect oldAbsCaretBounds = m_absCaretBounds; |
| 1267 m_absCaretBounds = absoluteBoundsForLocalRect(m_selection.start().deprecated Node(), localCaretRectWithoutUpdate()); | 1266 m_absCaretBounds = absoluteBoundsForLocalRect(m_selection.start().deprecated Node(), localCaretRectWithoutUpdate()); |
| 1268 m_absCaretBoundsDirty = false; | 1267 m_absCaretBoundsDirty = false; |
| 1269 | 1268 |
| 1270 if (oldAbsCaretBounds == m_absCaretBounds) | 1269 if (oldAbsCaretBounds == m_absCaretBounds) |
| 1271 return false; | 1270 return false; |
| 1272 | 1271 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1285 void FrameSelection::invalidateCaretRect() | 1284 void FrameSelection::invalidateCaretRect() |
| 1286 { | 1285 { |
| 1287 if (!isCaret()) | 1286 if (!isCaret()) |
| 1288 return; | 1287 return; |
| 1289 | 1288 |
| 1290 CaretBase::invalidateCaretRect(m_selection.start().deprecatedNode(), recompu teCaretRect()); | 1289 CaretBase::invalidateCaretRect(m_selection.start().deprecatedNode(), recompu teCaretRect()); |
| 1291 } | 1290 } |
| 1292 | 1291 |
| 1293 void FrameSelection::paintCaret(GraphicsContext* context, const LayoutPoint& pai ntOffset, const LayoutRect& clipRect) | 1292 void FrameSelection::paintCaret(GraphicsContext* context, const LayoutPoint& pai ntOffset, const LayoutRect& clipRect) |
| 1294 { | 1293 { |
| 1295 if (m_selection.isCaret() && m_caretPaint) | 1294 if (m_selection.isCaret() && m_caretPaint) { |
| 1295 updateLocalCaretRect(); | |
|
esprehn
2014/08/05 01:00:02
Calling updateLayoutIgnorePendingStylesheets from
yoichio
2014/08/05 05:56:38
OK. How about calling updateLocalCaretRect in WebV
| |
| 1296 CaretBase::paintCaret(m_selection.start().deprecatedNode(), context, pai ntOffset, clipRect); | 1296 CaretBase::paintCaret(m_selection.start().deprecatedNode(), context, pai ntOffset, clipRect); |
| 1297 } | |
| 1297 } | 1298 } |
| 1298 | 1299 |
| 1299 bool FrameSelection::contains(const LayoutPoint& point) | 1300 bool FrameSelection::contains(const LayoutPoint& point) |
| 1300 { | 1301 { |
| 1301 Document* document = m_frame->document(); | 1302 Document* document = m_frame->document(); |
| 1302 | 1303 |
| 1303 // Treat a collapsed selection like no selection. | 1304 // Treat a collapsed selection like no selection. |
| 1304 if (!isRange()) | 1305 if (!isRange()) |
| 1305 return false; | 1306 return false; |
| 1306 if (!document->renderView()) | 1307 if (!document->renderView()) |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1535 return m_focused && m_frame->page() && m_frame->page()->focusController().is Active(); | 1536 return m_focused && m_frame->page() && m_frame->page()->focusController().is Active(); |
| 1536 } | 1537 } |
| 1537 | 1538 |
| 1538 inline static bool shouldStopBlinkingDueToTypingCommand(LocalFrame* frame) | 1539 inline static bool shouldStopBlinkingDueToTypingCommand(LocalFrame* frame) |
| 1539 { | 1540 { |
| 1540 return frame->editor().lastEditCommand() && frame->editor().lastEditCommand( )->shouldStopCaretBlinking(); | 1541 return frame->editor().lastEditCommand() && frame->editor().lastEditCommand( )->shouldStopCaretBlinking(); |
| 1541 } | 1542 } |
| 1542 | 1543 |
| 1543 void FrameSelection::updateAppearance() | 1544 void FrameSelection::updateAppearance() |
| 1544 { | 1545 { |
| 1546 bool isTextForm = isTextFormControl(m_selection); | |
|
esprehn
2014/08/05 01:00:02
I don't think we want to special case stuff like t
yoichio
2014/08/05 05:56:38
Actually, this CL is for improvement benchmark sco
| |
| 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 | 1547 // 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). | 1548 // the FrameSelection will paint a blinking caret as usual). |
| 1547 VisiblePosition forwardPosition; | 1549 VisiblePosition forwardPosition; |
| 1548 if (m_shouldShowBlockCursor && m_selection.isCaret()) { | 1550 if (m_shouldShowBlockCursor && m_selection.isCaret()) { |
| 1549 forwardPosition = modifyExtendingForward(CharacterGranularity); | 1551 forwardPosition = modifyExtendingForward(CharacterGranularity); |
| 1550 m_caretPaint = forwardPosition.isNull(); | 1552 m_caretPaint = forwardPosition.isNull(); |
| 1551 } | 1553 } |
| 1552 | 1554 |
| 1553 bool caretRectChangedOrCleared = recomputeCaretRect(); | 1555 bool caretRectChangedOrCleared = isTextForm || recomputeCaretRect(); |
| 1554 bool shouldBlink = shouldBlinkCaret() && forwardPosition.isNull(); | 1556 bool shouldBlink = shouldBlinkCaret() && forwardPosition.isNull(); |
| 1555 | 1557 |
| 1556 // If the caret moved, stop the blink timer so we can restart with a | 1558 // If the caret moved, stop the blink timer so we can restart with a |
| 1557 // black caret in the new location. | 1559 // black caret in the new location. |
| 1558 if (caretRectChangedOrCleared || !shouldBlink || shouldStopBlinkingDueToTypi ngCommand(m_frame)) { | 1560 if (caretRectChangedOrCleared || !shouldBlink || shouldStopBlinkingDueToTypi ngCommand(m_frame)) { |
| 1559 m_caretBlinkTimer.stop(); | 1561 m_caretBlinkTimer.stop(); |
| 1560 if (!shouldBlink && m_caretPaint) { | 1562 if (!shouldBlink && m_caretPaint) { |
| 1561 m_caretPaint = false; | 1563 m_caretPaint = false; |
| 1562 invalidateCaretRect(); | 1564 invalidateCaretRect(); |
| 1563 } | 1565 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1574 invalidateCaretRect(); | 1576 invalidateCaretRect(); |
| 1575 } | 1577 } |
| 1576 } | 1578 } |
| 1577 | 1579 |
| 1578 RenderView* view = m_frame->contentRenderer(); | 1580 RenderView* view = m_frame->contentRenderer(); |
| 1579 if (!view) | 1581 if (!view) |
| 1580 return; | 1582 return; |
| 1581 | 1583 |
| 1582 // Construct a new VisibleSolution, since m_selection is not necessarily val id, and the following steps | 1584 // Construct a new VisibleSolution, since m_selection is not necessarily val id, and the following steps |
| 1583 // assume a valid selection. See <https://bugs.webkit.org/show_bug.cgi?id=69 563> and <rdar://problem/10232866>. | 1585 // assume a valid selection. See <https://bugs.webkit.org/show_bug.cgi?id=69 563> and <rdar://problem/10232866>. |
| 1584 VisibleSelection selection(m_selection.visibleStart(), forwardPosition.isNot Null() ? forwardPosition : m_selection.visibleEnd()); | 1586 VisibleSelection selection; |
| 1587 if (isTextForm) | |
| 1588 selection.setWithoutValidation(m_selection.start(), forwardPosition.isNo tNull() ? forwardPosition.deepEquivalent() : m_selection.end()); | |
| 1589 else | |
| 1590 selection = VisibleSelection(m_selection.visibleStart(), forwardPosition .isNotNull() ? forwardPosition : m_selection.visibleEnd()); | |
| 1585 | 1591 |
| 1586 if (!selection.isRange()) { | 1592 if (!selection.isRange()) { |
| 1587 view->clearSelection(); | 1593 view->clearSelection(); |
| 1588 return; | 1594 return; |
| 1589 } | 1595 } |
| 1590 | 1596 |
| 1591 // Use the rightmost candidate for the start of the selection, and the leftm ost candidate for the end of the selection. | 1597 // Use the rightmost candidate for the start of the selection, and the leftm ost candidate for the end of the selection. |
| 1592 // Example: foo <a>bar</a>. Imagine that a line wrap occurs after 'foo', an d that 'bar' is selected. If we pass [foo, 3] | 1598 // Example: foo <a>bar</a>. Imagine that a line wrap occurs after 'foo', an d that 'bar' is selected. If we pass [foo, 3] |
| 1593 // as the start of the selection, the selection painting code will think tha t content on the line containing 'foo' is selected | 1599 // as the start of the selection, the selection painting code will think tha t content on the line containing 'foo' is selected |
| 1594 // and will fill the gap before 'bar'. | 1600 // and will fill the gap before 'bar'. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1650 ASSERT(caretIsVisible()); | 1656 ASSERT(caretIsVisible()); |
| 1651 ASSERT(isCaret()); | 1657 ASSERT(isCaret()); |
| 1652 if (isCaretBlinkingSuspended() && m_caretPaint) | 1658 if (isCaretBlinkingSuspended() && m_caretPaint) |
| 1653 return; | 1659 return; |
| 1654 m_caretPaint = !m_caretPaint; | 1660 m_caretPaint = !m_caretPaint; |
| 1655 invalidateCaretRect(); | 1661 invalidateCaretRect(); |
| 1656 } | 1662 } |
| 1657 | 1663 |
| 1658 void FrameSelection::notifyRendererOfSelectionChange(EUserTriggered userTriggere d) | 1664 void FrameSelection::notifyRendererOfSelectionChange(EUserTriggered userTriggere d) |
| 1659 { | 1665 { |
| 1660 m_frame->document()->updateRenderTreeIfNeeded(); | |
| 1661 | |
| 1662 if (HTMLTextFormControlElement* textControl = enclosingTextFormControl(start ())) | 1666 if (HTMLTextFormControlElement* textControl = enclosingTextFormControl(start ())) |
| 1663 textControl->selectionChanged(userTriggered == UserTriggered); | 1667 textControl->selectionChanged(userTriggered == UserTriggered); |
| 1664 } | 1668 } |
| 1665 | 1669 |
| 1666 // Helper function that tells whether a particular node is an element that has a n entire | 1670 // Helper function that tells whether a particular node is an element that has a n entire |
| 1667 // LocalFrame and FrameView, a <frame>, <iframe>, or <object>. | 1671 // LocalFrame and FrameView, a <frame>, <iframe>, or <object>. |
| 1668 static bool isFrameElement(const Node* n) | 1672 static bool isFrameElement(const Node* n) |
| 1669 { | 1673 { |
| 1670 if (!n) | 1674 if (!n) |
| 1671 return false; | 1675 return false; |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1927 sel.showTreeForThis(); | 1931 sel.showTreeForThis(); |
| 1928 } | 1932 } |
| 1929 | 1933 |
| 1930 void showTree(const blink::FrameSelection* sel) | 1934 void showTree(const blink::FrameSelection* sel) |
| 1931 { | 1935 { |
| 1932 if (sel) | 1936 if (sel) |
| 1933 sel->showTreeForThis(); | 1937 sel->showTreeForThis(); |
| 1934 } | 1938 } |
| 1935 | 1939 |
| 1936 #endif | 1940 #endif |
| OLD | NEW |