diff --git a/editor/libeditor/html/nsHTMLEditRules.cpp b/editor/libeditor/html/nsHTMLEditRules.cpp
index 10782cfbda3..d1811d1615c 100644
--- a/editor/libeditor/html/nsHTMLEditRules.cpp
+++ b/editor/libeditor/html/nsHTMLEditRules.cpp
@@ -2942,10 +2942,10 @@ nsHTMLEditRules::DidDeleteSelection(nsISelection *aSelection,
res = GetTopEnclosingMailCite(startNode, address_of(citeNode),
IsPlaintextEditor());
NS_ENSURE_SUCCESS(res, res);
- if (citeNode)
- {
+ if (citeNode) {
+ nsCOMPtr cite = do_QueryInterface(citeNode);
bool isEmpty = true, seenBR = false;
- mHTMLEditor->IsEmptyNodeImpl(citeNode, &isEmpty, true, true, false, &seenBR);
+ mHTMLEditor->IsEmptyNodeImpl(cite, &isEmpty, true, true, false, &seenBR);
if (isEmpty)
{
nsCOMPtr parent, brNode;
diff --git a/editor/libeditor/html/nsHTMLEditUtils.cpp b/editor/libeditor/html/nsHTMLEditUtils.cpp
index 45fb5dc14b4..da636ffbb56 100644
--- a/editor/libeditor/html/nsHTMLEditUtils.cpp
+++ b/editor/libeditor/html/nsHTMLEditUtils.cpp
@@ -35,9 +35,12 @@
*
* ***** END LICENSE BLOCK ***** */
-#include "mozilla/Util.h"
-
#include "nsHTMLEditUtils.h"
+
+#include "mozilla/Assertions.h"
+#include "mozilla/Util.h"
+#include "mozilla/dom/Element.h"
+
#include "nsTextEditUtils.h"
#include "nsString.h"
@@ -177,7 +180,15 @@ bool
nsHTMLEditUtils::IsListItem(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null parent passed to nsHTMLEditUtils::IsListItem");
- nsCOMPtr nodeAtom = nsEditor::GetTag(node);
+ nsCOMPtr element = do_QueryInterface(node);
+ return element && IsListItem(element);
+}
+
+bool
+nsHTMLEditUtils::IsListItem(dom::Element* node)
+{
+ MOZ_ASSERT(node);
+ nsCOMPtr nodeAtom = node->Tag();
return (nodeAtom == nsEditProperty::li)
|| (nodeAtom == nsEditProperty::dd)
|| (nodeAtom == nsEditProperty::dt);
@@ -245,7 +256,15 @@ bool
nsHTMLEditUtils::IsTableCell(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null parent passed to nsHTMLEditUtils::IsTableCell");
- nsCOMPtr nodeAtom = nsEditor::GetTag(node);
+ nsCOMPtr element = do_QueryInterface(node);
+ return element && IsTableCell(element);
+}
+
+bool
+nsHTMLEditUtils::IsTableCell(dom::Element* node)
+{
+ MOZ_ASSERT(node);
+ nsCOMPtr nodeAtom = node->Tag();
return (nodeAtom == nsEditProperty::td)
|| (nodeAtom == nsEditProperty::th);
}
@@ -268,11 +287,19 @@ nsHTMLEditUtils::IsTableCellOrCaption(nsIDOMNode *node)
///////////////////////////////////////////////////////////////////////////
// IsList: true if node an html list
//
-bool
+bool
nsHTMLEditUtils::IsList(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null parent passed to nsHTMLEditUtils::IsList");
- nsCOMPtr nodeAtom = nsEditor::GetTag(node);
+ nsCOMPtr element = do_QueryInterface(node);
+ return element && IsList(element);
+}
+
+bool
+nsHTMLEditUtils::IsList(dom::Element* node)
+{
+ MOZ_ASSERT(node);
+ nsCOMPtr nodeAtom = node->Tag();
return (nodeAtom == nsEditProperty::ul)
|| (nodeAtom == nsEditProperty::ol)
|| (nodeAtom == nsEditProperty::dl);
@@ -345,15 +372,21 @@ nsHTMLEditUtils::IsLink(nsIDOMNode *aNode)
bool
nsHTMLEditUtils::IsNamedAnchor(nsIDOMNode *aNode)
{
- NS_ENSURE_TRUE(aNode, false);
- nsCOMPtr anchor = do_QueryInterface(aNode);
- if (anchor)
- {
- nsAutoString tmpText;
- if (NS_SUCCEEDED(anchor->GetName(tmpText)) && !tmpText.IsEmpty())
- return true;
+ nsCOMPtr element = do_QueryInterface(aNode);
+ return element && IsNamedAnchor(element);
+}
+
+bool
+nsHTMLEditUtils::IsNamedAnchor(dom::Element* aNode)
+{
+ MOZ_ASSERT(aNode);
+ if (!aNode->IsHTML(nsGkAtoms::a)) {
+ return false;
}
- return false;
+
+ nsAutoString text;
+ return aNode->GetAttr(kNameSpaceID_None, nsGkAtoms::name, text) &&
+ !text.IsEmpty();
}
@@ -419,11 +452,19 @@ nsHTMLEditUtils::IsMailCite(nsIDOMNode *node)
///////////////////////////////////////////////////////////////////////////
// IsFormWidget: true if node is a form widget of some kind
//
-bool
+bool
nsHTMLEditUtils::IsFormWidget(nsIDOMNode *node)
{
NS_PRECONDITION(node, "null node passed to nsHTMLEditUtils::IsFormWidget");
- nsCOMPtr nodeAtom = nsEditor::GetTag(node);
+ nsCOMPtr element = do_QueryInterface(node);
+ return element && IsFormWidget(element);
+}
+
+bool
+nsHTMLEditUtils::IsFormWidget(dom::Element* node)
+{
+ MOZ_ASSERT(node);
+ nsCOMPtr nodeAtom = node->Tag();
return (nodeAtom == nsEditProperty::textarea)
|| (nodeAtom == nsEditProperty::select)
|| (nodeAtom == nsEditProperty::button)
diff --git a/editor/libeditor/html/nsHTMLEditUtils.h b/editor/libeditor/html/nsHTMLEditUtils.h
index 4543f6d6771..5da26773737 100644
--- a/editor/libeditor/html/nsHTMLEditUtils.h
+++ b/editor/libeditor/html/nsHTMLEditUtils.h
@@ -40,6 +40,12 @@
#include "prtypes.h" // for PRInt32
+namespace mozilla {
+namespace dom {
+class Element;
+} // namespace dom
+} // namespace mozilla
+
class nsIDOMNode;
class nsHTMLEditUtils
@@ -56,13 +62,16 @@ public:
static bool IsHeader(nsIDOMNode *aNode);
static bool IsParagraph(nsIDOMNode *aNode);
static bool IsHR(nsIDOMNode *aNode);
+ static bool IsListItem(mozilla::dom::Element* aNode);
static bool IsListItem(nsIDOMNode *aNode);
static bool IsTable(nsIDOMNode *aNode);
static bool IsTableRow(nsIDOMNode *aNode);
static bool IsTableElement(nsIDOMNode *aNode);
static bool IsTableElementButNotTable(nsIDOMNode *aNode);
+ static bool IsTableCell(mozilla::dom::Element* node);
static bool IsTableCell(nsIDOMNode *aNode);
static bool IsTableCellOrCaption(nsIDOMNode *aNode);
+ static bool IsList(mozilla::dom::Element* aNode);
static bool IsList(nsIDOMNode *aNode);
static bool IsOrderedList(nsIDOMNode *aNode);
static bool IsUnorderedList(nsIDOMNode *aNode);
@@ -71,10 +80,12 @@ public:
static bool IsAnchor(nsIDOMNode *aNode);
static bool IsImage(nsIDOMNode *aNode);
static bool IsLink(nsIDOMNode *aNode);
+ static bool IsNamedAnchor(mozilla::dom::Element* aNode);
static bool IsNamedAnchor(nsIDOMNode *aNode);
static bool IsDiv(nsIDOMNode *aNode);
static bool IsMozDiv(nsIDOMNode *aNode);
static bool IsMailCite(nsIDOMNode *aNode);
+ static bool IsFormWidget(mozilla::dom::Element* aNode);
static bool IsFormWidget(nsIDOMNode *aNode);
static bool SupportsAlignAttr(nsIDOMNode *aNode);
static bool CanContain(PRInt32 aParent, PRInt32 aChild);
diff --git a/editor/libeditor/html/nsHTMLEditor.cpp b/editor/libeditor/html/nsHTMLEditor.cpp
index 10315b3c01d..dec29f54895 100644
--- a/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/editor/libeditor/html/nsHTMLEditor.cpp
@@ -3953,7 +3953,14 @@ nsHTMLEditor::TagCanContainTag(const nsAString& aParentTag, const nsAString& aCh
return nsHTMLEditUtils::CanContain(parentTagEnum, childTagEnum);
}
-bool
+bool
+nsHTMLEditor::IsContainer(nsINode* aNode)
+{
+ nsCOMPtr node = do_QueryInterface(aNode);
+ return IsContainer(node);
+}
+
+bool
nsHTMLEditor::IsContainer(nsIDOMNode *aNode)
{
if (!aNode) {
@@ -4773,13 +4780,10 @@ bool
nsHTMLEditor::IsTextInDirtyFrameVisible(nsIContent *aNode)
{
bool isEmptyTextNode;
- nsCOMPtr node = do_QueryInterface(aNode);
- nsresult res = IsVisTextNode(node, &isEmptyTextNode, false);
- if (NS_FAILED(res))
- {
+ nsresult rv = IsVisTextNode(aNode, &isEmptyTextNode, false);
+ if (NS_FAILED(rv)) {
// We are following the historical decision:
// if we don't know, we say it's visible...
-
return true;
}
@@ -4790,6 +4794,15 @@ nsHTMLEditor::IsTextInDirtyFrameVisible(nsIContent *aNode)
///////////////////////////////////////////////////////////////////////////
// IsVisTextNode: figure out if textnode aTextNode has any visible content.
//
+nsresult
+nsHTMLEditor::IsVisTextNode(nsIContent* aNode,
+ bool* outIsEmptyNode,
+ bool aSafeToAskFrames)
+{
+ nsCOMPtr node = do_QueryInterface(aNode);
+ return IsVisTextNode(node);
+}
+
nsresult
nsHTMLEditor::IsVisTextNode( nsIDOMNode* aNode,
bool *outIsEmptyNode,
@@ -4861,10 +4874,11 @@ nsHTMLEditor::IsEmptyNode( nsIDOMNode *aNode,
bool aListOrCellNotEmpty,
bool aSafeToAskFrames)
{
- NS_ENSURE_TRUE(aNode && outIsEmptyNode, NS_ERROR_NULL_POINTER);
+ nsCOMPtr node = do_QueryInterface(aNode);
+ NS_ENSURE_TRUE(node && outIsEmptyNode, NS_ERROR_NULL_POINTER);
*outIsEmptyNode = true;
bool seenBR = false;
- return IsEmptyNodeImpl(aNode, outIsEmptyNode, aSingleBRDoesntCount,
+ return IsEmptyNodeImpl(node, outIsEmptyNode, aSingleBRDoesntCount,
aListOrCellNotEmpty, aSafeToAskFrames, &seenBR);
}
@@ -4872,20 +4886,17 @@ nsHTMLEditor::IsEmptyNode( nsIDOMNode *aNode,
// IsEmptyNodeImpl: workhorse for IsEmptyNode.
//
nsresult
-nsHTMLEditor::IsEmptyNodeImpl( nsIDOMNode *aNode,
- bool *outIsEmptyNode,
- bool aSingleBRDoesntCount,
- bool aListOrCellNotEmpty,
- bool aSafeToAskFrames,
- bool *aSeenBR)
+nsHTMLEditor::IsEmptyNodeImpl(nsINode* aNode,
+ bool *outIsEmptyNode,
+ bool aSingleBRDoesntCount,
+ bool aListOrCellNotEmpty,
+ bool aSafeToAskFrames,
+ bool *aSeenBR)
{
NS_ENSURE_TRUE(aNode && outIsEmptyNode && aSeenBR, NS_ERROR_NULL_POINTER);
- nsresult res = NS_OK;
- if (nsEditor::IsTextNode(aNode))
- {
- res = IsVisTextNode(aNode, outIsEmptyNode, aSafeToAskFrames);
- return res;
+ if (aNode->NodeType() == nsIDOMNode::TEXT_NODE) {
+ return IsVisTextNode(static_cast(aNode), outIsEmptyNode, aSafeToAskFrames);
}
// if it's not a text node (handled above) and it's not a container,
@@ -4894,74 +4905,72 @@ nsHTMLEditor::IsEmptyNodeImpl( nsIDOMNode *aNode,
// anchors are containers, named anchors are "empty" but we don't
// want to treat them as such. Also, don't call ListItems or table
// cells empty if caller desires. Form Widgets not empty.
- if (!IsContainer(aNode) || nsHTMLEditUtils::IsNamedAnchor(aNode) ||
- nsHTMLEditUtils::IsFormWidget(aNode) ||
- (aListOrCellNotEmpty && nsHTMLEditUtils::IsListItem(aNode)) ||
- (aListOrCellNotEmpty && nsHTMLEditUtils::IsTableCell(aNode)) )
- {
+ if (!IsContainer(aNode) ||
+ (aNode->IsElement() &&
+ (nsHTMLEditUtils::IsNamedAnchor(aNode->AsElement()) ||
+ nsHTMLEditUtils::IsFormWidget(aNode->AsElement()) ||
+ (aListOrCellNotEmpty &&
+ (nsHTMLEditUtils::IsListItem(aNode->AsElement()) ||
+ nsHTMLEditUtils::IsTableCell(aNode->AsElement())))))) {
*outIsEmptyNode = false;
return NS_OK;
}
// need this for later
- bool isListItemOrCell =
- nsHTMLEditUtils::IsListItem(aNode) || nsHTMLEditUtils::IsTableCell(aNode);
+ bool isListItemOrCell = aNode->IsElement() &&
+ (nsHTMLEditUtils::IsListItem(aNode->AsElement()) ||
+ nsHTMLEditUtils::IsTableCell(aNode->AsElement()));
// loop over children of node. if no children, or all children are either
// empty text nodes or non-editable, then node qualifies as empty
- nsCOMPtr child;
- aNode->GetFirstChild(getter_AddRefs(child));
-
- while (child)
- {
- nsCOMPtr node = child;
- // is the node editable and non-empty? if so, return false
- if (nsEditor::IsEditable(node))
- {
- if (nsEditor::IsTextNode(node))
- {
- res = IsVisTextNode(node, outIsEmptyNode, aSafeToAskFrames);
- NS_ENSURE_SUCCESS(res, res);
+ for (nsCOMPtr child = aNode->GetFirstChild();
+ child;
+ child = child->GetNextSibling()) {
+ // Is the child editable and non-empty? if so, return false
+ if (nsEditor::IsEditable(child)) {
+ if (child->NodeType() == nsIDOMNode::TEXT_NODE) {
+ nsresult rv = IsVisTextNode(child, outIsEmptyNode, aSafeToAskFrames);
+ NS_ENSURE_SUCCESS(rv, rv);
// break out if we find we aren't emtpy
if (!*outIsEmptyNode) {
return NS_OK;
}
- }
- else // an editable, non-text node. we need to check it's content.
- {
- // is it the node we are iterating over?
- if (node == aNode) break;
- else if (aSingleBRDoesntCount && !*aSeenBR && nsTextEditUtils::IsBreak(node))
- {
+ } else {
+ // An editable, non-text node. We need to check its content.
+ // Is it the node we are iterating over?
+ if (child == aNode) {
+ break;
+ }
+
+ if (aSingleBRDoesntCount && !*aSeenBR && child->IsHTML(nsGkAtoms::br)) {
// the first br in a block doesn't count if the caller so indicated
*aSeenBR = true;
- }
- else
- {
+ } else {
// is it an empty node of some sort?
// note: list items or table cells are not considered empty
// if they contain other lists or tables
- if (isListItemOrCell)
- {
- if (nsHTMLEditUtils::IsList(node) || nsHTMLEditUtils::IsTable(node))
- { // break out if we find we aren't empty
+ if (child->IsElement()) {
+ if (isListItemOrCell) {
+ if (nsHTMLEditUtils::IsList(child->AsElement()) || child->IsHTML(nsGkAtoms::table)) {
+ // break out if we find we aren't empty
+ *outIsEmptyNode = false;
+ return NS_OK;
+ }
+ } else if (nsHTMLEditUtils::IsFormWidget(child->AsElement())) {
+ // is it a form widget?
+ // break out if we find we aren't empty
*outIsEmptyNode = false;
return NS_OK;
}
}
- // is it a form widget?
- else if (nsHTMLEditUtils::IsFormWidget(node))
- { // break out if we find we aren't empty
- *outIsEmptyNode = false;
- return NS_OK;
- }
-
+
bool isEmptyNode = true;
- res = IsEmptyNodeImpl(node, &isEmptyNode, aSingleBRDoesntCount,
- aListOrCellNotEmpty, aSafeToAskFrames, aSeenBR);
- NS_ENSURE_SUCCESS(res, res);
- if (!isEmptyNode)
- {
+ nsresult rv = IsEmptyNodeImpl(child, &isEmptyNode,
+ aSingleBRDoesntCount,
+ aListOrCellNotEmpty, aSafeToAskFrames,
+ aSeenBR);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!isEmptyNode) {
// otherwise it ain't empty
*outIsEmptyNode = false;
return NS_OK;
@@ -4969,7 +4978,6 @@ nsHTMLEditor::IsEmptyNodeImpl( nsIDOMNode *aNode,
}
}
}
- node->GetNextSibling(getter_AddRefs(child));
}
return NS_OK;
diff --git a/editor/libeditor/html/nsHTMLEditor.h b/editor/libeditor/html/nsHTMLEditor.h
index 51356971d8f..64ef81a8801 100644
--- a/editor/libeditor/html/nsHTMLEditor.h
+++ b/editor/libeditor/html/nsHTMLEditor.h
@@ -324,6 +324,7 @@ public:
virtual bool TagCanContainTag(const nsAString& aParentTag, const nsAString& aChildTag);
/** returns true if aNode is a container */
+ virtual bool IsContainer(nsINode* aNode);
virtual bool IsContainer(nsIDOMNode *aNode);
/** make the given selection span the entire document */
@@ -387,6 +388,9 @@ public:
virtual bool IsTextInDirtyFrameVisible(nsIContent *aNode);
+ nsresult IsVisTextNode(nsIContent* aNode,
+ bool* outIsEmptyNode,
+ bool aSafeToAskFrames);
nsresult IsVisTextNode( nsIDOMNode *aNode,
bool *outIsEmptyNode,
bool aSafeToAskFrames);
@@ -394,7 +398,7 @@ public:
bool aMozBRDoesntCount = false,
bool aListOrCellNotEmpty = false,
bool aSafeToAskFrames = false);
- nsresult IsEmptyNodeImpl(nsIDOMNode *aNode,
+ nsresult IsEmptyNodeImpl(nsINode* aNode,
bool *outIsEmptyBlock,
bool aMozBRDoesntCount,
bool aListOrCellNotEmpty,