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

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

Issue 2931443003: Add support for Android spellcheck menu in Chrome/WebViews (Closed)
Patch Set: 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. 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 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 25 matching lines...) Expand all
36 #include "core/dom/Range.h" 36 #include "core/dom/Range.h"
37 #include "core/editing/EditingUtilities.h" 37 #include "core/editing/EditingUtilities.h"
38 #include "core/editing/Editor.h" 38 #include "core/editing/Editor.h"
39 #include "core/editing/EphemeralRange.h" 39 #include "core/editing/EphemeralRange.h"
40 #include "core/editing/VisibleUnits.h" 40 #include "core/editing/VisibleUnits.h"
41 #include "core/editing/commands/CompositeEditCommand.h" 41 #include "core/editing/commands/CompositeEditCommand.h"
42 #include "core/editing/commands/ReplaceSelectionCommand.h" 42 #include "core/editing/commands/ReplaceSelectionCommand.h"
43 #include "core/editing/commands/TypingCommand.h" 43 #include "core/editing/commands/TypingCommand.h"
44 #include "core/editing/iterators/CharacterIterator.h" 44 #include "core/editing/iterators/CharacterIterator.h"
45 #include "core/editing/markers/DocumentMarkerController.h" 45 #include "core/editing/markers/DocumentMarkerController.h"
46 #include "core/editing/markers/SpellCheckMarker.h"
46 #include "core/editing/spellcheck/IdleSpellCheckCallback.h" 47 #include "core/editing/spellcheck/IdleSpellCheckCallback.h"
47 #include "core/editing/spellcheck/SpellCheckRequester.h" 48 #include "core/editing/spellcheck/SpellCheckRequester.h"
48 #include "core/editing/spellcheck/SpellCheckerClient.h" 49 #include "core/editing/spellcheck/SpellCheckerClient.h"
49 #include "core/editing/spellcheck/TextCheckingParagraph.h" 50 #include "core/editing/spellcheck/TextCheckingParagraph.h"
50 #include "core/frame/LocalFrame.h" 51 #include "core/frame/LocalFrame.h"
51 #include "core/frame/Settings.h" 52 #include "core/frame/Settings.h"
52 #include "core/html/HTMLInputElement.h" 53 #include "core/html/HTMLInputElement.h"
53 #include "core/layout/LayoutTextControl.h" 54 #include "core/layout/LayoutTextControl.h"
54 #include "core/loader/EmptyClients.h" 55 #include "core/loader/EmptyClients.h"
55 #include "core/page/Page.h" 56 #include "core/page/Page.h"
(...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 DocumentMarker::MarkerTypes marker_types(DocumentMarker::kSpelling); 805 DocumentMarker::MarkerTypes marker_types(DocumentMarker::kSpelling);
805 marker_types.Add(DocumentMarker::kGrammar); 806 marker_types.Add(DocumentMarker::kGrammar);
806 for (Node& node : NodeTraversal::InclusiveDescendantsOf(element)) { 807 for (Node& node : NodeTraversal::InclusiveDescendantsOf(element)) {
807 if (elements_type == ElementsType::kAll || !HasEditableStyle(node)) { 808 if (elements_type == ElementsType::kAll || !HasEditableStyle(node)) {
808 GetFrame().GetDocument()->Markers().RemoveMarkersForNode(&node, 809 GetFrame().GetDocument()->Markers().RemoveMarkersForNode(&node,
809 marker_types); 810 marker_types);
810 } 811 }
811 } 812 }
812 } 813 }
813 814
815 Optional<std::pair<Node*, SpellCheckMarker*>>
816 SpellChecker::GetSpellCheckMarkerTouchingSelection() {
817 const VisibleSelection& selection =
818 GetFrame().Selection().ComputeVisibleSelectionInDOMTree();
819 if (selection.IsNone())
820 return Optional<std::pair<Node*, SpellCheckMarker*>>();
821
822 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
823 // If some text is actually selected, we can use the selection range as-is to
824 // check for a marker. If no text is selected (we just have a caret
825 // somewhere), we need to expand one character on either side so we can find
826 // a spelling marker immediately before or after the caret.
827
828 // (The spelling markers on these words may be anchored to a different node
829 // than the collapsed selection's Position is, but once we expand the
830 // selection, if we're next to a marker, either the start or end point should
831 // now be anchored relative to the same text node as that marker.)
832 if (range_to_check.IsCollapsed()) {
833 const VisiblePosition& caret_pos = selection.VisibleStart();
834
835 Position range_to_check_start =
836 PreviousPositionOf(caret_pos).DeepEquivalent();
837 if (range_to_check_start.IsNull())
838 range_to_check_start = caret_pos.DeepEquivalent();
839
840 Position range_to_check_end = NextPositionOf(caret_pos).DeepEquivalent();
841 if (range_to_check_end.IsNull())
842 range_to_check_end = caret_pos.DeepEquivalent();
843
844 range_to_check = EphemeralRange(range_to_check_start, range_to_check_end);
845 }
846
847 Node* start_container = range_to_check.StartPosition().ComputeContainerNode();
yosin_UTC9 2017/06/07 01:34:16 nit: s/Node*/Node* const/
848 const unsigned start_offset =
849 range_to_check.StartPosition().ComputeOffsetInContainerNode();
850 Node* end_container = range_to_check.EndPosition().ComputeContainerNode();
yosin_UTC9 2017/06/07 01:34:15 nit: s/Node*/Node* const/
851 const unsigned end_offset =
852 range_to_check.EndPosition().ComputeOffsetInContainerNode();
853
854 for (Node& node : range_to_check.Nodes()) {
855 const DocumentMarkerVector& markers_in_node =
856 GetFrame().GetDocument()->Markers().MarkersFor(
857 &node, DocumentMarker::MisspellingMarkers());
858 for (DocumentMarker* marker : markers_in_node) {
859 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
860 continue;
861 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
862 continue;
863
864 return std::make_pair(&node, &ToSpellCheckMarker(*marker));
865 }
866 }
867
868 // No marker found
869 return Optional<std::pair<Node*, SpellCheckMarker*>>();
870 }
871
814 void SpellChecker::ReplaceMisspelledRange(const String& text) { 872 void SpellChecker::ReplaceMisspelledRange(const String& text) {
815 EphemeralRange caret_range = GetFrame() 873 Optional<std::pair<Node*, SpellCheckMarker*>> node_and_marker =
yosin_UTC9 2017/06/07 01:34:15 nit: s/Optional<std::pair<Node*, SpellCheckMarker*
816 .Selection() 874 GetSpellCheckMarkerTouchingSelection();
817 .ComputeVisibleSelectionInDOMTree() 875 if (!node_and_marker)
818 .ToNormalizedEphemeralRange();
819 if (caret_range.IsNull())
820 return; 876 return;
821 877
822 Node* const caret_start_container = 878 Node* container_node = node_and_marker.value().first;
yosin_UTC9 2017/06/07 01:34:15 nit: s/Node*/Node* const/
823 caret_range.StartPosition().ComputeContainerNode(); 879 SpellCheckMarker* marker = node_and_marker.value().second;
yosin_UTC9 2017/06/07 01:34:15 nit: s/SpellCheckMakrer*/SpellCheckMakrer* const/
824 Node* const caret_end_container =
825 caret_range.EndPosition().ComputeContainerNode();
826 880
827 // We don't currently support the case where a misspelling spans multiple 881 EphemeralRange misspelled_range(
yosin_UTC9 2017/06/07 01:34:15 nit: s/EphemeralRange/const EphemeralRange/
828 // nodes 882 Position(container_node, marker->StartOffset()),
829 if (caret_start_container != caret_end_container) 883 Position(container_node, marker->EndOffset()));
830 return;
831
832 const unsigned caret_start_offset =
833 caret_range.StartPosition().ComputeOffsetInContainerNode();
834 const unsigned caret_end_offset =
835 caret_range.EndPosition().ComputeOffsetInContainerNode();
836
837 const DocumentMarkerVector& markers_in_node =
838 GetFrame().GetDocument()->Markers().MarkersFor(
839 caret_start_container, DocumentMarker::MisspellingMarkers());
840
841 const auto marker_it =
842 std::find_if(markers_in_node.begin(), markers_in_node.end(),
843 [=](const DocumentMarker* marker) {
844 return marker->StartOffset() < caret_end_offset &&
845 marker->EndOffset() > caret_start_offset;
846 });
847 if (marker_it == markers_in_node.end())
848 return;
849
850 const DocumentMarker* found_marker = *marker_it;
851 EphemeralRange marker_range = EphemeralRange(
852 Position(caret_start_container, found_marker->StartOffset()),
853 Position(caret_start_container, found_marker->EndOffset()));
854 if (marker_range.IsNull())
855 return;
856 884
857 GetFrame().Selection().SetSelection( 885 GetFrame().Selection().SetSelection(
858 SelectionInDOMTree::Builder().SetBaseAndExtent(marker_range).Build()); 886 SelectionInDOMTree::Builder().SetBaseAndExtent(misspelled_range).Build());
859 887
860 Document& current_document = *GetFrame().GetDocument(); 888 Document& current_document = *GetFrame().GetDocument();
861 889
862 // Dispatch 'beforeinput'. 890 // Dispatch 'beforeinput'.
863 Element* const target = GetFrame().GetEditor().FindEventTargetFromSelection(); 891 Element* const target = GetFrame().GetEditor().FindEventTargetFromSelection();
864 DataTransfer* const data_transfer = DataTransfer::Create( 892 DataTransfer* const data_transfer = DataTransfer::Create(
865 DataTransfer::DataTransferType::kInsertReplacementText, 893 DataTransfer::DataTransferType::kInsertReplacementText,
866 DataTransferAccessPolicy::kDataTransferReadable, 894 DataTransferAccessPolicy::kDataTransferReadable,
867 DataObject::CreateFromString(text)); 895 DataObject::CreateFromString(text));
868 896
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 if (!input.IsFocusedElementInDocument()) 1267 if (!input.IsFocusedElementInDocument())
1240 return false; 1268 return false;
1241 } 1269 }
1242 } 1270 }
1243 HTMLElement* element = 1271 HTMLElement* element =
1244 Traversal<HTMLElement>::FirstAncestorOrSelf(*position.AnchorNode()); 1272 Traversal<HTMLElement>::FirstAncestorOrSelf(*position.AnchorNode());
1245 return element && element->IsSpellCheckingEnabled(); 1273 return element && element->IsSpellCheckingEnabled();
1246 } 1274 }
1247 1275
1248 } // namespace blink 1276 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698