| 1 | /* |
| 2 | * Copyright (C) 2006, 2007, 2008, 2014 Apple Inc. All rights reserved. |
| 3 | * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
| 4 | * |
| 5 | * This library is free software; you can redistribute it and/or |
| 6 | * modify it under the terms of the GNU Library General Public |
| 7 | * License as published by the Free Software Foundation; either |
| 8 | * version 2 of the License, or (at your option) any later version. |
| 9 | * |
| 10 | * This library is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | * Library General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU Library General Public License |
| 16 | * along with this library; see the file COPYING.LIB. If not, write to |
| 17 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 18 | * Boston, MA 02110-1301, USA. |
| 19 | */ |
| 20 | |
| 21 | #pragma once |
| 22 | |
| 23 | #include "EditorClient.h" |
| 24 | #include "ExceptionOr.h" |
| 25 | #include "TextChecking.h" |
| 26 | |
| 27 | namespace WebCore { |
| 28 | |
| 29 | class Position; |
| 30 | class Range; |
| 31 | |
| 32 | struct TextCheckingResult; |
| 33 | |
| 34 | class TextCheckingParagraph { |
| 35 | public: |
| 36 | explicit TextCheckingParagraph(Ref<Range>&& checkingAndAutomaticReplacementRange); |
| 37 | explicit TextCheckingParagraph(Ref<Range>&& checkingRange, Ref<Range>&& automaticReplacementRange, RefPtr<Range>&& paragraphRange); |
| 38 | |
| 39 | int rangeLength() const; |
| 40 | Ref<Range> subrange(int characterOffset, int characterCount) const; |
| 41 | ExceptionOr<int> offsetTo(const Position&) const; |
| 42 | void expandRangeToNextEnd(); |
| 43 | |
| 44 | // FIXME: Consider changing this to return a StringView. |
| 45 | const String& text() const; |
| 46 | |
| 47 | // FIXME: Consider removing these and just having the caller use text() directly. |
| 48 | int textLength() const { return text().length(); } |
| 49 | String textSubstring(unsigned pos, unsigned len = UINT_MAX) const { return text().substring(pos, len); } |
| 50 | UChar textCharAt(int index) const { return text()[static_cast<unsigned>(index)]; } |
| 51 | |
| 52 | bool isEmpty() const; |
| 53 | |
| 54 | int checkingStart() const; |
| 55 | int checkingEnd() const; |
| 56 | int checkingLength() const; |
| 57 | String checkingSubstring() const { return textSubstring(checkingStart(), checkingLength()); } |
| 58 | |
| 59 | // Determines the range in which we allow automatic text replacement. If an automatic replacement range is not passed to the |
| 60 | // text checking paragraph, this defaults to the spell checking range. |
| 61 | int automaticReplacementStart() const; |
| 62 | int automaticReplacementLength() const; |
| 63 | |
| 64 | bool checkingRangeMatches(int location, int length) const { return location == checkingStart() && length == checkingLength(); } |
| 65 | bool isCheckingRangeCoveredBy(int location, int length) const { return location <= checkingStart() && location + length >= checkingStart() + checkingLength(); } |
| 66 | bool checkingRangeCovers(int location, int length) const { return location < checkingEnd() && location + length > checkingStart(); } |
| 67 | Range& paragraphRange() const; |
| 68 | |
| 69 | private: |
| 70 | void invalidateParagraphRangeValues(); |
| 71 | Range& offsetAsRange() const; |
| 72 | |
| 73 | Ref<Range> m_checkingRange; |
| 74 | Ref<Range> m_automaticReplacementRange; |
| 75 | mutable RefPtr<Range> m_paragraphRange; |
| 76 | mutable RefPtr<Range> m_offsetAsRange; |
| 77 | mutable String m_text; |
| 78 | mutable Optional<int> m_checkingStart; |
| 79 | mutable Optional<int> m_checkingEnd; |
| 80 | mutable Optional<int> m_checkingLength; |
| 81 | mutable Optional<int> m_automaticReplacementStart; |
| 82 | mutable Optional<int> m_automaticReplacementLength; |
| 83 | }; |
| 84 | |
| 85 | class TextCheckingHelper { |
| 86 | WTF_MAKE_NONCOPYABLE(TextCheckingHelper); |
| 87 | public: |
| 88 | TextCheckingHelper(EditorClient&, Range&); |
| 89 | ~TextCheckingHelper(); |
| 90 | |
| 91 | String findFirstMisspelling(int& firstMisspellingOffset, bool markAll, RefPtr<Range>& firstMisspellingRange); |
| 92 | String findFirstMisspellingOrBadGrammar(bool checkGrammar, bool& outIsSpelling, int& outFirstFoundOffset, GrammarDetail& outGrammarDetail); |
| 93 | void markAllMisspellings(RefPtr<Range>& firstMisspellingRange); |
| 94 | #if USE(GRAMMAR_CHECKING) |
| 95 | String findFirstBadGrammar(GrammarDetail& outGrammarDetail, int& outGrammarPhraseOffset, bool markAll) const; |
| 96 | void markAllBadGrammar(); |
| 97 | bool isUngrammatical() const; |
| 98 | #endif |
| 99 | Vector<String> guessesForMisspelledOrUngrammaticalRange(bool checkGrammar, bool& misspelled, bool& ungrammatical) const; |
| 100 | |
| 101 | private: |
| 102 | EditorClient& m_client; |
| 103 | Ref<Range> m_range; |
| 104 | |
| 105 | bool unifiedTextCheckerEnabled() const; |
| 106 | #if USE(GRAMMAR_CHECKING) |
| 107 | int findFirstGrammarDetail(const Vector<GrammarDetail>&, int badGrammarPhraseLocation, int startOffset, int endOffset, bool markAll) const; |
| 108 | #endif |
| 109 | }; |
| 110 | |
| 111 | void checkTextOfParagraph(TextCheckerClient&, StringView, OptionSet<TextCheckingType>, Vector<TextCheckingResult>&, const VisibleSelection& currentSelection); |
| 112 | |
| 113 | bool unifiedTextCheckerEnabled(const Frame*); |
| 114 | bool platformDrivenTextCheckerEnabled(); |
| 115 | |
| 116 | } // namespace WebCore |
| 117 | |