improved paste performance in editor (WIP) (bug 28783)

set/remove inline stlye rewrite (lots of bug #s)


git-svn-id: svn://10.0.0.236/trunk@63948 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
jfrancis%netscape.com 2000-03-24 00:26:47 +00:00
parent 6a0120def8
commit 386e43e682
24 changed files with 5500 additions and 2918 deletions

View File

@ -69,6 +69,8 @@ NS_IMETHODIMP SplitElementTxn::Do(void)
NS_ASSERTION(((NS_SUCCEEDED(result)) && (mNewLeftNode)), "could not create element.");
if (NS_FAILED(result)) return result;
if (!mNewLeftNode) return NS_ERROR_NULL_POINTER;
mEditor->MarkNodeDirty(mExistingRightNode);
if (gNoisy) { printf(" created left node = %p\n", mNewLeftNode.get()); }
// get the parent node
@ -80,9 +82,6 @@ NS_IMETHODIMP SplitElementTxn::Do(void)
result = mEditor->SplitNodeImpl(mExistingRightNode, mOffset, mNewLeftNode, mParent);
if (NS_SUCCEEDED(result) && mNewLeftNode)
{
// Insert formatting whitespace for the new node:
mEditor->InsertFormattingForNode(mExistingRightNode);
nsCOMPtr<nsIDOMSelection>selection;
mEditor->GetSelection(getter_AddRefs(selection));
if (NS_FAILED(result)) return result;

View File

@ -23,6 +23,11 @@
#ifndef nsEditRules_h__
#define nsEditRules_h__
#define NS_IEDITRULES_IID \
{ /* a6cf911b-15b3-11d2-932e-00805f8add32 */ \
0xa6cf911b, 0x15b3, 0x11d2, \
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
class nsHTMLEditor;
class nsIDOMSelection;
@ -40,20 +45,21 @@ class nsRulesInfo
int action;
};
MOZ_DECL_CTOR_COUNTER(nsEditRules);
/***************************************************************************
* Interface of editing rules.
*
*/
class nsEditRules
class nsIEditRules : public nsISupports
{
public:
nsEditRules() { MOZ_COUNT_CTOR(nsEditRules); }
virtual ~nsEditRules() { MOZ_COUNT_DTOR(nsEditRules); }
static const nsIID& GetIID() { static nsIID iid = NS_IEDITRULES_IID; return iid; }
//Interfaces for addref and release and queryinterface
//NOTE: Use NS_DECL_ISUPPORTS_INHERITED in any class inherited from nsIEditRules
NS_IMETHOD Init(nsHTMLEditor *aEditor, PRUint32 aFlags)=0;
NS_IMETHOD BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection)=0;
NS_IMETHOD AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection, PRBool aSetSelection)=0;
NS_IMETHOD AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection)=0;
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled)=0;
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult)=0;
NS_IMETHOD GetFlags(PRUint32 *aFlags)=0;

File diff suppressed because it is too large Load Diff

View File

@ -100,11 +100,41 @@ class nsSelectionState
nsresult RestoreSelection(nsIDOMSelection *aSel);
PRBool IsCollapsed();
PRBool IsEqual(nsSelectionState *aSelState);
void MakeEmpty();
PRBool IsEmpty();
// editor selection gravity routines. Note that we can't always depend on
// DOM Range gravity to do what we want to the "real" selection. For instance,
// if you move a node, that corresponds to deleting it and reinserting it.
// DOM Range gravity will promote the selection out of the node on deletion,
// which is not what you want if you know you are reinserting it.
nsresult SelAdjCreateNode(nsIDOMNode *aParent, PRInt32 aPosition);
nsresult SelAdjInsertNode(nsIDOMNode *aParent, PRInt32 aPosition);
nsresult SelAdjDeleteNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aOffset);
nsresult SelAdjSplitNode(nsIDOMNode *aOldRightNode, PRInt32 aOffset, nsIDOMNode *aNewLeftNode);
nsresult SelAdjJoinNodes(nsIDOMNode *aLeftNode,
nsIDOMNode *aRightNode,
nsIDOMNode *aParent,
PRInt32 aOffset,
PRInt32 aOldLeftNodeLength);
nsresult SelAdjInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsString &aString);
nsresult SelAdjDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength);
// the following gravity routines need will/did sandwiches, because the other gravity
// routines will be called inside of these sandwiches, but should be ignored.
nsresult WillReplaceContainer();
nsresult DidReplaceContainer(nsIDOMNode *aOriginalNode, nsIDOMNode *aNewNode);
nsresult WillRemoveContainer();
nsresult DidRemoveContainer(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aOffset, PRUint32 aNodeOrigLen);
nsresult WillInsertContainer();
nsresult DidInsertContainer();
nsresult WillMoveNode();
nsresult DidMoveNode(nsIDOMNode *aOldParent, PRInt32 aOldOffset, nsIDOMNode *aNewParent, PRInt32 aNewOffset);
nsVoidArray mArray;
PRBool mLock;
};
/** implementation of an editor object. it will be the controler/focal point
/** implementation of an editor object. it will be the controller/focal point
* for the main editor services. i.e. the GUIManager, publishing, transaction
* manager, event interfaces. the idea for the event interfaces is to have them
* delegate the actual commands to the editor independent of the XPFE implementation.
@ -237,7 +267,7 @@ public:
NS_IMETHOD InsertNoneditableTextNode(nsIDOMNode* aParent,
PRInt32 aOffset,
nsString& aStr);
NS_IMETHOD InsertFormattingForNode(nsIDOMNode* aNode);
NS_IMETHOD MarkNodeDirty(nsIDOMNode* aNode);
/* output */
@ -274,8 +304,28 @@ public:
NS_IMETHOD InsertTextImpl(const nsString& aStringToInsert);
NS_IMETHOD JoeInsertTextImpl(const nsString& aStringToInsert,
nsCOMPtr<nsIDOMNode> *aInOutNode,
PRInt32 *aInOutOffset,
nsIDOMDocument *aDoc);
NS_IMETHOD JoeInsertTextIntoTextNodeImpl(const nsString& aStringToInsert,
nsIDOMCharacterData *aTextNode,
PRInt32 aOffset);
NS_IMETHOD DeleteSelectionImpl(EDirection aAction);
/* helper routines for node/parent manipulations */
nsresult ReplaceContainer(nsIDOMNode *inNode,
nsCOMPtr<nsIDOMNode> *outNode,
const nsString &aNodeType,
const nsString *aAttribute = nsnull,
const nsString *aValue = nsnull);
nsresult RemoveContainer(nsIDOMNode *inNode);
nsresult InsertContainerAbove(nsIDOMNode *inNode,
nsCOMPtr<nsIDOMNode> *outNode,
const nsString &aNodeType,
const nsString *aAttribute = nsnull,
const nsString *aValue = nsnull);
nsresult MoveNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aOffset);
protected:
@ -423,7 +473,7 @@ public:
/** All editor operations which alter the doc should be followed
* with a call to EndOperation, naming the action and direction */
NS_IMETHOD EndOperation(PRInt32 opID, nsIEditor::EDirection aDirection, PRBool aSetSelection);
NS_IMETHOD EndOperation(PRInt32 opID, nsIEditor::EDirection aDirection);
/** return the string that represents text nodes in the content tree */
static nsresult GetTextNodeTag(nsString& aOutString);
@ -702,7 +752,8 @@ protected:
nsWeakPtr mPlaceHolderTxn; // weak reference to placeholder for begin/end batch purposes
nsIAtom *mPlaceHolderName; // name of placeholder transaction
PRInt32 mPlaceHolderBatch; // nesting count for batching
nsSelectionState *mSelState; // saved selection state for placeholder txn batching
nsSelectionState *mSelState; // saved selection state for placeholder txn batching
nsSelectionState *mSavedSel; // cached selection for nsAutoSelectionReset
PRBool mShouldTxnSetSelection; // turn off for conservative selection adjustment by txns
nsCOMPtr<nsIDOMElement> mBodyElement; // cached body node
//
@ -718,7 +769,6 @@ protected:
nsCOMPtr<nsISupportsArray> mDocStateListeners;
PRInt8 mDocDirtyState; // -1 = not initialized
nsWeakPtr mDocWeak; // weak reference to the nsIDOMDocument
nsCOMPtr<nsIDTD> mDTD;
@ -726,6 +776,7 @@ protected:
friend PRBool NSCanUnload(nsISupports* serviceMgr);
friend class nsAutoTxnsConserveSelection;
friend class nsAutoSelectionReset;
};

