fixing a heap-o-undo problems and some mBogusNode problems

This commit is contained in:
jfrancis%netscape.com 1999-09-20 01:31:44 +00:00
Родитель d235ccb522
Коммит 54d647b458
10 изменённых файлов: 212 добавлений и 72 удалений

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -36,6 +36,19 @@ class nsAutoEditBatch
~nsAutoEditBatch() { if (mEd) mEd->EndTransaction(); }
};
class nsAutoEditMayBatch
{
private:
nsCOMPtr<nsIEditor> 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:

Просмотреть файл

@ -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<nsIDOMNode> 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<nsIDOMNode> 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<nsIDOMNode> node;
PRInt32 offset;

Просмотреть файл

@ -4764,6 +4764,8 @@ nsHTMLEditor::DeleteSelectionAndPrepareToCreateNode(nsCOMPtr<nsIDOMNode> &parent
nsCOMPtr<nsIDOMCharacterData>selectedParentNodeAsText;
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<nsIDOMNode> &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<nsIDOMNode> &parent
}
}
}
#endif
// Here's where the new node was inserted
}

Просмотреть файл

@ -758,27 +758,37 @@ nsTextEditRules:: DidUndo(nsIDOMSelection *aSelection, nsresult aResult)
}
else
{
nsCOMPtr<nsIDOMNode>node;
PRInt32 offset;
res = aSelection->GetAnchorNode(getter_AddRefs(node));
nsCOMPtr<nsIDOMElement> 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<nsIDOMNodeList> nodeList;
res = theBody->GetElementsByTagName(tagName, getter_AddRefs(nodeList));
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMElement>element;
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
nsCOMPtr<nsIDOMNode>node;
nsCOMPtr<nsIDOMElement>element;
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<nsIDOMNode> temp;
res = node->GetParentNode(getter_AddRefs(temp));
node = do_QueryInterface(temp);
}
}
return res;
@ -806,27 +816,37 @@ nsTextEditRules::DidRedo(nsIDOMSelection *aSelection, nsresult aResult)
}
else
{
nsCOMPtr<nsIDOMNode>node;
PRInt32 offset;
res = aSelection->GetAnchorNode(getter_AddRefs(node));
nsCOMPtr<nsIDOMElement> 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<nsIDOMNodeList> nodeList;
res = theBody->GetElementsByTagName(tagName, getter_AddRefs(nodeList));
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMElement>element;
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
nsCOMPtr<nsIDOMNode>node;
nsCOMPtr<nsIDOMElement>element;
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<nsIDOMNode> 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<nsIDOMElement> bodyElement;
nsresult res = mEditor->GetBodyElement(getter_AddRefs(bodyElement));
if (NS_FAILED(res)) return res;

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -36,6 +36,19 @@ class nsAutoEditBatch
~nsAutoEditBatch() { if (mEd) mEd->EndTransaction(); }
};
class nsAutoEditMayBatch
{
private:
nsCOMPtr<nsIEditor> 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:

Просмотреть файл

@ -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<nsIDOMNode> 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<nsIDOMNode> 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<nsIDOMNode> node;
PRInt32 offset;

Просмотреть файл

@ -4764,6 +4764,8 @@ nsHTMLEditor::DeleteSelectionAndPrepareToCreateNode(nsCOMPtr<nsIDOMNode> &parent
nsCOMPtr<nsIDOMCharacterData>selectedParentNodeAsText;
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<nsIDOMNode> &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<nsIDOMNode> &parent
}
}
}
#endif
// Here's where the new node was inserted
}

Просмотреть файл

@ -758,27 +758,37 @@ nsTextEditRules:: DidUndo(nsIDOMSelection *aSelection, nsresult aResult)
}
else
{
nsCOMPtr<nsIDOMNode>node;
PRInt32 offset;
res = aSelection->GetAnchorNode(getter_AddRefs(node));
nsCOMPtr<nsIDOMElement> 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<nsIDOMNodeList> nodeList;
res = theBody->GetElementsByTagName(tagName, getter_AddRefs(nodeList));
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMElement>element;
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
nsCOMPtr<nsIDOMNode>node;
nsCOMPtr<nsIDOMElement>element;
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<nsIDOMNode> temp;
res = node->GetParentNode(getter_AddRefs(temp));
node = do_QueryInterface(temp);
}
}
return res;
@ -806,27 +816,37 @@ nsTextEditRules::DidRedo(nsIDOMSelection *aSelection, nsresult aResult)
}
else
{
nsCOMPtr<nsIDOMNode>node;
PRInt32 offset;
res = aSelection->GetAnchorNode(getter_AddRefs(node));
nsCOMPtr<nsIDOMElement> 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<nsIDOMNodeList> nodeList;
res = theBody->GetElementsByTagName(tagName, getter_AddRefs(nodeList));
if (NS_FAILED(res)) return res;
nsCOMPtr<nsIDOMElement>element;
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
nsCOMPtr<nsIDOMNode>node;
nsCOMPtr<nsIDOMElement>element;
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<nsIDOMNode> 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<nsIDOMElement> bodyElement;
nsresult res = mEditor->GetBodyElement(getter_AddRefs(bodyElement));
if (NS_FAILED(res)) return res;