Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights | 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights |
| 4 * reserved. | 4 * reserved. |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
| 10 * | 10 * |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 155 SelectedMap() = default; | 155 SelectedMap() = default; |
| 156 SelectedMap(SelectedMap&& other) { | 156 SelectedMap(SelectedMap&& other) { |
| 157 object_map = std::move(other.object_map); | 157 object_map = std::move(other.object_map); |
| 158 block_map = std::move(other.block_map); | 158 block_map = std::move(other.block_map); |
| 159 } | 159 } |
| 160 | 160 |
| 161 private: | 161 private: |
| 162 DISALLOW_COPY_AND_ASSIGN(SelectedMap); | 162 DISALLOW_COPY_AND_ASSIGN(SelectedMap); |
| 163 }; | 163 }; |
| 164 | 164 |
| 165 static SelectedMap CollectSelectedMap( | 165 enum class CollectSelectedMapOption { |
| 166 const SelectionPaintRange& range, | 166 kCollectBlock, |
| 167 LayoutSelection::SelectionPaintInvalidationMode | 167 kNotCollectBlock, |
| 168 block_paint_invalidation_mode) { | 168 }; |
| 169 static SelectedMap CollectSelectedMap(const SelectionPaintRange& range, | |
|
yosin_UTC9
2017/05/29 07:59:37
nit: Could you add a blank line between enum and f
yoichio
2017/05/30 04:15:03
Done.
| |
| 170 CollectSelectedMapOption option) { | |
| 169 if (range.IsNull()) | 171 if (range.IsNull()) |
| 170 return SelectedMap(); | 172 return SelectedMap(); |
| 171 | 173 |
| 172 SelectedMap selected_map; | 174 SelectedMap selected_map; |
| 173 | 175 |
| 174 LayoutObject* const stop = | 176 LayoutObject* const stop = |
| 175 LayoutObjectAfterPosition(range.EndLayoutObject(), range.EndOffset()); | 177 LayoutObjectAfterPosition(range.EndLayoutObject(), range.EndOffset()); |
| 176 for (LayoutObject* runner = range.StartLayoutObject(); | 178 for (LayoutObject* runner = range.StartLayoutObject(); |
| 177 runner && (runner != stop); runner = runner->NextInPreOrder()) { | 179 runner && (runner != stop); runner = runner->NextInPreOrder()) { |
| 178 if (!runner->CanBeSelectionLeaf() && runner != range.StartLayoutObject() && | 180 if (!runner->CanBeSelectionLeaf() && runner != range.StartLayoutObject() && |
| 179 runner != range.EndLayoutObject()) | 181 runner != range.EndLayoutObject()) |
| 180 continue; | 182 continue; |
| 181 if (runner->GetSelectionState() == SelectionNone) | 183 if (runner->GetSelectionState() == SelectionNone) |
| 182 continue; | 184 continue; |
| 183 | 185 |
| 184 // Blocks are responsible for painting line gaps and margin gaps. They | 186 // Blocks are responsible for painting line gaps and margin gaps. They |
| 185 // must be examined as well. | 187 // must be examined as well. |
| 186 selected_map.object_map.Set(runner, runner->GetSelectionState()); | 188 selected_map.object_map.Set(runner, runner->GetSelectionState()); |
| 187 if (block_paint_invalidation_mode == | 189 if (option == CollectSelectedMapOption::kCollectBlock) { |
| 188 LayoutSelection::kPaintInvalidationNewXOROld) { | |
| 189 LayoutBlock* containing_block = runner->ContainingBlock(); | 190 LayoutBlock* containing_block = runner->ContainingBlock(); |
| 190 while (containing_block && !containing_block->IsLayoutView()) { | 191 while (containing_block && !containing_block->IsLayoutView()) { |
| 191 SelectedBlockMap::AddResult result = selected_map.block_map.insert( | 192 SelectedBlockMap::AddResult result = selected_map.block_map.insert( |
| 192 containing_block, containing_block->GetSelectionState()); | 193 containing_block, containing_block->GetSelectionState()); |
| 193 if (!result.is_new_entry) | 194 if (!result.is_new_entry) |
| 194 break; | 195 break; |
| 195 containing_block = containing_block->ContainingBlock(); | 196 containing_block = containing_block->ContainingBlock(); |
| 196 } | 197 } |
| 197 } | 198 } |
| 198 } | 199 } |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 214 LayoutObject* const stop = | 215 LayoutObject* const stop = |
| 215 LayoutObjectAfterPosition(range.EndLayoutObject(), range.EndOffset()); | 216 LayoutObjectAfterPosition(range.EndLayoutObject(), range.EndOffset()); |
| 216 for (LayoutObject* runner = range.StartLayoutObject(); | 217 for (LayoutObject* runner = range.StartLayoutObject(); |
| 217 runner && runner != stop; runner = runner->NextInPreOrder()) { | 218 runner && runner != stop; runner = runner->NextInPreOrder()) { |
| 218 if (runner != range.StartLayoutObject() && | 219 if (runner != range.StartLayoutObject() && |
| 219 runner != range.EndLayoutObject() && runner->CanBeSelectionLeaf()) | 220 runner != range.EndLayoutObject() && runner->CanBeSelectionLeaf()) |
| 220 runner->SetSelectionStateIfNeeded(SelectionInside); | 221 runner->SetSelectionStateIfNeeded(SelectionInside); |
| 221 } | 222 } |
| 222 } | 223 } |
| 223 | 224 |
| 224 void LayoutSelection::SetSelection( | 225 static void SetSelectionStateAndShouldInvalidateSelection( |
|
yosin_UTC9
2017/05/29 07:59:37
nit: s/SetSelectionStateAndShouldInvalidateSelecti
yoichio
2017/05/29 08:36:26
Fmm, actually we don't invalidate LayoutObject yet
yosin_UTC9
2017/05/29 09:38:15
How about SetSelectionStateAndPaintInvalidationFla
yoichio
2017/05/30 04:15:03
Sine this is a local function and used only once,
| |
| 225 const SelectionPaintRange& new_range, | 226 const SelectionPaintRange& new_range, |
| 226 SelectionPaintInvalidationMode block_paint_invalidation_mode) { | 227 const SelectionPaintRange& old_range) { |
| 227 DCHECK(!new_range.IsNull()); | |
| 228 | |
| 229 // Just return if the selection hasn't changed. | |
| 230 if (paint_range_ == new_range) | |
| 231 return; | |
| 232 | |
| 233 DCHECK(frame_selection_->GetDocument().GetLayoutView()->GetFrameView()); | |
| 234 DCHECK(!frame_selection_->GetDocument().NeedsLayoutTreeUpdate()); | |
| 235 | |
| 236 SelectedMap old_selected_map = | 228 SelectedMap old_selected_map = |
| 237 CollectSelectedMap(paint_range_, block_paint_invalidation_mode); | 229 CollectSelectedMap(old_range, CollectSelectedMapOption::kCollectBlock); |
| 238 | 230 |
| 239 // Now clear the selection. | 231 // Now clear the selection. |
| 240 for (auto layout_object : old_selected_map.object_map.Keys()) | 232 for (auto layout_object : old_selected_map.object_map.Keys()) |
| 241 layout_object->SetSelectionStateIfNeeded(SelectionNone); | 233 layout_object->SetSelectionStateIfNeeded(SelectionNone); |
| 242 | 234 |
| 243 SetSelectionState(new_range); | 235 SetSelectionState(new_range); |
| 244 | 236 |
| 245 // Now that the selection state has been updated for the new objects, walk | 237 // Now that the selection state has been updated for the new objects, walk |
| 246 // them again and put them in the new objects list. | 238 // them again and put them in the new objects list. |
| 247 // TODO(editing-dev): |new_selected_map| doesn't really need to store the | 239 // TODO(editing-dev): |new_selected_map| doesn't really need to store the |
| 248 // SelectionState, it's just more convenient to have it use the same data | 240 // SelectionState, it's just more convenient to have it use the same data |
| 249 // structure as |old_selected_map|. | 241 // structure as |old_selected_map|. |
| 250 SelectedMap new_selected_map = | 242 SelectedMap new_selected_map = |
| 251 CollectSelectedMap(new_range, kPaintInvalidationNewXOROld); | 243 CollectSelectedMap(new_range, CollectSelectedMapOption::kCollectBlock); |
| 252 | 244 |
| 253 // Have any of the old selected objects changed compared to the new selection? | 245 // Have any of the old selected objects changed compared to the new selection? |
| 254 for (const auto& pair : old_selected_map.object_map) { | 246 for (const auto& pair : old_selected_map.object_map) { |
| 255 LayoutObject* obj = pair.key; | 247 LayoutObject* obj = pair.key; |
| 256 SelectionState new_selection_state = obj->GetSelectionState(); | 248 SelectionState new_selection_state = obj->GetSelectionState(); |
| 257 SelectionState old_selection_state = pair.value; | 249 SelectionState old_selection_state = pair.value; |
| 258 if (new_selection_state != old_selection_state || | 250 if (new_selection_state != old_selection_state || |
| 259 (new_range.StartLayoutObject() == obj && | 251 (new_range.StartLayoutObject() == obj && |
| 260 new_range.StartOffset() != paint_range_.StartOffset()) || | 252 new_range.StartOffset() != old_range.StartOffset()) || |
| 261 (new_range.EndLayoutObject() == obj && | 253 (new_range.EndLayoutObject() == obj && |
| 262 new_range.EndOffset() != paint_range_.EndOffset())) { | 254 new_range.EndOffset() != old_range.EndOffset())) { |
| 263 obj->SetShouldInvalidateSelection(); | 255 obj->SetShouldInvalidateSelection(); |
| 264 new_selected_map.object_map.erase(obj); | 256 new_selected_map.object_map.erase(obj); |
| 265 } | 257 } |
| 266 } | 258 } |
| 267 | 259 |
| 268 // Any new objects that remain were not found in the old objects dict, and so | 260 // Any new objects that remain were not found in the old objects dict, and so |
| 269 // they need to be updated. | 261 // they need to be updated. |
| 270 for (auto layout_object : new_selected_map.object_map.Keys()) | 262 for (auto layout_object : new_selected_map.object_map.Keys()) |
| 271 layout_object->SetShouldInvalidateSelection(); | 263 layout_object->SetShouldInvalidateSelection(); |
| 272 | 264 |
| 273 // Have any of the old blocks changed? | 265 // Have any of the old blocks changed? |
| 274 for (const auto& pair : old_selected_map.block_map) { | 266 for (const auto& pair : old_selected_map.block_map) { |
| 275 LayoutBlock* block = pair.key; | 267 LayoutBlock* block = pair.key; |
| 276 SelectionState new_selection_state = block->GetSelectionState(); | 268 SelectionState new_selection_state = block->GetSelectionState(); |
| 277 SelectionState old_selection_state = pair.value; | 269 SelectionState old_selection_state = pair.value; |
| 278 if (new_selection_state != old_selection_state) { | 270 if (new_selection_state != old_selection_state) { |
| 279 block->SetShouldInvalidateSelection(); | 271 block->SetShouldInvalidateSelection(); |
| 280 new_selected_map.block_map.erase(block); | 272 new_selected_map.block_map.erase(block); |
| 281 } | 273 } |
| 282 } | 274 } |
| 283 | 275 |
| 284 // Any new blocks that remain were not found in the old blocks dict, and so | 276 // Any new blocks that remain were not found in the old blocks dict, and so |
| 285 // they need to be updated. | 277 // they need to be updated. |
| 286 for (auto layout_object : new_selected_map.block_map.Keys()) | 278 for (auto layout_object : new_selected_map.block_map.Keys()) |
| 287 layout_object->SetShouldInvalidateSelection(); | 279 layout_object->SetShouldInvalidateSelection(); |
| 288 | |
| 289 paint_range_ = new_range; | |
| 290 } | 280 } |
| 291 | 281 |
| 292 std::pair<int, int> LayoutSelection::SelectionStartEnd() { | 282 std::pair<int, int> LayoutSelection::SelectionStartEnd() { |
| 293 Commit(); | 283 Commit(); |
| 294 if (paint_range_.IsNull()) | 284 if (paint_range_.IsNull()) |
| 295 return std::make_pair(-1, -1); | 285 return std::make_pair(-1, -1); |
| 296 return std::make_pair(paint_range_.StartOffset(), paint_range_.EndOffset()); | 286 return std::make_pair(paint_range_.StartOffset(), paint_range_.EndOffset()); |
| 297 } | 287 } |
| 298 | 288 |
| 299 void LayoutSelection::ClearSelection() { | 289 void LayoutSelection::ClearSelection() { |
| 300 // For querying Layer::compositingState() | 290 // For querying Layer::compositingState() |
| 301 // This is correct, since destroying layout objects needs to cause eager paint | 291 // This is correct, since destroying layout objects needs to cause eager paint |
| 302 // invalidations. | 292 // invalidations. |
| 303 DisableCompositingQueryAsserts disabler; | 293 DisableCompositingQueryAsserts disabler; |
| 304 | 294 |
| 305 // Just return if the selection is already empty. | 295 // Just return if the selection is already empty. |
| 306 if (paint_range_.IsNull()) | 296 if (paint_range_.IsNull()) |
| 307 return; | 297 return; |
| 308 | 298 |
| 309 const SelectedMap& old_selected_map = | 299 const SelectedMap& old_selected_map = CollectSelectedMap( |
| 310 CollectSelectedMap(paint_range_, kPaintInvalidationNewMinusOld); | 300 paint_range_, CollectSelectedMapOption::kNotCollectBlock); |
| 311 // Clear SelectionState and invalidation. | 301 // Clear SelectionState and invalidation. |
| 312 for (auto layout_object : old_selected_map.object_map.Keys()) { | 302 for (auto layout_object : old_selected_map.object_map.Keys()) { |
| 313 const SelectionState old_state = layout_object->GetSelectionState(); | 303 const SelectionState old_state = layout_object->GetSelectionState(); |
| 314 layout_object->SetSelectionStateIfNeeded(SelectionNone); | 304 layout_object->SetSelectionStateIfNeeded(SelectionNone); |
| 315 if (layout_object->GetSelectionState() == old_state) | 305 if (layout_object->GetSelectionState() == old_state) |
| 316 continue; | 306 continue; |
| 317 layout_object->SetShouldInvalidateSelection(); | 307 layout_object->SetShouldInvalidateSelection(); |
| 318 } | 308 } |
| 319 | 309 |
| 320 // Reset selection. | 310 // Reset selection. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 362 if (start_pos.IsNull() || end_pos.IsNull() || | 352 if (start_pos.IsNull() || end_pos.IsNull() || |
| 363 selection.VisibleStart().DeepEquivalent() == | 353 selection.VisibleStart().DeepEquivalent() == |
| 364 selection.VisibleEnd().DeepEquivalent()) | 354 selection.VisibleEnd().DeepEquivalent()) |
| 365 return; | 355 return; |
| 366 DCHECK_LE(start_pos, end_pos); | 356 DCHECK_LE(start_pos, end_pos); |
| 367 LayoutObject* start_layout_object = start_pos.AnchorNode()->GetLayoutObject(); | 357 LayoutObject* start_layout_object = start_pos.AnchorNode()->GetLayoutObject(); |
| 368 LayoutObject* end_layout_object = end_pos.AnchorNode()->GetLayoutObject(); | 358 LayoutObject* end_layout_object = end_pos.AnchorNode()->GetLayoutObject(); |
| 369 if (!start_layout_object || !end_layout_object) | 359 if (!start_layout_object || !end_layout_object) |
| 370 return; | 360 return; |
| 371 DCHECK(start_layout_object->View() == end_layout_object->View()); | 361 DCHECK(start_layout_object->View() == end_layout_object->View()); |
| 372 SetSelection( | 362 |
| 373 SelectionPaintRange(start_layout_object, start_pos.ComputeEditingOffset(), | 363 SelectionPaintRange new_range( |
| 374 end_layout_object, end_pos.ComputeEditingOffset())); | 364 start_layout_object, start_pos.ComputeEditingOffset(), end_layout_object, |
| 365 end_pos.ComputeEditingOffset()); | |
| 366 // Just return if the selection hasn't changed. | |
| 367 if (paint_range_ == new_range) | |
| 368 return; | |
| 369 | |
| 370 DCHECK(frame_selection_->GetDocument().GetLayoutView()->GetFrameView()); | |
| 371 DCHECK(!frame_selection_->GetDocument().NeedsLayoutTreeUpdate()); | |
| 372 SetSelectionStateAndShouldInvalidateSelection(new_range, paint_range_); | |
| 373 paint_range_ = new_range; | |
| 375 } | 374 } |
| 376 | 375 |
| 377 void LayoutSelection::OnDocumentShutdown() { | 376 void LayoutSelection::OnDocumentShutdown() { |
| 378 has_pending_selection_ = false; | 377 has_pending_selection_ = false; |
| 379 paint_range_ = SelectionPaintRange(); | 378 paint_range_ = SelectionPaintRange(); |
| 380 } | 379 } |
| 381 | 380 |
| 382 static LayoutRect SelectionRectForLayoutObject(const LayoutObject* object) { | 381 static LayoutRect SelectionRectForLayoutObject(const LayoutObject* object) { |
| 383 if (!object->IsRooted()) | 382 if (!object->IsRooted()) |
| 384 return LayoutRect(); | 383 return LayoutRect(); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 443 | 442 |
| 444 o->SetShouldInvalidateSelection(); | 443 o->SetShouldInvalidateSelection(); |
| 445 } | 444 } |
| 446 } | 445 } |
| 447 | 446 |
| 448 DEFINE_TRACE(LayoutSelection) { | 447 DEFINE_TRACE(LayoutSelection) { |
| 449 visitor->Trace(frame_selection_); | 448 visitor->Trace(frame_selection_); |
| 450 } | 449 } |
| 451 | 450 |
| 452 } // namespace blink | 451 } // namespace blink |
| OLD | NEW |