OLD | NEW |
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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 // TODO(yosin): We should fix |startOfWord()| and |endOfWord()| not to return | 88 // TODO(yosin): We should fix |startOfWord()| and |endOfWord()| not to return |
89 // null position. | 89 // null position. |
90 const VisiblePosition& start = StartOfWord(position, kLeftWordIfOnBoundary); | 90 const VisiblePosition& start = StartOfWord(position, kLeftWordIfOnBoundary); |
91 const VisiblePosition& end = EndOfWord(position, kRightWordIfOnBoundary); | 91 const VisiblePosition& end = EndOfWord(position, kRightWordIfOnBoundary); |
92 return SelectionInDOMTree::Builder() | 92 return SelectionInDOMTree::Builder() |
93 .SetBaseAndExtentDeprecated(start.DeepEquivalent(), end.DeepEquivalent()) | 93 .SetBaseAndExtentDeprecated(start.DeepEquivalent(), end.DeepEquivalent()) |
94 .SetAffinity(start.Affinity()) | 94 .SetAffinity(start.Affinity()) |
95 .Build(); | 95 .Build(); |
96 } | 96 } |
97 | 97 |
| 98 static bool IsWhiteSpaceOrPunctuation(UChar c) { |
| 99 return IsSpaceOrNewline(c) || WTF::Unicode::IsPunct(c); |
| 100 } |
| 101 |
98 } // namespace | 102 } // namespace |
99 | 103 |
100 SpellChecker* SpellChecker::Create(LocalFrame& frame) { | 104 SpellChecker* SpellChecker::Create(LocalFrame& frame) { |
101 return new SpellChecker(frame); | 105 return new SpellChecker(frame); |
102 } | 106 } |
103 | 107 |
104 static SpellCheckerClient& GetEmptySpellCheckerClient() { | 108 static SpellCheckerClient& GetEmptySpellCheckerClient() { |
105 DEFINE_STATIC_LOCAL(EmptySpellCheckerClient, client, ()); | 109 DEFINE_STATIC_LOCAL(EmptySpellCheckerClient, client, ()); |
106 return client; | 110 return client; |
107 } | 111 } |
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
860 DocumentMarker* const marker = | 864 DocumentMarker* const marker = |
861 GetFrame().GetDocument()->Markers().FirstMarkerIntersectingOffsetRange( | 865 GetFrame().GetDocument()->Markers().FirstMarkerIntersectingOffsetRange( |
862 ToText(*selection_start_container), selection_start_offset, | 866 ToText(*selection_start_container), selection_start_offset, |
863 selection_end_offset, DocumentMarker::MisspellingMarkers()); | 867 selection_end_offset, DocumentMarker::MisspellingMarkers()); |
864 if (!marker) | 868 if (!marker) |
865 return Optional<std::pair<Node*, SpellCheckMarker*>>(); | 869 return Optional<std::pair<Node*, SpellCheckMarker*>>(); |
866 | 870 |
867 return std::make_pair(selection_start_container, ToSpellCheckMarker(marker)); | 871 return std::make_pair(selection_start_container, ToSpellCheckMarker(marker)); |
868 } | 872 } |
869 | 873 |
| 874 String SpellChecker::SelectMisspellingAsync(String& description) { |
| 875 VisibleSelection selection = |
| 876 GetFrame().Selection().ComputeVisibleSelectionInDOMTree(); |
| 877 if (selection.IsNone()) |
| 878 return String(); |
| 879 |
| 880 // Caret and range selections always return valid normalized ranges. |
| 881 const EphemeralRange& selection_range = |
| 882 selection.ToNormalizedEphemeralRange(); |
| 883 |
| 884 Node* const selection_start_container = |
| 885 selection_range.StartPosition().ComputeContainerNode(); |
| 886 Node* const selection_end_container = |
| 887 selection_range.EndPosition().ComputeContainerNode(); |
| 888 |
| 889 // We don't currently support the case where a misspelling spans multiple |
| 890 // nodes. See crbug.com/720065 |
| 891 if (selection_start_container != selection_end_container) |
| 892 return String(); |
| 893 |
| 894 const unsigned selection_start_offset = |
| 895 selection_range.StartPosition().ComputeOffsetInContainerNode(); |
| 896 const unsigned selection_end_offset = |
| 897 selection_range.EndPosition().ComputeOffsetInContainerNode(); |
| 898 |
| 899 const DocumentMarkerVector& markers_in_node = |
| 900 GetFrame().GetDocument()->Markers().MarkersFor( |
| 901 selection_start_container, DocumentMarker::MisspellingMarkers()); |
| 902 |
| 903 const auto marker_it = |
| 904 std::find_if(markers_in_node.begin(), markers_in_node.end(), |
| 905 [=](const DocumentMarker* marker) { |
| 906 return marker->StartOffset() < selection_end_offset && |
| 907 marker->EndOffset() > selection_start_offset; |
| 908 }); |
| 909 if (marker_it == markers_in_node.end()) |
| 910 return String(); |
| 911 |
| 912 const SpellCheckMarker* const found_marker = ToSpellCheckMarker(*marker_it); |
| 913 description = found_marker->Description(); |
| 914 |
| 915 Range* const marker_range = |
| 916 Range::Create(*GetFrame().GetDocument(), selection_start_container, |
| 917 found_marker->StartOffset(), selection_start_container, |
| 918 found_marker->EndOffset()); |
| 919 |
| 920 if (marker_range->GetText().StripWhiteSpace(&IsWhiteSpaceOrPunctuation) != |
| 921 CreateRange(selection_range) |
| 922 ->GetText() |
| 923 .StripWhiteSpace(&IsWhiteSpaceOrPunctuation)) |
| 924 return String(); |
| 925 |
| 926 return marker_range->GetText(); |
| 927 } |
| 928 |
870 void SpellChecker::ReplaceMisspelledRange(const String& text) { | 929 void SpellChecker::ReplaceMisspelledRange(const String& text) { |
871 const Optional<std::pair<Node*, SpellCheckMarker*>>& node_and_marker = | 930 const Optional<std::pair<Node*, SpellCheckMarker*>>& node_and_marker = |
872 GetSpellCheckMarkerUnderSelection(); | 931 GetSpellCheckMarkerUnderSelection(); |
873 if (!node_and_marker) | 932 if (!node_and_marker) |
874 return; | 933 return; |
875 | 934 |
876 Node* const container_node = node_and_marker.value().first; | 935 Node* const container_node = node_and_marker.value().first; |
877 const SpellCheckMarker* const marker = node_and_marker.value().second; | 936 const SpellCheckMarker* const marker = node_and_marker.value().second; |
878 | 937 |
879 GetFrame().Selection().SetSelection( | 938 GetFrame().Selection().SetSelection( |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 if (!input.IsFocusedElementInDocument()) | 1323 if (!input.IsFocusedElementInDocument()) |
1265 return false; | 1324 return false; |
1266 } | 1325 } |
1267 } | 1326 } |
1268 HTMLElement* element = | 1327 HTMLElement* element = |
1269 Traversal<HTMLElement>::FirstAncestorOrSelf(*position.AnchorNode()); | 1328 Traversal<HTMLElement>::FirstAncestorOrSelf(*position.AnchorNode()); |
1270 return element && element->IsSpellCheckingEnabled(); | 1329 return element && element->IsSpellCheckingEnabled(); |
1271 } | 1330 } |
1272 | 1331 |
1273 } // namespace blink | 1332 } // namespace blink |
OLD | NEW |