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"
|
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 "nsTextEditor.h"
|
1999-03-15 03:57:32 +03:00
|
|
|
#include "PlaceholderTxn.h"
|
|
|
|
#include "InsertTextTxn.h"
|
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-10 22:53:26 +03:00
|
|
|
#include "nsIEnumerator.h"
|
1999-03-13 07:53:21 +03:00
|
|
|
#include "nsIContent.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-03-13 07:53:21 +03:00
|
|
|
const static char* kMOZEditorBogusNodeAttr="MOZ_EDITOR_BOGUS_NODE";
|
|
|
|
const static char* kMOZEditorBogusNodeValue="TRUE";
|
1999-03-10 22:53:26 +03:00
|
|
|
|
1999-03-15 03:57:32 +03:00
|
|
|
static NS_DEFINE_IID(kPlaceholderTxnIID, PLACEHOLDER_TXN_IID);
|
|
|
|
|
1999-04-05 21:21:59 +04:00
|
|
|
/********************************************************
|
1999-03-29 12:02:05 +04:00
|
|
|
* Helper Functions
|
1999-04-05 21:21:59 +04:00
|
|
|
********************************************************/
|
1999-03-29 12:02:05 +04:00
|
|
|
|
|
|
|
PRBool nsTextEditRules::NodeIsType(nsIDOMNode *aNode, nsIAtom *aTag)
|
1999-03-10 22:53:26 +03:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMElement>element;
|
|
|
|
element = do_QueryInterface(aNode);
|
|
|
|
if (element)
|
|
|
|
{
|
|
|
|
nsAutoString tag;
|
|
|
|
element->GetTagName(tag);
|
|
|
|
if (tag.Equals(aTag))
|
|
|
|
{
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
1999-03-29 12:02:05 +04:00
|
|
|
PRBool nsTextEditRules::IsEditable(nsIDOMNode *aNode)
|
1999-03-13 07:53:21 +03:00
|
|
|
{
|
|
|
|
if (!aNode) return PR_FALSE;
|
|
|
|
nsCOMPtr<nsIDOMElement>element;
|
|
|
|
element = do_QueryInterface(aNode);
|
|
|
|
if (element)
|
|
|
|
{
|
|
|
|
nsAutoString att(kMOZEditorBogusNodeAttr);
|
|
|
|
nsAutoString val;
|
1999-03-30 02:01:26 +04:00
|
|
|
(void)element->GetAttribute(att, val);
|
1999-03-13 07:53:21 +03:00
|
|
|
if (val.Equals(kMOZEditorBogusNodeValue)) {
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMCharacterData>text;
|
|
|
|
text = do_QueryInterface(aNode);
|
|
|
|
if (text)
|
|
|
|
{
|
|
|
|
nsAutoString data;
|
|
|
|
text->GetData(data);
|
|
|
|
if (0==data.Length()) {
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
if ('\n'==data[0]) {
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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-03-10 22:53:26 +03:00
|
|
|
nsTextEditRules::nsTextEditRules()
|
|
|
|
{
|
1999-03-12 05:28:24 +03:00
|
|
|
mEditor = nsnull;
|
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-04-05 21:21:59 +04:00
|
|
|
nsTextEditRules::Init(nsIEditor *aEditor)
|
1999-03-10 22:53:26 +03:00
|
|
|
{
|
|
|
|
// null aNextRule is ok
|
|
|
|
if (!aEditor) { return NS_ERROR_NULL_POINTER; }
|
1999-04-05 21:21:59 +04:00
|
|
|
mEditor = (nsTextEditor*)aEditor; // we hold a non-refcounted reference back to our editor
|
1999-03-10 22:53:26 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-04-05 21:21:59 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditRules::WillDoAction(int aAction, nsIDOMSelection *aSelection,
|
|
|
|
void **aOtherInfo, PRBool *aCancel)
|
1999-03-29 12:02:05 +04:00
|
|
|
{
|
1999-04-05 21:21:59 +04:00
|
|
|
if (!aSelection)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
switch (aAction)
|
|
|
|
{
|
|
|
|
case kInsertText:
|
|
|
|
return WillInsertText(aSelection, aCancel, (PlaceholderTxn**)aOtherInfo);
|
|
|
|
case kDeleteSelection:
|
|
|
|
return WillDeleteSelection(aSelection, aCancel);
|
|
|
|
case kUndo:
|
|
|
|
return WillUndo(aSelection, aCancel);
|
|
|
|
case kRedo:
|
|
|
|
return WillRedo(aSelection, aCancel);
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
1999-03-29 12:02:05 +04:00
|
|
|
}
|
1999-04-05 21:21:59 +04:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditRules::DidDoAction(int aAction, nsIDOMSelection *aSelection,
|
|
|
|
void **aOtherInfo, nsresult aResult)
|
1999-03-29 12:02:05 +04:00
|
|
|
{
|
1999-04-05 21:21:59 +04:00
|
|
|
if (!aSelection)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
switch (aAction)
|
|
|
|
{
|
|
|
|
case kInsertText:
|
|
|
|
return DidInsertText(aSelection, aResult);
|
|
|
|
case kDeleteSelection:
|
|
|
|
return DidDeleteSelection(aSelection, aResult);
|
|
|
|
case kUndo:
|
|
|
|
return DidUndo(aSelection, aResult);
|
|
|
|
case kRedo:
|
|
|
|
return DidRedo(aSelection, aResult);
|
|
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
1999-03-29 12:02:05 +04:00
|
|
|
}
|
1999-04-05 21:21:59 +04:00
|
|
|
|
|
|
|
|
|
|
|
/********************************************************
|
|
|
|
* Protected methods
|
|
|
|
********************************************************/
|
|
|
|
|
1999-03-12 05:28:24 +03:00
|
|
|
|
1999-03-13 07:53:21 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditRules::WillInsert(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|
|
|
{
|
|
|
|
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
// 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);
|
|
|
|
// there is no longer any legit selection, so clear it.
|
|
|
|
aSelection->ClearSelection();
|
1999-03-13 07:53:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditRules::DidInsert(nsIDOMSelection *aSelection, nsresult aResult)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditRules::WillInsertText(nsIDOMSelection *aSelection,
|
1999-04-05 21:21:59 +04:00
|
|
|
PRBool *aCancel,
|
1999-03-15 03:57:32 +03:00
|
|
|
PlaceholderTxn **aTxn)
|
1999-03-13 07:53:21 +03:00
|
|
|
{
|
|
|
|
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
// initialize out param
|
|
|
|
*aCancel = PR_FALSE;
|
1999-04-05 21:21:59 +04:00
|
|
|
TypeInState typeInState = mEditor->GetTypeInState();
|
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 (mBogusNode || (PR_TRUE==typeInState.IsAnySet()))
|
1999-03-15 03:57:32 +03:00
|
|
|
{
|
|
|
|
nsresult result = TransactionFactory::GetNewTransaction(kPlaceholderTxnIID, (EditTxn **)aTxn);
|
|
|
|
if (NS_FAILED(result)) { return result; }
|
|
|
|
if (!*aTxn) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
(*aTxn)->SetName(InsertTextTxn::gInsertTextTxnName);
|
|
|
|
mEditor->Do(*aTxn);
|
|
|
|
}
|
1999-03-16 19:38:09 +03:00
|
|
|
nsresult result = WillInsert(aSelection, aCancel);
|
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 (NS_SUCCEEDED(result) && (PR_FALSE==*aCancel))
|
|
|
|
{
|
|
|
|
if (PR_TRUE==typeInState.IsAnySet())
|
|
|
|
{ // for every property that is set, insert a new inline style node
|
|
|
|
result = CreateStyleForInsertText(aSelection, typeInState);
|
|
|
|
}
|
|
|
|
}
|
1999-03-16 19:38:09 +03:00
|
|
|
return result;
|
1999-03-13 07:53:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditRules::DidInsertText(nsIDOMSelection *aSelection,
|
|
|
|
nsresult aResult)
|
|
|
|
{
|
|
|
|
return DidInsert(aSelection, aResult);
|
|
|
|
}
|
1999-03-12 05:28:24 +03: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
|
|
|
NS_IMETHODIMP
|
|
|
|
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;
|
|
|
|
nsresult result = aSelection->GetAnchorNodeAndOffset(getter_AddRefs(anchor), &offset);
|
|
|
|
if ((NS_SUCCEEDED(result)) && anchor)
|
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
result = mEditor->SplitNode(anchorAsText, offset, getter_AddRefs(newTextNode));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PRUint32 length;
|
|
|
|
anchorAsText->GetLength(&length);
|
|
|
|
if (length==offset)
|
|
|
|
{
|
|
|
|
// newTextNode will be the left node
|
|
|
|
result = mEditor->SplitNode(anchorAsText, offset, getter_AddRefs(newTextNode));
|
|
|
|
// 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
|
|
|
|
result = mEditor->SplitNode(anchorAsText, offset, getter_AddRefs(newTextNode));
|
|
|
|
result = mEditor->SplitNode(anchorAsText, 0, getter_AddRefs(newTextNode));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 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.
|
|
|
|
if ((NS_SUCCEEDED(result)) && newTextNode)
|
|
|
|
{
|
|
|
|
if (aTypeInState.IsSet(NS_TYPEINSTATE_BOLD))
|
|
|
|
{
|
1999-04-05 00:10:39 +04:00
|
|
|
if (PR_TRUE==aTypeInState.GetBold()) {
|
|
|
|
InsertStyleNode(newTextNode, nsIEditProperty::b, aSelection);
|
|
|
|
}
|
|
|
|
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()) {
|
|
|
|
InsertStyleNode(newTextNode, nsIEditProperty::i, 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
|
|
|
}
|
|
|
|
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))
|
|
|
|
{
|
|
|
|
if (PR_TRUE==aTypeInState.GetUnderline()) {
|
|
|
|
InsertStyleNode(newTextNode, nsIEditProperty::u, aSelection);
|
|
|
|
}
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf("not yet implemented. selection is not text.\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else // we have no selection, so insert a style tag in the body
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMDocument>doc;
|
|
|
|
mEditor->GetDocument(getter_AddRefs(doc));
|
|
|
|
nsCOMPtr<nsIDOMNodeList>nodeList;
|
|
|
|
nsAutoString bodyTag = "body";
|
|
|
|
nsresult result = doc->GetElementsByTagName(bodyTag, getter_AddRefs(nodeList));
|
|
|
|
if ((NS_SUCCEEDED(result)) && nodeList)
|
|
|
|
{
|
|
|
|
PRUint32 count;
|
|
|
|
nodeList->GetLength(&count);
|
|
|
|
NS_ASSERTION(1==count, "there is not exactly 1 body in the document!");
|
|
|
|
nsCOMPtr<nsIDOMNode>bodyNode;
|
|
|
|
result = nodeList->Item(0, getter_AddRefs(bodyNode));
|
|
|
|
if ((NS_SUCCEEDED(result)) && bodyNode)
|
|
|
|
{ // now we've got the body tag. insert the style tag
|
|
|
|
if (aTypeInState.IsSet(NS_TYPEINSTATE_BOLD))
|
|
|
|
{
|
1999-04-06 00:52:29 +04:00
|
|
|
if (PR_TRUE==aTypeInState.GetBold()) {
|
|
|
|
InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::b, aSelection);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (aTypeInState.IsSet(NS_TYPEINSTATE_ITALIC))
|
|
|
|
{
|
|
|
|
if (PR_TRUE==aTypeInState.GetItalic()) {
|
|
|
|
InsertStyleAndNewTextNode(bodyNode, nsIEditProperty::i, aSelection);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-04-05 00:10:39 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditRules::InsertStyleNode(nsIDOMNode *aNode, nsIAtom *aTag, nsIDOMSelection *aSelection)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aNode && aTag, "bad args");
|
|
|
|
if (!aNode || !aTag) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
|
|
|
|
nsresult result;
|
|
|
|
nsCOMPtr<nsIDOMNode>parent;
|
|
|
|
aNode->GetParentNode(getter_AddRefs(parent));
|
|
|
|
PRInt32 offsetInParent;
|
|
|
|
nsIEditorSupport::GetChildOffset(aNode, parent, offsetInParent);
|
|
|
|
nsAutoString tag;
|
|
|
|
aTag->ToString(tag);
|
|
|
|
nsCOMPtr<nsIDOMNode>newStyleNode;
|
|
|
|
result = mEditor->CreateNode(tag, parent, offsetInParent, getter_AddRefs(newStyleNode));
|
|
|
|
if ((NS_SUCCEEDED(result)) && newStyleNode)
|
|
|
|
{
|
|
|
|
result = mEditor->DeleteNode(aNode);
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
result = mEditor->InsertNode(aNode, newStyleNode, 0);
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
if (aSelection) {
|
|
|
|
aSelection->Collapse(aNode, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
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-06 00:52:29 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditRules::InsertStyleAndNewTextNode(nsIDOMNode *aParentNode, nsIAtom *aTag, nsIDOMSelection *aSelection)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aParentNode && aTag, "bad args");
|
|
|
|
if (!aParentNode || !aTag) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
|
|
|
|
nsresult result;
|
|
|
|
// if the selection already points to a text node, just call InsertStyleNode()
|
|
|
|
if (aSelection)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode>anchor;
|
|
|
|
PRInt32 offset;
|
|
|
|
nsresult result = aSelection->GetAnchorNodeAndOffset(getter_AddRefs(anchor), &offset);
|
|
|
|
if ((NS_SUCCEEDED(result)) && anchor)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMCharacterData>anchorAsText;
|
|
|
|
anchorAsText = do_QueryInterface(anchor);
|
|
|
|
if (anchorAsText)
|
|
|
|
{
|
|
|
|
result = InsertStyleNode(anchor, aTag, aSelection);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 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;
|
|
|
|
result = mEditor->CreateNode(tag, aParentNode, 0, getter_AddRefs(newStyleNode));
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
result = mEditor->CreateNode(nsIEditor::GetTextNodeTag(), newStyleNode, 0, getter_AddRefs(newTextNode));
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
if (aSelection) {
|
|
|
|
aSelection->Collapse(newTextNode, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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
|
|
|
/*
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditRules::GetInsertBreakTag(nsIAtom **aTag)
|
|
|
|
{
|
|
|
|
if (!aTag) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
*aTag = NS_NewAtom("BR");
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
1999-03-10 22:53:26 +03:00
|
|
|
NS_IMETHODIMP
|
1999-03-12 05:28:24 +03:00
|
|
|
nsTextEditRules::WillDeleteSelection(nsIDOMSelection *aSelection, 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; }
|
|
|
|
// 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-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-03-12 05:28:24 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditRules::DidDeleteSelection(nsIDOMSelection *aSelection, nsresult aResult)
|
|
|
|
{
|
|
|
|
nsresult result = aResult; // if aResult is an error, we just return it
|
|
|
|
if (!aSelection) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
PRBool isCollapsed;
|
|
|
|
aSelection->IsCollapsed(&isCollapsed);
|
|
|
|
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-03-16 19:38:09 +03:00
|
|
|
if (NS_SUCCEEDED(result)) // only do this work if DeleteSelection completed successfully
|
1999-03-12 05:28:24 +03:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMDocument>doc;
|
|
|
|
mEditor->GetDocument(getter_AddRefs(doc));
|
|
|
|
nsCOMPtr<nsIDOMNodeList>nodeList;
|
|
|
|
nsAutoString bodyTag = "body";
|
|
|
|
nsresult result = doc->GetElementsByTagName(bodyTag, getter_AddRefs(nodeList));
|
|
|
|
if ((NS_SUCCEEDED(result)) && nodeList)
|
|
|
|
{
|
|
|
|
PRUint32 count;
|
|
|
|
nodeList->GetLength(&count);
|
|
|
|
NS_ASSERTION(1==count, "there is not exactly 1 body in the document!");
|
|
|
|
nsCOMPtr<nsIDOMNode>bodyNode;
|
|
|
|
result = nodeList->Item(0, getter_AddRefs(bodyNode));
|
|
|
|
if ((NS_SUCCEEDED(result)) && bodyNode)
|
|
|
|
{ // 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;
|
|
|
|
result = bodyNode->GetFirstChild(getter_AddRefs(bodyChild));
|
|
|
|
while ((NS_SUCCEEDED(result)) && bodyChild)
|
1999-03-13 07:53:21 +03:00
|
|
|
{
|
|
|
|
if (PR_TRUE==IsEditable(bodyChild))
|
|
|
|
{
|
|
|
|
needsBogusContent = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
1999-03-12 05:28:24 +03:00
|
|
|
nsCOMPtr<nsIDOMNode>temp;
|
1999-03-13 07:53:21 +03:00
|
|
|
bodyChild->GetNextSibling(getter_AddRefs(temp));
|
1999-03-12 05:28:24 +03:00
|
|
|
bodyChild = do_QueryInterface(temp);
|
|
|
|
}
|
|
|
|
if (PR_TRUE==needsBogusContent)
|
|
|
|
{
|
1999-03-15 03:57:32 +03:00
|
|
|
// set mBogusNode to be the newly created <P>
|
1999-03-12 05:28:24 +03:00
|
|
|
result = mEditor->CreateNode(nsAutoString("P"), bodyNode, 0,
|
1999-03-15 03:57:32 +03:00
|
|
|
getter_AddRefs(mBogusNode));
|
|
|
|
if ((NS_SUCCEEDED(result)) && mBogusNode)
|
1999-03-12 05:28:24 +03:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode>newTNode;
|
1999-03-15 03:57:32 +03:00
|
|
|
result = mEditor->CreateNode(nsIEditor::GetTextNodeTag(), mBogusNode, 0,
|
1999-03-12 05:28:24 +03:00
|
|
|
getter_AddRefs(newTNode));
|
|
|
|
if ((NS_SUCCEEDED(result)) && newTNode)
|
|
|
|
{
|
|
|
|
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;
|
1999-03-15 03:57:32 +03:00
|
|
|
newPElement = do_QueryInterface(mBogusNode);
|
1999-03-12 05:28:24 +03:00
|
|
|
if (newPElement)
|
|
|
|
{
|
1999-03-13 07:53:21 +03:00
|
|
|
nsAutoString att(kMOZEditorBogusNodeAttr);
|
|
|
|
nsAutoString val(kMOZEditorBogusNodeValue);
|
|
|
|
newPElement->SetAttribute(att, val);
|
1999-03-12 05:28:24 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
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;
|
|
|
|
nsresult result = aSelection->GetAnchorNodeAndOffset(getter_AddRefs(anchor), &offset);
|
|
|
|
if ((NS_SUCCEEDED(result)) && anchor)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNodeList> anchorChildren;
|
|
|
|
result = anchor->GetChildNodes(getter_AddRefs(anchorChildren));
|
|
|
|
nsCOMPtr<nsIDOMNode> selectedNode;
|
|
|
|
if ((NS_SUCCEEDED(result)) && anchorChildren) {
|
|
|
|
result = anchorChildren->Item(offset, getter_AddRefs(selectedNode));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
selectedNode = do_QueryInterface(anchor);
|
|
|
|
}
|
|
|
|
if ((NS_SUCCEEDED(result)) && selectedNode)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMCharacterData>selectedNodeAsText;
|
|
|
|
selectedNodeAsText = do_QueryInterface(selectedNode);
|
|
|
|
if (selectedNodeAsText)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode> siblingNode;
|
|
|
|
selectedNode->GetPreviousSibling(getter_AddRefs(siblingNode));
|
|
|
|
if (siblingNode)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMCharacterData>siblingNodeAsText;
|
|
|
|
siblingNodeAsText = do_QueryInterface(siblingNode);
|
|
|
|
if (siblingNodeAsText)
|
|
|
|
{
|
|
|
|
PRUint32 siblingLength; // the length of siblingNode before the join
|
|
|
|
siblingNodeAsText->GetLength(&siblingLength);
|
|
|
|
nsCOMPtr<nsIDOMNode> parentNode;
|
|
|
|
selectedNode->GetParentNode(getter_AddRefs(parentNode));
|
|
|
|
result = mEditor->JoinNodes(siblingNode, selectedNode, parentNode);
|
1999-04-06 00:52:29 +04:00
|
|
|
// selectedNode will remain after the join, siblingNode is removed
|
1999-03-16 19:38:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
selectedNode->GetNextSibling(getter_AddRefs(siblingNode));
|
|
|
|
if (siblingNode)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMCharacterData>siblingNodeAsText;
|
|
|
|
siblingNodeAsText = do_QueryInterface(siblingNode);
|
|
|
|
if (siblingNodeAsText)
|
|
|
|
{
|
|
|
|
PRUint32 selectedNodeLength; // the length of siblingNode before the join
|
|
|
|
selectedNodeAsText->GetLength(&selectedNodeLength);
|
|
|
|
nsCOMPtr<nsIDOMNode> parentNode;
|
|
|
|
selectedNode->GetParentNode(getter_AddRefs(parentNode));
|
|
|
|
result = mEditor->JoinNodes(selectedNode, siblingNode, parentNode);
|
1999-04-06 00:52:29 +04:00
|
|
|
// selectedNode will remain after the join, siblingNode is removed
|
1999-03-16 19:38:09 +03:00
|
|
|
// set selection
|
1999-04-06 00:52:29 +04:00
|
|
|
aSelection->Collapse(siblingNode, selectedNodeLength);
|
1999-03-16 19:38:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-03-10 22:53:26 +03:00
|
|
|
}
|
1999-03-12 05:28:24 +03:00
|
|
|
return result;
|
1999-03-10 22:53:26 +03:00
|
|
|
}
|
|
|
|
|
1999-03-15 08:08:30 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditRules::WillUndo(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|
|
|
{
|
|
|
|
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
// initialize out param
|
|
|
|
*aCancel = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* the idea here is to see if the magic empty node has suddenly reappeared as the result of the undo.
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditRules:: DidUndo(nsIDOMSelection *aSelection, nsresult aResult)
|
|
|
|
{
|
|
|
|
nsresult result = aResult; // if aResult is an error, we return it.
|
|
|
|
if (!aSelection) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
if (mBogusNode) {
|
|
|
|
mBogusNode = do_QueryInterface(nsnull);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode>node;
|
|
|
|
PRInt32 offset;
|
|
|
|
nsresult result = aSelection->GetAnchorNodeAndOffset(getter_AddRefs(node), &offset);
|
|
|
|
while ((NS_SUCCEEDED(result)) && node)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMElement>element;
|
|
|
|
element = do_QueryInterface(node);
|
|
|
|
if (element)
|
|
|
|
{
|
|
|
|
nsAutoString att(kMOZEditorBogusNodeAttr);
|
|
|
|
nsAutoString val;
|
1999-03-30 02:01:26 +04:00
|
|
|
(void)element->GetAttribute(att, val);
|
1999-03-15 08:08:30 +03:00
|
|
|
if (val.Equals(kMOZEditorBogusNodeValue)) {
|
|
|
|
mBogusNode = do_QueryInterface(element);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMNode> temp;
|
|
|
|
result = node->GetParentNode(getter_AddRefs(temp));
|
|
|
|
node = do_QueryInterface(temp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditRules::WillRedo(nsIDOMSelection *aSelection, PRBool *aCancel)
|
|
|
|
{
|
|
|
|
if (!aSelection || !aCancel) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
// initialize out param
|
|
|
|
*aCancel = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditRules::DidRedo(nsIDOMSelection *aSelection, nsresult aResult)
|
|
|
|
{
|
|
|
|
nsresult result = aResult; // if aResult is an error, we return it.
|
|
|
|
if (!aSelection) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
if (mBogusNode) {
|
|
|
|
mBogusNode = do_QueryInterface(nsnull);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode>node;
|
|
|
|
PRInt32 offset;
|
|
|
|
nsresult result = aSelection->GetAnchorNodeAndOffset(getter_AddRefs(node), &offset);
|
|
|
|
while ((NS_SUCCEEDED(result)) && node)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMElement>element;
|
|
|
|
element = do_QueryInterface(node);
|
|
|
|
if (element)
|
|
|
|
{
|
|
|
|
nsAutoString att(kMOZEditorBogusNodeAttr);
|
|
|
|
nsAutoString val;
|
1999-03-30 02:01:26 +04:00
|
|
|
(void)element->GetAttribute(att, val);
|
1999-03-15 08:08:30 +03:00
|
|
|
if (val.Equals(kMOZEditorBogusNodeValue)) {
|
|
|
|
mBogusNode = do_QueryInterface(element);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMNode> temp;
|
|
|
|
result = node->GetParentNode(getter_AddRefs(temp));
|
|
|
|
node = do_QueryInterface(temp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-03-10 22:53:26 +03:00
|
|
|
|
|
|
|
|
1999-03-12 05:28:24 +03:00
|
|
|
|
|
|
|
|
|
|
|
|