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 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 285 new_selected_map.block_map.erase(block); | 285 new_selected_map.block_map.erase(block); |
| 286 } | 286 } |
| 287 } | 287 } |
| 288 | 288 |
| 289 // Any new blocks that remain were not found in the old blocks dict, and so | 289 // Any new blocks that remain were not found in the old blocks dict, and so |
| 290 // they need to be updated. | 290 // they need to be updated. |
| 291 for (auto layout_object : new_selected_map.block_map.Keys()) | 291 for (auto layout_object : new_selected_map.block_map.Keys()) |
| 292 layout_object->SetShouldInvalidateSelection(); | 292 layout_object->SetShouldInvalidateSelection(); |
| 293 } | 293 } |
| 294 | 294 |
| 295 static LayoutBlockFlow* MostRecentLayoutBlockFlow(LayoutObject* layout_object) { | |
| 296 for (LayoutObject* runner = layout_object; runner && !runner->IsLayoutView(); | |
| 297 runner = runner->ContainingBlock()) { | |
|
kojii
2017/06/21 10:10:09
Parent()
| |
| 298 if (runner->IsLayoutBlockFlow()) | |
| 299 return ToLayoutBlockFlow(runner); | |
| 300 } | |
| 301 return nullptr; | |
| 302 } | |
| 303 | |
| 304 static int GetOffsetInMixedTree(LayoutObject* layout_object, int offset) { | |
| 305 LayoutBlockFlow* start_block_flow = MostRecentLayoutBlockFlow(layout_object); | |
| 306 if (!start_block_flow || !start_block_flow->IsLayoutNGBlockFlow()) | |
| 307 return offset; // Legay. Return DOM offset; | |
| 308 | |
| 309 // TODO(yoichio): How about caching? Create takes | |
| 310 // O(<LayoutNGBlockflow.Data.text_content_>). | |
| 311 const NGTextOffsetMap& offset_map = | |
| 312 NGTextOffsetMap::Create(*ToLayoutNGBlockFlowOrDie(start_block_flow)); | |
| 313 const Optional<int> ng_offset = | |
| 314 offset_map.Get(layout_object->GetNode(), offset); | |
| 315 return ng_offset.value(); | |
| 316 } | |
| 317 | |
| 295 std::pair<int, int> LayoutSelection::SelectionStartEnd() { | 318 std::pair<int, int> LayoutSelection::SelectionStartEnd() { |
| 296 Commit(); | 319 Commit(); |
| 297 if (paint_range_.IsNull()) | 320 if (paint_range_.IsNull()) |
| 298 return std::make_pair(-1, -1); | 321 return std::make_pair(-1, -1); |
| 299 return std::make_pair(paint_range_.StartOffset(), paint_range_.EndOffset()); | 322 if (!RuntimeEnabledFeatures::LayoutNGEnabled()) { |
| 323 return std::make_pair(paint_range_.StartOffset(), paint_range_.EndOffset()); | |
| 324 } | |
| 325 // Layout NG mapping | |
| 326 const int start_offset_mixed = GetOffsetInMixedTree( | |
| 327 paint_range_.StartLayoutObject(), paint_range_.StartOffset()); | |
| 328 const int end_offset_mixed = GetOffsetInMixedTree( | |
| 329 paint_range_.EndLayoutObject(), paint_range_.EndOffset()); | |
| 330 return std::make_pair(start_offset_mixed, end_offset_mixed); | |
| 300 } | 331 } |
| 301 | 332 |
| 302 void LayoutSelection::ClearSelection() { | 333 void LayoutSelection::ClearSelection() { |
| 303 // For querying Layer::compositingState() | 334 // For querying Layer::compositingState() |
| 304 // This is correct, since destroying layout objects needs to cause eager paint | 335 // This is correct, since destroying layout objects needs to cause eager paint |
| 305 // invalidations. | 336 // invalidations. |
| 306 DisableCompositingQueryAsserts disabler; | 337 DisableCompositingQueryAsserts disabler; |
| 307 | 338 |
| 308 // Just return if the selection is already empty. | 339 // Just return if the selection is already empty. |
| 309 if (paint_range_.IsNull()) | 340 if (paint_range_.IsNull()) |
| 310 return; | 341 return; |
| 311 | 342 |
| 312 for (auto layout_object : paint_range_) { | 343 for (auto layout_object : paint_range_) { |
| 313 const SelectionState old_state = layout_object->GetSelectionState(); | 344 const SelectionState old_state = layout_object->GetSelectionState(); |
| 314 layout_object->SetSelectionStateIfNeeded(SelectionState::kNone); | 345 layout_object->SetSelectionStateIfNeeded(SelectionState::kNone); |
| 315 if (layout_object->GetSelectionState() == old_state) | 346 if (layout_object->GetSelectionState() == old_state) |
| 316 continue; | 347 continue; |
| 317 layout_object->SetShouldInvalidateSelection(); | 348 layout_object->SetShouldInvalidateSelection(); |
| 318 } | 349 } |
| 319 | 350 |
| 320 // Reset selection. | 351 // Reset selection. |
| 321 paint_range_ = SelectionPaintRange(); | 352 paint_range_ = SelectionPaintRange(); |
| 322 } | 353 } |
| 323 | 354 |
| 355 static SelectionPaintRange CalcSelectionNG( | |
|
yoichio
2017/06/27 07:54:52
Its strange that we have 3 code pass for legacy, n
| |
| 356 const FrameSelection& frame_selection) { | |
| 357 const SelectionInDOMTree& selection_in_dom = | |
| 358 frame_selection.GetSelectionInDOMTree(); | |
| 359 if (selection_in_dom.IsNone()) | |
| 360 return SelectionPaintRange(); | |
| 361 | |
| 362 // yoichio: Tthis should be on FlatTree. | |
| 363 const Position& start = selection_in_dom.ComputeStartPosition(); | |
| 364 const Position& end = selection_in_dom.ComputeEndPosition(); | |
| 365 LayoutObject* const start_layout_object = | |
| 366 start.AnchorNode()->GetLayoutObject(); | |
| 367 LayoutObject* const end_layout_object = end.AnchorNode()->GetLayoutObject(); | |
| 368 | |
| 369 Node* start_node = nullptr; | |
| 370 LayoutObject* paint_range_start = nullptr; | |
| 371 int paint_range_start_offset = -1; | |
| 372 // Seek the first text node. | |
| 373 for (LayoutObject* runner = start_layout_object; | |
| 374 runner && runner != end_layout_object->NextInPreOrder(); | |
| 375 runner = runner->NextInPreOrder()) { | |
| 376 if (runner->IsText() && runner->GetNode()->IsTextNode()) { | |
|
yoichio
2017/06/27 07:54:52
LayoutText will gone.
| |
| 377 start_node = runner->GetNode(); | |
| 378 paint_range_start = runner; | |
| 379 if (runner == start_layout_object) { | |
| 380 paint_range_start_offset = start.ComputeEditingOffset(); | |
| 381 break; | |
| 382 } | |
| 383 paint_range_start_offset = 0; | |
| 384 break; | |
| 385 } | |
|
yoichio
2017/06/27 07:54:52
br is LayouObject.isText().
| |
| 386 } | |
| 387 DCHECK(paint_range_start); | |
| 388 // Should consider block cursor painting. | |
| 389 Node* end_node = nullptr; | |
| 390 LayoutObject* paint_range_end = nullptr; | |
| 391 int paint_range_end_offset = -1; | |
| 392 for (LayoutObject* runner = end_layout_object; | |
| 393 runner && runner != start_layout_object->PreviousInPreOrder(); | |
| 394 runner = runner->PreviousInPreOrder()) { | |
| 395 if (runner->IsText() && runner->GetNode()->IsTextNode()) { | |
| 396 end_node = runner->GetNode(); | |
| 397 paint_range_end = runner; | |
| 398 if (runner == end_layout_object) { | |
| 399 paint_range_end_offset = end.ComputeEditingOffset(); | |
| 400 break; | |
| 401 } | |
| 402 LayoutText* text = ToLayoutText(runner); | |
| 403 paint_range_end_offset = text->TextLength(); | |
| 404 break; | |
| 405 } | |
| 406 } | |
| 407 DCHECK(paint_range_end); | |
| 408 | |
| 409 return SelectionPaintRange(paint_range_start, paint_range_start_offset, | |
| 410 paint_range_end, paint_range_end_offset); | |
| 411 } | |
| 412 | |
| 324 static SelectionPaintRange CalcSelectionPaintRange( | 413 static SelectionPaintRange CalcSelectionPaintRange( |
| 325 const FrameSelection& frame_selection) { | 414 const FrameSelection& frame_selection) { |
| 326 const SelectionInDOMTree& selection_in_dom = | 415 const SelectionInDOMTree& selection_in_dom = |
| 327 frame_selection.GetSelectionInDOMTree(); | 416 frame_selection.GetSelectionInDOMTree(); |
| 328 if (selection_in_dom.IsNone()) | 417 if (selection_in_dom.IsNone()) |
| 329 return SelectionPaintRange(); | 418 return SelectionPaintRange(); |
| 330 | 419 |
| 420 if (RuntimeEnabledFeatures::LayoutNGEnabled()) | |
| 421 return CalcSelectionNG(frame_selection); | |
| 422 | |
| 423 // NGMemo: ComputeVisibleSelectionInFlatTree depends on offsetmapping from | |
| 424 // DOM->NG. | |
| 331 const VisibleSelectionInFlatTree& original_selection = | 425 const VisibleSelectionInFlatTree& original_selection = |
| 332 frame_selection.ComputeVisibleSelectionInFlatTree(); | 426 frame_selection.ComputeVisibleSelectionInFlatTree(); |
| 333 // Construct a new VisibleSolution, since visibleSelection() is not | 427 // Construct a new VisibleSolution, since visibleSelection() is not |
| 334 // necessarily valid, and the following steps assume a valid selection. See | 428 // necessarily valid, and the following steps assume a valid selection. See |
| 335 // <https://bugs.webkit.org/show_bug.cgi?id=69563> and | 429 // <https://bugs.webkit.org/show_bug.cgi?id=69563> and |
| 336 // <rdar://problem/10232866>. | 430 // <rdar://problem/10232866>. |
| 337 const SelectionInFlatTree& new_selection = CalcSelection( | 431 const SelectionInFlatTree& new_selection = CalcSelection( |
| 338 original_selection, frame_selection.ShouldShowBlockCursor()); | 432 original_selection, frame_selection.ShouldShowBlockCursor()); |
| 339 const VisibleSelectionInFlatTree& selection = | 433 const VisibleSelectionInFlatTree& selection = |
| 340 CreateVisibleSelection(new_selection); | 434 CreateVisibleSelection(new_selection); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 488 int ng_offset = offset_mapping[begin + i - 1]; | 582 int ng_offset = offset_mapping[begin + i - 1]; |
| 489 builder.Add(text, i, ng_offset); | 583 builder.Add(text, i, ng_offset); |
| 490 } | 584 } |
| 491 | 585 |
| 492 last_object = layout_object; | 586 last_object = layout_object; |
| 493 } | 587 } |
| 494 return builder.Build(); | 588 return builder.Build(); |
| 495 } | 589 } |
| 496 | 590 |
| 497 } // namespace blink | 591 } // namespace blink |
| OLD | NEW |