Bug 1484113 - part 1: Create HTMLEditor::GetFirstTableRowElement() for internal use of nsITableEditor::GetFirstRow() r=m_kato

nsITableEditor::GetFirstRow() is an XPCOM method, so, for internal use,
we should create non-virtual method, that is GetFirstTableRowElement().

This patch makes it never return NS_SUCCESS_EDITOR_ELEMENT_NOT_FOUND since
nobody refers it and it's detectable.  If the method returns nullptr without
error, it's the case of NS_SUCCESS_EDITOR_ELEMENT_NOT_FOUND.

Additionally, this patch changes the return type of GetFirstRow() from
Node to Element since it always return an Element node if not null.

Differential Revision: https://phabricator.services.mozilla.com/D3780

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Masayuki Nakano 2018-08-22 01:20:23 +00:00
Родитель 56de772ab3
Коммит 57ac6bcbf2
4 изменённых файлов: 85 добавлений и 45 удалений

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

@ -2561,7 +2561,7 @@ HTMLEditor::Align(const nsAString& aAlignType)
Element* Element*
HTMLEditor::GetElementOrParentByTagName(const nsAtom& aTagName, HTMLEditor::GetElementOrParentByTagName(const nsAtom& aTagName,
nsINode* aNode) nsINode* aNode) const
{ {
MOZ_ASSERT(&aTagName != nsGkAtoms::_empty); MOZ_ASSERT(&aTagName != nsGkAtoms::_empty);
@ -2577,7 +2577,7 @@ HTMLEditor::GetElementOrParentByTagName(const nsAtom& aTagName,
Element* Element*
HTMLEditor::GetElementOrParentByTagNameAtSelection(Selection& aSelection, HTMLEditor::GetElementOrParentByTagNameAtSelection(Selection& aSelection,
const nsAtom& aTagName) const nsAtom& aTagName) const
{ {
MOZ_ASSERT(&aTagName != nsGkAtoms::_empty); MOZ_ASSERT(&aTagName != nsGkAtoms::_empty);
@ -2605,7 +2605,7 @@ HTMLEditor::GetElementOrParentByTagNameAtSelection(Selection& aSelection,
Element* Element*
HTMLEditor::GetElementOrParentByTagNameInternal(const nsAtom& aTagName, HTMLEditor::GetElementOrParentByTagNameInternal(const nsAtom& aTagName,
nsINode& aNode) nsINode& aNode) const
{ {
MOZ_ASSERT(&aTagName != nsGkAtoms::_empty); MOZ_ASSERT(&aTagName != nsGkAtoms::_empty);

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

@ -402,7 +402,7 @@ public:
* an Element. Otherwise, nullptr. * an Element. Otherwise, nullptr.
*/ */
Element* Element*
GetElementOrParentByTagName(const nsAtom& aTagName, nsINode* aNode); GetElementOrParentByTagName(const nsAtom& aTagName, nsINode* aNode) const;
/** /**
* Get an active editor's editing host in DOM window. If this editor isn't * Get an active editor's editing host in DOM window. If this editor isn't
@ -912,7 +912,7 @@ protected: // Shouldn't be used by friend classes
*/ */
Element* Element*
GetElementOrParentByTagNameAtSelection(Selection& aSelection, GetElementOrParentByTagNameAtSelection(Selection& aSelection,
const nsAtom& aTagName); const nsAtom& aTagName) const;
/** /**
* GetElementOrParentByTagNameInternal() looks for an element node whose * GetElementOrParentByTagNameInternal() looks for an element node whose
@ -933,7 +933,7 @@ protected: // Shouldn't be used by friend classes
*/ */
Element* Element*
GetElementOrParentByTagNameInternal(const nsAtom& aTagName, GetElementOrParentByTagNameInternal(const nsAtom& aTagName,
nsINode& aNode); nsINode& aNode) const;
/** /**
* GetSelectedElement() returns an element node which is in first range of * GetSelectedElement() returns an element node which is in first range of
@ -972,6 +972,26 @@ protected: // Shouldn't be used by friend classes
const nsAtom* aTagName, const nsAtom* aTagName,
ErrorResult& aRv); ErrorResult& aRv);
/**
* GetFirstTableRowElement() returns the first <tr> element in the most
* nearest ancestor of aTableOrElementInTable or itself.
*
* @param aTableOrElementInTable <table> element or another element.
* If this is a <table> element, returns
* first <tr> element in it. Otherwise,
* returns first <tr> element in nearest
* ancestor <table> element.
* @param aRv Returns an error code. When
* aTableOrElementInTable is neither
* <table> nor in a <table> element,
* returns NS_ERROR_FAILURE.
* However, if <table> does not have
* <tr> element, returns NS_OK.
*/
Element*
GetFirstTableRowElement(Element& aTableOrElementInTable,
ErrorResult& aRv) const;
/** /**
* PasteInternal() pasts text with replacing selected content. * PasteInternal() pasts text with replacing selected content.
* This tries to dispatch ePaste event first. If its defaultPrevent() is * This tries to dispatch ePaste event first. If its defaultPrevent() is

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

@ -221,52 +221,60 @@ HTMLEditor::InsertTableCell(int32_t aNumber,
} }
NS_IMETHODIMP NS_IMETHODIMP
HTMLEditor::GetFirstRow(Element* aTableElement, HTMLEditor::GetFirstRow(Element* aTableOrElementInTable,
nsINode** aRowNode) Element** aFirstRowElement)
{ {
if (NS_WARN_IF(!aTableElement) || NS_WARN_IF(!aRowNode)) { if (NS_WARN_IF(!aTableOrElementInTable) || NS_WARN_IF(!aFirstRowElement)) {
return NS_ERROR_INVALID_ARG; return NS_ERROR_INVALID_ARG;
} }
ErrorResult error;
RefPtr<Element> firstRowElement =
GetFirstTableRowElement(*aTableOrElementInTable, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
firstRowElement.forget(aFirstRowElement);
return NS_OK;
}
*aRowNode = nullptr; Element*
HTMLEditor::GetFirstTableRowElement(Element& aTableOrElementInTable,
ErrorResult& aRv) const
{
MOZ_ASSERT(!aRv.Failed());
Element* tableElement = Element* tableElement =
GetElementOrParentByTagNameInternal(*nsGkAtoms::table, *aTableElement); GetElementOrParentByTagNameInternal(*nsGkAtoms::table,
aTableOrElementInTable);
// If the element is not in <table>, return error.
if (NS_WARN_IF(!tableElement)) { if (NS_WARN_IF(!tableElement)) {
return NS_ERROR_FAILURE; aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
} }
nsCOMPtr<nsIContent> tableChild = tableElement->GetFirstChild(); for (nsIContent* tableChild = tableElement->GetFirstChild();
while (tableChild) { tableChild;
tableChild = tableChild->GetNextSibling()) {
if (tableChild->IsHTMLElement(nsGkAtoms::tr)) { if (tableChild->IsHTMLElement(nsGkAtoms::tr)) {
// Found a row directly under <table> // Found a row directly under <table>
tableChild.forget(aRowNode); return tableChild->AsElement();
return NS_OK;
} }
// Look for row in one of the row container elements // <table> can have table section elements like <tbody>. <tr> elements
// may be children of them.
if (tableChild->IsAnyOfHTMLElements(nsGkAtoms::tbody, if (tableChild->IsAnyOfHTMLElements(nsGkAtoms::tbody,
nsGkAtoms::thead, nsGkAtoms::thead,
nsGkAtoms::tfoot)) { nsGkAtoms::tfoot)) {
nsCOMPtr<nsIContent> rowNode = tableChild->GetFirstChild(); for (nsIContent* tableSectionChild = tableChild->GetFirstChild();
tableSectionChild;
// We can encounter textnodes here -- must find a row tableSectionChild = tableSectionChild->GetNextSibling()) {
while (rowNode && !HTMLEditUtils::IsTableRow(rowNode)) { if (tableSectionChild->IsHTMLElement(nsGkAtoms::tr)) {
rowNode = rowNode->GetNextSibling(); return tableSectionChild->AsElement();
} }
if (rowNode) {
rowNode.forget(aRowNode);
return NS_OK;
} }
} }
// Here if table child was a CAPTION or COLGROUP
// or child of a row parent wasn't a row (bad HTML?),
// or first child was a textnode
// Look in next table child
tableChild = tableChild->GetNextSibling();
} }
// If here, row was not found // Don't return error when there is no <tr> element in the <table>.
return NS_SUCCESS_EDITOR_ELEMENT_NOT_FOUND; return nullptr;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -442,9 +450,10 @@ HTMLEditor::InsertTableColumn(int32_t aNumber,
} else { } else {
// Get current row and append new cells after last cell in row // Get current row and append new cells after last cell in row
if (!rowIndex) { if (!rowIndex) {
rv = GetFirstRow(table, getter_AddRefs(rowNode)); ErrorResult error;
if (NS_WARN_IF(NS_FAILED(rv))) { rowNode = GetFirstTableRowElement(*table, error);
return rv; if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
} }
} else { } else {
nsCOMPtr<nsINode> nextRow; nsCOMPtr<nsINode> nextRow;

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

@ -203,14 +203,25 @@ interface nsITableEditor : nsISupports
out long aActualRowSpan, out long aActualColSpan, out long aActualRowSpan, out long aActualColSpan,
out boolean aIsSelected); out boolean aIsSelected);
/** Get the first row element in a table /**
* * getFirstRow() returns first <tr> element in a <table> element.
* @return The row at the requested index *
* Returns null if there are no rows in table * @param aTableOrElementInTable If a <table> element, returns its first
* (in C++ returns: NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found * <tr> element.
* passes NS_SUCCEEDED macro) * If another element, looks for nearest
*/ * ancestor <table> element first. Then,
Node getFirstRow(in Element aTableElement); * return its first <tr> element.
* @return <tr> element in the <table> element.
* If <table> element is not found, this
* throws an exception.
* If there is a <table> element but it
* does not have <tr> elements, returns
* null without throwing exception.
* Note that this may return anonymous <tr>
* element if <table> has one or more cells
* but <tr> element is not in the source.
*/
Element getFirstRow(in Element aTableElement);
/** Get the next row element starting the search from aTableElement /** Get the next row element starting the search from aTableElement
* *