| 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 const SelectionEditor& selectionEditor) | 47 const SelectionEditor& selectionEditor) |
| 48 : m_selectionEditor(&selectionEditor), | 48 : m_selectionEditor(&selectionEditor), |
| 49 m_frame(frame), | 49 m_frame(frame), |
| 50 m_caretBase(new CaretDisplayItemClient()), | 50 m_caretBase(new CaretDisplayItemClient()), |
| 51 m_caretVisibility(CaretVisibility::Hidden), | 51 m_caretVisibility(CaretVisibility::Hidden), |
| 52 m_caretBlinkTimer(TaskRunnerHelper::get(TaskType::UnspecedTimer, &frame), | 52 m_caretBlinkTimer(TaskRunnerHelper::get(TaskType::UnspecedTimer, &frame), |
| 53 this, | 53 this, |
| 54 &FrameCaret::caretBlinkTimerFired), | 54 &FrameCaret::caretBlinkTimerFired), |
| 55 m_shouldPaintCaret(true), | 55 m_shouldPaintCaret(true), |
| 56 m_isCaretBlinkingSuspended(false), | 56 m_isCaretBlinkingSuspended(false), |
| 57 m_shouldShowBlockCursor(false) {} | 57 m_shouldShowBlockCursor(false), |
| 58 m_shouldUpdateLayoutAndStyle(false) {} |
| 58 | 59 |
| 59 FrameCaret::~FrameCaret() = default; | 60 FrameCaret::~FrameCaret() = default; |
| 60 | 61 |
| 61 DEFINE_TRACE(FrameCaret) { | 62 DEFINE_TRACE(FrameCaret) { |
| 62 visitor->trace(m_selectionEditor); | 63 visitor->trace(m_selectionEditor); |
| 63 visitor->trace(m_frame); | 64 visitor->trace(m_frame); |
| 64 } | 65 } |
| 65 | 66 |
| 66 const DisplayItemClient& FrameCaret::displayItemClient() const { | 67 const DisplayItemClient& FrameCaret::displayItemClient() const { |
| 67 return *m_caretBase; | 68 return *m_caretBase; |
| 68 } | 69 } |
| 69 | 70 |
| 70 const PositionWithAffinity FrameCaret::caretPosition() const { | 71 const PositionWithAffinity FrameCaret::caretPosition() const { |
| 71 const VisibleSelection& selection = | 72 const VisibleSelection& selection = |
| 72 m_selectionEditor->visibleSelection<EditingStrategy>(); | 73 m_selectionEditor->visibleSelection<EditingStrategy>(); |
| 73 if (!selection.isCaret()) | 74 if (!selection.isCaret()) |
| 74 return PositionWithAffinity(); | 75 return PositionWithAffinity(); |
| 75 return PositionWithAffinity(selection.start(), selection.affinity()); | 76 return PositionWithAffinity(selection.start(), selection.affinity()); |
| 76 } | 77 } |
| 77 | 78 |
| 78 inline static bool shouldStopBlinkingDueToTypingCommand(LocalFrame* frame) { | 79 inline static bool shouldStopBlinkingDueToTypingCommand(LocalFrame* frame) { |
| 79 return frame->editor().lastEditCommand() && | 80 return frame->editor().lastEditCommand() && |
| 80 frame->editor().lastEditCommand()->shouldStopCaretBlinking(); | 81 frame->editor().lastEditCommand()->shouldStopCaretBlinking(); |
| 81 } | 82 } |
| 82 | 83 |
| 83 void FrameCaret::updateAppearance() { | 84 void FrameCaret::updateAppearance() { |
| 85 DCHECK_GE(m_frame->document()->lifecycle().state(), |
| 86 DocumentLifecycle::LayoutClean); |
| 84 // Paint a block cursor instead of a caret in overtype mode unless the caret | 87 // 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 | 88 // is at the end of a line (in this case the FrameSelection will paint a |
| 86 // blinking caret as usual). | 89 // blinking caret as usual). |
| 87 bool paintBlockCursor = m_shouldShowBlockCursor && isActive(); | 90 const bool paintBlockCursor = |
| 88 if (paintBlockCursor) { | 91 m_shouldShowBlockCursor && isActive() && |
| 89 // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets | 92 !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 | 93 |
| 99 bool shouldBlink = !paintBlockCursor && shouldBlinkCaret(); | 94 bool shouldBlink = !paintBlockCursor && shouldBlinkCaret(); |
| 100 | 95 |
| 101 // If the caret moved, stop the blink timer so we can restart with a | 96 // If the caret moved, stop the blink timer so we can restart with a |
| 102 // black caret in the new location. | 97 // black caret in the new location. |
| 103 if (!shouldBlink || shouldStopBlinkingDueToTypingCommand(m_frame)) | 98 if (!shouldBlink || shouldStopBlinkingDueToTypingCommand(m_frame)) |
| 104 stopCaretBlinkTimer(); | 99 stopCaretBlinkTimer(); |
| 105 | 100 |
| 106 // Start blinking with a black caret. Be sure not to restart if we're | 101 // Start blinking with a black caret. Be sure not to restart if we're |
| 107 // already blinking in the right location. | 102 // already blinking in the right location. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 128 m_shouldPaintCaret = true; | 123 m_shouldPaintCaret = true; |
| 129 scheduleVisualUpdateForPaintInvalidationIfNeeded(); | 124 scheduleVisualUpdateForPaintInvalidationIfNeeded(); |
| 130 } | 125 } |
| 131 | 126 |
| 132 void FrameCaret::setCaretVisibility(CaretVisibility visibility) { | 127 void FrameCaret::setCaretVisibility(CaretVisibility visibility) { |
| 133 if (m_caretVisibility == visibility) | 128 if (m_caretVisibility == visibility) |
| 134 return; | 129 return; |
| 135 | 130 |
| 136 m_caretVisibility = visibility; | 131 m_caretVisibility = visibility; |
| 137 | 132 |
| 138 updateAppearance(); | 133 if (visibility == CaretVisibility::Hidden) |
| 134 stopCaretBlinkTimer(); |
| 139 scheduleVisualUpdateForPaintInvalidationIfNeeded(); | 135 scheduleVisualUpdateForPaintInvalidationIfNeeded(); |
| 140 } | 136 } |
| 141 | 137 |
| 142 void FrameCaret::clearPreviousVisualRect(const LayoutBlock& block) { | 138 void FrameCaret::clearPreviousVisualRect(const LayoutBlock& block) { |
| 143 m_caretBase->clearPreviousVisualRect(block); | 139 m_caretBase->clearPreviousVisualRect(block); |
| 144 } | 140 } |
| 145 | 141 |
| 146 void FrameCaret::layoutBlockWillBeDestroyed(const LayoutBlock& block) { | 142 void FrameCaret::layoutBlockWillBeDestroyed(const LayoutBlock& block) { |
| 147 m_caretBase->layoutBlockWillBeDestroyed(block); | 143 m_caretBase->layoutBlockWillBeDestroyed(block); |
| 148 } | 144 } |
| 149 | 145 |
| 150 void FrameCaret::updateStyleAndLayoutIfNeeded() { | 146 void FrameCaret::updateStyleAndLayoutIfNeeded() { |
| 147 DCHECK_GE(m_frame->document()->lifecycle().state(), |
| 148 DocumentLifecycle::LayoutClean); |
| 149 updateAppearance(); |
| 151 bool shouldPaintCaret = | 150 bool shouldPaintCaret = |
| 152 m_shouldPaintCaret && isActive() && | 151 m_shouldPaintCaret && isActive() && |
| 153 m_caretVisibility == CaretVisibility::Visible && | 152 m_caretVisibility == CaretVisibility::Visible && |
| 154 m_selectionEditor->visibleSelection<EditingStrategy>().hasEditableStyle(); | 153 m_selectionEditor->visibleSelection<EditingStrategy>().hasEditableStyle(); |
| 155 | 154 |
| 156 m_caretBase->updateStyleAndLayoutIfNeeded( | 155 m_caretBase->updateStyleAndLayoutIfNeeded( |
| 157 shouldPaintCaret ? caretPosition() : PositionWithAffinity()); | 156 shouldPaintCaret ? caretPosition() : PositionWithAffinity()); |
| 158 } | 157 } |
| 159 | 158 |
| 160 void FrameCaret::invalidatePaintIfNeeded(const LayoutBlock& block, | 159 void FrameCaret::invalidatePaintIfNeeded(const LayoutBlock& block, |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 caretNode, CaretDisplayItemClient::computeCaretRect(caretPosition())); | 198 caretNode, CaretDisplayItemClient::computeCaretRect(caretPosition())); |
| 200 } | 199 } |
| 201 return absoluteBoundsForLocalRect( | 200 return absoluteBoundsForLocalRect( |
| 202 caretNode, | 201 caretNode, |
| 203 CaretDisplayItemClient::computeCaretRect( | 202 CaretDisplayItemClient::computeCaretRect( |
| 204 createVisiblePosition(caretPosition()).toPositionWithAffinity())); | 203 createVisiblePosition(caretPosition()).toPositionWithAffinity())); |
| 205 } | 204 } |
| 206 | 205 |
| 207 void FrameCaret::setShouldShowBlockCursor(bool shouldShowBlockCursor) { | 206 void FrameCaret::setShouldShowBlockCursor(bool shouldShowBlockCursor) { |
| 208 m_shouldShowBlockCursor = shouldShowBlockCursor; | 207 m_shouldShowBlockCursor = shouldShowBlockCursor; |
| 209 | 208 scheduleVisualUpdateForPaintInvalidationIfNeeded(); |
| 210 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | |
| 211 | |
| 212 updateAppearance(); | |
| 213 } | 209 } |
| 214 | 210 |
| 215 bool FrameCaret::shouldPaintCaret(const LayoutBlock& block) const { | 211 bool FrameCaret::shouldPaintCaret(const LayoutBlock& block) const { |
| 216 return m_caretBase->shouldPaintCaret(block); | 212 return m_caretBase->shouldPaintCaret(block); |
| 217 } | 213 } |
| 218 | 214 |
| 219 void FrameCaret::paintCaret(GraphicsContext& context, | 215 void FrameCaret::paintCaret(GraphicsContext& context, |
| 220 const LayoutPoint& paintOffset) const { | 216 const LayoutPoint& paintOffset) const { |
| 221 m_caretBase->paintCaret(context, paintOffset, DisplayItem::kCaret); | 217 m_caretBase->paintCaret(context, paintOffset, DisplayItem::kCaret); |
| 222 } | 218 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 244 m_shouldPaintCaret = !m_shouldPaintCaret; | 240 m_shouldPaintCaret = !m_shouldPaintCaret; |
| 245 scheduleVisualUpdateForPaintInvalidationIfNeeded(); | 241 scheduleVisualUpdateForPaintInvalidationIfNeeded(); |
| 246 } | 242 } |
| 247 | 243 |
| 248 void FrameCaret::scheduleVisualUpdateForPaintInvalidationIfNeeded() { | 244 void FrameCaret::scheduleVisualUpdateForPaintInvalidationIfNeeded() { |
| 249 if (FrameView* frameView = m_frame->view()) | 245 if (FrameView* frameView = m_frame->view()) |
| 250 frameView->scheduleVisualUpdateForPaintInvalidationIfNeeded(); | 246 frameView->scheduleVisualUpdateForPaintInvalidationIfNeeded(); |
| 251 } | 247 } |
| 252 | 248 |
| 253 } // namespace blink | 249 } // namespace blink |
| OLD | NEW |