View File

@ -29,39 +29,28 @@
* nsAutoSelectionReset
*****************************************************************************/
nsAutoSelectionReset::nsAutoSelectionReset(nsIDOMSelection *aSel)
nsAutoSelectionReset::nsAutoSelectionReset(nsIDOMSelection *aSel, nsEditor *aEd) :
mSel(nsnull)
,mEd(nsnull)
{
mInitialized = PR_FALSE;
if (!aSel || !aEd) return; // not much we can do, bail.
if (aEd->mSavedSel) return; // we already have initted mSavedSel, so this must be nested call.
mSel = do_QueryInterface(aSel);
mEd = aEd;
if (mSel)
{
mSel->GetAnchorNode(getter_AddRefs(mStartNode));
mSel->GetAnchorOffset(&mStartOffset);
mSel->GetFocusNode(getter_AddRefs(mEndNode));
mSel->GetFocusOffset(&mEndOffset);
if (mStartNode && mEndNode)
mInitialized = PR_TRUE;
mEd->mSavedSel = new nsSelectionState();
mEd->mSavedSel->SaveSelection(mSel);
}
}
nsAutoSelectionReset::~nsAutoSelectionReset()
{
if (mSel && mInitialized)
if (mSel && mEd->mSavedSel) // mSel will be null if this was nested call
{
// make sure that mStartNode and mEndNode are still in a document
nsCOMPtr<nsIDOMDocument> docStart;
nsresult res = mStartNode->GetOwnerDocument(getter_AddRefs(docStart));
if (NS_SUCCEEDED(res) && docStart)
{
nsCOMPtr<nsIDOMDocument> docEnd;
res = mEndNode->GetOwnerDocument(getter_AddRefs(docEnd));
if (NS_SUCCEEDED(res) && (docStart == docEnd))
{
// restore original selection
mSel->Collapse(mStartNode, mStartOffset);
mSel->Extend(mEndNode, mEndOffset);
}
}
mEd->mSavedSel->RestoreSelection(mSel);
delete mEd->mSavedSel;
mEd->mSavedSel = nsnull;
}
}

View File

@ -69,18 +69,11 @@ class nsAutoSelectionReset
private:
/** ref-counted reference to the selection that we are supposed to restore */
nsCOMPtr<nsIDOMSelection> mSel;
/** PR_TRUE if this instance initialized itself correctly */
PRBool mInitialized;
nsCOMPtr<nsIDOMNode> mStartNode;
nsCOMPtr<nsIDOMNode> mEndNode;
PRInt32 mStartOffset;
PRInt32 mEndOffset;
nsEditor *mEd; // non-owning ref to nsEditor
public:
/** constructor responsible for remembering all state needed to restore aSel */
nsAutoSelectionReset(nsIDOMSelection *aSel);
nsAutoSelectionReset(nsIDOMSelection *aSel, nsEditor *aEd);
/** destructor restores mSel to its former state */
~nsAutoSelectionReset();
@ -93,16 +86,15 @@ class nsAutoRules
{
public:
nsAutoRules(nsEditor *ed, PRInt32 action, nsIEditor::EDirection aDirection, PRBool setSelection=PR_FALSE) :
mEd(ed), mAction(action), mDirection(aDirection), mSetSelection(setSelection)
nsAutoRules(nsEditor *ed, PRInt32 action, nsIEditor::EDirection aDirection) :
mEd(ed), mAction(action), mDirection(aDirection)
{if (mEd) mEd->StartOperation(mAction, mDirection);}
~nsAutoRules() {if (mEd) mEd->EndOperation(mAction, mDirection, mSetSelection);}
~nsAutoRules() {if (mEd) mEd->EndOperation(mAction, mDirection);}
protected:
nsEditor *mEd;
PRInt32 mAction;
nsIEditor::EDirection mDirection;
PRBool mSetSelection;
};

File diff suppressed because it is too large Load Diff

View File

