1999-02-12 20:18:58 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
*
|
1999-11-06 06:43:54 +03:00
|
|
|
* 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/
|
1999-02-12 20:18:58 +03:00
|
|
|
*
|
1999-11-06 06:43:54 +03:00
|
|
|
* 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.
|
1999-02-12 20:18:58 +03:00
|
|
|
*
|
1999-11-06 06:43:54 +03:00
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape
|
1999-02-12 20:18:58 +03:00
|
|
|
* Communications Corporation. Portions created by Netscape are
|
1999-11-06 06:43:54 +03:00
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
|
|
* Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
2000-01-11 23:49:15 +03:00
|
|
|
* Pierre Phaneuf <pp@ludusdesign.com>
|
1999-02-12 20:18:58 +03:00
|
|
|
*/
|
|
|
|
#include "nsEditorEventListeners.h"
|
|
|
|
#include "nsEditor.h"
|
1999-08-09 05:37:50 +04:00
|
|
|
#include "nsVoidArray.h"
|
|
|
|
#include "nsString.h"
|
|
|
|
|
2000-05-10 03:03:41 +04:00
|
|
|
#include "nsIDOMEvent.h"
|
1999-02-12 20:18:58 +03:00
|
|
|
#include "nsIDOMDocument.h"
|
Preparation for ender-based text control
* added focus listener. Doesn't do much yet, but when focus notifications start appearing, we'll be ready for them. The code is in
place to hide selection when we lose focus and paint selection when we get focus. That's probably not quite right, but it's a start.
We will need to be able to determine the distinction between losing focus to another control within our app, and losing focus to
another app.
* added support for disabled and readonly states in the editor. This is accomplished by having flags set by the client, and letting the
rules system deal with those flags. The flags I added are:
TEXT_EDITOR_FLAG_PLAINTEXT 0x01 // only plain text editing is allowed
TEXT_EDITOR_FLAG_SINGLELINE 0x02 // enter key and CR-LF handled specially
TEXT_EDITOR_FLAG_PASSWORD 0x04 // text is not entered into content, only a representative character
TEXT_EDITOR_FLAG_READONLY 0x08 // editing events are disabled. Editor may still accept focus.
TEXT_EDITOR_FLAG_DISALBED 0x10 // all events are disabled (like scrolling). Editor will not accept focus.
* added WillInsertBreak/DidInsertBreak into text rules, so flags could be checked. This gets us readonly, disabled, and single line
behavior.
* cleaned up the code that allocates, registers, and destroys event listeners. Thanks to Kin and Simon for cleaning up the
ownership model on the listeners, it was a big help.
* added support for a max text length. You can now tell the text editor, be no bigger than n characters.
1999-05-29 01:24:18 +04:00
|
|
|
#include "nsIDocument.h"
|
|
|
|
#include "nsIPresShell.h"
|
1999-02-12 20:18:58 +03:00
|
|
|
#include "nsIDOMElement.h"
|
1999-05-07 23:22:38 +04:00
|
|
|
#include "nsIDOMSelection.h"
|
1999-02-12 20:18:58 +03:00
|
|
|
#include "nsIDOMCharacterData.h"
|
1999-02-24 20:24:37 +03:00
|
|
|
#include "nsIEditProperty.h"
|
|
|
|
#include "nsISupportsArray.h"
|
1999-03-23 01:10:29 +03:00
|
|
|
#include "nsIStringStream.h"
|
1999-11-03 10:11:45 +03:00
|
|
|
#include "nsIDOMKeyEvent.h"
|
|
|
|
#include "nsIDOMMouseEvent.h"
|
1999-06-09 01:51:40 +04:00
|
|
|
#include "nsIDOMNSUIEvent.h"
|
1999-08-06 06:32:13 +04:00
|
|
|
#include "nsIPrivateTextEvent.h"
|
1999-08-31 05:20:32 +04:00
|
|
|
#include "nsIPrivateCompositionEvent.h"
|
1999-08-09 05:37:50 +04:00
|
|
|
#include "nsIEditorMailSupport.h"
|
1999-08-24 22:30:19 +04:00
|
|
|
#include "nsIDocumentEncoder.h"
|
1999-12-16 01:04:43 +03:00
|
|
|
#include "nsIPrivateDOMEvent.h"
|
2000-03-30 05:23:47 +04:00
|
|
|
#include "nsIPref.h"
|
2000-07-29 02:12:45 +04:00
|
|
|
#include "nsILookAndFeel.h"
|
|
|
|
#include "nsIPresContext.h"
|
1999-08-02 17:53:23 +04:00
|
|
|
// for repainting hack only
|
|
|
|
#include "nsIView.h"
|
|
|
|
#include "nsIViewManager.h"
|
|
|
|
// end repainting hack only
|
|
|
|
|
1999-04-07 00:24:09 +04:00
|
|
|
// Drag & Drop, Clipboard
|
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsWidgetsCID.h"
|
2000-04-15 03:38:21 +04:00
|
|
|
#include "nsIClipboard.h"
|
1999-04-17 17:52:28 +04:00
|
|
|
#include "nsIDragService.h"
|
1999-05-07 23:42:27 +04:00
|
|
|
#include "nsIDragSession.h"
|
1999-04-07 00:24:09 +04:00
|
|
|
#include "nsITransferable.h"
|
|
|
|
#include "nsIFormatConverter.h"
|
1999-08-19 17:30:48 +04:00
|
|
|
#include "nsIContentIterator.h"
|
|
|
|
#include "nsIContent.h"
|
1999-08-25 12:35:06 +04:00
|
|
|
#include "nsISupportsPrimitives.h"
|
1999-08-19 17:30:48 +04:00
|
|
|
#include "nsLayoutCID.h"
|
2000-08-10 05:01:18 +04:00
|
|
|
#include "nsIDOMNSRange.h"
|
1999-04-07 00:24:09 +04:00
|
|
|
|
|
|
|
// Drag & Drop, Clipboard Support
|
2000-07-29 02:12:45 +04:00
|
|
|
static NS_DEFINE_CID(kCDataFlavorCID, NS_DATAFLAVOR_CID);
|
|
|
|
static NS_DEFINE_CID(kContentIteratorCID, NS_CONTENTITERATOR_CID);
|
|
|
|
static NS_DEFINE_CID(kCXIFConverterCID, NS_XIFFORMATCONVERTER_CID);
|
|
|
|
static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
|
|
|
|
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
2000-03-30 05:23:47 +04:00
|
|
|
|
1999-12-01 03:35:31 +03:00
|
|
|
//#define DEBUG_IME
|
1999-04-07 00:24:09 +04:00
|
|
|
|
2000-05-31 07:18:05 +04:00
|
|
|
static nsresult ScrollSelectionIntoView(nsIEditor *aEditor);
|
1999-04-07 00:24:09 +04:00
|
|
|
|
1999-02-12 20:18:58 +03:00
|
|
|
/*
|
|
|
|
* nsTextEditorKeyListener implementation
|
|
|
|
*/
|
|
|
|
|
|
|
|
NS_IMPL_ADDREF(nsTextEditorKeyListener)
|
|
|
|
|
|
|
|
NS_IMPL_RELEASE(nsTextEditorKeyListener)
|
|
|
|
|
|
|
|
|
1999-03-20 02:36:20 +03:00
|
|
|
nsTextEditorKeyListener::nsTextEditorKeyListener()
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsTextEditorKeyListener::~nsTextEditorKeyListener()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditorKeyListener::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|
|
|
{
|
|
|
|
if (nsnull == aInstancePtr) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
2000-01-11 23:49:15 +03:00
|
|
|
if (aIID.Equals(NS_GET_IID(nsISupports))) {
|
1999-02-12 20:18:58 +03:00
|
|
|
*aInstancePtr = (void*)(nsISupports*)this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-01-11 23:49:15 +03:00
|
|
|
if (aIID.Equals(NS_GET_IID(nsIDOMEventListener))) {
|
1999-02-12 20:18:58 +03:00
|
|
|
*aInstancePtr = (void*)(nsIDOMEventListener*)this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-01-11 23:49:15 +03:00
|
|
|
if (aIID.Equals(NS_GET_IID(nsIDOMKeyListener))) {
|
1999-02-12 20:18:58 +03:00
|
|
|
*aInstancePtr = (void*)(nsIDOMKeyListener*)this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
1999-03-29 02:27:38 +04:00
|
|
|
nsTextEditorKeyListener::HandleEvent(nsIDOMEvent* aEvent)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-07-07 03:31:08 +04:00
|
|
|
// individual key handlers return NS_OK to indicate NOT consumed
|
|
|
|
// by default, an error is returned indicating event is consumed
|
|
|
|
// joki is fixing this interface.
|
1999-06-04 09:14:01 +04:00
|
|
|
nsresult
|
|
|
|
nsTextEditorKeyListener::KeyDown(nsIDOMEvent* aKeyEvent)
|
|
|
|
{
|
1999-09-18 00:11:13 +04:00
|
|
|
return NS_OK;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditorKeyListener::KeyUp(nsIDOMEvent* aKeyEvent)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-06-04 09:14:01 +04:00
|
|
|
nsresult
|
|
|
|
nsTextEditorKeyListener::KeyPress(nsIDOMEvent* aKeyEvent)
|
|
|
|
{
|
1999-11-03 10:11:45 +03:00
|
|
|
nsCOMPtr<nsIDOMKeyEvent>keyEvent;
|
|
|
|
keyEvent = do_QueryInterface(aKeyEvent);
|
|
|
|
if (!keyEvent)
|
1999-08-25 14:51:55 +04:00
|
|
|
{
|
|
|
|
//non-key event passed to keydown. bad things.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-12-16 01:04:43 +03:00
|
|
|
|
|
|
|
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(aKeyEvent);
|
|
|
|
if(privateEvent)
|
|
|
|
{
|
|
|
|
PRBool dispatchStopped;
|
|
|
|
privateEvent->IsDispatchStopped(&dispatchStopped);
|
|
|
|
if(dispatchStopped)
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-07-08 23:52:44 +04:00
|
|
|
|
1999-09-20 08:16:34 +04:00
|
|
|
// we should check a flag here to see if we should be using built-in key bindings
|
|
|
|
// mEditor->GetFlags(&flags);
|
|
|
|
// if (flags & ...)
|
1999-08-25 14:51:55 +04:00
|
|
|
|
2000-07-28 01:39:48 +04:00
|
|
|
PRUint32 keyCode;
|
|
|
|
PRUint32 flags;
|
|
|
|
keyEvent->GetKeyCode(&keyCode);
|
|
|
|
|
|
|
|
// if we are readonly or disabled, then do nothing.
|
|
|
|
if (NS_SUCCEEDED(mEditor->GetFlags(&flags)))
|
|
|
|
{
|
|
|
|
if (flags & nsIHTMLEditor::eEditorReadonlyMask ||
|
|
|
|
flags & nsIHTMLEditor::eEditorDisabledMask)
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return NS_ERROR_FAILURE; // Editor unable to handle this.
|
|
|
|
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor);
|
|
|
|
if (!htmlEditor) return NS_ERROR_NO_INTERFACE;
|
1999-08-25 14:51:55 +04:00
|
|
|
|
2000-07-28 01:39:48 +04:00
|
|
|
// if there is no charCode, then it's a key that doesn't map to a character,
|
|
|
|
// so look for special keys using keyCode
|
|
|
|
if (0 != keyCode)
|
|
|
|
{
|
|
|
|
PRBool isAnyModifierKey;
|
|
|
|
nsresult rv;
|
|
|
|
rv = keyEvent->GetAltKey(&isAnyModifierKey);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (!isAnyModifierKey)
|
1999-08-25 14:51:55 +04:00
|
|
|
{
|
2000-07-28 01:39:48 +04:00
|
|
|
rv = keyEvent->GetMetaKey(&isAnyModifierKey);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (!isAnyModifierKey)
|
1999-08-25 14:51:55 +04:00
|
|
|
{
|
2000-07-28 01:39:48 +04:00
|
|
|
rv = keyEvent->GetShiftKey(&isAnyModifierKey);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
if (!isAnyModifierKey)
|
|
|
|
{
|
|
|
|
rv = keyEvent->GetCtrlKey(&isAnyModifierKey);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (keyCode)
|
|
|
|
{
|
|
|
|
// we should be handling DOM_VK_META here too but it doesn't exist at the moment
|
|
|
|
case nsIDOMKeyEvent::DOM_VK_SHIFT:
|
|
|
|
case nsIDOMKeyEvent::DOM_VK_CONTROL:
|
|
|
|
case nsIDOMKeyEvent::DOM_VK_ALT:
|
|
|
|
aKeyEvent->PreventDefault(); // consumed
|
|
|
|
return NS_OK;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case nsIDOMKeyEvent::DOM_VK_BACK_SPACE:
|
|
|
|
if (isAnyModifierKey)
|
2000-06-20 18:23:43 +04:00
|
|
|
return NS_OK;
|
1999-09-18 00:11:13 +04:00
|
|
|
|
2000-07-28 01:39:48 +04:00
|
|
|
mEditor->DeleteSelection(nsIEditor::ePrevious);
|
|
|
|
ScrollSelectionIntoView(mEditor);
|
|
|
|
aKeyEvent->PreventDefault(); // consumed
|
|
|
|
return NS_OK;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case nsIDOMKeyEvent::DOM_VK_DELETE:
|
|
|
|
if (isAnyModifierKey)
|
2000-06-20 18:23:43 +04:00
|
|
|
return NS_OK;
|
2000-07-28 01:39:48 +04:00
|
|
|
|
|
|
|
mEditor->DeleteSelection(nsIEditor::eNext);
|
|
|
|
ScrollSelectionIntoView(mEditor);
|
|
|
|
aKeyEvent->PreventDefault(); // consumed
|
|
|
|
return NS_OK;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case nsIDOMKeyEvent::DOM_VK_TAB:
|
|
|
|
if ((flags & nsIHTMLEditor::eEditorSingleLineMask))
|
|
|
|
return NS_OK; // let it be used for focus switching
|
|
|
|
|
|
|
|
// else we insert the tab straight through
|
|
|
|
htmlEditor->EditorKeyPress(keyEvent);
|
|
|
|
ScrollSelectionIntoView(mEditor);
|
|
|
|
aKeyEvent->PreventDefault(); // consumed
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
case nsIDOMKeyEvent::DOM_VK_RETURN:
|
|
|
|
case nsIDOMKeyEvent::DOM_VK_ENTER:
|
|
|
|
if (!(flags & nsIHTMLEditor::eEditorSingleLineMask))
|
|
|
|
{
|
|
|
|
//htmlEditor->InsertBreak();
|
1999-11-03 10:11:45 +03:00
|
|
|
htmlEditor->EditorKeyPress(keyEvent);
|
2000-05-31 07:18:05 +04:00
|
|
|
ScrollSelectionIntoView(mEditor);
|
2000-06-20 18:23:43 +04:00
|
|
|
aKeyEvent->PreventDefault(); // consumed
|
2000-07-28 01:39:48 +04:00
|
|
|
}
|
|
|
|
return NS_OK;
|
1999-08-25 14:51:55 +04:00
|
|
|
}
|
|
|
|
}
|
2000-07-28 01:39:48 +04:00
|
|
|
|
|
|
|
if (NS_SUCCEEDED(htmlEditor->EditorKeyPress(keyEvent)))
|
2000-05-31 07:18:05 +04:00
|
|
|
ScrollSelectionIntoView(mEditor);
|
1999-08-25 14:51:55 +04:00
|
|
|
|
2000-06-20 18:23:43 +04:00
|
|
|
return NS_OK; // we don't PreventDefault() here or keybindings like control-x won't work
|
1999-06-04 09:14:01 +04:00
|
|
|
}
|
|
|
|
|
1999-02-12 20:18:58 +03:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aProcessed)
|
|
|
|
{
|
|
|
|
aProcessed=PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-08-31 05:14:40 +04:00
|
|
|
nsresult
|
2000-05-31 07:18:05 +04:00
|
|
|
ScrollSelectionIntoView(nsIEditor *aEditor)
|
1999-08-31 05:14:40 +04:00
|
|
|
{
|
2000-05-31 07:18:05 +04:00
|
|
|
if (! aEditor)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
2000-04-27 11:37:12 +04:00
|
|
|
nsCOMPtr<nsISelectionController> selCon;
|
1999-08-31 05:14:40 +04:00
|
|
|
|
2000-05-31 07:18:05 +04:00
|
|
|
nsresult result = aEditor->GetSelectionController(getter_AddRefs(selCon));
|
1999-08-31 05:14:40 +04:00
|
|
|
|
2000-04-27 11:37:12 +04:00
|
|
|
if (NS_FAILED(result) || ! selCon)
|
|
|
|
return result ? result: NS_ERROR_FAILURE;
|
1999-08-31 05:14:40 +04:00
|
|
|
|
2000-04-27 11:37:12 +04:00
|
|
|
return selCon->ScrollSelectionIntoView(nsISelectionController::SELECTION_NORMAL, nsISelectionController::SELECTION_FOCUS_REGION);
|
1999-08-31 05:14:40 +04:00
|
|
|
}
|
1999-02-12 20:18:58 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* nsTextEditorMouseListener implementation
|
|
|
|
*/
|
|
|
|
|
|
|
|
NS_IMPL_ADDREF(nsTextEditorMouseListener)
|
|
|
|
|
|
|
|
NS_IMPL_RELEASE(nsTextEditorMouseListener)
|
|
|
|
|
|
|
|
|
|
|
|
nsTextEditorMouseListener::nsTextEditorMouseListener()
|
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsTextEditorMouseListener::~nsTextEditorMouseListener()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditorMouseListener::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|
|
|
{
|
|
|
|
if (nsnull == aInstancePtr) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
1999-05-28 04:19:51 +04:00
|
|
|
|
2000-01-11 23:49:15 +03:00
|
|
|
if (aIID.Equals(NS_GET_IID(nsISupports))) {
|
1999-02-12 20:18:58 +03:00
|
|
|
*aInstancePtr = (void*)(nsISupports*)this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-01-11 23:49:15 +03:00
|
|
|
if (aIID.Equals(NS_GET_IID(nsIDOMEventListener))) {
|
1999-02-12 20:18:58 +03:00
|
|
|
*aInstancePtr = (void*)(nsIDOMEventListener*)this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-01-11 23:49:15 +03:00
|
|
|
if (aIID.Equals(NS_GET_IID(nsIDOMMouseListener))) {
|
1999-02-12 20:18:58 +03:00
|
|
|
*aInstancePtr = (void*)(nsIDOMMouseListener*)this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
1999-03-29 02:27:38 +04:00
|
|
|
nsTextEditorMouseListener::HandleEvent(nsIDOMEvent* aEvent)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
2000-06-14 03:19:48 +04:00
|
|
|
nsTextEditorMouseListener::MouseClick(nsIDOMEvent* aMouseEvent)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-05-07 23:22:38 +04:00
|
|
|
if (!aMouseEvent)
|
|
|
|
return NS_OK; // NS_OK means "we didn't process the event". Go figure.
|
|
|
|
|
1999-11-30 03:10:55 +03:00
|
|
|
nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aMouseEvent) );
|
1999-11-03 10:11:45 +03:00
|
|
|
if (!mouseEvent) {
|
1999-05-19 03:51:04 +04:00
|
|
|
//non-ui event passed in. bad things.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-12-08 06:39:36 +03:00
|
|
|
// If we got a mouse down inside the editing area, we should force the
|
|
|
|
// IME to commit before we change the cursor position
|
|
|
|
nsCOMPtr<nsIEditorIMESupport> imeEditor = do_QueryInterface(mEditor);
|
|
|
|
if(imeEditor)
|
|
|
|
imeEditor->ForceCompositionEnd();
|
|
|
|
|
1999-08-25 14:51:55 +04:00
|
|
|
nsCOMPtr<nsIEditor> editor (do_QueryInterface(mEditor));
|
1999-08-19 17:30:48 +04:00
|
|
|
if (!editor) { return NS_OK; }
|
1999-06-09 01:51:40 +04:00
|
|
|
|
1999-08-19 17:30:48 +04:00
|
|
|
PRUint16 button = 0;
|
1999-11-03 10:11:45 +03:00
|
|
|
mouseEvent->GetButton(&button);
|
1999-08-19 17:30:48 +04:00
|
|
|
// middle-mouse click (paste);
|
1999-11-30 03:10:55 +03:00
|
|
|
if (button == 2)
|
|
|
|
{
|
2000-03-30 05:23:47 +04:00
|
|
|
nsresult rv;
|
|
|
|
NS_WITH_SERVICE(nsIPref, prefService, kPrefServiceCID, &rv);
|
|
|
|
if (NS_SUCCEEDED(rv) && prefService)
|
|
|
|
{
|
2000-04-26 05:00:50 +04:00
|
|
|
PRBool doMiddleMousePaste = PR_FALSE;;
|
2000-03-30 05:23:47 +04:00
|
|
|
rv = prefService->GetBoolPref("middlemouse.paste", &doMiddleMousePaste);
|
|
|
|
if (NS_SUCCEEDED(rv) && doMiddleMousePaste)
|
1999-08-25 14:51:55 +04:00
|
|
|
{
|
2000-03-30 05:23:47 +04:00
|
|
|
// Set the selection to the point under the mouse cursor:
|
|
|
|
nsCOMPtr<nsIDOMNSUIEvent> nsuiEvent (do_QueryInterface(aMouseEvent));
|
|
|
|
|
|
|
|
if (!nsuiEvent)
|
2000-06-20 18:23:43 +04:00
|
|
|
return NS_ERROR_NULL_POINTER;
|
2000-03-30 05:23:47 +04:00
|
|
|
nsCOMPtr<nsIDOMNode> parent;
|
|
|
|
if (!NS_SUCCEEDED(nsuiEvent->GetRangeParent(getter_AddRefs(parent))))
|
2000-06-20 18:23:43 +04:00
|
|
|
return NS_ERROR_NULL_POINTER;
|
2000-03-30 05:23:47 +04:00
|
|
|
PRInt32 offset = 0;
|
|
|
|
if (!NS_SUCCEEDED(nsuiEvent->GetRangeOffset(&offset)))
|
2000-06-20 18:23:43 +04:00
|
|
|
return NS_ERROR_NULL_POINTER;
|
2000-03-30 05:23:47 +04:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMSelection> selection;
|
|
|
|
if (NS_SUCCEEDED(editor->GetSelection(getter_AddRefs(selection))))
|
|
|
|
(void)selection->Collapse(parent, offset);
|
|
|
|
|
|
|
|
// If the ctrl key is pressed, we'll do paste as quotation.
|
|
|
|
// Would've used the alt key, but the kde wmgr treats alt-middle specially.
|
|
|
|
nsCOMPtr<nsIEditorMailSupport> mailEditor;
|
|
|
|
mouseEvent = do_QueryInterface(aMouseEvent);
|
|
|
|
PRBool ctrlKey = PR_FALSE;
|
|
|
|
mouseEvent->GetCtrlKey(&ctrlKey);
|
|
|
|
if (ctrlKey)
|
|
|
|
mailEditor = do_QueryInterface(mEditor);
|
|
|
|
|
|
|
|
if (mailEditor)
|
2000-04-15 03:38:21 +04:00
|
|
|
mailEditor->PasteAsQuotation(nsIClipboard::kSelectionClipboard);
|
2000-03-30 05:23:47 +04:00
|
|
|
else
|
2000-04-15 03:38:21 +04:00
|
|
|
editor->Paste(nsIClipboard::kSelectionClipboard);
|
2000-03-30 05:23:47 +04:00
|
|
|
|
2000-06-20 18:23:43 +04:00
|
|
|
// Prevent the event from bubbling up to be possibly handled
|
2000-06-14 03:19:48 +04:00
|
|
|
// again by the containing window:
|
|
|
|
mouseEvent->PreventBubble();
|
|
|
|
mouseEvent->PreventDefault();
|
|
|
|
|
2000-06-20 18:23:43 +04:00
|
|
|
// We processed the event, whether drop/paste succeeded or not
|
|
|
|
return NS_OK;
|
1999-08-25 14:51:55 +04:00
|
|
|
}
|
2000-03-30 05:23:47 +04:00
|
|
|
}
|
1999-08-25 14:51:55 +04:00
|
|
|
}
|
2000-06-20 18:23:43 +04:00
|
|
|
return NS_OK;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-06-14 03:19:48 +04:00
|
|
|
nsTextEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-06-14 03:19:48 +04:00
|
|
|
nsTextEditorMouseListener::MouseUp(nsIDOMEvent* aMouseEvent)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditorMouseListener::MouseDblClick(nsIDOMEvent* aMouseEvent)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditorMouseListener::MouseOver(nsIDOMEvent* aMouseEvent)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditorMouseListener::MouseOut(nsIDOMEvent* aMouseEvent)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-03-20 02:36:20 +03:00
|
|
|
|
|
|
|
/*
|
2000-05-10 03:03:41 +04:00
|
|
|
* nsTextEditorTextListener implementation
|
1999-03-20 02:36:20 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
NS_IMPL_ADDREF(nsTextEditorTextListener)
|
|
|
|
|
|
|
|
NS_IMPL_RELEASE(nsTextEditorTextListener)
|
|
|
|
|
|
|
|
|
|
|
|
nsTextEditorTextListener::nsTextEditorTextListener()
|
1999-08-25 14:51:55 +04:00
|
|
|
: mCommitText(PR_FALSE),
|
|
|
|
mInTransaction(PR_FALSE)
|
1999-03-20 02:36:20 +03:00
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsTextEditorTextListener::~nsTextEditorTextListener()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditorTextListener::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|
|
|
{
|
|
|
|
if (nsnull == aInstancePtr) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
1999-05-28 04:19:51 +04:00
|
|
|
|
2000-01-11 23:49:15 +03:00
|
|
|
if (aIID.Equals(NS_GET_IID(nsISupports))) {
|
1999-03-20 02:36:20 +03:00
|
|
|
*aInstancePtr = (void*)(nsISupports*)this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-01-11 23:49:15 +03:00
|
|
|
if (aIID.Equals(NS_GET_IID(nsIDOMEventListener))) {
|
1999-03-20 02:36:20 +03:00
|
|
|
*aInstancePtr = (void*)(nsIDOMEventListener*)this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-01-11 23:49:15 +03:00
|
|
|
if (aIID.Equals(NS_GET_IID(nsIDOMTextListener))) {
|
1999-03-20 02:36:20 +03:00
|
|
|
*aInstancePtr = (void*)(nsIDOMTextListener*)this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-03-29 02:27:38 +04:00
|
|
|
nsTextEditorTextListener::HandleEvent(nsIDOMEvent* aEvent)
|
1999-03-20 02:36:20 +03:00
|
|
|
{
|
1999-12-01 03:35:31 +03:00
|
|
|
#ifdef DEBUG_IME
|
1999-10-28 02:56:36 +04:00
|
|
|
printf("nsTextEditorTextListener::HandleEvent\n");
|
|
|
|
#endif
|
1999-03-20 02:36:20 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditorTextListener::HandleText(nsIDOMEvent* aTextEvent)
|
|
|
|
{
|
1999-12-01 03:35:31 +03:00
|
|
|
#ifdef DEBUG_IME
|
1999-10-28 02:56:36 +04:00
|
|
|
printf("nsTextEditorTextListener::HandleText\n");
|
|
|
|
#endif
|
1999-09-15 03:40:16 +04:00
|
|
|
nsAutoString composedText;
|
1999-08-25 14:51:55 +04:00
|
|
|
nsresult result = NS_OK;
|
|
|
|
nsCOMPtr<nsIPrivateTextEvent> textEvent;
|
|
|
|
nsIPrivateTextRangeList *textRangeList;
|
|
|
|
nsTextEventReply *textEventReply;
|
|
|
|
|
|
|
|
textEvent = do_QueryInterface(aTextEvent);
|
|
|
|
if (!textEvent) {
|
|
|
|
//non-ui event passed in. bad things.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
textEvent->GetText(composedText);
|
|
|
|
textEvent->GetInputRange(&textRangeList);
|
|
|
|
textEvent->GetEventReply(&textEventReply);
|
|
|
|
textRangeList->AddRef();
|
|
|
|
nsCOMPtr<nsIEditorIMESupport> imeEditor = do_QueryInterface(mEditor, &result);
|
2000-05-31 07:18:05 +04:00
|
|
|
if (imeEditor) {
|
1999-08-09 05:37:50 +04:00
|
|
|
result = imeEditor->SetCompositionString(composedText,textRangeList,textEventReply);
|
2000-05-31 07:18:05 +04:00
|
|
|
ScrollSelectionIntoView(mEditor);
|
|
|
|
}
|
1999-08-25 14:51:55 +04:00
|
|
|
return result;
|
1999-03-20 02:36:20 +03:00
|
|
|
}
|
|
|
|
|
1999-05-07 23:42:27 +04:00
|
|
|
/*
|
|
|
|
* nsTextEditorDragListener implementation
|
|
|
|
*/
|
|
|
|
|
|
|
|
NS_IMPL_ADDREF(nsTextEditorDragListener)
|
|
|
|
|
|
|
|
NS_IMPL_RELEASE(nsTextEditorDragListener)
|
|
|
|
|
|
|
|
|
|
|
|
nsTextEditorDragListener::nsTextEditorDragListener()
|
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
}
|
|
|
|
|
|
|
|
nsTextEditorDragListener::~nsTextEditorDragListener()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
1999-03-14 07:45:00 +03:00
|
|
|
nsresult
|
|
|
|
nsTextEditorDragListener::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|
|
|
{
|
|
|
|
if (nsnull == aInstancePtr) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
1999-05-28 04:19:51 +04:00
|
|
|
|
2000-01-11 23:49:15 +03:00
|
|
|
if (aIID.Equals(NS_GET_IID(nsISupports))) {
|
1999-03-14 07:45:00 +03:00
|
|
|
*aInstancePtr = (void*)(nsISupports*)this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-01-11 23:49:15 +03:00
|
|
|
if (aIID.Equals(NS_GET_IID(nsIDOMEventListener))) {
|
1999-03-14 07:45:00 +03:00
|
|
|
*aInstancePtr = (void*)(nsIDOMEventListener*)this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-01-11 23:49:15 +03:00
|
|
|
if (aIID.Equals(NS_GET_IID(nsIDOMDragListener))) {
|
1999-03-14 07:45:00 +03:00
|
|
|
*aInstancePtr = (void*)(nsIDOMDragListener*)this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
1999-03-29 02:27:38 +04:00
|
|
|
nsTextEditorDragListener::HandleEvent(nsIDOMEvent* aEvent)
|
1999-03-14 07:45:00 +03:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-08-19 23:48:33 +04:00
|
|
|
nsresult
|
|
|
|
nsTextEditorDragListener::DragGesture(nsIDOMEvent* aDragEvent)
|
|
|
|
{
|
2000-06-08 18:47:29 +04:00
|
|
|
PRBool canDrag = PR_FALSE;
|
|
|
|
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor);
|
|
|
|
if ( !htmlEditor )
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1999-11-30 01:35:35 +03:00
|
|
|
|
2000-06-08 18:47:29 +04:00
|
|
|
// ...figure out if a drag should be started...
|
|
|
|
nsresult rv = htmlEditor->CanDrag(aDragEvent, canDrag);
|
|
|
|
if ( NS_SUCCEEDED(rv) && canDrag )
|
|
|
|
rv = htmlEditor->DoDrag(aDragEvent);
|
|
|
|
|
|
|
|
return rv;
|
1999-08-19 23:48:33 +04:00
|
|
|
}
|
|
|
|
|
1999-03-14 07:45:00 +03:00
|
|
|
|
|
|
|
nsresult
|
1999-04-07 00:24:09 +04:00
|
|
|
nsTextEditorDragListener::DragEnter(nsIDOMEvent* aDragEvent)
|
|
|
|
{
|
2000-06-20 18:23:43 +04:00
|
|
|
return DragOver(aDragEvent);
|
1999-04-07 00:24:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditorDragListener::DragOver(nsIDOMEvent* aDragEvent)
|
|
|
|
{
|
1999-08-25 12:35:06 +04:00
|
|
|
nsresult rv;
|
1999-11-30 03:10:55 +03:00
|
|
|
NS_WITH_SERVICE ( nsIDragService, dragService, "component://netscape/widget/dragservice", &rv );
|
1999-08-25 12:35:06 +04:00
|
|
|
if ( NS_SUCCEEDED(rv) ) {
|
1999-05-07 23:42:27 +04:00
|
|
|
nsCOMPtr<nsIDragSession> dragSession(do_QueryInterface(dragService));
|
1999-08-25 12:35:06 +04:00
|
|
|
if ( dragSession ) {
|
2000-05-17 01:57:06 +04:00
|
|
|
PRUint32 flags;
|
|
|
|
if (NS_SUCCEEDED(mEditor->GetFlags(&flags))) {
|
|
|
|
if ((flags & nsIHTMLEditor::eEditorDisabledMask) ||
|
|
|
|
(flags & nsIHTMLEditor::eEditorReadonlyMask)) {
|
|
|
|
dragSession->SetCanDrop(PR_FALSE);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
1999-08-25 12:35:06 +04:00
|
|
|
PRBool flavorSupported = PR_FALSE;
|
2000-02-02 01:26:21 +03:00
|
|
|
dragSession->IsDataFlavorSupported(kUnicodeMime, &flavorSupported);
|
2000-05-16 18:53:43 +04:00
|
|
|
if ( !flavorSupported )
|
|
|
|
dragSession->IsDataFlavorSupported(kHTMLMime, &flavorSupported);
|
|
|
|
if ( !flavorSupported )
|
|
|
|
dragSession->IsDataFlavorSupported(kFileMime, &flavorSupported);
|
|
|
|
if ( !flavorSupported )
|
|
|
|
dragSession->IsDataFlavorSupported(kJPEGImageMime, &flavorSupported);
|
|
|
|
if ( flavorSupported )
|
1999-08-25 12:35:06 +04:00
|
|
|
dragSession->SetCanDrop(PR_TRUE);
|
1999-05-07 23:42:27 +04:00
|
|
|
}
|
1999-04-17 17:52:28 +04:00
|
|
|
}
|
1999-06-16 08:52:05 +04:00
|
|
|
|
1999-04-07 00:24:09 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditorDragListener::DragExit(nsIDOMEvent* aDragEvent)
|
1999-03-14 07:45:00 +03:00
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent)
|
|
|
|
{
|
2000-04-25 18:15:33 +04:00
|
|
|
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(mEditor);
|
|
|
|
if ( htmlEditor )
|
|
|
|
{
|
2000-06-20 05:01:49 +04:00
|
|
|
nsresult rv;
|
|
|
|
NS_WITH_SERVICE(nsIDragService, dragService, "component://netscape/widget/dragservice", &rv);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDragSession> dragSession(do_QueryInterface(dragService));
|
|
|
|
if (dragSession)
|
|
|
|
{
|
|
|
|
PRBool flavorSupported = PR_FALSE;
|
|
|
|
dragSession->IsDataFlavorSupported(kUnicodeMime, &flavorSupported);
|
|
|
|
if ( !flavorSupported )
|
|
|
|
dragSession->IsDataFlavorSupported(kHTMLMime, &flavorSupported);
|
|
|
|
if ( !flavorSupported )
|
|
|
|
dragSession->IsDataFlavorSupported(kFileMime, &flavorSupported);
|
|
|
|
if ( !flavorSupported )
|
|
|
|
dragSession->IsDataFlavorSupported(kJPEGImageMime, &flavorSupported);
|
|
|
|
if (! flavorSupported )
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-14 06:58:34 +04:00
|
|
|
//some day we want to use another way to stop this from bubbling.
|
|
|
|
aMouseEvent->PreventBubble();
|
|
|
|
aMouseEvent->PreventDefault();
|
|
|
|
|
2000-08-10 05:01:18 +04:00
|
|
|
/* for bug 47399, when dropping a drag session, if you are over your original
|
|
|
|
selection, nothing should happen. */
|
|
|
|
nsCOMPtr<nsIDOMSelection> tempSelection;
|
|
|
|
rv = mEditor->GetSelection(getter_AddRefs(tempSelection));
|
|
|
|
if (NS_FAILED(rv) || !tempSelection)
|
|
|
|
return rv?rv:NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
PRInt32 rangeCount;
|
|
|
|
rv = tempSelection->GetRangeCount(&rangeCount);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv?rv:NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
for(int i = 0; i < rangeCount; i++)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMRange> range;
|
|
|
|
|
|
|
|
rv = tempSelection->GetRangeAt(i, getter_AddRefs(range));
|
|
|
|
if (NS_FAILED(rv) || !range)
|
|
|
|
continue;//dont bail yet, iterate through them all
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMNSRange> nsrange(do_QueryInterface(range));
|
|
|
|
if (NS_FAILED(rv) || !nsrange)
|
|
|
|
continue;//dont bail yet, iterate through them all
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMNSUIEvent> nsuiEvent (do_QueryInterface(aMouseEvent));
|
|
|
|
if (!nsuiEvent)
|
|
|
|
continue;//dont bail yet, iterate through them all
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMNode> parent;
|
|
|
|
if (!NS_SUCCEEDED(nsuiEvent->GetRangeParent(getter_AddRefs(parent))))
|
|
|
|
continue;//dont bail yet, iterate through them all
|
|
|
|
|
|
|
|
PRInt32 offset = 0;
|
|
|
|
if (!NS_SUCCEEDED(nsuiEvent->GetRangeOffset(&offset)))
|
|
|
|
continue;//dont bail yet, iterate through them all
|
|
|
|
|
|
|
|
PRBool inrange;
|
|
|
|
rv = nsrange->IsPointInRange(parent, offset, &inrange);
|
|
|
|
if(inrange)
|
|
|
|
return NS_ERROR_FAILURE;//okay, now you can bail, we are over the orginal selection
|
|
|
|
}
|
|
|
|
// if we are not over orginal selection, drop that baby!
|
2000-06-08 18:47:29 +04:00
|
|
|
return htmlEditor->InsertFromDrop(aMouseEvent);
|
2000-04-25 18:15:33 +04:00
|
|
|
}
|
1999-04-07 00:24:09 +04:00
|
|
|
|
1999-03-14 07:45:00 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-05-07 23:42:27 +04:00
|
|
|
|
1999-05-04 02:57:48 +04:00
|
|
|
nsTextEditorCompositionListener::nsTextEditorCompositionListener()
|
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
}
|
|
|
|
|
|
|
|
nsTextEditorCompositionListener::~nsTextEditorCompositionListener()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditorCompositionListener::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|
|
|
{
|
|
|
|
if (nsnull == aInstancePtr) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
2000-01-11 23:49:15 +03:00
|
|
|
if (aIID.Equals(NS_GET_IID(nsISupports))) {
|
1999-05-04 02:57:48 +04:00
|
|
|
*aInstancePtr = (void*)(nsISupports*)this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-01-11 23:49:15 +03:00
|
|
|
if (aIID.Equals(NS_GET_IID(nsIDOMEventListener))) {
|
1999-05-04 02:57:48 +04:00
|
|
|
*aInstancePtr = (void*)(nsIDOMEventListener*)this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-01-11 23:49:15 +03:00
|
|
|
if (aIID.Equals(NS_GET_IID(nsIDOMCompositionListener))) {
|
1999-05-04 02:57:48 +04:00
|
|
|
*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)
|
|
|
|
{
|
1999-12-01 03:35:31 +03:00
|
|
|
#ifdef DEBUG_IME
|
1999-10-28 02:56:36 +04:00
|
|
|
printf("nsTextEditorCompositionListener::HandleEvent\n");
|
|
|
|
#endif
|
1999-05-04 02:57:48 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-08-09 05:37:50 +04:00
|
|
|
|
|
|
|
void nsTextEditorCompositionListener::SetEditor(nsIEditor *aEditor)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIEditorIMESupport> imeEditor = do_QueryInterface(aEditor);
|
1999-08-25 14:51:55 +04:00
|
|
|
if (!imeEditor) return; // should return an error here!
|
1999-08-09 05:37:50 +04:00
|
|
|
|
|
|
|
// note that we don't hold an extra reference here.
|
|
|
|
mEditor = imeEditor;
|
|
|
|
}
|
|
|
|
|
1999-05-04 02:57:48 +04:00
|
|
|
nsresult
|
|
|
|
nsTextEditorCompositionListener::HandleStartComposition(nsIDOMEvent* aCompositionEvent)
|
|
|
|
{
|
1999-12-01 03:35:31 +03:00
|
|
|
#ifdef DEBUG_IME
|
1999-10-28 02:56:36 +04:00
|
|
|
printf("nsTextEditorCompositionListener::HandleStartComposition\n");
|
|
|
|
#endif
|
1999-08-31 05:20:32 +04:00
|
|
|
nsCOMPtr<nsIPrivateCompositionEvent> pCompositionEvent = do_QueryInterface(aCompositionEvent);
|
|
|
|
nsTextEventReply* eventReply;
|
|
|
|
|
|
|
|
if (!pCompositionEvent) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsresult rv = pCompositionEvent->GetCompositionReply(&eventReply);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
return mEditor->BeginComposition(eventReply);
|
1999-05-04 02:57:48 +04:00
|
|
|
}
|
1999-12-07 04:29:00 +03:00
|
|
|
nsresult
|
|
|
|
nsTextEditorCompositionListener::HandleQueryComposition(nsIDOMEvent* aCompositionEvent)
|
|
|
|
{
|
|
|
|
#ifdef DEBUG_IME
|
|
|
|
printf("nsTextEditorCompositionListener::HandleQueryComposition\n");
|
|
|
|
#endif
|
|
|
|
nsCOMPtr<nsIPrivateCompositionEvent> pCompositionEvent = do_QueryInterface(aCompositionEvent);
|
|
|
|
nsTextEventReply* eventReply;
|
|
|
|
|
|
|
|
if (!pCompositionEvent) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsresult rv = pCompositionEvent->GetCompositionReply(&eventReply);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
return mEditor->QueryComposition(eventReply);
|
|
|
|
}
|
1999-05-04 02:57:48 +04:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditorCompositionListener::HandleEndComposition(nsIDOMEvent* aCompositionEvent)
|
|
|
|
{
|
1999-12-01 03:35:31 +03:00
|
|
|
#ifdef DEBUG_IME
|
1999-10-28 02:56:36 +04:00
|
|
|
printf("nsTextEditorCompositionListener::HandleEndComposition\n");
|
|
|
|
#endif
|
1999-08-25 14:51:55 +04:00
|
|
|
return mEditor->EndComposition();
|
1999-05-04 02:57:48 +04:00
|
|
|
}
|
|
|
|
|
1999-02-12 20:18:58 +03:00
|
|
|
|
2000-08-05 01:43:29 +04:00
|
|
|
nsresult
|
|
|
|
nsTextEditorCompositionListener::HandleQueryReconversion(nsIDOMEvent* aReconversionEvent)
|
|
|
|
{
|
|
|
|
#ifdef DEBUG_IME
|
|
|
|
printf("nsTextEditorCompositionListener::HandleQueryReconversion\n");
|
|
|
|
#endif
|
|
|
|
nsCOMPtr<nsIPrivateCompositionEvent> pCompositionEvent = do_QueryInterface(aReconversionEvent);
|
|
|
|
nsReconversionEventReply* eventReply;
|
|
|
|
|
|
|
|
if (!pCompositionEvent)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
nsresult rv = pCompositionEvent->GetReconversionReply(&eventReply);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
return mEditor->GetReconversionString(eventReply);
|
|
|
|
}
|
1999-02-12 20:18:58 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Factory functions
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
NS_NewEditorKeyListener(nsIDOMEventListener ** aInstancePtrResult,
|
1999-08-09 05:37:50 +04:00
|
|
|
nsIEditor *aEditor)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
|
|
|
nsTextEditorKeyListener* it = new nsTextEditorKeyListener();
|
|
|
|
if (nsnull == it) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
it->SetEditor(aEditor);
|
|
|
|
|
2000-01-11 23:49:15 +03:00
|
|
|
return it->QueryInterface(NS_GET_IID(nsIDOMEventListener), (void **) aInstancePtrResult);
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
NS_NewEditorMouseListener(nsIDOMEventListener ** aInstancePtrResult,
|
1999-08-09 05:37:50 +04:00
|
|
|
nsIEditor *aEditor)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
|
|
|
nsTextEditorMouseListener* it = new nsTextEditorMouseListener();
|
|
|
|
if (nsnull == it) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
it->SetEditor(aEditor);
|
|
|
|
|
2000-01-11 23:49:15 +03:00
|
|
|
return it->QueryInterface(NS_GET_IID(nsIDOMEventListener), (void **) aInstancePtrResult);
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-03-20 02:36:20 +03:00
|
|
|
nsresult
|
1999-08-09 05:37:50 +04:00
|
|
|
NS_NewEditorTextListener(nsIDOMEventListener** aInstancePtrResult, nsIEditor* aEditor)
|
1999-03-20 02:36:20 +03:00
|
|
|
{
|
1999-08-25 14:51:55 +04:00
|
|
|
nsTextEditorTextListener* it = new nsTextEditorTextListener();
|
|
|
|
if (nsnull==it) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
1999-03-20 02:36:20 +03:00
|
|
|
|
1999-08-25 14:51:55 +04:00
|
|
|
it->SetEditor(aEditor);
|
1999-03-20 02:36:20 +03:00
|
|
|
|
2000-01-11 23:49:15 +03:00
|
|
|
return it->QueryInterface(NS_GET_IID(nsIDOMEventListener), (void **) aInstancePtrResult);
|
1999-03-20 02:36:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-02-12 20:18:58 +03:00
|
|
|
|
1999-03-14 07:45:00 +03:00
|
|
|
nsresult
|
|
|
|
NS_NewEditorDragListener(nsIDOMEventListener ** aInstancePtrResult,
|
1999-08-09 05:37:50 +04:00
|
|
|
nsIEditor *aEditor)
|
1999-03-14 07:45:00 +03:00
|
|
|
{
|
|
|
|
nsTextEditorDragListener* it = new nsTextEditorDragListener();
|
|
|
|
if (nsnull == it) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
it->SetEditor(aEditor);
|
|
|
|
|
2000-01-11 23:49:15 +03:00
|
|
|
return it->QueryInterface(NS_GET_IID(nsIDOMEventListener), (void **) aInstancePtrResult);
|
1999-03-14 07:45:00 +03:00
|
|
|
}
|
|
|
|
|
1999-05-04 02:57:48 +04:00
|
|
|
nsresult
|
1999-08-09 05:37:50 +04:00
|
|
|
NS_NewEditorCompositionListener(nsIDOMEventListener** aInstancePtrResult, nsIEditor* aEditor)
|
1999-05-04 02:57:48 +04:00
|
|
|
{
|
1999-08-25 14:51:55 +04:00
|
|
|
nsTextEditorCompositionListener* it = new nsTextEditorCompositionListener();
|
|
|
|
if (nsnull==it) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
it->SetEditor(aEditor);
|
2000-01-11 23:49:15 +03:00
|
|
|
return it->QueryInterface(NS_GET_IID(nsIDOMEventListener), (void **) aInstancePtrResult);
|
Preparation for ender-based text control
* added focus listener. Doesn't do much yet, but when focus notifications start appearing, we'll be ready for them. The code is in
place to hide selection when we lose focus and paint selection when we get focus. That's probably not quite right, but it's a start.
We will need to be able to determine the distinction between losing focus to another control within our app, and losing focus to
another app.
* added support for disabled and readonly states in the editor. This is accomplished by having flags set by the client, and letting the
rules system deal with those flags. The flags I added are:
TEXT_EDITOR_FLAG_PLAINTEXT 0x01 // only plain text editing is allowed
TEXT_EDITOR_FLAG_SINGLELINE 0x02 // enter key and CR-LF handled specially
TEXT_EDITOR_FLAG_PASSWORD 0x04 // text is not entered into content, only a representative character
TEXT_EDITOR_FLAG_READONLY 0x08 // editing events are disabled. Editor may still accept focus.
TEXT_EDITOR_FLAG_DISALBED 0x10 // all events are disabled (like scrolling). Editor will not accept focus.
* added WillInsertBreak/DidInsertBreak into text rules, so flags could be checked. This gets us readonly, disabled, and single line
behavior.
* cleaned up the code that allocates, registers, and destroys event listeners. Thanks to Kin and Simon for cleaning up the
ownership model on the listeners, it was a big help.
* added support for a max text length. You can now tell the text editor, be no bigger than n characters.
1999-05-29 01:24:18 +04:00
|
|
|
}
|
1999-05-04 02:57:48 +04:00
|
|
|
|
Preparation for ender-based text control
* added focus listener. Doesn't do much yet, but when focus notifications start appearing, we'll be ready for them. The code is in
place to hide selection when we lose focus and paint selection when we get focus. That's probably not quite right, but it's a start.
We will need to be able to determine the distinction between losing focus to another control within our app, and losing focus to
another app.
* added support for disabled and readonly states in the editor. This is accomplished by having flags set by the client, and letting the
rules system deal with those flags. The flags I added are:
TEXT_EDITOR_FLAG_PLAINTEXT 0x01 // only plain text editing is allowed
TEXT_EDITOR_FLAG_SINGLELINE 0x02 // enter key and CR-LF handled specially
TEXT_EDITOR_FLAG_PASSWORD 0x04 // text is not entered into content, only a representative character
TEXT_EDITOR_FLAG_READONLY 0x08 // editing events are disabled. Editor may still accept focus.
TEXT_EDITOR_FLAG_DISALBED 0x10 // all events are disabled (like scrolling). Editor will not accept focus.
* added WillInsertBreak/DidInsertBreak into text rules, so flags could be checked. This gets us readonly, disabled, and single line
behavior.
* cleaned up the code that allocates, registers, and destroys event listeners. Thanks to Kin and Simon for cleaning up the
ownership model on the listeners, it was a big help.
* added support for a max text length. You can now tell the text editor, be no bigger than n characters.
1999-05-29 01:24:18 +04:00
|
|
|
nsresult
|
|
|
|
NS_NewEditorFocusListener(nsIDOMEventListener ** aInstancePtrResult,
|
1999-08-09 05:37:50 +04:00
|
|
|
nsIEditor *aEditor)
|
Preparation for ender-based text control
* added focus listener. Doesn't do much yet, but when focus notifications start appearing, we'll be ready for them. The code is in
place to hide selection when we lose focus and paint selection when we get focus. That's probably not quite right, but it's a start.
We will need to be able to determine the distinction between losing focus to another control within our app, and losing focus to
another app.
* added support for disabled and readonly states in the editor. This is accomplished by having flags set by the client, and letting the
rules system deal with those flags. The flags I added are:
TEXT_EDITOR_FLAG_PLAINTEXT 0x01 // only plain text editing is allowed
TEXT_EDITOR_FLAG_SINGLELINE 0x02 // enter key and CR-LF handled specially
TEXT_EDITOR_FLAG_PASSWORD 0x04 // text is not entered into content, only a representative character
TEXT_EDITOR_FLAG_READONLY 0x08 // editing events are disabled. Editor may still accept focus.
TEXT_EDITOR_FLAG_DISALBED 0x10 // all events are disabled (like scrolling). Editor will not accept focus.
* added WillInsertBreak/DidInsertBreak into text rules, so flags could be checked. This gets us readonly, disabled, and single line
behavior.
* cleaned up the code that allocates, registers, and destroys event listeners. Thanks to Kin and Simon for cleaning up the
ownership model on the listeners, it was a big help.
* added support for a max text length. You can now tell the text editor, be no bigger than n characters.
1999-05-29 01:24:18 +04:00
|
|
|
{
|
|
|
|
nsTextEditorFocusListener* it = new nsTextEditorFocusListener();
|
|
|
|
if (nsnull == it) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
it->SetEditor(aEditor);
|
2000-01-11 23:49:15 +03:00
|
|
|
return it->QueryInterface(NS_GET_IID(nsIDOMEventListener), (void **) aInstancePtrResult);
|
1999-05-04 02:57:48 +04:00
|
|
|
}
|
1999-02-12 20:18:58 +03:00
|
|
|
|
1999-03-20 02:36:20 +03:00
|
|
|
|
Preparation for ender-based text control
* added focus listener. Doesn't do much yet, but when focus notifications start appearing, we'll be ready for them. The code is in
place to hide selection when we lose focus and paint selection when we get focus. That's probably not quite right, but it's a start.
We will need to be able to determine the distinction between losing focus to another control within our app, and losing focus to
another app.
* added support for disabled and readonly states in the editor. This is accomplished by having flags set by the client, and letting the
rules system deal with those flags. The flags I added are:
TEXT_EDITOR_FLAG_PLAINTEXT 0x01 // only plain text editing is allowed
TEXT_EDITOR_FLAG_SINGLELINE 0x02 // enter key and CR-LF handled specially
TEXT_EDITOR_FLAG_PASSWORD 0x04 // text is not entered into content, only a representative character
TEXT_EDITOR_FLAG_READONLY 0x08 // editing events are disabled. Editor may still accept focus.
TEXT_EDITOR_FLAG_DISALBED 0x10 // all events are disabled (like scrolling). Editor will not accept focus.
* added WillInsertBreak/DidInsertBreak into text rules, so flags could be checked. This gets us readonly, disabled, and single line
behavior.
* cleaned up the code that allocates, registers, and destroys event listeners. Thanks to Kin and Simon for cleaning up the
ownership model on the listeners, it was a big help.
* added support for a max text length. You can now tell the text editor, be no bigger than n characters.
1999-05-29 01:24:18 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* nsTextEditorFocusListener implementation
|
|
|
|
*/
|
|
|
|
|
|
|
|
NS_IMPL_ADDREF(nsTextEditorFocusListener)
|
|
|
|
|
|
|
|
NS_IMPL_RELEASE(nsTextEditorFocusListener)
|
|
|
|
|
|
|
|
|
|
|
|
nsTextEditorFocusListener::nsTextEditorFocusListener()
|
|
|
|
{
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
}
|
|
|
|
|
|
|
|
nsTextEditorFocusListener::~nsTextEditorFocusListener()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditorFocusListener::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|
|
|
{
|
|
|
|
if (nsnull == aInstancePtr) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
static NS_DEFINE_IID(kIDOMFocusListenerIID, NS_IDOMFOCUSLISTENER_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(kIDOMFocusListenerIID)) {
|
|
|
|
*aInstancePtr = (void*)(nsIDOMFocusListener*)this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditorFocusListener::HandleEvent(nsIDOMEvent* aEvent)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-08-02 17:53:23 +04:00
|
|
|
nsTextEditorFocusListener::Focus(nsIDOMEvent* aEvent)
|
Preparation for ender-based text control
* added focus listener. Doesn't do much yet, but when focus notifications start appearing, we'll be ready for them. The code is in
place to hide selection when we lose focus and paint selection when we get focus. That's probably not quite right, but it's a start.
We will need to be able to determine the distinction between losing focus to another control within our app, and losing focus to
another app.
* added support for disabled and readonly states in the editor. This is accomplished by having flags set by the client, and letting the
rules system deal with those flags. The flags I added are:
TEXT_EDITOR_FLAG_PLAINTEXT 0x01 // only plain text editing is allowed
TEXT_EDITOR_FLAG_SINGLELINE 0x02 // enter key and CR-LF handled specially
TEXT_EDITOR_FLAG_PASSWORD 0x04 // text is not entered into content, only a representative character
TEXT_EDITOR_FLAG_READONLY 0x08 // editing events are disabled. Editor may still accept focus.
TEXT_EDITOR_FLAG_DISALBED 0x10 // all events are disabled (like scrolling). Editor will not accept focus.
* added WillInsertBreak/DidInsertBreak into text rules, so flags could be checked. This gets us readonly, disabled, and single line
behavior.
* cleaned up the code that allocates, registers, and destroys event listeners. Thanks to Kin and Simon for cleaning up the
ownership model on the listeners, it was a big help.
* added support for a max text length. You can now tell the text editor, be no bigger than n characters.
1999-05-29 01:24:18 +04:00
|
|
|
{
|
|
|
|
// turn on selection and caret
|
|
|
|
if (mEditor)
|
|
|
|
{
|
1999-08-07 09:28:57 +04:00
|
|
|
PRUint32 flags;
|
2000-06-10 01:13:03 +04:00
|
|
|
aEvent->PreventBubble();
|
1999-08-07 09:28:57 +04:00
|
|
|
mEditor->GetFlags(&flags);
|
1999-08-09 05:37:50 +04:00
|
|
|
if (! (flags & nsIHTMLEditor::eEditorDisabledMask))
|
1999-08-07 09:28:57 +04:00
|
|
|
{ // only enable caret and selection if the editor is not disabled
|
|
|
|
nsCOMPtr<nsIEditor>editor = do_QueryInterface(mEditor);
|
|
|
|
if (editor)
|
Preparation for ender-based text control
* added focus listener. Doesn't do much yet, but when focus notifications start appearing, we'll be ready for them. The code is in
place to hide selection when we lose focus and paint selection when we get focus. That's probably not quite right, but it's a start.
We will need to be able to determine the distinction between losing focus to another control within our app, and losing focus to
another app.
* added support for disabled and readonly states in the editor. This is accomplished by having flags set by the client, and letting the
rules system deal with those flags. The flags I added are:
TEXT_EDITOR_FLAG_PLAINTEXT 0x01 // only plain text editing is allowed
TEXT_EDITOR_FLAG_SINGLELINE 0x02 // enter key and CR-LF handled specially
TEXT_EDITOR_FLAG_PASSWORD 0x04 // text is not entered into content, only a representative character
TEXT_EDITOR_FLAG_READONLY 0x08 // editing events are disabled. Editor may still accept focus.
TEXT_EDITOR_FLAG_DISALBED 0x10 // all events are disabled (like scrolling). Editor will not accept focus.
* added WillInsertBreak/DidInsertBreak into text rules, so flags could be checked. This gets us readonly, disabled, and single line
behavior.
* cleaned up the code that allocates, registers, and destroys event listeners. Thanks to Kin and Simon for cleaning up the
ownership model on the listeners, it was a big help.
* added support for a max text length. You can now tell the text editor, be no bigger than n characters.
1999-05-29 01:24:18 +04:00
|
|
|
{
|
2000-04-27 11:37:12 +04:00
|
|
|
nsCOMPtr<nsISelectionController>selCon;
|
|
|
|
editor->GetSelectionController(getter_AddRefs(selCon));
|
|
|
|
if (selCon)
|
Preparation for ender-based text control
* added focus listener. Doesn't do much yet, but when focus notifications start appearing, we'll be ready for them. The code is in
place to hide selection when we lose focus and paint selection when we get focus. That's probably not quite right, but it's a start.
We will need to be able to determine the distinction between losing focus to another control within our app, and losing focus to
another app.
* added support for disabled and readonly states in the editor. This is accomplished by having flags set by the client, and letting the
rules system deal with those flags. The flags I added are:
TEXT_EDITOR_FLAG_PLAINTEXT 0x01 // only plain text editing is allowed
TEXT_EDITOR_FLAG_SINGLELINE 0x02 // enter key and CR-LF handled specially
TEXT_EDITOR_FLAG_PASSWORD 0x04 // text is not entered into content, only a representative character
TEXT_EDITOR_FLAG_READONLY 0x08 // editing events are disabled. Editor may still accept focus.
TEXT_EDITOR_FLAG_DISALBED 0x10 // all events are disabled (like scrolling). Editor will not accept focus.
* added WillInsertBreak/DidInsertBreak into text rules, so flags could be checked. This gets us readonly, disabled, and single line
behavior.
* cleaned up the code that allocates, registers, and destroys event listeners. Thanks to Kin and Simon for cleaning up the
ownership model on the listeners, it was a big help.
* added support for a max text length. You can now tell the text editor, be no bigger than n characters.
1999-05-29 01:24:18 +04:00
|
|
|
{
|
1999-08-09 05:37:50 +04:00
|
|
|
if (! (flags & nsIHTMLEditor::eEditorReadonlyMask))
|
1999-08-07 09:28:57 +04:00
|
|
|
{ // only enable caret if the editor is not readonly
|
2000-07-29 02:12:45 +04:00
|
|
|
PRInt32 pixelWidth;
|
|
|
|
nsresult result;
|
|
|
|
|
|
|
|
NS_WITH_SERVICE(nsILookAndFeel, look, kLookAndFeelCID, &result);
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(result) && look)
|
|
|
|
{
|
|
|
|
if(flags & nsIHTMLEditor::eEditorSingleLineMask)
|
|
|
|
look->GetMetric(nsILookAndFeel::eMetric_SingleLineCaretWidth, pixelWidth);
|
|
|
|
else
|
|
|
|
look->GetMetric(nsILookAndFeel::eMetric_MultiLineCaretWidth, pixelWidth);
|
|
|
|
}
|
|
|
|
|
|
|
|
selCon->SetCaretWidth(pixelWidth);
|
2000-04-27 11:37:12 +04:00
|
|
|
selCon->SetCaretEnabled(PR_TRUE);
|
1999-08-07 09:28:57 +04:00
|
|
|
|
2000-07-29 02:12:45 +04:00
|
|
|
}
|
2000-04-28 10:20:36 +04:00
|
|
|
selCon->SetDisplaySelection(nsISelectionController::SELECTION_ON);
|
1999-08-31 05:14:40 +04:00
|
|
|
#ifdef USE_HACK_REPAINT
|
1999-08-07 09:28:57 +04:00
|
|
|
// begin hack repaint
|
|
|
|
nsCOMPtr<nsIViewManager> viewmgr;
|
|
|
|
ps->GetViewManager(getter_AddRefs(viewmgr));
|
|
|
|
if (viewmgr) {
|
|
|
|
nsIView* view;
|
1999-08-25 14:51:55 +04:00
|
|
|
viewmgr->GetRootView(view); // views are not refCounted
|
1999-08-07 09:28:57 +04:00
|
|
|
if (view) {
|
1999-11-14 05:51:25 +03:00
|
|
|
viewmgr->UpdateView(view,NS_VMREFRESH_IMMEDIATE);
|
1999-08-07 09:28:57 +04:00
|
|
|
}
|
1999-08-31 04:51:23 +04:00
|
|
|
}
|
1999-08-31 05:14:40 +04:00
|
|
|
// end hack repaint
|
|
|
|
#else
|
2000-04-27 11:37:12 +04:00
|
|
|
selCon->RepaintSelection(nsISelectionController::SELECTION_NORMAL);
|
1999-08-31 05:14:40 +04:00
|
|
|
#endif
|
Preparation for ender-based text control
* added focus listener. Doesn't do much yet, but when focus notifications start appearing, we'll be ready for them. The code is in
place to hide selection when we lose focus and paint selection when we get focus. That's probably not quite right, but it's a start.
We will need to be able to determine the distinction between losing focus to another control within our app, and losing focus to
another app.
* added support for disabled and readonly states in the editor. This is accomplished by having flags set by the client, and letting the
rules system deal with those flags. The flags I added are:
TEXT_EDITOR_FLAG_PLAINTEXT 0x01 // only plain text editing is allowed
TEXT_EDITOR_FLAG_SINGLELINE 0x02 // enter key and CR-LF handled specially
TEXT_EDITOR_FLAG_PASSWORD 0x04 // text is not entered into content, only a representative character
TEXT_EDITOR_FLAG_READONLY 0x08 // editing events are disabled. Editor may still accept focus.
TEXT_EDITOR_FLAG_DISALBED 0x10 // all events are disabled (like scrolling). Editor will not accept focus.
* added WillInsertBreak/DidInsertBreak into text rules, so flags could be checked. This gets us readonly, disabled, and single line
behavior.
* cleaned up the code that allocates, registers, and destroys event listeners. Thanks to Kin and Simon for cleaning up the
ownership model on the listeners, it was a big help.
* added support for a max text length. You can now tell the text editor, be no bigger than n characters.
1999-05-29 01:24:18 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
1999-08-02 17:53:23 +04:00
|
|
|
nsTextEditorFocusListener::Blur(nsIDOMEvent* aEvent)
|
Preparation for ender-based text control
* added focus listener. Doesn't do much yet, but when focus notifications start appearing, we'll be ready for them. The code is in
place to hide selection when we lose focus and paint selection when we get focus. That's probably not quite right, but it's a start.
We will need to be able to determine the distinction between losing focus to another control within our app, and losing focus to
another app.
* added support for disabled and readonly states in the editor. This is accomplished by having flags set by the client, and letting the
rules system deal with those flags. The flags I added are:
TEXT_EDITOR_FLAG_PLAINTEXT 0x01 // only plain text editing is allowed
TEXT_EDITOR_FLAG_SINGLELINE 0x02 // enter key and CR-LF handled specially
TEXT_EDITOR_FLAG_PASSWORD 0x04 // text is not entered into content, only a representative character
TEXT_EDITOR_FLAG_READONLY 0x08 // editing events are disabled. Editor may still accept focus.
TEXT_EDITOR_FLAG_DISALBED 0x10 // all events are disabled (like scrolling). Editor will not accept focus.
* added WillInsertBreak/DidInsertBreak into text rules, so flags could be checked. This gets us readonly, disabled, and single line
behavior.
* cleaned up the code that allocates, registers, and destroys event listeners. Thanks to Kin and Simon for cleaning up the
ownership model on the listeners, it was a big help.
* added support for a max text length. You can now tell the text editor, be no bigger than n characters.
1999-05-29 01:24:18 +04:00
|
|
|
{
|
|
|
|
// turn off selection and caret
|
|
|
|
if (mEditor)
|
|
|
|
{
|
2000-02-23 08:07:42 +03:00
|
|
|
PRUint32 flags;
|
2000-06-10 01:13:03 +04:00
|
|
|
aEvent->PreventBubble();
|
2000-02-23 08:07:42 +03:00
|
|
|
mEditor->GetFlags(&flags);
|
Preparation for ender-based text control
* added focus listener. Doesn't do much yet, but when focus notifications start appearing, we'll be ready for them. The code is in
place to hide selection when we lose focus and paint selection when we get focus. That's probably not quite right, but it's a start.
We will need to be able to determine the distinction between losing focus to another control within our app, and losing focus to
another app.
* added support for disabled and readonly states in the editor. This is accomplished by having flags set by the client, and letting the
rules system deal with those flags. The flags I added are:
TEXT_EDITOR_FLAG_PLAINTEXT 0x01 // only plain text editing is allowed
TEXT_EDITOR_FLAG_SINGLELINE 0x02 // enter key and CR-LF handled specially
TEXT_EDITOR_FLAG_PASSWORD 0x04 // text is not entered into content, only a representative character
TEXT_EDITOR_FLAG_READONLY 0x08 // editing events are disabled. Editor may still accept focus.
TEXT_EDITOR_FLAG_DISALBED 0x10 // all events are disabled (like scrolling). Editor will not accept focus.
* added WillInsertBreak/DidInsertBreak into text rules, so flags could be checked. This gets us readonly, disabled, and single line
behavior.
* cleaned up the code that allocates, registers, and destroys event listeners. Thanks to Kin and Simon for cleaning up the
ownership model on the listeners, it was a big help.
* added support for a max text length. You can now tell the text editor, be no bigger than n characters.
1999-05-29 01:24:18 +04:00
|
|
|
nsCOMPtr<nsIEditor>editor = do_QueryInterface(mEditor);
|
|
|
|
if (editor)
|
|
|
|
{
|
2000-04-27 11:37:12 +04:00
|
|
|
nsCOMPtr<nsISelectionController>selCon;
|
|
|
|
editor->GetSelectionController(getter_AddRefs(selCon));
|
|
|
|
if (selCon)
|
Preparation for ender-based text control
* added focus listener. Doesn't do much yet, but when focus notifications start appearing, we'll be ready for them. The code is in
place to hide selection when we lose focus and paint selection when we get focus. That's probably not quite right, but it's a start.
We will need to be able to determine the distinction between losing focus to another control within our app, and losing focus to
another app.
* added support for disabled and readonly states in the editor. This is accomplished by having flags set by the client, and letting the
rules system deal with those flags. The flags I added are:
TEXT_EDITOR_FLAG_PLAINTEXT 0x01 // only plain text editing is allowed
TEXT_EDITOR_FLAG_SINGLELINE 0x02 // enter key and CR-LF handled specially
TEXT_EDITOR_FLAG_PASSWORD 0x04 // text is not entered into content, only a representative character
TEXT_EDITOR_FLAG_READONLY 0x08 // editing events are disabled. Editor may still accept focus.
TEXT_EDITOR_FLAG_DISALBED 0x10 // all events are disabled (like scrolling). Editor will not accept focus.
* added WillInsertBreak/DidInsertBreak into text rules, so flags could be checked. This gets us readonly, disabled, and single line
behavior.
* cleaned up the code that allocates, registers, and destroys event listeners. Thanks to Kin and Simon for cleaning up the
ownership model on the listeners, it was a big help.
* added support for a max text length. You can now tell the text editor, be no bigger than n characters.
1999-05-29 01:24:18 +04:00
|
|
|
{
|
2000-04-27 11:37:12 +04:00
|
|
|
selCon->SetCaretEnabled(PR_FALSE);
|
2000-08-24 07:54:30 +04:00
|
|
|
if((flags & nsIHTMLEditor::eEditorWidgetMask) ||
|
2000-04-30 22:55:13 +04:00
|
|
|
(flags & nsIHTMLEditor::eEditorPasswordMask) ||
|
|
|
|
(flags & nsIHTMLEditor::eEditorReadonlyMask) ||
|
|
|
|
(flags & nsIHTMLEditor::eEditorDisabledMask) ||
|
|
|
|
(flags & nsIHTMLEditor::eEditorFilterInputMask))
|
|
|
|
{
|
2000-05-11 08:22:32 +04:00
|
|
|
selCon->SetDisplaySelection(nsISelectionController::SELECTION_HIDDEN);//hide but do NOT turn off
|
2000-04-30 22:55:13 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
selCon->SetDisplaySelection(nsISelectionController::SELECTION_DISABLED);
|
|
|
|
}
|
|
|
|
|
1999-08-31 05:14:40 +04:00
|
|
|
#ifdef USE_HACK_REPAINT
|
1999-08-03 10:07:29 +04:00
|
|
|
// begin hack repaint
|
|
|
|
nsCOMPtr<nsIViewManager> viewmgr;
|
|
|
|
ps->GetViewManager(getter_AddRefs(viewmgr));
|
|
|
|
if (viewmgr)
|
|
|
|
{
|
|
|
|
nsIView* view;
|
1999-08-25 14:51:55 +04:00
|
|
|
viewmgr->GetRootView(view); // views are not refCounted
|
1999-08-03 10:07:29 +04:00
|
|
|
if (view) {
|
1999-11-14 05:51:25 +03:00
|
|
|
viewmgr->UpdateView(view,NS_VMREFRESH_IMMEDIATE);
|
1999-08-03 10:07:29 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// end hack repaint
|
1999-08-31 05:14:40 +04:00
|
|
|
#else
|
2000-04-27 11:37:12 +04:00
|
|
|
selCon->RepaintSelection(nsISelectionController::SELECTION_NORMAL);
|
1999-08-31 05:14:40 +04:00
|
|
|
#endif
|
Preparation for ender-based text control
* added focus listener. Doesn't do much yet, but when focus notifications start appearing, we'll be ready for them. The code is in
place to hide selection when we lose focus and paint selection when we get focus. That's probably not quite right, but it's a start.
We will need to be able to determine the distinction between losing focus to another control within our app, and losing focus to
another app.
* added support for disabled and readonly states in the editor. This is accomplished by having flags set by the client, and letting the
rules system deal with those flags. The flags I added are:
TEXT_EDITOR_FLAG_PLAINTEXT 0x01 // only plain text editing is allowed
TEXT_EDITOR_FLAG_SINGLELINE 0x02 // enter key and CR-LF handled specially
TEXT_EDITOR_FLAG_PASSWORD 0x04 // text is not entered into content, only a representative character
TEXT_EDITOR_FLAG_READONLY 0x08 // editing events are disabled. Editor may still accept focus.
TEXT_EDITOR_FLAG_DISALBED 0x10 // all events are disabled (like scrolling). Editor will not accept focus.
* added WillInsertBreak/DidInsertBreak into text rules, so flags could be checked. This gets us readonly, disabled, and single line
behavior.
* cleaned up the code that allocates, registers, and destroys event listeners. Thanks to Kin and Simon for cleaning up the
ownership model on the listeners, it was a big help.
* added support for a max text length. You can now tell the text editor, be no bigger than n characters.
1999-05-29 01:24:18 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|