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