| 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 29 matching lines...) Expand all Loading... |
| 40 #include "core/editing/markers/DocumentMarkerController.h" | 40 #include "core/editing/markers/DocumentMarkerController.h" |
| 41 #include "core/editing/spellcheck/SpellCheckRequester.h" | 41 #include "core/editing/spellcheck/SpellCheckRequester.h" |
| 42 #include "core/editing/spellcheck/TextCheckingHelper.h" | 42 #include "core/editing/spellcheck/TextCheckingHelper.h" |
| 43 #include "core/frame/LocalFrame.h" | 43 #include "core/frame/LocalFrame.h" |
| 44 #include "core/frame/Settings.h" | 44 #include "core/frame/Settings.h" |
| 45 #include "core/html/HTMLInputElement.h" | 45 #include "core/html/HTMLInputElement.h" |
| 46 #include "core/layout/LayoutTextControl.h" | 46 #include "core/layout/LayoutTextControl.h" |
| 47 #include "core/loader/EmptyClients.h" | 47 #include "core/loader/EmptyClients.h" |
| 48 #include "core/page/Page.h" | 48 #include "core/page/Page.h" |
| 49 #include "core/page/SpellCheckerClient.h" | 49 #include "core/page/SpellCheckerClient.h" |
| 50 #include "platform/text/TextBreakIterator.h" |
| 50 #include "platform/text/TextCheckerClient.h" | 51 #include "platform/text/TextCheckerClient.h" |
| 51 | 52 |
| 52 namespace blink { | 53 namespace blink { |
| 53 | 54 |
| 54 using namespace HTMLNames; | 55 using namespace HTMLNames; |
| 55 | 56 |
| 56 namespace { | 57 namespace { |
| 57 | 58 |
| 58 bool isSelectionInTextField(const VisibleSelection& selection) | 59 bool isSelectionInTextField(const VisibleSelection& selection) |
| 59 { | 60 { |
| (...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 { | 780 { |
| 780 visitor->trace(m_frame); | 781 visitor->trace(m_frame); |
| 781 visitor->trace(m_spellCheckRequester); | 782 visitor->trace(m_spellCheckRequester); |
| 782 } | 783 } |
| 783 | 784 |
| 784 void SpellChecker::prepareForLeakDetection() | 785 void SpellChecker::prepareForLeakDetection() |
| 785 { | 786 { |
| 786 m_spellCheckRequester->prepareForLeakDetection(); | 787 m_spellCheckRequester->prepareForLeakDetection(); |
| 787 } | 788 } |
| 788 | 789 |
| 790 void SpellChecker::findMisspellings(const String& text, Vector<TextCheckingResul
t>& results) |
| 791 { |
| 792 Vector<UChar> characters; |
| 793 text.appendTo(characters); |
| 794 unsigned length = text.length(); |
| 795 |
| 796 TextBreakIterator* iterator = wordBreakIterator(characters.data(), length); |
| 797 if (!iterator) |
| 798 return; |
| 799 |
| 800 int wordStart = iterator->current(); |
| 801 while (0 <= wordStart) { |
| 802 int wordEnd = iterator->next(); |
| 803 if (wordEnd < 0) |
| 804 break; |
| 805 int wordLength = wordEnd - wordStart; |
| 806 int misspellingLocation = -1; |
| 807 int misspellingLength = 0; |
| 808 textChecker().checkSpellingOfString(String(characters.data() + wordStart
, wordLength), &misspellingLocation, &misspellingLength); |
| 809 if (0 < misspellingLength) { |
| 810 DCHECK_LE(0, misspellingLocation); |
| 811 DCHECK_LE(misspellingLocation, wordLength); |
| 812 DCHECK_LT(0, misspellingLength); |
| 813 DCHECK_LE(misspellingLocation + misspellingLength, wordLength); |
| 814 TextCheckingResult misspelling; |
| 815 misspelling.decoration = TextDecorationTypeSpelling; |
| 816 misspelling.location = wordStart + misspellingLocation; |
| 817 misspelling.length = misspellingLength; |
| 818 results.append(misspelling); |
| 819 } |
| 820 |
| 821 wordStart = wordEnd; |
| 822 } |
| 823 } |
| 824 |
| 825 String SpellChecker::findFirstMisspellingOrBadGrammar(const Position& start, con
st Position& end, int& outFirstFoundOffset) |
| 826 { |
| 827 String firstFoundItem; |
| 828 String misspelledWord; |
| 829 |
| 830 // Initialize out parameter; it will be updated if we find something to retu
rn. |
| 831 outFirstFoundOffset = 0; |
| 832 |
| 833 // Expand the search range to encompass entire paragraphs, since text checki
ng needs that much context. |
| 834 // Determine the character offset from the start of the paragraph to the sta
rt of the original search range, |
| 835 // since we will want to ignore results in this area. |
| 836 Position paragraphStart = startOfParagraph(createVisiblePosition(start)).toP
arentAnchoredPosition(); |
| 837 Position paragraphEnd = end; |
| 838 int totalRangeLength = TextIterator::rangeLength(paragraphStart, paragraphEn
d); |
| 839 paragraphEnd = endOfParagraph(createVisiblePosition(start)).toParentAnchored
Position(); |
| 840 |
| 841 int rangeStartOffset = TextIterator::rangeLength(paragraphStart, start); |
| 842 int totalLengthProcessed = 0; |
| 843 |
| 844 bool firstIteration = true; |
| 845 bool lastIteration = false; |
| 846 while (totalLengthProcessed < totalRangeLength) { |
| 847 // Iterate through the search range by paragraphs, checking each one for
spelling. |
| 848 int currentLength = TextIterator::rangeLength(paragraphStart, paragraphE
nd); |
| 849 int currentStartOffset = firstIteration ? rangeStartOffset : 0; |
| 850 int currentEndOffset = currentLength; |
| 851 if (inSameParagraph(createVisiblePosition(paragraphStart), createVisible
Position(end))) { |
| 852 // Determine the character offset from the end of the original searc
h range to the end of the paragraph, |
| 853 // since we will want to ignore results in this area. |
| 854 currentEndOffset = TextIterator::rangeLength(paragraphStart, end); |
| 855 lastIteration = true; |
| 856 } |
| 857 if (currentStartOffset < currentEndOffset) { |
| 858 String paragraphString = plainText(EphemeralRange(paragraphStart, pa
ragraphEnd)); |
| 859 if (paragraphString.length() > 0) { |
| 860 int spellingLocation = 0; |
| 861 |
| 862 Vector<TextCheckingResult> results; |
| 863 findMisspellings(paragraphString, results); |
| 864 |
| 865 for (unsigned i = 0; i < results.size(); i++) { |
| 866 const TextCheckingResult* result = &results[i]; |
| 867 if (result->decoration == TextDecorationTypeSpelling && resu
lt->location >= currentStartOffset && result->location + result->length <= curre
ntEndOffset) { |
| 868 DCHECK_GT(result->length, 0); |
| 869 DCHECK_GE(result->location, 0); |
| 870 spellingLocation = result->location; |
| 871 misspelledWord = paragraphString.substring(result->locat
ion, result->length); |
| 872 DCHECK(misspelledWord.length()); |
| 873 break; |
| 874 } |
| 875 } |
| 876 |
| 877 if (!misspelledWord.isEmpty()) { |
| 878 int spellingOffset = spellingLocation - currentStartOffset; |
| 879 if (!firstIteration) |
| 880 spellingOffset += TextIterator::rangeLength(start, parag
raphStart); |
| 881 outFirstFoundOffset = spellingOffset; |
| 882 firstFoundItem = misspelledWord; |
| 883 break; |
| 884 } |
| 885 } |
| 886 } |
| 887 if (lastIteration || totalLengthProcessed + currentLength >= totalRangeL
ength) |
| 888 break; |
| 889 VisiblePosition newParagraphStart = startOfNextParagraph(createVisiblePo
sition(paragraphEnd)); |
| 890 paragraphStart = newParagraphStart.toParentAnchoredPosition(); |
| 891 paragraphEnd = endOfParagraph(newParagraphStart).toParentAnchoredPositio
n(); |
| 892 firstIteration = false; |
| 893 totalLengthProcessed += currentLength; |
| 894 } |
| 895 return firstFoundItem; |
| 896 } |
| 897 |
| 789 } // namespace blink | 898 } // namespace blink |
| OLD | NEW |