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

Unified Diff: third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp

Issue 2931443003: Add support for Android spellcheck menu in Chrome/WebViews (Closed)
Patch Set: Respond to yosin@'s comments Created 3 years, 6 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
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 902073e0dd73acc496431ce33711eb029351e7f4..46e0c7f130cd5f3384113508bfe8e8e856c2aa6d 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,93 @@ void SpellChecker::RemoveSpellingAndGrammarMarkers(const HTMLElement& element,
}
}
yosin_UTC9 2017/06/08 01:50:09 Could you move spell checker changes into another
-void SpellChecker::ReplaceMisspelledRange(const String& text) {
- EphemeralRange caret_range = GetFrame()
- .Selection()
- .ComputeVisibleSelectionInDOMTree()
- .ToNormalizedEphemeralRange();
- if (caret_range.IsNull())
- return;
+namespace {
- Node* const caret_start_container =
- caret_range.StartPosition().ComputeContainerNode();
- Node* const caret_end_container =
- caret_range.EndPosition().ComputeContainerNode();
+EphemeralRange ExpandSelectionRangeIfNecessary(
+ const VisibleSelection& selection) {
+ DCHECK(!selection.IsNone());
- // We don't currently support the case where a misspelling spans multiple
- // nodes
- if (caret_start_container != caret_end_container)
- return;
+ // 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.
- 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;
+ // (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.)
+
+ // Some text is actually selected
+ if (selection.IsRange())
+ return EphemeralRange(selection.Start(), selection.End());
+
+ // No text is actually selected, need to expand the selection range
+ 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();
+
+ return EphemeralRange(range_to_check_start, range_to_check_end);
+}
+
+} // namespace
- 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())
+Optional<std::pair<Node*, SpellCheckMarker*>>
+SpellChecker::GetSpellCheckMarkerTouchingSelection() {
+ const VisibleSelection& selection =
+ GetFrame().Selection().ComputeVisibleSelectionInDOMTree();
+ if (selection.IsNone())
+ return Optional<std::pair<Node*, SpellCheckMarker*>>();
+
+ const EphemeralRange& range_to_check =
+ ExpandSelectionRangeIfNecessary(selection);
+
+ Node* start_container = range_to_check.StartPosition().ComputeContainerNode();
+ const unsigned start_offset =
+ range_to_check.StartPosition().ComputeOffsetInContainerNode();
+ Node* end_container = range_to_check.EndPosition().ComputeContainerNode();
+ 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)
+ continue;
+ if (node == end_container && marker->StartOffset() >= end_offset)
+ continue;
+
+ return std::make_pair(&node, &ToSpellCheckMarker(*marker));
+ }
+ }
+
+ // No marker found
+ return Optional<std::pair<Node*, SpellCheckMarker*>>();
+}
+
+void SpellChecker::ReplaceMisspelledRange(const String& text) {
+ const Optional<std::pair<Node*, SpellCheckMarker*>>& node_and_marker =
+ GetSpellCheckMarkerTouchingSelection();
+ if (!node_and_marker)
return;
+ Node* const container_node = node_and_marker.value().first;
+ const SpellCheckMarker* const marker = node_and_marker.value().second;
+
+ const EphemeralRange misspelled_range(
+ 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();

Powered by Google App Engine
This is Rietveld 408576698