1999-03-10 22:53:26 +03:00
|
|
|
/* -*- 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "nsTextEditRules.h"
|
1999-08-09 05:37:50 +04:00
|
|
|
|
1999-05-05 08:05:19 +04:00
|
|
|
#include "nsEditor.h"
|
1999-03-15 03:57:32 +03:00
|
|
|
#include "PlaceholderTxn.h"
|
|
|
|
#include "InsertTextTxn.h"
|
1999-08-09 05:37:50 +04:00
|
|
|
|
1999-03-10 22:53:26 +03:00
|
|
|
#include "nsCOMPtr.h"
|
|
|
|
#include "nsIDOMNode.h"
|
|
|
|
#include "nsIDOMElement.h"
|
|
|
|
#include "nsIDOMNodeList.h"
|
|
|
|
#include "nsIDOMSelection.h"
|
|
|
|
#include "nsIDOMRange.h"
|
1999-03-12 05:28:24 +03:00
|
|
|
#include "nsIDOMCharacterData.h"
|
1999-03-13 07:53:21 +03:00
|
|
|
#include "nsIContent.h"
|
1999-06-25 03:36:56 +04:00
|
|
|
#include "nsIContentIterator.h"
|
|
|
|
#include "nsIEnumerator.h"
|
|
|
|
#include "nsLayoutCID.h"
|
As a reminder, we decided to do this based strictly content. Some support for style-based text properties is written, but not used
anywhere any more.
* Cleaned up split and join undo/redo.
* Added TypeInState, a data struct that remembers things about text properties for collapsed selections, so you can type
* Ctrl-B with an insertion point and the next character will be bold.
* Added all the logic to handle inline vs. block elements when setting text properties.
* Added some support for italic and underline as well. Adding these things is pretty easy now. Ctrl-B, Ctrl-I, Ctrl-U for testing bold, italic, underline.
* Added all the logic to make sure we only add style tags where they're needed, so you should never get the same style tag nested within itself, except as needed for block elements.
* Added methods for testing a node to see if a particular style is set. This isn't 100% done yet, but with very little work we could have toolbar buttons that respond to selection changed notification that show the state of bold, italic, underline, etc. in real time. Supports tri-state: whole selection is bold, some of selection is bold, none of selection is bold, ...
* Fully undoable and redoable.
* Added some debug printfs to transactions and editors. all controlled by a gNoisy static in each module. helps me track down undo/redo problems. if the output bugs people enough, I'll shut it off and re-enable it in my local tree.
Noticably missing: make un-bold, make un-italic, etc. This is coming soon.
1999-04-01 21:58:07 +04:00
|
|
|
#include "nsIEditProperty.h"
|
1999-03-10 22:53:26 +03:00
|
|
|
|
1999-06-25 03:36:56 +04:00
|
|
|
static NS_DEFINE_CID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
|
1999-03-15 03:57:32 +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
|
|
|
#define CANCEL_OPERATION_IF_READONLY_OR_DISABLED \
|
1999-08-09 05:37:50 +04:00
|
|
|
if ((mFlags & nsIHTMLEditor::eEditorReadonlyMask) || (mFlags & nsIHTMLEditor::eEditorDisabledMask)) \
|
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
|
|
|
{ \
|
|
|
|
*aCancel = PR_TRUE; \
|
|
|
|
return NS_OK; \
|
|
|
|
};
|
1999-03-13 07:53:21 +03:00
|
|
|
|
1999-04-05 21:21:59 +04:00
|
|
|
/********************************************************
|
1999-03-29 12:02:05 +04:00
|
|
|
* Constructor/Destructor
|
1999-04-05 21:21:59 +04:00
|
|
|
********************************************************/
|
1999-03-29 12:02:05 +04:00
|
|
|
|
1999-08-09 22:39:49 +04:00
|
|
|
nsTextEditRules::nsTextEditRules()
|
1999-08-09 05:37:50 +04:00
|
|
|
: mEditor(nsnull)
|
1999-08-09 22:39:49 +04:00
|
|
|
, mFlags(0) // initialized to 0 ("no flags set"). Real initial value is given in Init()
|
1999-03-10 22:53:26 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
nsTextEditRules::~nsTextEditRules()
|
|
|
|
{
|
1999-03-12 05:28:24 +03:00
|
|
|
// do NOT delete mEditor here. We do not hold a ref count to mEditor. mEditor owns our lifespan.
|
1999-03-10 22:53:26 +03:00
|
|
|
}
|
|
|
|
|
1999-03-29 12:02:05 +04:00
|
|
|
|
1999-04-05 21:21:59 +04:00
|
|
|
/********************************************************
|
1999-03-29 12:02:05 +04:00
|
|
|
* Public methods
|
1999-04-05 21:21:59 +04:00
|
|
|
********************************************************/
|
1999-03-29 12:02:05 +04:00
|
|
|
|
1999-03-10 22:53:26 +03:00
|
|
|
NS_IMETHODIMP
|
1999-08-09 22:39:49 +04:00
|
|
|
nsTextEditRules::Init(nsHTMLEditor *aEditor, PRUint32 aFlags)
|
1999-03-10 22:53:26 +03:00
|
|
|
{
|
|
|
|
if (!aEditor) { return NS_ERROR_NULL_POINTER; }
|
1999-08-09 05:37:50 +04:00
|
|
|
|
|
|
|
mEditor = aEditor; // we hold a non-refcounted reference back to our editor
|
1999-08-09 22:39:49 +04:00
|
|
|
// call SetFlags only aftet mEditor has been initialized!
|
|
|
|
SetFlags(aFlags);
|
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<nsIDOMSelection> selection;
|
|
|
|
mEditor->GetSelection(getter_AddRefs(selection));
|
|
|
|
NS_ASSERTION(selection, "editor cannot get selection");
|
1999-08-24 12:56:51 +04:00
|
|
|
nsresult res = CreateBogusNodeIfNeeded(selection); // this method handles null selection, which should never happen anyway
|
|
|
|
return res;
|
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
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditRules::GetFlags(PRUint32 *aFlags)
|
|
|
|
{
|
|
|
|
if (!aFlags) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
*aFlags = mFlags;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-08-21 02:39:48 +04:00
|
|
|
// Initial style for plaintext
|
|
|
|
static char* PlaintextInitalStyle = "white-space: -moz-pre-wrap; width: 72ch; \
|
|
|
|
font-family: -moz-fixed; \
|
|
|
|
background-color: rgb(255, 255, 255)";
|
|
|
|
|
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
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditRules::SetFlags(PRUint32 aFlags)
|
|
|
|
{
|
1999-07-25 09:34:02 +04:00
|
|
|
if (mFlags == aFlags) return NS_OK;
|
|
|
|
|
|
|
|
// XXX - this won't work if body element already has
|
|
|
|
// a style attribute on it, don't know why.
|
|
|
|
// SetFlags() is really meant to only be called once
|
|
|
|
// and at editor init time.
|
1999-08-09 05:37:50 +04:00
|
|
|
if (aFlags & nsIHTMLEditor::eEditorPlaintextMask)
|
1999-07-25 09:34:02 +04:00
|
|
|
{
|
1999-08-09 05:37:50 +04:00
|
|
|
if (!(mFlags & nsIHTMLEditor::eEditorPlaintextMask))
|
1999-07-25 09:34:02 +04:00
|
|
|
{
|
|
|
|
// we are converting TO a plaintext editor
|
|
|
|
// put a "white-space: pre" style on the body
|
1999-08-09 05:37:50 +04:00
|
|
|
nsCOMPtr<nsIDOMElement> bodyElement;
|
|
|
|
nsresult res = mEditor->GetBodyElement(getter_AddRefs(bodyElement));
|
1999-08-19 17:30:48 +04:00
|
|
|
if (NS_FAILED(res)) return res;
|
|
|
|
if (!bodyElement) return NS_ERROR_NULL_POINTER;
|
|
|
|
// not going through the editor to do this.
|
1999-08-21 02:39:48 +04:00
|
|
|
// XXX This is not the right way to do this; we need an editor style
|
|
|
|
// system so that we can add & replace style attrs.
|
|
|
|
bodyElement->SetAttribute("style", PlaintextInitalStyle);
|
1999-07-25 09:34:02 +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
|
|
|
mFlags = aFlags;
|
1999-03-10 22:53:26 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-04-05 21:21:59 +04:00
|
|
|
NS_IMETHODIMP
|
1999-04-12 16:01:32 +04:00
|
|
|
nsTextEditRules::WillDoAction(nsIDOMSelection *aSelection,
|
|
|
|
nsRulesInfo *aInfo, PRBool *aCancel)
|
1999-03-29 12:02:05 +04:00
|
|
|
{
|
1999-07-25 22:14:44 +04:00
|
|
|
// null selection is legal
|
|
|
|
if (!aInfo || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
1999-06-08 10:04:51 +04:00
|
|
|
|
|
|
|
*aCancel = PR_FALSE;
|
1999-04-12 16:01:32 +04:00
|
|
|
|
|
|
|
// my kingdom for dynamic cast
|
|
|
|
nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo);
|
1999-04-05 21:21:59 +04:00
|
|
|
|
1999-04-12 16:01:32 +04:00
|
|
|
switch (info->action)
|
1999-04-05 21:21:59 +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
|
|
|
case kInsertBreak:
|
|
|
|
return WillInsertBreak(aSelection, aCancel);
|
1999-04-05 21:21:59 +04:00
|
|
|
case kInsertText:
|
1999-04-12 16:01:32 +04:00
|
|
|
return WillInsertText(aSelection,
|
|
|
|
aCancel,
|
|
|
|
info->placeTxn,
|
|
|
|
info->inString,
|
|
|
|
info->outString,
|
1999-06-08 10:04:51 +04:00
|
|
|
info->typeInState,
|
|
|
|
info->maxLength);
|
1999-04-05 21:21:59 +04:00
|
|
|
case kDeleteSelection:
|
1999-06-25 03:36:56 +04:00
|
|
|
return WillDeleteSelection(aSelection, info->collapsedAction, aCancel);
|
1999-04-05 21:21:59 +04:00
|
|
|
case kUndo:
|
|
|
|
return WillUndo(aSelection, aCancel);
|
|
|
|
case kRedo:
|
|
|
|
return WillRedo(aSelection, aCancel);
|
1999-06-08 10:04:51 +04:00
|
|
|
case kSetTextProperty:
|
|
|
|
return WillSetTextProperty(aSelection, aCancel);
|
|
|
|
case kRemoveTextProperty:
|
|
|
|
return WillRemoveTextProperty(aSelection, aCancel);
|
1999-06-25 03:36:56 +04:00
|
|
|
case kOutputText:
|
|
|
|
return WillOutputText(aSelection,
|
1999-09-09 23:39:36 +04:00
|
|
|
info->outputFormat,
|
|
|
|
info->outString,
|
1999-06-25 03:36:56 +04:00
|
|
|
aCancel);
|
1999-04-05 21:21:59 +04:00
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
1999-03-29 12:02:05 +04:00
|
|
|
}
|
1999-04-05 21:21:59 +04:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1999-04-12 16:01:32 +04:00
|
|
|
nsTextEditRules::DidDoAction(nsIDOMSelection *aSelection,
|
|
|
|
nsRulesInfo *aInfo, nsresult aResult)
|
1999-03-29 12:02:05 +04:00
|
|
|
{
|
1999-04-12 16:01:32 +04:00
|
|
|
if (!aSelection || !aInfo)
|
1999-04-05 21:21:59 +04:00
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
1999-04-12 16:01:32 +04:00
|
|
|
// my kingdom for dynamic cast
|
|
|
|
nsTextRulesInfo *info = NS_STATIC_CAST(nsTextRulesInfo*, aInfo);
|
|
|
|
|
|
|
|
switch (info->action)
|
1999-04-05 21:21:59 +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
|
|
|
case kInsertBreak:
|
|
|
|
return DidInsertBreak(aSelection, aResult);
|
1999-04-05 21:21:59 +04:00
|
|
|
case kInsertText:
|
|
|
|
return DidInsertText(aSelection, aResult);
|
|
|
|
case kDeleteSelection:
|
1999-06-25 03:36:56 +04:00
|
|
|
return DidDeleteSelection(aSelection, info->collapsedAction, aResult);
|
1999-04-05 21:21:59 +04:00
|
|
|
case kUndo:
|
|
|
|
return DidUndo(aSelection, aResult);
|
|
|
|
case kRedo:
|
|
|
|
return DidRedo(aSelection, aResult);
|
1999-06-08 10:04:51 +04:00
|
|
|
case kSetTextProperty:
|
|
|
|
return DidSetTextProperty(aSelection, aResult);
|
|
|
|
case kRemoveTextProperty:
|
|
|
|
return DidRemoveTextProperty(aSelection, aResult);
|
1999-06-25 03:36:56 +04:00
|
|
|
case kOutputText:
|
|
|
|
return DidOutputText(aSelection, aResult);
|
1999-04-05 21:21:59 +04:00
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
1999-03-29 12:02:05 +04:00
|
|
|
}
|
1999-09-09 03:32:04 +04:00
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditRules::DocumentIsEmpty(PRBool *aDocumentIsEmpty)
|
|
|
|
{
|
|
|
|
if (!aDocumentIsEmpty)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1999-04-05 21:21:59 +04:00
|
|
|
|
1999-09-09 03:32:04 +04:00
|
|
|
*aDocumentIsEmpty = (mBogusNode.get() != nsnull);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-04-05 21:21:59 +04:00
|
|
|
|
|
|
|
/********************************************************
|
|
|
|
* Protected methods
|
|
|
|
********************************************************/
|
|
|
|
|
1999-03-12 05:28:24 +03:00
|
|
|
|
1999-04-12 16:01:32 +04:00
|
|
|
nsresult
|
1999-03-13 07:53:21 +03:00
|
|
|
nsTextEditRules::WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|
|
|
{
|
1999-08-09 05:37:50 +04:00
|
|
|
if (!aSelection || !aCancel)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
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
|
|
|
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
|
|
|
|
1999-03-13 07:53:21 +03:00
|
|
|
// initialize out param
|
|
|
|
*aCancel = PR_FALSE;
|
|
|
|
|
|
|
|
// check for the magic content node and delete it if it exists
|
1999-03-15 03:57:32 +03:00
|
|
|
if (mBogusNode)
|
1999-03-13 07:53:21 +03:00
|
|
|
{
|
1999-03-15 03:57:32 +03:00
|
|
|
mEditor->DeleteNode(mBogusNode);
|
|
|
|
mBogusNode = do_QueryInterface(nsnull);
|
1999-03-13 07:53:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-04-12 16:01:32 +04:00
|
|
|
nsresult
|
1999-03-13 07:53:21 +03:00
|
|
|
nsTextEditRules::DidInsert(nsIDOMSelection *aSelection, nsresult aResult)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
nsTextEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|
|
|
{
|
|
|
|
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
1999-08-09 05:37:50 +04:00
|
|
|
if (mFlags & nsIHTMLEditor::eEditorSingleLineMask) {
|
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
|
|
|
*aCancel = PR_TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*aCancel = PR_FALSE;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditRules::DidInsertBreak(nsIDOMSelection *aSelection, nsresult aResult)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-04-12 16:01:32 +04:00
|
|
|
nsresult
|
1999-06-08 10:04:51 +04:00
|
|
|
nsTextEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
1999-04-12 16:01:32 +04:00
|
|
|
PRBool *aCancel,
|
|
|
|
PlaceholderTxn **aTxn,
|
1999-07-15 23:13:46 +04:00
|
|
|
const nsString *aInString,
|
|
|
|
nsString *aOutString,
|
|
|
|
TypeInState aTypeInState,
|
|
|
|
PRInt32 aMaxLength)
|
1999-03-13 07:53:21 +03:00
|
|
|
{
|
1999-06-26 02:57:26 +04:00
|
|
|
if (!aSelection || !aCancel || !aInString || !aOutString) {return NS_ERROR_NULL_POINTER;}
|
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
|
|
|
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
1999-06-08 10:04:51 +04:00
|
|
|
|
1999-08-24 12:56:51 +04:00
|
|
|
nsresult res;
|
1999-06-25 03:36:56 +04:00
|
|
|
|
1999-04-13 17:35:08 +04:00
|
|
|
// initialize out params
|
1999-08-24 12:56:51 +04:00
|
|
|
*aCancel = PR_TRUE;
|
|
|
|
*aOutString = *aInString;
|
1999-04-13 17:35:08 +04:00
|
|
|
|
1999-08-24 12:56:51 +04:00
|
|
|
// handle docs with a max length
|
|
|
|
res = TruncateInsertionIfNeeded(aSelection, aInString, aOutString, aMaxLength);
|
|
|
|
if (NS_FAILED(res)) return res;
|
|
|
|
|
1999-09-15 23:43:19 +04:00
|
|
|
// handle password field docs
|
|
|
|
if (mFlags & nsIHTMLEditor::eEditorPasswordMask)
|
As a reminder, we decided to do this based strictly content. Some support for style-based text properties is written, but not used
anywhere any more.
* Cleaned up split and join undo/redo.
* Added TypeInState, a data struct that remembers things about text properties for collapsed selections, so you can type
* Ctrl-B with an insertion point and the next character will be bold.
* Added all the logic to handle inline vs. block elements when setting text properties.
* Added some support for italic and underline as well. Adding these things is pretty easy now. Ctrl-B, Ctrl-I, Ctrl-U for testing bold, italic, underline.
* Added all the logic to make sure we only add style tags where they're needed, so you should never get the same style tag nested within itself, except as needed for block elements.
* Added methods for testing a node to see if a particular style is set. This isn't 100% done yet, but with very little work we could have toolbar buttons that respond to selection changed notification that show the state of bold, italic, underline, etc. in real time. Supports tri-state: whole selection is bold, some of selection is bold, none of selection is bold, ...
* Fully undoable and redoable.
* Added some debug printfs to transactions and editors. all controlled by a gNoisy static in each module. helps me track down undo/redo problems. if the output bugs people enough, I'll shut it off and re-enable it in my local tree.
Noticably missing: make un-bold, make un-italic, etc. This is coming soon.
1999-04-01 21:58:07 +04:00
|
|
|
{
|
1999-09-15 23:43:19 +04:00
|
|
|
res = EchoInsertionToPWBuff(aSelection, aOutString);
|
1999-08-24 12:56:51 +04:00
|
|
|
if (NS_FAILED(res)) return res;
|
As a reminder, we decided to do this based strictly content. Some support for style-based text properties is written, but not used
anywhere any more.
* Cleaned up split and join undo/redo.
* Added TypeInState, a data struct that remembers things about text properties for collapsed selections, so you can type
* Ctrl-B with an insertion point and the next character will be bold.
* Added all the logic to handle inline vs. block elements when setting text properties.
* Added some support for italic and underline as well. Adding these things is pretty easy now. Ctrl-B, Ctrl-I, Ctrl-U for testing bold, italic, underline.
* Added all the logic to make sure we only add style tags where they're needed, so you should never get the same style tag nested within itself, except as needed for block elements.
* Added methods for testing a node to see if a particular style is set. This isn't 100% done yet, but with very little work we could have toolbar buttons that respond to selection changed notification that show the state of bold, italic, underline, etc. in real time. Supports tri-state: whole selection is bold, some of selection is bold, none of selection is bold, ...
* Fully undoable and redoable.
* Added some debug printfs to transactions and editors. all controlled by a gNoisy static in each module. helps me track down undo/redo problems. if the output bugs people enough, I'll shut it off and re-enable it in my local tree.
Noticably missing: make un-bold, make un-italic, etc. This is coming soon.
1999-04-01 21:58:07 +04:00
|
|
|
}
|
1999-09-15 23:43:19 +04:00
|
|
|
|
|
|
|
// do text insertion
|
|
|
|
PRBool bCancel;
|
|
|
|
res = DoTextInsertion(aSelection, &bCancel, aTxn, aOutString, aTypeInState);
|
|
|
|
|
1999-08-24 12:56:51 +04:00
|
|
|
return res;
|
1999-03-13 07:53:21 +03:00
|
|
|
}
|
|
|
|
|
1999-04-12 16:01:32 +04:00
|
|
|
nsresult
|
1999-03-13 07:53:21 +03:00
|
|
|
nsTextEditRules::DidInsertText(nsIDOMSelection *aSelection,
|
|
|
|
nsresult aResult)
|
|
|
|
{
|
|
|
|
return DidInsert(aSelection, aResult);
|
|
|
|
}
|
1999-03-12 05:28:24 +03:00
|
|
|
|
1999-04-12 16:01:32 +04:00
|
|
|
nsresult
|
As a reminder, we decided to do this based strictly content. Some support for style-based text properties is written, but not used
anywhere any more.
* Cleaned up split and join undo/redo.
* Added TypeInState, a data struct that remembers things about text properties for collapsed selections, so you can type
* Ctrl-B with an insertion point and the next character will be bold.
* Added all the logic to handle inline vs. block elements when setting text properties.
* Added some support for italic and underline as well. Adding these things is pretty easy now. Ctrl-B, Ctrl-I, Ctrl-U for testing bold, italic, underline.
* Added all the logic to make sure we only add style tags where they're needed, so you should never get the same style tag nested within itself, except as needed for block elements.
* Added methods for testing a node to see if a particular style is set. This isn't 100% done yet, but with very little work we could have toolbar buttons that respond to selection changed notification that show the state of bold, italic, underline, etc. in real time. Supports tri-state: whole selection is bold, some of selection is bold, none of selection is bold, ...
* Fully undoable and redoable.
* Added some debug printfs to transactions and editors. all controlled by a gNoisy static in each module. helps me track down undo/redo problems. if the output bugs people enough, I'll shut it off and re-enable it in my local tree.
Noticably missing: make un-bold, make un-italic, etc. This is coming soon.
1999-04-01 21:58:07 +04:00
|
|
|
nsTextEditRules::CreateStyleForInsertText(nsIDOMSelection *aSelection, TypeInState &aTypeInState)
|
|
|
|
{
|
|
|
|
// private method, we know aSelection is not null, and that it is collapsed
|
|
|
|
NS_ASSERTION(nsnull!=aSelection, "bad selection");
|
|
|
|
|
|
|
|
// We know at least one style is set and we're about to insert at least one character.
|
|
|
|
// If the selection is in a text node, split the node (even if we're at the beginning or end)
|
|
|
|
// then put the text node inside new inline style parents.
|
|
|
|
// Otherwise, create the text node and the new inline style parents.
|
|
|
|
nsCOMPtr<nsIDOMNode>anchor;
|
|
|
|
PRInt32 offset;
|
1999-08-24 12:56:51 +04:00
|
|
|
nsresult res = aSelection->GetAnchorNode( getter_AddRefs(anchor));
|
|
|
|
if (NS_SUCCEEDED(res) && NS_SUCCEEDED(aSelection->GetAnchorOffset(&offset)) && anchor)
|
As a reminder, we decided to do this based strictly content. Some support for style-based text properties is written, but not used
anywhere any more.
* Cleaned up split and join undo/redo.
* Added TypeInState, a data struct that remembers things about text properties for collapsed selections, so you can type
* Ctrl-B with an insertion point and the next character will be bold.
* Added all the logic to handle inline vs. block elements when setting text properties.
* Added some support for italic and underline as well. Adding these things is pretty easy now. Ctrl-B, Ctrl-I, Ctrl-U for testing bold, italic, underline.
* Added all the logic to make sure we only add style tags where they're needed, so you should never get the same style tag nested within itself, except as needed for block elements.
* Added methods for testing a node to see if a particular style is set. This isn't 100% done yet, but with very little work we could have toolbar buttons that respond to selection changed notification that show the state of bold, italic, underline, etc. in real time. Supports tri-state: whole selection is bold, some of selection is bold, none of selection is bold, ...
* Fully undoable and redoable.
* Added some debug printfs to transactions and editors. all controlled by a gNoisy static in each module. helps me track down undo/redo problems. if the output bugs people enough, I'll shut it off and re-enable it in my local tree.
Noticably missing: make un-bold, make un-italic, etc. This is coming soon.
1999-04-01 21:58:07 +04:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMCharacterData>anchorAsText;
|
|
|
|
anchorAsText = do_QueryInterface(anchor);
|
|
|
|
if (anchorAsText)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode>newTextNode;
|
|
|
|
// create an empty text node by splitting the selected text node according to offset
|
|
|
|
if (0==offset)
|
|
|
|
{
|
1999-08-24 12:56:51 +04:00
|
|
|
res = mEditor->SplitNode(anchorAsText, offset, getter_AddRefs(newTextNode));
|
As a reminder, we decided to do this based strictly content. Some support for style-based text properties is written, but not used
anywhere any more.
* Cleaned up split and join undo/redo.
* Added TypeInState, a data struct that remembers things about text properties for collapsed selections, so you can type
* Ctrl-B with an insertion point and the next character will be bold.
* Added all the logic to handle inline vs. block elements when setting text properties.
* Added some support for italic and underline as well. Adding these things is pretty easy now. Ctrl-B, Ctrl-I, Ctrl-U for testing bold, italic, underline.
* Added all the logic to make sure we only add style tags where they're needed, so you should never get the same style tag nested within itself, except as needed for block elements.
* Added methods for testing a node to see if a particular style is set. This isn't 100% done yet, but with very little work we could have toolbar buttons that respond to selection changed notification that show the state of bold, italic, underline, etc. in real time. Supports tri-state: whole selection is bold, some of selection is bold, none of selection is bold, ...
* Fully undoable and redoable.
* Added some debug printfs to transactions and editors. all controlled by a gNoisy static in each module. helps me track down undo/redo problems. if the output bugs people enough, I'll shut it off and re-enable it in my local tree.
Noticably missing: make un-bold, make un-italic, etc. This is coming soon.
1999-04-01 21:58:07 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PRUint32 length;
|
|
|
|
anchorAsText->GetLength(&length);
|
1999-06-28 17:36:38 +04:00
|
|
|
if (length==(PRUint32)offset)
|
As a reminder, we decided to do this based strictly content. Some support for style-based text properties is written, but not used
anywhere any more.
* Cleaned up split and join undo/redo.
* Added TypeInState, a data struct that remembers things about text properties for collapsed selections, so you can type
* Ctrl-B with an insertion point and the next character will be bold.
* Added all the logic to handle inline vs. block elements when setting text properties.
* Added some support for italic and underline as well. Adding these things is pretty easy now. Ctrl-B, Ctrl-I, Ctrl-U for testing bold, italic, underline.
* Added all the logic to make sure we only add style tags where they're needed, so you should never get the same style tag nested within itself, except as needed for block elements.
* Added methods for testing a node to see if a particular style is set. This isn't 100% done yet, but with very little work we could have toolbar buttons that respond to selection changed notification that show the state of bold, italic, underline, etc. in real time. Supports tri-state: whole selection is bold, some of selection is bold, none of selection is bold, ...
* Fully undoable and redoable.
* Added some debug printfs to transactions and editors. all controlled by a gNoisy static in each module. helps me track down undo/redo problems. if the output bugs people enough, I'll shut it off and re-enable it in my local tree.
Noticably missing: make un-bold, make un-italic, etc. This is coming soon.
1999-04-01 21:58:07 +04:00
|
|
|
{
|
|
|
|
// newTextNode will be the left node
|
1999-08-24 12:56:51 +04:00
|
|
|
res = mEditor->SplitNode(anchorAsText, offset, getter_AddRefs(newTextNode));
|
As a reminder, we decided to do this based strictly content. Some support for style-based text properties is written, but not used
anywhere any more.
* Cleaned up split and join undo/redo.
* Added TypeInState, a data struct that remembers things about text properties for collapsed selections, so you can type
* Ctrl-B with an insertion point and the next character will be bold.
* Added all the logic to handle inline vs. block elements when setting text properties.
* Added some support for italic and underline as well. Adding these things is pretty easy now. Ctrl-B, Ctrl-I, Ctrl-U for testing bold, italic, underline.
* Added all the logic to make sure we only add style tags where they're needed, so you should never get the same style tag nested within itself, except as needed for block elements.
* Added methods for testing a node to see if a particular style is set. This isn't 100% done yet, but with very little work we could have toolbar buttons that respond to selection changed notification that show the state of bold, italic, underline, etc. in real time. Supports tri-state: whole selection is bold, some of selection is bold, none of selection is bold, ...
* Fully undoable and redoable.
* Added some debug printfs to transactions and editors. all controlled by a gNoisy static in each module. helps me track down undo/redo problems. if the output bugs people enough, I'll shut it off and re-enable it in my local tree.
Noticably missing: make un-bold, make un-italic, etc. This is coming soon.
1999-04-01 21:58:07 +04:00
|
|
|
// but we want the right node in this case
|
|
|
|
newTextNode = do_QueryInterface(anchor);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// splitting anchor twice sets newTextNode as an empty text node between
|
|
|
|
// two halves of the original text node
|
1999-08-24 12:56:51 +04:00
|
|
|
res = mEditor->SplitNode(anchorAsText, offset, getter_AddRefs(newTextNode));
|
|
|
|
if (NS_SUCCEEDED(res)) {
|
|
|
|
res = mEditor->SplitNode(anchorAsText, 0, getter_AddRefs(newTextNode));
|
1999-08-19 17:30:48 +04:00
|
|
|
}
|
As a reminder, we decided to do this based strictly content. Some support for style-based text properties is written, but not used
anywhere any more.
* Cleaned up split and join undo/redo.
* Added TypeInState, a data struct that remembers things about text properties for collapsed selections, so you can type
* Ctrl-B with an insertion point and the next character will be bold.
* Added all the logic to handle inline vs. block elements when setting text properties.
* Added some support for italic and underline as well. Adding these things is pretty easy now. Ctrl-B, Ctrl-I, Ctrl-U for testing bold, italic, underline.
* Added all the logic to make sure we only add style tags where they're needed, so you should never get the same style tag nested within itself, except as needed for block elements.
* Added methods for testing a node to see if a particular style is set. This isn't 100% done yet, but with very little work we could have toolbar buttons that respond to selection changed notification that show the state of bold, italic, underline, etc. in real time. Supports tri-state: whole selection is bold, some of selection is bold, none of selection is bold, ...
* Fully undoable and redoable.
* Added some debug printfs to transactions and editors. all controlled by a gNoisy static in each module. helps me track down undo/redo problems. if the output bugs people enough, I'll shut it off and re-enable it in my local tree.
Noticably missing: make un-bold, make un-italic, etc. This is coming soon.
1999-04-01 21:58:07 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// now we have the new text node we are going to insert into.
|
|
|
|
// create style nodes or move it up the content hierarchy as needed.
|
1999-08-24 12:56:51 +04:00
|
|
|
if ((NS_SUCCEEDED(res)) && newTextNode)
|
As a reminder, we decided to do this based strictly content. Some support for style-based text properties is written, but not used
anywhere any more.
* Cleaned up split and join undo/redo.
* Added TypeInState, a data struct that remembers things about text properties for collapsed selections, so you can type
* Ctrl-B with an insertion point and the next character will be bold.
* Added all the logic to handle inline vs. block elements when setting text properties.
* Added some support for italic and underline as well. Adding these things is pretty easy now. Ctrl-B, Ctrl-I, Ctrl-U for testing bold, italic, underline.
* Added all the logic to make sure we only add style tags where they're needed, so you should never get the same style tag nested within itself, except as needed for block elements.
* Added methods for testing a node to see if a particular style is set. This isn't 100% done yet, but with very little work we could have toolbar buttons that respond to selection changed notification that show the state of bold, italic, underline, etc. in real time. Supports tri-state: whole selection is bold, some of selection is bold, none of selection is bold, ...
* Fully undoable and redoable.
* Added some debug printfs to transactions and editors. all controlled by a gNoisy static in each module. helps me track down undo/redo problems. if the output bugs people enough, I'll shut it off and re-enable it in my local tree.
Noticably missing: make un-bold, make un-italic, etc. This is coming soon.
1999-04-01 21:58:07 +04:00
|
|
|
{
|
1999-04-16 22:29:12 +04:00
|
|
|
nsCOMPtr<nsIDOMNode>newStyleNode;
|
As a reminder, we decided to do this based strictly content. Some support for style-based text properties is written, but not used
anywhere any more.
* Cleaned up split and join undo/redo.
* Added TypeInState, a data struct that remembers things about text properties for collapsed selections, so you can type
* Ctrl-B with an insertion point and the next character will be bold.
* Added all the logic to handle inline vs. block elements when setting text properties.
* Added some support for italic and underline as well. Adding these things is pretty easy now. Ctrl-B, Ctrl-I, Ctrl-U for testing bold, italic, underline.
* Added all the logic to make sure we only add style tags where they're needed, so you should never get the same style tag nested within itself, except as needed for block elements.
* Added methods for testing a node to see if a particular style is set. This isn't 100% done yet, but with very little work we could have toolbar buttons that respond to selection changed notification that show the state of bold, italic, underline, etc. in real time. Supports tri-state: whole selection is bold, some of selection is bold, none of selection is bold, ...
* Fully undoable and redoable.
* Added some debug printfs to transactions and editors. all controlled by a gNoisy static in each module. helps me track down undo/redo problems. if the output bugs people enough, I'll shut it off and re-enable it in my local tree.
Noticably missing: make un-bold, make un-italic, etc. This is coming soon.
1999-04-01 21:58:07 +04:00
|
|
|
if (aTypeInState.IsSet(NS_TYPEINSTATE_BOLD))
|
|
|
|
{
|
1999-04-05 00:10:39 +04:00
|
|
|
if (PR_TRUE==aTypeInState.GetBold()) {
|
1999-08-24 12:56:51 +04:00
|
|
|
res = InsertStyleNode(newTextNode, nsIEditProperty::b, aSelection, getter_AddRefs(newStyleNode));
|
1999-04-05 00:10:39 +04:00
|
|
|
}
|
|
|
|
else {
|
1999-04-06 00:52:29 +04:00
|
|
|
printf("not yet implemented, make not bold in a bold context\n");
|
1999-04-05 00:10:39 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (aTypeInState.IsSet(NS_TYPEINSTATE_ITALIC))
|
|
|
|
{
|
|
|
|
if (PR_TRUE==aTypeInState.GetItalic()) {
|
1999-08-24 12:56:51 +04:00
|
|
|
res = InsertStyleNode(newTextNode, nsIEditProperty::i, aSelection, getter_AddRefs(newStyleNode));
|
As a reminder, we decided to do this based strictly content. Some support for style-based text properties is written, but not used
anywhere any more.
* Cleaned up split and join undo/redo.
* Added TypeInState, a data struct that remembers things about text properties for collapsed selections, so you can type
* Ctrl-B with an insertion point and the next character will be bold.
* Added all the logic to handle inline vs. block elements when setting text properties.
* Added some support for italic and underline as well. Adding these things is pretty easy now. Ctrl-B, Ctrl-I, Ctrl-U for testing bold, italic, underline.
* Added all the logic to make sure we only add style tags where they're needed, so you should never get the same style tag nested within itself, except as needed for block elements.
* Added methods for testing a node to see if a particular style is set. This isn't 100% done yet, but with very little work we could have toolbar buttons that respond to selection changed notification that show the state of bold, italic, underline, etc. in real time. Supports tri-state: whole selection is bold, some of selection is bold, none of selection is bold, ...
* Fully undoable and redoable.
* Added some debug printfs to transactions and editors. all controlled by a gNoisy static in each module. helps me track down undo/redo problems. if the output bugs people enough, I'll shut it off and re-enable it in my local tree.
Noticably missing: make un-bold, make un-italic, etc. This is coming soon.
1999-04-01 21:58:07 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-04-06 00:52:29 +04:00
|
|
|
printf("not yet implemented, make not italic in a italic context\n");
|
1999-04-05 00:10:39 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (aTypeInState.IsSet(NS_TYPEINSTATE_UNDERLINE))
|
|
|
|
{
|
1999-04-16 22:29:12 +04:00
|
|
|
if (PR_TRUE==aTypeInState.GetUnderline()) {
|
1999-08-24 12:56:51 +04:00
|
|
|
res = InsertStyleNode(newTextNode, nsIEditProperty::u, aSelection, getter_AddRefs(newStyleNode));
|
1999-04-05 00:10:39 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf("not yet implemented, make not underline in an underline context\n");
|
As a reminder, we decided to do this based strictly content. Some support for style-based text properties is written, but not used
anywhere any more.
* Cleaned up split and join undo/redo.
* Added TypeInState, a data struct that remembers things about text properties for collapsed selections, so you can type
* Ctrl-B with an insertion point and the next character will be bold.
* Added all the logic to handle inline vs. block elements when setting text properties.
* Added some support for italic and underline as well. Adding these things is pretty easy now. Ctrl-B, Ctrl-I, Ctrl-U for testing bold, italic, underline.
* Added all the logic to make sure we only add style tags where they're needed, so you should never get the same style tag nested within itself, except as needed for block elements.
* Added methods for testing a node to see if a particular style is set. This isn't 100% done yet, but with very little work we could have toolbar buttons that respond to selection changed notification that show the state of bold, italic, underline, etc. in real time. Supports tri-state: whole selection is bold, some of selection is bold, none of selection is bold, ...
* Fully undoable and redoable.
* Added some debug printfs to transactions and editors. all controlled by a gNoisy static in each module. helps me track down undo/redo problems. if the output bugs people enough, I'll shut it off and re-enable it in my local tree.
Noticably missing: make un-bold, make un-italic, etc. This is coming soon.
1999-04-01 21:58:07 +04:00
|
|
|
}
|
|
|
|
}
|
1999-04-16 22:29:12 +04:00
|
|
|
if (aTypeInState.IsSet(NS_TYPEINSTATE_FONTCOLOR))
|
|
|
|
{
|
1999-04-20 21:49:34 +04:00
|
|
|
nsAutoString value;
|
1999-04-22 18:46:53 +04:00
|
|
|
aTypeInState.GetFontColor(value);
|
1999-04-20 21:49:34 +04:00
|
|
|
nsAutoString attr;
|
|
|
|
nsIEditProperty::color->ToString(attr);
|
1999-08-24 12:56:51 +04:00
|
|
|
res = CreateFontStyleForInsertText(newTextNode, attr, value, aSelection);
|
1999-04-20 21:49:34 +04:00
|
|
|
}
|
|
|
|
if (aTypeInState.IsSet(NS_TYPEINSTATE_FONTFACE))
|
|
|
|
{
|
|
|
|
nsAutoString value;
|
1999-04-22 18:46:53 +04:00
|
|
|
aTypeInState.GetFontFace(value);
|
1999-04-20 21:49:34 +04:00
|
|
|
nsAutoString attr;
|
|
|
|
nsIEditProperty::face->ToString(attr);
|
1999-08-24 12:56:51 +04:00
|
|
|
res = CreateFontStyleForInsertText(newTextNode, attr, value, aSelection);
|
1999-04-20 21:49:34 +04:00
|
|
|
}
|
|
|
|
if (aTypeInState.IsSet(NS_TYPEINSTATE_FONTSIZE))
|
|
|
|
{
|
|
|
|
nsAutoString value;
|
1999-04-22 18:46:53 +04:00
|
|
|
aTypeInState.GetFontSize(value);
|
1999-04-20 21:49:34 +04:00
|
|
|
nsAutoString attr;
|
|
|
|
nsIEditProperty::size->ToString(attr);
|
1999-08-24 12:56:51 +04:00
|
|
|
res = CreateFontStyleForInsertText(newTextNode, attr, value, aSelection);
|
1999-04-16 22:29:12 +04:00
|
|
|
}
|
As a reminder, we decided to do this based strictly content. Some support for style-based text properties is written, but not used
anywhere any more.
* Cleaned up split and join undo/redo.
* Added TypeInState, a data struct that remembers things about text properties for collapsed selections, so you can type
* Ctrl-B with an insertion point and the next character will be bold.
* Added all the logic to handle inline vs. block elements when setting text properties.
* Added some support for italic and underline as well. Adding these things is pretty easy now. Ctrl-B, Ctrl-I, Ctrl-U for testing bold, italic, underline.
* Added all the logic to make sure we only add style tags where they're needed, so you should never get the same style tag nested within itself, except as needed for block elements.
* Added methods for testing a node to see if a particular style is set. This isn't 100% done yet, but with very little work we could have toolbar buttons that respond to selection changed notification that show the state of bold, italic, underline, etc. in real time. Supports tri-state: whole selection is bold, some of selection is bold, none of selection is bold, ...
* Fully undoable and redoable.
* Added some debug printfs to transactions and editors. all controlled by a gNoisy static in each module. helps me track down undo/redo problems. if the output bugs people enough, I'll shut it off and re-enable it in my local tree.
Noticably missing: make un-bold, make un-italic, etc. This is coming soon.
1999-04-01 21:58:07 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf("not yet implemented. selection is not text.\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else // we have no selection, so insert a style tag in the body
|
|
|
|
{
|
1999-08-19 17:30:48 +04:00
|
|
|
nsCOMPtr<nsIDOMElement> bodyElement;
|
1999-09-18 00:17:22 +04:00
|
|
|
res = mEditor->GetBodyElement(getter_AddRefs(bodyElement));
|
1999-08-19 17:30:48 +04:00
|
|
|
if (NS_FAILED(res)) return res;
|
|
|
|
if (!bodyElement) return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMNode>bodyNode = do_QueryInterface(bodyElement);
|
|
|
|
if (bodyNode)
|
|
|
|
{ // now we've got the body tag. insert the style tag
|
|
|
|
if (aTypeInState.IsSet(NS_TYPEINSTATE_BOLD))
|
|
|
|
{
|
|
|
|
if (PR_TRUE==aTypeInState.GetBold()) {
|
|
|
|
InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::b, aSelection);
|
1999-04-06 00:52:29 +04:00
|
|
|
}
|
1999-08-19 17:30:48 +04:00
|
|
|
}
|
|
|
|
if (aTypeInState.IsSet(NS_TYPEINSTATE_ITALIC))
|
|
|
|
{
|
|
|
|
if (PR_TRUE==aTypeInState.GetItalic()) {
|
|
|
|
InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::i, aSelection);
|
1999-04-06 00:52:29 +04:00
|
|
|
}
|
1999-08-19 17:30:48 +04:00
|
|
|
}
|
|
|
|
if (aTypeInState.IsSet(NS_TYPEINSTATE_UNDERLINE))
|
|
|
|
{
|
|
|
|
if (PR_TRUE==aTypeInState.GetUnderline()) {
|
|
|
|
InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::u, aSelection);
|
As a reminder, we decided to do this based strictly content. Some support for style-based text properties is written, but not used
anywhere any more.
* Cleaned up split and join undo/redo.
* Added TypeInState, a data struct that remembers things about text properties for collapsed selections, so you can type
* Ctrl-B with an insertion point and the next character will be bold.
* Added all the logic to handle inline vs. block elements when setting text properties.
* Added some support for italic and underline as well. Adding these things is pretty easy now. Ctrl-B, Ctrl-I, Ctrl-U for testing bold, italic, underline.
* Added all the logic to make sure we only add style tags where they're needed, so you should never get the same style tag nested within itself, except as needed for block elements.
* Added methods for testing a node to see if a particular style is set. This isn't 100% done yet, but with very little work we could have toolbar buttons that respond to selection changed notification that show the state of bold, italic, underline, etc. in real time. Supports tri-state: whole selection is bold, some of selection is bold, none of selection is bold, ...
* Fully undoable and redoable.
* Added some debug printfs to transactions and editors. all controlled by a gNoisy static in each module. helps me track down undo/redo problems. if the output bugs people enough, I'll shut it off and re-enable it in my local tree.
Noticably missing: make un-bold, make un-italic, etc. This is coming soon.
1999-04-01 21:58:07 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-08-24 12:56:51 +04:00
|
|
|
return res;
|
As a reminder, we decided to do this based strictly content. Some support for style-based text properties is written, but not used
anywhere any more.
* Cleaned up split and join undo/redo.
* Added TypeInState, a data struct that remembers things about text properties for collapsed selections, so you can type
* Ctrl-B with an insertion point and the next character will be bold.
* Added all the logic to handle inline vs. block elements when setting text properties.
* Added some support for italic and underline as well. Adding these things is pretty easy now. Ctrl-B, Ctrl-I, Ctrl-U for testing bold, italic, underline.
* Added all the logic to make sure we only add style tags where they're needed, so you should never get the same style tag nested within itself, except as needed for block elements.
* Added methods for testing a node to see if a particular style is set. This isn't 100% done yet, but with very little work we could have toolbar buttons that respond to selection changed notification that show the state of bold, italic, underline, etc. in real time. Supports tri-state: whole selection is bold, some of selection is bold, none of selection is bold, ...
* Fully undoable and redoable.
* Added some debug printfs to transactions and editors. all controlled by a gNoisy static in each module. helps me track down undo/redo problems. if the output bugs people enough, I'll shut it off and re-enable it in my local tree.
Noticably missing: make un-bold, make un-italic, etc. This is coming soon.
1999-04-01 21:58:07 +04:00
|
|
|
}
|
|
|
|
|
1999-04-20 21:49:34 +04:00
|
|
|
nsresult
|
|
|
|
nsTextEditRules::CreateFontStyleForInsertText(nsIDOMNode *aNewTextNode,
|
|
|
|
const nsString &aAttr,
|
|
|
|
const nsString &aValue,
|
|
|
|
nsIDOMSelection *aSelection)
|
|
|
|
{
|
1999-08-24 12:56:51 +04:00
|
|
|
nsresult res = NS_OK;
|
1999-04-20 21:49:34 +04:00
|
|
|
nsCOMPtr<nsIDOMNode>newStyleNode;
|
|
|
|
if (0!=aValue.Length())
|
|
|
|
{
|
1999-08-24 12:56:51 +04:00
|
|
|
res = InsertStyleNode(aNewTextNode, nsIEditProperty::font, aSelection, getter_AddRefs(newStyleNode));
|
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
if (!newStyleNode) return NS_ERROR_NULL_POINTER;
|
|
|
|
nsCOMPtr<nsIDOMElement>element = do_QueryInterface(newStyleNode);
|
|
|
|
if (element) {
|
1999-08-24 12:56:51 +04:00
|
|
|
res = mEditor->SetAttribute(element, aAttr, aValue);
|
1999-04-20 21:49:34 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf("not yet implemented, undo font in an font context\n");
|
|
|
|
}
|
1999-08-24 12:56:51 +04:00
|
|
|
return res;
|
1999-04-20 21:49:34 +04:00
|
|
|
}
|
|
|
|
|
1999-04-12 16:01:32 +04:00
|
|
|
nsresult
|
1999-04-16 22:29:12 +04:00
|
|
|
nsTextEditRules::InsertStyleNode(nsIDOMNode *aNode,
|
|
|
|
nsIAtom *aTag,
|
|
|
|
nsIDOMSelection *aSelection,
|
|
|
|
nsIDOMNode **aNewNode)
|
1999-04-05 00:10:39 +04:00
|
|
|
{
|
|
|
|
NS_ASSERTION(aNode && aTag, "bad args");
|
|
|
|
if (!aNode || !aTag) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
|
1999-08-24 12:56:51 +04:00
|
|
|
nsresult res;
|
1999-04-05 00:10:39 +04:00
|
|
|
nsCOMPtr<nsIDOMNode>parent;
|
|
|
|
aNode->GetParentNode(getter_AddRefs(parent));
|
1999-08-24 12:56:51 +04:00
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
if (!parent) return NS_ERROR_NULL_POINTER;
|
|
|
|
|
1999-04-05 00:10:39 +04:00
|
|
|
PRInt32 offsetInParent;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = nsEditor::GetChildOffset(aNode, parent, offsetInParent);
|
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
|
1999-04-05 00:10:39 +04:00
|
|
|
nsAutoString tag;
|
|
|
|
aTag->ToString(tag);
|
1999-08-24 12:56:51 +04:00
|
|
|
res = mEditor->CreateNode(tag, parent, offsetInParent, aNewNode);
|
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
if (!aNewNode) return NS_ERROR_NULL_POINTER;
|
|
|
|
|
1999-08-24 12:56:51 +04:00
|
|
|
res = mEditor->DeleteNode(aNode);
|
|
|
|
if (NS_SUCCEEDED(res))
|
1999-04-05 00:10:39 +04:00
|
|
|
{
|
1999-08-24 12:56:51 +04:00
|
|
|
res = mEditor->InsertNode(aNode, *aNewNode, 0);
|
|
|
|
if (NS_SUCCEEDED(res)) {
|
1999-08-19 17:30:48 +04:00
|
|
|
if (aSelection) {
|
1999-08-24 12:56:51 +04:00
|
|
|
res = aSelection->Collapse(aNode, 0);
|
1999-04-05 00:10:39 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-08-24 12:56:51 +04:00
|
|
|
return res;
|
1999-04-05 00:10:39 +04:00
|
|
|
}
|
|
|
|
|
As a reminder, we decided to do this based strictly content. Some support for style-based text properties is written, but not used
anywhere any more.
* Cleaned up split and join undo/redo.
* Added TypeInState, a data struct that remembers things about text properties for collapsed selections, so you can type
* Ctrl-B with an insertion point and the next character will be bold.
* Added all the logic to handle inline vs. block elements when setting text properties.
* Added some support for italic and underline as well. Adding these things is pretty easy now. Ctrl-B, Ctrl-I, Ctrl-U for testing bold, italic, underline.
* Added all the logic to make sure we only add style tags where they're needed, so you should never get the same style tag nested within itself, except as needed for block elements.
* Added methods for testing a node to see if a particular style is set. This isn't 100% done yet, but with very little work we could have toolbar buttons that respond to selection changed notification that show the state of bold, italic, underline, etc. in real time. Supports tri-state: whole selection is bold, some of selection is bold, none of selection is bold, ...
* Fully undoable and redoable.
* Added some debug printfs to transactions and editors. all controlled by a gNoisy static in each module. helps me track down undo/redo problems. if the output bugs people enough, I'll shut it off and re-enable it in my local tree.
Noticably missing: make un-bold, make un-italic, etc. This is coming soon.
1999-04-01 21:58:07 +04:00
|
|
|
|
1999-04-12 16:01:32 +04:00
|
|
|
nsresult
|
1999-04-06 00:52:29 +04:00
|
|
|
nsTextEditRules::InsertStyleAndNewTextNode(nsIDOMNode *aParentNode, nsIAtom *aTag, nsIDOMSelection *aSelection)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aParentNode && aTag, "bad args");
|
|
|
|
if (!aParentNode || !aTag) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
|
1999-08-24 12:56:51 +04:00
|
|
|
nsresult res;
|
1999-04-06 00:52:29 +04:00
|
|
|
// if the selection already points to a text node, just call InsertStyleNode()
|
|
|
|
if (aSelection)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode>anchor;
|
|
|
|
PRInt32 offset;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = aSelection->GetAnchorNode(getter_AddRefs(anchor));
|
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
if (!anchor) return NS_ERROR_NULL_POINTER;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = aSelection->GetAnchorOffset(&offset);
|
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
nsCOMPtr<nsIDOMCharacterData>anchorAsText;
|
|
|
|
anchorAsText = do_QueryInterface(anchor);
|
|
|
|
if (anchorAsText)
|
1999-04-06 00:52:29 +04:00
|
|
|
{
|
1999-08-19 17:30:48 +04:00
|
|
|
nsCOMPtr<nsIDOMNode> newStyleNode;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = InsertStyleNode(anchor, aTag, aSelection, getter_AddRefs(newStyleNode));
|
|
|
|
return res;
|
1999-04-06 00:52:29 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// if we get here, there is no selected text node so we create one.
|
|
|
|
nsAutoString tag;
|
|
|
|
aTag->ToString(tag);
|
|
|
|
nsCOMPtr<nsIDOMNode>newStyleNode;
|
|
|
|
nsCOMPtr<nsIDOMNode>newTextNode;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = mEditor->CreateNode(tag, aParentNode, 0, getter_AddRefs(newStyleNode));
|
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
if (!newStyleNode) return NS_ERROR_NULL_POINTER;
|
|
|
|
|
1999-08-31 02:11:09 +04:00
|
|
|
nsAutoString textNodeTag;
|
|
|
|
res = nsEditor::GetTextNodeTag(textNodeTag);
|
|
|
|
if (NS_FAILED(res)) { return res; }
|
|
|
|
|
|
|
|
res = mEditor->CreateNode(textNodeTag, newStyleNode, 0, getter_AddRefs(newTextNode));
|
1999-08-24 12:56:51 +04:00
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
if (!newTextNode) return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
if (aSelection) {
|
1999-08-24 12:56:51 +04:00
|
|
|
res = aSelection->Collapse(newTextNode, 0);
|
1999-04-06 00:52:29 +04:00
|
|
|
}
|
1999-08-24 12:56:51 +04:00
|
|
|
return res;
|
1999-04-06 00:52:29 +04:00
|
|
|
}
|
|
|
|
|
1999-06-08 10:04:51 +04:00
|
|
|
nsresult
|
|
|
|
nsTextEditRules::WillSetTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|
|
|
{
|
1999-08-24 12:56:51 +04:00
|
|
|
nsresult res = NS_OK;
|
1999-06-08 10:04:51 +04:00
|
|
|
|
|
|
|
// XXX: should probably return a success value other than NS_OK that means "not allowed"
|
1999-08-09 05:37:50 +04:00
|
|
|
if (nsIHTMLEditor::eEditorPlaintextMask & mFlags) {
|
1999-06-08 10:04:51 +04:00
|
|
|
*aCancel = PR_TRUE;
|
|
|
|
}
|
1999-08-24 12:56:51 +04:00
|
|
|
return res;
|
1999-06-08 10:04:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditRules::DidSetTextProperty(nsIDOMSelection *aSelection, nsresult aResult)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditRules::WillRemoveTextProperty(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|
|
|
{
|
1999-08-24 12:56:51 +04:00
|
|
|
nsresult res = NS_OK;
|
1999-06-08 10:04:51 +04:00
|
|
|
|
|
|
|
// XXX: should probably return a success value other than NS_OK that means "not allowed"
|
1999-08-09 05:37:50 +04:00
|
|
|
if (nsIHTMLEditor::eEditorPlaintextMask & mFlags) {
|
1999-06-08 10:04:51 +04:00
|
|
|
*aCancel = PR_TRUE;
|
|
|
|
}
|
1999-08-24 12:56:51 +04:00
|
|
|
return res;
|
1999-06-08 10:04:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditRules::DidRemoveTextProperty(nsIDOMSelection *aSelection, nsresult aResult)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-04-12 16:01:32 +04:00
|
|
|
nsresult
|
1999-06-25 03:36:56 +04:00
|
|
|
nsTextEditRules::WillDeleteSelection(nsIDOMSelection *aSelection,
|
1999-08-09 05:37:50 +04:00
|
|
|
nsIEditor::ESelectionCollapseDirection aCollapsedAction,
|
1999-06-25 03:36:56 +04:00
|
|
|
PRBool *aCancel)
|
1999-03-10 22:53:26 +03:00
|
|
|
{
|
1999-03-12 05:28:24 +03:00
|
|
|
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
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
|
|
|
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
|
|
|
|
1999-03-12 05:28:24 +03:00
|
|
|
// initialize out param
|
|
|
|
*aCancel = PR_FALSE;
|
1999-03-13 07:53:21 +03:00
|
|
|
|
|
|
|
// if there is only bogus content, cancel the operation
|
1999-03-15 03:57:32 +03:00
|
|
|
if (mBogusNode) {
|
|
|
|
*aCancel = PR_TRUE;
|
|
|
|
return NS_OK;
|
1999-03-13 07:53:21 +03:00
|
|
|
}
|
1999-08-09 05:37:50 +04:00
|
|
|
if (mFlags & nsIHTMLEditor::eEditorPasswordMask)
|
1999-06-25 03:36:56 +04:00
|
|
|
{
|
|
|
|
// manage the password buffer
|
|
|
|
PRInt32 start, end;
|
1999-06-28 17:36:38 +04:00
|
|
|
mEditor->GetTextSelectionOffsets(aSelection, start, end);
|
1999-06-25 03:36:56 +04:00
|
|
|
if (end==start)
|
|
|
|
{ // collapsed selection
|
1999-08-09 05:37:50 +04:00
|
|
|
if (nsIEditor::eDeletePrevious==aCollapsedAction && 0<start) { // del back
|
1999-06-25 03:36:56 +04:00
|
|
|
mPasswordText.Cut(start-1, 1);
|
|
|
|
}
|
1999-08-09 05:37:50 +04:00
|
|
|
else if (nsIEditor::eDeleteNext==aCollapsedAction) { // del forward
|
1999-06-25 03:36:56 +04:00
|
|
|
mPasswordText.Cut(start, 1);
|
|
|
|
}
|
|
|
|
// otherwise nothing to do for this collapsed selection
|
|
|
|
}
|
|
|
|
else { // extended selection
|
|
|
|
mPasswordText.Cut(start, end-start);
|
|
|
|
}
|
|
|
|
|
1999-09-03 12:31:33 +04:00
|
|
|
#ifdef DEBUG_buster
|
1999-06-25 03:36:56 +04:00
|
|
|
char *password = mPasswordText.ToNewCString();
|
|
|
|
printf("mPasswordText is %s\n", password);
|
1999-09-06 10:22:51 +04:00
|
|
|
nsCRT::free(password);
|
1999-09-03 12:31:33 +04:00
|
|
|
#endif
|
1999-06-25 03:36:56 +04:00
|
|
|
}
|
1999-03-12 05:28:24 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if the document is empty, insert a bogus text node with a
|
1999-03-16 19:38:09 +03:00
|
|
|
// if we ended up with consecutive text nodes, merge them
|
1999-04-12 16:01:32 +04:00
|
|
|
nsresult
|
1999-06-25 03:36:56 +04:00
|
|
|
nsTextEditRules::DidDeleteSelection(nsIDOMSelection *aSelection,
|
1999-08-09 05:37:50 +04:00
|
|
|
nsIEditor::ESelectionCollapseDirection aCollapsedAction,
|
1999-06-25 03:36:56 +04:00
|
|
|
nsresult aResult)
|
1999-03-12 05:28:24 +03:00
|
|
|
{
|
1999-08-24 12:56:51 +04:00
|
|
|
nsresult res = aResult; // if aResult is an error, we just return it
|
1999-03-12 05:28:24 +03:00
|
|
|
if (!aSelection) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
PRBool isCollapsed;
|
1999-07-18 06:27:19 +04:00
|
|
|
aSelection->GetIsCollapsed(&isCollapsed);
|
1999-03-12 05:28:24 +03:00
|
|
|
NS_ASSERTION(PR_TRUE==isCollapsed, "selection not collapsed after delete selection.");
|
|
|
|
// if the delete selection resulted in no content
|
|
|
|
// insert a special bogus text node with a character in it.
|
1999-08-24 12:56:51 +04:00
|
|
|
if (NS_SUCCEEDED(res)) // only do this work if DeleteSelection completed successfully
|
1999-03-12 05:28:24 +03:00
|
|
|
{
|
1999-08-24 12:56:51 +04:00
|
|
|
res = CreateBogusNodeIfNeeded(aSelection);
|
1999-03-16 19:38:09 +03:00
|
|
|
// if we don't have an empty document, check the selection to see if any collapsing is necessary
|
|
|
|
if (!mBogusNode)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode>anchor;
|
|
|
|
PRInt32 offset;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = aSelection->GetAnchorNode(getter_AddRefs(anchor));
|
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
if (!anchor) return NS_ERROR_NULL_POINTER;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = aSelection->GetAnchorOffset(&offset);
|
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMNodeList> anchorChildren;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = anchor->GetChildNodes(getter_AddRefs(anchorChildren));
|
1999-08-19 17:30:48 +04:00
|
|
|
nsCOMPtr<nsIDOMNode> selectedNode;
|
1999-08-24 12:56:51 +04:00
|
|
|
if ((NS_SUCCEEDED(res)) && anchorChildren) {
|
|
|
|
res = anchorChildren->Item(offset, getter_AddRefs(selectedNode));
|
1999-08-19 17:30:48 +04:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
selectedNode = do_QueryInterface(anchor);
|
|
|
|
}
|
1999-08-24 12:56:51 +04:00
|
|
|
if ((NS_SUCCEEDED(res)) && selectedNode)
|
1999-03-16 19:38:09 +03:00
|
|
|
{
|
1999-08-19 17:30:48 +04:00
|
|
|
nsCOMPtr<nsIDOMCharacterData>selectedNodeAsText;
|
|
|
|
selectedNodeAsText = do_QueryInterface(selectedNode);
|
|
|
|
if (selectedNodeAsText)
|
1999-03-16 19:38:09 +03:00
|
|
|
{
|
1999-08-19 17:30:48 +04:00
|
|
|
nsCOMPtr<nsIDOMNode> siblingNode;
|
|
|
|
selectedNode->GetPreviousSibling(getter_AddRefs(siblingNode));
|
|
|
|
if (siblingNode)
|
1999-03-16 19:38:09 +03:00
|
|
|
{
|
1999-08-19 17:30:48 +04:00
|
|
|
nsCOMPtr<nsIDOMCharacterData>siblingNodeAsText;
|
|
|
|
siblingNodeAsText = do_QueryInterface(siblingNode);
|
|
|
|
if (siblingNodeAsText)
|
1999-03-16 19:38:09 +03:00
|
|
|
{
|
1999-08-19 17:30:48 +04:00
|
|
|
PRUint32 siblingLength; // the length of siblingNode before the join
|
|
|
|
siblingNodeAsText->GetLength(&siblingLength);
|
|
|
|
nsCOMPtr<nsIDOMNode> parentNode;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = selectedNode->GetParentNode(getter_AddRefs(parentNode));
|
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
if (!parentNode) return NS_ERROR_NULL_POINTER;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = mEditor->JoinNodes(siblingNode, selectedNode, parentNode);
|
1999-08-19 17:30:48 +04:00
|
|
|
// selectedNode will remain after the join, siblingNode is removed
|
1999-03-16 19:38:09 +03:00
|
|
|
}
|
1999-08-19 17:30:48 +04:00
|
|
|
}
|
|
|
|
selectedNode->GetNextSibling(getter_AddRefs(siblingNode));
|
|
|
|
if (siblingNode)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMCharacterData>siblingNodeAsText;
|
|
|
|
siblingNodeAsText = do_QueryInterface(siblingNode);
|
|
|
|
if (siblingNodeAsText)
|
1999-03-16 19:38:09 +03:00
|
|
|
{
|
1999-08-19 17:30:48 +04:00
|
|
|
PRUint32 selectedNodeLength; // the length of siblingNode before the join
|
|
|
|
selectedNodeAsText->GetLength(&selectedNodeLength);
|
|
|
|
nsCOMPtr<nsIDOMNode> parentNode;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = selectedNode->GetParentNode(getter_AddRefs(parentNode));
|
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
if (!parentNode) return NS_ERROR_NULL_POINTER;
|
|
|
|
|
1999-08-24 12:56:51 +04:00
|
|
|
res = mEditor->JoinNodes(selectedNode, siblingNode, parentNode);
|
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
// selectedNode will remain after the join, siblingNode is removed
|
|
|
|
// set selection
|
1999-08-24 12:56:51 +04:00
|
|
|
res = aSelection->Collapse(siblingNode, selectedNodeLength);
|
1999-03-16 19:38:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-03-10 22:53:26 +03:00
|
|
|
}
|
1999-08-24 12:56:51 +04:00
|
|
|
return res;
|
1999-03-10 22:53:26 +03:00
|
|
|
}
|
|
|
|
|
1999-04-12 16:01:32 +04:00
|
|
|
nsresult
|
1999-03-15 08:08:30 +03:00
|
|
|
nsTextEditRules::WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|
|
|
{
|
|
|
|
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
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
|
|
|
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
1999-03-15 08:08:30 +03:00
|
|
|
// initialize out param
|
|
|
|
*aCancel = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-08-24 12:56:51 +04:00
|
|
|
/* the idea here is to see if the magic empty node has suddenly reappeared as the res of the undo.
|
1999-03-15 08:08:30 +03:00
|
|
|
* if it has, set our state so we remember it.
|
|
|
|
* There is a tradeoff between doing here and at redo, or doing it everywhere else that might care.
|
|
|
|
* Since undo and redo are relatively rare, it makes sense to take the (small) performance hit here.
|
|
|
|
*/
|
1999-04-12 16:01:32 +04:00
|
|
|
nsresult
|
1999-03-15 08:08:30 +03:00
|
|
|
nsTextEditRules:: DidUndo(nsIDOMSelection *aSelection, nsresult aResult)
|
|
|
|
{
|
1999-08-24 12:56:51 +04:00
|
|
|
nsresult res = aResult; // if aResult is an error, we return it.
|
1999-03-15 08:08:30 +03:00
|
|
|
if (!aSelection) { return NS_ERROR_NULL_POINTER; }
|
1999-08-24 12:56:51 +04:00
|
|
|
if (NS_SUCCEEDED(res))
|
1999-03-15 08:08:30 +03:00
|
|
|
{
|
|
|
|
if (mBogusNode) {
|
|
|
|
mBogusNode = do_QueryInterface(nsnull);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode>node;
|
|
|
|
PRInt32 offset;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = aSelection->GetAnchorNode(getter_AddRefs(node));
|
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
if (!node) return NS_ERROR_NULL_POINTER;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = aSelection->GetAnchorOffset(&offset);
|
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
nsCOMPtr<nsIDOMElement>element;
|
|
|
|
element = do_QueryInterface(node);
|
|
|
|
if (element)
|
1999-03-15 08:08:30 +03:00
|
|
|
{
|
1999-08-19 17:30:48 +04:00
|
|
|
nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr);
|
|
|
|
nsAutoString val;
|
|
|
|
(void)element->GetAttribute(att, val);
|
|
|
|
if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) {
|
|
|
|
mBogusNode = do_QueryInterface(element);
|
1999-03-15 08:08:30 +03:00
|
|
|
}
|
|
|
|
}
|
1999-08-19 17:30:48 +04:00
|
|
|
nsCOMPtr<nsIDOMNode> temp;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = node->GetParentNode(getter_AddRefs(temp));
|
1999-08-19 17:30:48 +04:00
|
|
|
node = do_QueryInterface(temp);
|
1999-03-15 08:08:30 +03:00
|
|
|
}
|
|
|
|
}
|
1999-08-24 12:56:51 +04:00
|
|
|
return res;
|
1999-03-15 08:08:30 +03:00
|
|
|
}
|
|
|
|
|
1999-04-12 16:01:32 +04:00
|
|
|
nsresult
|
1999-03-15 08:08:30 +03:00
|
|
|
nsTextEditRules::WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|
|
|
{
|
|
|
|
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
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
|
|
|
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
|
1999-03-15 08:08:30 +03:00
|
|
|
// initialize out param
|
|
|
|
*aCancel = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-04-12 16:01:32 +04:00
|
|
|
nsresult
|
1999-03-15 08:08:30 +03:00
|
|
|
nsTextEditRules::DidRedo(nsIDOMSelection *aSelection, nsresult aResult)
|
|
|
|
{
|
1999-08-24 12:56:51 +04:00
|
|
|
nsresult res = aResult; // if aResult is an error, we return it.
|
1999-03-15 08:08:30 +03:00
|
|
|
if (!aSelection) { return NS_ERROR_NULL_POINTER; }
|
1999-08-24 12:56:51 +04:00
|
|
|
if (NS_SUCCEEDED(res))
|
1999-03-15 08:08:30 +03:00
|
|
|
{
|
|
|
|
if (mBogusNode) {
|
|
|
|
mBogusNode = do_QueryInterface(nsnull);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode>node;
|
|
|
|
PRInt32 offset;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = aSelection->GetAnchorNode(getter_AddRefs(node));
|
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
if (!node) return NS_ERROR_NULL_POINTER;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = aSelection->GetAnchorOffset(&offset);
|
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
nsCOMPtr<nsIDOMElement>element;
|
|
|
|
element = do_QueryInterface(node);
|
|
|
|
if (element)
|
1999-03-15 08:08:30 +03:00
|
|
|
{
|
1999-08-19 17:30:48 +04:00
|
|
|
nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr);
|
|
|
|
nsAutoString val;
|
|
|
|
(void)element->GetAttribute(att, val);
|
|
|
|
if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) {
|
|
|
|
mBogusNode = do_QueryInterface(element);
|
1999-03-15 08:08:30 +03:00
|
|
|
}
|
|
|
|
}
|
1999-08-19 17:30:48 +04:00
|
|
|
nsCOMPtr<nsIDOMNode> temp;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = node->GetParentNode(getter_AddRefs(temp));
|
1999-08-19 17:30:48 +04:00
|
|
|
node = do_QueryInterface(temp);
|
1999-03-15 08:08:30 +03:00
|
|
|
}
|
|
|
|
}
|
1999-08-24 12:56:51 +04:00
|
|
|
return res;
|
1999-03-15 08:08:30 +03:00
|
|
|
}
|
|
|
|
|
1999-06-25 03:36:56 +04:00
|
|
|
nsresult
|
|
|
|
nsTextEditRules::WillOutputText(nsIDOMSelection *aSelection,
|
1999-09-09 23:39:36 +04:00
|
|
|
const nsString *aOutputFormat,
|
|
|
|
nsString *aOutString,
|
|
|
|
PRBool *aCancel)
|
1999-06-25 03:36:56 +04:00
|
|
|
{
|
|
|
|
// null selection ok
|
1999-09-09 23:39:36 +04:00
|
|
|
if (!aOutString || !aOutputFormat || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
1999-06-25 03:36:56 +04:00
|
|
|
|
|
|
|
// initialize out param
|
|
|
|
*aCancel = PR_FALSE;
|
1999-09-09 23:39:36 +04:00
|
|
|
|
|
|
|
if (PR_TRUE == aOutputFormat->Equals("text/plain"))
|
|
|
|
{ // only use these rules for plain text output
|
|
|
|
if (mFlags & nsIHTMLEditor::eEditorPasswordMask)
|
|
|
|
{
|
|
|
|
*aOutString = mPasswordText;
|
|
|
|
*aCancel = PR_TRUE;
|
|
|
|
}
|
|
|
|
else if (mBogusNode)
|
|
|
|
{ // this means there's no content, so output null string
|
|
|
|
*aOutString = "";
|
|
|
|
*aCancel = PR_TRUE;
|
|
|
|
}
|
1999-08-24 17:48:08 +04:00
|
|
|
}
|
1999-06-25 03:36:56 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditRules::DidOutputText(nsIDOMSelection *aSelection, nsresult aResult)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-03-10 22:53:26 +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
|
|
|
nsresult
|
|
|
|
nsTextEditRules::CreateBogusNodeIfNeeded(nsIDOMSelection *aSelection)
|
|
|
|
{
|
|
|
|
if (!aSelection) { return NS_ERROR_NULL_POINTER; }
|
1999-07-01 22:42:28 +04:00
|
|
|
if (!mEditor) { return NS_ERROR_NULL_POINTER; }
|
1999-08-19 17:30:48 +04:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMElement> bodyElement;
|
1999-08-24 12:56:51 +04:00
|
|
|
nsresult res = mEditor->GetBodyElement(getter_AddRefs(bodyElement));
|
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
if (!bodyElement) return NS_ERROR_NULL_POINTER;
|
|
|
|
nsCOMPtr<nsIDOMNode>bodyNode = do_QueryInterface(bodyElement);
|
|
|
|
|
|
|
|
// now we've got the body tag.
|
|
|
|
// iterate the body tag, looking for editable content
|
|
|
|
// if no editable content is found, insert the bogus node
|
|
|
|
PRBool needsBogusContent=PR_TRUE;
|
|
|
|
nsCOMPtr<nsIDOMNode>bodyChild;
|
1999-08-24 12:56:51 +04:00
|
|
|
res = bodyNode->GetFirstChild(getter_AddRefs(bodyChild));
|
|
|
|
while ((NS_SUCCEEDED(res)) && bodyChild)
|
1999-08-19 17:30:48 +04:00
|
|
|
{
|
|
|
|
if (PR_TRUE==mEditor->IsEditable(bodyChild))
|
|
|
|
{
|
|
|
|
needsBogusContent = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMNode>temp;
|
|
|
|
bodyChild->GetNextSibling(getter_AddRefs(temp));
|
|
|
|
bodyChild = do_QueryInterface(temp);
|
|
|
|
}
|
|
|
|
if (PR_TRUE==needsBogusContent)
|
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-09-06 23:45:26 +04:00
|
|
|
// set mBogusNode to be the newly created <div>
|
|
|
|
res = mEditor->CreateNode(nsAutoString("div"), bodyNode, 0,
|
1999-08-19 17:30:48 +04:00
|
|
|
getter_AddRefs(mBogusNode));
|
1999-08-24 12:56:51 +04:00
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
if (!mBogusNode) return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMNode>newTNode;
|
1999-08-31 02:11:09 +04:00
|
|
|
nsAutoString textNodeTag;
|
|
|
|
res = nsEditor::GetTextNodeTag(textNodeTag);
|
|
|
|
if (NS_FAILED(res)) { return res; }
|
|
|
|
res = mEditor->CreateNode(textNodeTag, mBogusNode, 0,
|
1999-08-19 17:30:48 +04:00
|
|
|
getter_AddRefs(newTNode));
|
1999-08-24 12:56:51 +04:00
|
|
|
if (NS_FAILED(res)) return res;
|
1999-08-19 17:30:48 +04:00
|
|
|
if (!newTNode) return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMCharacterData>newNodeAsText;
|
|
|
|
newNodeAsText = do_QueryInterface(newTNode);
|
|
|
|
if (newNodeAsText)
|
|
|
|
{
|
|
|
|
nsAutoString data;
|
|
|
|
data += 160;
|
|
|
|
newNodeAsText->SetData(data);
|
|
|
|
aSelection->Collapse(newTNode, 0);
|
|
|
|
}
|
|
|
|
// make sure we know the PNode is bogus
|
|
|
|
nsCOMPtr<nsIDOMElement>newPElement;
|
|
|
|
newPElement = do_QueryInterface(mBogusNode);
|
|
|
|
if (newPElement)
|
|
|
|
{
|
|
|
|
nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr);
|
|
|
|
nsAutoString val(nsEditor::kMOZEditorBogusNodeValue);
|
|
|
|
newPElement->SetAttribute(att, val);
|
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-24 12:56:51 +04:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditRules::TruncateInsertionIfNeeded(nsIDOMSelection *aSelection,
|
|
|
|
const nsString *aInString,
|
|
|
|
nsString *aOutString,
|
|
|
|
PRInt32 aMaxLength)
|
|
|
|
{
|
|
|
|
if (!aSelection || !aInString || !aOutString) {return NS_ERROR_NULL_POINTER;}
|
|
|
|
|
|
|
|
nsresult res = NS_OK;
|
|
|
|
*aOutString = *aInString;
|
|
|
|
|
|
|
|
if ((-1 != aMaxLength) && (mFlags & nsIHTMLEditor::eEditorPlaintextMask))
|
|
|
|
{
|
|
|
|
// Get the current text length.
|
|
|
|
// Get the length of inString.
|
|
|
|
// Get the length of the selection.
|
|
|
|
// If selection is collapsed, it is length 0.
|
|
|
|
// Subtract the length of the selection from the len(doc)
|
|
|
|
// since we'll delete the selection on insert.
|
|
|
|
// This is resultingDocLength.
|
|
|
|
// If (resultingDocLength) is at or over max, cancel the insert
|
|
|
|
// If (resultingDocLength) + (length of input) > max,
|
|
|
|
// set aOutString to subset of inString so length = max
|
|
|
|
PRInt32 docLength;
|
|
|
|
res = mEditor->GetDocumentLength(&docLength);
|
|
|
|
if (NS_FAILED(res)) { return res; }
|
|
|
|
PRInt32 start, end;
|
|
|
|
res = mEditor->GetTextSelectionOffsets(aSelection, start, end);
|
|
|
|
if (NS_FAILED(res)) { return res; }
|
|
|
|
PRInt32 selectionLength = end-start;
|
|
|
|
if (selectionLength<0) { selectionLength *= (-1); }
|
|
|
|
PRInt32 resultingDocLength = docLength - selectionLength;
|
|
|
|
if (resultingDocLength >= aMaxLength)
|
|
|
|
{
|
|
|
|
*aOutString = "";
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PRInt32 inCount = aOutString->Length();
|
|
|
|
if ((inCount+resultingDocLength) > aMaxLength)
|
|
|
|
{
|
|
|
|
aOutString->Truncate(aMaxLength-resultingDocLength);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
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-07-01 17:42:03 +04:00
|
|
|
|
1999-08-24 12:56:51 +04:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditRules::EchoInsertionToPWBuff(nsIDOMSelection *aSelection, nsString *aOutString)
|
|
|
|
{
|
|
|
|
if (!aSelection || !aOutString) {return NS_ERROR_NULL_POINTER;}
|
|
|
|
|
|
|
|
// manage the password buffer
|
|
|
|
PRInt32 start, end;
|
|
|
|
nsresult res = mEditor->GetTextSelectionOffsets(aSelection, start, end);
|
|
|
|
NS_ASSERTION((NS_SUCCEEDED(res)), "getTextSelectionOffsets failed!");
|
1999-09-14 04:11:22 +04:00
|
|
|
if (end!=start)
|
|
|
|
{
|
|
|
|
mPasswordText.Cut(start, end-start);
|
|
|
|
}
|
1999-08-24 12:56:51 +04:00
|
|
|
mPasswordText.Insert(*aOutString, start);
|
|
|
|
|
1999-09-03 12:31:33 +04:00
|
|
|
#ifdef DEBUG_jfrancis
|
1999-08-24 12:56:51 +04:00
|
|
|
char *password = mPasswordText.ToNewCString();
|
|
|
|
printf("mPasswordText is %s\n", password);
|
1999-09-06 10:22:51 +04:00
|
|
|
nsCRT::free(password);
|
1999-08-24 12:56:51 +04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// change the output to '*' only
|
|
|
|
PRInt32 length = aOutString->Length();
|
|
|
|
PRInt32 i;
|
1999-08-31 02:11:09 +04:00
|
|
|
*aOutString = "";
|
1999-08-24 12:56:51 +04:00
|
|
|
for (i=0; i<length; i++)
|
|
|
|
*aOutString += '*';
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsTextEditRules::DoTextInsertion(nsIDOMSelection *aSelection,
|
|
|
|
PRBool *aCancel,
|
|
|
|
PlaceholderTxn **aTxn,
|
|
|
|
const nsString *aInString,
|
|
|
|
TypeInState aTypeInState)
|
|
|
|
{
|
|
|
|
if (!aSelection || !aCancel || !aInString) {return NS_ERROR_NULL_POINTER;}
|
|
|
|
nsresult res = NS_OK;
|
|
|
|
|
|
|
|
// for now, we always cancel editor handling of insert text.
|
|
|
|
// rules code always does the insertion
|
|
|
|
*aCancel = PR_TRUE;
|
|
|
|
|
|
|
|
if (mBogusNode || (PR_TRUE==aTypeInState.IsAnySet()))
|
|
|
|
{
|
|
|
|
res = TransactionFactory::GetNewTransaction(PlaceholderTxn::GetCID(), (EditTxn **)aTxn);
|
|
|
|
if (NS_FAILED(res)) { return res; }
|
|
|
|
if (!*aTxn) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
(*aTxn)->SetName(InsertTextTxn::gInsertTextTxnName);
|
|
|
|
mEditor->Do(*aTxn);
|
|
|
|
}
|
|
|
|
PRBool bCancel;
|
|
|
|
res = WillInsert(aSelection, &bCancel);
|
|
|
|
if (NS_SUCCEEDED(res) && (!bCancel))
|
|
|
|
{
|
|
|
|
if (PR_TRUE==aTypeInState.IsAnySet())
|
|
|
|
{ // for every property that is set, insert a new inline style node
|
|
|
|
res = CreateStyleForInsertText(aSelection, aTypeInState);
|
|
|
|
if (NS_FAILED(res)) { return res; }
|
|
|
|
}
|
|
|
|
res = mEditor->InsertTextImpl(*aInString);
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|