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

Side by Side Diff: third_party/WebKit/Source/core/editing/FrameCaret.cpp

Issue 1958093002: CONTINUED Make FrameSelection to hold non-canonicalized positions Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 2017-01-16T20:04:35 Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
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
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26 #include "core/editing/FrameCaret.h" 26 #include "core/editing/FrameCaret.h"
27 27
28 #include "core/dom/TaskRunnerHelper.h" 28 #include "core/dom/TaskRunnerHelper.h"
29 #include "core/editing/CaretBase.h"
29 #include "core/editing/EditingUtilities.h" 30 #include "core/editing/EditingUtilities.h"
30 #include "core/editing/Editor.h" 31 #include "core/editing/Editor.h"
31 #include "core/editing/SelectionEditor.h" 32 #include "core/editing/SelectionEditor.h"
32 #include "core/editing/commands/CompositeEditCommand.h" 33 #include "core/editing/commands/CompositeEditCommand.h"
33 #include "core/frame/FrameView.h" 34 #include "core/frame/FrameView.h"
34 #include "core/frame/LocalFrame.h" 35 #include "core/frame/LocalFrame.h"
35 #include "core/frame/Settings.h" 36 #include "core/frame/Settings.h"
36 #include "core/html/TextControlElement.h" 37 #include "core/html/TextControlElement.h"
38 #include "core/layout/LayoutBlock.h"
37 #include "core/layout/LayoutTheme.h" 39 #include "core/layout/LayoutTheme.h"
38 #include "core/layout/api/LayoutPartItem.h" 40 #include "core/layout/api/LayoutPartItem.h"
39 #include "core/page/Page.h" 41 #include "core/page/Page.h"
40 #include "core/paint/PaintLayer.h" 42 #include "core/paint/PaintLayer.h"
41 #include "public/platform/WebTraceLocation.h" 43 #include "public/platform/WebTraceLocation.h"
42 44
43 namespace blink { 45 namespace blink {
44 46
45 FrameCaret::FrameCaret(LocalFrame& frame, 47 FrameCaret::FrameCaret(LocalFrame& frame,
46 const SelectionEditor& selectionEditor) 48 const SelectionEditor& selectionEditor)
47 : m_selectionEditor(&selectionEditor), 49 : m_selectionEditor(&selectionEditor),
48 m_frame(frame), 50 m_frame(frame),
51 m_caretBase(new CaretBase()),
49 m_caretVisibility(CaretVisibility::Hidden), 52 m_caretVisibility(CaretVisibility::Hidden),
50 m_previousCaretVisibility(CaretVisibility::Hidden), 53 m_previousCaretVisibility(CaretVisibility::Hidden),
51 m_caretBlinkTimer(TaskRunnerHelper::get(TaskType::UnspecedTimer, &frame), 54 m_caretBlinkTimer(TaskRunnerHelper::get(TaskType::UnspecedTimer, &frame),
52 this, 55 this,
53 &FrameCaret::caretBlinkTimerFired), 56 &FrameCaret::caretBlinkTimerFired),
54 m_caretRectDirty(true), 57 m_didScheduleUpdate(true),
55 m_shouldPaintCaret(true), 58 m_shouldPaintCaret(true),
56 m_isCaretBlinkingSuspended(false), 59 m_isCaretBlinkingSuspended(false),
57 m_shouldShowBlockCursor(false) {} 60 m_shouldShowBlockCursor(false) {}
58 61
59 FrameCaret::~FrameCaret() = default; 62 FrameCaret::~FrameCaret() = default;
60 63
61 DEFINE_TRACE(FrameCaret) { 64 DEFINE_TRACE(FrameCaret) {
62 visitor->trace(m_selectionEditor); 65 visitor->trace(m_selectionEditor);
63 visitor->trace(m_frame); 66 visitor->trace(m_frame);
64 visitor->trace(m_previousCaretNode); 67 visitor->trace(m_previousCaretNode);
65 visitor->trace(m_previousCaretAnchorNode); 68 visitor->trace(m_previousCaretAnchorNode);
66 CaretBase::trace(visitor); 69 SynchronousMutationObserver::trace(visitor);
70 }
71
72 void FrameCaret::documentAttached(Document* document) {
73 setContext(document);
67 } 74 }
68 75
69 const PositionWithAffinity FrameCaret::caretPosition() const { 76 const PositionWithAffinity FrameCaret::caretPosition() const {
70 const VisibleSelection& selection = 77 const VisibleSelection& selection =
71 m_selectionEditor->visibleSelection<EditingStrategy>(); 78 m_selectionEditor->computeVisibleSelectionInDOMTree();
72 if (!selection.isCaret()) 79 if (!selection.isCaret())
73 return PositionWithAffinity(); 80 return PositionWithAffinity();
74 return PositionWithAffinity(selection.start(), selection.affinity()); 81 return PositionWithAffinity(selection.start(), selection.affinity());
75 } 82 }
76 83
84 const DisplayItemClient& FrameCaret::displayItemClient() const {
85 return *m_caretBase;
86 }
87
77 inline static bool shouldStopBlinkingDueToTypingCommand(LocalFrame* frame) { 88 inline static bool shouldStopBlinkingDueToTypingCommand(LocalFrame* frame) {
78 return frame->editor().lastEditCommand() && 89 return frame->editor().lastEditCommand() &&
79 frame->editor().lastEditCommand()->shouldStopCaretBlinking(); 90 frame->editor().lastEditCommand()->shouldStopCaretBlinking();
80 } 91 }
81 92
82 void FrameCaret::updateAppearance() { 93 void FrameCaret::updateAppearance() {
94 DCHECK_GE(lifecycleContext()->lifecycle().state(),
95 DocumentLifecycle::AfterPerformLayout);
83 // Paint a block cursor instead of a caret in overtype mode unless the caret 96 // Paint a block cursor instead of a caret in overtype mode unless the caret
84 // is at the end of a line (in this case the FrameSelection will paint a 97 // is at the end of a line (in this case the FrameSelection will paint a
85 // blinking caret as usual). 98 // blinking caret as usual).
86 bool paintBlockCursor = m_shouldShowBlockCursor && isActive(); 99 bool paintBlockCursor = m_shouldShowBlockCursor && isActive();
87 if (paintBlockCursor) { 100 if (paintBlockCursor &&
88 // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets 101 isLogicalEndOfLine(createVisiblePosition(caretPosition()))) {
89 // needs to be audited. see http://crbug.com/590369 for more details. 102 paintBlockCursor = false;
90 // In the long term, we should defer the update of the caret's appearance
91 // to prevent synchronous layout.
92 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets();
93
94 if (isLogicalEndOfLine(createVisiblePosition(caretPosition())))
95 paintBlockCursor = false;
96 } 103 }
97 104
98 bool shouldBlink = !paintBlockCursor && shouldBlinkCaret(); 105 bool shouldBlink = !paintBlockCursor && shouldBlinkCaret();
99 106
100 // If the caret moved, stop the blink timer so we can restart with a 107 // If the caret moved, stop the blink timer so we can restart with a
101 // black caret in the new location. 108 // black caret in the new location.
102 if (!shouldBlink || shouldStopBlinkingDueToTypingCommand(m_frame)) 109 if (!shouldBlink || shouldStopBlinkingDueToTypingCommand(m_frame))
103 stopCaretBlinkTimer(); 110 stopCaretBlinkTimer();
104 111
105 // Start blinking with a black caret. Be sure not to restart if we're 112 // Start blinking with a black caret. Be sure not to restart if we're
(...skipping 21 matching lines...) Expand all
127 m_shouldPaintCaret = true; 134 m_shouldPaintCaret = true;
128 setCaretRectNeedsUpdate(); 135 setCaretRectNeedsUpdate();
129 } 136 }
130 137
131 void FrameCaret::setCaretVisibility(CaretVisibility visibility) { 138 void FrameCaret::setCaretVisibility(CaretVisibility visibility) {
132 if (m_caretVisibility == visibility) 139 if (m_caretVisibility == visibility)
133 return; 140 return;
134 141
135 m_caretVisibility = visibility; 142 m_caretVisibility = visibility;
136 143
137 updateAppearance(); 144 setCaretRectNeedsUpdate();
138 } 145 }
139 146
140 void FrameCaret::setCaretRectNeedsUpdate() { 147 void FrameCaret::setCaretRectNeedsUpdate() {
141 if (m_caretRectDirty) 148 if (m_didScheduleUpdate)
142 return; 149 return;
143 m_caretRectDirty = true; 150 m_didScheduleUpdate = true;
144 151
145 if (Page* page = m_frame->page()) 152 if (Page* page = m_frame->page())
146 page->animator().scheduleVisualUpdate(m_frame->localFrameRoot()); 153 page->animator().scheduleVisualUpdate(m_frame->localFrameRoot());
147 154
148 // Ensure the frame will be checked for paint invalidation during 155 // Ensure the frame will be checked for paint invalidation during
149 // PrePaintTreeWalk. 156 // PrePaintTreeWalk.
150 if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) { 157 if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) {
151 if (auto layoutItem = m_frame->ownerLayoutItem()) 158 if (auto layoutItem = m_frame->ownerLayoutItem())
152 layoutItem.setMayNeedPaintInvalidation(); 159 layoutItem.setMayNeedPaintInvalidation();
153 } 160 }
154 } 161 }
155 162
156 bool FrameCaret::caretPositionIsValidForDocument( 163 bool FrameCaret::caretPositionIsValidForDocument(
157 const Document& document) const { 164 const Document& document) const {
158 if (!isActive()) 165 if (!isActive())
159 return true; 166 return true;
160 167
161 return caretPosition().document() == document && !caretPosition().isOrphan(); 168 return caretPosition().document() == document && !caretPosition().isOrphan();
162 } 169 }
163 170
171 static bool shouldRepaintCaret(Node& node) {
172 // If PositionAnchorType::BeforeAnchor or PositionAnchorType::AfterAnchor,
173 // carets need to be repainted not only when the node is contentEditable but
174 // also when its parentNode() is contentEditable.
175 node.document().updateStyleAndLayoutTree();
176 return hasEditableStyle(node) ||
177 (node.parentNode() && hasEditableStyle(*node.parentNode()));
178 }
179
164 void FrameCaret::invalidateCaretRect(bool forceInvalidation) { 180 void FrameCaret::invalidateCaretRect(bool forceInvalidation) {
165 if (!m_caretRectDirty) 181 updateAppearance();
166 return; 182 m_didScheduleUpdate = false;
167 m_caretRectDirty = false;
168 183
169 DCHECK(caretPositionIsValidForDocument(*m_frame->document())); 184 DCHECK(caretPositionIsValidForDocument(*m_frame->document()));
170 LayoutObject* layoutObject = nullptr; 185 LayoutObject* layoutObject = nullptr;
171 LayoutRect newRect; 186 LayoutRect newRect;
172 PositionWithAffinity currentCaretPosition = caretPosition(); 187 PositionWithAffinity currentCaretPosition = caretPosition();
188 const Node* const colorNode = caretPosition().anchorNode();
189 Color newCaretColor =
190 colorNode ? colorNode->layoutObject()->resolveColor(CSSPropertyCaretColor)
191 : Color();
173 if (isActive()) 192 if (isActive())
174 newRect = localCaretRectOfPosition(currentCaretPosition, layoutObject); 193 newRect = localCaretRectOfPosition(currentCaretPosition, layoutObject);
175 Node* newNode = layoutObject ? layoutObject->node() : nullptr; 194 Node* newNode = layoutObject ? layoutObject->node() : nullptr;
176 // The current selected node |newNode| could be a child multiple levels below 195 // The current selected node |newNode| could be a child multiple levels below
177 // its associated "anchor node" ancestor, so we reference and keep around the 196 // its associated "anchor node" ancestor, so we reference and keep around the
178 // anchor node for checking editability. 197 // anchor node for checking editability.
179 // TODO(wkorman): Consider storing previous Position, rather than Node, and 198 // TODO(wkorman): Consider storing previous Position, rather than Node, and
180 // making use of EditingUtilies::isEditablePosition() directly. 199 // making use of EditingUtilies::isEditablePosition() directly.
181 Node* newAnchorNode = 200 Node* newAnchorNode =
182 currentCaretPosition.position().parentAnchoredEquivalent().anchorNode(); 201 currentCaretPosition.position().parentAnchoredEquivalent().anchorNode();
183 if (newNode && newAnchorNode && newNode != newAnchorNode && 202 if (newNode && newAnchorNode && newNode != newAnchorNode &&
184 newAnchorNode->layoutObject() && newAnchorNode->layoutObject()->isBox()) { 203 newAnchorNode->layoutObject() && newAnchorNode->layoutObject()->isBox()) {
185 newNode->layoutObject()->mapToVisualRectInAncestorSpace( 204 newNode->layoutObject()->mapToVisualRectInAncestorSpace(
186 toLayoutBoxModelObject(newAnchorNode->layoutObject()), newRect); 205 toLayoutBoxModelObject(newAnchorNode->layoutObject()), newRect);
187 } 206 }
188 // It's possible for the timer to be inactive even though we want to 207 // It's possible for the timer to be inactive even though we want to
189 // invalidate the caret. For example, when running as a layout test the 208 // invalidate the caret. For example, when running as a layout test the
190 // caret blink interval could be zero and thus |m_caretBlinkTimer| will 209 // caret blink interval could be zero and thus |m_caretBlinkTimer| will
191 // never be started. We provide |forceInvalidation| for use by paint 210 // never be started. We provide |forceInvalidation| for use by paint
192 // invalidation internals where we need to invalidate the caret regardless 211 // invalidation internals where we need to invalidate the caret regardless
193 // of timer state. 212 // of timer state.
194 if (!forceInvalidation && !m_caretBlinkTimer.isActive() && 213 if (!forceInvalidation && !m_caretBlinkTimer.isActive() &&
195 newNode == m_previousCaretNode && newRect == m_previousCaretRect && 214 newNode == m_previousCaretNode && newRect == m_previousCaretRect &&
196 m_caretVisibility == m_previousCaretVisibility) 215 m_caretVisibility == m_previousCaretVisibility &&
216 newCaretColor == m_previousCaretColor) {
197 return; 217 return;
218 }
198 219
199 if (m_previousCaretAnchorNode && 220 if (m_previousCaretAnchorNode &&
200 shouldRepaintCaret(*m_previousCaretAnchorNode)) { 221 shouldRepaintCaret(*m_previousCaretAnchorNode)) {
201 invalidateLocalCaretRect(m_previousCaretAnchorNode.get(), 222 m_caretBase->invalidateLocalCaretRect(m_previousCaretAnchorNode.get(),
202 m_previousCaretRect); 223 m_previousCaretRect);
203 } 224 }
204 if (newAnchorNode && shouldRepaintCaret(*newAnchorNode)) 225 if (newAnchorNode && shouldRepaintCaret(*newAnchorNode))
205 invalidateLocalCaretRect(newAnchorNode, newRect); 226 m_caretBase->invalidateLocalCaretRect(newAnchorNode, newRect);
206 m_previousCaretNode = newNode; 227 m_previousCaretNode = newNode;
207 m_previousCaretAnchorNode = newAnchorNode; 228 m_previousCaretAnchorNode = newAnchorNode;
208 m_previousCaretRect = newRect; 229 m_previousCaretRect = newRect;
209 m_previousCaretVisibility = m_caretVisibility; 230 m_previousCaretVisibility = m_caretVisibility;
231 m_previousCaretColor = newCaretColor;
232 }
233
234 static IntRect absoluteBoundsForLocalRect(Node* node, const LayoutRect& rect) {
235 LayoutBlock* caretPainter = CaretBase::caretLayoutObject(node);
236 if (!caretPainter)
237 return IntRect();
238
239 LayoutRect localRect(rect);
240 caretPainter->flipForWritingMode(localRect);
241 return caretPainter->localToAbsoluteQuad(FloatRect(localRect))
242 .enclosingBoundingBox();
210 } 243 }
211 244
212 // TDOO(yosin): We should mark |FrameCaret::absoluteCaretBounds()| to |const|. 245 // TDOO(yosin): We should mark |FrameCaret::absoluteCaretBounds()| to |const|.
213 IntRect FrameCaret::absoluteCaretBounds() { 246 IntRect FrameCaret::absoluteCaretBounds() {
214 DCHECK_NE(m_frame->document()->lifecycle().state(), 247 DCHECK_NE(m_frame->document()->lifecycle().state(),
215 DocumentLifecycle::InPaintInvalidation); 248 DocumentLifecycle::InPaintInvalidation);
216 DCHECK(!m_frame->document()->needsLayoutTreeUpdate()); 249 DCHECK(!m_frame->document()->needsLayoutTreeUpdate());
217 DocumentLifecycle::DisallowTransitionScope disallowTransition( 250 DocumentLifecycle::DisallowTransitionScope disallowTransition(
218 m_frame->document()->lifecycle()); 251 m_frame->document()->lifecycle());
219 252
220 Node* const caretNode = caretPosition().anchorNode(); 253 Node* const caretNode = caretPosition().anchorNode();
221 if (!isActive()) 254 if (!isActive())
222 return absoluteBoundsForLocalRect(caretNode, LayoutRect()); 255 return absoluteBoundsForLocalRect(caretNode, LayoutRect());
223 // TODO(yosin): We should get rid of text control short path since layout 256 // TODO(yosin): We should get rid of text control short path since layout
224 // tree is clean. 257 // tree is clean.
225 if (enclosingTextControl(caretPosition().position()) && 258 if (enclosingTextControl(caretPosition().position()) &&
226 isVisuallyEquivalentCandidate(caretPosition().position())) { 259 isVisuallyEquivalentCandidate(caretPosition().position())) {
227 return absoluteBoundsForLocalRect(caretNode, 260 return absoluteBoundsForLocalRect(
228 computeCaretRect(caretPosition())); 261 caretNode, CaretBase::computeCaretRect(caretPosition()));
229 } 262 }
230 return absoluteBoundsForLocalRect( 263 return absoluteBoundsForLocalRect(
231 caretNode, computeCaretRect(createVisiblePosition(caretPosition()))); 264 caretNode,
265 CaretBase::computeCaretRect(
266 createVisiblePosition(caretPosition()).toPositionWithAffinity()));
232 } 267 }
233 268
234 void FrameCaret::setShouldShowBlockCursor(bool shouldShowBlockCursor) { 269 void FrameCaret::setShouldShowBlockCursor(bool shouldShowBlockCursor) {
235 m_shouldShowBlockCursor = shouldShowBlockCursor; 270 m_shouldShowBlockCursor = shouldShowBlockCursor;
236 271
237 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); 272 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets();
238 273
239 updateAppearance(); 274 setCaretRectNeedsUpdate();
240 } 275 }
241 276
242 void FrameCaret::paintCaret(GraphicsContext& context, 277 void FrameCaret::paintCaret(GraphicsContext& context,
243 const LayoutPoint& paintOffset) { 278 const LayoutPoint& paintOffset) {
244 if (m_caretVisibility == CaretVisibility::Hidden) 279 if (m_caretVisibility == CaretVisibility::Hidden)
245 return; 280 return;
246 281
247 if (!(isActive() && m_shouldPaintCaret)) 282 if (!(isActive() && m_shouldPaintCaret))
248 return; 283 return;
249 284
250 const LayoutRect caretLocalRect = computeCaretRect(caretPosition()); 285 const LayoutRect caretLocalRect =
251 CaretBase::paintCaret(caretPosition().anchorNode(), context, *this, 286 CaretBase::computeCaretRect(caretPosition());
252 caretLocalRect, paintOffset, DisplayItem::kCaret); 287 m_caretBase->paintCaret(caretPosition().anchorNode(), context, caretLocalRect,
288 paintOffset, DisplayItem::kCaret);
253 } 289 }
254 290
255 void FrameCaret::dataWillChange(const CharacterData& node) { 291 void FrameCaret::dataWillChange(const CharacterData& node) {
256 if (node == m_previousCaretNode) { 292 if (node == m_previousCaretNode) {
257 // This invalidation is eager, and intentionally uses stale state. 293 // This invalidation is eager, and intentionally uses stale state.
258 DisableCompositingQueryAsserts disabler; 294 DisableCompositingQueryAsserts disabler;
259 invalidateLocalCaretRect(m_previousCaretAnchorNode.get(), 295 m_caretBase->invalidateLocalCaretRect(m_previousCaretAnchorNode.get(),
260 m_previousCaretRect); 296 m_previousCaretRect);
261 } 297 }
262 } 298 }
263 299
264 void FrameCaret::nodeWillBeRemoved(Node& node) { 300 void FrameCaret::nodeWillBeRemoved(Node& node) {
265 if (node != m_previousCaretNode && node != m_previousCaretAnchorNode) 301 if (node != m_previousCaretNode && node != m_previousCaretAnchorNode)
266 return; 302 return;
267 // Hits in ManualTests/caret-paint-after-last-text-is-removed.html 303 // Hits in ManualTests/caret-paint-after-last-text-is-removed.html
268 DisableCompositingQueryAsserts disabler; 304 DisableCompositingQueryAsserts disabler;
269 invalidateLocalCaretRect(m_previousCaretAnchorNode.get(), 305 m_caretBase->invalidateLocalCaretRect(m_previousCaretAnchorNode.get(),
270 m_previousCaretRect); 306 m_previousCaretRect);
271 m_previousCaretNode = nullptr; 307 m_previousCaretNode = nullptr;
272 m_previousCaretAnchorNode = nullptr; 308 m_previousCaretAnchorNode = nullptr;
273 m_previousCaretRect = LayoutRect(); 309 m_previousCaretRect = LayoutRect();
274 m_previousCaretVisibility = CaretVisibility::Hidden; 310 m_previousCaretVisibility = CaretVisibility::Hidden;
275 } 311 }
276 312
277 void FrameCaret::documentDetached() { 313 void FrameCaret::contextDestroyed(Document*) {
278 m_caretBlinkTimer.stop(); 314 m_caretBlinkTimer.stop();
279 m_previousCaretNode.clear(); 315 m_previousCaretNode.clear();
280 m_previousCaretAnchorNode.clear(); 316 m_previousCaretAnchorNode.clear();
281 } 317 }
282 318
283 bool FrameCaret::shouldBlinkCaret() const { 319 bool FrameCaret::shouldBlinkCaret() const {
284 if (m_caretVisibility != CaretVisibility::Visible || !isActive()) 320 if (m_caretVisibility != CaretVisibility::Visible || !isActive())
285 return false; 321 return false;
286 322
287 Element* root = rootEditableElementOf(caretPosition().position()); 323 Element* root = rootEditableElementOf(caretPosition().position());
(...skipping 10 matching lines...) Expand all
298 334
299 void FrameCaret::caretBlinkTimerFired(TimerBase*) { 335 void FrameCaret::caretBlinkTimerFired(TimerBase*) {
300 DCHECK_EQ(m_caretVisibility, CaretVisibility::Visible); 336 DCHECK_EQ(m_caretVisibility, CaretVisibility::Visible);
301 if (isCaretBlinkingSuspended() && m_shouldPaintCaret) 337 if (isCaretBlinkingSuspended() && m_shouldPaintCaret)
302 return; 338 return;
303 m_shouldPaintCaret = !m_shouldPaintCaret; 339 m_shouldPaintCaret = !m_shouldPaintCaret;
304 setCaretRectNeedsUpdate(); 340 setCaretRectNeedsUpdate();
305 } 341 }
306 342
307 } // namespace blink 343 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/editing/FrameCaret.h ('k') | third_party/WebKit/Source/core/editing/FrameSelection.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698