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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 } | 159 } |
160 | 160 |
161 bool FrameCaret::caretPositionIsValidForDocument( | 161 bool FrameCaret::caretPositionIsValidForDocument( |
162 const Document& document) const { | 162 const Document& document) const { |
163 if (!isActive()) | 163 if (!isActive()) |
164 return true; | 164 return true; |
165 | 165 |
166 return caretPosition().document() == document && !caretPosition().isOrphan(); | 166 return caretPosition().document() == document && !caretPosition().isOrphan(); |
167 } | 167 } |
168 | 168 |
| 169 static bool shouldRepaintCaret(Node& node) { |
| 170 // If PositionAnchorType::BeforeAnchor or PositionAnchorType::AfterAnchor, |
| 171 // carets need to be repainted not only when the node is contentEditable but |
| 172 // also when its parentNode() is contentEditable. |
| 173 node.document().updateStyleAndLayoutTree(); |
| 174 return hasEditableStyle(node) || |
| 175 (node.parentNode() && hasEditableStyle(*node.parentNode())); |
| 176 } |
| 177 |
169 void FrameCaret::invalidateCaretRect(bool forceInvalidation) { | 178 void FrameCaret::invalidateCaretRect(bool forceInvalidation) { |
170 if (!m_caretRectDirty) | 179 if (!m_caretRectDirty) |
171 return; | 180 return; |
172 m_caretRectDirty = false; | 181 m_caretRectDirty = false; |
173 | 182 |
174 DCHECK(caretPositionIsValidForDocument(*m_frame->document())); | 183 DCHECK(caretPositionIsValidForDocument(*m_frame->document())); |
175 LayoutObject* layoutObject = nullptr; | 184 LayoutObject* layoutObject = nullptr; |
176 LayoutRect newRect; | 185 LayoutRect newRect; |
177 PositionWithAffinity currentCaretPosition = caretPosition(); | 186 PositionWithAffinity currentCaretPosition = caretPosition(); |
178 if (isActive()) | 187 if (isActive()) |
(...skipping 16 matching lines...) Expand all Loading... |
195 // caret blink interval could be zero and thus |m_caretBlinkTimer| will | 204 // caret blink interval could be zero and thus |m_caretBlinkTimer| will |
196 // never be started. We provide |forceInvalidation| for use by paint | 205 // never be started. We provide |forceInvalidation| for use by paint |
197 // invalidation internals where we need to invalidate the caret regardless | 206 // invalidation internals where we need to invalidate the caret regardless |
198 // of timer state. | 207 // of timer state. |
199 if (!forceInvalidation && !m_caretBlinkTimer.isActive() && | 208 if (!forceInvalidation && !m_caretBlinkTimer.isActive() && |
200 newNode == m_previousCaretNode && newRect == m_previousCaretRect && | 209 newNode == m_previousCaretNode && newRect == m_previousCaretRect && |
201 m_caretVisibility == m_previousCaretVisibility) | 210 m_caretVisibility == m_previousCaretVisibility) |
202 return; | 211 return; |
203 | 212 |
204 if (m_previousCaretAnchorNode && | 213 if (m_previousCaretAnchorNode && |
205 CaretBase::shouldRepaintCaret(*m_previousCaretAnchorNode)) { | 214 shouldRepaintCaret(*m_previousCaretAnchorNode)) { |
206 m_caretBase->invalidateLocalCaretRect(m_previousCaretAnchorNode.get(), | 215 m_caretBase->invalidateLocalCaretRect(m_previousCaretAnchorNode.get(), |
207 m_previousCaretRect); | 216 m_previousCaretRect); |
208 } | 217 } |
209 if (newAnchorNode && CaretBase::shouldRepaintCaret(*newAnchorNode)) | 218 if (newAnchorNode && shouldRepaintCaret(*newAnchorNode)) |
210 m_caretBase->invalidateLocalCaretRect(newAnchorNode, newRect); | 219 m_caretBase->invalidateLocalCaretRect(newAnchorNode, newRect); |
211 m_previousCaretNode = newNode; | 220 m_previousCaretNode = newNode; |
212 m_previousCaretAnchorNode = newAnchorNode; | 221 m_previousCaretAnchorNode = newAnchorNode; |
213 m_previousCaretRect = newRect; | 222 m_previousCaretRect = newRect; |
214 m_previousCaretVisibility = m_caretVisibility; | 223 m_previousCaretVisibility = m_caretVisibility; |
215 } | 224 } |
216 | 225 |
217 // TDOO(yosin): We should mark |FrameCaret::absoluteCaretBounds()| to |const|. | 226 // TDOO(yosin): We should mark |FrameCaret::absoluteCaretBounds()| to |const|. |
218 IntRect FrameCaret::absoluteCaretBounds() { | 227 IntRect FrameCaret::absoluteCaretBounds() { |
219 DCHECK_NE(m_frame->document()->lifecycle().state(), | 228 DCHECK_NE(m_frame->document()->lifecycle().state(), |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 | 315 |
307 void FrameCaret::caretBlinkTimerFired(TimerBase*) { | 316 void FrameCaret::caretBlinkTimerFired(TimerBase*) { |
308 DCHECK_EQ(m_caretVisibility, CaretVisibility::Visible); | 317 DCHECK_EQ(m_caretVisibility, CaretVisibility::Visible); |
309 if (isCaretBlinkingSuspended() && m_shouldPaintCaret) | 318 if (isCaretBlinkingSuspended() && m_shouldPaintCaret) |
310 return; | 319 return; |
311 m_shouldPaintCaret = !m_shouldPaintCaret; | 320 m_shouldPaintCaret = !m_shouldPaintCaret; |
312 setCaretRectNeedsUpdate(); | 321 setCaretRectNeedsUpdate(); |
313 } | 322 } |
314 | 323 |
315 } // namespace blink | 324 } // namespace blink |
OLD | NEW |