diff --git a/editor/base/nsHTMLEditor.cpp b/editor/base/nsHTMLEditor.cpp index 19725df1798..43cfda324c7 100644 --- a/editor/base/nsHTMLEditor.cpp +++ b/editor/base/nsHTMLEditor.cpp @@ -501,33 +501,12 @@ NS_IMETHODIMP nsHTMLEditor::TabInTable(PRBool inIsShift, PRBool *outHandled) else block = GetBlockNodeParent(selNode); if (!block) return res; - nsAutoString tagName; - GetTagString(block,tagName); - tagName.ToLowerCase(); - if (tagName == "table" || tagName == "tr" || - tagName == "td" || tagName == "th" || - tagName == "thead" || tagName == "tfoot" || - tagName == "tbody" || tagName == "caption") + if (IsTableElement(block)) { // find enclosing table nsCOMPtr tbl; - if (tagName == "table") tbl = block; - else - { - nsCOMPtr tmp, node = block; - do - { - GetTagString(node,tagName); - tagName.ToLowerCase(); - if (tagName == "table") - { - tbl = node; - break; - } - tmp = GetBlockNodeParent(node); - node= tmp; - } while (node); - } + if (IsTable(block)) tbl = block; + else tbl = GetEnclosingTable(block); if (!tbl) return res; // advance to next cell // first create an iterator over the table @@ -554,9 +533,7 @@ NS_IMETHODIMP nsHTMLEditor::TabInTable(PRBool inIsShift, PRBool *outHandled) res = iter->CurrentNode(getter_AddRefs(cNode)); if (NS_FAILED(res)) return res; node = do_QueryInterface(cNode); - GetTagString(node,tagName); - tagName.ToLowerCase(); - if (tagName == "td") + if (IsTableCell(node) && (GetEnclosingTable(node) == tbl)) { selection->Collapse(node, 0); *outHandled = PR_TRUE; @@ -3101,6 +3078,56 @@ nsHTMLEditor::GetEmbeddedObjects(nsISupportsArray** aNodeList) #pragma mark - #endif + +NS_IMETHODIMP +nsHTMLEditor::Undo(PRUint32 aCount) +{ + nsresult result = NS_OK; + + BeginUpdateViewBatch(); + + nsTextRulesInfo ruleInfo(nsTextEditRules::kUndo); + nsCOMPtr selection; + GetSelection(getter_AddRefs(selection)); + PRBool cancel; + result = mRules->WillDoAction(selection, &ruleInfo, &cancel); + + if (!cancel && NS_SUCCEEDED(result)) + { + result = nsEditor::Undo(aCount); + result = mRules->DidDoAction(selection, &ruleInfo, result); + } + + EndUpdateViewBatch(); + + return result; +} + + +NS_IMETHODIMP +nsHTMLEditor::Redo(PRUint32 aCount) +{ + nsresult result = NS_OK; + + BeginUpdateViewBatch(); + + nsTextRulesInfo ruleInfo(nsTextEditRules::kRedo); + nsCOMPtr selection; + GetSelection(getter_AddRefs(selection)); + PRBool cancel; + result = mRules->WillDoAction(selection, &ruleInfo, &cancel); + + if (!cancel && NS_SUCCEEDED(result)) + { + result = nsEditor::Redo(aCount); + result = mRules->DidDoAction(selection, &ruleInfo, result); + } + + EndUpdateViewBatch(); + + return result; +} + NS_IMETHODIMP nsHTMLEditor::Cut() { nsCOMPtr selection; @@ -4617,6 +4644,79 @@ nsHTMLEditor::IsSubordinateBlock(nsString &aTag, PRBool &aIsTag) return NS_OK; } +/////////////////////////////////////////////////////////////////////////// +// IsTable: true if node an html table +// +PRBool +nsHTMLEditor::IsTable(nsIDOMNode *node) +{ + NS_PRECONDITION(node, "null node passed to nsHTMLEditor::IsTable"); + nsAutoString tag; + nsEditor::GetTagString(node,tag); + if (tag == "table") + { + return PR_TRUE; + } + return PR_FALSE; +} + + +/////////////////////////////////////////////////////////////////////////// +// IsTableCell: true if node an html td +// +PRBool +nsHTMLEditor::IsTableCell(nsIDOMNode *node) +{ + NS_PRECONDITION(node, "null node passed to nsHTMLEditor::IsTableCell"); + nsAutoString tag; + nsEditor::GetTagString(node,tag); + if (tag == "td") + { + return PR_TRUE; + } + return PR_FALSE; +} + + +/////////////////////////////////////////////////////////////////////////// +// IsTableElement: true if node an html table, td, tr, ... +// +PRBool +nsHTMLEditor::IsTableElement(nsIDOMNode *node) +{ + NS_PRECONDITION(node, "null node passed to nsHTMLEditor::IsTableElement"); + nsAutoString tagName; + nsEditor::GetTagString(node,tagName); + if (tagName == "table" || tagName == "tr" || + tagName == "td" || tagName == "th" || + tagName == "thead" || tagName == "tfoot" || + tagName == "tbody" || tagName == "caption") + { + return PR_TRUE; + } + return PR_FALSE; +} + + +/////////////////////////////////////////////////////////////////////////// +// GetEnclosingTable: find ancestor who is a table, if any +// +nsCOMPtr +nsHTMLEditor::GetEnclosingTable(nsIDOMNode *aNode) +{ + NS_PRECONDITION(aNode, "null node passed to nsHTMLEditor::GetEnclosingTable"); + nsCOMPtr tbl, tmp, node = aNode; + + while (!tbl) + { + tmp = GetBlockNodeParent(node); + if (!tmp) break; + if (IsTable(tmp)) tbl = tmp; + node = tmp; + } + return tbl; +} + NS_IMETHODIMP nsHTMLEditor::DeleteSelectionAndPrepareToCreateNode(nsCOMPtr &parentSelectedNode, PRInt32& offsetOfNewNode) diff --git a/editor/base/nsHTMLEditor.h b/editor/base/nsHTMLEditor.h index 0dac4f604f5..6e0d3673043 100644 --- a/editor/base/nsHTMLEditor.h +++ b/editor/base/nsHTMLEditor.h @@ -182,6 +182,9 @@ public: NS_IMETHOD GetFlags(PRUint32 *aFlags); NS_IMETHOD SetFlags(PRUint32 aFlags); + NS_IMETHOD Undo(PRUint32 aCount); + NS_IMETHOD Redo(PRUint32 aCount); + NS_IMETHOD Cut(); NS_IMETHOD Copy(); NS_IMETHOD Paste(); @@ -288,6 +291,10 @@ protected: NS_IMETHOD IsSubordinateBlock(nsString &aTag, PRBool &aIsTag); + static PRBool IsTable(nsIDOMNode *aNode); + static PRBool IsTableCell(nsIDOMNode *aNode); + static PRBool IsTableElement(nsIDOMNode *aNode); + static nsCOMPtr GetEnclosingTable(nsIDOMNode *aNode); /** content-based query returns PR_TRUE if effects aNode * If contains aNode, diff --git a/editor/libeditor/html/nsHTMLEditor.cpp b/editor/libeditor/html/nsHTMLEditor.cpp index 19725df1798..43cfda324c7 100644 --- a/editor/libeditor/html/nsHTMLEditor.cpp +++ b/editor/libeditor/html/nsHTMLEditor.cpp @@ -501,33 +501,12 @@ NS_IMETHODIMP nsHTMLEditor::TabInTable(PRBool inIsShift, PRBool *outHandled) else block = GetBlockNodeParent(selNode); if (!block) return res; - nsAutoString tagName; - GetTagString(block,tagName); - tagName.ToLowerCase(); - if (tagName == "table" || tagName == "tr" || - tagName == "td" || tagName == "th" || - tagName == "thead" || tagName == "tfoot" || - tagName == "tbody" || tagName == "caption") + if (IsTableElement(block)) { // find enclosing table nsCOMPtr tbl; - if (tagName == "table") tbl = block; - else - { - nsCOMPtr tmp, node = block; - do - { - GetTagString(node,tagName); - tagName.ToLowerCase(); - if (tagName == "table") - { - tbl = node; - break; - } - tmp = GetBlockNodeParent(node); - node= tmp; - } while (node); - } + if (IsTable(block)) tbl = block; + else tbl = GetEnclosingTable(block); if (!tbl) return res; // advance to next cell // first create an iterator over the table @@ -554,9 +533,7 @@ NS_IMETHODIMP nsHTMLEditor::TabInTable(PRBool inIsShift, PRBool *outHandled) res = iter->CurrentNode(getter_AddRefs(cNode)); if (NS_FAILED(res)) return res; node = do_QueryInterface(cNode); - GetTagString(node,tagName); - tagName.ToLowerCase(); - if (tagName == "td") + if (IsTableCell(node) && (GetEnclosingTable(node) == tbl)) { selection->Collapse(node, 0); *outHandled = PR_TRUE; @@ -3101,6 +3078,56 @@ nsHTMLEditor::GetEmbeddedObjects(nsISupportsArray** aNodeList) #pragma mark - #endif + +NS_IMETHODIMP +nsHTMLEditor::Undo(PRUint32 aCount) +{ + nsresult result = NS_OK; + + BeginUpdateViewBatch(); + + nsTextRulesInfo ruleInfo(nsTextEditRules::kUndo); + nsCOMPtr selection; + GetSelection(getter_AddRefs(selection)); + PRBool cancel; + result = mRules->WillDoAction(selection, &ruleInfo, &cancel); + + if (!cancel && NS_SUCCEEDED(result)) + { + result = nsEditor::Undo(aCount); + result = mRules->DidDoAction(selection, &ruleInfo, result); + } + + EndUpdateViewBatch(); + + return result; +} + + +NS_IMETHODIMP +nsHTMLEditor::Redo(PRUint32 aCount) +{ + nsresult result = NS_OK; + + BeginUpdateViewBatch(); + + nsTextRulesInfo ruleInfo(nsTextEditRules::kRedo); + nsCOMPtr selection; + GetSelection(getter_AddRefs(selection)); + PRBool cancel; + result = mRules->WillDoAction(selection, &ruleInfo, &cancel); + + if (!cancel && NS_SUCCEEDED(result)) + { + result = nsEditor::Redo(aCount); + result = mRules->DidDoAction(selection, &ruleInfo, result); + } + + EndUpdateViewBatch(); + + return result; +} + NS_IMETHODIMP nsHTMLEditor::Cut() { nsCOMPtr selection; @@ -4617,6 +4644,79 @@ nsHTMLEditor::IsSubordinateBlock(nsString &aTag, PRBool &aIsTag) return NS_OK; } +/////////////////////////////////////////////////////////////////////////// +// IsTable: true if node an html table +// +PRBool +nsHTMLEditor::IsTable(nsIDOMNode *node) +{ + NS_PRECONDITION(node, "null node passed to nsHTMLEditor::IsTable"); + nsAutoString tag; + nsEditor::GetTagString(node,tag); + if (tag == "table") + { + return PR_TRUE; + } + return PR_FALSE; +} + + +/////////////////////////////////////////////////////////////////////////// +// IsTableCell: true if node an html td +// +PRBool +nsHTMLEditor::IsTableCell(nsIDOMNode *node) +{ + NS_PRECONDITION(node, "null node passed to nsHTMLEditor::IsTableCell"); + nsAutoString tag; + nsEditor::GetTagString(node,tag); + if (tag == "td") + { + return PR_TRUE; + } + return PR_FALSE; +} + + +/////////////////////////////////////////////////////////////////////////// +// IsTableElement: true if node an html table, td, tr, ... +// +PRBool +nsHTMLEditor::IsTableElement(nsIDOMNode *node) +{ + NS_PRECONDITION(node, "null node passed to nsHTMLEditor::IsTableElement"); + nsAutoString tagName; + nsEditor::GetTagString(node,tagName); + if (tagName == "table" || tagName == "tr" || + tagName == "td" || tagName == "th" || + tagName == "thead" || tagName == "tfoot" || + tagName == "tbody" || tagName == "caption") + { + return PR_TRUE; + } + return PR_FALSE; +} + + +/////////////////////////////////////////////////////////////////////////// +// GetEnclosingTable: find ancestor who is a table, if any +// +nsCOMPtr +nsHTMLEditor::GetEnclosingTable(nsIDOMNode *aNode) +{ + NS_PRECONDITION(aNode, "null node passed to nsHTMLEditor::GetEnclosingTable"); + nsCOMPtr tbl, tmp, node = aNode; + + while (!tbl) + { + tmp = GetBlockNodeParent(node); + if (!tmp) break; + if (IsTable(tmp)) tbl = tmp; + node = tmp; + } + return tbl; +} + NS_IMETHODIMP nsHTMLEditor::DeleteSelectionAndPrepareToCreateNode(nsCOMPtr &parentSelectedNode, PRInt32& offsetOfNewNode) diff --git a/editor/libeditor/html/nsHTMLEditor.h b/editor/libeditor/html/nsHTMLEditor.h index 0dac4f604f5..6e0d3673043 100644 --- a/editor/libeditor/html/nsHTMLEditor.h +++ b/editor/libeditor/html/nsHTMLEditor.h @@ -182,6 +182,9 @@ public: NS_IMETHOD GetFlags(PRUint32 *aFlags); NS_IMETHOD SetFlags(PRUint32 aFlags); + NS_IMETHOD Undo(PRUint32 aCount); + NS_IMETHOD Redo(PRUint32 aCount); + NS_IMETHOD Cut(); NS_IMETHOD Copy(); NS_IMETHOD Paste(); @@ -288,6 +291,10 @@ protected: NS_IMETHOD IsSubordinateBlock(nsString &aTag, PRBool &aIsTag); + static PRBool IsTable(nsIDOMNode *aNode); + static PRBool IsTableCell(nsIDOMNode *aNode); + static PRBool IsTableElement(nsIDOMNode *aNode); + static nsCOMPtr GetEnclosingTable(nsIDOMNode *aNode); /** content-based query returns PR_TRUE if effects aNode * If contains aNode,