@ -33,20 +33,42 @@ class nsISupportsArray;
class nsVoidArray;
class nsIDOMElement;
class nsHTMLEditRules : public nsTextEditRules
class nsHTMLEditRules : public nsTextEditRules, nsIEditActionListener
{
public:
NS_DECL_ISUPPORTS_INHERITED
nsHTMLEditRules();
virtual ~nsHTMLEditRules();
// nsEditRules methods
NS_IMETHOD BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection);
NS_IMETHOD AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection, PRBool aSetSelection);
// nsIEditRules methods
NS_IMETHOD Init(nsHTMLEditor *aEditor, PRUint32 aFlags);
NS_IMETHOD BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection);
NS_IMETHOD AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection);
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled);
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
// nsIEditActionListener methods
NS_IMETHOD WillCreateNode(const nsString& aTag, nsIDOMNode *aParent, PRInt32 aPosition);
NS_IMETHOD DidCreateNode(const nsString& aTag, nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition, nsresult aResult);
NS_IMETHOD WillInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition);
NS_IMETHOD DidInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition, nsresult aResult);
NS_IMETHOD WillDeleteNode(nsIDOMNode *aChild);
NS_IMETHOD DidDeleteNode(nsIDOMNode *aChild, nsresult aResult);
NS_IMETHOD WillSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset);
NS_IMETHOD DidSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset, nsIDOMNode *aNewLeftNode, nsresult aResult);
NS_IMETHOD WillJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent);
NS_IMETHOD DidJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent, nsresult aResult);
NS_IMETHOD WillInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsString &aString);
NS_IMETHOD DidInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsString &aString, nsresult aResult);
NS_IMETHOD WillDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength);
NS_IMETHOD DidDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength, nsresult aResult);
NS_IMETHOD WillDeleteSelection(nsIDOMSelection *aSelection);
NS_IMETHOD DidDeleteSelection(nsIDOMSelection *aSelection);
protected:
enum RulesEndpoint
@ -138,67 +160,19 @@ protected:
nsresult ConvertWhitespace(const nsString & inString, nsString & outString);
nsresult ConfirmSelectionInBody();
// removed from use:
#if 0
nsresult AddTrailerBR(nsIDOMNode *aNode);
nsresult CreateMozDiv(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outDiv);
#endif
// data members
protected:
nsCOMPtr<nsIEditActionListener> mListener;
nsCOMPtr<nsIDOMRange> mDocChangeRange;
// friends
friend class nsHTMLEditListener;
friend nsresult NS_NewEditListener(nsIEditActionListener **aResult,
nsHTMLEditor *htmlEditor,
nsHTMLEditRules *htmlRules);
};
class nsHTMLEditListener : public nsIEditActionListener
{
public:
nsHTMLEditListener(nsHTMLEditor *htmlEditor, nsHTMLEditRules *htmlRules);
virtual ~nsHTMLEditListener();
NS_DECL_ISUPPORTS
// nsIEditActionListener methods
NS_IMETHOD WillCreateNode(const nsString& aTag, nsIDOMNode *aParent, PRInt32 aPosition);
NS_IMETHOD DidCreateNode(const nsString& aTag, nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition, nsresult aResult);
NS_IMETHOD WillInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition);
NS_IMETHOD DidInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition, nsresult aResult);
NS_IMETHOD WillDeleteNode(nsIDOMNode *aChild);
NS_IMETHOD DidDeleteNode(nsIDOMNode *aChild, nsresult aResult);
NS_IMETHOD WillSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset);
NS_IMETHOD DidSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset, nsIDOMNode *aNewLeftNode, nsresult aResult);
NS_IMETHOD WillJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent);
NS_IMETHOD DidJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent, nsresult aResult);
NS_IMETHOD WillInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsString &aString);
NS_IMETHOD DidInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsString &aString, nsresult aResult);
NS_IMETHOD WillDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength);
NS_IMETHOD DidDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength, nsresult aResult);
NS_IMETHOD WillDeleteSelection(nsIDOMSelection *aSelection);
NS_IMETHOD DidDeleteSelection(nsIDOMSelection *aSelection);
protected:
nsresult MakeRangeFromNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMRange> *outRange);
nsresult MakeRangeFromTextOffsets(nsIDOMCharacterData *inNode,
PRInt32 inStart,
PRInt32 inEnd,
nsCOMPtr<nsIDOMRange> *outRange);
nsresult MakeCollapsedRange(nsIDOMNode *inNode, PRInt32 inOffset, nsCOMPtr<nsIDOMRange> *outRange);
PRBool IsDescendantOfBody(nsIDOMNode *inNode) ;
// data members
nsHTMLEditor *mEditor;
nsHTMLEditRules *mRules;
nsCOMPtr<nsIDOMNode> mBody;
PRUint32 mJoinOffset; // need to remember an int across willJoin/didJoin...
protected:
nsCOMPtr<nsIDOMRange> mDocChangeRange;
PRBool mListenerEnabled;
nsCOMPtr<nsIDOMRange> mUtilRange;
nsCOMPtr<nsIDOMNode> mBody;
PRUint32 mJoinOffset; // need to remember an int across willJoin/didJoin...
};
nsresult NS_NewHTMLEditRules(nsIEditRules** aInstancePtrResult);
#endif //nsHTMLEditRules_h__

File diff suppressed because it is too large Load Diff

View File

