Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(207)

Unified Diff: third_party/WebKit/Source/core/editing/LayoutSelection.cpp

Issue 2901263002: Introduce SelectionPaintRange in LayoutSelection (Closed)
Patch Set: Add null check Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/core/editing/LayoutSelection.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..81174f1e27f92bd38e33634a79b251a30c2ca537 100644
--- a/third_party/WebKit/Source/core/editing/LayoutSelection.cpp
+++ b/third_party/WebKit/Source/core/editing/LayoutSelection.cpp
@@ -32,13 +32,52 @@
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(start_layout_object_);
+ DCHECK(end_layout_object_);
+ if (start_layout_object_ != end_layout_object_)
+ return;
+ DCHECK_LT(start_offset_, end_offset_);
+}
+
+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_;
+}
+
+LayoutObject* SelectionPaintRange::StartLayoutObject() const {
+ DCHECK(!IsNull());
+ return start_layout_object_;
+}
+
+int SelectionPaintRange::StartOffset() const {
+ DCHECK(!IsNull());
+ return start_offset_;
+}
+
+LayoutObject* SelectionPaintRange::EndLayoutObject() const {
+ DCHECK(!IsNull());
+ return end_layout_object_;
+}
+
+int SelectionPaintRange::EndOffset() const {
+ DCHECK(!IsNull());
+ return end_offset_;
+}
+
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 +163,20 @@ struct SelectedMap {
};
static SelectedMap CollectSelectedMap(
- LayoutObject* selection_start,
- LayoutObject* selection_end,
- int selection_end_pos,
+ const SelectionPaintRange& range,
LayoutSelection::SelectionPaintInvalidationMode
block_paint_invalidation_mode) {
+ if (range.IsNull())
+ return SelectedMap();
+
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 +200,47 @@ 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) {
+ if (range.IsNull())
+ return;
+
+ 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.IsNull());
// 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 +248,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 +256,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 +286,14 @@ 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_);
+ if (paint_range_.IsNull())
+ return std::make_pair(-1, -1);
+ return std::make_pair(paint_range_.StartOffset(), paint_range_.EndOffset());
}
void LayoutSelection::ClearSelection() {
@@ -267,17 +302,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_.IsNull())
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();
@@ -287,11 +317,8 @@ void LayoutSelection::ClearSelection() {
layout_object->SetShouldInvalidateSelection();
}
- // Reset selection start and end.
- selection_start_ = nullptr;
- selection_start_pos_ = -1;
- selection_end_ = nullptr;
- selection_end_pos_ = -1;
+ // Reset selection.
+ paint_range_ = SelectionPaintRange();
}
void LayoutSelection::Commit() {
@@ -342,16 +369,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 +397,15 @@ IntRect LayoutSelection::SelectionBounds() {
VisitedContainingBlockSet visited_containing_blocks;
Commit();
- LayoutObject* os = selection_start_;
- LayoutObject* stop =
- LayoutObjectAfterPosition(selection_end_, selection_end_pos_);
+ if (paint_range_.IsNull())
+ return IntRect();
+
+ 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 +428,15 @@ IntRect LayoutSelection::SelectionBounds() {
}
void LayoutSelection::InvalidatePaintForSelection() {
- LayoutObject* end =
- LayoutObjectAfterPosition(selection_end_, selection_end_pos_);
- for (LayoutObject* o = selection_start_; o && o != end;
+ if (paint_range_.IsNull())
+ return;
+
+ 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;
« no previous file with comments | « third_party/WebKit/Source/core/editing/LayoutSelection.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698