Fixed bug #5527 (Editor is not able to accumulate successive Japanese input)

git-svn-id: svn://10.0.0.236/trunk@30002 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
tague%netscape.com 1999-05-03 22:57:48 +00:00
parent 7ec5fb9eec
commit 6b3b505007
33 changed files with 1107 additions and 68 deletions

View File

@ -25,6 +25,7 @@
#include "nsIDOMDragListener.h"
#include "nsIDOMPaintListener.h"
#include "nsIDOMTextListener.h"
#include "nsIDOMCompositionListener.h"
NS_DEFINE_IID(kIDOMMouseListenerIID, NS_IDOMMOUSELISTENER_IID);
NS_DEFINE_IID(kIDOMKeyListenerIID, NS_IDOMKEYLISTENER_IID);
@ -35,3 +36,4 @@ NS_DEFINE_IID(kIDOMLoadListenerIID, NS_IDOMLOADLISTENER_IID);
NS_DEFINE_IID(kIDOMDragListenerIID, NS_IDOMDRAGLISTENER_IID);
NS_DEFINE_IID(kIDOMPaintListenerIID, NS_IDOMPAINTLISTENER_IID);
NS_DEFINE_IID(kIDOMTextListenerIID,NS_IDOMTEXTLISTENER_IID);
NS_DEFINE_IID(kIDOMCompositionListenerIID,NS_IDOMCOMPOSITIONLISTENER_IID);

View File

@ -29,5 +29,6 @@ extern const nsIID kIDOMLoadListenerIID;
extern const nsIID kIDOMDragListenerIID;
extern const nsIID kIDOMPaintListenerIID;
extern const nsIID kIDOMTextListenerIID;
extern const nsIID kIDOMCompositionListenerIID;
#endif /* nsDOMEVENTSIIDs_h___ */

View File

@ -31,6 +31,7 @@
#include "nsIDOMDragListener.h"
#include "nsIDOMPaintListener.h"
#include "nsIDOMTextListener.h"
#include "nsIDOMCompositionListener.h"
#include "nsIEventStateManager.h"
#include "nsIPrivateDOMEvent.h"
#include "nsIScriptObjectOwner.h"
@ -55,6 +56,7 @@ nsEventListenerManager::nsEventListenerManager()
mDragListeners = nsnull;
mPaintListeners = nsnull;
mTextListeners = nsnull;
mCompositionListeners = nsnull;
NS_INIT_REFCNT();
}
@ -70,6 +72,7 @@ nsEventListenerManager::~nsEventListenerManager()
ReleaseListeners(mDragListeners);
ReleaseListeners(mPaintListeners);
ReleaseListeners(mTextListeners);
ReleaseListeners(mCompositionListeners);
}
NS_IMPL_ADDREF(nsEventListenerManager)
@ -119,6 +122,9 @@ nsVoidArray** nsEventListenerManager::GetListenersByIID(const nsIID& aIID)
else if (aIID.Equals(kIDOMTextListenerIID)) {
return &mTextListeners;
}
else if (aIID.Equals(kIDOMCompositionListenerIID)) {
return &mCompositionListeners;
}
return nsnull;
}
@ -333,7 +339,7 @@ nsresult nsEventListenerManager::GetIdentifiersForType(const nsString& aType, ns
else if (aType == "paint") {
aIID = kIDOMPaintListenerIID;
*aFlags = NS_EVENT_BITS_PAINT_PAINT;
}
} // extened this to handle IME related events
else {
return NS_ERROR_FAILURE;
}
@ -607,6 +613,58 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
}
break;
case NS_COMPOSITION_START:
case NS_COMPOSITION_END:
#if DEBUG_TAGUE
printf("DOM: got composition event\n");
#endif
if (nsnull != mCompositionListeners) {
if (nsnull == *aDOMEvent) {
ret = NS_NewDOMEvent(aDOMEvent,aPresContext,aEvent);
}
if (NS_OK == ret) {
for(int i=0;i<mTextListeners->Count();i++) {
nsListenerStruct *ls;
nsIDOMCompositionListener* mCompositionListener;
ls =(nsListenerStruct*)mCompositionListeners->ElementAt(i);
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMCompositionListenerIID, (void**)&mCompositionListener)) {
if (aEvent->message==NS_COMPOSITION_START) {
ret = mCompositionListener->HandleStartComposition(*aDOMEvent);
}
if (aEvent->message==NS_COMPOSITION_END) {
ret = mCompositionListener->HandleEndComposition(*aDOMEvent);
}
}
NS_RELEASE(mCompositionListener);
}
else {
PRBool correctSubType = PR_FALSE;
switch(aEvent->message) {
case NS_COMPOSITION_START:
if (ls->mSubType & NS_EVENT_BITS_COMPOSITION_START) {
correctSubType = PR_TRUE;
}
break;
case NS_COMPOSITION_END:
if (ls->mSubType & NS_EVENT_BITS_COMPOSITION_END) {
correctSubType = PR_TRUE;
}
break;
default:
break;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
}
break;
case NS_TEXT_EVENT:
#if DEBUG_TAGUE
printf("DOM: got text event\n");

View File

@ -105,6 +105,7 @@ protected:
nsVoidArray* mDragListeners;
nsVoidArray* mPaintListeners;
nsVoidArray* mTextListeners;
nsVoidArray* mCompositionListeners;
};
@ -138,6 +139,11 @@ protected:
#define NS_EVENT_BITS_TEXT_NONE 0x00
#define NS_EVENT_BITS_TEXT_TEXT 0x01
//nsIDOMCompositionListener
#define NS_EVENT_BITS_COMPOSITION_NONE 0x00
#define NS_EVENT_BITS_COMPOSITION_START 0x01
#define NS_EVENT_BITS_COMPOSITION_END 0x02
//nsIDOMFocusListener
#define NS_EVENT_BITS_FOCUS_NONE 0x00
#define NS_EVENT_BITS_FOCUS_FOCUS 0x01

View File

@ -17,3 +17,4 @@ nsIDOMDragListener.h
nsIDOMPaintListener.h
nsIDOMEventTarget.h
nsIDOMTextListener.h
nsIDOMCompositionListener.h

View File

@ -41,6 +41,7 @@ EXPORTS = \
nsIDOMNSEvent.h \
nsIDOMEventTarget.h \
nsIDOMTextListener.h \
nsIDOMCompositionListener.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))

View File

@ -36,6 +36,7 @@ EXPORTS = \
nsIDOMNSEvent.h \
nsIDOMEventTarget.h \
nsIDOMTextListener.h \
nsIDOMCompositionListener.h \
$(NULL)
MODULE=dom

View File

@ -0,0 +1,42 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIDOMCompositionListener_h__
#define nsIDOMCompositionListener_h__
#include "nsIDOMEvent.h"
#include "nsIDOMEventListener.h"
/*
* Key pressed / released / typed listener interface.
*/
// {F14B6491-E95B-11d2-9E85-0060089FE59B}
#define NS_IDOMCOMPOSITIONLISTENER_IID \
{ 0xf14b6491, 0xe95b, 0x11d2, \
{ 0x9e, 0x85, 0x0, 0x60, 0x8, 0x9f, 0xe5, 0x9b } }
class nsIDOMCompositionListener : public nsIDOMEventListener {
public:
virtual nsresult HandleStartComposition(nsIDOMEvent* aCompositionEvent) = 0;
virtual nsresult HandleEndComposition(nsIDOMEvent* aCompositionEvent) = 0;
};
#endif // nsIDOMCompositionListener_h__