@ -246,9 +246,6 @@ public:
NS_IMETHOD GetFlags(PRUint32 *aFlags);
NS_IMETHOD SetFlags(PRUint32 aFlags);
/** Inherited from nsEditor with special cases for some html nodes **/
NS_IMETHOD InsertFormattingForNode(nsIDOMNode* aNode);
NS_IMETHOD Undo(PRUint32 aCount);
NS_IMETHOD Redo(PRUint32 aCount);
@ -276,7 +273,7 @@ public:
/** All editor operations which alter the doc should be followed
* with a call to EndOperation, naming the action and direction */
NS_IMETHOD EndOperation(PRInt32 opID, nsIEditor::EDirection aDirection, PRBool aSetSelection);
NS_IMETHOD EndOperation(PRInt32 opID, nsIEditor::EDirection aDirection);
/** returns PR_TRUE if aParent can contain a child of type aTag */
PRBool CanContainTag(nsIDOMNode* aParent, const nsString &aTag);
@ -292,7 +289,7 @@ public:
protected:
virtual void InitRules();
NS_IMETHOD InitRules();
/** install the event listeners for the editor
* used to be part of Init, but now broken out into a separate method
@ -336,6 +333,10 @@ protected:
NS_IMETHOD TabInTable(PRBool inIsShift, PRBool *outHandled);
NS_IMETHOD CreateBR(nsIDOMNode *aNode, PRInt32 aOffset,
nsCOMPtr<nsIDOMNode> *outBRNode, EDirection aSelect = eNone);
NS_IMETHOD JoeCreateBR(nsCOMPtr<nsIDOMNode> *aInOutParent,
PRInt32 *aInOutOffset,
nsCOMPtr<nsIDOMNode> *outBRNode,
EDirection aSelect);
NS_IMETHOD InsertBR(nsCOMPtr<nsIDOMNode> *outBRNode);
// Table Editing (implemented in nsTableEditor.cpp)
@ -582,17 +583,59 @@ protected:
nsresult RelativeFontChangeOnNode( PRInt32 aSizeChange,
nsIDOMNode *aNode);
/* helper routines for node/parent manipulations */
nsresult ReplaceContainer(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode, const nsString &aNodeType);
nsresult RemoveContainer(nsIDOMNode *inNode);
nsresult InsertContainerAbove(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode, const nsString &aNodeType);
/* helper routines for inline style */
nsresult SetInlinePropertyOnTextNode( nsIDOMCharacterData *aTextNode,
PRInt32 aStartOffset,
PRInt32 aEndOffset,
nsIAtom *aProperty,
const nsString *aAttribute,
const nsString *aValue);
nsresult SetInlinePropertyOnNode( nsIDOMNode *aNode,
nsIAtom *aProperty,
const nsString *aAttribute,
const nsString *aValue);
nsresult PromoteInlineRange(nsIDOMRange *inRange);
nsresult SplitStyleAboveRange(nsIDOMRange *aRange,
nsIAtom *aProperty,
const nsString *aAttribute);
nsresult SplitStyleAbovePoint(nsCOMPtr<nsIDOMNode> *aNode,
PRInt32 *aOffset,
nsIAtom *aProperty,
const nsString *aAttribute);
nsresult RemoveStyleInside(nsIDOMNode *aNode,
nsIAtom *aProperty,
const nsString *aAttribute,
PRBool aChildrenOnly = PR_FALSE);
PRBool HasAttr(nsIDOMNode *aNode, const nsString *aAttribute);
PRBool HasAttrVal(nsIDOMNode *aNode, const nsString *aAttribute, const nsString *aValue);
PRBool IsAtFrontOfNode(nsIDOMNode *aNode, PRInt32 aOffset);
PRBool IsAtEndOfNode(nsIDOMNode *aNode, PRInt32 aOffset);
PRBool IsOnlyAttribute(nsIDOMNode *aElement, const nsString *aAttribute);
PRBool HasMatchingAttributes(nsIDOMNode *aNode1,
nsIDOMNode *aNode2);
nsresult GetPriorHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetPriorHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetPriorHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode);
nsresult IsFirstEditableChild( nsIDOMNode *aNode, PRBool *aOutIsFirst);
nsresult IsLastEditableChild( nsIDOMNode *aNode, PRBool *aOutIsLast);
nsresult GetFirstEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutFirstChild);
nsresult GetLastEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutLastChild);
// Data members
protected:
TypeInState* mTypeInState;
nsEditRules* mRules;
TypeInState* mTypeInState;
nsCOMPtr<nsIEditRules> mRules;
nsCOMPtr<nsIDOMEventListener> mKeyListenerP;
nsCOMPtr<nsIDOMEventListener> mMouseListenerP;
nsCOMPtr<nsIDOMEventListener> mTextListenerP;

View File

@ -51,6 +51,17 @@ static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
return NS_OK; \
};
nsresult
NS_NewTextEditRules(nsIEditRules** aInstancePtrResult)
{
nsTextEditRules * rules = new nsTextEditRules();
if (rules)
return rules->QueryInterface(NS_GET_IID(nsIEditRules), (void**) aInstancePtrResult);
return NS_ERROR_OUT_OF_MEMORY;
}
/********************************************************
* Constructor/Destructor
********************************************************/
@ -62,6 +73,7 @@ nsTextEditRules::nsTextEditRules()
, mLockRulesSniffing(PR_FALSE)
, mTheAction(0)
{
NS_INIT_REFCNT();
}
nsTextEditRules::~nsTextEditRules()
@ -69,6 +81,14 @@ nsTextEditRules::~nsTextEditRules()
// do NOT delete mEditor here. We do not hold a ref count to mEditor. mEditor owns our lifespan.
}
/********************************************************
* XPCOM Cruft
********************************************************/
NS_IMPL_ADDREF(nsTextEditRules)
NS_IMPL_RELEASE(nsTextEditRules)
NS_IMPL_QUERY_INTERFACE1(nsTextEditRules, nsIEditRules)
/********************************************************
* Public methods
@ -156,7 +176,7 @@ nsTextEditRules::BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection)
NS_IMETHODIMP
nsTextEditRules::AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection, PRBool aSetSelection)
nsTextEditRules::AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection)
{
if (mLockRulesSniffing) return NS_OK;

View File

@ -42,17 +42,18 @@
* 2. Selection must not be explicitly set by the rule method.
* Any manipulation of Selection must be done by the editor.
*/
class nsTextEditRules : public nsEditRules
class nsTextEditRules : public nsIEditRules
{
public:
NS_DECL_ISUPPORTS
nsTextEditRules();
virtual ~nsTextEditRules();
// nsEditRules methods
// nsIEditRules methods
NS_IMETHOD Init(nsHTMLEditor *aEditor, PRUint32 aFlags);
NS_IMETHOD BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection);
NS_IMETHOD AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection, PRBool aSetSelection);
NS_IMETHOD AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection);
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled);
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
NS_IMETHOD GetFlags(PRUint32 *aFlags);
@ -302,5 +303,25 @@ class nsAutoLockRulesSniffing
/***************************************************************************
* stack based helper class for turning on/off the edit listener.
*/
class nsAutoLockListener
{
public:
nsAutoLockListener(PRBool *enabled) : mEnabled(enabled)
{if (mEnabled) { mOldState=*mEnabled; *mEnabled = PR_FALSE;}}
~nsAutoLockListener()
{if (mEnabled) *mEnabled = mOldState;}
protected:
PRBool *mEnabled;
PRBool mOldState;
};
nsresult NS_NewTextEditRules(nsIEditRules** aInstancePtrResult);
#endif //nsTextEditRules_h__

View File

