From 54d647b45878929b5e3103e4fe47351a9746ce9f Mon Sep 17 00:00:00 2001 From: "jfrancis%netscape.com" Date: Mon, 20 Sep 1999 01:31:44 +0000 Subject: [PATCH] fixing a heap-o-undo problems and some mBogusNode problems --- editor/base/nsEditor.cpp | 2 - editor/base/nsEditorUtils.h | 13 ++++ editor/base/nsHTMLEditRules.cpp | 29 +++++++- editor/base/nsHTMLEditor.cpp | 11 +++ editor/base/nsTextEditRules.cpp | 87 ++++++++++++++--------- editor/libeditor/base/nsEditor.cpp | 2 - editor/libeditor/base/nsEditorUtils.h | 13 ++++ editor/libeditor/html/nsHTMLEditRules.cpp | 29 +++++++- editor/libeditor/html/nsHTMLEditor.cpp | 11 +++ editor/libeditor/text/nsTextEditRules.cpp | 87 ++++++++++++++--------- 10 files changed, 212 insertions(+), 72 deletions(-) diff --git a/editor/base/nsEditor.cpp b/editor/base/nsEditor.cpp index 1323de756008..4ca38d4e29b1 100644 --- a/editor/base/nsEditor.cpp +++ b/editor/base/nsEditor.cpp @@ -1481,7 +1481,6 @@ NS_IMETHODIMP nsEditor::InsertTextImpl(const nsString& aStringToInsert) } else if (NS_ERROR_EDITOR_NO_TEXTNODE==result) { - BeginTransaction(); result = Do(aggTxn); if (NS_SUCCEEDED(result)) { @@ -1516,7 +1515,6 @@ NS_IMETHODIMP nsEditor::InsertTextImpl(const nsString& aStringToInsert) } } } - EndTransaction(); } return result; } diff --git a/editor/base/nsEditorUtils.h b/editor/base/nsEditorUtils.h index 9cdf8dc5fd03..5c7c07844b62 100644 --- a/editor/base/nsEditorUtils.h +++ b/editor/base/nsEditorUtils.h @@ -36,6 +36,19 @@ class nsAutoEditBatch ~nsAutoEditBatch() { if (mEd) mEd->EndTransaction(); } }; +class nsAutoEditMayBatch +{ + private: + nsCOMPtr mEd; + PRBool mDidBatch; + public: + nsAutoEditMayBatch( nsIEditor *aEd) : mEd(do_QueryInterface(aEd)), mDidBatch(PR_FALSE) {} + nsAutoEditMayBatch() { if (mEd && mDidBatch) mEd->EndTransaction(); } + + void batch() { if (mEd && !mDidBatch) {mEd->BeginTransaction(); mDidBatch=PR_TRUE;} } +}; + + class nsAutoSelectionReset { private: diff --git a/editor/base/nsHTMLEditRules.cpp b/editor/base/nsHTMLEditRules.cpp index 05bef2aa79e2..0211e3c89c41 100644 --- a/editor/base/nsHTMLEditRules.cpp +++ b/editor/base/nsHTMLEditRules.cpp @@ -155,6 +155,7 @@ nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection, // initialize out param *aCancel = PR_TRUE; nsresult res; + nsAutoEditMayBatch optionalBatch; char specialChars[] = {'\t',' ',nbsp,'\n',0}; @@ -169,7 +170,7 @@ nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection, } // split any mailcites in the way - if (mFlags & nsIHTMLEditor::eEditorMailMask) + if (1 || mFlags & nsIHTMLEditor::eEditorMailMask) { nsCOMPtr citeNode, selNode; PRInt32 selOffset, newOffset; @@ -180,6 +181,8 @@ nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection, if (citeNode) { + // turn batching on + optionalBatch.batch(); res = mEditor->SplitNodeDeep(citeNode, selNode, selOffset, &newOffset); if (NS_FAILED(res)) return res; res = citeNode->GetParentNode(getter_AddRefs(selNode)); @@ -247,6 +250,7 @@ nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel) *aCancel = PR_FALSE; nsresult res; + nsAutoEditMayBatch optionalBatch; res = WillInsert(aSelection, aCancel); if (NS_FAILED(res)) return res; @@ -264,6 +268,29 @@ nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel) if (NS_FAILED(res)) return res; } + // split any mailcites in the way + if (1 || mFlags & nsIHTMLEditor::eEditorMailMask) + { + nsCOMPtr citeNode, selNode; + PRInt32 selOffset, newOffset; + res = mEditor->GetStartNodeAndOffset(aSelection, &selNode, &selOffset); + if (NS_FAILED(res)) return res; + res = GetTopEnclosingMailCite(selNode, &citeNode); + if (NS_FAILED(res)) return res; + + if (citeNode) + { + // turn batching on + optionalBatch.batch(); + res = mEditor->SplitNodeDeep(citeNode, selNode, selOffset, &newOffset); + if (NS_FAILED(res)) return res; + res = citeNode->GetParentNode(getter_AddRefs(selNode)); + if (NS_FAILED(res)) return res; + res = aSelection->Collapse(selNode, newOffset); + if (NS_FAILED(res)) return res; + } + } + // smart splitting rules nsCOMPtr node; PRInt32 offset; diff --git a/editor/base/nsHTMLEditor.cpp b/editor/base/nsHTMLEditor.cpp index 43cfda324c78..02e22b5d1b16 100644 --- a/editor/base/nsHTMLEditor.cpp +++ b/editor/base/nsHTMLEditor.cpp @@ -4764,6 +4764,8 @@ nsHTMLEditor::DeleteSelectionAndPrepareToCreateNode(nsCOMPtr &parent nsCOMPtrselectedParentNodeAsText; selectedParentNodeAsText = do_QueryInterface(parentSelectedNode); + offsetOfNewNode = offsetOfSelectedNode; + /* if the selection is a text node, split the text node if necesary and compute where to put the new node */ @@ -4795,6 +4797,14 @@ nsHTMLEditor::DeleteSelectionAndPrepareToCreateNode(nsCOMPtr &parent } } } + + // I dont know what is up with this, but there is no reason to split + // any node we happen to be inserting into. The code below (ifdef'd out) + // breaks InsertBreak(). + + +#if 0 + /* if the selection is not a text node, split the parent node if necesary and compute where to put the new node */ @@ -4854,6 +4864,7 @@ nsHTMLEditor::DeleteSelectionAndPrepareToCreateNode(nsCOMPtr &parent } } } +#endif // Here's where the new node was inserted } diff --git a/editor/base/nsTextEditRules.cpp b/editor/base/nsTextEditRules.cpp index e290a049e461..7f44e28691c1 100644 --- a/editor/base/nsTextEditRules.cpp +++ b/editor/base/nsTextEditRules.cpp @@ -758,27 +758,37 @@ nsTextEditRules:: DidUndo(nsIDOMSelection *aSelection, nsresult aResult) } else { - nsCOMPtrnode; - PRInt32 offset; - res = aSelection->GetAnchorNode(getter_AddRefs(node)); + nsCOMPtr theBody; + res = mEditor->GetBodyElement(getter_AddRefs(theBody)); if (NS_FAILED(res)) return res; - if (!node) return NS_ERROR_NULL_POINTER; - res = aSelection->GetAnchorOffset(&offset); + if (!theBody) return NS_ERROR_FAILURE; + + nsAutoString tagName("div"); + nsCOMPtr nodeList; + res = theBody->GetElementsByTagName(tagName, getter_AddRefs(nodeList)); if (NS_FAILED(res)) return res; - nsCOMPtrelement; - element = do_QueryInterface(node); - if (element) + if (nodeList) { - nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr); - nsAutoString val; - (void)element->GetAttribute(att, val); - if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) { - mBogusNode = do_QueryInterface(element); + PRUint32 len, j; + nodeList->GetLength(&len); + + if (len != 1) return NS_OK; // only in the case of one div could there be the bogus node + nsCOMPtrnode; + nsCOMPtrelement; + nodeList->Item(0, getter_AddRefs(node)); + if (!node) return NS_ERROR_NULL_POINTER; + element = do_QueryInterface(node); + if (element) + { + nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr); + nsAutoString val; + (void)element->GetAttribute(att, val); + if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) + { + mBogusNode = do_QueryInterface(element); + } } } - nsCOMPtr temp; - res = node->GetParentNode(getter_AddRefs(temp)); - node = do_QueryInterface(temp); } } return res; @@ -806,27 +816,37 @@ nsTextEditRules::DidRedo(nsIDOMSelection *aSelection, nsresult aResult) } else { - nsCOMPtrnode; - PRInt32 offset; - res = aSelection->GetAnchorNode(getter_AddRefs(node)); + nsCOMPtr theBody; + res = mEditor->GetBodyElement(getter_AddRefs(theBody)); if (NS_FAILED(res)) return res; - if (!node) return NS_ERROR_NULL_POINTER; - res = aSelection->GetAnchorOffset(&offset); + if (!theBody) return NS_ERROR_FAILURE; + + nsAutoString tagName("div"); + nsCOMPtr nodeList; + res = theBody->GetElementsByTagName(tagName, getter_AddRefs(nodeList)); if (NS_FAILED(res)) return res; - nsCOMPtrelement; - element = do_QueryInterface(node); - if (element) + if (nodeList) { - nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr); - nsAutoString val; - (void)element->GetAttribute(att, val); - if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) { - mBogusNode = do_QueryInterface(element); + PRUint32 len, j; + nodeList->GetLength(&len); + + if (len != 1) return NS_OK; // only in the case of one div could there be the bogus node + nsCOMPtrnode; + nsCOMPtrelement; + nodeList->Item(0, getter_AddRefs(node)); + if (!node) return NS_ERROR_NULL_POINTER; + element = do_QueryInterface(node); + if (element) + { + nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr); + nsAutoString val; + (void)element->GetAttribute(att, val); + if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) + { + mBogusNode = do_QueryInterface(element); + } } } - nsCOMPtr temp; - res = node->GetParentNode(getter_AddRefs(temp)); - node = do_QueryInterface(temp); } } return res; @@ -872,7 +892,8 @@ nsTextEditRules::CreateBogusNodeIfNeeded(nsIDOMSelection *aSelection) { if (!aSelection) { return NS_ERROR_NULL_POINTER; } if (!mEditor) { return NS_ERROR_NULL_POINTER; } - + if (mBogusNode) return NS_OK; // let's not create more than one, ok? + nsCOMPtr bodyElement; nsresult res = mEditor->GetBodyElement(getter_AddRefs(bodyElement)); if (NS_FAILED(res)) return res; diff --git a/editor/libeditor/base/nsEditor.cpp b/editor/libeditor/base/nsEditor.cpp index 1323de756008..4ca38d4e29b1 100644 --- a/editor/libeditor/base/nsEditor.cpp +++ b/editor/libeditor/base/nsEditor.cpp @@ -1481,7 +1481,6 @@ NS_IMETHODIMP nsEditor::InsertTextImpl(const nsString& aStringToInsert) } else if (NS_ERROR_EDITOR_NO_TEXTNODE==result) { - BeginTransaction(); result = Do(aggTxn); if (NS_SUCCEEDED(result)) { @@ -1516,7 +1515,6 @@ NS_IMETHODIMP nsEditor::InsertTextImpl(const nsString& aStringToInsert) } } } - EndTransaction(); } return result; } diff --git a/editor/libeditor/base/nsEditorUtils.h b/editor/libeditor/base/nsEditorUtils.h index 9cdf8dc5fd03..5c7c07844b62 100644 --- a/editor/libeditor/base/nsEditorUtils.h +++ b/editor/libeditor/base/nsEditorUtils.h @@ -36,6 +36,19 @@ class nsAutoEditBatch ~nsAutoEditBatch() { if (mEd) mEd->EndTransaction(); } }; +class nsAutoEditMayBatch +{ + private: + nsCOMPtr mEd; + PRBool mDidBatch; + public: + nsAutoEditMayBatch( nsIEditor *aEd) : mEd(do_QueryInterface(aEd)), mDidBatch(PR_FALSE) {} + nsAutoEditMayBatch() { if (mEd && mDidBatch) mEd->EndTransaction(); } + + void batch() { if (mEd && !mDidBatch) {mEd->BeginTransaction(); mDidBatch=PR_TRUE;} } +}; + + class nsAutoSelectionReset { private: diff --git a/editor/libeditor/html/nsHTMLEditRules.cpp b/editor/libeditor/html/nsHTMLEditRules.cpp index 05bef2aa79e2..0211e3c89c41 100644 --- a/editor/libeditor/html/nsHTMLEditRules.cpp +++ b/editor/libeditor/html/nsHTMLEditRules.cpp @@ -155,6 +155,7 @@ nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection, // initialize out param *aCancel = PR_TRUE; nsresult res; + nsAutoEditMayBatch optionalBatch; char specialChars[] = {'\t',' ',nbsp,'\n',0}; @@ -169,7 +170,7 @@ nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection, } // split any mailcites in the way - if (mFlags & nsIHTMLEditor::eEditorMailMask) + if (1 || mFlags & nsIHTMLEditor::eEditorMailMask) { nsCOMPtr citeNode, selNode; PRInt32 selOffset, newOffset; @@ -180,6 +181,8 @@ nsHTMLEditRules::WillInsertText(nsIDOMSelection *aSelection, if (citeNode) { + // turn batching on + optionalBatch.batch(); res = mEditor->SplitNodeDeep(citeNode, selNode, selOffset, &newOffset); if (NS_FAILED(res)) return res; res = citeNode->GetParentNode(getter_AddRefs(selNode)); @@ -247,6 +250,7 @@ nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel) *aCancel = PR_FALSE; nsresult res; + nsAutoEditMayBatch optionalBatch; res = WillInsert(aSelection, aCancel); if (NS_FAILED(res)) return res; @@ -264,6 +268,29 @@ nsHTMLEditRules::WillInsertBreak(nsIDOMSelection *aSelection, PRBool *aCancel) if (NS_FAILED(res)) return res; } + // split any mailcites in the way + if (1 || mFlags & nsIHTMLEditor::eEditorMailMask) + { + nsCOMPtr citeNode, selNode; + PRInt32 selOffset, newOffset; + res = mEditor->GetStartNodeAndOffset(aSelection, &selNode, &selOffset); + if (NS_FAILED(res)) return res; + res = GetTopEnclosingMailCite(selNode, &citeNode); + if (NS_FAILED(res)) return res; + + if (citeNode) + { + // turn batching on + optionalBatch.batch(); + res = mEditor->SplitNodeDeep(citeNode, selNode, selOffset, &newOffset); + if (NS_FAILED(res)) return res; + res = citeNode->GetParentNode(getter_AddRefs(selNode)); + if (NS_FAILED(res)) return res; + res = aSelection->Collapse(selNode, newOffset); + if (NS_FAILED(res)) return res; + } + } + // smart splitting rules nsCOMPtr node; PRInt32 offset; diff --git a/editor/libeditor/html/nsHTMLEditor.cpp b/editor/libeditor/html/nsHTMLEditor.cpp index 43cfda324c78..02e22b5d1b16 100644 --- a/editor/libeditor/html/nsHTMLEditor.cpp +++ b/editor/libeditor/html/nsHTMLEditor.cpp @@ -4764,6 +4764,8 @@ nsHTMLEditor::DeleteSelectionAndPrepareToCreateNode(nsCOMPtr &parent nsCOMPtrselectedParentNodeAsText; selectedParentNodeAsText = do_QueryInterface(parentSelectedNode); + offsetOfNewNode = offsetOfSelectedNode; + /* if the selection is a text node, split the text node if necesary and compute where to put the new node */ @@ -4795,6 +4797,14 @@ nsHTMLEditor::DeleteSelectionAndPrepareToCreateNode(nsCOMPtr &parent } } } + + // I dont know what is up with this, but there is no reason to split + // any node we happen to be inserting into. The code below (ifdef'd out) + // breaks InsertBreak(). + + +#if 0 + /* if the selection is not a text node, split the parent node if necesary and compute where to put the new node */ @@ -4854,6 +4864,7 @@ nsHTMLEditor::DeleteSelectionAndPrepareToCreateNode(nsCOMPtr &parent } } } +#endif // Here's where the new node was inserted } diff --git a/editor/libeditor/text/nsTextEditRules.cpp b/editor/libeditor/text/nsTextEditRules.cpp index e290a049e461..7f44e28691c1 100644 --- a/editor/libeditor/text/nsTextEditRules.cpp +++ b/editor/libeditor/text/nsTextEditRules.cpp @@ -758,27 +758,37 @@ nsTextEditRules:: DidUndo(nsIDOMSelection *aSelection, nsresult aResult) } else { - nsCOMPtrnode; - PRInt32 offset; - res = aSelection->GetAnchorNode(getter_AddRefs(node)); + nsCOMPtr theBody; + res = mEditor->GetBodyElement(getter_AddRefs(theBody)); if (NS_FAILED(res)) return res; - if (!node) return NS_ERROR_NULL_POINTER; - res = aSelection->GetAnchorOffset(&offset); + if (!theBody) return NS_ERROR_FAILURE; + + nsAutoString tagName("div"); + nsCOMPtr nodeList; + res = theBody->GetElementsByTagName(tagName, getter_AddRefs(nodeList)); if (NS_FAILED(res)) return res; - nsCOMPtrelement; - element = do_QueryInterface(node); - if (element) + if (nodeList) { - nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr); - nsAutoString val; - (void)element->GetAttribute(att, val); - if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) { - mBogusNode = do_QueryInterface(element); + PRUint32 len, j; + nodeList->GetLength(&len); + + if (len != 1) return NS_OK; // only in the case of one div could there be the bogus node + nsCOMPtrnode; + nsCOMPtrelement; + nodeList->Item(0, getter_AddRefs(node)); + if (!node) return NS_ERROR_NULL_POINTER; + element = do_QueryInterface(node); + if (element) + { + nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr); + nsAutoString val; + (void)element->GetAttribute(att, val); + if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) + { + mBogusNode = do_QueryInterface(element); + } } } - nsCOMPtr temp; - res = node->GetParentNode(getter_AddRefs(temp)); - node = do_QueryInterface(temp); } } return res; @@ -806,27 +816,37 @@ nsTextEditRules::DidRedo(nsIDOMSelection *aSelection, nsresult aResult) } else { - nsCOMPtrnode; - PRInt32 offset; - res = aSelection->GetAnchorNode(getter_AddRefs(node)); + nsCOMPtr theBody; + res = mEditor->GetBodyElement(getter_AddRefs(theBody)); if (NS_FAILED(res)) return res; - if (!node) return NS_ERROR_NULL_POINTER; - res = aSelection->GetAnchorOffset(&offset); + if (!theBody) return NS_ERROR_FAILURE; + + nsAutoString tagName("div"); + nsCOMPtr nodeList; + res = theBody->GetElementsByTagName(tagName, getter_AddRefs(nodeList)); if (NS_FAILED(res)) return res; - nsCOMPtrelement; - element = do_QueryInterface(node); - if (element) + if (nodeList) { - nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr); - nsAutoString val; - (void)element->GetAttribute(att, val); - if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) { - mBogusNode = do_QueryInterface(element); + PRUint32 len, j; + nodeList->GetLength(&len); + + if (len != 1) return NS_OK; // only in the case of one div could there be the bogus node + nsCOMPtrnode; + nsCOMPtrelement; + nodeList->Item(0, getter_AddRefs(node)); + if (!node) return NS_ERROR_NULL_POINTER; + element = do_QueryInterface(node); + if (element) + { + nsAutoString att(nsEditor::kMOZEditorBogusNodeAttr); + nsAutoString val; + (void)element->GetAttribute(att, val); + if (val.Equals(nsEditor::kMOZEditorBogusNodeValue)) + { + mBogusNode = do_QueryInterface(element); + } } } - nsCOMPtr temp; - res = node->GetParentNode(getter_AddRefs(temp)); - node = do_QueryInterface(temp); } } return res; @@ -872,7 +892,8 @@ nsTextEditRules::CreateBogusNodeIfNeeded(nsIDOMSelection *aSelection) { if (!aSelection) { return NS_ERROR_NULL_POINTER; } if (!mEditor) { return NS_ERROR_NULL_POINTER; } - + if (mBogusNode) return NS_OK; // let's not create more than one, ok? + nsCOMPtr bodyElement; nsresult res = mEditor->GetBodyElement(getter_AddRefs(bodyElement)); if (NS_FAILED(res)) return res;