View File

@ -1079,7 +1079,7 @@ extern "C" NS_DOM nsresult NS_InitRangeClass(nsIScriptContext *aContext, void **
//
// Method for creating a new Range JavaScript object
//
extern "C" NS_DOM nsresult NS_NewScriptRange(nsIScriptContext *aContext, nsISupports *aSupports, nsISupports *aParent, void **aReturn)
NS_DOM nsresult NS_NewScriptRange(nsIScriptContext *aContext, nsISupports *aSupports, nsISupports *aParent, void **aReturn)
{
NS_PRECONDITION(nsnull != aContext && nsnull != aSupports && nsnull != aReturn, "null argument to NS_NewScriptRange");
JSObject *proto;

View File

@ -61,7 +61,6 @@
#include "DeleteRangeTxn.h"
#include "SplitElementTxn.h"
#include "JoinElementTxn.h"
#include "nsIStringStream.h"
#define HACK_FORCE_REDRAW 1
@ -130,6 +129,7 @@ static NS_DEFINE_IID(kSplitElementTxnIID, SPLIT_ELEMENT_TXN_IID);
static NS_DEFINE_IID(kJoinElementTxnIID, JOIN_ELEMENT_TXN_IID);
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
static NS_DEFINE_CID(kCDOMRangeCID, NS_RANGE_CID);
#ifdef XP_PC
#define TRANSACTION_MANAGER_DLL "txmgr.dll"
@ -294,10 +294,12 @@ nsEditor::nsEditor()
{
//initialize member variables here
NS_INIT_REFCNT();
mIMEFirstTransaction=PR_FALSE;
PR_EnterMonitor(getEditorMonitor());
gInstanceCount++;
mActionListeners = 0;
PR_ExitMonitor(getEditorMonitor());
}
@ -2286,6 +2288,94 @@ NS_IMETHODIMP nsEditor::GetLayoutObject(nsIDOMNode *aNode, nsISupports **aLayout
return result;
}
NS_IMETHODIMP
nsEditor::BeginComposition(void)
{
if ((nsITransactionManager *)nsnull!=mTxnMgr.get())
{
#ifdef DEBUG_tague
printf("nsEditor::StartComposition -- begin batch.\n");
#endif
mTxnMgr->BeginBatch();
}
if (!mIMESelectionRange)
{
nsresult result = nsComponentManager::CreateInstance(kCDOMRangeCID, nsnull,
nsIDOMRange::GetIID(),
getter_AddRefs(mIMESelectionRange));
if (NS_FAILED(result))
{
mTxnMgr->EndBatch();
return result;
}
}
mIMEFirstTransaction=PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsEditor::EndComposition(void)
{
if ((nsITransactionManager *)nsnull!=mTxnMgr.get())
{
#ifdef DEBUG_tague
printf("nsEditor::EndComposition -- end batch.\n");
#endif
mTxnMgr->EndBatch();
mIMEFirstTransaction=PR_TRUE;
return NS_OK;
}
// mIMESelectionRange = nsCOMPtr<nsIDOMRange>();
return NS_OK;
}
NS_IMETHODIMP
nsEditor::SetCompositionString(const nsString& aCompositionString)
{
if (mIMEFirstTransaction==PR_TRUE) {
mIMEFirstTransaction = PR_FALSE;
} else {
// printf("Undo!\n");
// mTxnMgr->Undo();
nsCOMPtr<nsIDOMSelection> selection;
nsresult result;
result = mPresShell->GetSelection(getter_AddRefs(selection));
if (NS_FAILED(result))
{
return result;
}
nsCOMPtr<nsIDOMNode> node;
PRInt32 offset;
result = mIMESelectionRange->GetStartParent(getter_AddRefs(node));
result = mIMESelectionRange->GetStartOffset(&offset);
result = selection->Collapse(node, offset);
result = mIMESelectionRange->GetEndParent(getter_AddRefs(node));
result = mIMESelectionRange->GetEndOffset(&offset);
result = selection->Extend(node, offset);
}
#ifdef DEBUG_tague
printf("nsEditor::SetCompositionString: string=%s\n",aCompositionString);
#endif
return SetPreeditText(aCompositionString);
}
NS_IMETHODIMP
nsEditor::DebugDumpContent() const
{
@ -2345,7 +2435,169 @@ NS_IMETHODIMP GetColIndexForCell(nsIPresShell *aPresShell, nsIDOMNode *aCellNode
/* ----- END TEST METHODS ----- */
NS_IMETHODIMP nsEditor::DoInitialPreeeditInsert(const nsString& aStringToInsert)
{
if (!mDoc) {
return NS_ERROR_NOT_INITIALIZED;
}
nsCOMPtr<nsIDOMNodeList>nodeList;
nsAutoString bodyTag = "body";
nsresult result = mDoc->GetElementsByTagName(bodyTag, getter_AddRefs(nodeList));
if ((NS_SUCCEEDED(result)) && nodeList)
{
PRUint32 count;
nodeList->GetLength(&count);
NS_ASSERTION(1==count, "there is not exactly 1 body in the document!");
nsCOMPtr<nsIDOMNode>node;
result = nodeList->Item(0, getter_AddRefs(node));
if ((NS_SUCCEEDED(result)) && node)
{ // now we've got the body tag.
// create transaction to insert the text node,
// and create a transaction to insert the text
CreateElementTxn *txn;
result = CreateTxnForCreateElement(GetTextNodeTag(), node, 0, &txn);
if ((NS_SUCCEEDED(result)) && txn)
{
result = Do(txn);
if (NS_SUCCEEDED(result))
{
nsCOMPtr<nsIDOMNode>newNode;
txn->GetNewNode(getter_AddRefs(newNode));
if ((NS_SUCCEEDED(result)) && newNode)
{
nsCOMPtr<nsIDOMCharacterData>newTextNode;
newTextNode = do_QueryInterface(newNode);
if (newTextNode)
{
InsertTextTxn *insertTxn;
result = CreateTxnForInsertText(aStringToInsert, newTextNode, &insertTxn);
if (NS_SUCCEEDED(result)) {
result = Do(insertTxn);
}
}
else {
result = NS_ERROR_UNEXPECTED;
}
}
}
}
}
}
return result;
}
NS_IMETHODIMP
nsEditor::SetPreeditText(const nsString& aStringToInsert)
{
nsresult result;
EditAggregateTxn *aggTxn = nsnull;
// Create the "delete current selection" txn
nsCOMPtr<nsIDOMSelection> selection;
BeginTransaction();
result = mPresShell->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result) && selection)
{
PRBool collapsed;
result = selection->GetIsCollapsed(&collapsed);
if (NS_SUCCEEDED(result) && !collapsed) {
EditAggregateTxn *delSelTxn;
result = CreateTxnForDeleteSelection(nsIEditor::eLTR, &delSelTxn);
if (NS_SUCCEEDED(result) && delSelTxn) {
result = Do(delSelTxn);
if (NS_FAILED(result)) {
EndTransaction();
return result;
}
}
}
}
result = mPresShell->GetSelection(getter_AddRefs(selection));
if (NS_FAILED(result))
{
EndTransaction();
return result;
}
nsCOMPtr<nsIDOMRange> startRange;
nsCOMPtr<nsIDOMRange> endRange;
result = selection->GetRangeAt(0, getter_AddRefs(startRange));
if (NS_FAILED(result))
{
EndTransaction();
return result;
}
InsertTextTxn *txn;
result = CreateTxnForInsertText(aStringToInsert, nsnull, &txn); // insert at the current selection
if ((NS_SUCCEEDED(result)) && txn) {
result = Do(txn);
}
else if (NS_ERROR_EDITOR_NO_SELECTION==result) {
result = DoInitialInsert(aStringToInsert);
}
else if (NS_ERROR_EDITOR_NO_TEXTNODE==result)
{
nsCOMPtr<nsIDOMSelection> selection;
result = GetSelection(getter_AddRefs(selection));
if ((NS_SUCCEEDED(result)) && selection)
{
nsCOMPtr<nsIDOMNode> selectedNode;
PRInt32 offset;
result = selection->GetAnchorNode(getter_AddRefs(selectedNode));
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(selection->GetAnchorOffset(&offset)) && selectedNode)
{
nsCOMPtr<nsIDOMNode> newNode;
result = CreateNode(GetTextNodeTag(), selectedNode, offset+1,
getter_AddRefs(newNode));
if (NS_SUCCEEDED(result) && newNode)
{
nsCOMPtr<nsIDOMCharacterData>newTextNode;
newTextNode = do_QueryInterface(newNode);
if (newTextNode)
{
nsAutoString placeholderText(" ");
newTextNode->SetData(placeholderText);
selection->Collapse(newNode, 0);
selection->Extend(newNode, 1);
result = SetPreeditText(aStringToInsert);
}
}
}
}
}
result = mPresShell->GetSelection(getter_AddRefs(selection));
if (NS_FAILED(result))
{
EndTransaction();
return result;
}
result = selection->GetRangeAt(0, getter_AddRefs(endRange));
nsCOMPtr<nsIDOMNode> node;
PRInt32 offset;
startRange->GetStartParent(getter_AddRefs(node));
startRange->GetStartOffset(&offset);
mIMESelectionRange->SetStart(node, offset);
endRange->GetStartParent(getter_AddRefs(node));
endRange->GetStartOffset(&offset);
mIMESelectionRange->SetEnd(node, offset);
EndTransaction();
return result;
}

View File

@ -25,6 +25,7 @@
#include "nsIContextLoader.h"
#include "nsIDOMDocument.h"
#include "nsIDOMEventListener.h"
#include "nsIDOMRange.h"
#include "nsCOMPtr.h"
#include "nsITransactionManager.h"
#include "TransactionFactory.h"
@ -63,6 +64,7 @@ private:
PRUint32 mUpdateCount;
nsCOMPtr<nsITransactionManager> mTxnMgr;
nsCOMPtr<nsIDOMRange> mIMESelectionRange;
friend PRBool NSCanUnload(nsISupports* serviceMgr);
static PRInt32 gInstanceCount;
@ -124,6 +126,12 @@ public:
nsIDOMNode * aParent,
PRInt32 aPosition);
NS_IMETHOD InsertText(const nsString& aStringToInsert);
NS_IMETHOD BeginComposition(void);
NS_IMETHOD SetCompositionString(const nsString& aCompositionString);
NS_IMETHOD EndComposition(void);
NS_IMETHOD DeleteNode(nsIDOMNode * aChild);
@ -304,14 +312,21 @@ protected:
NS_IMETHOD DebugDumpContent() const;
NS_IMETHODIMP SetPreeditText(const nsString& aStringToInsert);
NS_IMETHODIMP DoInitialPreeeditInsert(const nsString& aStringToInsert);
protected:
// XXXX: Horrible hack! We are doing this because
// of an error in Gecko which is not rendering the
// document after a change via the DOM - gpk 2/13/99
void HACKForceRedraw(void);
PRBool mIMEFirstTransaction;
NS_IMETHOD DeleteSelectionAndPrepareToCreateNode(nsCOMPtr<nsIDOMNode> &parentSelectedNode, PRInt32& offsetOfNewNode);
};

