1999-02-12 20:18:58 +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 "nsTextEditor.h"
|
1999-02-22 18:53:31 +03:00
|
|
|
#include "nsIEditorSupport.h"
|
1999-02-12 20:18:58 +03:00
|
|
|
#include "nsEditorEventListeners.h"
|
1999-02-24 20:24:37 +03:00
|
|
|
#include "nsIEditProperty.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 "nsEditProperty.h" // temporary, to get html atoms
|
1999-03-05 00:53:42 +03:00
|
|
|
|
|
|
|
#include "nsIStreamListener.h"
|
|
|
|
#include "nsIParser.h"
|
|
|
|
#include "nsParserCIID.h"
|
|
|
|
#include "nsIDocument.h"
|
|
|
|
#include "nsIHTMLContentSink.h"
|
|
|
|
#include "nsHTMLContentSinkStream.h"
|
|
|
|
#include "nsHTMLToTXTSinkStream.h"
|
|
|
|
#include "nsXIFDTD.h"
|
|
|
|
|
|
|
|
|
1999-02-12 20:18:58 +03:00
|
|
|
#include "nsIDOMDocument.h"
|
|
|
|
#include "nsIDOMEventReceiver.h"
|
|
|
|
#include "nsIDOMKeyListener.h"
|
|
|
|
#include "nsIDOMMouseListener.h"
|
1999-03-14 07:45:00 +03:00
|
|
|
#include "nsIDOMDragListener.h"
|
1999-02-17 22:42:29 +03:00
|
|
|
#include "nsIDOMSelection.h"
|
1999-02-24 20:24:37 +03:00
|
|
|
#include "nsIDOMRange.h"
|
1999-02-17 22:42:29 +03:00
|
|
|
#include "nsIDOMNodeList.h"
|
1999-02-25 19:05:43 +03:00
|
|
|
#include "nsIDOMCharacterData.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 "nsIDOMElement.h"
|
1999-03-20 02:36:20 +03:00
|
|
|
#include "nsIDOMTextListener.h"
|
1999-02-12 20:18:58 +03:00
|
|
|
#include "nsEditorCID.h"
|
1999-02-24 20:24:37 +03:00
|
|
|
#include "nsISupportsArray.h"
|
|
|
|
#include "nsIEnumerator.h"
|
1999-03-02 10:52:41 +03:00
|
|
|
#include "nsIContentIterator.h"
|
|
|
|
#include "nsIContent.h"
|
|
|
|
#include "nsLayoutCID.h"
|
|
|
|
#include "nsIPresShell.h"
|
|
|
|
#include "nsIStyleContext.h"
|
1999-04-06 22:21:43 +04:00
|
|
|
#include "nsVoidArray.h"
|
1999-03-05 00:53:42 +03:00
|
|
|
|
1999-03-15 03:57:32 +03:00
|
|
|
// transactions the text editor knows how to build itself
|
|
|
|
#include "TransactionFactory.h"
|
|
|
|
#include "PlaceholderTxn.h"
|
|
|
|
#include "InsertTextTxn.h"
|
|
|
|
|
1999-03-05 00:53:42 +03:00
|
|
|
|
1999-03-02 10:52:41 +03:00
|
|
|
class nsIFrame;
|
1999-02-12 20:18:58 +03:00
|
|
|
|
1999-03-05 00:53:42 +03:00
|
|
|
#ifdef XP_UNIX
|
|
|
|
#include <strstream.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef XP_MAC
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef XP_PC
|
|
|
|
#include <strstrea.h>
|
|
|
|
#endif
|
|
|
|
|
1999-03-09 12:44:27 +03:00
|
|
|
#include "nsIComponentManager.h"
|
1999-02-12 20:18:58 +03:00
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
|
1999-03-10 22:48:46 +03:00
|
|
|
#include "nsTextEditRules.h"
|
|
|
|
|
|
|
|
|
1999-02-12 20:18:58 +03:00
|
|
|
static NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID);
|
|
|
|
static NS_DEFINE_IID(kIDOMMouseListenerIID, NS_IDOMMOUSELISTENER_IID);
|
|
|
|
static NS_DEFINE_IID(kIDOMKeyListenerIID, NS_IDOMKEYLISTENER_IID);
|
1999-03-20 02:36:20 +03:00
|
|
|
static NS_DEFINE_IID(kIDOMTextListenerIID, NS_IDOMTEXTLISTENER_IID);
|
1999-03-14 07:45:00 +03:00
|
|
|
static NS_DEFINE_IID(kIDOMDragListenerIID, NS_IDOMDRAGLISTENER_IID);
|
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
|
|
|
static NS_DEFINE_IID(kIDOMSelectionListenerIID, NS_IDOMSELECTIONLISTENER_IID);
|
1999-02-12 20:18:58 +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
|
|
|
static NS_DEFINE_IID(kIEditPropertyIID, NS_IEDITPROPERTY_IID);
|
|
|
|
static NS_DEFINE_CID(kEditorCID, NS_EDITOR_CID);
|
|
|
|
static NS_DEFINE_IID(kIEditorIID, NS_IEDITOR_IID);
|
|
|
|
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
|
|
static NS_DEFINE_IID(kITextEditorIID, NS_ITEXTEDITOR_IID);
|
|
|
|
static NS_DEFINE_CID(kTextEditorCID, NS_TEXTEDITOR_CID);
|
1999-02-12 20:18:58 +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
|
|
|
static NS_DEFINE_IID(kIContentIteratorIID, NS_ICONTENTITERTOR_IID);
|
|
|
|
static NS_DEFINE_CID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
|
|
|
|
|
1999-04-12 02:55:40 +04:00
|
|
|
static NS_DEFINE_IID(kIDOMRangeIID, NS_IDOMRANGE_IID);
|
|
|
|
static NS_DEFINE_CID(kCRangeCID, NS_RANGE_CID);
|
|
|
|
|
1999-04-04 22:01:35 +04:00
|
|
|
#ifdef NS_DEBUG
|
1999-04-12 02:55:40 +04:00
|
|
|
static PRBool gNoisy = PR_FALSE;
|
1999-04-04 22:01:35 +04:00
|
|
|
#else
|
|
|
|
static const PRBool gNoisy = PR_FALSE;
|
|
|
|
#endif
|
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
|
|
|
|
|
|
|
/* ---------- TypeInState implementation ---------- */
|
|
|
|
// most methods are defined inline in TypeInState.h
|
|
|
|
|
|
|
|
NS_IMPL_ADDREF(TypeInState)
|
|
|
|
|
|
|
|
NS_IMPL_RELEASE(TypeInState)
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
TypeInState::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|
|
|
{
|
|
|
|
if (nsnull == aInstancePtr) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
if (aIID.Equals(kISupportsIID)) {
|
|
|
|
*aInstancePtr = (void*)(nsISupports*)this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
if (aIID.Equals(kIDOMSelectionListenerIID)) {
|
|
|
|
*aInstancePtr = (void*)(nsIDOMSelectionListener*)this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
return NS_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
TypeInState::~TypeInState()
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
NS_IMETHODIMP TypeInState::NotifySelectionChanged()
|
|
|
|
{
|
|
|
|
Reset();
|
|
|
|
return NS_OK;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* ---------- nsTextEditor implementation ---------- */
|
1999-02-12 20:18:58 +03:00
|
|
|
|
|
|
|
nsTextEditor::nsTextEditor()
|
|
|
|
{
|
1999-03-06 00:05:35 +03:00
|
|
|
// Done in nsEditor
|
|
|
|
// NS_INIT_REFCNT();
|
1999-03-12 05:28:24 +03:00
|
|
|
mRules = nsnull;
|
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
|
|
|
nsEditProperty::InstanceInit();
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsTextEditor::~nsTextEditor()
|
|
|
|
{
|
|
|
|
//the autopointers will clear themselves up.
|
|
|
|
//but we need to also remove the listeners or we have a leak
|
1999-03-06 00:05:35 +03:00
|
|
|
nsCOMPtr<nsIDOMDocument> doc;
|
1999-03-11 01:41:18 +03:00
|
|
|
nsEditor::GetDocument(getter_AddRefs(doc));
|
1999-03-06 00:05:35 +03:00
|
|
|
if (doc)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-06 00:05:35 +03:00
|
|
|
nsCOMPtr<nsIDOMEventReceiver> erP;
|
|
|
|
nsresult result = doc->QueryInterface(kIDOMEventReceiverIID, getter_AddRefs(erP));
|
|
|
|
if (NS_SUCCEEDED(result) && erP)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-06 00:05:35 +03:00
|
|
|
if (mKeyListenerP) {
|
1999-03-29 02:27:38 +04:00
|
|
|
erP->RemoveEventListenerByIID(mKeyListenerP, kIDOMKeyListenerIID);
|
1999-03-06 00:05:35 +03:00
|
|
|
}
|
|
|
|
if (mMouseListenerP) {
|
1999-03-29 02:27:38 +04:00
|
|
|
erP->RemoveEventListenerByIID(mMouseListenerP, kIDOMMouseListenerIID);
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
1999-03-20 02:36:20 +03:00
|
|
|
|
|
|
|
if (mTextListenerP) {
|
1999-03-29 02:27:38 +04:00
|
|
|
erP->RemoveEventListenerByIID(mTextListenerP, kIDOMTextListenerIID);
|
1999-03-20 02:36:20 +03:00
|
|
|
}
|
|
|
|
|
1999-03-14 07:45:00 +03:00
|
|
|
if (mDragListenerP) {
|
1999-03-29 02:27:38 +04:00
|
|
|
erP->RemoveEventListenerByIID(mDragListenerP, kIDOMDragListenerIID);
|
1999-03-14 07:45:00 +03:00
|
|
|
}
|
1999-03-20 02:36:20 +03:00
|
|
|
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
1999-03-06 00:05:35 +03:00
|
|
|
else
|
|
|
|
NS_NOTREACHED("~nsTextEditor");
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
1999-03-12 05:28:24 +03:00
|
|
|
if (mRules) {
|
|
|
|
delete mRules;
|
|
|
|
}
|
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
|
|
|
nsEditProperty::InstanceShutdown();
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-06 00:05:35 +03:00
|
|
|
// Adds appropriate AddRef, Release, and QueryInterface methods for derived class
|
|
|
|
//NS_IMPL_ISUPPORTS_INHERITED(nsTextEditor, nsEditor, nsITextEditor)
|
|
|
|
|
|
|
|
//NS_IMPL_ADDREF_INHERITED(Class, Super)
|
|
|
|
NS_IMETHODIMP_(nsrefcnt) nsTextEditor::AddRef(void)
|
|
|
|
{
|
1999-03-11 01:41:18 +03:00
|
|
|
return nsEditor::AddRef();
|
1999-03-06 00:05:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//NS_IMPL_RELEASE_INHERITED(Class, Super)
|
|
|
|
NS_IMETHODIMP_(nsrefcnt) nsTextEditor::Release(void)
|
|
|
|
{
|
1999-03-11 01:41:18 +03:00
|
|
|
return nsEditor::Release();
|
1999-03-06 00:05:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//NS_IMPL_QUERY_INTERFACE_INHERITED(Class, Super, AdditionalInterface)
|
|
|
|
NS_IMETHODIMP nsTextEditor::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|
|
|
{
|
|
|
|
if (!aInstancePtr) return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
if (aIID.Equals(nsITextEditor::GetIID())) {
|
|
|
|
*aInstancePtr = NS_STATIC_CAST(nsITextEditor*, this);
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-03-11 01:41:18 +03:00
|
|
|
return nsEditor::QueryInterface(aIID, aInstancePtr);
|
1999-03-06 00:05:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsTextEditor::Init(nsIDOMDocument *aDoc, nsIPresShell *aPresShell)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
|
|
|
NS_PRECONDITION(nsnull!=aDoc && nsnull!=aPresShell, "bad arg");
|
|
|
|
nsresult result=NS_ERROR_NULL_POINTER;
|
|
|
|
if ((nsnull!=aDoc) && (nsnull!=aPresShell))
|
|
|
|
{
|
1999-03-06 00:05:35 +03:00
|
|
|
// Init the base editor
|
1999-03-11 01:41:18 +03:00
|
|
|
result = nsEditor::Init(aDoc, aPresShell);
|
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_OK != result) { return result; }
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMSelection>selection;
|
|
|
|
result = nsEditor::GetSelection(getter_AddRefs(selection));
|
|
|
|
if (NS_OK != result) { return result; }
|
|
|
|
if (selection) {
|
|
|
|
nsCOMPtr<nsIDOMSelectionListener>listener;
|
|
|
|
listener = do_QueryInterface(&mTypeInState);
|
|
|
|
if (listener) {
|
|
|
|
selection->AddSelectionListener(listener);
|
|
|
|
}
|
|
|
|
}
|
1999-02-12 20:18:58 +03:00
|
|
|
|
1999-03-29 12:02:05 +04:00
|
|
|
// Init the rules system
|
|
|
|
InitRules();
|
|
|
|
|
1999-02-12 20:18:58 +03:00
|
|
|
result = NS_NewEditorKeyListener(getter_AddRefs(mKeyListenerP), this);
|
|
|
|
if (NS_OK != result) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
result = NS_NewEditorMouseListener(getter_AddRefs(mMouseListenerP), this);
|
|
|
|
if (NS_OK != result) {
|
1999-02-19 14:30:31 +03:00
|
|
|
// drop the key listener if we couldn't get a mouse listener.
|
|
|
|
mKeyListenerP = do_QueryInterface(0);
|
1999-02-12 20:18:58 +03:00
|
|
|
return result;
|
|
|
|
}
|
1999-03-06 00:05:35 +03:00
|
|
|
|
1999-03-20 02:36:20 +03:00
|
|
|
result = NS_NewEditorTextListener(getter_AddRefs(mTextListenerP),this);
|
|
|
|
if (NS_OK !=result) {
|
|
|
|
// drop the key and mouse listeners
|
|
|
|
#ifdef DEBUG_TAGUE
|
|
|
|
printf("nsTextEditor.cpp: failed to get TextEvent Listener\n");
|
|
|
|
#endif
|
|
|
|
mMouseListenerP = do_QueryInterface(0);
|
|
|
|
mKeyListenerP = do_QueryInterface(0);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-03-14 07:45:00 +03:00
|
|
|
result = NS_NewEditorDragListener(getter_AddRefs(mDragListenerP), this);
|
|
|
|
if (NS_OK != result) {
|
|
|
|
//return result;
|
1999-03-20 02:36:20 +03:00
|
|
|
mMouseListenerP = do_QueryInterface(0);
|
|
|
|
mKeyListenerP = do_QueryInterface(0);
|
|
|
|
mTextListenerP = do_QueryInterface(0);
|
1999-03-14 07:45:00 +03:00
|
|
|
}
|
|
|
|
|
1999-02-12 20:18:58 +03:00
|
|
|
nsCOMPtr<nsIDOMEventReceiver> erP;
|
|
|
|
result = aDoc->QueryInterface(kIDOMEventReceiverIID, getter_AddRefs(erP));
|
|
|
|
if (NS_OK != result)
|
|
|
|
{
|
1999-02-19 14:30:31 +03:00
|
|
|
mKeyListenerP = do_QueryInterface(0);
|
|
|
|
mMouseListenerP = do_QueryInterface(0); //dont need these if we cant register them
|
1999-04-12 02:55:40 +04:00
|
|
|
mTextListenerP = do_QueryInterface(0);
|
1999-03-14 07:45:00 +03:00
|
|
|
mDragListenerP = do_QueryInterface(0); //dont need these if we cant register them
|
1999-02-12 20:18:58 +03:00
|
|
|
return result;
|
|
|
|
}
|
1999-03-06 00:05:35 +03:00
|
|
|
//cmanske: Shouldn't we check result from this?
|
1999-03-29 02:27:38 +04:00
|
|
|
erP->AddEventListenerByIID(mKeyListenerP, kIDOMKeyListenerIID);
|
1999-03-29 12:02:05 +04:00
|
|
|
//erP->AddEventListener(mDragListenerP, kIDOMDragListenerIID);
|
|
|
|
//erP->AddEventListener(mMouseListenerP, kIDOMMouseListenerIID);
|
1999-03-20 02:36:20 +03:00
|
|
|
|
1999-03-29 12:02:05 +04:00
|
|
|
erP->AddEventListenerByIID(mTextListenerP,kIDOMTextListenerIID);
|
1999-03-10 22:48:46 +03:00
|
|
|
|
1999-02-12 20:18:58 +03:00
|
|
|
result = NS_OK;
|
1999-03-06 00:05:35 +03:00
|
|
|
|
|
|
|
EnableUndo(PR_TRUE);
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-03-29 12:02:05 +04:00
|
|
|
void nsTextEditor::InitRules()
|
|
|
|
{
|
|
|
|
// instantiate the rules for this text editor
|
|
|
|
// XXX: we should be told which set of rules to instantiate
|
|
|
|
mRules = new nsTextEditRules();
|
|
|
|
mRules->Init(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-03-02 10:52:41 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::SetTextProperty(nsIAtom *aProperty)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-02 10:52:41 +03:00
|
|
|
if (!aProperty)
|
1999-02-24 20:24:37 +03:00
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy)
|
|
|
|
{
|
|
|
|
nsAutoString propString;
|
|
|
|
aProperty->ToString(propString);
|
|
|
|
char *propCString = propString.ToNewCString();
|
|
|
|
if (gNoisy) { printf("---------- nsTextEditor::SetTextProperty %s ----------\n", propCString); }
|
|
|
|
delete [] propCString;
|
|
|
|
}
|
|
|
|
|
1999-02-12 20:18:58 +03:00
|
|
|
nsresult result=NS_ERROR_NOT_INITIALIZED;
|
1999-03-06 00:05:35 +03:00
|
|
|
nsCOMPtr<nsIDOMSelection>selection;
|
1999-03-11 01:41:18 +03:00
|
|
|
result = nsEditor::GetSelection(getter_AddRefs(selection));
|
1999-03-06 00:05:35 +03:00
|
|
|
if ((NS_SUCCEEDED(result)) && selection)
|
|
|
|
{
|
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
|
|
|
PRBool isCollapsed;
|
1999-04-13 05:33:32 +04:00
|
|
|
selection->GetIsCollapsed(&isCollapsed);
|
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 (PR_TRUE==isCollapsed)
|
1999-02-24 20:24:37 +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
|
|
|
// manipulating text attributes on a collapsed selection only sets state for the next text insertion
|
|
|
|
SetTypeInStateForProperty(mTypeInState, aProperty);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nsEditor::BeginTransaction();
|
|
|
|
nsCOMPtr<nsIEnumerator> enumerator;
|
1999-04-04 22:01:35 +04:00
|
|
|
enumerator = do_QueryInterface(selection);
|
|
|
|
if (enumerator)
|
1999-02-24 20:24:37 +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
|
|
|
enumerator->First();
|
|
|
|
nsISupports *currentItem;
|
|
|
|
result = enumerator->CurrentItem(¤tItem);
|
|
|
|
if ((NS_SUCCEEDED(result)) && (nsnull!=currentItem))
|
1999-02-24 20:24:37 +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
|
|
|
nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
|
|
|
|
nsCOMPtr<nsIDOMNode>commonParent;
|
|
|
|
result = range->GetCommonParent(getter_AddRefs(commonParent));
|
|
|
|
if ((NS_SUCCEEDED(result)) && commonParent)
|
1999-02-24 20:24:37 +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
|
|
|
PRInt32 startOffset, endOffset;
|
|
|
|
range->GetStartOffset(&startOffset);
|
|
|
|
range->GetEndOffset(&endOffset);
|
|
|
|
nsCOMPtr<nsIDOMNode> startParent; nsCOMPtr<nsIDOMNode> endParent;
|
|
|
|
range->GetStartParent(getter_AddRefs(startParent));
|
|
|
|
range->GetEndParent(getter_AddRefs(endParent));
|
|
|
|
if (startParent.get()==endParent.get())
|
|
|
|
{ // the range is entirely contained within a single text node
|
|
|
|
// commonParent==aStartParent, so get the "real" parent of the selection
|
|
|
|
startParent->GetParentNode(getter_AddRefs(commonParent));
|
|
|
|
result = SetTextPropertiesForNode(startParent, commonParent,
|
|
|
|
startOffset, endOffset,
|
|
|
|
aProperty);
|
|
|
|
}
|
|
|
|
else
|
1999-02-24 20:24:37 +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
|
|
|
nsCOMPtr<nsIDOMNode> startGrandParent;
|
|
|
|
startParent->GetParentNode(getter_AddRefs(startGrandParent));
|
|
|
|
nsCOMPtr<nsIDOMNode> endGrandParent;
|
|
|
|
endParent->GetParentNode(getter_AddRefs(endGrandParent));
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
PRBool canCollapseStyleNode = PR_FALSE;
|
|
|
|
if (endGrandParent.get()==startGrandParent.get())
|
|
|
|
{
|
|
|
|
result = IntermediateNodesAreInline(range, startParent, startOffset,
|
|
|
|
endParent, endOffset,
|
|
|
|
startGrandParent, canCollapseStyleNode);
|
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
if (PR_TRUE==canCollapseStyleNode)
|
|
|
|
{ // the range is between 2 nodes that have a common (immediate) grandparent,
|
|
|
|
// and any intermediate nodes are just inline style nodes
|
|
|
|
result = SetTextPropertiesForNodesWithSameParent(startParent,startOffset,
|
|
|
|
endParent, endOffset,
|
|
|
|
commonParent,
|
|
|
|
aProperty);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // the range is between 2 nodes that have no simple relationship
|
|
|
|
result = SetTextPropertiesForNodeWithDifferentParents(range,
|
|
|
|
startParent,startOffset,
|
|
|
|
endParent, endOffset,
|
|
|
|
commonParent,
|
|
|
|
aProperty);
|
|
|
|
}
|
|
|
|
}
|
1999-02-24 20:24:37 +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
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{ // compute a range for the selection
|
|
|
|
// don't want to actually do anything with selection, because
|
|
|
|
// we are still iterating through it. Just want to create and remember
|
|
|
|
// an nsIDOMRange, and later add the range to the selection after clearing it.
|
|
|
|
// XXX: I'm blocked here because nsIDOMSelection doesn't provide a mechanism
|
|
|
|
// for setting a compound selection yet.
|
|
|
|
}
|
1999-02-24 20:24:37 +03:00
|
|
|
}
|
|
|
|
}
|
1999-03-02 10:52:41 +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
|
|
|
nsEditor::EndTransaction();
|
1999-03-06 00:05:35 +03:00
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{ // set the selection
|
|
|
|
// XXX: can't do anything until I can create ranges
|
1999-02-24 20:24:37 +03:00
|
|
|
}
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
1999-02-12 20:18:58 +03:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-04-04 22:01:35 +04:00
|
|
|
NS_IMETHODIMP nsTextEditor::GetTextProperty(nsIAtom *aProperty, PRBool &aFirst, PRBool &aAny, PRBool &aAll)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-02 10:52:41 +03:00
|
|
|
if (!aProperty)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy)
|
|
|
|
{
|
|
|
|
nsAutoString propString;
|
|
|
|
aProperty->ToString(propString);
|
|
|
|
char *propCString = propString.ToNewCString();
|
|
|
|
if (gNoisy) { printf("nsTextEditor::GetTextProperty %s\n", propCString); }
|
|
|
|
delete [] propCString;
|
|
|
|
}
|
|
|
|
|
1999-02-12 20:18:58 +03:00
|
|
|
nsresult result=NS_ERROR_NOT_INITIALIZED;
|
1999-03-02 10:52:41 +03:00
|
|
|
aAny=PR_FALSE;
|
|
|
|
aAll=PR_TRUE;
|
1999-04-04 22:01:35 +04:00
|
|
|
aFirst=PR_FALSE;
|
|
|
|
PRBool first=PR_TRUE;
|
1999-03-06 00:05:35 +03:00
|
|
|
nsCOMPtr<nsIDOMSelection>selection;
|
1999-03-11 01:41:18 +03:00
|
|
|
result = nsEditor::GetSelection(getter_AddRefs(selection));
|
1999-03-06 00:05:35 +03:00
|
|
|
if ((NS_SUCCEEDED(result)) && selection)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-06 00:05:35 +03:00
|
|
|
nsCOMPtr<nsIEnumerator> enumerator;
|
1999-04-04 22:01:35 +04:00
|
|
|
enumerator = do_QueryInterface(selection);
|
|
|
|
if (enumerator)
|
1999-03-02 10:52:41 +03:00
|
|
|
{
|
1999-03-06 00:05:35 +03:00
|
|
|
enumerator->First();
|
|
|
|
nsISupports *currentItem;
|
|
|
|
result = enumerator->CurrentItem(¤tItem);
|
1999-04-12 02:55:40 +04:00
|
|
|
// XXX: should be a while loop, to get each separate range
|
1999-03-06 00:05:35 +03:00
|
|
|
if ((NS_SUCCEEDED(result)) && currentItem)
|
1999-03-02 10:52:41 +03:00
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
PRBool firstNodeInRange = PR_TRUE; // for each range, set a flag
|
1999-03-06 00:05:35 +03:00
|
|
|
nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
|
|
|
|
nsCOMPtr<nsIContentIterator> iter;
|
1999-03-09 12:44:27 +03:00
|
|
|
result = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull,
|
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
|
|
|
kIContentIteratorIID,
|
|
|
|
getter_AddRefs(iter));
|
1999-03-06 00:05:35 +03:00
|
|
|
if ((NS_SUCCEEDED(result)) && iter)
|
1999-03-02 10:52:41 +03:00
|
|
|
{
|
1999-03-06 00:05:35 +03:00
|
|
|
iter->Init(range);
|
|
|
|
// loop through the content iterator for each content node
|
|
|
|
// for each text node:
|
|
|
|
// get the frame for the content, and from it the style context
|
|
|
|
// ask the style context about the property
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
result = iter->CurrentNode(getter_AddRefs(content));
|
|
|
|
while (NS_COMFALSE == iter->IsDone())
|
1999-03-02 10:52:41 +03:00
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf(" checking node %p\n", content.get()); }
|
1999-03-06 00:05:35 +03:00
|
|
|
nsCOMPtr<nsIDOMCharacterData>text;
|
|
|
|
text = do_QueryInterface(content);
|
|
|
|
if (text)
|
1999-03-02 10:52:41 +03:00
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
PRBool skipNode = PR_FALSE;
|
|
|
|
if (PR_TRUE==first && PR_TRUE==firstNodeInRange)
|
1999-03-02 10:52:41 +03:00
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
firstNodeInRange = PR_FALSE;
|
|
|
|
PRInt32 startOffset;
|
|
|
|
range->GetStartOffset(&startOffset);
|
|
|
|
PRUint32 count;
|
|
|
|
text->GetLength(&count);
|
|
|
|
if (startOffset==(PRInt32)count)
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf(" skipping node %p\n", content.get()); }
|
|
|
|
skipNode = PR_TRUE;
|
1999-04-04 22:01:35 +04:00
|
|
|
}
|
1999-04-12 02:55:40 +04:00
|
|
|
}
|
|
|
|
if (PR_FALSE==skipNode)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode>node;
|
|
|
|
node = do_QueryInterface(content);
|
|
|
|
if (node)
|
|
|
|
{
|
|
|
|
PRBool isSet;
|
|
|
|
nsCOMPtr<nsIDOMNode>resultNode;
|
|
|
|
IsTextPropertySetByContent(node, aProperty, isSet, getter_AddRefs(resultNode));
|
|
|
|
if (PR_TRUE==first)
|
|
|
|
{
|
|
|
|
aFirst = isSet;
|
|
|
|
first = PR_FALSE;
|
|
|
|
}
|
|
|
|
if (PR_TRUE==isSet) {
|
|
|
|
aAny = PR_TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
aAll = PR_FALSE;
|
|
|
|
}
|
1999-03-02 10:52:41 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-03-06 00:05:35 +03:00
|
|
|
iter->Next();
|
|
|
|
result = iter->CurrentNode(getter_AddRefs(content));
|
1999-03-02 10:52:41 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf(" returning first=%d any=%d all=%d\n", aFirst, aAny, aAll); }
|
1999-02-12 20:18:58 +03:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-03-02 10:52:41 +03:00
|
|
|
void nsTextEditor::IsTextStyleSet(nsIStyleContext *aSC,
|
|
|
|
nsIAtom *aProperty,
|
|
|
|
PRBool &aIsSet) const
|
|
|
|
{
|
|
|
|
aIsSet = PR_FALSE;
|
|
|
|
if (aSC && aProperty)
|
|
|
|
{
|
|
|
|
nsStyleFont* font = (nsStyleFont*)aSC->GetStyleData(eStyleStruct_Font);
|
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 (nsIEditProperty::i==aProperty)
|
1999-03-02 10:52:41 +03:00
|
|
|
{
|
|
|
|
aIsSet = PRBool(font->mFont.style & NS_FONT_STYLE_ITALIC);
|
|
|
|
}
|
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 if (nsIEditProperty::b==aProperty)
|
1999-03-02 10:52:41 +03:00
|
|
|
{ // XXX: check this logic with Peter
|
|
|
|
aIsSet = PRBool(font->mFont.weight > NS_FONT_WEIGHT_NORMAL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-04-06 22:21:43 +04:00
|
|
|
void nsTextEditor::IsTextPropertySetByContent(nsIDOMNode *aNode,
|
|
|
|
nsIAtom *aProperty,
|
|
|
|
PRBool &aIsSet,
|
|
|
|
nsIDOMNode **aStyleNode) const
|
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
|
|
|
{
|
|
|
|
nsresult result;
|
|
|
|
aIsSet = PR_FALSE;
|
|
|
|
nsAutoString propName;
|
|
|
|
aProperty->ToString(propName);
|
|
|
|
nsCOMPtr<nsIDOMNode>parent;
|
|
|
|
result = aNode->GetParentNode(getter_AddRefs(parent));
|
|
|
|
while (NS_SUCCEEDED(result) && parent)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMElement>element;
|
|
|
|
element = do_QueryInterface(parent);
|
|
|
|
if (element)
|
|
|
|
{
|
|
|
|
nsString tag;
|
|
|
|
element->GetTagName(tag);
|
|
|
|
if (propName.Equals(tag))
|
|
|
|
{
|
|
|
|
aIsSet = PR_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMNode>temp;
|
|
|
|
result = parent->GetParentNode(getter_AddRefs(temp));
|
|
|
|
if (NS_SUCCEEDED(result) && temp) {
|
|
|
|
parent = do_QueryInterface(temp);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
parent = do_QueryInterface(nsnull);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-03-02 10:52:41 +03:00
|
|
|
|
|
|
|
NS_IMETHODIMP nsTextEditor::RemoveTextProperty(nsIAtom *aProperty)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-04-04 22:01:35 +04:00
|
|
|
if (!aProperty)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy)
|
|
|
|
{
|
|
|
|
nsAutoString propString;
|
|
|
|
aProperty->ToString(propString);
|
|
|
|
char *propCString = propString.ToNewCString();
|
|
|
|
if (gNoisy) { printf("---------- nsTextEditor::RemoveTextProperty %s ----------\n", propCString); }
|
|
|
|
delete [] propCString;
|
|
|
|
}
|
|
|
|
|
1999-04-04 22:01:35 +04:00
|
|
|
nsresult result=NS_ERROR_NOT_INITIALIZED;
|
|
|
|
nsCOMPtr<nsIDOMSelection>selection;
|
|
|
|
result = nsEditor::GetSelection(getter_AddRefs(selection));
|
|
|
|
if ((NS_SUCCEEDED(result)) && selection)
|
|
|
|
{
|
|
|
|
PRBool isCollapsed;
|
1999-04-13 05:33:32 +04:00
|
|
|
selection->GetIsCollapsed(&isCollapsed);
|
1999-04-04 22:01:35 +04:00
|
|
|
if (PR_TRUE==isCollapsed)
|
|
|
|
{
|
|
|
|
// manipulating text attributes on a collapsed selection only sets state for the next text insertion
|
|
|
|
SetTypeInStateForProperty(mTypeInState, aProperty);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nsEditor::BeginTransaction();
|
|
|
|
nsCOMPtr<nsIEnumerator> enumerator;
|
|
|
|
enumerator = do_QueryInterface(selection);
|
|
|
|
if (enumerator)
|
|
|
|
{
|
|
|
|
enumerator->First();
|
|
|
|
nsISupports *currentItem;
|
|
|
|
result = enumerator->CurrentItem(¤tItem);
|
|
|
|
if ((NS_SUCCEEDED(result)) && (nsnull!=currentItem))
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMRange> range( do_QueryInterface(currentItem) );
|
|
|
|
nsCOMPtr<nsIDOMNode>commonParent;
|
|
|
|
result = range->GetCommonParent(getter_AddRefs(commonParent));
|
|
|
|
if ((NS_SUCCEEDED(result)) && commonParent)
|
|
|
|
{
|
|
|
|
PRInt32 startOffset, endOffset;
|
|
|
|
range->GetStartOffset(&startOffset);
|
|
|
|
range->GetEndOffset(&endOffset);
|
|
|
|
nsCOMPtr<nsIDOMNode> startParent; nsCOMPtr<nsIDOMNode> endParent;
|
|
|
|
range->GetStartParent(getter_AddRefs(startParent));
|
|
|
|
range->GetEndParent(getter_AddRefs(endParent));
|
|
|
|
if (startParent.get()==endParent.get())
|
|
|
|
{ // the range is entirely contained within a single text node
|
|
|
|
// commonParent==aStartParent, so get the "real" parent of the selection
|
|
|
|
startParent->GetParentNode(getter_AddRefs(commonParent));
|
|
|
|
result = RemoveTextPropertiesForNode(startParent, commonParent,
|
|
|
|
startOffset, endOffset,
|
|
|
|
aProperty);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode> startGrandParent;
|
|
|
|
startParent->GetParentNode(getter_AddRefs(startGrandParent));
|
|
|
|
nsCOMPtr<nsIDOMNode> endGrandParent;
|
|
|
|
endParent->GetParentNode(getter_AddRefs(endGrandParent));
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
PRBool canCollapseStyleNode = PR_FALSE;
|
|
|
|
if (endGrandParent.get()==startGrandParent.get())
|
|
|
|
{
|
|
|
|
result = IntermediateNodesAreInline(range, startParent, startOffset,
|
|
|
|
endParent, endOffset,
|
|
|
|
startGrandParent, canCollapseStyleNode);
|
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
if (PR_TRUE==canCollapseStyleNode)
|
|
|
|
{ // the range is between 2 nodes that have a common (immediate) grandparent,
|
|
|
|
// and any intermediate nodes are just inline style nodes
|
|
|
|
result = RemoveTextPropertiesForNodesWithSameParent(startParent,startOffset,
|
|
|
|
endParent, endOffset,
|
|
|
|
commonParent,
|
|
|
|
aProperty);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // the range is between 2 nodes that have no simple relationship
|
|
|
|
result = RemoveTextPropertiesForNodeWithDifferentParents(range,
|
|
|
|
startParent,startOffset,
|
|
|
|
endParent, endOffset,
|
|
|
|
commonParent,
|
|
|
|
aProperty);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{ // compute a range for the selection
|
|
|
|
// don't want to actually do anything with selection, because
|
|
|
|
// we are still iterating through it. Just want to create and remember
|
|
|
|
// an nsIDOMRange, and later add the range to the selection after clearing it.
|
|
|
|
// XXX: I'm blocked here because nsIDOMSelection doesn't provide a mechanism
|
|
|
|
// for setting a compound selection yet.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nsEditor::EndTransaction();
|
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{ // set the selection
|
|
|
|
// XXX: can't do anything until I can create ranges
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::DeleteSelection(nsIEditor::Direction aDir)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-12 05:28:24 +03:00
|
|
|
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMSelection> selection;
|
|
|
|
PRBool cancel= PR_FALSE;
|
|
|
|
|
|
|
|
nsresult result = nsEditor::BeginTransaction();
|
|
|
|
if (NS_FAILED(result)) { return result; }
|
|
|
|
|
|
|
|
// pre-process
|
|
|
|
nsEditor::GetSelection(getter_AddRefs(selection));
|
1999-04-12 16:01:32 +04:00
|
|
|
nsTextRulesInfo ruleInfo(nsTextEditRules::kDeleteSelection);
|
|
|
|
result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
1999-03-12 05:28:24 +03:00
|
|
|
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
|
|
|
|
{
|
|
|
|
result = nsEditor::DeleteSelection(aDir);
|
|
|
|
// post-process
|
1999-04-12 16:01:32 +04:00
|
|
|
result = mRules->DidDoAction(selection, &ruleInfo, result);
|
1999-03-12 05:28:24 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult endTxnResult = nsEditor::EndTransaction(); // don't return this result!
|
|
|
|
NS_ASSERTION ((NS_SUCCEEDED(endTxnResult)), "bad end transaction result");
|
|
|
|
|
1999-03-14 04:02:53 +03:00
|
|
|
|
|
|
|
// XXXX: Horrible hack! We are doing this because
|
|
|
|
// of an error in Gecko which is not rendering the
|
|
|
|
// document after a change via the DOM - gpk 2/13/99
|
|
|
|
// BEGIN HACK!!!
|
|
|
|
HACKForceRedraw();
|
|
|
|
// END HACK
|
|
|
|
|
1999-03-12 05:28:24 +03:00
|
|
|
return result;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::InsertText(const nsString& aStringToInsert)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-13 07:53:21 +03:00
|
|
|
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMSelection> selection;
|
|
|
|
PRBool cancel= PR_FALSE;
|
|
|
|
|
|
|
|
// pre-process
|
|
|
|
nsEditor::GetSelection(getter_AddRefs(selection));
|
1999-04-12 16:01:32 +04:00
|
|
|
nsString resultString;
|
1999-03-15 03:57:32 +03:00
|
|
|
PlaceholderTxn *placeholderTxn=nsnull;
|
1999-04-12 16:01:32 +04:00
|
|
|
nsTextRulesInfo ruleInfo(nsTextEditRules::kInsertText);
|
|
|
|
ruleInfo.placeTxn = &placeholderTxn;
|
|
|
|
ruleInfo.inString = &aStringToInsert;
|
|
|
|
ruleInfo.outString = &resultString;
|
|
|
|
ruleInfo.typeInState = mTypeInState;
|
|
|
|
|
|
|
|
nsresult result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
1999-03-13 07:53:21 +03:00
|
|
|
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
|
|
|
|
{
|
1999-04-05 23:21:22 +04:00
|
|
|
result = nsEditor::InsertText(aStringToInsert);
|
1999-03-13 07:53:21 +03:00
|
|
|
// post-process
|
1999-04-12 16:01:32 +04:00
|
|
|
result = mRules->DidDoAction(selection, &ruleInfo, result);
|
1999-03-13 07:53:21 +03:00
|
|
|
}
|
1999-03-15 03:57:32 +03:00
|
|
|
if (placeholderTxn)
|
|
|
|
placeholderTxn->SetAbsorb(PR_FALSE); // this ends the merging of txns into placeholderTxn
|
1999-03-13 07:53:21 +03:00
|
|
|
|
1999-03-14 04:02:53 +03:00
|
|
|
// BEGIN HACK!!!
|
|
|
|
HACKForceRedraw();
|
|
|
|
// END HACK
|
1999-03-13 07:53:21 +03:00
|
|
|
return result;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-10 22:48:46 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::InsertBreak()
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-29 12:02:05 +04:00
|
|
|
// For plainttext just pass newlines through
|
|
|
|
nsAutoString key;
|
|
|
|
key += '\n';
|
|
|
|
return InsertText(key);
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-10 22:48:46 +03:00
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::EnableUndo(PRBool aEnable)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-11 01:41:18 +03:00
|
|
|
return nsEditor::EnableUndo(aEnable);
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::Undo(PRUint32 aCount)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-15 08:08:30 +03:00
|
|
|
nsCOMPtr<nsIDOMSelection> selection;
|
|
|
|
PRBool cancel= PR_FALSE;
|
|
|
|
|
|
|
|
// pre-process
|
|
|
|
nsEditor::GetSelection(getter_AddRefs(selection));
|
1999-04-12 16:01:32 +04:00
|
|
|
nsTextRulesInfo ruleInfo(nsTextEditRules::kUndo);
|
|
|
|
nsresult result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
1999-03-15 08:08:30 +03:00
|
|
|
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
|
|
|
|
{
|
|
|
|
result = nsEditor::Undo(aCount);
|
|
|
|
nsEditor::GetSelection(getter_AddRefs(selection));
|
1999-04-12 16:01:32 +04:00
|
|
|
result = mRules->DidDoAction(selection, &ruleInfo, result);
|
1999-03-15 08:08:30 +03:00
|
|
|
}
|
|
|
|
return result;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::CanUndo(PRBool &aIsEnabled, PRBool &aCanUndo)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-11 01:41:18 +03:00
|
|
|
return nsEditor::CanUndo(aIsEnabled, aCanUndo);
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::Redo(PRUint32 aCount)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-15 08:08:30 +03:00
|
|
|
nsCOMPtr<nsIDOMSelection> selection;
|
|
|
|
PRBool cancel= PR_FALSE;
|
|
|
|
|
|
|
|
// pre-process
|
|
|
|
nsEditor::GetSelection(getter_AddRefs(selection));
|
1999-04-12 16:01:32 +04:00
|
|
|
nsTextRulesInfo ruleInfo(nsTextEditRules::kRedo);
|
|
|
|
nsresult result = mRules->WillDoAction(selection, &ruleInfo, &cancel);
|
1999-03-15 08:08:30 +03:00
|
|
|
if ((PR_FALSE==cancel) && (NS_SUCCEEDED(result)))
|
|
|
|
{
|
|
|
|
result = nsEditor::Redo(aCount);
|
|
|
|
nsEditor::GetSelection(getter_AddRefs(selection));
|
1999-04-12 16:01:32 +04:00
|
|
|
result = mRules->DidDoAction(selection, &ruleInfo, result);
|
1999-03-15 08:08:30 +03:00
|
|
|
}
|
|
|
|
return result;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::CanRedo(PRBool &aIsEnabled, PRBool &aCanRedo)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-11 01:41:18 +03:00
|
|
|
return nsEditor::CanRedo(aIsEnabled, aCanRedo);
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::BeginTransaction()
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-11 01:41:18 +03:00
|
|
|
return nsEditor::BeginTransaction();
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::EndTransaction()
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-11 01:41:18 +03:00
|
|
|
return nsEditor::EndTransaction();
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::MoveSelectionUp(nsIAtom *aIncrement, PRBool aExtendSelection)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-06 00:05:35 +03:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::MoveSelectionDown(nsIAtom *aIncrement, PRBool aExtendSelection)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-06 00:05:35 +03:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::MoveSelectionNext(nsIAtom *aIncrement, PRBool aExtendSelection)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-06 00:05:35 +03:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::MoveSelectionPrevious(nsIAtom *aIncrement, PRBool aExtendSelection)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-06 00:05:35 +03:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::SelectNext(nsIAtom *aIncrement, PRBool aExtendSelection)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-06 00:05:35 +03:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::SelectPrevious(nsIAtom *aIncrement, PRBool aExtendSelection)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-06 00:05:35 +03:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-10 22:48:46 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::SelectAll()
|
|
|
|
{
|
1999-03-11 01:41:18 +03:00
|
|
|
return nsEditor::SelectAll();
|
1999-03-10 22:48:46 +03:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::ScrollUp(nsIAtom *aIncrement)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-06 00:05:35 +03:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::ScrollDown(nsIAtom *aIncrement)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-06 00:05:35 +03:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::ScrollIntoView(PRBool aScrollToBegin)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-11 01:41:18 +03:00
|
|
|
return nsEditor::ScrollIntoView(aScrollToBegin);
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-11 00:29:41 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::Cut()
|
|
|
|
{
|
1999-03-11 01:41:18 +03:00
|
|
|
return nsEditor::Cut();
|
1999-03-11 00:29:41 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsTextEditor::Copy()
|
|
|
|
{
|
1999-03-11 01:41:18 +03:00
|
|
|
return nsEditor::Copy();
|
1999-03-11 00:29:41 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsTextEditor::Paste()
|
|
|
|
{
|
1999-03-11 01:41:18 +03:00
|
|
|
return nsEditor::Paste();
|
1999-03-11 00:29:41 +03:00
|
|
|
}
|
|
|
|
|
1999-03-30 02:01:26 +04:00
|
|
|
NS_IMETHODIMP nsTextEditor::Insert(nsString& aInputString)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-30 02:01:26 +04:00
|
|
|
printf("nsTextEditor::Insert not yet implemented\n");
|
1999-03-06 00:05:35 +03:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-05 00:53:42 +03:00
|
|
|
#ifdef XP_MAC
|
1999-03-06 23:32:48 +03:00
|
|
|
static void WriteFromStringstream(stringstream& aIn, nsString& aOutputString)
|
1999-03-05 00:53:42 +03:00
|
|
|
{
|
1999-03-06 23:32:48 +03:00
|
|
|
string theString = aIn.str();
|
1999-03-05 00:53:42 +03:00
|
|
|
|
1999-03-12 00:31:03 +03:00
|
|
|
aOutputString.SetLength(0); // empty the string
|
1999-03-06 23:32:48 +03:00
|
|
|
aOutputString += theString.data();
|
1999-03-12 00:31:03 +03:00
|
|
|
aOutputString.SetLength(theString.length()); // make sure it's terminated
|
1999-03-06 23:32:48 +03:00
|
|
|
|
|
|
|
/* relace LF with CR. Don't do this here, because strings passed out
|
|
|
|
to JavaScript need LF termination.
|
|
|
|
PRUnichar lineFeed = '\n';
|
|
|
|
PRUnichar carriageReturn = '\r';
|
|
|
|
aOutputString.ReplaceChar(lineFeed, carriageReturn);
|
|
|
|
*/
|
1999-03-05 00:53:42 +03:00
|
|
|
}
|
|
|
|
#else
|
1999-03-06 23:32:48 +03:00
|
|
|
static void WriteFromOstrstream(ostrstream& aIn, nsString& aOutputString)
|
1999-03-05 00:53:42 +03:00
|
|
|
{
|
1999-03-12 00:31:03 +03:00
|
|
|
char* strData = aIn.str(); // get a copy of the buffer (unterminated)
|
1999-03-06 23:32:48 +03:00
|
|
|
|
|
|
|
aOutputString.SetLength(0); // empty the string
|
|
|
|
aOutputString += strData;
|
1999-03-12 00:31:03 +03:00
|
|
|
aOutputString.SetLength(aIn.pcount()); // terminate
|
1999-03-06 23:32:48 +03:00
|
|
|
|
|
|
|
// in ostrstreams if you call the str() function
|
|
|
|
// then you are responsible for deleting the string
|
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
|
|
|
delete [] strData;
|
1999-03-05 00:53:42 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1999-03-06 23:32:48 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::OutputText(nsString& aOutputString)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-05 00:53:42 +03:00
|
|
|
#ifdef XP_MAC
|
1999-03-06 23:32:48 +03:00
|
|
|
stringstream outStream;
|
1999-03-05 00:53:42 +03:00
|
|
|
#else
|
1999-03-06 23:32:48 +03:00
|
|
|
ostrstream outStream;
|
1999-03-05 00:53:42 +03:00
|
|
|
#endif
|
|
|
|
|
1999-03-06 23:32:48 +03:00
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
1999-03-06 00:05:35 +03:00
|
|
|
nsIPresShell* shell = nsnull;
|
1999-03-06 23:32:48 +03:00
|
|
|
|
|
|
|
GetPresShell(&shell);
|
1999-03-06 00:05:35 +03:00
|
|
|
if (nsnull != shell) {
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
shell->GetDocument(getter_AddRefs(doc));
|
|
|
|
if (doc) {
|
|
|
|
nsString buffer;
|
1999-03-05 00:53:42 +03:00
|
|
|
|
1999-03-06 00:05:35 +03:00
|
|
|
doc->CreateXIF(buffer);
|
1999-03-05 00:53:42 +03:00
|
|
|
|
1999-03-06 00:05:35 +03:00
|
|
|
nsIParser* parser;
|
1999-03-05 00:53:42 +03:00
|
|
|
|
1999-03-06 00:05:35 +03:00
|
|
|
static NS_DEFINE_IID(kCParserIID, NS_IPARSER_IID);
|
|
|
|
static NS_DEFINE_IID(kCParserCID, NS_PARSER_IID);
|
1999-03-05 00:53:42 +03:00
|
|
|
|
1999-03-09 12:44:27 +03:00
|
|
|
rv = nsComponentManager::CreateInstance(kCParserCID,
|
1999-03-06 00:05:35 +03:00
|
|
|
nsnull,
|
|
|
|
kCParserIID,
|
|
|
|
(void **)&parser);
|
1999-03-05 00:53:42 +03:00
|
|
|
|
1999-03-06 00:05:35 +03:00
|
|
|
if (NS_OK == rv) {
|
|
|
|
nsIHTMLContentSink* sink = nsnull;
|
|
|
|
|
|
|
|
rv = NS_New_HTMLToTXT_SinkStream(&sink);
|
1999-03-06 23:32:48 +03:00
|
|
|
if (NS_OK == rv) {
|
|
|
|
// what't this cast doing here, Greg?
|
|
|
|
((nsHTMLContentSinkStream*)sink)->SetOutputStream(outStream);
|
|
|
|
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
parser->SetContentSink(sink);
|
|
|
|
|
|
|
|
nsIDTD* dtd = nsnull;
|
|
|
|
rv = NS_NewXIFDTD(&dtd);
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
parser->RegisterDTD(dtd);
|
|
|
|
parser->Parse(buffer, 0, "text/xif",PR_FALSE,PR_TRUE);
|
|
|
|
}
|
|
|
|
#ifdef XP_MAC
|
|
|
|
WriteFromStringstream(outStream, aOutputString);
|
|
|
|
#else
|
|
|
|
WriteFromOstrstream(outStream, aOutputString);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
NS_IF_RELEASE(dtd);
|
|
|
|
NS_IF_RELEASE(sink);
|
1999-03-05 00:53:42 +03:00
|
|
|
}
|
|
|
|
}
|
1999-03-06 00:05:35 +03:00
|
|
|
NS_RELEASE(parser);
|
1999-03-05 00:53:42 +03:00
|
|
|
}
|
|
|
|
}
|
1999-03-06 00:05:35 +03:00
|
|
|
NS_RELEASE(shell);
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
1999-03-06 23:32:48 +03:00
|
|
|
|
|
|
|
return rv;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
1999-03-05 00:53:42 +03:00
|
|
|
|
|
|
|
|
1999-03-06 23:32:48 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::OutputHTML(nsString& aOutputString)
|
1999-02-12 20:18:58 +03:00
|
|
|
{
|
1999-03-05 00:53:42 +03:00
|
|
|
#ifdef XP_MAC
|
1999-03-06 23:32:48 +03:00
|
|
|
stringstream outStream;
|
1999-03-05 00:53:42 +03:00
|
|
|
#else
|
1999-03-06 23:32:48 +03:00
|
|
|
ostrstream outStream;
|
1999-03-05 00:53:42 +03:00
|
|
|
#endif
|
|
|
|
|
1999-03-06 23:32:48 +03:00
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
1999-03-06 00:05:35 +03:00
|
|
|
nsIPresShell* shell = nsnull;
|
1999-03-06 23:32:48 +03:00
|
|
|
|
|
|
|
GetPresShell(&shell);
|
1999-03-06 00:05:35 +03:00
|
|
|
if (nsnull != shell) {
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
shell->GetDocument(getter_AddRefs(doc));
|
|
|
|
if (doc) {
|
|
|
|
nsString buffer;
|
1999-03-05 00:53:42 +03:00
|
|
|
|
1999-03-06 00:05:35 +03:00
|
|
|
doc->CreateXIF(buffer);
|
1999-03-05 00:53:42 +03:00
|
|
|
|
1999-03-06 00:05:35 +03:00
|
|
|
nsIParser* parser;
|
1999-03-05 00:53:42 +03:00
|
|
|
|
1999-03-06 00:05:35 +03:00
|
|
|
static NS_DEFINE_IID(kCParserIID, NS_IPARSER_IID);
|
|
|
|
static NS_DEFINE_IID(kCParserCID, NS_PARSER_IID);
|
1999-03-05 00:53:42 +03:00
|
|
|
|
1999-03-09 12:44:27 +03:00
|
|
|
rv = nsComponentManager::CreateInstance(kCParserCID,
|
1999-03-06 00:05:35 +03:00
|
|
|
nsnull,
|
|
|
|
kCParserIID,
|
|
|
|
(void **)&parser);
|
1999-03-05 00:53:42 +03:00
|
|
|
|
1999-03-06 00:05:35 +03:00
|
|
|
if (NS_OK == rv) {
|
|
|
|
nsIHTMLContentSink* sink = nsnull;
|
|
|
|
|
|
|
|
rv = NS_New_HTML_ContentSinkStream(&sink);
|
1999-03-06 23:32:48 +03:00
|
|
|
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
((nsHTMLContentSinkStream*)sink)->SetOutputStream(outStream);
|
|
|
|
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
parser->SetContentSink(sink);
|
|
|
|
|
|
|
|
nsIDTD* dtd = nsnull;
|
|
|
|
rv = NS_NewXIFDTD(&dtd);
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
parser->RegisterDTD(dtd);
|
|
|
|
parser->Parse(buffer, 0, "text/xif",PR_FALSE,PR_TRUE);
|
|
|
|
}
|
|
|
|
#ifdef XP_MAC
|
|
|
|
WriteFromStringstream(outStream, aOutputString);
|
|
|
|
#else
|
|
|
|
WriteFromOstrstream(outStream, aOutputString);
|
|
|
|
#endif
|
|
|
|
NS_IF_RELEASE(dtd);
|
|
|
|
NS_IF_RELEASE(sink);
|
|
|
|
}
|
1999-03-05 00:53:42 +03:00
|
|
|
}
|
1999-03-06 00:05:35 +03:00
|
|
|
NS_RELEASE(parser);
|
1999-03-05 00:53:42 +03:00
|
|
|
}
|
1999-03-06 23:32:48 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return rv;
|
1999-02-12 20:18:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP nsTextEditor::SetTextPropertiesForNode(nsIDOMNode *aNode,
|
1999-03-12 05:28:24 +03:00
|
|
|
nsIDOMNode *aParent,
|
1999-03-19 00:55:23 +03:00
|
|
|
PRInt32 aStartOffset,
|
|
|
|
PRInt32 aEndOffset,
|
|
|
|
nsIAtom *aPropName)
|
1999-02-24 20:24:37 +03:00
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("nsTextEditor::SetTextPropertyForNode\n"); }
|
1999-02-25 19:05:43 +03:00
|
|
|
nsresult result=NS_OK;
|
|
|
|
nsCOMPtr<nsIDOMCharacterData>nodeAsChar;
|
1999-03-03 01:27:46 +03:00
|
|
|
nodeAsChar = do_QueryInterface(aNode);
|
1999-02-25 19:05:43 +03:00
|
|
|
if (!nodeAsChar)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
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
|
|
|
PRBool textPropertySet;
|
1999-04-06 22:21:43 +04:00
|
|
|
nsCOMPtr<nsIDOMNode>resultNode;
|
|
|
|
IsTextPropertySetByContent(aNode, aPropName, textPropertySet, getter_AddRefs(resultNode));
|
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 (PR_FALSE==textPropertySet)
|
1999-02-25 19:05:43 +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
|
|
|
PRUint32 count;
|
|
|
|
nodeAsChar->GetLength(&count);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMNode>newTextNode; // this will be the text node we move into the new style node
|
|
|
|
if (aStartOffset!=0)
|
1999-02-25 19:05:43 +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
|
|
|
result = nsEditor::SplitNode(aNode, aStartOffset, getter_AddRefs(newTextNode));
|
1999-02-25 19:05:43 +03:00
|
|
|
}
|
1999-02-24 20:24:37 +03:00
|
|
|
if (NS_SUCCEEDED(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
|
|
|
if (aEndOffset!=(PRInt32)count)
|
|
|
|
{
|
|
|
|
result = nsEditor::SplitNode(aNode, aEndOffset-aStartOffset, getter_AddRefs(newTextNode));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
newTextNode = do_QueryInterface(aNode);
|
|
|
|
}
|
1999-02-25 19:05:43 +03:00
|
|
|
if (NS_SUCCEEDED(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
|
|
|
nsAutoString tag;
|
|
|
|
aPropName->ToString(tag);
|
1999-02-25 19:05:43 +03:00
|
|
|
PRInt32 offsetInParent;
|
|
|
|
result = nsIEditorSupport::GetChildOffset(aNode, aParent, offsetInParent);
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode>newStyleNode;
|
1999-03-11 01:41:18 +03:00
|
|
|
result = nsEditor::CreateNode(tag, aParent, offsetInParent, getter_AddRefs(newStyleNode));
|
1999-02-25 19:05:43 +03:00
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
1999-03-11 01:41:18 +03:00
|
|
|
result = nsEditor::DeleteNode(newTextNode);
|
1999-02-25 19:05:43 +03:00
|
|
|
if (NS_SUCCEEDED(result)) {
|
1999-03-11 01:41:18 +03:00
|
|
|
result = nsEditor::InsertNode(newTextNode, newStyleNode, 0);
|
1999-04-12 02:55:40 +04:00
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{ // set the selection
|
1999-04-08 05:30:05 +04:00
|
|
|
nsCOMPtr<nsIDOMSelection>selection;
|
|
|
|
result = nsEditor::GetSelection(getter_AddRefs(selection));
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
selection->Collapse(newTextNode, 0);
|
|
|
|
PRInt32 endOffset = aEndOffset-aStartOffset;
|
|
|
|
selection->Extend(newTextNode, endOffset);
|
|
|
|
}
|
|
|
|
}
|
1999-02-25 19:05:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-02-24 20:24:37 +03:00
|
|
|
}
|
1999-02-25 19:05:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-04-12 02:55:40 +04:00
|
|
|
// content-based inline vs. block query
|
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 nsTextEditor::IsNodeInline(nsIDOMNode *aNode, PRBool &aIsInline) const
|
|
|
|
{
|
|
|
|
// this is a content-based implementation
|
|
|
|
if (!aNode) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
|
|
|
|
nsresult result;
|
|
|
|
aIsInline = PR_FALSE;
|
|
|
|
nsCOMPtr<nsIDOMElement>element;
|
|
|
|
element = do_QueryInterface(aNode);
|
|
|
|
if (element)
|
|
|
|
{
|
|
|
|
nsAutoString tag;
|
|
|
|
result = element->GetTagName(tag);
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
nsIAtom *tagAtom = NS_NewAtom(tag);
|
|
|
|
if (!tagAtom) { return NS_ERROR_NULL_POINTER; }
|
1999-04-05 00:10:39 +04:00
|
|
|
if (tagAtom==nsIEditProperty::a ||
|
|
|
|
tagAtom==nsIEditProperty::b ||
|
|
|
|
tagAtom==nsIEditProperty::big ||
|
|
|
|
tagAtom==nsIEditProperty::font ||
|
|
|
|
tagAtom==nsIEditProperty::i ||
|
|
|
|
tagAtom==nsIEditProperty::span ||
|
|
|
|
tagAtom==nsIEditProperty::small ||
|
|
|
|
tagAtom==nsIEditProperty::strike ||
|
|
|
|
tagAtom==nsIEditProperty::sub ||
|
|
|
|
tagAtom==nsIEditProperty::sup ||
|
|
|
|
tagAtom==nsIEditProperty::tt ||
|
|
|
|
tagAtom==nsIEditProperty::u )
|
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
|
|
|
{
|
|
|
|
aIsInline = PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditor::IntermediateNodesAreInline(nsIDOMRange *aRange,
|
|
|
|
nsIDOMNode *aStartNode,
|
|
|
|
PRInt32 aStartOffset,
|
|
|
|
nsIDOMNode *aEndNode,
|
|
|
|
PRInt32 aEndOffset,
|
|
|
|
nsIDOMNode *aParent,
|
|
|
|
PRBool &aResult) const
|
|
|
|
{
|
|
|
|
aResult = PR_TRUE; // init out param. we assume the condition is true unless we find a node that violates it
|
|
|
|
if (!aStartNode || !aEndNode || !aParent) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
|
|
|
|
nsCOMPtr<nsIContentIterator>iter;
|
|
|
|
nsresult result;
|
|
|
|
result = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull,
|
|
|
|
kIContentIteratorIID, getter_AddRefs(iter));
|
|
|
|
//XXX: maybe CreateInstance is expensive, and I should keep around a static iter?
|
|
|
|
// as long as this method can't be called recursively or re-entrantly!
|
|
|
|
|
|
|
|
if ((NS_SUCCEEDED(result)) && iter)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIContent>startContent;
|
|
|
|
startContent = do_QueryInterface(aStartNode);
|
|
|
|
nsCOMPtr<nsIContent>endContent;
|
|
|
|
endContent = do_QueryInterface(aEndNode);
|
|
|
|
if (startContent && endContent)
|
|
|
|
{
|
|
|
|
iter->Init(aRange);
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
iter->CurrentNode(getter_AddRefs(content));
|
|
|
|
while (NS_COMFALSE == iter->IsDone())
|
|
|
|
{
|
|
|
|
if ((content.get() != startContent.get()) &&
|
|
|
|
(content.get() != endContent.get()))
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode>currentNode;
|
|
|
|
currentNode = do_QueryInterface(content);
|
|
|
|
PRBool isInline=PR_FALSE;
|
|
|
|
IsNodeInline(currentNode, isInline);
|
|
|
|
if (PR_FALSE==isInline)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMCharacterData>nodeAsText;
|
|
|
|
nodeAsText = do_QueryInterface(currentNode);
|
|
|
|
if (!nodeAsText) // text nodes don't count in this check, so ignore them
|
|
|
|
{
|
|
|
|
aResult = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* do not check result here, and especially do not return the result code.
|
|
|
|
* we rely on iter->IsDone to tell us when the iteration is complete
|
|
|
|
*/
|
|
|
|
iter->Next();
|
|
|
|
iter->CurrentNode(getter_AddRefs(content));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* this should only get called if the only intervening nodes are inline style nodes */
|
1999-03-02 08:30:53 +03:00
|
|
|
NS_IMETHODIMP
|
1999-02-25 19:05:43 +03:00
|
|
|
nsTextEditor::SetTextPropertiesForNodesWithSameParent(nsIDOMNode *aStartNode,
|
|
|
|
PRInt32 aStartOffset,
|
|
|
|
nsIDOMNode *aEndNode,
|
|
|
|
PRInt32 aEndOffset,
|
|
|
|
nsIDOMNode *aParent,
|
|
|
|
nsIAtom *aPropName)
|
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("nsTextEditor::SetTextPropertiesForNodesWithSameParent\n"); }
|
1999-02-25 19:05:43 +03:00
|
|
|
nsresult result=NS_OK;
|
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
|
|
|
PRBool textPropertySet;
|
1999-04-06 22:21:43 +04:00
|
|
|
nsCOMPtr<nsIDOMNode>resultNode;
|
|
|
|
IsTextPropertySetByContent(aStartNode, aPropName, textPropertySet, getter_AddRefs(resultNode));
|
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 (PR_FALSE==textPropertySet)
|
1999-02-25 19:05:43 +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
|
|
|
nsCOMPtr<nsIDOMNode>newLeftTextNode; // this will be the middle text node
|
|
|
|
if (0!=aStartOffset) {
|
|
|
|
result = nsEditor::SplitNode(aStartNode, aStartOffset, getter_AddRefs(newLeftTextNode));
|
1999-02-25 19:05:43 +03:00
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(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
|
|
|
nsCOMPtr<nsIDOMCharacterData>endNodeAsChar;
|
|
|
|
endNodeAsChar = do_QueryInterface(aEndNode);
|
|
|
|
if (!endNodeAsChar)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
PRUint32 count;
|
|
|
|
endNodeAsChar->GetLength(&count);
|
|
|
|
nsCOMPtr<nsIDOMNode>newRightTextNode; // this will be the middle text node
|
|
|
|
if ((PRInt32)count!=aEndOffset) {
|
|
|
|
result = nsEditor::SplitNode(aEndNode, aEndOffset, getter_AddRefs(newRightTextNode));
|
1999-02-25 19:05:43 +03:00
|
|
|
}
|
|
|
|
else {
|
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
|
|
|
newRightTextNode = do_QueryInterface(aEndNode);
|
1999-02-25 19:05:43 +03:00
|
|
|
}
|
1999-02-24 20:24:37 +03:00
|
|
|
if (NS_SUCCEEDED(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
|
|
|
PRInt32 offsetInParent;
|
|
|
|
if (newLeftTextNode) {
|
|
|
|
result = nsIEditorSupport::GetChildOffset(newLeftTextNode, aParent, offsetInParent);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
offsetInParent = -1; // relies on +1 below in call to CreateNode
|
|
|
|
}
|
1999-02-24 20:24:37 +03:00
|
|
|
if (NS_SUCCEEDED(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
|
|
|
{
|
|
|
|
nsAutoString tag;
|
|
|
|
aPropName->ToString(tag);
|
|
|
|
// create the new style node, which will be the new parent for the selected nodes
|
1999-02-25 19:05:43 +03:00
|
|
|
nsCOMPtr<nsIDOMNode>newStyleNode;
|
1999-03-11 01:41:18 +03:00
|
|
|
result = nsEditor::CreateNode(tag, aParent, offsetInParent+1, getter_AddRefs(newStyleNode));
|
1999-02-25 19:05:43 +03:00
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{ // move the right half of the start node into the new style node
|
|
|
|
nsCOMPtr<nsIDOMNode>intermediateNode;
|
|
|
|
result = aStartNode->GetNextSibling(getter_AddRefs(intermediateNode));
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
1999-03-11 01:41:18 +03:00
|
|
|
result = nsEditor::DeleteNode(aStartNode);
|
1999-02-25 19:05:43 +03:00
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
PRInt32 childIndex=0;
|
1999-03-11 01:41:18 +03:00
|
|
|
result = nsEditor::InsertNode(aStartNode, newStyleNode, childIndex);
|
1999-02-25 19:05:43 +03:00
|
|
|
childIndex++;
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{ // move all the intermediate nodes into the new style node
|
|
|
|
nsCOMPtr<nsIDOMNode>nextSibling;
|
|
|
|
while (intermediateNode.get() != aEndNode)
|
|
|
|
{
|
|
|
|
if (!intermediateNode)
|
|
|
|
result = NS_ERROR_NULL_POINTER;
|
|
|
|
if (NS_FAILED(result)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// get the next sibling before moving the current child!!!
|
|
|
|
intermediateNode->GetNextSibling(getter_AddRefs(nextSibling));
|
1999-03-11 01:41:18 +03:00
|
|
|
result = nsEditor::DeleteNode(intermediateNode);
|
1999-02-25 19:05:43 +03:00
|
|
|
if (NS_SUCCEEDED(result)) {
|
1999-03-11 01:41:18 +03:00
|
|
|
result = nsEditor::InsertNode(intermediateNode, newStyleNode, childIndex);
|
1999-02-25 19:05:43 +03:00
|
|
|
childIndex++;
|
|
|
|
}
|
|
|
|
intermediateNode = do_QueryInterface(nextSibling);
|
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{ // move the left half of the end node into the new style node
|
1999-03-11 01:41:18 +03:00
|
|
|
result = nsEditor::DeleteNode(newRightTextNode);
|
1999-02-25 19:05:43 +03:00
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
1999-03-11 01:41:18 +03:00
|
|
|
result = nsEditor::InsertNode(newRightTextNode, newStyleNode, childIndex);
|
1999-02-25 19:05:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-02-24 20:24:37 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
1999-02-25 19:05:43 +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
|
|
|
/* this wraps every selected text node in a new inline style node if needed
|
|
|
|
the text nodes are treated as being unique -- each needs it's own style node
|
|
|
|
if the style is not already present.
|
|
|
|
each action has immediate effect on the content tree and resolved style, so
|
|
|
|
doing outermost text nodes first removes the need for interior style nodes in some cases.
|
|
|
|
XXX: need to code test to see if new style node is needed
|
|
|
|
*/
|
1999-03-02 10:52:41 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditor::SetTextPropertiesForNodeWithDifferentParents(nsIDOMRange *aRange,
|
|
|
|
nsIDOMNode *aStartNode,
|
|
|
|
PRInt32 aStartOffset,
|
|
|
|
nsIDOMNode *aEndNode,
|
|
|
|
PRInt32 aEndOffset,
|
|
|
|
nsIDOMNode *aParent,
|
|
|
|
nsIAtom *aPropName)
|
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("nsTextEditor::SetTextPropertiesForNodeWithDifferentParents\n"); }
|
1999-03-02 10:52:41 +03:00
|
|
|
nsresult result=NS_OK;
|
|
|
|
if (!aRange || !aStartNode || !aEndNode || !aParent || !aPropName)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
// create a style node for the text in the start parent
|
|
|
|
nsCOMPtr<nsIDOMNode>parent;
|
|
|
|
result = aStartNode->GetParentNode(getter_AddRefs(parent));
|
|
|
|
if (NS_FAILED(result)) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// create style nodes for all the content between the start and end nodes
|
|
|
|
nsCOMPtr<nsIContentIterator>iter;
|
1999-03-09 12:44:27 +03:00
|
|
|
result = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull,
|
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
|
|
|
kIContentIteratorIID, getter_AddRefs(iter));
|
1999-03-02 10:52:41 +03:00
|
|
|
if ((NS_SUCCEEDED(result)) && iter)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIContent>startContent;
|
|
|
|
startContent = do_QueryInterface(aStartNode);
|
|
|
|
nsCOMPtr<nsIContent>endContent;
|
|
|
|
endContent = do_QueryInterface(aEndNode);
|
|
|
|
if (startContent && endContent)
|
|
|
|
{
|
|
|
|
iter->Init(aRange);
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
iter->CurrentNode(getter_AddRefs(content));
|
|
|
|
nsAutoString tag;
|
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
|
|
|
aPropName->ToString(tag);
|
1999-03-02 10:52:41 +03:00
|
|
|
while (NS_COMFALSE == iter->IsDone())
|
|
|
|
{
|
|
|
|
if ((content.get() != startContent.get()) &&
|
|
|
|
(content.get() != endContent.get()))
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMCharacterData>charNode;
|
|
|
|
charNode = do_QueryInterface(content);
|
|
|
|
if (charNode)
|
|
|
|
{
|
|
|
|
// only want to wrap the text node in a new style node if it doesn't already have that style
|
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<nsIDOMNode>node;
|
|
|
|
node = do_QueryInterface(content);
|
|
|
|
PRBool textPropertySet;
|
1999-04-06 22:21:43 +04:00
|
|
|
nsCOMPtr<nsIDOMNode>resultNode;
|
|
|
|
IsTextPropertySetByContent(node, aPropName, textPropertySet, getter_AddRefs(resultNode));
|
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 (PR_FALSE==textPropertySet)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode>parent;
|
|
|
|
charNode->GetParentNode(getter_AddRefs(parent));
|
|
|
|
if (!parent) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIContent>parentContent;
|
|
|
|
parentContent = do_QueryInterface(parent);
|
1999-03-02 10:52:41 +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
|
|
|
PRInt32 offsetInParent;
|
|
|
|
parentContent->IndexOf(content, offsetInParent);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMNode>newStyleNode;
|
|
|
|
result = nsEditor::CreateNode(tag, parent, offsetInParent, getter_AddRefs(newStyleNode));
|
|
|
|
if (NS_SUCCEEDED(result) && newStyleNode) {
|
|
|
|
nsCOMPtr<nsIDOMNode>contentNode;
|
|
|
|
contentNode = do_QueryInterface(content);
|
|
|
|
result = nsEditor::DeleteNode(contentNode);
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
result = nsEditor::InsertNode(contentNode, newStyleNode, 0);
|
|
|
|
}
|
1999-03-02 10:52:41 +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
|
|
|
// note we don't check the result, we just rely on iter->IsDone
|
1999-03-02 10:52:41 +03:00
|
|
|
iter->Next();
|
|
|
|
result = iter->CurrentNode(getter_AddRefs(content));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-04-06 00:52:29 +04:00
|
|
|
// create a style node for the text in the start parent
|
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>nodeAsChar;
|
|
|
|
nodeAsChar = do_QueryInterface(aStartNode);
|
|
|
|
if (!nodeAsChar)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
PRUint32 count;
|
|
|
|
nodeAsChar->GetLength(&count);
|
|
|
|
result = SetTextPropertiesForNode(aStartNode, parent, aStartOffset, count, aPropName);
|
|
|
|
|
|
|
|
// create a style node for the text in the end parent
|
|
|
|
result = aEndNode->GetParentNode(getter_AddRefs(parent));
|
|
|
|
if (NS_FAILED(result)) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
nodeAsChar = do_QueryInterface(aEndNode);
|
|
|
|
if (!nodeAsChar)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
nodeAsChar->GetLength(&count);
|
|
|
|
result = SetTextPropertiesForNode(aEndNode, parent, 0, aEndOffset, aPropName);
|
1999-03-02 10:52:41 +03:00
|
|
|
|
1999-02-25 19:05:43 +03:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
1999-04-04 22:01:35 +04:00
|
|
|
NS_IMETHODIMP nsTextEditor::RemoveTextPropertiesForNode(nsIDOMNode *aNode,
|
|
|
|
nsIDOMNode *aParent,
|
|
|
|
PRInt32 aStartOffset,
|
|
|
|
PRInt32 aEndOffset,
|
|
|
|
nsIAtom *aPropName)
|
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("nsTextEditor::RemoveTextPropertyForNode\n"); }
|
1999-04-04 22:01:35 +04:00
|
|
|
nsresult result=NS_OK;
|
|
|
|
nsCOMPtr<nsIDOMCharacterData>nodeAsChar;
|
|
|
|
nodeAsChar = do_QueryInterface(aNode);
|
|
|
|
PRBool textPropertySet;
|
1999-04-06 22:21:43 +04:00
|
|
|
nsCOMPtr<nsIDOMNode>resultNode;
|
|
|
|
IsTextPropertySetByContent(aNode, aPropName, textPropertySet, getter_AddRefs(resultNode));
|
1999-04-04 22:01:35 +04:00
|
|
|
if (PR_TRUE==textPropertySet)
|
|
|
|
{
|
1999-04-06 00:52:29 +04:00
|
|
|
nsCOMPtr<nsIDOMNode>parent; // initially set to first interior parent node to process
|
|
|
|
nsCOMPtr<nsIDOMNode>newMiddleNode; // this will be the middle node after any required splits
|
|
|
|
nsCOMPtr<nsIDOMNode>newLeftNode; // this will be the leftmost node,
|
|
|
|
// the node being split will be rightmost
|
1999-04-04 22:01:35 +04:00
|
|
|
PRUint32 count;
|
1999-04-06 00:52:29 +04:00
|
|
|
// if aNode is a text node, treat is specially
|
|
|
|
if (nodeAsChar)
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-06 00:52:29 +04:00
|
|
|
nodeAsChar->GetLength(&count);
|
|
|
|
// split the node, and all parent nodes up to the style node
|
|
|
|
// then promote the selected content to the parent of the style node
|
|
|
|
if (0!=aStartOffset) {
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("* splitting text node %p at %d\n", aNode, aStartOffset);}
|
1999-04-06 00:52:29 +04:00
|
|
|
result = nsEditor::SplitNode(aNode, aStartOffset, getter_AddRefs(newLeftNode));
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("* split created left node %p\n", newLeftNode.get());}
|
1999-04-04 22:01:35 +04:00
|
|
|
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
|
|
|
}
|
1999-04-06 00:52:29 +04:00
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
if ((PRInt32)count!=aEndOffset) {
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("* splitting text node (right node) %p at %d\n", aNode, aEndOffset-aStartOffset);}
|
1999-04-06 00:52:29 +04:00
|
|
|
result = nsEditor::SplitNode(aNode, aEndOffset-aStartOffset, getter_AddRefs(newMiddleNode));
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("* split created middle node %p\n", newMiddleNode.get());}
|
1999-04-06 00:52:29 +04:00
|
|
|
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
|
|
|
}
|
|
|
|
else {
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("* no need to split text node, middle to aNode\n");}
|
1999-04-06 00:52:29 +04:00
|
|
|
newMiddleNode = do_QueryInterface(aNode);
|
|
|
|
}
|
|
|
|
NS_ASSERTION(newMiddleNode, "no middle node created");
|
|
|
|
// now that the text node is split, split parent nodes until we get to the style node
|
|
|
|
parent = do_QueryInterface(aParent); // we know this has to succeed, no need to check
|
1999-04-04 22:01:35 +04:00
|
|
|
}
|
1999-04-06 00:52:29 +04:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
newMiddleNode = do_QueryInterface(aNode);
|
|
|
|
parent = do_QueryInterface(aParent);
|
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(result) && newMiddleNode)
|
|
|
|
{
|
|
|
|
// split every ancestor until we find the node that is giving us the style we want to remove
|
|
|
|
// then split the style node and promote the selected content to the style node's parent
|
|
|
|
while (NS_SUCCEEDED(result) && parent)
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("* looking at parent %p\n", parent);}
|
1999-04-06 00:52:29 +04:00
|
|
|
// get the tag from parent and see if we're done
|
|
|
|
nsCOMPtr<nsIDOMNode>temp;
|
|
|
|
nsCOMPtr<nsIDOMElement>element;
|
|
|
|
element = do_QueryInterface(parent);
|
|
|
|
if (element)
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-06 00:52:29 +04:00
|
|
|
nsAutoString tag;
|
|
|
|
result = element->GetTagName(tag);
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("* parent has tag %s\n", tag.ToNewCString()); } // XXX leak!
|
1999-04-06 00:52:29 +04:00
|
|
|
if (NS_SUCCEEDED(result))
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-06 00:52:29 +04:00
|
|
|
if (PR_FALSE==tag.Equals(aPropName))
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-06 00:52:29 +04:00
|
|
|
PRInt32 offsetInParent;
|
|
|
|
result = nsIEditorSupport::GetChildOffset(newMiddleNode, parent, offsetInParent);
|
|
|
|
if (NS_SUCCEEDED(result))
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-06 00:52:29 +04:00
|
|
|
if (0!=offsetInParent) {
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("* splitting parent %p at offset %d\n", parent, offsetInParent);}
|
1999-04-06 00:52:29 +04:00
|
|
|
result = nsEditor::SplitNode(parent, offsetInParent, getter_AddRefs(newLeftNode));
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("* split created left node %p sibling of parent\n", newLeftNode.get());}
|
1999-04-06 00:52:29 +04:00
|
|
|
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
|
|
|
}
|
1999-04-04 22:01:35 +04:00
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
1999-04-06 00:52:29 +04:00
|
|
|
nsCOMPtr<nsIDOMNodeList>childNodes;
|
|
|
|
result = parent->GetChildNodes(getter_AddRefs(childNodes));
|
|
|
|
if (NS_SUCCEEDED(result) && childNodes)
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-06 00:52:29 +04:00
|
|
|
childNodes->GetLength(&count);
|
|
|
|
NS_ASSERTION(count>0, "bad child count in newly split node");
|
|
|
|
if ((PRInt32)count!=1)
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("* splitting parent %p at offset %d\n", parent, 1);}
|
1999-04-06 00:52:29 +04:00
|
|
|
result = nsEditor::SplitNode(parent, 1, getter_AddRefs(newMiddleNode));
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("* split created middle node %p sibling of parent\n", newMiddleNode.get());}
|
1999-04-06 00:52:29 +04:00
|
|
|
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
1999-04-04 22:01:35 +04:00
|
|
|
}
|
1999-04-06 00:52:29 +04:00
|
|
|
else {
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("* no need to split parent, newMiddleNode=parent\n");}
|
1999-04-06 00:52:29 +04:00
|
|
|
newMiddleNode = do_QueryInterface(parent);
|
|
|
|
}
|
|
|
|
NS_ASSERTION(newMiddleNode, "no middle node created");
|
|
|
|
parent->GetParentNode(getter_AddRefs(temp));
|
|
|
|
parent = do_QueryInterface(temp);
|
1999-04-04 22:01:35 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-04-06 00:52:29 +04:00
|
|
|
}
|
|
|
|
// else we've found the style tag (referred to by "parent")
|
|
|
|
// nwMiddleNode is the node that is an ancestor to the selection
|
|
|
|
else
|
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("* this is the style node\n");}
|
1999-04-06 00:52:29 +04:00
|
|
|
PRInt32 offsetInParent;
|
|
|
|
result = nsIEditorSupport::GetChildOffset(newMiddleNode, parent, offsetInParent);
|
|
|
|
if (NS_SUCCEEDED(result))
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-06 00:52:29 +04:00
|
|
|
nsCOMPtr<nsIDOMNodeList>childNodes;
|
|
|
|
result = parent->GetChildNodes(getter_AddRefs(childNodes));
|
|
|
|
if (NS_SUCCEEDED(result) && childNodes)
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-06 00:52:29 +04:00
|
|
|
childNodes->GetLength(&count);
|
1999-04-12 02:55:40 +04:00
|
|
|
// if there are siblings to the right, split parent at offsetInParent+1
|
|
|
|
if ((PRInt32)count!=offsetInParent+1)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode>newRightNode;
|
|
|
|
nsCOMPtr<nsIDOMNode>temp;
|
|
|
|
if (gNoisy) { printf("* splitting parent %p at offset %d for right side\n", parent, offsetInParent+1);}
|
|
|
|
result = nsEditor::SplitNode(parent, offsetInParent+1, getter_AddRefs(temp));
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
newRightNode = do_QueryInterface(parent);
|
|
|
|
parent = do_QueryInterface(temp);
|
|
|
|
if (gNoisy) { printf("* split created right node %p sibling of parent %p\n", newRightNode.get(), parent.get());}
|
|
|
|
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(result) && 0!=offsetInParent) {
|
|
|
|
if (gNoisy) { printf("* splitting parent %p at offset %d for left side\n", parent, offsetInParent);}
|
1999-04-06 00:52:29 +04:00
|
|
|
result = nsEditor::SplitNode(parent, offsetInParent, getter_AddRefs(newLeftNode));
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("* split created left node %p sibling of parent %p\n", newLeftNode.get(), parent.get());}
|
1999-04-06 00:52:29 +04:00
|
|
|
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{ // promote the selection to the grandparent
|
1999-04-12 02:55:40 +04:00
|
|
|
// first, determine the child's position in it's parent
|
|
|
|
PRInt32 childPositionInParent;
|
|
|
|
nsIEditorSupport::GetChildOffset(newMiddleNode, parent, childPositionInParent);
|
|
|
|
// compare childPositionInParent to the number of children in parent
|
|
|
|
PRUint32 count=0;
|
|
|
|
nsCOMPtr<nsIDOMNodeList>childNodes;
|
|
|
|
result = parent->GetChildNodes(getter_AddRefs(childNodes));
|
|
|
|
if (NS_SUCCEEDED(result) && childNodes) {
|
|
|
|
childNodes->GetLength(&count);
|
|
|
|
}
|
|
|
|
PRBool insertAfter = PR_FALSE;
|
|
|
|
// if they're equal, we'll insert newMiddleNode in grandParent after the parent
|
|
|
|
if ((PRInt32)count==childPositionInParent) {
|
|
|
|
insertAfter = PR_TRUE;
|
|
|
|
}
|
|
|
|
// now that we know where to put newMiddleNode, do it.
|
1999-04-06 00:52:29 +04:00
|
|
|
nsCOMPtr<nsIDOMNode>grandParent;
|
|
|
|
result = parent->GetParentNode(getter_AddRefs(grandParent));
|
|
|
|
if (NS_SUCCEEDED(result) && grandParent)
|
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("* deleting middle node %p\n", newMiddleNode.get());}
|
1999-04-06 00:52:29 +04:00
|
|
|
result = nsEditor::DeleteNode(newMiddleNode);
|
1999-04-04 22:01:35 +04:00
|
|
|
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
1999-04-06 00:52:29 +04:00
|
|
|
if (NS_SUCCEEDED(result))
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-06 00:52:29 +04:00
|
|
|
PRInt32 position;
|
|
|
|
result = nsIEditorSupport::GetChildOffset(parent, grandParent, position);
|
|
|
|
if (NS_SUCCEEDED(result))
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-06 00:52:29 +04:00
|
|
|
if (PR_TRUE==insertAfter)
|
|
|
|
{
|
|
|
|
if (gNoisy) {printf("insertAfter=PR_TRUE, incr. position\n"); }
|
|
|
|
position++;
|
|
|
|
}
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) {
|
|
|
|
printf("* inserting node %p in grandparent %p at offset %d\n",
|
|
|
|
newMiddleNode.get(), grandParent.get(), position);
|
|
|
|
}
|
1999-04-06 00:52:29 +04:00
|
|
|
result = nsEditor::InsertNode(newMiddleNode, grandParent, position);
|
|
|
|
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
1999-04-04 22:01:35 +04:00
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
1999-04-06 00:52:29 +04:00
|
|
|
PRBool hasChildren=PR_TRUE;
|
|
|
|
parent->HasChildNodes(&hasChildren);
|
|
|
|
if (PR_FALSE==hasChildren) {
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("* deleting empty style node %p\n", parent.get());}
|
1999-04-06 00:52:29 +04:00
|
|
|
result = nsEditor::DeleteNode(parent);
|
|
|
|
if (gNoisy) {DebugDumpContent(); } // DEBUG
|
1999-04-04 22:01:35 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-04-06 00:52:29 +04:00
|
|
|
break;
|
1999-04-04 22:01:35 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* this should only get called if the only intervening nodes are inline style nodes */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditor::RemoveTextPropertiesForNodesWithSameParent(nsIDOMNode *aStartNode,
|
|
|
|
PRInt32 aStartOffset,
|
|
|
|
nsIDOMNode *aEndNode,
|
|
|
|
PRInt32 aEndOffset,
|
|
|
|
nsIDOMNode *aParent,
|
|
|
|
nsIAtom *aPropName)
|
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("nsTextEditor::RemoveTextPropertiesForNodesWithSameParent\n"); }
|
1999-04-04 22:01:35 +04:00
|
|
|
nsresult result=NS_OK;
|
1999-04-06 00:52:29 +04:00
|
|
|
PRInt32 startOffset = aStartOffset;
|
|
|
|
PRInt32 endOffset;
|
|
|
|
nsCOMPtr<nsIDOMCharacterData>nodeAsChar;
|
|
|
|
nsCOMPtr<nsIDOMNode>parentNode = do_QueryInterface(aParent);
|
|
|
|
|
|
|
|
// remove aPropName from all intermediate nodes
|
|
|
|
nsCOMPtr<nsIDOMNode>siblingNode;
|
|
|
|
nsCOMPtr<nsIDOMNode>nextSiblingNode; // temp to hold the next node in the list
|
|
|
|
result = aStartNode->GetNextSibling(getter_AddRefs(siblingNode));
|
|
|
|
while (siblingNode && NS_SUCCEEDED(result))
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-06 00:52:29 +04:00
|
|
|
// get next sibling right away, before we move siblingNode!
|
|
|
|
siblingNode->GetNextSibling(getter_AddRefs(nextSiblingNode));
|
|
|
|
if (aEndNode==siblingNode.get()) { // found the end node, handle that below
|
|
|
|
break;
|
1999-04-04 22:01:35 +04:00
|
|
|
}
|
1999-04-06 00:52:29 +04:00
|
|
|
else
|
1999-04-06 22:21:43 +04:00
|
|
|
{ // found a sibling node between aStartNode and aEndNode, remove the style node
|
1999-04-06 00:52:29 +04:00
|
|
|
PRUint32 childCount=0;
|
|
|
|
nodeAsChar = do_QueryInterface(siblingNode);
|
|
|
|
if (nodeAsChar) {
|
|
|
|
nodeAsChar->GetLength(&childCount);
|
1999-04-04 22:01:35 +04:00
|
|
|
}
|
1999-04-06 00:52:29 +04:00
|
|
|
else
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-06 00:52:29 +04:00
|
|
|
nsCOMPtr<nsIDOMNodeList>grandChildNodes;
|
|
|
|
result = siblingNode->GetChildNodes(getter_AddRefs(grandChildNodes));
|
|
|
|
if (NS_SUCCEEDED(result) && grandChildNodes) {
|
|
|
|
grandChildNodes->GetLength(&childCount);
|
1999-04-04 22:01:35 +04:00
|
|
|
}
|
1999-04-06 00:52:29 +04:00
|
|
|
if (0==childCount)
|
|
|
|
{ // node has no children
|
|
|
|
// XXX: for now, I think that's ok. just pass in 0
|
1999-04-04 22:01:35 +04:00
|
|
|
}
|
|
|
|
}
|
1999-04-06 00:52:29 +04:00
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
siblingNode->GetParentNode(getter_AddRefs(parentNode));
|
|
|
|
result = RemoveTextPropertiesForNode(siblingNode, parentNode, 0, childCount, aPropName);
|
|
|
|
}
|
|
|
|
}
|
1999-04-06 22:21:43 +04:00
|
|
|
siblingNode = do_QueryInterface(nextSiblingNode);
|
1999-04-06 00:52:29 +04:00
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
// remove aPropName from aStartNode
|
|
|
|
nsCOMPtr<nsIDOMCharacterData>nodeAsChar;
|
|
|
|
nodeAsChar = do_QueryInterface(aStartNode);
|
|
|
|
if (nodeAsChar) {
|
|
|
|
nodeAsChar->GetLength((PRUint32 *)&endOffset);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("not yet supported\n");}
|
1999-04-06 00:52:29 +04:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
result = aStartNode->GetParentNode(getter_AddRefs(parentNode));
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
result = RemoveTextPropertiesForNode(aStartNode, parentNode, startOffset, endOffset, aPropName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
// remove aPropName from the end node
|
|
|
|
startOffset = 0;
|
|
|
|
endOffset = aEndOffset;
|
|
|
|
result = aEndNode->GetParentNode(getter_AddRefs(parentNode));
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
result = RemoveTextPropertiesForNode(aEndNode, parentNode, startOffset, endOffset, aPropName);
|
1999-04-04 22:01:35 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsTextEditor::RemoveTextPropertiesForNodeWithDifferentParents(nsIDOMRange *aRange,
|
|
|
|
nsIDOMNode *aStartNode,
|
|
|
|
PRInt32 aStartOffset,
|
|
|
|
nsIDOMNode *aEndNode,
|
|
|
|
PRInt32 aEndOffset,
|
|
|
|
nsIDOMNode *aParent,
|
|
|
|
nsIAtom *aPropName)
|
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
if (gNoisy) { printf("nsTextEditor::RemoveTextPropertiesForNodeWithDifferentParents\n"); }
|
1999-04-04 22:01:35 +04:00
|
|
|
nsresult result=NS_OK;
|
|
|
|
if (!aRange || !aStartNode || !aEndNode || !aParent || !aPropName)
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1999-04-06 22:21:43 +04:00
|
|
|
|
1999-04-12 02:55:40 +04:00
|
|
|
PRInt32 rangeStartOffset = aStartOffset; // used to construct a range for the nodes between
|
|
|
|
PRInt32 rangeEndOffset = aEndOffset; // aStartNode and aEndNode after we've processed those endpoints
|
|
|
|
|
1999-04-06 22:21:43 +04:00
|
|
|
// delete the style node for the text in the start parent
|
1999-04-12 02:55:40 +04:00
|
|
|
PRBool skippedStartNode = PR_FALSE;
|
1999-04-06 22:21:43 +04:00
|
|
|
nsCOMPtr<nsIDOMCharacterData>nodeAsChar;
|
|
|
|
PRUint32 count;
|
1999-04-04 22:01:35 +04:00
|
|
|
nsCOMPtr<nsIDOMNode>parent;
|
|
|
|
result = aStartNode->GetParentNode(getter_AddRefs(parent));
|
|
|
|
if (NS_FAILED(result)) {
|
|
|
|
return result;
|
|
|
|
}
|
1999-04-06 22:21:43 +04:00
|
|
|
nodeAsChar = do_QueryInterface(aStartNode);
|
|
|
|
if (!nodeAsChar) { return NS_ERROR_FAILURE; }
|
|
|
|
nodeAsChar->GetLength(&count);
|
1999-04-12 02:55:40 +04:00
|
|
|
if (aStartOffset!=count) { // only do this if at least one child is selected
|
|
|
|
result = RemoveTextPropertiesForNode(aStartNode, parent, aStartOffset, count, aPropName);
|
|
|
|
if (0!=aStartOffset) {
|
|
|
|
rangeStartOffset = 0; // we split aStartNode at aStartOffset and it is the right node now
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
skippedStartNode = PR_TRUE;
|
|
|
|
if (gNoisy) { printf("skipping start node because aStartOffset==count\n"); }
|
|
|
|
}
|
1999-04-04 22:01:35 +04:00
|
|
|
|
1999-04-06 22:21:43 +04:00
|
|
|
// delete the style node for the text in the end parent
|
|
|
|
if (NS_SUCCEEDED(result))
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-06 22:21:43 +04:00
|
|
|
result = aEndNode->GetParentNode(getter_AddRefs(parent));
|
|
|
|
if (NS_SUCCEEDED(result))
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-06 22:21:43 +04:00
|
|
|
nodeAsChar = do_QueryInterface(aEndNode);
|
|
|
|
if (!nodeAsChar) { return NS_ERROR_FAILURE; }
|
|
|
|
nodeAsChar->GetLength(&count);
|
1999-04-12 02:55:40 +04:00
|
|
|
if (aEndOffset!=0) { // only do this if at least one child is selected
|
|
|
|
result = RemoveTextPropertiesForNode(aEndNode, parent, 0, aEndOffset, aPropName);
|
|
|
|
if (0!=aEndOffset) {
|
|
|
|
rangeEndOffset = 0; // we split aEndNode at aEndOffset and it is the right node now
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else { if (gNoisy) { printf("skipping end node because aEndOffset==0\n"); } }
|
1999-04-06 22:21:43 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// remove aPropName style nodes for all the content between the start and end nodes
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
// build our own range now, because the endpoints may have shifted during shipping
|
|
|
|
nsCOMPtr<nsIDOMRange> range;
|
|
|
|
result = nsComponentManager::CreateInstance(kCRangeCID,
|
|
|
|
nsnull,
|
|
|
|
kIDOMRangeIID,
|
|
|
|
getter_AddRefs(range));
|
|
|
|
if (NS_FAILED(result)) { return result; }
|
|
|
|
if (!range) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
// compute the start node
|
|
|
|
nsCOMPtr<nsIDOMNode>startNode = do_QueryInterface(aStartNode);
|
|
|
|
if (PR_TRUE==skippedStartNode) {
|
|
|
|
nsEditor::GetNextNode(aStartNode, getter_AddRefs(startNode));
|
|
|
|
}
|
|
|
|
range->SetStart(startNode, rangeStartOffset);
|
|
|
|
range->SetEnd(aEndNode, rangeEndOffset);
|
|
|
|
if (gNoisy)
|
|
|
|
{
|
|
|
|
printf("created range [(%p,%d), (%p,%d)]\n",
|
|
|
|
aStartNode, rangeStartOffset,
|
|
|
|
aEndNode, rangeEndOffset);
|
|
|
|
}
|
|
|
|
|
1999-04-06 22:21:43 +04:00
|
|
|
nsVoidArray nodeList;
|
|
|
|
nsCOMPtr<nsIContentIterator>iter;
|
|
|
|
result = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull,
|
|
|
|
kIContentIteratorIID, getter_AddRefs(iter));
|
|
|
|
if ((NS_SUCCEEDED(result)) && iter)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIContent>startContent;
|
|
|
|
startContent = do_QueryInterface(aStartNode);
|
|
|
|
nsCOMPtr<nsIContent>endContent;
|
|
|
|
endContent = do_QueryInterface(aEndNode);
|
|
|
|
if (startContent && endContent)
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-12 02:55:40 +04:00
|
|
|
iter->Init(range);
|
1999-04-06 22:21:43 +04:00
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
iter->CurrentNode(getter_AddRefs(content));
|
|
|
|
nsAutoString propName; // the property we are removing
|
|
|
|
aPropName->ToString(propName);
|
|
|
|
while (NS_COMFALSE == iter->IsDone())
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-06 22:21:43 +04:00
|
|
|
if ((content.get() != startContent.get()) &&
|
|
|
|
(content.get() != endContent.get()))
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-06 22:21:43 +04:00
|
|
|
nsCOMPtr<nsIDOMElement>element;
|
|
|
|
element = do_QueryInterface(content);
|
|
|
|
if (element)
|
1999-04-04 22:01:35 +04:00
|
|
|
{
|
1999-04-06 22:21:43 +04:00
|
|
|
nsString tag;
|
|
|
|
element->GetTagName(tag);
|
|
|
|
if (propName.Equals(tag))
|
|
|
|
{
|
|
|
|
if (-1==nodeList.IndexOf(content.get())) {
|
|
|
|
nodeList.AppendElement((void *)(content.get()));
|
1999-04-04 22:01:35 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-04-06 22:21:43 +04:00
|
|
|
// note we don't check the result, we just rely on iter->IsDone
|
|
|
|
iter->Next();
|
|
|
|
iter->CurrentNode(getter_AddRefs(content));
|
1999-04-04 22:01:35 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-04-06 22:21:43 +04:00
|
|
|
// now delete all the style nodes we found
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
nsIContent *contentPtr;
|
|
|
|
contentPtr = (nsIContent*)(nodeList.ElementAt(0));
|
|
|
|
while (NS_SUCCEEDED(result) && contentPtr)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode>styleNode;
|
|
|
|
styleNode = do_QueryInterface(contentPtr);
|
|
|
|
// promote the children of styleNode
|
|
|
|
nsCOMPtr<nsIDOMNode>parentNode;
|
|
|
|
result = styleNode->GetParentNode(getter_AddRefs(parentNode));
|
|
|
|
if (NS_SUCCEEDED(result) && parentNode)
|
|
|
|
{
|
|
|
|
PRInt32 position;
|
|
|
|
result = nsIEditorSupport::GetChildOffset(styleNode, parentNode, position);
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIDOMNode>previousSiblingNode;
|
|
|
|
nsCOMPtr<nsIDOMNode>childNode;
|
|
|
|
result = styleNode->GetLastChild(getter_AddRefs(childNode));
|
|
|
|
while (NS_SUCCEEDED(result) && childNode)
|
|
|
|
{
|
|
|
|
childNode->GetPreviousSibling(getter_AddRefs(previousSiblingNode));
|
|
|
|
// explicitly delete of childNode from styleNode
|
|
|
|
// can't just rely on DOM semantics of InsertNode doing the delete implicitly, doesn't undo!
|
|
|
|
result = nsEditor::DeleteNode(childNode);
|
|
|
|
if (NS_SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
result = nsEditor::InsertNode(childNode, parentNode, position);
|
|
|
|
if (gNoisy)
|
|
|
|
{
|
|
|
|
printf("deleted next sibling node %p\n", childNode.get());
|
|
|
|
DebugDumpContent(); // DEBUG
|
|
|
|
}
|
|
|
|
}
|
|
|
|
childNode = do_QueryInterface(previousSiblingNode);
|
|
|
|
} // end while loop
|
|
|
|
// delete styleNode
|
|
|
|
result = nsEditor::DeleteNode(styleNode);
|
|
|
|
if (gNoisy)
|
|
|
|
{
|
|
|
|
printf("deleted style node %p\n", styleNode.get());
|
|
|
|
DebugDumpContent(); // DEBUG
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1999-04-04 22:01:35 +04:00
|
|
|
|
1999-04-06 22:21:43 +04:00
|
|
|
// get next content ptr
|
|
|
|
nodeList.RemoveElementAt(0);
|
|
|
|
contentPtr = (nsIContent*)(nodeList.ElementAt(0));
|
|
|
|
}
|
|
|
|
}
|
1999-04-04 22:01:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
nsTextEditor::SetTypeInStateForProperty(TypeInState &aTypeInState, nsIAtom *aPropName)
|
1999-02-25 19:05:43 +03:00
|
|
|
{
|
|
|
|
if (!aPropName) {
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
}
|
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 (nsIEditProperty::b==aPropName)
|
|
|
|
{
|
|
|
|
if (PR_TRUE==aTypeInState.IsSet(NS_TYPEINSTATE_BOLD))
|
|
|
|
{ // toggle currently set boldness
|
|
|
|
aTypeInState.UnSet(NS_TYPEINSTATE_BOLD);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // get the current style and set boldness to the opposite of the current state
|
|
|
|
PRBool any = PR_FALSE;
|
|
|
|
PRBool all = PR_FALSE;
|
1999-04-04 22:01:35 +04:00
|
|
|
PRBool first = PR_FALSE;
|
|
|
|
GetTextProperty(aPropName, first, any, all); // operates on current selection
|
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
|
|
|
aTypeInState.SetBold(!any);
|
|
|
|
}
|
1999-02-25 19:05:43 +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
|
|
|
else if (nsIEditProperty::i==aPropName)
|
|
|
|
{
|
|
|
|
if (PR_TRUE==aTypeInState.IsSet(NS_TYPEINSTATE_ITALIC))
|
|
|
|
{ // toggle currently set italicness
|
|
|
|
aTypeInState.UnSet(NS_TYPEINSTATE_ITALIC);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // get the current style and set boldness to the opposite of the current state
|
|
|
|
PRBool any = PR_FALSE;
|
|
|
|
PRBool all = PR_FALSE;
|
1999-04-04 22:01:35 +04:00
|
|
|
PRBool first = PR_FALSE;
|
|
|
|
GetTextProperty(aPropName, first, any, all); // operates on current selection
|
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
|
|
|
aTypeInState.SetItalic(!any);
|
|
|
|
}
|
1999-02-25 19:05:43 +03:00
|
|
|
}
|
1999-04-05 00:10:39 +04:00
|
|
|
else if (nsIEditProperty::u==aPropName)
|
|
|
|
{
|
|
|
|
if (PR_TRUE==aTypeInState.IsSet(NS_TYPEINSTATE_UNDERLINE))
|
|
|
|
{ // toggle currently set italicness
|
|
|
|
aTypeInState.UnSet(NS_TYPEINSTATE_UNDERLINE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // get the current style and set boldness to the opposite of the current state
|
|
|
|
PRBool any = PR_FALSE;
|
|
|
|
PRBool all = PR_FALSE;
|
|
|
|
PRBool first = PR_FALSE;
|
|
|
|
GetTextProperty(aPropName, first, any, all); // operates on current selection
|
|
|
|
aTypeInState.SetUnderline(!any);
|
|
|
|
}
|
|
|
|
}
|
1999-02-25 19:05:43 +03:00
|
|
|
else {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|