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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 return PositionWithAffinity(); | 74 return PositionWithAffinity(); |
75 return PositionWithAffinity(selection.start(), selection.affinity()); | 75 return PositionWithAffinity(selection.start(), selection.affinity()); |
76 } | 76 } |
77 | 77 |
78 inline static bool shouldStopBlinkingDueToTypingCommand(LocalFrame* frame) { | 78 inline static bool shouldStopBlinkingDueToTypingCommand(LocalFrame* frame) { |
79 return frame->editor().lastEditCommand() && | 79 return frame->editor().lastEditCommand() && |
80 frame->editor().lastEditCommand()->shouldStopCaretBlinking(); | 80 frame->editor().lastEditCommand()->shouldStopCaretBlinking(); |
81 } | 81 } |
82 | 82 |
83 void FrameCaret::updateAppearance() { | 83 void FrameCaret::updateAppearance() { |
| 84 DCHECK_GE(m_frame->document()->lifecycle().state(), |
| 85 DocumentLifecycle::LayoutClean); |
84 // Paint a block cursor instead of a caret in overtype mode unless the caret | 86 // Paint a block cursor instead of a caret in overtype mode unless the caret |
85 // is at the end of a line (in this case the FrameSelection will paint a | 87 // is at the end of a line (in this case the FrameSelection will paint a |
86 // blinking caret as usual). | 88 // blinking caret as usual). |
87 bool paintBlockCursor = m_shouldShowBlockCursor && isActive(); | 89 const bool paintBlockCursor = |
88 if (paintBlockCursor) { | 90 m_shouldShowBlockCursor && isActive() && |
89 // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets | 91 !isLogicalEndOfLine(createVisiblePosition(caretPosition())); |
90 // needs to be audited. see http://crbug.com/590369 for more details. | |
91 // In the long term, we should defer the update of the caret's appearance | |
92 // to prevent synchronous layout. | |
93 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | |
94 | |
95 if (isLogicalEndOfLine(createVisiblePosition(caretPosition()))) | |
96 paintBlockCursor = false; | |
97 } | |
98 | 92 |
99 bool shouldBlink = !paintBlockCursor && shouldBlinkCaret(); | 93 bool shouldBlink = !paintBlockCursor && shouldBlinkCaret(); |
100 | 94 |
101 // If the caret moved, stop the blink timer so we can restart with a | 95 // If the caret moved, stop the blink timer so we can restart with a |
102 // black caret in the new location. | 96 // black caret in the new location. |
103 if (!shouldBlink || shouldStopBlinkingDueToTypingCommand(m_frame)) | 97 if (!shouldBlink || shouldStopBlinkingDueToTypingCommand(m_frame)) |
104 stopCaretBlinkTimer(); | 98 stopCaretBlinkTimer(); |
105 | 99 |
106 // Start blinking with a black caret. Be sure not to restart if we're | 100 // Start blinking with a black caret. Be sure not to restart if we're |
107 // already blinking in the right location. | 101 // already blinking in the right location. |
(...skipping 20 matching lines...) Expand all Loading... |
128 m_shouldPaintCaret = true; | 122 m_shouldPaintCaret = true; |
129 scheduleVisualUpdateForPaintInvalidationIfNeeded(); | 123 scheduleVisualUpdateForPaintInvalidationIfNeeded(); |
130 } | 124 } |
131 | 125 |
132 void FrameCaret::setCaretVisibility(CaretVisibility visibility) { | 126 void FrameCaret::setCaretVisibility(CaretVisibility visibility) { |
133 if (m_caretVisibility == visibility) | 127 if (m_caretVisibility == visibility) |
134 return; | 128 return; |
135 | 129 |
136 m_caretVisibility = visibility; | 130 m_caretVisibility = visibility; |
137 | 131 |
138 updateAppearance(); | 132 if (visibility == CaretVisibility::Hidden) |
| 133 stopCaretBlinkTimer(); |
139 scheduleVisualUpdateForPaintInvalidationIfNeeded(); | 134 scheduleVisualUpdateForPaintInvalidationIfNeeded(); |
140 } | 135 } |
141 | 136 |
142 void FrameCaret::clearPreviousVisualRect(const LayoutBlock& block) { | 137 void FrameCaret::clearPreviousVisualRect(const LayoutBlock& block) { |
143 m_displayItemClient->clearPreviousVisualRect(block); | 138 m_displayItemClient->clearPreviousVisualRect(block); |
144 } | 139 } |
145 | 140 |
146 void FrameCaret::layoutBlockWillBeDestroyed(const LayoutBlock& block) { | 141 void FrameCaret::layoutBlockWillBeDestroyed(const LayoutBlock& block) { |
147 m_displayItemClient->layoutBlockWillBeDestroyed(block); | 142 m_displayItemClient->layoutBlockWillBeDestroyed(block); |
148 } | 143 } |
149 | 144 |
150 void FrameCaret::updateStyleAndLayoutIfNeeded() { | 145 void FrameCaret::updateStyleAndLayoutIfNeeded() { |
| 146 DCHECK_GE(m_frame->document()->lifecycle().state(), |
| 147 DocumentLifecycle::LayoutClean); |
| 148 updateAppearance(); |
151 bool shouldPaintCaret = | 149 bool shouldPaintCaret = |
152 m_shouldPaintCaret && isActive() && | 150 m_shouldPaintCaret && isActive() && |
153 m_caretVisibility == CaretVisibility::Visible && | 151 m_caretVisibility == CaretVisibility::Visible && |
154 m_selectionEditor->visibleSelection<EditingStrategy>().hasEditableStyle(); | 152 m_selectionEditor->visibleSelection<EditingStrategy>().hasEditableStyle(); |
155 | 153 |
156 m_displayItemClient->updateStyleAndLayoutIfNeeded( | 154 m_displayItemClient->updateStyleAndLayoutIfNeeded( |
157 shouldPaintCaret ? caretPosition() : PositionWithAffinity()); | 155 shouldPaintCaret ? caretPosition() : PositionWithAffinity()); |
158 } | 156 } |
159 | 157 |
160 void FrameCaret::invalidatePaintIfNeeded(const LayoutBlock& block, | 158 void FrameCaret::invalidatePaintIfNeeded(const LayoutBlock& block, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 if (!isActive()) | 190 if (!isActive()) |
193 return absoluteBoundsForLocalRect(caretNode, LayoutRect()); | 191 return absoluteBoundsForLocalRect(caretNode, LayoutRect()); |
194 return absoluteBoundsForLocalRect( | 192 return absoluteBoundsForLocalRect( |
195 caretNode, | 193 caretNode, |
196 CaretDisplayItemClient::computeCaretRect( | 194 CaretDisplayItemClient::computeCaretRect( |
197 createVisiblePosition(caretPosition()).toPositionWithAffinity())); | 195 createVisiblePosition(caretPosition()).toPositionWithAffinity())); |
198 } | 196 } |
199 | 197 |
200 void FrameCaret::setShouldShowBlockCursor(bool shouldShowBlockCursor) { | 198 void FrameCaret::setShouldShowBlockCursor(bool shouldShowBlockCursor) { |
201 m_shouldShowBlockCursor = shouldShowBlockCursor; | 199 m_shouldShowBlockCursor = shouldShowBlockCursor; |
202 | 200 scheduleVisualUpdateForPaintInvalidationIfNeeded(); |
203 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | |
204 | |
205 updateAppearance(); | |
206 } | 201 } |
207 | 202 |
208 bool FrameCaret::shouldPaintCaret(const LayoutBlock& block) const { | 203 bool FrameCaret::shouldPaintCaret(const LayoutBlock& block) const { |
209 return m_displayItemClient->shouldPaintCaret(block); | 204 return m_displayItemClient->shouldPaintCaret(block); |
210 } | 205 } |
211 | 206 |
212 void FrameCaret::paintCaret(GraphicsContext& context, | 207 void FrameCaret::paintCaret(GraphicsContext& context, |
213 const LayoutPoint& paintOffset) const { | 208 const LayoutPoint& paintOffset) const { |
214 m_displayItemClient->paintCaret(context, paintOffset, DisplayItem::kCaret); | 209 m_displayItemClient->paintCaret(context, paintOffset, DisplayItem::kCaret); |
215 } | 210 } |
(...skipping 21 matching lines...) Expand all Loading... |
237 m_shouldPaintCaret = !m_shouldPaintCaret; | 232 m_shouldPaintCaret = !m_shouldPaintCaret; |
238 scheduleVisualUpdateForPaintInvalidationIfNeeded(); | 233 scheduleVisualUpdateForPaintInvalidationIfNeeded(); |
239 } | 234 } |
240 | 235 |
241 void FrameCaret::scheduleVisualUpdateForPaintInvalidationIfNeeded() { | 236 void FrameCaret::scheduleVisualUpdateForPaintInvalidationIfNeeded() { |
242 if (FrameView* frameView = m_frame->view()) | 237 if (FrameView* frameView = m_frame->view()) |
243 frameView->scheduleVisualUpdateForPaintInvalidationIfNeeded(); | 238 frameView->scheduleVisualUpdateForPaintInvalidationIfNeeded(); |
244 } | 239 } |
245 | 240 |
246 } // namespace blink | 241 } // namespace blink |
OLD | NEW |