View File

@ -871,34 +871,10 @@ nsresult
nsTextEditorTextListener::HandleText(nsIDOMEvent* aTextEvent)
{
nsString composedText;
const PRUnichar* composedTextAsChar;
PRBool commitText;
nsresult result;
aTextEvent->GetText(composedText);
composedTextAsChar = (const PRUnichar*)(&composedText);
if (!mInTransaction) {
// mEditor->BeginTransaction();
mInTransaction = PR_TRUE;
}
aTextEvent->GetCommitText(&commitText);
if (commitText) {
mEditor->Undo(1);
result = mEditor->InsertText(composedText);
// result = mEditor->EndTransaction();
mInTransaction=PR_FALSE;
mCommitText = PR_TRUE;
} else {
if (!mCommitText) {
mEditor->Undo(1);
} else {
mCommitText = PR_FALSE;
}
result = mEditor->InsertText(composedText);
}
result = mEditor->SetCompositionString(composedText);
return result;
}
@ -1029,6 +1005,64 @@ nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent)
return NS_OK;
}
nsTextEditorCompositionListener::nsTextEditorCompositionListener()
{
NS_INIT_REFCNT();
}
nsTextEditorCompositionListener::~nsTextEditorCompositionListener()
{
}
nsresult
nsTextEditorCompositionListener::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (nsnull == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
static NS_DEFINE_IID(kIDOMCompositionListenerIID, NS_IDOMCOMPOSITIONLISTENER_IID);
static NS_DEFINE_IID(kIDOMEventListenerIID, NS_IDOMEVENTLISTENER_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMEventListenerIID)) {
*aInstancePtr = (void*)(nsIDOMEventListener*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMCompositionListenerIID)) {
*aInstancePtr = (void*)(nsIDOMCompositionListener*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsTextEditorCompositionListener)
NS_IMPL_RELEASE(nsTextEditorCompositionListener)
nsresult
nsTextEditorCompositionListener::HandleEvent(nsIDOMEvent* aEvent)
{
return NS_OK;
}
nsresult
nsTextEditorCompositionListener::HandleStartComposition(nsIDOMEvent* aCompositionEvent)
{
return mEditor->BeginComposition();
}
nsresult
nsTextEditorCompositionListener::HandleEndComposition(nsIDOMEvent* aCompositionEvent)
{
return mEditor->EndComposition();
}
/*
@ -1104,5 +1138,18 @@ NS_NewEditorDragListener(nsIDOMEventListener ** aInstancePtrResult,
return it->QueryInterface(kIDOMEventListenerIID, (void **) aInstancePtrResult);
}
nsresult
NS_NewEditorCompositionListener(nsIDOMEventListener** aInstancePtrResult, nsITextEditor* aEditor)
{
nsTextEditorCompositionListener* it = new nsTextEditorCompositionListener();
if (nsnull==it) {
return NS_ERROR_OUT_OF_MEMORY;
}
it->SetEditor(aEditor);
static NS_DEFINE_IID(kIDOMEventListenerIID, NS_IDOMEVENTLISTENER_IID);
return it->QueryInterface(kIDOMEventListenerIID, (void **) aInstancePtrResult);
}

View File

@ -24,6 +24,7 @@
#include "nsIDOMMouseListener.h"
#include "nsIDOMTextListener.h"
#include "nsIDOMDragListener.h"
#include "nsIDOMCompositionListener.h"
#include "nsITextEditor.h"
#include "nsCOMPtr.h"
@ -68,7 +69,7 @@ protected:
/** editor Implementation of the MouseListener interface
*/
class nsTextEditorTextListener : public nsIDOMTextListener
class nsTextEditorTextListener : public nsIDOMTextListener
{
public:
/** default constructor
@ -98,6 +99,35 @@ protected:
PRBool mInTransaction;
};
class nsTextEditorCompositionListener : public nsIDOMCompositionListener
{
public:
/** default constructor
*/
nsTextEditorCompositionListener();
/** default destructor
*/
virtual ~nsTextEditorCompositionListener();
/** SetEditor gives an address to the editor that will be accessed
* @param aEditor the editor this listener calls for editing operations
*/
void SetEditor(nsITextEditor *aEditor){mEditor = do_QueryInterface(aEditor);}
/*interfaces for addref and release and queryinterface*/
NS_DECL_ISUPPORTS
/*BEGIN implementations of textevent handler interface*/
virtual nsresult HandleEvent(nsIDOMEvent* aEvent);
public:
virtual nsresult HandleStartComposition(nsIDOMEvent* aCompositionEvent);
virtual nsresult HandleEndComposition(nsIDOMEvent* aCompositionEvent);
/*END implementations of textevent handler interface*/
protected:
nsCOMPtr<nsITextEditor> mEditor;
};
/** editor Implementation of the TextListener interface
*/
@ -187,5 +217,8 @@ extern nsresult NS_NewEditorTextListener(nsIDOMEventListener** aInstancePtrResul
*/
extern nsresult NS_NewEditorDragListener(nsIDOMEventListener ** aInstancePtrResult, nsITextEditor *aEditor);
/** factory for the editor composition listener
*/
extern nsresult NS_NewEditorCompositionListener(nsIDOMEventListener** aInstancePtrResult, nsITextEditor *aEditor);
#endif //editorInterfaces_h__

View File

@ -1330,3 +1330,18 @@ nsHTMLEditor::InsertElement(nsIDOMElement* aElement, PRBool aDeleteSelection, ns
return result;
}
NS_IMETHODIMP nsHTMLEditor::BeginComposition(void)
{
return nsTextEditor::BeginComposition();
}
NS_IMETHODIMP nsHTMLEditor::EndComposition(void)
{
return nsTextEditor::EndComposition();
}
NS_IMETHODIMP nsHTMLEditor::SetCompositionString(const nsString& aCompositionString)
{
return nsTextEditor::SetCompositionString(aCompositionString);
}

View File

@ -93,6 +93,9 @@ public:
// Input/Output
NS_IMETHOD Insert(nsString& aInputString);
NS_IMETHOD BeginComposition(void);
NS_IMETHOD SetCompositionString(const nsString& aCompositionString);
NS_IMETHOD EndComposition(void);
NS_IMETHOD OutputText(nsString& aOutputString);
NS_IMETHOD OutputHTML(nsString& aOutputString);
NS_IMETHOD OutputText(nsIOutputStream* aOutputStream,nsString* aCharsetOverride = nsnull);

View File

@ -75,6 +75,7 @@ static NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID);
static NS_DEFINE_IID(kIDOMMouseListenerIID, NS_IDOMMOUSELISTENER_IID);
static NS_DEFINE_IID(kIDOMKeyListenerIID, NS_IDOMKEYLISTENER_IID);
static NS_DEFINE_IID(kIDOMTextListenerIID, NS_IDOMTEXTLISTENER_IID);
static NS_DEFINE_IID(kIDOMCompositionListenerIID, NS_IDOMCOMPOSITIONLISTENER_IID);
static NS_DEFINE_IID(kIDOMDragListenerIID, NS_IDOMDRAGLISTENER_IID);
static NS_DEFINE_IID(kIDOMSelectionListenerIID, NS_IDOMSELECTIONLISTENER_IID);
@ -170,7 +171,11 @@ nsTextEditor::~nsTextEditor()
erP->RemoveEventListenerByIID(mTextListenerP, kIDOMTextListenerIID);
}
if (mDragListenerP) {
if (mCompositionListenerP) {
erP->RemoveEventListenerByIID(mCompositionListenerP, kIDOMCompositionListenerIID);
}
if (mDragListenerP) {
erP->RemoveEventListenerByIID(mDragListenerP, kIDOMDragListenerIID);
}
@ -265,12 +270,25 @@ NS_IMETHODIMP nsTextEditor::Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell)
return result;
}
result = NS_NewEditorCompositionListener(getter_AddRefs(mCompositionListenerP),this);
if (NS_OK!=result) {
// drop the key and mouse listeners
#ifdef DEBUG_TAGUE
printf("nsTextEditor.cpp: failed to get TextEvent Listener\n");
#endif
mMouseListenerP = do_QueryInterface(0);
mKeyListenerP = do_QueryInterface(0);
mTextListenerP = do_QueryInterface(0);
return result;
}
result = NS_NewEditorDragListener(getter_AddRefs(mDragListenerP), this);
if (NS_OK != result) {
//return result;
mMouseListenerP = do_QueryInterface(0);
mKeyListenerP = do_QueryInterface(0);
mTextListenerP = do_QueryInterface(0);
mCompositionListenerP = do_QueryInterface(0);
}
nsCOMPtr<nsIDOMEventReceiver> erP;
@ -279,8 +297,9 @@ NS_IMETHODIMP nsTextEditor::Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell)
{
mKeyListenerP = do_QueryInterface(0);
mMouseListenerP = do_QueryInterface(0); //dont need these if we cant register them
mTextListenerP = do_QueryInterface(0);
mTextListenerP = do_QueryInterface(0);
mDragListenerP = do_QueryInterface(0); //dont need these if we cant register them
mCompositionListenerP = do_QueryInterface(0);
return result;
}
//cmanske: Shouldn't we check result from this?
@ -289,6 +308,7 @@ NS_IMETHODIMP nsTextEditor::Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell)
//erP->AddEventListener(mMouseListenerP, kIDOMMouseListenerIID);
erP->AddEventListenerByIID(mTextListenerP,kIDOMTextListenerIID);
erP->AddEventListenerByIID(mCompositionListenerP,kIDOMCompositionListenerIID);
result = NS_OK;
@ -2371,3 +2391,21 @@ nsTextEditor::CopyAttributes(nsIDOMNode *aDestNode, nsIDOMNode *aSourceNode)
{
return nsEditor::CopyAttributes(aDestNode, aSourceNode);
}
NS_IMETHODIMP
nsTextEditor::BeginComposition(void)
{
return nsEditor::BeginComposition();
}
NS_IMETHODIMP
nsTextEditor::SetCompositionString(const nsString& aCompositionString)
{
return nsEditor::SetCompositionString(aCompositionString);
}
NS_IMETHODIMP
nsTextEditor::EndComposition(void)
{
return nsEditor::EndComposition();
}

