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

Side by Side Diff: third_party/WebKit/Source/core/editing/SurroundingText.cpp

Issue 2928073002: Reland: Made surrounding text work for last word in a document (Closed)
Patch Set: Do not create surrounding text for control elements, updated layout tests Created 3 years, 5 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 19 matching lines...) Expand all
30 30
31 #include "core/editing/SurroundingText.h" 31 #include "core/editing/SurroundingText.h"
32 32
33 #include "core/dom/Document.h" 33 #include "core/dom/Document.h"
34 #include "core/dom/Element.h" 34 #include "core/dom/Element.h"
35 #include "core/dom/Range.h" 35 #include "core/dom/Range.h"
36 #include "core/editing/EditingUtilities.h" 36 #include "core/editing/EditingUtilities.h"
37 #include "core/editing/Position.h" 37 #include "core/editing/Position.h"
38 #include "core/editing/iterators/BackwardsCharacterIterator.h" 38 #include "core/editing/iterators/BackwardsCharacterIterator.h"
39 #include "core/editing/iterators/CharacterIterator.h" 39 #include "core/editing/iterators/CharacterIterator.h"
40 #include "core/html/HTMLFormControlElement.h"
40 41
41 namespace blink { 42 namespace blink {
42 43
43 SurroundingText::SurroundingText(const Range& range, unsigned max_length) 44 SurroundingText::SurroundingText(const Range& range, unsigned max_length)
44 : start_offset_in_content_(0), end_offset_in_content_(0) { 45 : start_offset_in_content_(0), end_offset_in_content_(0) {
45 Initialize(range.StartPosition(), range.EndPosition(), max_length); 46 Initialize(range.StartPosition(), range.EndPosition(), max_length);
46 } 47 }
47 48
48 SurroundingText::SurroundingText(const Position& position, unsigned max_length) 49 SurroundingText::SurroundingText(const Position& position, unsigned max_length)
49 : start_offset_in_content_(0), end_offset_in_content_(0) { 50 : start_offset_in_content_(0), end_offset_in_content_(0) {
(...skipping 15 matching lines...) Expand all
65 66
66 // The forward range starts at the selection end and ends at the document's 67 // The forward range starts at the selection end and ends at the document's
67 // or the input element's end. It will then be updated to only contain the 68 // or the input element's end. It will then be updated to only contain the
68 // text in the right range around the selection. 69 // text in the right range around the selection.
69 DCHECK_EQ(RootEditableElementOf(start_position), 70 DCHECK_EQ(RootEditableElementOf(start_position),
70 RootEditableElementOf(end_position)); 71 RootEditableElementOf(end_position));
71 Element* const root_editable = RootEditableElementOf(start_position); 72 Element* const root_editable = RootEditableElementOf(start_position);
72 Element* const root_element = 73 Element* const root_element =
73 root_editable ? root_editable : document->documentElement(); 74 root_editable ? root_editable : document->documentElement();
74 75
76 // Do not create surrounding text if start or end position is within a
77 // control.
78 if (HTMLFormControlElement::EnclosingFormControlElement(
79 start_position.ComputeContainerNode()) ||
80 HTMLFormControlElement::EnclosingFormControlElement(
81 end_position.ComputeContainerNode()))
82 return;
83
75 CharacterIterator forward_iterator( 84 CharacterIterator forward_iterator(
76 end_position, 85 end_position,
77 Position::LastPositionInNode(*root_element).ParentAnchoredEquivalent(), 86 Position::LastPositionInNode(*root_element).ParentAnchoredEquivalent(),
78 TextIteratorBehavior::Builder().SetStopsOnFormControls(true).Build()); 87 TextIteratorBehavior::Builder().SetStopsOnFormControls(true).Build());
79 // FIXME: why do we stop going trough the text if we were not able to select
80 // something on the right?
81 if (!forward_iterator.AtEnd()) 88 if (!forward_iterator.AtEnd())
82 forward_iterator.Advance(max_length - half_max_length); 89 forward_iterator.Advance(max_length - half_max_length);
83 90
84 EphemeralRange forward_range = forward_iterator.Range();
85 if (forward_range.IsNull() ||
86 !Range::Create(*document, end_position, forward_range.StartPosition())
87 ->GetText()
88 .length())
89 return;
90
91 // Same as with the forward range but with the backward range. The range 91 // Same as with the forward range but with the backward range. The range
92 // starts at the document's or input element's start and ends at the selection 92 // starts at the document's or input element's start and ends at the selection
93 // start and will be updated. 93 // start and will be updated.
94 BackwardsCharacterIterator backwards_iterator( 94 BackwardsCharacterIterator backwards_iterator(
95 Position::FirstPositionInNode(*root_element).ParentAnchoredEquivalent(), 95 Position::FirstPositionInNode(*root_element).ParentAnchoredEquivalent(),
96 start_position, 96 start_position,
97 TextIteratorBehavior::Builder().SetStopsOnFormControls(true).Build()); 97 TextIteratorBehavior::Builder().SetStopsOnFormControls(true).Build());
98 if (!backwards_iterator.AtEnd()) 98 if (!backwards_iterator.AtEnd())
99 backwards_iterator.Advance(half_max_length); 99 backwards_iterator.Advance(half_max_length);
100 100
101 const TextIteratorBehavior behavior = 101 const TextIteratorBehavior behavior =
102 TextIteratorBehavior::NoTrailingSpaceRangeLengthBehavior(); 102 TextIteratorBehavior::NoTrailingSpaceRangeLengthBehavior();
103 start_offset_in_content_ = TextIterator::RangeLength( 103 start_offset_in_content_ = TextIterator::RangeLength(
104 backwards_iterator.EndPosition(), start_position, behavior); 104 backwards_iterator.EndPosition(), start_position, behavior);
105 end_offset_in_content_ = TextIterator::RangeLength( 105 end_offset_in_content_ = TextIterator::RangeLength(
106 backwards_iterator.EndPosition(), end_position, behavior); 106 backwards_iterator.EndPosition(), end_position, behavior);
107 content_range_ = Range::Create(*document, backwards_iterator.EndPosition(), 107 content_range_ = Range::Create(*document, backwards_iterator.EndPosition(),
108 forward_range.StartPosition()); 108 forward_iterator.StartPosition());
109 DCHECK(content_range_); 109 DCHECK(content_range_);
110 } 110 }
111 111
112 String SurroundingText::Content() const { 112 String SurroundingText::Content() const {
113 if (content_range_) { 113 if (content_range_) {
114 // SurroundingText is created with clean layout and must not be stored 114 // SurroundingText is created with clean layout and must not be stored
115 // through DOM or style changes, so layout must still be clean here. 115 // through DOM or style changes, so layout must still be clean here.
116 DCHECK(!content_range_->OwnerDocument().NeedsLayoutTreeUpdate()); 116 DCHECK(!content_range_->OwnerDocument().NeedsLayoutTreeUpdate());
117 return content_range_->GetText(); 117 return content_range_->GetText();
118 } 118 }
119 return String(); 119 return String();
120 } 120 }
121 121
122 unsigned SurroundingText::StartOffsetInContent() const { 122 unsigned SurroundingText::StartOffsetInContent() const {
123 return start_offset_in_content_; 123 return start_offset_in_content_;
124 } 124 }
125 125
126 unsigned SurroundingText::EndOffsetInContent() const { 126 unsigned SurroundingText::EndOffsetInContent() const {
127 return end_offset_in_content_; 127 return end_offset_in_content_;
128 } 128 }
129 129
130 } // namespace blink 130 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698