@ -69,6 +69,8 @@ NS_IMETHODIMP SplitElementTxn::Do(void)
NS_ASSERTION(((NS_SUCCEEDED(result)) && (mNewLeftNode)), "could not create element.");
if (NS_FAILED(result)) return result;
if (!mNewLeftNode) return NS_ERROR_NULL_POINTER;
mEditor->MarkNodeDirty(mExistingRightNode);
if (gNoisy) { printf(" created left node = %p\n", mNewLeftNode.get()); }
// get the parent node
@ -80,9 +82,6 @@ NS_IMETHODIMP SplitElementTxn::Do(void)
result = mEditor->SplitNodeImpl(mExistingRightNode, mOffset, mNewLeftNode, mParent);
if (NS_SUCCEEDED(result) && mNewLeftNode)
{
// Insert formatting whitespace for the new node:
mEditor->InsertFormattingForNode(mExistingRightNode);
nsCOMPtr<nsIDOMSelection>selection;
mEditor->GetSelection(getter_AddRefs(selection));
if (NS_FAILED(result)) return result;

View File

@ -23,6 +23,11 @@
#ifndef nsEditRules_h__
#define nsEditRules_h__
#define NS_IEDITRULES_IID \
{ /* a6cf911b-15b3-11d2-932e-00805f8add32 */ \
0xa6cf911b, 0x15b3, 0x11d2, \
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
class nsHTMLEditor;
class nsIDOMSelection;
@ -40,20 +45,21 @@ class nsRulesInfo
int action;
};
MOZ_DECL_CTOR_COUNTER(nsEditRules);
/***************************************************************************
* Interface of editing rules.
*
*/
class nsEditRules
class nsIEditRules : public nsISupports
{
public:
nsEditRules() { MOZ_COUNT_CTOR(nsEditRules); }
virtual ~nsEditRules() { MOZ_COUNT_DTOR(nsEditRules); }
static const nsIID& GetIID() { static nsIID iid = NS_IEDITRULES_IID; return iid; }
//Interfaces for addref and release and queryinterface
//NOTE: Use NS_DECL_ISUPPORTS_INHERITED in any class inherited from nsIEditRules
NS_IMETHOD Init(nsHTMLEditor *aEditor, PRUint32 aFlags)=0;
NS_IMETHOD BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection)=0;
NS_IMETHOD AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection, PRBool aSetSelection)=0;
NS_IMETHOD AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection)=0;
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled)=0;
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult)=0;
NS_IMETHOD GetFlags(PRUint32 *aFlags)=0;

File diff suppressed because it is too large Load Diff

View File

@ -100,11 +100,41 @@ class nsSelectionState
nsresult RestoreSelection(nsIDOMSelection *aSel);
PRBool IsCollapsed();
PRBool IsEqual(nsSelectionState *aSelState);
void MakeEmpty();
PRBool IsEmpty();
// editor selection gravity routines. Note that we can't always depend on
// DOM Range gravity to do what we want to the "real" selection. For instance,
// if you move a node, that corresponds to deleting it and reinserting it.
// DOM Range gravity will promote the selection out of the node on deletion,
// which is not what you want if you know you are reinserting it.
nsresult SelAdjCreateNode(nsIDOMNode *aParent, PRInt32 aPosition);
nsresult SelAdjInsertNode(nsIDOMNode *aParent, PRInt32 aPosition);
nsresult SelAdjDeleteNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aOffset);
nsresult SelAdjSplitNode(nsIDOMNode *aOldRightNode, PRInt32 aOffset, nsIDOMNode *aNewLeftNode);
nsresult SelAdjJoinNodes(nsIDOMNode *aLeftNode,
nsIDOMNode *aRightNode,
nsIDOMNode *aParent,
PRInt32 aOffset,
PRInt32 aOldLeftNodeLength);
nsresult SelAdjInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsString &aString);
nsresult SelAdjDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength);
// the following gravity routines need will/did sandwiches, because the other gravity
// routines will be called inside of these sandwiches, but should be ignored.
nsresult WillReplaceContainer();
nsresult DidReplaceContainer(nsIDOMNode *aOriginalNode, nsIDOMNode *aNewNode);
nsresult WillRemoveContainer();
nsresult DidRemoveContainer(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aOffset, PRUint32 aNodeOrigLen);
nsresult WillInsertContainer();
nsresult DidInsertContainer();
nsresult WillMoveNode();
nsresult DidMoveNode(nsIDOMNode *aOldParent, PRInt32 aOldOffset, nsIDOMNode *aNewParent, PRInt32 aNewOffset);
nsVoidArray mArray;
PRBool mLock;
};
/** implementation of an editor object. it will be the controler/focal point
/** implementation of an editor object. it will be the controller/focal point
* for the main editor services. i.e. the GUIManager, publishing, transaction
* manager, event interfaces. the idea for the event interfaces is to have them
* delegate the actual commands to the editor independent of the XPFE implementation.
@ -237,7 +267,7 @@ public:
NS_IMETHOD InsertNoneditableTextNode(nsIDOMNode* aParent,
PRInt32 aOffset,
nsString& aStr);
NS_IMETHOD InsertFormattingForNode(nsIDOMNode* aNode);
NS_IMETHOD MarkNodeDirty(nsIDOMNode* aNode);
/* output */
@ -274,8 +304,28 @@ public:
NS_IMETHOD InsertTextImpl(const nsString& aStringToInsert);
NS_IMETHOD JoeInsertTextImpl(const nsString& aStringToInsert,
nsCOMPtr<nsIDOMNode> *aInOutNode,
PRInt32 *aInOutOffset,
nsIDOMDocument *aDoc);
NS_IMETHOD JoeInsertTextIntoTextNodeImpl(const nsString& aStringToInsert,
nsIDOMCharacterData *aTextNode,
PRInt32 aOffset);
NS_IMETHOD DeleteSelectionImpl(EDirection aAction);
/* helper routines for node/parent manipulations */
nsresult ReplaceContainer(nsIDOMNode *inNode,
nsCOMPtr<nsIDOMNode> *outNode,
const nsString &aNodeType,
const nsString *aAttribute = nsnull,
const nsString *aValue = nsnull);
nsresult RemoveContainer(nsIDOMNode *inNode);
nsresult InsertContainerAbove(nsIDOMNode *inNode,
nsCOMPtr<nsIDOMNode> *outNode,
const nsString &aNodeType,
const nsString *aAttribute = nsnull,
const nsString *aValue = nsnull);
nsresult MoveNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aOffset);
protected:
@ -423,7 +473,7 @@ public:
/** All editor operations which alter the doc should be followed
* with a call to EndOperation, naming the action and direction */
NS_IMETHOD EndOperation(PRInt32 opID, nsIEditor::EDirection aDirection, PRBool aSetSelection);
NS_IMETHOD EndOperation(PRInt32 opID, nsIEditor::EDirection aDirection);
/** return the string that represents text nodes in the content tree */
static nsresult GetTextNodeTag(nsString& aOutString);
@ -702,7 +752,8 @@ protected:
nsWeakPtr mPlaceHolderTxn; // weak reference to placeholder for begin/end batch purposes
nsIAtom *mPlaceHolderName; // name of placeholder transaction
PRInt32 mPlaceHolderBatch; // nesting count for batching
nsSelectionState *mSelState; // saved selection state for placeholder txn batching
nsSelectionState *mSelState; // saved selection state for placeholder txn batching
nsSelectionState *mSavedSel; // cached selection for nsAutoSelectionReset
PRBool mShouldTxnSetSelection; // turn off for conservative selection adjustment by txns
nsCOMPtr<nsIDOMElement> mBodyElement; // cached body node
//
@ -718,7 +769,6 @@ protected:
nsCOMPtr<nsISupportsArray> mDocStateListeners;
PRInt8 mDocDirtyState; // -1 = not initialized
nsWeakPtr mDocWeak; // weak reference to the nsIDOMDocument
nsCOMPtr<nsIDTD> mDTD;
@ -726,6 +776,7 @@ protected:
friend PRBool NSCanUnload(nsISupports* serviceMgr);
friend class nsAutoTxnsConserveSelection;
friend class nsAutoSelectionReset;
};