View File

@ -96,6 +96,9 @@ public:
// Input/Output
NS_IMETHOD Insert(nsString& aInputString);
NS_IMETHOD BeginComposition(void);
NS_IMETHOD SetCompositionString(const nsString& aCompositionString);
NS_IMETHOD EndComposition(void);
NS_IMETHOD OutputText(nsString& aOutputString);
NS_IMETHOD OutputHTML(nsString& aOutputString);
NS_IMETHOD OutputText(nsIOutputStream* aOutputStream, nsString* aCharsetOverride);
@ -283,7 +286,9 @@ protected:
nsCOMPtr<nsIDOMEventListener> mKeyListenerP;
nsCOMPtr<nsIDOMEventListener> mMouseListenerP;
nsCOMPtr<nsIDOMEventListener> mTextListenerP;
nsCOMPtr<nsIDOMEventListener> mCompositionListenerP;
nsCOMPtr<nsIDOMEventListener> mDragListenerP;
PRBool mIsComposing;
// friends
friend class nsTextEditRules;

View File

@ -61,7 +61,6 @@
#include "DeleteRangeTxn.h"
#include "SplitElementTxn.h"
#include "JoinElementTxn.h"
#include "nsIStringStream.h"
#define HACK_FORCE_REDRAW 1
@ -130,6 +129,7 @@ static NS_DEFINE_IID(kSplitElementTxnIID, SPLIT_ELEMENT_TXN_IID);
static NS_DEFINE_IID(kJoinElementTxnIID, JOIN_ELEMENT_TXN_IID);
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
static NS_DEFINE_CID(kCDOMRangeCID, NS_RANGE_CID);
#ifdef XP_PC
#define TRANSACTION_MANAGER_DLL "txmgr.dll"
@ -294,10 +294,12 @@ nsEditor::nsEditor()
{
//initialize member variables here
NS_INIT_REFCNT();
mIMEFirstTransaction=PR_FALSE;
PR_EnterMonitor(getEditorMonitor());
gInstanceCount++;
mActionListeners = 0;
PR_ExitMonitor(getEditorMonitor());
}
@ -2286,6 +2288,94 @@ NS_IMETHODIMP nsEditor::GetLayoutObject(nsIDOMNode *aNode, nsISupports **aLayout
return result;
}
NS_IMETHODIMP
nsEditor::BeginComposition(void)
{
if ((nsITransactionManager *)nsnull!=mTxnMgr.get())
{
#ifdef DEBUG_tague
printf("nsEditor::StartComposition -- begin batch.\n");
#endif
mTxnMgr->BeginBatch();
}
if (!mIMESelectionRange)
{
nsresult result = nsComponentManager::CreateInstance(kCDOMRangeCID, nsnull,
nsIDOMRange::GetIID(),
getter_AddRefs(mIMESelectionRange));
if (NS_FAILED(result))
{
mTxnMgr->EndBatch();
return result;
}
}
mIMEFirstTransaction=PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsEditor::EndComposition(void)
{
if ((nsITransactionManager *)nsnull!=mTxnMgr.get())
{
#ifdef DEBUG_tague
printf("nsEditor::EndComposition -- end batch.\n");
#endif
mTxnMgr->EndBatch();
mIMEFirstTransaction=PR_TRUE;
return NS_OK;
}
// mIMESelectionRange = nsCOMPtr<nsIDOMRange>();
return NS_OK;
}
NS_IMETHODIMP
nsEditor::SetCompositionString(const nsString& aCompositionString)
{
if (mIMEFirstTransaction==PR_TRUE) {
mIMEFirstTransaction = PR_FALSE;
} else {
// printf("Undo!\n");
// mTxnMgr->Undo();
nsCOMPtr<nsIDOMSelection> selection;
nsresult result;
result = mPresShell->GetSelection(getter_AddRefs(selection));
if (NS_FAILED(result))
{
return result;
}
nsCOMPtr<nsIDOMNode> node;
PRInt32 offset;
result = mIMESelectionRange->GetStartParent(getter_AddRefs(node));
result = mIMESelectionRange->GetStartOffset(&offset);
result = selection->Collapse(node, offset);
result = mIMESelectionRange->GetEndParent(getter_AddRefs(node));
result = mIMESelectionRange->GetEndOffset(&offset);
result = selection->Extend(node, offset);
}
#ifdef DEBUG_tague
printf("nsEditor::SetCompositionString: string=%s\n",aCompositionString);
#endif
return SetPreeditText(aCompositionString);
}
NS_IMETHODIMP
nsEditor::DebugDumpContent() const
{
@ -2345,7 +2435,169 @@ NS_IMETHODIMP GetColIndexForCell(nsIPresShell *aPresShell, nsIDOMNode *aCellNode
/* ----- END TEST METHODS ----- */
NS_IMETHODIMP nsEditor::DoInitialPreeeditInsert(const nsString& aStringToInsert)
{
if (!mDoc) {
return NS_ERROR_NOT_INITIALIZED;
}
nsCOMPtr<nsIDOMNodeList>nodeList;
nsAutoString bodyTag = "body";
nsresult result = mDoc->GetElementsByTagName(bodyTag, getter_AddRefs(nodeList));
if ((NS_SUCCEEDED(result)) && nodeList)
{
PRUint32 count;
nodeList->GetLength(&count);
NS_ASSERTION(1==count, "there is not exactly 1 body in the document!");
nsCOMPtr<nsIDOMNode>node;
result = nodeList->Item(0, getter_AddRefs(node));
if ((NS_SUCCEEDED(result)) && node)
{ // now we've got the body tag.
// create transaction to insert the text node,
// and create a transaction to insert the text
CreateElementTxn *txn;
result = CreateTxnForCreateElement(GetTextNodeTag(), node, 0, &txn);
if ((NS_SUCCEEDED(result)) && txn)
{
result = Do(txn);
if (NS_SUCCEEDED(result))
{
nsCOMPtr<nsIDOMNode>newNode;
txn->GetNewNode(getter_AddRefs(newNode));
if ((NS_SUCCEEDED(result)) && newNode)
{
nsCOMPtr<nsIDOMCharacterData>newTextNode;
newTextNode = do_QueryInterface(newNode);
if (newTextNode)
{
InsertTextTxn *insertTxn;
result = CreateTxnForInsertText(aStringToInsert, newTextNode, &insertTxn);
if (NS_SUCCEEDED(result)) {
result = Do(insertTxn);
}
}
else {
result = NS_ERROR_UNEXPECTED;
}
}
}
}
}
}
return result;
}
NS_IMETHODIMP
nsEditor::SetPreeditText(const nsString& aStringToInsert)
{
nsresult result;
EditAggregateTxn *aggTxn = nsnull;
// Create the "delete current selection" txn
nsCOMPtr<nsIDOMSelection> selection;
BeginTransaction();
result = mPresShell->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(result) && selection)
{
PRBool collapsed;
result = selection->GetIsCollapsed(&collapsed);
if (NS_SUCCEEDED(result) && !collapsed) {
EditAggregateTxn *delSelTxn;
result = CreateTxnForDeleteSelection(nsIEditor::eLTR, &delSelTxn);
if (NS_SUCCEEDED(result) && delSelTxn) {
result = Do(delSelTxn);
if (NS_FAILED(result)) {
EndTransaction();
return result;
}
}
}
}
result = mPresShell->GetSelection(getter_AddRefs(selection));
if (NS_FAILED(result))
{
EndTransaction();
return result;
}
nsCOMPtr<nsIDOMRange> startRange;
nsCOMPtr<nsIDOMRange> endRange;
result = selection->GetRangeAt(0, getter_AddRefs(startRange));
if (NS_FAILED(result))
{
EndTransaction();
return result;
}
InsertTextTxn *txn;
result = CreateTxnForInsertText(aStringToInsert, nsnull, &txn); // insert at the current selection
if ((NS_SUCCEEDED(result)) && txn) {
result = Do(txn);
}
else if (NS_ERROR_EDITOR_NO_SELECTION==result) {
result = DoInitialInsert(aStringToInsert);
}
else if (NS_ERROR_EDITOR_NO_TEXTNODE==result)
{
nsCOMPtr<nsIDOMSelection> selection;
result = GetSelection(getter_AddRefs(selection));
if ((NS_SUCCEEDED(result)) && selection)
{
nsCOMPtr<nsIDOMNode> selectedNode;
PRInt32 offset;
result = selection->GetAnchorNode(getter_AddRefs(selectedNode));
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(selection->GetAnchorOffset(&offset)) && selectedNode)
{
nsCOMPtr<nsIDOMNode> newNode;
result = CreateNode(GetTextNodeTag(), selectedNode, offset+1,
getter_AddRefs(newNode));
if (NS_SUCCEEDED(result) && newNode)
{
nsCOMPtr<nsIDOMCharacterData>newTextNode;
newTextNode = do_QueryInterface(newNode);
if (newTextNode)
{
nsAutoString placeholderText(" ");
newTextNode->SetData(placeholderText);
selection->Collapse(newNode, 0);
selection->Extend(newNode, 1);
result = SetPreeditText(aStringToInsert);
}
}
}
}
}
result = mPresShell->GetSelection(getter_AddRefs(selection));
if (NS_FAILED(result))
{
EndTransaction();
return result;
}
result = selection->GetRangeAt(0, getter_AddRefs(endRange));
nsCOMPtr<nsIDOMNode> node;
PRInt32 offset;
startRange->GetStartParent(getter_AddRefs(node));
startRange->GetStartOffset(&offset);
mIMESelectionRange->SetStart(node, offset);
endRange->GetStartParent(getter_AddRefs(node));
endRange->GetStartOffset(&offset);
mIMESelectionRange->SetEnd(node, offset);
EndTransaction();
return result;
}

View File

@ -25,6 +25,7 @@
#include "nsIContextLoader.h"
#include "nsIDOMDocument.h"
#include "nsIDOMEventListener.h"
#include "nsIDOMRange.h"
#include "nsCOMPtr.h"
#include "nsITransactionManager.h"
#include "TransactionFactory.h"
@ -63,6 +64,7 @@ private:
PRUint32 mUpdateCount;
nsCOMPtr<nsITransactionManager> mTxnMgr;
nsCOMPtr<nsIDOMRange> mIMESelectionRange;
friend PRBool NSCanUnload(nsISupports* serviceMgr);
static PRInt32 gInstanceCount;
@ -124,6 +126,12 @@ public:
nsIDOMNode * aParent,
PRInt32 aPosition);
NS_IMETHOD InsertText(const nsString& aStringToInsert);
NS_IMETHOD BeginComposition(void);
NS_IMETHOD SetCompositionString(const nsString& aCompositionString);
NS_IMETHOD EndComposition(void);
NS_IMETHOD DeleteNode(nsIDOMNode * aChild);
@ -304,14 +312,21 @@ protected:
NS_IMETHOD DebugDumpContent() const;
NS_IMETHODIMP SetPreeditText(const nsString& aStringToInsert);
NS_IMETHODIMP DoInitialPreeeditInsert(const nsString& aStringToInsert);
protected:
// XXXX: Horrible hack! We are doing this because
// of an error in Gecko which is not rendering the
// document after a change via the DOM - gpk 2/13/99
void HACKForceRedraw(void);
PRBool mIMEFirstTransaction;
NS_IMETHOD DeleteSelectionAndPrepareToCreateNode(nsCOMPtr<nsIDOMNode> &parentSelectedNode, PRInt32& offsetOfNewNode);
};

