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 21 matching lines...) Expand all Loading... | |
| 32 #include "core/editing/SelectionEditor.h" | 32 #include "core/editing/SelectionEditor.h" |
| 33 #include "core/editing/commands/CompositeEditCommand.h" | 33 #include "core/editing/commands/CompositeEditCommand.h" |
| 34 #include "core/frame/FrameView.h" | 34 #include "core/frame/FrameView.h" |
| 35 #include "core/frame/LocalFrame.h" | 35 #include "core/frame/LocalFrame.h" |
| 36 #include "core/frame/Settings.h" | 36 #include "core/frame/Settings.h" |
| 37 #include "core/html/TextControlElement.h" | 37 #include "core/html/TextControlElement.h" |
| 38 #include "core/layout/LayoutBlock.h" | 38 #include "core/layout/LayoutBlock.h" |
| 39 #include "core/layout/LayoutTheme.h" | 39 #include "core/layout/LayoutTheme.h" |
| 40 #include "core/layout/api/LayoutPartItem.h" | 40 #include "core/layout/api/LayoutPartItem.h" |
| 41 #include "core/page/Page.h" | 41 #include "core/page/Page.h" |
| 42 #include "core/paint/PaintLayer.h" | |
| 43 #include "public/platform/WebTraceLocation.h" | 42 #include "public/platform/WebTraceLocation.h" |
| 44 | 43 |
| 45 namespace blink { | 44 namespace blink { |
| 46 | 45 |
| 47 FrameCaret::FrameCaret(LocalFrame& frame, | 46 FrameCaret::FrameCaret(LocalFrame& frame, |
| 48 const SelectionEditor& selectionEditor) | 47 const SelectionEditor& selectionEditor) |
| 49 : m_selectionEditor(&selectionEditor), | 48 : m_selectionEditor(&selectionEditor), |
| 50 m_frame(frame), | 49 m_frame(frame), |
| 51 m_caretBase(new CaretDisplayItemClient()), | 50 m_caretBase(new CaretDisplayItemClient()), |
| 52 m_caretVisibility(CaretVisibility::Hidden), | 51 m_caretVisibility(CaretVisibility::Hidden), |
| 53 m_previousCaretVisibility(CaretVisibility::Hidden), | |
| 54 m_caretBlinkTimer(TaskRunnerHelper::get(TaskType::UnspecedTimer, &frame), | 52 m_caretBlinkTimer(TaskRunnerHelper::get(TaskType::UnspecedTimer, &frame), |
| 55 this, | 53 this, |
| 56 &FrameCaret::caretBlinkTimerFired), | 54 &FrameCaret::caretBlinkTimerFired), |
| 57 m_caretRectDirty(true), | |
| 58 m_shouldPaintCaret(true), | 55 m_shouldPaintCaret(true), |
| 59 m_isCaretBlinkingSuspended(false), | 56 m_isCaretBlinkingSuspended(false), |
| 60 m_shouldShowBlockCursor(false) {} | 57 m_shouldShowBlockCursor(false) {} |
| 61 | 58 |
| 62 FrameCaret::~FrameCaret() = default; | 59 FrameCaret::~FrameCaret() = default; |
| 63 | 60 |
| 64 DEFINE_TRACE(FrameCaret) { | 61 DEFINE_TRACE(FrameCaret) { |
| 65 visitor->trace(m_selectionEditor); | 62 visitor->trace(m_selectionEditor); |
| 66 visitor->trace(m_frame); | 63 visitor->trace(m_frame); |
| 67 visitor->trace(m_previousCaretNode); | |
| 68 visitor->trace(m_previousCaretAnchorNode); | |
| 69 SynchronousMutationObserver::trace(visitor); | 64 SynchronousMutationObserver::trace(visitor); |
| 70 } | 65 } |
| 71 | 66 |
| 72 void FrameCaret::documentAttached(Document* document) { | 67 void FrameCaret::documentAttached(Document* document) { |
| 73 setContext(document); | 68 setContext(document); |
| 74 } | 69 } |
| 75 | 70 |
| 76 const PositionWithAffinity FrameCaret::caretPosition() const { | 71 const PositionWithAffinity FrameCaret::caretPosition() const { |
| 77 const VisibleSelection& selection = | 72 const VisibleSelection& selection = |
| 78 m_selectionEditor->visibleSelection<EditingStrategy>(); | 73 m_selectionEditor->visibleSelection<EditingStrategy>(); |
| 79 if (!selection.isCaret()) | 74 if (!selection.isCaret()) |
| 80 return PositionWithAffinity(); | 75 return PositionWithAffinity(); |
| 81 return PositionWithAffinity(selection.start(), selection.affinity()); | 76 return PositionWithAffinity(selection.start(), selection.affinity()); |
| 82 } | 77 } |
| 83 | 78 |
| 84 const DisplayItemClient& FrameCaret::displayItemClient() const { | 79 void FrameCaret::setVisualRect(const LayoutRect& r) { |
| 80 m_caretBase->setVisualRect(r); | |
| 81 } | |
| 82 | |
| 83 const DisplayItemClient& FrameCaret::getDisplayItemClient() const { | |
| 85 return *m_caretBase; | 84 return *m_caretBase; |
| 86 } | 85 } |
| 87 | 86 |
| 88 inline static bool shouldStopBlinkingDueToTypingCommand(LocalFrame* frame) { | 87 inline static bool shouldStopBlinkingDueToTypingCommand(LocalFrame* frame) { |
| 89 return frame->editor().lastEditCommand() && | 88 return frame->editor().lastEditCommand() && |
| 90 frame->editor().lastEditCommand()->shouldStopCaretBlinking(); | 89 frame->editor().lastEditCommand()->shouldStopCaretBlinking(); |
| 91 } | 90 } |
| 92 | 91 |
| 93 void FrameCaret::updateAppearance() { | 92 void FrameCaret::updateAppearance() { |
| 94 // Paint a block cursor instead of a caret in overtype mode unless the caret | 93 // Paint a block cursor instead of a caret in overtype mode unless the caret |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 114 stopCaretBlinkTimer(); | 113 stopCaretBlinkTimer(); |
| 115 | 114 |
| 116 // Start blinking with a black caret. Be sure not to restart if we're | 115 // Start blinking with a black caret. Be sure not to restart if we're |
| 117 // already blinking in the right location. | 116 // already blinking in the right location. |
| 118 if (shouldBlink) | 117 if (shouldBlink) |
| 119 startBlinkCaret(); | 118 startBlinkCaret(); |
| 120 } | 119 } |
| 121 | 120 |
| 122 void FrameCaret::stopCaretBlinkTimer() { | 121 void FrameCaret::stopCaretBlinkTimer() { |
| 123 if (m_caretBlinkTimer.isActive() || m_shouldPaintCaret) | 122 if (m_caretBlinkTimer.isActive() || m_shouldPaintCaret) |
| 124 setCaretRectNeedsUpdate(); | 123 setNeedsPaintInvalidation(); |
| 125 m_shouldPaintCaret = false; | 124 m_shouldPaintCaret = false; |
| 126 m_caretBlinkTimer.stop(); | 125 m_caretBlinkTimer.stop(); |
| 127 } | 126 } |
| 128 | 127 |
| 129 void FrameCaret::startBlinkCaret() { | 128 void FrameCaret::startBlinkCaret() { |
| 130 // Start blinking with a black caret. Be sure not to restart if we're | 129 // Start blinking with a black caret. Be sure not to restart if we're |
| 131 // already blinking in the right location. | 130 // already blinking in the right location. |
| 132 if (m_caretBlinkTimer.isActive()) | 131 if (m_caretBlinkTimer.isActive()) |
| 133 return; | 132 return; |
| 134 | 133 |
| 135 if (double blinkInterval = LayoutTheme::theme().caretBlinkInterval()) | 134 if (double blinkInterval = LayoutTheme::theme().caretBlinkInterval()) |
| 136 m_caretBlinkTimer.startRepeating(blinkInterval, BLINK_FROM_HERE); | 135 m_caretBlinkTimer.startRepeating(blinkInterval, BLINK_FROM_HERE); |
| 137 | 136 |
| 138 m_shouldPaintCaret = true; | 137 m_shouldPaintCaret = true; |
| 139 setCaretRectNeedsUpdate(); | 138 setNeedsPaintInvalidation(); |
| 140 } | 139 } |
| 141 | 140 |
| 142 void FrameCaret::setCaretVisibility(CaretVisibility visibility) { | 141 void FrameCaret::setCaretVisibility(CaretVisibility visibility) { |
| 143 if (m_caretVisibility == visibility) | 142 if (m_caretVisibility == visibility) |
| 144 return; | 143 return; |
| 145 | 144 |
| 146 m_caretVisibility = visibility; | 145 m_caretVisibility = visibility; |
| 147 | 146 |
| 148 updateAppearance(); | 147 updateAppearance(); |
| 149 } | 148 } |
| 150 | 149 |
| 151 void FrameCaret::setCaretRectNeedsUpdate() { | 150 void FrameCaret::setMayNeedPaintInvalidation() { |
| 152 if (m_caretRectDirty) | 151 if (LayoutBlock* block = caretLayoutBlock()) |
|
yosin_UTC9
2017/01/31 20:12:58
Let's use early-return style to avoid to have (sin
| |
| 153 return; | 152 block->setMayNeedPaintInvalidation(); |
| 154 m_caretRectDirty = true; | 153 else |
| 154 scheduleVisualUpdate(); | |
| 155 } | |
| 155 | 156 |
| 157 void FrameCaret::setNeedsPaintInvalidation() { | |
| 158 if (LayoutBlock* block = caretLayoutBlock()) | |
| 159 block->setCaretsNeedPaintInvalidation(); | |
|
yosin_UTC9
2017/01/31 20:12:58
Let's use early-return style to avoid to have (sin
| |
| 160 else | |
| 161 scheduleVisualUpdate(); | |
| 162 } | |
| 163 | |
| 164 void FrameCaret::scheduleVisualUpdate() { | |
| 156 if (Page* page = m_frame->page()) | 165 if (Page* page = m_frame->page()) |
| 157 page->animator().scheduleVisualUpdate(m_frame->localFrameRoot()); | 166 page->animator().scheduleVisualUpdate(m_frame->localFrameRoot()); |
| 158 | |
| 159 // Ensure the frame will be checked for paint invalidation during | |
| 160 // PrePaintTreeWalk. | |
| 161 if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) { | |
|
chrishtr
2017/01/31 22:51:03
Why is this no longer needed?
Xianzhu
2017/02/02 23:42:06
Now block->setMayNeedPaintInvalidation() marks the
| |
| 162 if (auto layoutItem = m_frame->ownerLayoutItem()) | |
| 163 layoutItem.setMayNeedPaintInvalidation(); | |
| 164 } | |
| 165 } | 167 } |
| 166 | 168 |
| 167 bool FrameCaret::caretPositionIsValidForDocument( | 169 bool FrameCaret::caretPositionIsValidForDocument( |
| 168 const Document& document) const { | 170 const Document& document) const { |
| 169 if (!isActive()) | 171 if (!isActive()) |
| 170 return true; | 172 return true; |
| 171 | 173 |
| 172 return caretPosition().document() == document && !caretPosition().isOrphan(); | 174 return caretPosition().document() == document && !caretPosition().isOrphan(); |
| 173 } | 175 } |
| 174 | 176 |
| 175 static bool shouldRepaintCaret(Node& node) { | 177 LayoutRect FrameCaret::caretLocalRect() const { |
| 176 // If PositionAnchorType::BeforeAnchor or PositionAnchorType::AfterAnchor, | 178 if (!isActive()) |
| 177 // carets need to be repainted not only when the node is contentEditable but | 179 return LayoutRect(); |
| 178 // also when its parentNode() is contentEditable. | 180 return CaretDisplayItemClient::computeCaretRect(caretPosition()); |
| 179 node.document().updateStyleAndLayoutTree(); | |
| 180 return hasEditableStyle(node) || | |
| 181 (node.parentNode() && hasEditableStyle(*node.parentNode())); | |
| 182 } | 181 } |
| 183 | 182 |
| 184 void FrameCaret::invalidateCaretRect(bool forceInvalidation) { | 183 LayoutBlock* FrameCaret::caretLayoutBlock() const { |
| 185 if (!m_caretRectDirty) | 184 return CaretDisplayItemClient::caretLayoutObject( |
| 186 return; | 185 caretPosition().anchorNode()); |
| 187 m_caretRectDirty = false; | |
| 188 | |
| 189 DCHECK(caretPositionIsValidForDocument(*m_frame->document())); | |
| 190 LayoutObject* layoutObject = nullptr; | |
| 191 LayoutRect newRect; | |
| 192 PositionWithAffinity currentCaretPosition = caretPosition(); | |
| 193 if (isActive()) | |
| 194 newRect = localCaretRectOfPosition(currentCaretPosition, layoutObject); | |
| 195 Node* newNode = layoutObject ? layoutObject->node() : nullptr; | |
| 196 // The current selected node |newNode| could be a child multiple levels below | |
| 197 // its associated "anchor node" ancestor, so we reference and keep around the | |
| 198 // anchor node for checking editability. | |
| 199 // TODO(wkorman): Consider storing previous Position, rather than Node, and | |
| 200 // making use of EditingUtilies::isEditablePosition() directly. | |
| 201 Node* newAnchorNode = | |
| 202 currentCaretPosition.position().parentAnchoredEquivalent().anchorNode(); | |
| 203 if (newNode && newAnchorNode && newNode != newAnchorNode && | |
| 204 newAnchorNode->layoutObject() && newAnchorNode->layoutObject()->isBox()) { | |
| 205 newNode->layoutObject()->mapToVisualRectInAncestorSpace( | |
| 206 toLayoutBoxModelObject(newAnchorNode->layoutObject()), newRect); | |
| 207 } | |
| 208 // It's possible for the timer to be inactive even though we want to | |
| 209 // invalidate the caret. For example, when running as a layout test the | |
| 210 // caret blink interval could be zero and thus |m_caretBlinkTimer| will | |
| 211 // never be started. We provide |forceInvalidation| for use by paint | |
| 212 // invalidation internals where we need to invalidate the caret regardless | |
| 213 // of timer state. | |
| 214 if (!forceInvalidation && !m_caretBlinkTimer.isActive() && | |
| 215 newNode == m_previousCaretNode && newRect == m_previousCaretRect && | |
| 216 m_caretVisibility == m_previousCaretVisibility) | |
| 217 return; | |
| 218 | |
| 219 if (m_previousCaretAnchorNode && | |
| 220 shouldRepaintCaret(*m_previousCaretAnchorNode)) { | |
| 221 m_caretBase->invalidateLocalCaretRect(m_previousCaretAnchorNode.get(), | |
| 222 m_previousCaretRect); | |
| 223 } | |
| 224 if (newAnchorNode && shouldRepaintCaret(*newAnchorNode)) | |
| 225 m_caretBase->invalidateLocalCaretRect(newAnchorNode, newRect); | |
| 226 m_previousCaretNode = newNode; | |
| 227 m_previousCaretAnchorNode = newAnchorNode; | |
| 228 m_previousCaretRect = newRect; | |
| 229 m_previousCaretVisibility = m_caretVisibility; | |
| 230 } | |
| 231 | |
| 232 static IntRect absoluteBoundsForLocalRect(Node* node, const LayoutRect& rect) { | |
| 233 LayoutBlock* caretPainter = CaretDisplayItemClient::caretLayoutObject(node); | |
| 234 if (!caretPainter) | |
| 235 return IntRect(); | |
| 236 | |
| 237 LayoutRect localRect(rect); | |
| 238 caretPainter->flipForWritingMode(localRect); | |
| 239 return caretPainter->localToAbsoluteQuad(FloatRect(localRect)) | |
| 240 .enclosingBoundingBox(); | |
| 241 } | 186 } |
| 242 | 187 |
| 243 IntRect FrameCaret::absoluteCaretBounds() const { | 188 IntRect FrameCaret::absoluteCaretBounds() const { |
| 244 DCHECK_NE(m_frame->document()->lifecycle().state(), | 189 DCHECK_NE(m_frame->document()->lifecycle().state(), |
| 245 DocumentLifecycle::InPaintInvalidation); | 190 DocumentLifecycle::InPaintInvalidation); |
| 246 DCHECK(!m_frame->document()->needsLayoutTreeUpdate()); | 191 DCHECK(!m_frame->document()->needsLayoutTreeUpdate()); |
| 247 DocumentLifecycle::DisallowTransitionScope disallowTransition( | 192 DocumentLifecycle::DisallowTransitionScope disallowTransition( |
| 248 m_frame->document()->lifecycle()); | 193 m_frame->document()->lifecycle()); |
| 249 | 194 |
| 250 Node* const caretNode = caretPosition().anchorNode(); | |
| 251 if (!isActive()) | 195 if (!isActive()) |
| 252 return absoluteBoundsForLocalRect(caretNode, LayoutRect()); | 196 return IntRect(); |
| 197 | |
| 198 const LayoutBlock* block = caretLayoutBlock(); | |
| 199 if (!block) | |
| 200 return IntRect(); | |
| 201 | |
| 253 // TODO(yosin): We should get rid of text control short path since layout | 202 // TODO(yosin): We should get rid of text control short path since layout |
| 254 // tree is clean. | 203 // tree is clean. |
| 204 LayoutRect localRect; | |
| 255 if (enclosingTextControl(caretPosition().position()) && | 205 if (enclosingTextControl(caretPosition().position()) && |
| 256 isVisuallyEquivalentCandidate(caretPosition().position())) { | 206 isVisuallyEquivalentCandidate(caretPosition().position())) { |
| 257 return absoluteBoundsForLocalRect( | 207 localRect = this->caretLocalRect(); |
| 258 caretNode, CaretDisplayItemClient::computeCaretRect(caretPosition())); | 208 } else { |
| 209 localRect = CaretDisplayItemClient::computeCaretRect( | |
| 210 createVisiblePosition(caretPosition()).toPositionWithAffinity()); | |
| 259 } | 211 } |
| 260 return absoluteBoundsForLocalRect( | 212 |
| 261 caretNode, | 213 block->flipForWritingMode(localRect); |
| 262 CaretDisplayItemClient::computeCaretRect( | 214 return block->localToAbsoluteQuad(FloatRect(localRect)) |
| 263 createVisiblePosition(caretPosition()).toPositionWithAffinity())); | 215 .enclosingBoundingBox(); |
| 264 } | 216 } |
| 265 | 217 |
| 266 void FrameCaret::setShouldShowBlockCursor(bool shouldShowBlockCursor) { | 218 void FrameCaret::setShouldShowBlockCursor(bool shouldShowBlockCursor) { |
| 267 m_shouldShowBlockCursor = shouldShowBlockCursor; | 219 m_shouldShowBlockCursor = shouldShowBlockCursor; |
| 268 | 220 |
| 269 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 221 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
| 270 | 222 |
| 271 updateAppearance(); | 223 updateAppearance(); |
| 272 } | 224 } |
| 273 | 225 |
| 274 void FrameCaret::paintCaret(GraphicsContext& context, | 226 void FrameCaret::paintCaret(GraphicsContext& context, |
| 275 const LayoutPoint& paintOffset) { | 227 const LayoutPoint& paintOffset) { |
| 276 if (m_caretVisibility == CaretVisibility::Hidden) | 228 if (m_caretVisibility == CaretVisibility::Hidden) |
| 277 return; | 229 return; |
| 278 | 230 |
| 279 if (!(isActive() && m_shouldPaintCaret)) | 231 if (!(isActive() && m_shouldPaintCaret)) |
| 280 return; | 232 return; |
| 281 | 233 |
| 282 const LayoutRect caretLocalRect = | 234 m_caretBase->paintCaret(caretPosition().anchorNode(), context, |
| 283 CaretDisplayItemClient::computeCaretRect(caretPosition()); | 235 caretLocalRect(), paintOffset, DisplayItem::kCaret); |
|
yosin_UTC9
2017/01/31 20:12:58
Yes, this is what I thought. It is redundant to ca
| |
| 284 m_caretBase->paintCaret(caretPosition().anchorNode(), context, caretLocalRect, | |
| 285 paintOffset, DisplayItem::kCaret); | |
| 286 } | |
| 287 | |
| 288 void FrameCaret::dataWillChange(const CharacterData& node) { | |
| 289 if (node == m_previousCaretNode) { | |
| 290 // This invalidation is eager, and intentionally uses stale state. | |
| 291 DisableCompositingQueryAsserts disabler; | |
| 292 m_caretBase->invalidateLocalCaretRect(m_previousCaretAnchorNode.get(), | |
| 293 m_previousCaretRect); | |
| 294 } | |
| 295 } | |
| 296 | |
| 297 void FrameCaret::nodeWillBeRemoved(Node& node) { | |
| 298 if (node != m_previousCaretNode && node != m_previousCaretAnchorNode) | |
| 299 return; | |
| 300 // Hits in ManualTests/caret-paint-after-last-text-is-removed.html | |
| 301 DisableCompositingQueryAsserts disabler; | |
| 302 m_caretBase->invalidateLocalCaretRect(m_previousCaretAnchorNode.get(), | |
| 303 m_previousCaretRect); | |
| 304 m_previousCaretNode = nullptr; | |
| 305 m_previousCaretAnchorNode = nullptr; | |
| 306 m_previousCaretRect = LayoutRect(); | |
| 307 m_previousCaretVisibility = CaretVisibility::Hidden; | |
| 308 } | 236 } |
| 309 | 237 |
| 310 void FrameCaret::contextDestroyed(Document*) { | 238 void FrameCaret::contextDestroyed(Document*) { |
| 311 m_caretBlinkTimer.stop(); | 239 m_caretBlinkTimer.stop(); |
| 312 m_previousCaretNode.clear(); | |
| 313 m_previousCaretAnchorNode.clear(); | |
| 314 } | 240 } |
| 315 | 241 |
| 316 bool FrameCaret::shouldBlinkCaret() const { | 242 bool FrameCaret::shouldBlinkCaret() const { |
| 317 if (m_caretVisibility != CaretVisibility::Visible || !isActive()) | 243 if (m_caretVisibility != CaretVisibility::Visible || !isActive()) |
| 318 return false; | 244 return false; |
| 319 | 245 |
| 320 Element* root = rootEditableElementOf(caretPosition().position()); | 246 Element* root = rootEditableElementOf(caretPosition().position()); |
| 321 if (!root) | 247 if (!root) |
| 322 return false; | 248 return false; |
| 323 | 249 |
| 324 Element* focusedElement = root->document().focusedElement(); | 250 Element* focusedElement = root->document().focusedElement(); |
| 325 if (!focusedElement) | 251 if (!focusedElement) |
| 326 return false; | 252 return false; |
| 327 | 253 |
| 328 return focusedElement->isShadowIncludingInclusiveAncestorOf( | 254 return focusedElement->isShadowIncludingInclusiveAncestorOf( |
| 329 caretPosition().anchorNode()); | 255 caretPosition().anchorNode()); |
| 330 } | 256 } |
| 331 | 257 |
| 332 void FrameCaret::caretBlinkTimerFired(TimerBase*) { | 258 void FrameCaret::caretBlinkTimerFired(TimerBase*) { |
| 333 DCHECK_EQ(m_caretVisibility, CaretVisibility::Visible); | 259 DCHECK_EQ(m_caretVisibility, CaretVisibility::Visible); |
| 334 if (isCaretBlinkingSuspended() && m_shouldPaintCaret) | 260 if (isCaretBlinkingSuspended() && m_shouldPaintCaret) |
| 335 return; | 261 return; |
| 336 m_shouldPaintCaret = !m_shouldPaintCaret; | 262 m_shouldPaintCaret = !m_shouldPaintCaret; |
| 337 setCaretRectNeedsUpdate(); | 263 setNeedsPaintInvalidation(); |
| 338 } | 264 } |
| 339 | 265 |
| 340 } // namespace blink | 266 } // namespace blink |
| OLD | NEW |