View File

@ -29,39 +29,28 @@
* nsAutoSelectionReset
*****************************************************************************/
nsAutoSelectionReset::nsAutoSelectionReset(nsIDOMSelection *aSel)
nsAutoSelectionReset::nsAutoSelectionReset(nsIDOMSelection *aSel, nsEditor *aEd) :
mSel(nsnull)
,mEd(nsnull)
{
mInitialized = PR_FALSE;
if (!aSel || !aEd) return; // not much we can do, bail.
if (aEd->mSavedSel) return; // we already have initted mSavedSel, so this must be nested call.
mSel = do_QueryInterface(aSel);
mEd = aEd;
if (mSel)
{
mSel->GetAnchorNode(getter_AddRefs(mStartNode));
mSel->GetAnchorOffset(&mStartOffset);
mSel->GetFocusNode(getter_AddRefs(mEndNode));
mSel->GetFocusOffset(&mEndOffset);
if (mStartNode && mEndNode)
mInitialized = PR_TRUE;
mEd->mSavedSel = new nsSelectionState();
mEd->mSavedSel->SaveSelection(mSel);
}
}
nsAutoSelectionReset::~nsAutoSelectionReset()
{
if (mSel && mInitialized)
if (mSel && mEd->mSavedSel) // mSel will be null if this was nested call
{
// make sure that mStartNode and mEndNode are still in a document
nsCOMPtr<nsIDOMDocument> docStart;
nsresult res = mStartNode->GetOwnerDocument(getter_AddRefs(docStart));
if (NS_SUCCEEDED(res) && docStart)
{
nsCOMPtr<nsIDOMDocument> docEnd;
res = mEndNode->GetOwnerDocument(getter_AddRefs(docEnd));
if (NS_SUCCEEDED(res) && (docStart == docEnd))
{
// restore original selection
mSel->Collapse(mStartNode, mStartOffset);
mSel->Extend(mEndNode, mEndOffset);
}
}
mEd->mSavedSel->RestoreSelection(mSel);
delete mEd->mSavedSel;
mEd->mSavedSel = nsnull;
}
}

View File

@ -69,18 +69,11 @@ class nsAutoSelectionReset
private:
/** ref-counted reference to the selection that we are supposed to restore */
nsCOMPtr<nsIDOMSelection> mSel;
/** PR_TRUE if this instance initialized itself correctly */
PRBool mInitialized;
nsCOMPtr<nsIDOMNode> mStartNode;
nsCOMPtr<nsIDOMNode> mEndNode;
PRInt32 mStartOffset;
PRInt32 mEndOffset;
nsEditor *mEd; // non-owning ref to nsEditor
public:
/** constructor responsible for remembering all state needed to restore aSel */
nsAutoSelectionReset(nsIDOMSelection *aSel);
nsAutoSelectionReset(nsIDOMSelection *aSel, nsEditor *aEd);
/** destructor restores mSel to its former state */
~nsAutoSelectionReset();
@ -93,16 +86,15 @@ class nsAutoRules
{
public:
nsAutoRules(nsEditor *ed, PRInt32 action, nsIEditor::EDirection aDirection, PRBool setSelection=PR_FALSE) :
mEd(ed), mAction(action), mDirection(aDirection), mSetSelection(setSelection)
nsAutoRules(nsEditor *ed, PRInt32 action, nsIEditor::EDirection aDirection) :
mEd(ed), mAction(action), mDirection(aDirection)
{if (mEd) mEd->StartOperation(mAction, mDirection);}
~nsAutoRules() {if (mEd) mEd->EndOperation(mAction, mDirection, mSetSelection);}
~nsAutoRules() {if (mEd) mEd->EndOperation(mAction, mDirection);}
protected:
nsEditor *mEd;
PRInt32 mAction;
nsIEditor::EDirection mDirection;
PRBool mSetSelection;
};

File diff suppressed because it is too large Load Diff

View File