View File

@ -1330,3 +1330,18 @@ nsHTMLEditor::InsertElement(nsIDOMElement* aElement, PRBool aDeleteSelection, ns
return result;
}
NS_IMETHODIMP nsHTMLEditor::BeginComposition(void)
{
return nsTextEditor::BeginComposition();
}
NS_IMETHODIMP nsHTMLEditor::EndComposition(void)
{
return nsTextEditor::EndComposition();
}
NS_IMETHODIMP nsHTMLEditor::SetCompositionString(const nsString& aCompositionString)
{
return nsTextEditor::SetCompositionString(aCompositionString);
}

View File

@ -93,6 +93,9 @@ public:
// Input/Output
NS_IMETHOD Insert(nsString& aInputString);
NS_IMETHOD BeginComposition(void);
NS_IMETHOD SetCompositionString(const nsString& aCompositionString);
NS_IMETHOD EndComposition(void);
NS_IMETHOD OutputText(nsString& aOutputString);
NS_IMETHOD OutputHTML(nsString& aOutputString);
NS_IMETHOD OutputText(nsIOutputStream* aOutputStream,nsString* aCharsetOverride = nsnull);

View File

@ -871,34 +871,10 @@ nsresult
nsTextEditorTextListener::HandleText(nsIDOMEvent* aTextEvent)
{
nsString composedText;
const PRUnichar* composedTextAsChar;
PRBool commitText;
nsresult result;
aTextEvent->GetText(composedText);
composedTextAsChar = (const PRUnichar*)(&composedText);
if (!mInTransaction) {
// mEditor->BeginTransaction();
mInTransaction = PR_TRUE;
}
aTextEvent->GetCommitText(&commitText);
if (commitText) {
mEditor->Undo(1);
result = mEditor->InsertText(composedText);
// result = mEditor->EndTransaction();
mInTransaction=PR_FALSE;
mCommitText = PR_TRUE;
} else {
if (!mCommitText) {
mEditor->Undo(1);
} else {
mCommitText = PR_FALSE;
}
result = mEditor->InsertText(composedText);
}
result = mEditor->SetCompositionString(composedText);
return result;
}
@ -1029,6 +1005,64 @@ nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent)
return NS_OK;
}
nsTextEditorCompositionListener::nsTextEditorCompositionListener()
{
NS_INIT_REFCNT();
}
nsTextEditorCompositionListener::~nsTextEditorCompositionListener()
{
}
nsresult
nsTextEditorCompositionListener::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (nsnull == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
static NS_DEFINE_IID(kIDOMCompositionListenerIID, NS_IDOMCOMPOSITIONLISTENER_IID);
static NS_DEFINE_IID(kIDOMEventListenerIID, NS_IDOMEVENTLISTENER_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMEventListenerIID)) {
*aInstancePtr = (void*)(nsIDOMEventListener*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMCompositionListenerIID)) {
*aInstancePtr = (void*)(nsIDOMCompositionListener*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsTextEditorCompositionListener)
NS_IMPL_RELEASE(nsTextEditorCompositionListener)
nsresult
nsTextEditorCompositionListener::HandleEvent(nsIDOMEvent* aEvent)
{
return NS_OK;
}
nsresult
nsTextEditorCompositionListener::HandleStartComposition(nsIDOMEvent* aCompositionEvent)
{
return mEditor->BeginComposition();
}
nsresult
nsTextEditorCompositionListener::HandleEndComposition(nsIDOMEvent* aCompositionEvent)
{
return mEditor->EndComposition();
}
/*
@ -1104,5 +1138,18 @@ NS_NewEditorDragListener(nsIDOMEventListener ** aInstancePtrResult,
return it->QueryInterface(kIDOMEventListenerIID, (void **) aInstancePtrResult);
}
nsresult
NS_NewEditorCompositionListener(nsIDOMEventListener** aInstancePtrResult, nsITextEditor* aEditor)
{
nsTextEditorCompositionListener* it = new nsTextEditorCompositionListener();
if (nsnull==it) {
return NS_ERROR_OUT_OF_MEMORY;
}
it->SetEditor(aEditor);
static NS_DEFINE_IID(kIDOMEventListenerIID, NS_IDOMEVENTLISTENER_IID);
return it->QueryInterface(kIDOMEventListenerIID, (void **) aInstancePtrResult);
}

View File

@ -24,6 +24,7 @@
#include "nsIDOMMouseListener.h"
#include "nsIDOMTextListener.h"
#include "nsIDOMDragListener.h"
#include "nsIDOMCompositionListener.h"
#include "nsITextEditor.h"
#include "nsCOMPtr.h"
@ -68,7 +69,7 @@ protected:
/** editor Implementation of the MouseListener interface
*/
class nsTextEditorTextListener : public nsIDOMTextListener
class nsTextEditorTextListener : public nsIDOMTextListener
{
public:
/** default constructor
@ -98,6 +99,35 @@ protected:
PRBool mInTransaction;
};
class nsTextEditorCompositionListener : public nsIDOMCompositionListener
{
public:
/** default constructor
*/
nsTextEditorCompositionListener();
/** default destructor
*/
virtual ~nsTextEditorCompositionListener();
/** SetEditor gives an address to the editor that will be accessed
* @param aEditor the editor this listener calls for editing operations
*/
void SetEditor(nsITextEditor *aEditor){mEditor = do_QueryInterface(aEditor);}
/*interfaces for addref and release and queryinterface*/
NS_DECL_ISUPPORTS
/*BEGIN implementations of textevent handler interface*/
virtual nsresult HandleEvent(nsIDOMEvent* aEvent);
public:
virtual nsresult HandleStartComposition(nsIDOMEvent* aCompositionEvent);
virtual nsresult HandleEndComposition(nsIDOMEvent* aCompositionEvent);
/*END implementations of textevent handler interface*/
protected:
nsCOMPtr<nsITextEditor> mEditor;
};
/** editor Implementation of the TextListener interface
*/
@ -187,5 +217,8 @@ extern nsresult NS_NewEditorTextListener(nsIDOMEventListener** aInstancePtrResul
*/
extern nsresult NS_NewEditorDragListener(nsIDOMEventListener ** aInstancePtrResult, nsITextEditor *aEditor);
/** factory for the editor composition listener
*/
extern nsresult NS_NewEditorCompositionListener(nsIDOMEventListener** aInstancePtrResult, nsITextEditor *aEditor);
#endif //editorInterfaces_h__

View File

@ -178,6 +178,27 @@ public:
*/
NS_IMETHOD InsertText(const nsString& aStringToInsert)=0;
/**
* BeginComposition() Handles the start of inline input composition.
*/
NS_IMETHOD BeginComposition(void) = 0;
/**
* SetCompositionString() Sets the inline input composition string.
* BeginComposition must be called prior to this.
*/
NS_IMETHOD SetCompositionString(const nsString& aCompositionString) = 0;
/**
* BeginComposition() Handles the end of inline input composition.
*/
NS_IMETHOD EndComposition(void) = 0;
/**
* DeleteNode removes aChild from aParent.
* @param aChild The node to delete

View File

@ -83,7 +83,6 @@ public:
NS_IMETHOD Paste()=0;
NS_IMETHOD Insert(nsString &aInputString)=0;
NS_IMETHOD OutputText(nsString& aOutputString)=0;
NS_IMETHOD OutputHTML(nsString& aOutputString)=0;
@ -153,6 +152,12 @@ public:
NS_IMETHOD DeleteTableColumn(PRInt32 aNumber)=0;
NS_IMETHOD DeleteTableRow(PRInt32 aNumber)=0;
NS_IMETHOD JoinTableCells(PRBool aCellToRight)=0;
// IME editing Methods
NS_IMETHOD BeginComposition(void)=0;
NS_IMETHOD SetCompositionString(const nsString& aCompositionString)=0;
NS_IMETHOD EndComposition(void)=0;
};
#endif //nsIEditor_h__

View File

@ -289,6 +289,11 @@ public:
* trigger off of ContentChanged notifications.
*/
// IME Editing Methods
NS_IMETHOD BeginComposition(void)=0;
NS_IMETHOD SetCompositionString(const nsString& aCompositionString)=0;
NS_IMETHOD EndComposition(void)=0;
};
#endif //nsIEditor_h__

View File

@ -25,6 +25,7 @@
#include "nsIDOMDragListener.h"
#include "nsIDOMPaintListener.h"
#include "nsIDOMTextListener.h"
#include "nsIDOMCompositionListener.h"
NS_DEFINE_IID(kIDOMMouseListenerIID, NS_IDOMMOUSELISTENER_IID);
NS_DEFINE_IID(kIDOMKeyListenerIID, NS_IDOMKEYLISTENER_IID);
@ -35,3 +36,4 @@ NS_DEFINE_IID(kIDOMLoadListenerIID, NS_IDOMLOADLISTENER_IID);
NS_DEFINE_IID(kIDOMDragListenerIID, NS_IDOMDRAGLISTENER_IID);
NS_DEFINE_IID(kIDOMPaintListenerIID, NS_IDOMPAINTLISTENER_IID);
NS_DEFINE_IID(kIDOMTextListenerIID,NS_IDOMTEXTLISTENER_IID);
NS_DEFINE_IID(kIDOMCompositionListenerIID,NS_IDOMCOMPOSITIONLISTENER_IID);

View File

@ -29,5 +29,6 @@ extern const nsIID kIDOMLoadListenerIID;
extern const nsIID kIDOMDragListenerIID;
extern const nsIID kIDOMPaintListenerIID;
extern const nsIID kIDOMTextListenerIID;
extern const nsIID kIDOMCompositionListenerIID;
#endif /* nsDOMEVENTSIIDs_h___ */

View File

@ -31,6 +31,7 @@
#include "nsIDOMDragListener.h"
#include "nsIDOMPaintListener.h"
#include "nsIDOMTextListener.h"
#include "nsIDOMCompositionListener.h"
#include "nsIEventStateManager.h"
#include "nsIPrivateDOMEvent.h"
#include "nsIScriptObjectOwner.h"
@ -55,6 +56,7 @@ nsEventListenerManager::nsEventListenerManager()
mDragListeners = nsnull;
mPaintListeners = nsnull;
mTextListeners = nsnull;
mCompositionListeners = nsnull;
NS_INIT_REFCNT();
}
@ -70,6 +72,7 @@ nsEventListenerManager::~nsEventListenerManager()
ReleaseListeners(mDragListeners);
ReleaseListeners(mPaintListeners);
ReleaseListeners(mTextListeners);
ReleaseListeners(mCompositionListeners);
}
NS_IMPL_ADDREF(nsEventListenerManager)
@ -119,6 +122,9 @@ nsVoidArray** nsEventListenerManager::GetListenersByIID(const nsIID& aIID)
else if (aIID.Equals(kIDOMTextListenerIID)) {
return &mTextListeners;
}
else if (aIID.Equals(kIDOMCompositionListenerIID)) {
return &mCompositionListeners;
}
return nsnull;
}
@ -333,7 +339,7 @@ nsresult nsEventListenerManager::GetIdentifiersForType(const nsString& aType, ns
else if (aType == "paint") {
aIID = kIDOMPaintListenerIID;
*aFlags = NS_EVENT_BITS_PAINT_PAINT;
}
} // extened this to handle IME related events
else {
return NS_ERROR_FAILURE;
}
@ -607,6 +613,58 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
}
break;
case NS_COMPOSITION_START:
case NS_COMPOSITION_END:
#if DEBUG_TAGUE
printf("DOM: got composition event\n");
#endif
if (nsnull != mCompositionListeners) {
if (nsnull == *aDOMEvent) {
ret = NS_NewDOMEvent(aDOMEvent,aPresContext,aEvent);
}
if (NS_OK == ret) {
for(int i=0;i<mTextListeners->Count();i++) {
nsListenerStruct *ls;
nsIDOMCompositionListener* mCompositionListener;
ls =(nsListenerStruct*)mCompositionListeners->ElementAt(i);
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMCompositionListenerIID, (void**)&mCompositionListener)) {
if (aEvent->message==NS_COMPOSITION_START) {
ret = mCompositionListener->HandleStartComposition(*aDOMEvent);
}
if (aEvent->message==NS_COMPOSITION_END) {
ret = mCompositionListener->HandleEndComposition(*aDOMEvent);
}
}
NS_RELEASE(mCompositionListener);
}
else {
PRBool correctSubType = PR_FALSE;
switch(aEvent->message) {
case NS_COMPOSITION_START:
if (ls->mSubType & NS_EVENT_BITS_COMPOSITION_START) {
correctSubType = PR_TRUE;
}
break;
case NS_COMPOSITION_END:
if (ls->mSubType & NS_EVENT_BITS_COMPOSITION_END) {
correctSubType = PR_TRUE;
}
break;
default:
break;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
}
break;
case NS_TEXT_EVENT:
#if DEBUG_TAGUE
printf("DOM: got text event\n");

View File

@ -105,6 +105,7 @@ protected:
nsVoidArray* mDragListeners;
nsVoidArray* mPaintListeners;
nsVoidArray* mTextListeners;
nsVoidArray* mCompositionListeners;
};
@ -138,6 +139,11 @@ protected:
#define NS_EVENT_BITS_TEXT_NONE 0x00
#define NS_EVENT_BITS_TEXT_TEXT 0x01
//nsIDOMCompositionListener
#define NS_EVENT_BITS_COMPOSITION_NONE 0x00
#define NS_EVENT_BITS_COMPOSITION_START 0x01
#define NS_EVENT_BITS_COMPOSITION_END 0x02
//nsIDOMFocusListener
#define NS_EVENT_BITS_FOCUS_NONE 0x00
#define NS_EVENT_BITS_FOCUS_FOCUS 0x01

