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 7fe3f6b27259f3321a664818cd3c5e9ff835272c..67b22d6e0cdc8b1769dd540c083c52529b45b176 100644 |
--- a/third_party/WebKit/Source/core/editing/LayoutSelection.cpp |
+++ b/third_party/WebKit/Source/core/editing/LayoutSelection.cpp |
@@ -32,13 +32,34 @@ |
namespace blink { |
+SelectionPaintRange::SelectionPaintRange(LayoutObject* start_layout_object, |
+ int start_offset, |
+ LayoutObject* end_layout_object, |
+ int end_offset) |
+ : start_layout_object_(start_layout_object), |
+ start_offset_(start_offset), |
+ end_layout_object_(end_layout_object), |
+ end_offset_(end_offset) { |
+ DCHECK(StartLayoutObject()); |
+ DCHECK(EndLayoutObject()); |
+ if (StartLayoutObject() == EndLayoutObject()) |
+ DCHECK_LT(StartOffset(), EndOffset()); |
+} |
+ |
+bool SelectionPaintRange::operator==(const SelectionPaintRange& other) const { |
+ return start_layout_object_ == other.start_layout_object_ && |
+ start_offset_ == other.start_offset_ && |
+ end_layout_object_ == other.end_layout_object_ && |
+ end_offset_ == other.end_offset_; |
+} |
+bool SelectionPaintRange::operator!=(const SelectionPaintRange& other) const { |
+ return !(*this == other); |
+} |
+ |
LayoutSelection::LayoutSelection(FrameSelection& frame_selection) |
: frame_selection_(&frame_selection), |
has_pending_selection_(false), |
- selection_start_(nullptr), |
- selection_end_(nullptr), |
- selection_start_pos_(-1), |
- selection_end_pos_(-1) {} |
+ paint_range_(SelectionPaintRange()) {} |
SelectionInFlatTree LayoutSelection::CalcVisibleSelection( |
const VisibleSelectionInFlatTree& original_selection) const { |
@@ -124,19 +145,17 @@ struct SelectedMap { |
}; |
static SelectedMap CollectSelectedMap( |
- LayoutObject* selection_start, |
- LayoutObject* selection_end, |
- int selection_end_pos, |
+ const SelectionPaintRange& range, |
LayoutSelection::SelectionPaintInvalidationMode |
block_paint_invalidation_mode) { |
SelectedMap selected_map; |
LayoutObject* const stop = |
- LayoutObjectAfterPosition(selection_end, selection_end_pos); |
- for (LayoutObject* runner = selection_start; runner && (runner != stop); |
- runner = runner->NextInPreOrder()) { |
- if (!runner->CanBeSelectionLeaf() && runner != selection_start && |
- runner != selection_end) |
+ LayoutObjectAfterPosition(range.EndLayoutObject(), range.EndOffset()); |
+ for (LayoutObject* runner = range.StartLayoutObject(); |
+ runner && (runner != stop); runner = runner->NextInPreOrder()) { |
+ if (!runner->CanBeSelectionLeaf() && runner != range.StartLayoutObject() && |
+ runner != range.EndLayoutObject()) |
continue; |
if (runner->GetSelectionState() == SelectionNone) |
continue; |
@@ -160,52 +179,45 @@ static SelectedMap CollectSelectedMap( |
} |
// Update the selection status of all LayoutObjects between |start| and |end|. |
-static void SetSelectionState(LayoutObject* start, |
- LayoutObject* end, |
- int end_pos) { |
- if (start && start == end) { |
- start->SetSelectionStateIfNeeded(SelectionBoth); |
+static void SetSelectionState(const SelectionPaintRange& range) { |
+ DCHECK(range != SelectionPaintRange()); |
+ if (range.StartLayoutObject() == range.EndLayoutObject()) { |
+ range.StartLayoutObject()->SetSelectionStateIfNeeded(SelectionBoth); |
} else { |
- if (start) |
- start->SetSelectionStateIfNeeded(SelectionStart); |
- if (end) |
- end->SetSelectionStateIfNeeded(SelectionEnd); |
+ range.StartLayoutObject()->SetSelectionStateIfNeeded(SelectionStart); |
+ range.EndLayoutObject()->SetSelectionStateIfNeeded(SelectionEnd); |
} |
- LayoutObject* const stop = LayoutObjectAfterPosition(end, end_pos); |
- for (LayoutObject* runner = start; runner && runner != stop; |
- runner = runner->NextInPreOrder()) { |
- if (runner != start && runner != end && runner->CanBeSelectionLeaf()) |
+ LayoutObject* const stop = |
+ LayoutObjectAfterPosition(range.EndLayoutObject(), range.EndOffset()); |
+ for (LayoutObject* runner = range.StartLayoutObject(); |
+ runner && runner != stop; runner = runner->NextInPreOrder()) { |
+ if (runner != range.StartLayoutObject() && |
+ runner != range.EndLayoutObject() && runner->CanBeSelectionLeaf()) |
runner->SetSelectionStateIfNeeded(SelectionInside); |
} |
} |
void LayoutSelection::SetSelection( |
- LayoutObject* start, |
- int start_pos, |
- LayoutObject* end, |
- int end_pos, |
+ const SelectionPaintRange& new_range, |
SelectionPaintInvalidationMode block_paint_invalidation_mode) { |
- DCHECK(start); |
- DCHECK(end); |
+ DCHECK(new_range != SelectionPaintRange()); |
yosin_UTC9
2017/05/24 09:31:18
I prefer to use |IsNull()| as |EpehemralRange|
yoichio
2017/05/25 02:00:35
Done.
|
// Just return if the selection hasn't changed. |
- if (selection_start_ == start && selection_start_pos_ == start_pos && |
- selection_end_ == end && selection_end_pos_ == end_pos) |
+ if (paint_range_ == new_range) |
return; |
DCHECK(frame_selection_->GetDocument().GetLayoutView()->GetFrameView()); |
DCHECK(!frame_selection_->GetDocument().NeedsLayoutTreeUpdate()); |
SelectedMap old_selected_map = |
- CollectSelectedMap(selection_start_, selection_end_, selection_end_pos_, |
- block_paint_invalidation_mode); |
+ CollectSelectedMap(paint_range_, block_paint_invalidation_mode); |
// Now clear the selection. |
for (auto layout_object : old_selected_map.object_map.Keys()) |
layout_object->SetSelectionStateIfNeeded(SelectionNone); |
- SetSelectionState(start, end, end_pos); |
+ SetSelectionState(new_range); |
// Now that the selection state has been updated for the new objects, walk |
// them again and put them in the new objects list. |
@@ -213,7 +225,7 @@ void LayoutSelection::SetSelection( |
// SelectionState, it's just more convenient to have it use the same data |
// structure as |old_selected_map|. |
SelectedMap new_selected_map = |
- CollectSelectedMap(start, end, end_pos, kPaintInvalidationNewXOROld); |
+ CollectSelectedMap(new_range, kPaintInvalidationNewXOROld); |
// Have any of the old selected objects changed compared to the new selection? |
for (const auto& pair : old_selected_map.object_map) { |
@@ -221,8 +233,10 @@ void LayoutSelection::SetSelection( |
SelectionState new_selection_state = obj->GetSelectionState(); |
SelectionState old_selection_state = pair.value; |
if (new_selection_state != old_selection_state || |
- (start == obj && start_pos != selection_start_pos_) || |
- (end == obj && end_pos != selection_end_pos_)) { |
+ (new_range.StartLayoutObject() == obj && |
+ new_range.StartOffset() != paint_range_.StartOffset()) || |
+ (new_range.EndLayoutObject() == obj && |
+ new_range.EndOffset() != paint_range_.EndOffset())) { |
obj->SetShouldInvalidateSelection(); |
new_selected_map.object_map.erase(obj); |
} |
@@ -249,16 +263,12 @@ void LayoutSelection::SetSelection( |
for (auto layout_object : new_selected_map.block_map.Keys()) |
layout_object->SetShouldInvalidateSelection(); |
- // set selection start and end |
- selection_start_ = start; |
- selection_start_pos_ = start_pos; |
- selection_end_ = end; |
- selection_end_pos_ = end_pos; |
+ paint_range_ = new_range; |
} |
std::pair<int, int> LayoutSelection::SelectionStartEnd() { |
Commit(); |
- return std::make_pair(selection_start_pos_, selection_end_pos_); |
+ return std::make_pair(paint_range_.StartOffset(), paint_range_.EndOffset()); |
} |
void LayoutSelection::ClearSelection() { |
@@ -267,17 +277,12 @@ void LayoutSelection::ClearSelection() { |
// invalidations. |
DisableCompositingQueryAsserts disabler; |
- // Just return if the selection hasn't changed. |
- if (!selection_start_) { |
- DCHECK_EQ(selection_end_, nullptr); |
- DCHECK_EQ(selection_start_pos_, -1); |
- DCHECK_EQ(selection_end_pos_, -1); |
+ // Just return if the selection is already empty. |
+ if (paint_range_ == SelectionPaintRange()) |
return; |
- } |
const SelectedMap& old_selected_map = |
- CollectSelectedMap(selection_start_, selection_end_, selection_end_pos_, |
- kPaintInvalidationNewMinusOld); |
+ CollectSelectedMap(paint_range_, kPaintInvalidationNewMinusOld); |
// Clear SelectionState and invalidation. |
for (auto layout_object : old_selected_map.object_map.Keys()) { |
const SelectionState old_state = layout_object->GetSelectionState(); |
@@ -288,10 +293,7 @@ void LayoutSelection::ClearSelection() { |
} |
// Reset selection start and end. |
- selection_start_ = nullptr; |
- selection_start_pos_ = -1; |
- selection_end_ = nullptr; |
- selection_end_pos_ = -1; |
+ paint_range_ = SelectionPaintRange(); |
} |
void LayoutSelection::Commit() { |
@@ -342,16 +344,14 @@ void LayoutSelection::Commit() { |
if (!start_layout_object || !end_layout_object) |
return; |
DCHECK(start_layout_object->View() == end_layout_object->View()); |
- SetSelection(start_layout_object, start_pos.ComputeEditingOffset(), |
- end_layout_object, end_pos.ComputeEditingOffset()); |
+ SetSelection( |
+ SelectionPaintRange(start_layout_object, start_pos.ComputeEditingOffset(), |
+ end_layout_object, end_pos.ComputeEditingOffset())); |
} |
void LayoutSelection::OnDocumentShutdown() { |
has_pending_selection_ = false; |
- selection_start_ = nullptr; |
- selection_end_ = nullptr; |
- selection_start_pos_ = -1; |
- selection_end_pos_ = -1; |
+ paint_range_ = SelectionPaintRange(); |
} |
static LayoutRect SelectionRectForLayoutObject(const LayoutObject* object) { |
@@ -372,12 +372,12 @@ IntRect LayoutSelection::SelectionBounds() { |
VisitedContainingBlockSet visited_containing_blocks; |
Commit(); |
- LayoutObject* os = selection_start_; |
- LayoutObject* stop = |
- LayoutObjectAfterPosition(selection_end_, selection_end_pos_); |
+ LayoutObject* os = paint_range_.StartLayoutObject(); |
+ LayoutObject* stop = LayoutObjectAfterPosition(paint_range_.EndLayoutObject(), |
+ paint_range_.EndOffset()); |
while (os && os != stop) { |
- if ((os->CanBeSelectionLeaf() || os == selection_start_ || |
- os == selection_end_) && |
+ if ((os->CanBeSelectionLeaf() || os == paint_range_.StartLayoutObject() || |
+ os == paint_range_.EndLayoutObject()) && |
os->GetSelectionState() != SelectionNone) { |
// Blocks are responsible for painting line gaps and margin gaps. They |
// must be examined as well. |
@@ -400,12 +400,12 @@ IntRect LayoutSelection::SelectionBounds() { |
} |
void LayoutSelection::InvalidatePaintForSelection() { |
- LayoutObject* end = |
- LayoutObjectAfterPosition(selection_end_, selection_end_pos_); |
- for (LayoutObject* o = selection_start_; o && o != end; |
+ LayoutObject* end = LayoutObjectAfterPosition(paint_range_.EndLayoutObject(), |
+ paint_range_.EndOffset()); |
+ for (LayoutObject* o = paint_range_.StartLayoutObject(); o && o != end; |
o = o->NextInPreOrder()) { |
- if (!o->CanBeSelectionLeaf() && o != selection_start_ && |
- o != selection_end_) |
+ if (!o->CanBeSelectionLeaf() && o != paint_range_.StartLayoutObject() && |
+ o != paint_range_.EndLayoutObject()) |
continue; |
if (o->GetSelectionState() == SelectionNone) |
continue; |