Chromium Code Reviews| Index: third_party/WebKit/Source/core/editing/LayoutSelection.cpp |
| diff --git a/third_party/WebKit/Source/core/editing/LayoutSelection.cpp b/third_party/WebKit/Source/core/editing/LayoutSelection.cpp |
| index fbdc210671b8a9b7f6947514547ff9709dba35af..0c98307f0f304049ed466294314cef866b620fa7 100644 |
| --- a/third_party/WebKit/Source/core/editing/LayoutSelection.cpp |
| +++ b/third_party/WebKit/Source/core/editing/LayoutSelection.cpp |
| @@ -292,11 +292,42 @@ static void UpdateLayoutObjectState(const SelectionPaintRange& new_range, |
| layout_object->SetShouldInvalidateSelection(); |
| } |
| +static LayoutBlockFlow* MostRecentLayoutBlockFlow(LayoutObject* layout_object) { |
| + for (LayoutObject* runner = layout_object; runner && !runner->IsLayoutView(); |
| + runner = runner->ContainingBlock()) { |
|
kojii
2017/06/21 10:10:09
Parent()
|
| + if (runner->IsLayoutBlockFlow()) |
| + return ToLayoutBlockFlow(runner); |
| + } |
| + return nullptr; |
| +} |
| + |
| +static int GetOffsetInMixedTree(LayoutObject* layout_object, int offset) { |
| + LayoutBlockFlow* start_block_flow = MostRecentLayoutBlockFlow(layout_object); |
| + if (!start_block_flow || !start_block_flow->IsLayoutNGBlockFlow()) |
| + return offset; // Legay. Return DOM offset; |
| + |
| + // TODO(yoichio): How about caching? Create takes |
| + // O(<LayoutNGBlockflow.Data.text_content_>). |
| + const NGTextOffsetMap& offset_map = |
| + NGTextOffsetMap::Create(*ToLayoutNGBlockFlowOrDie(start_block_flow)); |
| + const Optional<int> ng_offset = |
| + offset_map.Get(layout_object->GetNode(), offset); |
| + return ng_offset.value(); |
| +} |
| + |
| std::pair<int, int> LayoutSelection::SelectionStartEnd() { |
| Commit(); |
| if (paint_range_.IsNull()) |
| return std::make_pair(-1, -1); |
| - return std::make_pair(paint_range_.StartOffset(), paint_range_.EndOffset()); |
| + if (!RuntimeEnabledFeatures::LayoutNGEnabled()) { |
| + return std::make_pair(paint_range_.StartOffset(), paint_range_.EndOffset()); |
| + } |
| + // Layout NG mapping |
| + const int start_offset_mixed = GetOffsetInMixedTree( |
| + paint_range_.StartLayoutObject(), paint_range_.StartOffset()); |
| + const int end_offset_mixed = GetOffsetInMixedTree( |
| + paint_range_.EndLayoutObject(), paint_range_.EndOffset()); |
| + return std::make_pair(start_offset_mixed, end_offset_mixed); |
| } |
| void LayoutSelection::ClearSelection() { |
| @@ -321,6 +352,64 @@ void LayoutSelection::ClearSelection() { |
| paint_range_ = SelectionPaintRange(); |
| } |
| +static SelectionPaintRange CalcSelectionNG( |
|
yoichio
2017/06/27 07:54:52
Its strange that we have 3 code pass for legacy, n
|
| + const FrameSelection& frame_selection) { |
| + const SelectionInDOMTree& selection_in_dom = |
| + frame_selection.GetSelectionInDOMTree(); |
| + if (selection_in_dom.IsNone()) |
| + return SelectionPaintRange(); |
| + |
| + // yoichio: Tthis should be on FlatTree. |
| + const Position& start = selection_in_dom.ComputeStartPosition(); |
| + const Position& end = selection_in_dom.ComputeEndPosition(); |
| + LayoutObject* const start_layout_object = |
| + start.AnchorNode()->GetLayoutObject(); |
| + LayoutObject* const end_layout_object = end.AnchorNode()->GetLayoutObject(); |
| + |
| + Node* start_node = nullptr; |
| + LayoutObject* paint_range_start = nullptr; |
| + int paint_range_start_offset = -1; |
| + // Seek the first text node. |
| + for (LayoutObject* runner = start_layout_object; |
| + runner && runner != end_layout_object->NextInPreOrder(); |
| + runner = runner->NextInPreOrder()) { |
| + if (runner->IsText() && runner->GetNode()->IsTextNode()) { |
|
yoichio
2017/06/27 07:54:52
LayoutText will gone.
|
| + start_node = runner->GetNode(); |
| + paint_range_start = runner; |
| + if (runner == start_layout_object) { |
| + paint_range_start_offset = start.ComputeEditingOffset(); |
| + break; |
| + } |
| + paint_range_start_offset = 0; |
| + break; |
| + } |
|
yoichio
2017/06/27 07:54:52
br is LayouObject.isText().
|
| + } |
| + DCHECK(paint_range_start); |
| + // Should consider block cursor painting. |
| + Node* end_node = nullptr; |
| + LayoutObject* paint_range_end = nullptr; |
| + int paint_range_end_offset = -1; |
| + for (LayoutObject* runner = end_layout_object; |
| + runner && runner != start_layout_object->PreviousInPreOrder(); |
| + runner = runner->PreviousInPreOrder()) { |
| + if (runner->IsText() && runner->GetNode()->IsTextNode()) { |
| + end_node = runner->GetNode(); |
| + paint_range_end = runner; |
| + if (runner == end_layout_object) { |
| + paint_range_end_offset = end.ComputeEditingOffset(); |
| + break; |
| + } |
| + LayoutText* text = ToLayoutText(runner); |
| + paint_range_end_offset = text->TextLength(); |
| + break; |
| + } |
| + } |
| + DCHECK(paint_range_end); |
| + |
| + return SelectionPaintRange(paint_range_start, paint_range_start_offset, |
| + paint_range_end, paint_range_end_offset); |
| +} |
| + |
| static SelectionPaintRange CalcSelectionPaintRange( |
| const FrameSelection& frame_selection) { |
| const SelectionInDOMTree& selection_in_dom = |
| @@ -328,6 +417,11 @@ static SelectionPaintRange CalcSelectionPaintRange( |
| if (selection_in_dom.IsNone()) |
| return SelectionPaintRange(); |
| + if (RuntimeEnabledFeatures::LayoutNGEnabled()) |
| + return CalcSelectionNG(frame_selection); |
| + |
| + // NGMemo: ComputeVisibleSelectionInFlatTree depends on offsetmapping from |
| + // DOM->NG. |
| const VisibleSelectionInFlatTree& original_selection = |
| frame_selection.ComputeVisibleSelectionInFlatTree(); |
| // Construct a new VisibleSolution, since visibleSelection() is not |