Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/HTMLNames.h" | 5 #include "core/HTMLNames.h" |
| 6 #include "core/editing/FrameSelection.h" | 6 #include "core/editing/FrameSelection.h" |
| 7 #include "core/frame/FrameView.h" | 7 #include "core/frame/FrameView.h" |
| 8 #include "core/layout/LayoutTestHelper.h" | 8 #include "core/layout/LayoutTestHelper.h" |
| 9 #include "core/layout/LayoutView.h" | 9 #include "core/layout/LayoutView.h" |
| 10 #include "core/page/FocusController.h" | 10 #include "core/page/FocusController.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 43 return text; | 43 return text; |
| 44 } | 44 } |
| 45 | 45 |
| 46 Element* appendBlock(const String& data) { | 46 Element* appendBlock(const String& data) { |
| 47 Element* block = document().createElement("div"); | 47 Element* block = document().createElement("div"); |
| 48 Text* text = document().createTextNode(data); | 48 Text* text = document().createTextNode(data); |
| 49 block->appendChild(text); | 49 block->appendChild(text); |
| 50 document().body()->appendChild(block); | 50 document().body()->appendChild(block); |
| 51 return block; | 51 return block; |
| 52 } | 52 } |
| 53 | |
| 54 void updateAllLifecyclePhases() { | |
| 55 // Partial lifecycle updates should not affect caret paint invalidation. | |
| 56 document().view()->updateLifecycleToLayoutClean(); | |
|
Xianzhu
2017/03/08 17:07:05
This is to reproduce the bug situation about parti
| |
| 57 document().view()->updateAllLifecyclePhases(); | |
| 58 // Partial lifecycle updates should not affect caret paint invalidation. | |
| 59 document().view()->updateLifecycleToLayoutClean(); | |
| 60 } | |
| 53 }; | 61 }; |
| 54 | 62 |
| 55 TEST_F(CaretDisplayItemClientTest, CaretPaintInvalidation) { | 63 TEST_F(CaretDisplayItemClientTest, CaretPaintInvalidation) { |
| 56 document().body()->setContentEditable("true", ASSERT_NO_EXCEPTION); | 64 document().body()->setContentEditable("true", ASSERT_NO_EXCEPTION); |
| 57 document().page()->focusController().setActive(true); | 65 document().page()->focusController().setActive(true); |
| 58 document().page()->focusController().setFocused(true); | 66 document().page()->focusController().setFocused(true); |
| 59 | 67 |
| 60 Text* text = appendTextNode("Hello, World!"); | 68 Text* text = appendTextNode("Hello, World!"); |
| 61 document().view()->updateAllLifecyclePhases(); | 69 updateAllLifecyclePhases(); |
| 62 const auto* block = toLayoutBlock(document().body()->layoutObject()); | 70 const auto* block = toLayoutBlock(document().body()->layoutObject()); |
| 63 | 71 |
| 64 // Focus the body. Should invalidate the new caret. | 72 // Focus the body. Should invalidate the new caret. |
| 65 document().view()->setTracksPaintInvalidations(true); | 73 document().view()->setTracksPaintInvalidations(true); |
| 66 document().body()->focus(); | 74 document().body()->focus(); |
| 67 document().view()->updateAllLifecyclePhases(); | 75 updateAllLifecyclePhases(); |
| 68 EXPECT_TRUE(block->shouldPaintCursorCaret()); | 76 EXPECT_TRUE(block->shouldPaintCursorCaret()); |
| 69 | 77 |
| 70 LayoutRect caretVisualRect = caretDisplayItemClient().visualRect(); | 78 LayoutRect caretVisualRect = caretDisplayItemClient().visualRect(); |
| 71 EXPECT_EQ(1, caretVisualRect.width()); | 79 EXPECT_EQ(1, caretVisualRect.width()); |
| 72 EXPECT_EQ(block->location(), caretVisualRect.location()); | 80 EXPECT_EQ(block->location(), caretVisualRect.location()); |
| 73 | 81 |
| 74 const auto* rasterInvalidations = | 82 const auto* rasterInvalidations = |
| 75 &getRasterInvalidationTracking()->trackedRasterInvalidations; | 83 &getRasterInvalidationTracking()->trackedRasterInvalidations; |
| 76 ASSERT_EQ(1u, rasterInvalidations->size()); | 84 ASSERT_EQ(1u, rasterInvalidations->size()); |
| 77 EXPECT_EQ(enclosingIntRect(caretVisualRect), (*rasterInvalidations)[0].rect); | 85 EXPECT_EQ(enclosingIntRect(caretVisualRect), (*rasterInvalidations)[0].rect); |
| 78 EXPECT_EQ(block, (*rasterInvalidations)[0].client); | 86 EXPECT_EQ(block, (*rasterInvalidations)[0].client); |
| 79 EXPECT_EQ(PaintInvalidationCaret, (*rasterInvalidations)[0].reason); | 87 EXPECT_EQ(PaintInvalidationCaret, (*rasterInvalidations)[0].reason); |
| 80 | 88 |
| 81 std::unique_ptr<JSONArray> objectInvalidations = | 89 std::unique_ptr<JSONArray> objectInvalidations = |
| 82 document().view()->trackedObjectPaintInvalidationsAsJSON(); | 90 document().view()->trackedObjectPaintInvalidationsAsJSON(); |
| 83 ASSERT_EQ(1u, objectInvalidations->size()); | 91 ASSERT_EQ(1u, objectInvalidations->size()); |
| 84 String s; | 92 String s; |
| 85 JSONObject::cast(objectInvalidations->at(0))->get("object")->asString(&s); | 93 JSONObject::cast(objectInvalidations->at(0))->get("object")->asString(&s); |
| 86 EXPECT_EQ("Caret", s); | 94 EXPECT_EQ("Caret", s); |
| 87 document().view()->setTracksPaintInvalidations(false); | 95 document().view()->setTracksPaintInvalidations(false); |
| 88 | 96 |
| 89 // Move the caret to the end of the text. Should invalidate both the old and | 97 // Move the caret to the end of the text. Should invalidate both the old and |
| 90 // new carets. | 98 // new carets. |
| 91 document().view()->setTracksPaintInvalidations(true); | 99 document().view()->setTracksPaintInvalidations(true); |
| 92 selection().setSelection( | 100 selection().setSelection( |
| 93 SelectionInDOMTree::Builder().collapse(Position(text, 5)).build()); | 101 SelectionInDOMTree::Builder().collapse(Position(text, 5)).build()); |
| 94 document().view()->updateAllLifecyclePhases(); | 102 updateAllLifecyclePhases(); |
| 95 EXPECT_TRUE(block->shouldPaintCursorCaret()); | 103 EXPECT_TRUE(block->shouldPaintCursorCaret()); |
| 96 | 104 |
| 97 LayoutRect newCaretVisualRect = caretDisplayItemClient().visualRect(); | 105 LayoutRect newCaretVisualRect = caretDisplayItemClient().visualRect(); |
| 98 EXPECT_EQ(caretVisualRect.size(), newCaretVisualRect.size()); | 106 EXPECT_EQ(caretVisualRect.size(), newCaretVisualRect.size()); |
| 99 EXPECT_EQ(caretVisualRect.y(), newCaretVisualRect.y()); | 107 EXPECT_EQ(caretVisualRect.y(), newCaretVisualRect.y()); |
| 100 EXPECT_LT(caretVisualRect.x(), newCaretVisualRect.x()); | 108 EXPECT_LT(caretVisualRect.x(), newCaretVisualRect.x()); |
| 101 | 109 |
| 102 rasterInvalidations = | 110 rasterInvalidations = |
| 103 &getRasterInvalidationTracking()->trackedRasterInvalidations; | 111 &getRasterInvalidationTracking()->trackedRasterInvalidations; |
| 104 ASSERT_EQ(2u, rasterInvalidations->size()); | 112 ASSERT_EQ(2u, rasterInvalidations->size()); |
| 105 EXPECT_EQ(enclosingIntRect(caretVisualRect), (*rasterInvalidations)[0].rect); | 113 EXPECT_EQ(enclosingIntRect(caretVisualRect), (*rasterInvalidations)[0].rect); |
| 106 EXPECT_EQ(block, (*rasterInvalidations)[0].client); | 114 EXPECT_EQ(block, (*rasterInvalidations)[0].client); |
| 107 EXPECT_EQ(PaintInvalidationCaret, (*rasterInvalidations)[0].reason); | 115 EXPECT_EQ(PaintInvalidationCaret, (*rasterInvalidations)[0].reason); |
| 108 EXPECT_EQ(enclosingIntRect(newCaretVisualRect), | 116 EXPECT_EQ(enclosingIntRect(newCaretVisualRect), |
| 109 (*rasterInvalidations)[1].rect); | 117 (*rasterInvalidations)[1].rect); |
| 110 EXPECT_EQ(block, (*rasterInvalidations)[1].client); | 118 EXPECT_EQ(block, (*rasterInvalidations)[1].client); |
| 111 EXPECT_EQ(PaintInvalidationCaret, (*rasterInvalidations)[1].reason); | 119 EXPECT_EQ(PaintInvalidationCaret, (*rasterInvalidations)[1].reason); |
| 112 | 120 |
| 113 objectInvalidations = | 121 objectInvalidations = |
| 114 document().view()->trackedObjectPaintInvalidationsAsJSON(); | 122 document().view()->trackedObjectPaintInvalidationsAsJSON(); |
| 115 ASSERT_EQ(1u, objectInvalidations->size()); | 123 ASSERT_EQ(1u, objectInvalidations->size()); |
| 116 JSONObject::cast(objectInvalidations->at(0))->get("object")->asString(&s); | 124 JSONObject::cast(objectInvalidations->at(0))->get("object")->asString(&s); |
| 117 EXPECT_EQ("Caret", s); | 125 EXPECT_EQ("Caret", s); |
| 118 document().view()->setTracksPaintInvalidations(false); | 126 document().view()->setTracksPaintInvalidations(false); |
| 119 | 127 |
| 120 // Remove selection. Should invalidate the old caret. | 128 // Remove selection. Should invalidate the old caret. |
| 121 LayoutRect oldCaretVisualRect = newCaretVisualRect; | 129 LayoutRect oldCaretVisualRect = newCaretVisualRect; |
| 122 document().view()->setTracksPaintInvalidations(true); | 130 document().view()->setTracksPaintInvalidations(true); |
| 123 selection().setSelection(SelectionInDOMTree()); | 131 selection().setSelection(SelectionInDOMTree()); |
| 124 document().view()->updateAllLifecyclePhases(); | 132 updateAllLifecyclePhases(); |
| 125 EXPECT_FALSE(block->shouldPaintCursorCaret()); | 133 EXPECT_FALSE(block->shouldPaintCursorCaret()); |
| 126 EXPECT_EQ(LayoutRect(), caretDisplayItemClient().visualRect()); | 134 EXPECT_EQ(LayoutRect(), caretDisplayItemClient().visualRect()); |
| 127 | 135 |
| 128 rasterInvalidations = | 136 rasterInvalidations = |
| 129 &getRasterInvalidationTracking()->trackedRasterInvalidations; | 137 &getRasterInvalidationTracking()->trackedRasterInvalidations; |
| 130 ASSERT_EQ(1u, rasterInvalidations->size()); | 138 ASSERT_EQ(1u, rasterInvalidations->size()); |
| 131 EXPECT_EQ(enclosingIntRect(oldCaretVisualRect), | 139 EXPECT_EQ(enclosingIntRect(oldCaretVisualRect), |
| 132 (*rasterInvalidations)[0].rect); | 140 (*rasterInvalidations)[0].rect); |
| 133 EXPECT_EQ(block, (*rasterInvalidations)[0].client); | 141 EXPECT_EQ(block, (*rasterInvalidations)[0].client); |
| 134 | 142 |
| 135 objectInvalidations = | 143 objectInvalidations = |
| 136 document().view()->trackedObjectPaintInvalidationsAsJSON(); | 144 document().view()->trackedObjectPaintInvalidationsAsJSON(); |
| 137 ASSERT_EQ(1u, objectInvalidations->size()); | 145 ASSERT_EQ(1u, objectInvalidations->size()); |
| 138 JSONObject::cast(objectInvalidations->at(0))->get("object")->asString(&s); | 146 JSONObject::cast(objectInvalidations->at(0))->get("object")->asString(&s); |
| 139 EXPECT_EQ("Caret", s); | 147 EXPECT_EQ("Caret", s); |
| 140 document().view()->setTracksPaintInvalidations(false); | 148 document().view()->setTracksPaintInvalidations(false); |
| 141 } | 149 } |
| 142 | 150 |
| 143 TEST_F(CaretDisplayItemClientTest, CaretMovesBetweenBlocks) { | 151 TEST_F(CaretDisplayItemClientTest, CaretMovesBetweenBlocks) { |
| 144 document().body()->setContentEditable("true", ASSERT_NO_EXCEPTION); | 152 document().body()->setContentEditable("true", ASSERT_NO_EXCEPTION); |
| 145 document().page()->focusController().setActive(true); | 153 document().page()->focusController().setActive(true); |
| 146 document().page()->focusController().setFocused(true); | 154 document().page()->focusController().setFocused(true); |
| 147 auto* blockElement1 = appendBlock("Block1"); | 155 auto* blockElement1 = appendBlock("Block1"); |
| 148 auto* blockElement2 = appendBlock("Block2"); | 156 auto* blockElement2 = appendBlock("Block2"); |
| 149 document().view()->updateAllLifecyclePhases(); | 157 updateAllLifecyclePhases(); |
| 150 auto* block1 = toLayoutBlock(blockElement1->layoutObject()); | 158 auto* block1 = toLayoutBlock(blockElement1->layoutObject()); |
| 151 auto* block2 = toLayoutBlock(blockElement2->layoutObject()); | 159 auto* block2 = toLayoutBlock(blockElement2->layoutObject()); |
| 152 | 160 |
| 153 // Focus the body. | 161 // Focus the body. |
| 154 document().body()->focus(); | 162 document().body()->focus(); |
| 155 document().view()->updateAllLifecyclePhases(); | 163 updateAllLifecyclePhases(); |
| 156 LayoutRect caretVisualRect1 = caretDisplayItemClient().visualRect(); | 164 LayoutRect caretVisualRect1 = caretDisplayItemClient().visualRect(); |
| 157 EXPECT_EQ(1, caretVisualRect1.width()); | 165 EXPECT_EQ(1, caretVisualRect1.width()); |
| 158 EXPECT_EQ(block1->visualRect().location(), caretVisualRect1.location()); | 166 EXPECT_EQ(block1->visualRect().location(), caretVisualRect1.location()); |
| 159 EXPECT_TRUE(block1->shouldPaintCursorCaret()); | 167 EXPECT_TRUE(block1->shouldPaintCursorCaret()); |
| 160 EXPECT_FALSE(block2->shouldPaintCursorCaret()); | 168 EXPECT_FALSE(block2->shouldPaintCursorCaret()); |
| 161 | 169 |
| 162 // Move the caret into block2. Should invalidate both the old and new carets. | 170 // Move the caret into block2. Should invalidate both the old and new carets. |
| 163 document().view()->setTracksPaintInvalidations(true); | 171 document().view()->setTracksPaintInvalidations(true); |
| 164 selection().setSelection(SelectionInDOMTree::Builder() | 172 selection().setSelection(SelectionInDOMTree::Builder() |
| 165 .collapse(Position(blockElement2, 0)) | 173 .collapse(Position(blockElement2, 0)) |
| 166 .build()); | 174 .build()); |
| 167 document().view()->updateAllLifecyclePhases(); | 175 updateAllLifecyclePhases(); |
| 168 | 176 |
| 169 LayoutRect caretVisualRect2 = caretDisplayItemClient().visualRect(); | 177 LayoutRect caretVisualRect2 = caretDisplayItemClient().visualRect(); |
| 170 EXPECT_EQ(1, caretVisualRect2.width()); | 178 EXPECT_EQ(1, caretVisualRect2.width()); |
| 171 EXPECT_EQ(block2->visualRect().location(), caretVisualRect2.location()); | 179 EXPECT_EQ(block2->visualRect().location(), caretVisualRect2.location()); |
| 172 EXPECT_FALSE(block1->shouldPaintCursorCaret()); | 180 EXPECT_FALSE(block1->shouldPaintCursorCaret()); |
| 173 EXPECT_TRUE(block2->shouldPaintCursorCaret()); | 181 EXPECT_TRUE(block2->shouldPaintCursorCaret()); |
| 174 | 182 |
| 175 const auto* rasterInvalidations = | 183 const auto* rasterInvalidations = |
| 176 &getRasterInvalidationTracking()->trackedRasterInvalidations; | 184 &getRasterInvalidationTracking()->trackedRasterInvalidations; |
| 177 ASSERT_EQ(2u, rasterInvalidations->size()); | 185 ASSERT_EQ(2u, rasterInvalidations->size()); |
| 178 EXPECT_EQ(enclosingIntRect(caretVisualRect1), (*rasterInvalidations)[0].rect); | 186 EXPECT_EQ(enclosingIntRect(caretVisualRect1), (*rasterInvalidations)[0].rect); |
| 179 EXPECT_EQ(block1, (*rasterInvalidations)[0].client); | 187 EXPECT_EQ(block1, (*rasterInvalidations)[0].client); |
| 180 EXPECT_EQ(PaintInvalidationCaret, (*rasterInvalidations)[0].reason); | 188 EXPECT_EQ(PaintInvalidationCaret, (*rasterInvalidations)[0].reason); |
| 181 EXPECT_EQ(enclosingIntRect(caretVisualRect2), (*rasterInvalidations)[1].rect); | 189 EXPECT_EQ(enclosingIntRect(caretVisualRect2), (*rasterInvalidations)[1].rect); |
| 182 EXPECT_EQ(block2, (*rasterInvalidations)[1].client); | 190 EXPECT_EQ(block2, (*rasterInvalidations)[1].client); |
| 183 EXPECT_EQ(PaintInvalidationCaret, (*rasterInvalidations)[1].reason); | 191 EXPECT_EQ(PaintInvalidationCaret, (*rasterInvalidations)[1].reason); |
| 184 | 192 |
| 185 std::unique_ptr<JSONArray> objectInvalidations = | 193 std::unique_ptr<JSONArray> objectInvalidations = |
| 186 document().view()->trackedObjectPaintInvalidationsAsJSON(); | 194 document().view()->trackedObjectPaintInvalidationsAsJSON(); |
| 187 ASSERT_EQ(2u, objectInvalidations->size()); | 195 ASSERT_EQ(2u, objectInvalidations->size()); |
| 188 document().view()->setTracksPaintInvalidations(false); | 196 document().view()->setTracksPaintInvalidations(false); |
| 189 | 197 |
| 190 // Move the caret back into block1. | 198 // Move the caret back into block1. |
| 191 document().view()->setTracksPaintInvalidations(true); | 199 document().view()->setTracksPaintInvalidations(true); |
| 192 selection().setSelection(SelectionInDOMTree::Builder() | 200 selection().setSelection(SelectionInDOMTree::Builder() |
| 193 .collapse(Position(blockElement1, 0)) | 201 .collapse(Position(blockElement1, 0)) |
| 194 .build()); | 202 .build()); |
| 195 document().view()->updateAllLifecyclePhases(); | 203 updateAllLifecyclePhases(); |
| 196 | 204 |
| 197 EXPECT_EQ(caretVisualRect1, caretDisplayItemClient().visualRect()); | 205 EXPECT_EQ(caretVisualRect1, caretDisplayItemClient().visualRect()); |
| 198 EXPECT_TRUE(block1->shouldPaintCursorCaret()); | 206 EXPECT_TRUE(block1->shouldPaintCursorCaret()); |
| 199 EXPECT_FALSE(block2->shouldPaintCursorCaret()); | 207 EXPECT_FALSE(block2->shouldPaintCursorCaret()); |
| 200 | 208 |
| 201 rasterInvalidations = | 209 rasterInvalidations = |
| 202 &getRasterInvalidationTracking()->trackedRasterInvalidations; | 210 &getRasterInvalidationTracking()->trackedRasterInvalidations; |
| 203 ASSERT_EQ(2u, rasterInvalidations->size()); | 211 ASSERT_EQ(2u, rasterInvalidations->size()); |
| 204 EXPECT_EQ(enclosingIntRect(caretVisualRect1), (*rasterInvalidations)[0].rect); | 212 EXPECT_EQ(enclosingIntRect(caretVisualRect1), (*rasterInvalidations)[0].rect); |
| 205 EXPECT_EQ(block1, (*rasterInvalidations)[0].client); | 213 EXPECT_EQ(block1, (*rasterInvalidations)[0].client); |
| 206 EXPECT_EQ(PaintInvalidationCaret, (*rasterInvalidations)[0].reason); | 214 EXPECT_EQ(PaintInvalidationCaret, (*rasterInvalidations)[0].reason); |
| 207 EXPECT_EQ(enclosingIntRect(caretVisualRect2), (*rasterInvalidations)[1].rect); | 215 EXPECT_EQ(enclosingIntRect(caretVisualRect2), (*rasterInvalidations)[1].rect); |
| 208 EXPECT_EQ(block2, (*rasterInvalidations)[1].client); | 216 EXPECT_EQ(block2, (*rasterInvalidations)[1].client); |
| 209 EXPECT_EQ(PaintInvalidationCaret, (*rasterInvalidations)[1].reason); | 217 EXPECT_EQ(PaintInvalidationCaret, (*rasterInvalidations)[1].reason); |
| 210 | 218 |
| 211 objectInvalidations = | 219 objectInvalidations = |
| 212 document().view()->trackedObjectPaintInvalidationsAsJSON(); | 220 document().view()->trackedObjectPaintInvalidationsAsJSON(); |
| 213 ASSERT_EQ(2u, objectInvalidations->size()); | 221 ASSERT_EQ(2u, objectInvalidations->size()); |
| 214 document().view()->setTracksPaintInvalidations(false); | 222 document().view()->setTracksPaintInvalidations(false); |
| 215 } | 223 } |
| 216 | 224 |
| 217 } // namespace blink | 225 } // namespace blink |
| OLD | NEW |