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 |