View File

@ -143,6 +143,10 @@ struct nsTextEvent : public nsInputEvent {
PRBool commitText;
};
struct nsCompositionEvent : public nsInputEvent {
PRUint32 compositionMessage;
};
struct nsTooltipEvent : public nsGUIEvent {
/// Index of tooltip area which generated the event. @see SetTooltips in nsIWidget
PRUint32 tipIndex;
@ -161,6 +165,18 @@ struct nsMenuEvent : public nsGUIEvent {
};
/**
* Event status for D&D Event
*/
enum nsDragDropEventStatus {
/// The event is a enter
nsDragDropEventStatus_eDragEntered,
/// The event is exit
nsDragDropEventStatus_eDragExited,
/// The event is drop
nsDragDropEventStatus_eDrop
};
/**
* Event Struct Types
*/
@ -175,7 +191,9 @@ struct nsMenuEvent : public nsGUIEvent {
#define NS_TOOLTIP_EVENT 9
#define NS_MENU_EVENT 10
#define NS_DRAGDROP_EVENT 11
#define NS_TEXT_EVENT 12
#define NS_TEXT_EVENT 12
#define NS_COMPOSITION_START 13
#define NS_COMPOSITION_END 14
/**
* GUI MESSAGES

View File

@ -2484,7 +2484,7 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
HIMC hIMEContext;
mIMEIsComposing = PR_TRUE;
#ifdef DEBUG_TAGUE
#ifdef DEBUG_TAGUE
printf("IME: Recieved WM_IME_STARTCOMPOSITION\n");
#endif
if ((mIMEProperty & IME_PROP_SPECIAL_UI) || (mIMEProperty & IME_PROP_AT_CARET)) {
@ -2503,6 +2503,7 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
::ImmSetCompositionWindow(hIMEContext,&compForm);
::ImmReleaseContext(mWnd,hIMEContext);
HandleStartComposition();
result = PR_TRUE;
}
break;
@ -2519,6 +2520,9 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
}
if (lParam & GCS_COMPSTR) {
#ifdef DEBUG_TAGUE
fprintf(stderr,"nsWindow::WM_IME_COMPOSITION: handling GCS_COMPSTR\n");
#endif
long compStrLen = ::ImmGetCompositionString(hIMEContext,GCS_COMPSTR,NULL,0);
if (compStrLen+1>mIMECompositionStringSize) {
if (mIMECompositionString!=NULL) delete [] mIMECompositionString;
@ -2534,6 +2538,9 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
}
if (lParam & GCS_RESULTSTR) {
#ifdef DEBUG_TAGUE
fprintf(stderr,"nsWindow::WM_IME_COMPOSITION: handling GCS_RESULTSTR\n");
#endif
long compStrLen = ::ImmGetCompositionString(hIMEContext,GCS_RESULTSTR,NULL,0);
if (compStrLen+1>mIMECompositionStringSize) {
delete [] mIMECompositionString;
@ -2546,13 +2553,9 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
mIMECompositionString[compStrLen]='\0';
result = PR_TRUE;
HandleTextEvent(PR_TRUE);
HandleEndComposition();
HandleStartComposition();
}
#ifdef DEBUG_TAGUE
if (lParam & GCS_COMPSTR)
printf("IME: Composition String = %s\n",mIMECompositionString);
if (lParam & GCS_RESULTSTR)
printf("IME: Result String = %s\n",mIMECompositionString);
#endif
::ImmReleaseContext(mWnd,hIMEContext);
@ -2565,6 +2568,7 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
#ifdef DEBUG_TAGUE
printf("IME: Received WM_IME_ENDCOMPOSITION\n");
#endif
HandleEndComposition();
result = PR_TRUE;
break;
@ -3136,3 +3140,35 @@ nsWindow::HandleTextEvent(PRBool commit)
NS_RELEASE(event.widget);
}
void
nsWindow::HandleStartComposition(void)
{
nsCompositionEvent event;
nsPoint point;
point.x = 0;
point.y = 0;
InitEvent(event,NS_COMPOSITION_START,&point);
event.eventStructType = NS_COMPOSITION_START;
event.compositionMessage = NS_COMPOSITION_START;
(void)DispatchWindowEvent(&event);
NS_RELEASE(event.widget);
}
void
nsWindow::HandleEndComposition(void)
{
nsCompositionEvent event;
nsPoint point;
point.x = 0;
point.y = 0;
InitEvent(event,NS_COMPOSITION_END,&point);
event.eventStructType = NS_COMPOSITION_END;
event.compositionMessage = NS_COMPOSITION_END;
(void)DispatchWindowEvent(&event);
NS_RELEASE(event.widget);
}

View File

@ -189,6 +189,8 @@ protected:
void GetNonClientBounds(nsRect &aRect);
void HandleTextEvent(PRBool commit);
void HandleStartComposition(void);
void HandleEndComposition(void);
protected:
static nsWindow* gCurrentWindow;