Index: third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp |
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp |
index ba21d975ac05a24dba58647b0799d65f5bd65221..37423339387a8ee510c810aa4666dcaacbea140b 100644 |
--- a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp |
+++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp |
@@ -43,6 +43,7 @@ |
#include "core/editing/commands/TypingCommand.h" |
#include "core/editing/iterators/CharacterIterator.h" |
#include "core/editing/markers/DocumentMarkerController.h" |
+#include "core/editing/markers/SpellCheckMarker.h" |
#include "core/editing/spellcheck/IdleSpellCheckCallback.h" |
#include "core/editing/spellcheck/SpellCheckRequester.h" |
#include "core/editing/spellcheck/SpellCheckerClient.h" |
@@ -811,51 +812,78 @@ void SpellChecker::RemoveSpellingAndGrammarMarkers(const HTMLElement& element, |
} |
} |
-void SpellChecker::ReplaceMisspelledRange(const String& text) { |
- EphemeralRange caret_range = GetFrame() |
- .Selection() |
- .ComputeVisibleSelectionInDOMTree() |
- .ToNormalizedEphemeralRange(); |
- if (caret_range.IsNull()) |
- return; |
+Optional<std::pair<Node*, SpellCheckMarker*>> |
+SpellChecker::GetSpellCheckMarkerTouchingSelection() { |
+ const VisibleSelection& selection = |
+ GetFrame().Selection().ComputeVisibleSelectionInDOMTree(); |
+ if (selection.IsNone()) |
+ return Optional<std::pair<Node*, SpellCheckMarker*>>(); |
+ |
+ EphemeralRange range_to_check(selection.Start(), selection.End()); |
yosin_UTC9
2017/06/07 01:34:15
Could you move calculation of |range_to_check| in
|
+ // If some text is actually selected, we can use the selection range as-is to |
+ // check for a marker. If no text is selected (we just have a caret |
+ // somewhere), we need to expand one character on either side so we can find |
+ // a spelling marker immediately before or after the caret. |
+ |
+ // (The spelling markers on these words may be anchored to a different node |
+ // than the collapsed selection's Position is, but once we expand the |
+ // selection, if we're next to a marker, either the start or end point should |
+ // now be anchored relative to the same text node as that marker.) |
+ if (range_to_check.IsCollapsed()) { |
+ const VisiblePosition& caret_pos = selection.VisibleStart(); |
+ |
+ Position range_to_check_start = |
+ PreviousPositionOf(caret_pos).DeepEquivalent(); |
+ if (range_to_check_start.IsNull()) |
+ range_to_check_start = caret_pos.DeepEquivalent(); |
+ |
+ Position range_to_check_end = NextPositionOf(caret_pos).DeepEquivalent(); |
+ if (range_to_check_end.IsNull()) |
+ range_to_check_end = caret_pos.DeepEquivalent(); |
+ |
+ range_to_check = EphemeralRange(range_to_check_start, range_to_check_end); |
+ } |
- Node* const caret_start_container = |
- caret_range.StartPosition().ComputeContainerNode(); |
- Node* const caret_end_container = |
- caret_range.EndPosition().ComputeContainerNode(); |
+ Node* start_container = range_to_check.StartPosition().ComputeContainerNode(); |
yosin_UTC9
2017/06/07 01:34:16
nit: s/Node*/Node* const/
|
+ const unsigned start_offset = |
+ range_to_check.StartPosition().ComputeOffsetInContainerNode(); |
+ Node* end_container = range_to_check.EndPosition().ComputeContainerNode(); |
yosin_UTC9
2017/06/07 01:34:15
nit: s/Node*/Node* const/
|
+ const unsigned end_offset = |
+ range_to_check.EndPosition().ComputeOffsetInContainerNode(); |
+ |
+ for (Node& node : range_to_check.Nodes()) { |
+ const DocumentMarkerVector& markers_in_node = |
+ GetFrame().GetDocument()->Markers().MarkersFor( |
+ &node, DocumentMarker::MisspellingMarkers()); |
+ for (DocumentMarker* marker : markers_in_node) { |
+ if (&node == start_container && marker->EndOffset() <= start_offset) |
yosin_UTC9
2017/06/07 01:34:15
nit: s/&node/node/
There is |bool operator==(const
|
+ continue; |
+ if (&node == end_container && marker->StartOffset() >= end_offset) |
yosin_UTC9
2017/06/07 01:34:16
nit: s/&node/node/
There is |bool operator==(const
|
+ continue; |
- // We don't currently support the case where a misspelling spans multiple |
- // nodes |
- if (caret_start_container != caret_end_container) |
- return; |
+ return std::make_pair(&node, &ToSpellCheckMarker(*marker)); |
+ } |
+ } |
- const unsigned caret_start_offset = |
- caret_range.StartPosition().ComputeOffsetInContainerNode(); |
- const unsigned caret_end_offset = |
- caret_range.EndPosition().ComputeOffsetInContainerNode(); |
- |
- const DocumentMarkerVector& markers_in_node = |
- GetFrame().GetDocument()->Markers().MarkersFor( |
- caret_start_container, DocumentMarker::MisspellingMarkers()); |
- |
- const auto marker_it = |
- std::find_if(markers_in_node.begin(), markers_in_node.end(), |
- [=](const DocumentMarker* marker) { |
- return marker->StartOffset() < caret_end_offset && |
- marker->EndOffset() > caret_start_offset; |
- }); |
- if (marker_it == markers_in_node.end()) |
- return; |
+ // No marker found |
+ return Optional<std::pair<Node*, SpellCheckMarker*>>(); |
+} |
- const DocumentMarker* found_marker = *marker_it; |
- EphemeralRange marker_range = EphemeralRange( |
- Position(caret_start_container, found_marker->StartOffset()), |
- Position(caret_start_container, found_marker->EndOffset())); |
- if (marker_range.IsNull()) |
+void SpellChecker::ReplaceMisspelledRange(const String& text) { |
+ Optional<std::pair<Node*, SpellCheckMarker*>> node_and_marker = |
yosin_UTC9
2017/06/07 01:34:15
nit: s/Optional<std::pair<Node*, SpellCheckMarker*
|
+ GetSpellCheckMarkerTouchingSelection(); |
+ if (!node_and_marker) |
return; |
+ Node* container_node = node_and_marker.value().first; |
yosin_UTC9
2017/06/07 01:34:15
nit: s/Node*/Node* const/
|
+ SpellCheckMarker* marker = node_and_marker.value().second; |
yosin_UTC9
2017/06/07 01:34:15
nit: s/SpellCheckMakrer*/SpellCheckMakrer* const/
|
+ |
+ EphemeralRange misspelled_range( |
yosin_UTC9
2017/06/07 01:34:15
nit: s/EphemeralRange/const EphemeralRange/
|
+ Position(container_node, marker->StartOffset()), |
+ Position(container_node, marker->EndOffset())); |
+ |
GetFrame().Selection().SetSelection( |
- SelectionInDOMTree::Builder().SetBaseAndExtent(marker_range).Build()); |
+ SelectionInDOMTree::Builder().SetBaseAndExtent(misspelled_range).Build()); |
Document& current_document = *GetFrame().GetDocument(); |