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*
HTMLEditor::GetElementOrParentByTagName(const nsAtom& aTagName,
nsINode* aNode)
nsINode* aNode) const
{
MOZ_ASSERT(&aTagName != nsGkAtoms::_empty);
@ -2577,7 +2577,7 @@ HTMLEditor::GetElementOrParentByTagName(const nsAtom& aTagName,
Element*
HTMLEditor::GetElementOrParentByTagNameAtSelection(Selection& aSelection,
const nsAtom& aTagName)
const nsAtom& aTagName) const
{
MOZ_ASSERT(&aTagName != nsGkAtoms::_empty);
@ -2605,7 +2605,7 @@ HTMLEditor::GetElementOrParentByTagNameAtSelection(Selection& aSelection,
Element*
HTMLEditor::GetElementOrParentByTagNameInternal(const nsAtom& aTagName,
nsINode& aNode)
nsINode& aNode) const
{
MOZ_ASSERT(&aTagName != nsGkAtoms::_empty);

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

@ -402,7 +402,7 @@ public:
* an Element. Otherwise, nullptr.
*/
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
@ -912,7 +912,7 @@ protected: // Shouldn't be used by friend classes
*/
Element*
GetElementOrParentByTagNameAtSelection(Selection& aSelection,
const nsAtom& aTagName);
const nsAtom& aTagName) const;
/**
* GetElementOrParentByTagNameInternal() looks for an element node whose
@ -933,7 +933,7 @@ protected: // Shouldn't be used by friend classes
*/
Element*
GetElementOrParentByTagNameInternal(const nsAtom& aTagName,
nsINode& aNode);
nsINode& aNode) const;
/**
* 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,
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.
* This tries to dispatch ePaste event first. If its defaultPrevent() is

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

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

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

@ -203,14 +203,25 @@ interface nsITableEditor : nsISupports
out long aActualRowSpan, out long aActualColSpan,
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
* (in C++ returns: NS_EDITOR_ELEMENT_NOT_FOUND if an element is not found
* passes NS_SUCCEEDED macro)
* @param aTableOrElementInTable If a <table> element, returns its first
* <tr> element.
* If another element, looks for nearest
* ancestor <table> element first. Then,
* 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.
*/
Node getFirstRow(in Element aTableElement);
Element getFirstRow(in Element aTableElement);
/** Get the next row element starting the search from aTableElement
*