@ -33,20 +33,42 @@ class nsISupportsArray;
class nsVoidArray;
class nsIDOMElement;
class nsHTMLEditRules : public nsTextEditRules
class nsHTMLEditRules : public nsTextEditRules, nsIEditActionListener
{
public:
NS_DECL_ISUPPORTS_INHERITED
nsHTMLEditRules();
virtual ~nsHTMLEditRules();
// nsEditRules methods
NS_IMETHOD BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection);
NS_IMETHOD AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection, PRBool aSetSelection);
// nsIEditRules methods
NS_IMETHOD Init(nsHTMLEditor *aEditor, PRUint32 aFlags);
NS_IMETHOD BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection);
NS_IMETHOD AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection);
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled);
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
// nsIEditActionListener methods
NS_IMETHOD WillCreateNode(const nsString& aTag, nsIDOMNode *aParent, PRInt32 aPosition);
NS_IMETHOD DidCreateNode(const nsString& aTag, nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition, nsresult aResult);
NS_IMETHOD WillInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition);
NS_IMETHOD DidInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition, nsresult aResult);
NS_IMETHOD WillDeleteNode(nsIDOMNode *aChild);
NS_IMETHOD DidDeleteNode(nsIDOMNode *aChild, nsresult aResult);
NS_IMETHOD WillSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset);
NS_IMETHOD DidSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset, nsIDOMNode *aNewLeftNode, nsresult aResult);
NS_IMETHOD WillJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent);
NS_IMETHOD DidJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent, nsresult aResult);
NS_IMETHOD WillInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsString &aString);
NS_IMETHOD DidInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsString &aString, nsresult aResult);
NS_IMETHOD WillDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength);
NS_IMETHOD DidDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength, nsresult aResult);
NS_IMETHOD WillDeleteSelection(nsIDOMSelection *aSelection);
NS_IMETHOD DidDeleteSelection(nsIDOMSelection *aSelection);
protected:
enum RulesEndpoint
@ -138,67 +160,19 @@ protected:
nsresult ConvertWhitespace(const nsString & inString, nsString & outString);
nsresult ConfirmSelectionInBody();
// removed from use:
#if 0
nsresult AddTrailerBR(nsIDOMNode *aNode);
nsresult CreateMozDiv(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outDiv);
#endif
// data members
protected:
nsCOMPtr<nsIEditActionListener> mListener;
nsCOMPtr<nsIDOMRange> mDocChangeRange;
// friends
friend class nsHTMLEditListener;
friend nsresult NS_NewEditListener(nsIEditActionListener **aResult,
nsHTMLEditor *htmlEditor,
nsHTMLEditRules *htmlRules);
};
class nsHTMLEditListener : public nsIEditActionListener
{
public:
nsHTMLEditListener(nsHTMLEditor *htmlEditor, nsHTMLEditRules *htmlRules);
virtual ~nsHTMLEditListener();
NS_DECL_ISUPPORTS
// nsIEditActionListener methods
NS_IMETHOD WillCreateNode(const nsString& aTag, nsIDOMNode *aParent, PRInt32 aPosition);
NS_IMETHOD DidCreateNode(const nsString& aTag, nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition, nsresult aResult);
NS_IMETHOD WillInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition);
NS_IMETHOD DidInsertNode(nsIDOMNode *aNode, nsIDOMNode *aParent, PRInt32 aPosition, nsresult aResult);
NS_IMETHOD WillDeleteNode(nsIDOMNode *aChild);
NS_IMETHOD DidDeleteNode(nsIDOMNode *aChild, nsresult aResult);
NS_IMETHOD WillSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset);
NS_IMETHOD DidSplitNode(nsIDOMNode *aExistingRightNode, PRInt32 aOffset, nsIDOMNode *aNewLeftNode, nsresult aResult);
NS_IMETHOD WillJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent);
NS_IMETHOD DidJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent, nsresult aResult);
NS_IMETHOD WillInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsString &aString);
NS_IMETHOD DidInsertText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, const nsString &aString, nsresult aResult);
NS_IMETHOD WillDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength);
NS_IMETHOD DidDeleteText(nsIDOMCharacterData *aTextNode, PRInt32 aOffset, PRInt32 aLength, nsresult aResult);
NS_IMETHOD WillDeleteSelection(nsIDOMSelection *aSelection);
NS_IMETHOD DidDeleteSelection(nsIDOMSelection *aSelection);
protected:
nsresult MakeRangeFromNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMRange> *outRange);
nsresult MakeRangeFromTextOffsets(nsIDOMCharacterData *inNode,
PRInt32 inStart,
PRInt32 inEnd,
nsCOMPtr<nsIDOMRange> *outRange);
nsresult MakeCollapsedRange(nsIDOMNode *inNode, PRInt32 inOffset, nsCOMPtr<nsIDOMRange> *outRange);
PRBool IsDescendantOfBody(nsIDOMNode *inNode) ;
// data members
nsHTMLEditor *mEditor;
nsHTMLEditRules *mRules;
nsCOMPtr<nsIDOMNode> mBody;
PRUint32 mJoinOffset; // need to remember an int across willJoin/didJoin...
protected:
nsCOMPtr<nsIDOMRange> mDocChangeRange;
PRBool mListenerEnabled;
nsCOMPtr<nsIDOMRange> mUtilRange;
nsCOMPtr<nsIDOMNode> mBody;
PRUint32 mJoinOffset; // need to remember an int across willJoin/didJoin...
};
nsresult NS_NewHTMLEditRules(nsIEditRules** aInstancePtrResult);
#endif //nsHTMLEditRules_h__

File diff suppressed because it is too large Load Diff

View File

