mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
New spellcheck controller code
Not in build yet, checking in so Mac projects can be built Bug 180346
This commit is contained in:
parent
9b13bbe8dc
commit
f8c4297a73
36
extensions/spellcheck/Makefile.in
Normal file
36
extensions/spellcheck/Makefile.in
Normal file
@ -0,0 +1,36 @@
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing rights and limitations
|
||||
# under the License.
|
||||
|
||||
# The Initial Developer of the Original Code is Aaron Leventhal.
|
||||
# Portions created by Aaron Leventhal are Copyright (C) 2001
|
||||
# Aaron Leventhal. All Rights Reserved.
|
||||
|
||||
# Alternatively, the contents of this file may be used under the terms
|
||||
# of the GNU General Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above. If you
|
||||
# wish to allow use of your version of this file only under the terms of
|
||||
# the GPL and not to allow others to use your version of this file under
|
||||
# the MPL, indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by the
|
||||
# GPL. If you do not delete the provisions above, a recipient may use
|
||||
# your version of this file under either the MPL or the GPL.
|
||||
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = src
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
82
extensions/spellcheck/src/Makefile.in
Normal file
82
extensions/spellcheck/src/Makefile.in
Normal file
@ -0,0 +1,82 @@
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing rights and limitations
|
||||
# under the License.
|
||||
|
||||
# The Initial Developer of the Original Code is Aaron Leventhal.
|
||||
# Portions created by Aaron Leventhal are Copyright (C) 2001
|
||||
# Aaron Leventhal. All Rights Reserved.
|
||||
|
||||
# Alternatively, the contents of this file may be used under the terms
|
||||
# of the GNU General Public License (the "GPL"), in which case the
|
||||
# provisions of the GPL are applicable instead of those above. If you
|
||||
# wish to allow use of your version of this file only under the terms of
|
||||
# the GPL and not to allow others to use your version of this file under
|
||||
# the MPL, indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by the
|
||||
# GPL. If you do not delete the provisions above, a recipient may use
|
||||
# your version of this file under either the MPL or the GPL.
|
||||
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = spellcheckcontroller
|
||||
LIBRARY_NAME = spellcheckcontroller
|
||||
EXPORT_LIBRARY = 1
|
||||
IS_COMPONENT = 1
|
||||
MODULE_NAME = nsSpellCheckController
|
||||
|
||||
ifneq ($(OS_ARCH),WINNT)
|
||||
SHORT_LIBNAME = spchckcntl
|
||||
endif
|
||||
|
||||
REQUIRES = string \
|
||||
xpcom \
|
||||
dom \
|
||||
docshell \
|
||||
gfx \
|
||||
layout \
|
||||
content \
|
||||
widget \
|
||||
htmlparser \
|
||||
necko \
|
||||
unicharutil \
|
||||
lwbrk \
|
||||
string \
|
||||
txtsvc \
|
||||
uconv \
|
||||
lwbrk \
|
||||
editor \
|
||||
pref \
|
||||
spellcheck \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
nsSpellCheckController.cpp \
|
||||
nsSpellCheckUtils.cpp \
|
||||
nsSpellCheckModule.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LIBS = \
|
||||
gkgfx \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
$(LIBS_DIR) \
|
||||
$(MOZ_UNICHARUTIL_LIBS) \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
624
extensions/spellcheck/src/nsSpellCheckController.cpp
Normal file
624
extensions/spellcheck/src/nsSpellCheckController.cpp
Normal file
@ -0,0 +1,624 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Mozilla browser.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications, Inc. Portions created by Netscape are
|
||||
* Copyright (C) 1999, Mozilla. All Rights Reserved.
|
||||
*
|
||||
* Contributors:
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsSpellCheckController.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsISelection.h"
|
||||
#include "nsIDOMRange.h"
|
||||
|
||||
#define NBSP_SPACE_CODE ((PRUnichar)32)
|
||||
|
||||
nsSpellCheckController::nsSpellCheckController() :
|
||||
mOffset(0),
|
||||
mEndPoint(0)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsSpellCheckController::~nsSpellCheckController()
|
||||
{
|
||||
}
|
||||
|
||||
// #define DEBUG_SPELLCHECKGLUE_REFCNT 1
|
||||
|
||||
#ifdef DEBUG_SPELLCHECKGLUE_REFCNT
|
||||
|
||||
nsrefcnt nsSpellCheckController::AddRef(void)
|
||||
{
|
||||
return ++mRefCnt;
|
||||
}
|
||||
|
||||
nsrefcnt nsSpellCheckController::Release(void)
|
||||
{
|
||||
NS_PRECONDITION(0 != mRefCnt, "dup release");
|
||||
if (--mRefCnt == 0) {
|
||||
NS_DELETEXPCOM(this);
|
||||
return 0;
|
||||
}
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE1(nsSpellCheckController, nsISpellChecker)
|
||||
#else
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsSpellCheckController, nsISpellCheckController)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
nsresult
|
||||
NS_NewSpellCheckGlue(nsSpellCheckController** result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
nsSpellCheckController* spellCheckGlue = new nsSpellCheckController();
|
||||
NS_ENSURE_TRUE(spellCheckGlue, NS_ERROR_NULL_POINTER);
|
||||
|
||||
*result = spellCheckGlue;
|
||||
NS_ADDREF(*result);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// aInitialRange can be NULL
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsSpellCheckController::Init(nsITextServicesDocument* aDoc, nsIDOMRange* aInitialRange)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDoc);
|
||||
|
||||
// Create INSO Spell Checker
|
||||
nsresult rv;
|
||||
mSpellChecker = do_GetService(NS_SPELLCHECKER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Create WordBreaker
|
||||
rv = nsSpellCheckUtils::GetWordBreaker(getter_AddRefs(mWordBreaker));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// zero out offset before starting
|
||||
mOffset = 0;
|
||||
|
||||
return SetDocument(aDoc, aInitialRange);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSpellCheckController::SetDocument(nsITextServicesDocument *aDoc,nsIDOMRange* aInitialRange)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDoc);
|
||||
|
||||
// XXX: Modify this method so that it can be called
|
||||
// more than once with a different aDoc. This will
|
||||
// allow us to reuse a spellchecker.
|
||||
|
||||
mDocument = do_QueryInterface(aDoc);
|
||||
NS_ENSURE_TRUE(mDocument, NS_ERROR_NULL_POINTER);
|
||||
|
||||
nsresult rv;
|
||||
if (!aInitialRange) {
|
||||
rv = mDocument->FirstBlock();
|
||||
|
||||
} else {
|
||||
rv = aInitialRange->GetStartContainer(getter_AddRefs(mStartNode));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
PRInt32 startOffset;
|
||||
rv = aInitialRange->GetStartOffset(&startOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mOffset = PRUint32(startOffset);
|
||||
|
||||
rv = aInitialRange->GetEndContainer(getter_AddRefs(mEndNode));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
PRInt32 endOffset;
|
||||
rv = aInitialRange->GetEndOffset(&endOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mEndPoint = PRUint32(endOffset);
|
||||
|
||||
nsITextServicesDocument::TSDBlockSelectionStatus selStatus;
|
||||
PRInt32 selOffset, selLength;
|
||||
|
||||
rv = mDocument->FirstSelectedBlock(&selStatus, &selOffset, &selLength);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = nsSpellCheckUtils::LoadTextBlockIntoBuffer(mDocument, mSpellChecker, mBlockBuffer, mText, mOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!aInitialRange) {
|
||||
mOffset = 0;
|
||||
mEndPoint = mText.Length() - 1;
|
||||
} else {
|
||||
rv = FindBeginningOfWord(mOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (mStartNode == mEndNode) {
|
||||
rv = FindBeginningOfWord(mEndPoint);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSpellCheckController::FindBeginningOfWord(PRUint32& aPos)
|
||||
{
|
||||
const PRUnichar* text = mText.get();
|
||||
PRUint32 textLen = mText.Length();
|
||||
PRUint32 wlen = 0;
|
||||
PRUint32 beginWord = 0;
|
||||
PRUint32 endWord = 0;
|
||||
|
||||
PRUint32 prvWordEnd;
|
||||
PRUint32 offset = 0;
|
||||
while (offset < textLen) {
|
||||
prvWordEnd = endWord;
|
||||
nsresult rv = mWordBreaker->FindWord(text, textLen, offset, &beginWord, &endWord);
|
||||
if (NS_FAILED(rv)) break;
|
||||
|
||||
// The wordBreaker hands back the spaces inbetween the words
|
||||
// so we need to skip any words that are all spaces
|
||||
const PRUnichar* start = (text+offset);
|
||||
const PRUnichar* endPtr = (text+endWord);
|
||||
while (*start == NBSP_SPACE_CODE && start < endPtr)
|
||||
start++;
|
||||
|
||||
if (start == endPtr) {
|
||||
offset = endWord;
|
||||
continue;
|
||||
}
|
||||
|
||||
offset = endWord+1;
|
||||
|
||||
wlen = endWord - beginWord;
|
||||
if (endWord < aPos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (aPos >= beginWord) {
|
||||
aPos = beginWord;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSpellCheckController::GetSpellChecker(nsISpellChecker **aSpellChecker)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSpellChecker);
|
||||
*aSpellChecker = mSpellChecker;
|
||||
NS_IF_ADDREF(*aSpellChecker);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSpellCheckController::NextMisspelledWord(PRUnichar **aWord)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aWord);
|
||||
NS_ENSURE_TRUE(mDocument && mSpellChecker && mWordBreaker, NS_ERROR_NULL_POINTER);
|
||||
|
||||
// Init the return values.
|
||||
*aWord = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> currentNode;
|
||||
mDocument->GetCurrentNode(getter_AddRefs(currentNode));
|
||||
|
||||
// There might not have been any text in the
|
||||
// document. Just return NS_OK;
|
||||
if (mText.IsEmpty() || (mOffset >= mEndPoint && currentNode == mEndNode)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult result;
|
||||
|
||||
// Now get the next misspelled word in the document.
|
||||
const PRUnichar* text = mText.get();
|
||||
PRUint32 textLen = mText.Length();
|
||||
PRUint32 wlen = 0;
|
||||
PRUint32 beginWord = 0;
|
||||
PRUint32 endWord = 0;
|
||||
|
||||
PRBool isMisspelled = PR_FALSE;
|
||||
while (!isMisspelled) {
|
||||
PRUnichar* word;
|
||||
result = FindNextMisspelledWord(text, textLen, mOffset, wlen,
|
||||
beginWord, endWord, word, PR_TRUE, isMisspelled);
|
||||
if (NS_FAILED(result) || (beginWord > mEndPoint && currentNode == mEndNode)) {
|
||||
if (word) nsMemory::Free(word);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (isMisspelled) {
|
||||
*aWord = word;
|
||||
|
||||
} else {
|
||||
// No more misspelled words in the current buffer.
|
||||
// Load another text block into the buffer, try again.
|
||||
|
||||
result = mDocument->NextBlock();
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
PRBool isDone;
|
||||
|
||||
result = mDocument->IsDone(&isDone);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
if (isDone) {
|
||||
// No more blocks to process. We're done, so just
|
||||
// return OK for the result.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
result = nsSpellCheckUtils::LoadTextBlockIntoBuffer(mDocument, mSpellChecker, mBlockBuffer, mText, mOffset);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
mDocument->GetCurrentNode(getter_AddRefs(currentNode));
|
||||
if (currentNode == mEndNode) {
|
||||
FindBeginningOfWord(mEndPoint);
|
||||
}
|
||||
mOffset = 0;
|
||||
wlen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// We have a misspelled word. Select it in the document,
|
||||
// and scroll the selection into view.
|
||||
|
||||
// XXX: SetSelection() no longer scrolls the selection
|
||||
// into view. Something changed underneath the hood
|
||||
// in the presentation shell. Need to fix this!
|
||||
|
||||
result = mDocument->SetSelection(beginWord, wlen);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
result = mDocument->ScrollSelectionIntoView();
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSpellCheckController::CheckWord(const PRUnichar *aWord, PRBool *aIsMisspelled)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aWord);
|
||||
NS_ENSURE_ARG_POINTER(aIsMisspelled);
|
||||
NS_ENSURE_TRUE(mSpellChecker, NS_ERROR_NULL_POINTER);
|
||||
|
||||
// start by assuming everything is spelled correctly.
|
||||
*aIsMisspelled = PR_FALSE;
|
||||
|
||||
return mSpellChecker->Check(aWord, aIsMisspelled);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSpellCheckController::Replace(const PRUnichar *aOldWord, const PRUnichar *aNewWord, PRBool aAllOccurrences)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aOldWord);
|
||||
NS_ENSURE_ARG_POINTER(aNewWord);
|
||||
|
||||
NS_ENSURE_TRUE(mDocument, NS_ERROR_NULL_POINTER);
|
||||
|
||||
nsresult result;
|
||||
|
||||
// XXX: To make this method work for a non-modal dialog, we will
|
||||
// have to add code that compares the current selection with
|
||||
// aOldWord.
|
||||
|
||||
if (aAllOccurrences) {
|
||||
nsString oldWord(aOldWord);
|
||||
nsString newWord(aNewWord);
|
||||
result = ReplaceAll(&oldWord, &newWord);
|
||||
|
||||
} else if (!*aNewWord) {
|
||||
result = mDocument->DeleteSelection();
|
||||
|
||||
} else {
|
||||
nsString newWord(aNewWord);
|
||||
result = mDocument->InsertText(&newWord);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSpellCheckController::ReplaceAll(const nsString *aOldWord, const nsString *aNewWord)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aOldWord);
|
||||
NS_ENSURE_ARG_POINTER(aNewWord);
|
||||
NS_ENSURE_TRUE(mSpellChecker, NS_ERROR_NULL_POINTER);
|
||||
|
||||
nsresult result;
|
||||
CharBuffer oldWord;
|
||||
|
||||
nsCOMPtr<nsIUnicodeEncoder> unicodeEncoder;
|
||||
|
||||
nsXPIDLString charSet;
|
||||
result = mSpellChecker->GetCharset(getter_Copies(charSet));
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
nsCOMPtr<nsIUnicodeDecoder> unicodeDecoder;
|
||||
result = nsSpellCheckUtils::CreateUnicodeConverters(charSet,
|
||||
getter_AddRefs(unicodeEncoder),
|
||||
getter_AddRefs(unicodeDecoder));
|
||||
NS_ENSURE_TRUE(unicodeEncoder, NS_ERROR_NULL_POINTER);
|
||||
}
|
||||
|
||||
result = nsSpellCheckUtils::ReadStringIntoBuffer(unicodeEncoder, aOldWord, &oldWord);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
// Skip the current occurrence of old word. It will be the last
|
||||
// occurrence we replace so that we can figure out where we were
|
||||
// before replace all started!
|
||||
|
||||
result = ReplaceAllOccurrences(&oldWord, aNewWord);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
PRInt32 i, numBlocksBefore = 0;
|
||||
PRBool isDone = PR_FALSE;
|
||||
|
||||
// Count the number of text blocks that came before the current
|
||||
// one, so that we know when to stop replacing after we hit the
|
||||
// end of the document and swing around to the beginning of the
|
||||
// document.
|
||||
|
||||
while (!isDone) {
|
||||
++numBlocksBefore;
|
||||
|
||||
result = mDocument->PrevBlock();
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
result = mDocument->IsDone(&isDone);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
}
|
||||
|
||||
// Now reset the document so that we start replacing all occurrences
|
||||
// between the current block and the end of the document!
|
||||
|
||||
result = mDocument->FirstBlock();
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
i = numBlocksBefore;
|
||||
while (i-- > 0) {
|
||||
result = mDocument->NextBlock();
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
}
|
||||
|
||||
// Now replace all occurrences till we hit the end of the document!
|
||||
|
||||
result = mDocument->IsDone(&isDone);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
while (!isDone) {
|
||||
result = nsSpellCheckUtils::LoadTextBlockIntoBuffer(mDocument, mSpellChecker, mBlockBuffer, mText, mOffset);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
result = ReplaceAllOccurrences(&oldWord, aNewWord);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
result = mDocument->NextBlock();
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
result = mDocument->IsDone(&isDone);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
}
|
||||
|
||||
// Now swing around to the beginning of the document, and
|
||||
// replace all occurrences till we hit the old current block!
|
||||
|
||||
result = mDocument->FirstBlock();
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
isDone = PR_FALSE;
|
||||
|
||||
while (numBlocksBefore-- > 0 && !isDone) {
|
||||
result = nsSpellCheckUtils::LoadTextBlockIntoBuffer(mDocument, mSpellChecker, mBlockBuffer, mText, mOffset);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
result = ReplaceAllOccurrences(&oldWord, aNewWord);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
if (numBlocksBefore > 0) {
|
||||
result = mDocument->NextBlock();
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
// Track isDone because I'm paranoid!
|
||||
|
||||
result = mDocument->IsDone(&isDone);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
}
|
||||
}
|
||||
|
||||
// Now reload the text into the buffer so that the
|
||||
// spelling checker is reset to look for the next
|
||||
// misspelled word.
|
||||
|
||||
result = nsSpellCheckUtils::LoadTextBlockIntoBuffer(mDocument, mSpellChecker, mBlockBuffer, mText, mOffset);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSpellCheckController::ReplaceAllOccurrences(const CharBuffer *aOldWord, const nsString *aNewWord)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aOldWord);
|
||||
NS_ENSURE_ARG_POINTER(aNewWord);
|
||||
NS_ENSURE_TRUE(mSpellChecker && mWordBreaker, NS_ERROR_NULL_POINTER);
|
||||
|
||||
// Now get the next misspelled word in the document.
|
||||
const PRUnichar* text = mText.get();
|
||||
PRUint32 textLen = mText.Length();
|
||||
PRUint32 wlen = 0;
|
||||
PRUint32 beginWord = 0;
|
||||
PRUint32 endWord = 0;
|
||||
PRUint32 offset = 0;
|
||||
|
||||
PRBool isMisspelled = PR_TRUE;
|
||||
while (isMisspelled) {
|
||||
PRUnichar* word;
|
||||
nsresult result = FindNextMisspelledWord(text, textLen, offset, wlen,
|
||||
beginWord, endWord, word, PR_FALSE, isMisspelled);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
if (isMisspelled) {
|
||||
|
||||
mWordBuffer.AssureCapacity(wlen + 1);
|
||||
|
||||
PRUint32 i;
|
||||
for (i = 0; i < wlen; i++)
|
||||
mWordBuffer.mData[i] = mBlockBuffer.mData[i + beginWord];
|
||||
|
||||
mWordBuffer.mData[i] = '\0';
|
||||
mWordBuffer.mDataLength = wlen;
|
||||
|
||||
// XXX: Need to do a case insensitive comparison, and replace
|
||||
// with a word that matches the misspelled word's caps.
|
||||
|
||||
if (aOldWord->mDataLength == mWordBuffer.mDataLength &&
|
||||
!memcmp(aOldWord->mData, mWordBuffer.mData, aOldWord->mDataLength)) {
|
||||
// We found an occurrence of old word, so replace it!
|
||||
|
||||
result = mDocument->SetSelection(beginWord, wlen);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
result = mDocument->ScrollSelectionIntoView();
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
if (aNewWord->Length() > 0)
|
||||
result = mDocument->InsertText(aNewWord);
|
||||
else
|
||||
result = mDocument->DeleteSelection();
|
||||
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
offset = endWord;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSpellCheckController::SpellCheckDOMRange(nsIDOMRange *aRangeToCheck, nsISelection *aSelectionOfWords)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRangeToCheck);
|
||||
NS_ENSURE_ARG_POINTER(aSelectionOfWords);
|
||||
|
||||
NS_ENSURE_TRUE(mSpellChecker && mWordBreaker, NS_ERROR_NULL_POINTER);
|
||||
NS_ENSURE_TRUE(mDocument, NS_ERROR_NULL_POINTER);
|
||||
|
||||
mDocument->InitWithRange(aRangeToCheck);
|
||||
nsSpellCheckUtils::LoadTextBlockIntoBuffer(mDocument, mSpellChecker, mBlockBuffer, mText, mOffset);
|
||||
|
||||
// You may want to clear this externally instead of here
|
||||
aSelectionOfWords->RemoveAllRanges();
|
||||
|
||||
// Now get the next misspelled word in the document.
|
||||
const PRUnichar* text = mText.get();
|
||||
PRUint32 textLen = mText.Length();
|
||||
PRUint32 wlen = 0;
|
||||
PRUint32 beginWord = 0;
|
||||
PRUint32 endWord = 0;
|
||||
|
||||
PRBool isMisspelled = PR_TRUE;
|
||||
while (isMisspelled) {
|
||||
PRUnichar* word;
|
||||
nsresult result = FindNextMisspelledWord(text, textLen, mOffset, wlen,
|
||||
beginWord, endWord, word, PR_FALSE, isMisspelled);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
if (isMisspelled) {// We found an occurrence of old word, so replace it!
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
result = mDocument->GetDOMRangeFor(beginWord, wlen, getter_AddRefs(range));
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
result = aSelectionOfWords->AddRange(range);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Helper Method
|
||||
nsresult
|
||||
nsSpellCheckController::FindNextMisspelledWord(const PRUnichar* aText,
|
||||
const PRUint32& aTextLen,
|
||||
PRUint32& aOffset,
|
||||
PRUint32& aWLen,
|
||||
PRUint32& aBeginWord,
|
||||
PRUint32& aEndWord,
|
||||
PRUnichar*& aWord,
|
||||
PRBool aReturnWord,
|
||||
PRBool& aIsMisspelled)
|
||||
{
|
||||
aWord = nsnull;
|
||||
aIsMisspelled = PR_FALSE;
|
||||
|
||||
#ifdef DEBUG_rods
|
||||
DUMPWORDS(mWordBreaker, aText, aTextLen);
|
||||
#endif
|
||||
|
||||
while (aOffset < aTextLen) {
|
||||
nsresult result = mWordBreaker->FindWord(aText, aTextLen, aOffset, &aBeginWord, &aEndWord);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
aWLen = aEndWord - aBeginWord;
|
||||
|
||||
// The wordBreaker hands back the spaces inbetween the words
|
||||
// so we need to skip any words that are all spaces
|
||||
const PRUnichar* start = (aText+aOffset);
|
||||
const PRUnichar* endPtr = (aText+aEndWord);
|
||||
while (*start == NBSP_SPACE_CODE && start < endPtr)
|
||||
start++;
|
||||
|
||||
if (start == endPtr) {
|
||||
aOffset = aEndWord;
|
||||
continue;
|
||||
}
|
||||
|
||||
PRUnichar* word = nsCRT::strndup(start, aWLen);
|
||||
aOffset = aEndWord;
|
||||
|
||||
result = mSpellChecker->Check(word, &aIsMisspelled);
|
||||
#if DEBUG_rods
|
||||
printf("Word [%s] MSP: %s\n", NS_LossyConvertUCS2toASCII(word).get(), aIsMisspelled ? "YES":"NO");
|
||||
#endif
|
||||
if (NS_FAILED(result)) {
|
||||
nsMemory::Free(word);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (aIsMisspelled) {
|
||||
if (aReturnWord) {
|
||||
aWord = word;
|
||||
|
||||
} else {
|
||||
nsMemory::Free(word);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
nsMemory::Free(word);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
93
extensions/spellcheck/src/nsSpellCheckController.h
Normal file
93
extensions/spellcheck/src/nsSpellCheckController.h
Normal file
@ -0,0 +1,93 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Mozilla browser.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications, Inc. Portions created by Netscape are
|
||||
* Copyright (C) 1999, Mozilla. All Rights Reserved.
|
||||
*
|
||||
* Contributors:
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef nsSpellCheckController_h__
|
||||
#define nsSpellCheckController_h__
|
||||
|
||||
#include "nsITextServicesDocument.h"
|
||||
#include "nsISpellCheckController.h"
|
||||
#include "nsIWordBreakerFactory.h" // nsIWordBreaker
|
||||
#include "nsIDOMNode.h"
|
||||
|
||||
#include "nsISpellChecker.h"
|
||||
#include "nsSpellCheckUtils.h" // CharBuffer
|
||||
|
||||
/** implementation of a text services object.
|
||||
*
|
||||
*/
|
||||
class nsSpellCheckController : public nsISpellCheckController
|
||||
{
|
||||
public:
|
||||
|
||||
/** The default constructor.
|
||||
*/
|
||||
nsSpellCheckController();
|
||||
|
||||
/** The default destructor.
|
||||
*/
|
||||
virtual ~nsSpellCheckController();
|
||||
|
||||
/* Macro for AddRef(), Release(), and QueryInterface() */
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
/* nsISpellChecker method implementations. */
|
||||
NS_DECL_NSISPELLCHECKCONTROLLER
|
||||
|
||||
private:
|
||||
|
||||
nsresult LoadTextBlockIntoBuffer();
|
||||
nsresult ReplaceAll(const nsString *aOldWord, const nsString *aNewWord);
|
||||
nsresult ReplaceAllOccurrences(const CharBuffer *aOldWord, const nsString *aNewWord);
|
||||
nsresult FindNextMisspelledWord(const PRUnichar* aText,
|
||||
const PRUint32& aTextLen,
|
||||
PRUint32& aWLen,
|
||||
PRUint32& aBeginWord,
|
||||
PRUint32& aEndWord,
|
||||
PRUint32& aOffset,
|
||||
PRUnichar*& aWord,
|
||||
PRBool aReturnWord,
|
||||
PRBool& aIsMisspelled);
|
||||
nsresult SetDocument(nsITextServicesDocument *aDoc, nsIDOMRange* aInitialRange);
|
||||
nsresult FindBeginningOfWord(PRUint32& aPos);
|
||||
|
||||
nsCOMPtr<nsITextServicesDocument> mDocument;
|
||||
CharBuffer mBlockBuffer;
|
||||
CharBuffer mWordBuffer;
|
||||
|
||||
nsCOMPtr<nsIWordBreaker> mWordBreaker;
|
||||
nsCOMPtr<nsISpellChecker> mSpellChecker;
|
||||
nsString mText;
|
||||
PRUint32 mOffset; // starting offset to start spelling
|
||||
PRUint32 mEndPoint; // end point of range to be spell checked
|
||||
|
||||
nsCOMPtr<nsIDOMNode> mStartNode;
|
||||
nsCOMPtr<nsIDOMNode> mEndNode;
|
||||
};
|
||||
|
||||
#define NS_SPELLCHECKCONTROLLER_CID \
|
||||
{ /* 019718E4-CDB5-11d2-8D3C-000000000000 */ \
|
||||
0x019718e4, 0xcdb5, 0x11d2, \
|
||||
{ 0x8d, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }
|
||||
|
||||
|
||||
#endif // nsSpellCheckController_h__
|
49
extensions/spellcheck/src/nsSpellCheckModule.cpp
Normal file
49
extensions/spellcheck/src/nsSpellCheckModule.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsSpellCheckController.h"
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSpellCheckController)
|
||||
|
||||
static const nsModuleComponentInfo gSpellCheckComponents[] = {
|
||||
|
||||
{ "nsSpellCheckController", NS_SPELLCHECKCONTROLLER_CID, NS_SPELLCHECKCONTROLLER_CONTRACTID, nsSpellCheckControllerConstructor }
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE(spellcheckcontroller, gSpellCheckComponents)
|
238
extensions/spellcheck/src/nsSpellCheckUtils.cpp
Normal file
238
extensions/spellcheck/src/nsSpellCheckUtils.cpp
Normal file
@ -0,0 +1,238 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Mozilla browser.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications, Inc. Portions created by Netscape are
|
||||
* Copyright (C) 1999, Mozilla. All Rights Reserved.
|
||||
*
|
||||
* Contributors:
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "nsSpellCheckUtils.h"
|
||||
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsICharsetConverterManager2.h"
|
||||
#include "nsIPlatformCharset.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
#include "nsISpellChecker.h"
|
||||
#include "nsITextServicesDocument.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIWordBreakerFactory.h" // nsIWordBreaker
|
||||
#include "nsLWBrkCIID.h"
|
||||
|
||||
|
||||
#ifdef XP_MAC
|
||||
#define IS_NBSP_CHAR(c) (((unsigned char)0xca)==(c))
|
||||
#else
|
||||
#define IS_NBSP_CHAR(c) (((unsigned char)0xa0)==(c))
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
nsSpellCheckUtils::ReadStringIntoBuffer(nsIUnicodeEncoder* aUnicodeEncoder,
|
||||
const PRUnichar* aStr,
|
||||
CharBuffer* aBuf)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aUnicodeEncoder);
|
||||
NS_ENSURE_ARG_POINTER(aBuf);
|
||||
|
||||
if (!aStr || !*aStr) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
aBuf->mDataLength = 0;
|
||||
|
||||
PRInt32 unicodeLength = nsCRT::strlen(aStr);
|
||||
|
||||
// Estimate a string length after the conversion.
|
||||
PRInt32 estimatedLength, stringLength;
|
||||
nsresult result = aUnicodeEncoder->GetMaxLength(aStr, unicodeLength, &estimatedLength);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
result = aBuf->AssureCapacity(estimatedLength + 1);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
// Convert from unicode.
|
||||
stringLength = estimatedLength;
|
||||
result = aUnicodeEncoder->Convert(aStr, &unicodeLength, aBuf->mData, &stringLength);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
// Terminate the conversion (e.g. put escape sequence for JIS).
|
||||
PRInt32 finLen = estimatedLength - stringLength;
|
||||
if (finLen)
|
||||
{
|
||||
NS_ENSURE_TRUE(finLen > 0, NS_ERROR_FAILURE);
|
||||
result = aUnicodeEncoder->Finish(&aBuf->mData[stringLength], &finLen);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
}
|
||||
|
||||
aBuf->mDataLength = stringLength + finLen;
|
||||
aBuf->mData[aBuf->mDataLength] = '\0';
|
||||
for (unsigned char* p = (unsigned char*) aBuf->mData; *p ; p++)
|
||||
if( IS_NBSP_CHAR(*p) )
|
||||
*p = ' ';
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSpellCheckUtils::ReadStringIntoBuffer(nsIUnicodeEncoder* aUnicodeEncoder,
|
||||
const nsString* aStr,
|
||||
CharBuffer* aBuf)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aUnicodeEncoder);
|
||||
NS_ENSURE_ARG_POINTER(aStr);
|
||||
NS_ENSURE_ARG_POINTER(aBuf);
|
||||
return ReadStringIntoBuffer(aUnicodeEncoder, aStr->get(), aBuf);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSpellCheckUtils::CreateUnicodeConverters(const PRUnichar* aCharset,
|
||||
nsIUnicodeEncoder** aUnicodeEncoder,
|
||||
nsIUnicodeDecoder** aUnicodeDecoder)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCharset);
|
||||
NS_ENSURE_ARG_POINTER(aUnicodeEncoder);
|
||||
NS_ENSURE_ARG_POINTER(aUnicodeDecoder);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr <nsICharsetConverterManager2> ccm2 = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr <nsIAtom> charsetAtom;
|
||||
rv = ccm2->GetCharsetAtom(aCharset, getter_AddRefs(charsetAtom));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ccm2->GetUnicodeDecoder(charsetAtom, aUnicodeDecoder);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ccm2->GetUnicodeEncoder(charsetAtom, aUnicodeEncoder);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Set the error behavior, in case a character cannot be mapped.
|
||||
rv = (*aUnicodeEncoder)->SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Replace, nsnull, ' ');
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSpellCheckUtils::LoadTextBlockIntoBuffer(nsITextServicesDocument* aTxtSvcDoc,
|
||||
nsISpellChecker* aSpellChecker,
|
||||
CharBuffer& aCharBuf,
|
||||
nsString& aText,
|
||||
PRUint32& aOffset)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTxtSvcDoc);
|
||||
NS_ENSURE_ARG_POINTER(aSpellChecker);
|
||||
|
||||
nsCOMPtr<nsIUnicodeEncoder> unicodeEncoder;
|
||||
nsXPIDLString charSet;
|
||||
nsresult result = aSpellChecker->GetCharset(getter_Copies(charSet));
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
nsCOMPtr<nsIUnicodeDecoder> unicodeDecoder;
|
||||
result = nsSpellCheckUtils::CreateUnicodeConverters(charSet,
|
||||
getter_AddRefs(unicodeEncoder),
|
||||
getter_AddRefs(unicodeDecoder));
|
||||
NS_ENSURE_TRUE(unicodeEncoder, NS_ERROR_NULL_POINTER);
|
||||
}
|
||||
|
||||
if (aCharBuf.mData)
|
||||
aCharBuf.mData[0] = '\0';
|
||||
|
||||
nsString str;
|
||||
aCharBuf.mDataLength = 0;
|
||||
|
||||
result = aTxtSvcDoc->GetCurrentTextBlock(&str);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
result = nsSpellCheckUtils::ReadStringIntoBuffer(unicodeEncoder, &str, &aCharBuf);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
if (aCharBuf.mDataLength < 1)
|
||||
{
|
||||
// The document could be empty, so return
|
||||
// NS_OK!
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
aText.AssignWithConversion(aCharBuf.mData);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSpellCheckUtils::GetWordBreaker(nsIWordBreaker** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
// no line breaker, find a default one
|
||||
nsresult result;
|
||||
nsCOMPtr<nsIWordBreakerFactory> wbf(do_GetService(NS_LWBRK_CONTRACTID, &result));
|
||||
if (NS_SUCCEEDED(result))
|
||||
{
|
||||
nsAutoString wbarg;
|
||||
result = wbf->GetBreaker(wbarg, aResult);
|
||||
NS_IF_ADDREF(*aResult);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
nsresult
|
||||
nsSpellCheckUtils::DumpWords(nsIWordBreaker* aWordBreaker,
|
||||
const PRUnichar* aText,
|
||||
const PRUint32& aTextLen)
|
||||
{
|
||||
PRUint32 offset = 0;
|
||||
PRUint32 wlen = 0;
|
||||
for (int i=0;i<7;i++) printf("**********");
|
||||
printf("\n");
|
||||
for (i=0;i<7;i++) printf("0123456789");
|
||||
printf("\n");
|
||||
char* line = strdup(NS_LossyConvertUCS2toASCII(aText).get());
|
||||
for (i=0;i<aTextLen;i++)
|
||||
if (line[i] < 32)
|
||||
putc('_', stdout);
|
||||
else
|
||||
putc(line[i], stdout);
|
||||
printf("\n");
|
||||
//printf("%s\n", NS_LossyConvertUCS2toASCII(aText).get());
|
||||
free(line);
|
||||
|
||||
while (offset < aTextLen)
|
||||
{
|
||||
PRUint32 begin = 0;
|
||||
PRUint32 end = 0;
|
||||
nsresult result = aWordBreaker->FindWord(aText, aTextLen, offset, &begin, &end);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
wlen = end - begin;
|
||||
printf("%d %d l:%d ", begin, end, wlen);
|
||||
const PRUnichar* start = (const PRUnichar*)(aText+offset);
|
||||
PRUnichar* word = nsCRT::strndup(start, wlen);
|
||||
nsString str(word);
|
||||
printf("[%s]\n", NS_LossyConvertUCS2toASCII(str).get());
|
||||
nsMemory::Free(word);
|
||||
offset = end;
|
||||
}
|
||||
for (i=0;i<7;i++) printf("**********");
|
||||
printf("\n");
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
123
extensions/spellcheck/src/nsSpellCheckUtils.h
Normal file
123
extensions/spellcheck/src/nsSpellCheckUtils.h
Normal file
@ -0,0 +1,123 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Mozilla browser.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications, Inc. Portions created by Netscape are
|
||||
* Copyright (C) 1999, Mozilla. All Rights Reserved.
|
||||
*
|
||||
* Contributors:
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef nsSpellCheckUtils_h__
|
||||
#define nsSpellCheckUtils_h__
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsICharsetConverterManager.h"
|
||||
|
||||
class nsISpellChecker;
|
||||
class nsITextServicesDocument;
|
||||
class nsIWordBreaker;
|
||||
|
||||
class CharBuffer
|
||||
{
|
||||
public:
|
||||
|
||||
PRInt32 mCapacity;
|
||||
char *mData;
|
||||
PRInt32 mDataLength;
|
||||
|
||||
CharBuffer() : mCapacity(0), mData(0), mDataLength(0) {}
|
||||
|
||||
~CharBuffer()
|
||||
{
|
||||
if (mData)
|
||||
delete []mData;
|
||||
|
||||
mData = 0;
|
||||
mCapacity = 0;
|
||||
mDataLength = 0;
|
||||
}
|
||||
|
||||
nsresult AssureCapacity(PRInt32 aLength)
|
||||
{
|
||||
if (aLength > mCapacity)
|
||||
{
|
||||
if (mData)
|
||||
delete []mData;
|
||||
|
||||
mData = new char[aLength];
|
||||
|
||||
if (!mData)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mCapacity = aLength;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
/** implementation of a text services object.
|
||||
*
|
||||
*/
|
||||
class nsSpellCheckUtils
|
||||
{
|
||||
public:
|
||||
static nsresult ReadStringIntoBuffer(nsIUnicodeEncoder* aUnicodeEncoder,
|
||||
const PRUnichar* aStr,
|
||||
CharBuffer* aBuf);
|
||||
|
||||
static nsresult ReadStringIntoBuffer(nsIUnicodeEncoder* aUnicodeEncoder,
|
||||
const nsString* aStr,
|
||||
CharBuffer* aBuf);
|
||||
|
||||
|
||||
static nsresult CreateUnicodeConverters(const PRUnichar* aCharset,
|
||||
nsIUnicodeEncoder** aUnicodeEncoder,
|
||||
nsIUnicodeDecoder** aUnicodeDecoder);
|
||||
|
||||
static nsresult LoadTextBlockIntoBuffer(nsITextServicesDocument* aTxtSvcDoc,
|
||||
nsISpellChecker* aSpellChecker,
|
||||
CharBuffer& aCharBuf,
|
||||
nsString& aText,
|
||||
PRUint32& aOffset);
|
||||
|
||||
// helper
|
||||
static nsresult GetWordBreaker(nsIWordBreaker** aResult);
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
static nsresult DumpWords(nsIWordBreaker* aWordBreaker,
|
||||
const PRUnichar* aText,
|
||||
const PRUint32& aTextLen);
|
||||
#define DUMPWORDS(_wb, _txt, _txtLen) nsSpellCheckUtils::DumpWords(_wb, _txt, _txtLen);
|
||||
#else
|
||||
#define DUMPWORDS(_wb, _txt, _txtLen)
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
/** The default constructor.
|
||||
*/
|
||||
nsSpellCheckUtils() {}
|
||||
|
||||
/** The default destructor.
|
||||
*/
|
||||
virtual ~nsSpellCheckUtils() {}
|
||||
|
||||
};
|
||||
|
||||
#endif // nsSpellCheckUtils_h__
|
Loading…
Reference in New Issue
Block a user