@ -246,9 +246,6 @@ public:
NS_IMETHOD GetFlags(PRUint32 *aFlags);
NS_IMETHOD SetFlags(PRUint32 aFlags);
/** Inherited from nsEditor with special cases for some html nodes **/
NS_IMETHOD InsertFormattingForNode(nsIDOMNode* aNode);
NS_IMETHOD Undo(PRUint32 aCount);
NS_IMETHOD Redo(PRUint32 aCount);
@ -276,7 +273,7 @@ public:
/** All editor operations which alter the doc should be followed
* with a call to EndOperation, naming the action and direction */
NS_IMETHOD EndOperation(PRInt32 opID, nsIEditor::EDirection aDirection, PRBool aSetSelection);
NS_IMETHOD EndOperation(PRInt32 opID, nsIEditor::EDirection aDirection);
/** returns PR_TRUE if aParent can contain a child of type aTag */
PRBool CanContainTag(nsIDOMNode* aParent, const nsString &aTag);
@ -292,7 +289,7 @@ public:
protected:
virtual void InitRules();
NS_IMETHOD InitRules();
/** install the event listeners for the editor
* used to be part of Init, but now broken out into a separate method
@ -336,6 +333,10 @@ protected:
NS_IMETHOD TabInTable(PRBool inIsShift, PRBool *outHandled);
NS_IMETHOD CreateBR(nsIDOMNode *aNode, PRInt32 aOffset,
nsCOMPtr<nsIDOMNode> *outBRNode, EDirection aSelect = eNone);
NS_IMETHOD JoeCreateBR(nsCOMPtr<nsIDOMNode> *aInOutParent,
PRInt32 *aInOutOffset,
nsCOMPtr<nsIDOMNode> *outBRNode,
EDirection aSelect);
NS_IMETHOD InsertBR(nsCOMPtr<nsIDOMNode> *outBRNode);
// Table Editing (implemented in nsTableEditor.cpp)
@ -582,17 +583,59 @@ protected:
nsresult RelativeFontChangeOnNode( PRInt32 aSizeChange,
nsIDOMNode *aNode);
/* helper routines for node/parent manipulations */
nsresult ReplaceContainer(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode, const nsString &aNodeType);
nsresult RemoveContainer(nsIDOMNode *inNode);
nsresult InsertContainerAbove(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode, const nsString &aNodeType);
/* helper routines for inline style */
nsresult SetInlinePropertyOnTextNode( nsIDOMCharacterData *aTextNode,
PRInt32 aStartOffset,
PRInt32 aEndOffset,
nsIAtom *aProperty,
const nsString *aAttribute,
const nsString *aValue);
nsresult SetInlinePropertyOnNode( nsIDOMNode *aNode,
nsIAtom *aProperty,
const nsString *aAttribute,
const nsString *aValue);
nsresult PromoteInlineRange(nsIDOMRange *inRange);
nsresult SplitStyleAboveRange(nsIDOMRange *aRange,
nsIAtom *aProperty,
const nsString *aAttribute);
nsresult SplitStyleAbovePoint(nsCOMPtr<nsIDOMNode> *aNode,
PRInt32 *aOffset,
nsIAtom *aProperty,
const nsString *aAttribute);
nsresult RemoveStyleInside(nsIDOMNode *aNode,
nsIAtom *aProperty,
const nsString *aAttribute,
PRBool aChildrenOnly = PR_FALSE);
PRBool HasAttr(nsIDOMNode *aNode, const nsString *aAttribute);
PRBool HasAttrVal(nsIDOMNode *aNode, const nsString *aAttribute, const nsString *aValue);
PRBool IsAtFrontOfNode(nsIDOMNode *aNode, PRInt32 aOffset);
PRBool IsAtEndOfNode(nsIDOMNode *aNode, PRInt32 aOffset);
PRBool IsOnlyAttribute(nsIDOMNode *aElement, const nsString *aAttribute);
PRBool HasMatchingAttributes(nsIDOMNode *aNode1,
nsIDOMNode *aNode2);
nsresult GetPriorHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetPriorHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetPriorHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode);
nsresult GetNextHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode);
nsresult IsFirstEditableChild( nsIDOMNode *aNode, PRBool *aOutIsFirst);
nsresult IsLastEditableChild( nsIDOMNode *aNode, PRBool *aOutIsLast);
nsresult GetFirstEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutFirstChild);
nsresult GetLastEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutLastChild);
// Data members
protected:
TypeInState* mTypeInState;
nsEditRules* mRules;
TypeInState* mTypeInState;
nsCOMPtr<nsIEditRules> mRules;
nsCOMPtr<nsIDOMEventListener> mKeyListenerP;
nsCOMPtr<nsIDOMEventListener> mMouseListenerP;
nsCOMPtr<nsIDOMEventListener> mTextListenerP;

View File

@ -51,6 +51,17 @@ static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
return NS_OK; \
};
nsresult
NS_NewTextEditRules(nsIEditRules** aInstancePtrResult)
{
nsTextEditRules * rules = new nsTextEditRules();
if (rules)
return rules->QueryInterface(NS_GET_IID(nsIEditRules), (void**) aInstancePtrResult);
return NS_ERROR_OUT_OF_MEMORY;
}
/********************************************************
* Constructor/Destructor
********************************************************/
@ -62,6 +73,7 @@ nsTextEditRules::nsTextEditRules()
, mLockRulesSniffing(PR_FALSE)
, mTheAction(0)
{
NS_INIT_REFCNT();
}
nsTextEditRules::~nsTextEditRules()
@ -69,6 +81,14 @@ nsTextEditRules::~nsTextEditRules()
// do NOT delete mEditor here. We do not hold a ref count to mEditor. mEditor owns our lifespan.
}
/********************************************************
* XPCOM Cruft
********************************************************/
NS_IMPL_ADDREF(nsTextEditRules)
NS_IMPL_RELEASE(nsTextEditRules)
NS_IMPL_QUERY_INTERFACE1(nsTextEditRules, nsIEditRules)
/********************************************************
* Public methods
@ -156,7 +176,7 @@ nsTextEditRules::BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection)
NS_IMETHODIMP
nsTextEditRules::AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection, PRBool aSetSelection)
nsTextEditRules::AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection)
{
if (mLockRulesSniffing) return NS_OK;

View File

@ -42,17 +42,18 @@
* 2. Selection must not be explicitly set by the rule method.
* Any manipulation of Selection must be done by the editor.
*/
class nsTextEditRules : public nsEditRules
class nsTextEditRules : public nsIEditRules
{
public:
NS_DECL_ISUPPORTS
nsTextEditRules();
virtual ~nsTextEditRules();
// nsEditRules methods
// nsIEditRules methods
NS_IMETHOD Init(nsHTMLEditor *aEditor, PRUint32 aFlags);
NS_IMETHOD BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection);
NS_IMETHOD AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection, PRBool aSetSelection);
NS_IMETHOD AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection);
NS_IMETHOD WillDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, PRBool *aCancel, PRBool *aHandled);
NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
NS_IMETHOD GetFlags(PRUint32 *aFlags);
@ -302,5 +303,25 @@ class nsAutoLockRulesSniffing
/***************************************************************************
* stack based helper class for turning on/off the edit listener.
*/
class nsAutoLockListener
{
public:
nsAutoLockListener(PRBool *enabled) : mEnabled(enabled)
{if (mEnabled) { mOldState=*mEnabled; *mEnabled = PR_FALSE;}}
~nsAutoLockListener()
{if (mEnabled) *mEnabled = mOldState;}
protected:
PRBool *mEnabled;
PRBool mOldState;
};
nsresult NS_NewTextEditRules(nsIEditRules** aInstancePtrResult);
#endif //nsTextEditRules_h__