Backed out 7 changesets (bug 1730442) for causing reftest failures in editor/reftests/inline-table-editor-position-after-updating-table-size-from-input-event-listener.html. CLOSED TREE

Backed out changeset f6d7f162e57a (bug 1730442)
Backed out changeset e5d1671b3bbc (bug 1730442)
Backed out changeset e60a5cd69184 (bug 1730442)
Backed out changeset 943d4e4b0770 (bug 1730442)
Backed out changeset bd3324b635f4 (bug 1730442)
Backed out changeset ada0dda5bcde (bug 1730442)
Backed out changeset b67c4035c12f (bug 1730442)
This commit is contained in:
Molnar Sandor 2022-05-17 04:23:36 +03:00
parent b1015d9c01
commit 416e516586
21 changed files with 678 additions and 995 deletions

View File

@ -228,23 +228,6 @@ enum class EditAction {
// <td> or <th>.
eSetTableCellElementType,
// Those edit actions are mapped to the methods in nsITableEditor which
// access table layout information.
eSelectTableCell,
eSelectTableRow,
eSelectTableColumn,
eSelectTable,
eSelectAllTableCells,
eGetCellIndexes,
eGetTableSize,
eGetCellAt,
eGetCellDataAt,
eGetFirstRow,
eGetSelectedOrParentTableElement,
eGetSelectedCellsType,
eGetFirstSelectedCellInTable,
eGetSelectedCells,
// eSetInlineStyleProperty indicates to set CSS another inline style property
// which is not defined below.
eSetInlineStyleProperty,
@ -493,26 +476,6 @@ enum class EditSubAction : int32_t {
eCreatePaddingBRElementForEmptyEditor,
};
// You can use this macro as:
// case NS_EDIT_ACTION_CASES_ACCESSING_TABLE_DATA_WITHOUT_EDITING:
// clang-format off
#define NS_EDIT_ACTION_CASES_ACCESSING_TABLE_DATA_WITHOUT_EDITING \
mozilla::EditAction::eSelectTableCell: \
case mozilla::EditAction::eSelectTableRow: \
case mozilla::EditAction::eSelectTableColumn: \
case mozilla::EditAction::eSelectTable: \
case mozilla::EditAction::eSelectAllTableCells: \
case mozilla::EditAction::eGetCellIndexes: \
case mozilla::EditAction::eGetTableSize: \
case mozilla::EditAction::eGetCellAt: \
case mozilla::EditAction::eGetCellDataAt: \
case mozilla::EditAction::eGetFirstRow: \
case mozilla::EditAction::eGetSelectedOrParentTableElement: \
case mozilla::EditAction::eGetSelectedCellsType: \
case mozilla::EditAction::eGetFirstSelectedCellInTable: \
case mozilla::EditAction::eGetSelectedCells
// clang-format on
inline EditorInputType ToInputType(EditAction aEditAction) {
switch (aEditAction) {
case EditAction::eInsertText:
@ -649,16 +612,6 @@ inline bool MayEditActionDeleteAroundCollapsedSelection(
}
}
inline bool IsEditActionInOrderToEditSomething(const EditAction aEditAction) {
switch (aEditAction) {
case EditAction::eNotEditing:
case NS_EDIT_ACTION_CASES_ACCESSING_TABLE_DATA_WITHOUT_EDITING:
return false;
default:
return true;
}
}
inline bool IsEditActionTableEditing(const EditAction aEditAction) {
switch (aEditAction) {
case EditAction::eInsertTableRowElement:
@ -683,7 +636,6 @@ inline bool MayEditActionDeleteSelection(const EditAction aEditAction) {
case EditAction::eNone:
case EditAction::eNotEditing:
case EditAction::eInitializing:
case NS_EDIT_ACTION_CASES_ACCESSING_TABLE_DATA_WITHOUT_EDITING:
return false;
// EditActions modifying around selection.
@ -827,28 +779,6 @@ inline bool MayEditActionDeleteSelection(const EditAction aEditAction) {
return false;
}
inline bool MayEditActionRequireLayout(const EditAction aEditAction) {
switch (aEditAction) {
// Table editing require layout information for referring table cell data
// such as row/column number and rowspan/colspan.
case EditAction::eInsertTableRowElement:
case EditAction::eRemoveTableRowElement:
case EditAction::eInsertTableColumn:
case EditAction::eRemoveTableColumn:
case EditAction::eRemoveTableElement:
case EditAction::eRemoveTableCellElement:
case EditAction::eDeleteTableCellContents:
case EditAction::eInsertTableCellElement:
case EditAction::eJoinTableCellElements:
case EditAction::eSplitTableCellElement:
case EditAction::eSetTableCellElementType:
case NS_EDIT_ACTION_CASES_ACCESSING_TABLE_DATA_WITHOUT_EDITING:
return true;
default:
return false;
}
}
} // namespace mozilla
inline bool operator!(const mozilla::EditSubAction& aEditSubAction) {

View File

@ -6066,7 +6066,6 @@ EditorBase::AutoEditActionDataSetter::AutoEditActionDataSetter(
mPrincipal(aPrincipal),
mParentData(aEditorBase.mEditActionData),
mData(VoidString()),
mRawEditAction(aEditAction),
mTopLevelEditSubAction(EditSubAction::eNone),
mAborted(false),
mHasTriedToDispatchBeforeInputEvent(false),
@ -6083,10 +6082,10 @@ EditorBase::AutoEditActionDataSetter::AutoEditActionDataSetter(
MOZ_ASSERT(!mSelection ||
(mSelection->GetType() == SelectionType::eNormal));
// If we're not editing something, we should inherit the parent's edit
// action. This may occur if creator or its callee use public methods which
// If we're eNotEditing, we should inherit the parent's edit action.
// This may occur if creator or its callee use public methods which
// just returns something.
if (IsEditActionInOrderToEditSomething(aEditAction)) {
if (aEditAction != EditAction::eNotEditing) {
mEditAction = aEditAction;
} else {
mEditAction = mParentData->mEditAction;
@ -6328,31 +6327,13 @@ bool EditorBase::AutoEditActionDataSetter::IsBeforeInputEventEnabled() const {
return true;
}
nsresult EditorBase::AutoEditActionDataSetter::MaybeFlushPendingNotifications()
const {
MOZ_ASSERT(CanHandle());
if (!MayEditActionRequireLayout(mRawEditAction)) {
return NS_SUCCESS_DOM_NO_OPERATION;
}
OwningNonNull<EditorBase> editorBase = mEditorBase;
RefPtr<PresShell> presShell = editorBase->GetPresShell();
if (MOZ_UNLIKELY(NS_WARN_IF(!presShell))) {
return NS_ERROR_NOT_AVAILABLE;
}
presShell->FlushPendingNotifications(FlushType::Layout);
if (MOZ_UNLIKELY(NS_WARN_IF(editorBase->Destroyed()))) {
return NS_ERROR_EDITOR_DESTROYED;
}
return NS_OK;
}
nsresult EditorBase::AutoEditActionDataSetter::MaybeDispatchBeforeInputEvent(
nsIEditor::EDirection aDeleteDirectionAndAmount /* = nsIEditor::eNone */) {
nsIEditor::EDirection aDeleteDirectionAndAmount /* nsIEditor::eNone */) {
MOZ_ASSERT(!HasTriedToDispatchBeforeInputEvent(),
"We've already handled beforeinput event");
MOZ_ASSERT(CanHandle());
MOZ_ASSERT_IF(IsBeforeInputEventEnabled(),
ShouldAlreadyHaveHandledBeforeInputEventDispatching());
MOZ_ASSERT(!IsBeforeInputEventEnabled() ||
ShouldAlreadyHaveHandledBeforeInputEventDispatching());
MOZ_ASSERT_IF(!MayEditActionDeleteAroundCollapsedSelection(mEditAction),
aDeleteDirectionAndAmount == nsIEditor::eNone);

View File

@ -991,23 +991,11 @@ class EditorBase : public nsIEditor,
}
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
CanHandleAndMaybeDispatchBeforeInputEvent() {
if (MOZ_UNLIKELY(NS_WARN_IF(!CanHandle()))) {
if (NS_WARN_IF(!CanHandle())) {
return NS_ERROR_NOT_INITIALIZED;
}
nsresult rv = MaybeFlushPendingNotifications();
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
return rv;
}
return MaybeDispatchBeforeInputEvent();
}
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
CanHandleAndFlushPendingNotifications() {
if (MOZ_UNLIKELY(NS_WARN_IF(!CanHandle()))) {
return NS_ERROR_NOT_INITIALIZED;
}
MOZ_ASSERT(MayEditActionRequireLayout(mRawEditAction));
return MaybeFlushPendingNotifications();
}
[[nodiscard]] bool IsDataAvailable() const {
return mSelection && mEditorBase.IsInitialized();
@ -1289,9 +1277,6 @@ class EditorBase : public nsIEditor,
private:
bool IsBeforeInputEventEnabled() const;
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
MaybeFlushPendingNotifications() const;
static bool NeedsBeforeInputEventHandling(EditAction aEditAction) {
MOZ_ASSERT(aEditAction != EditAction::eNone);
switch (aEditAction) {
@ -1302,9 +1287,6 @@ class EditorBase : public nsIEditor,
// If we're being initialized, we may need to create a padding <br>
// element, but it shouldn't cause `beforeinput` event.
case EditAction::eInitializing:
// If we're just selecting or getting table cells, we shouldn't
// dispatch `beforeinput` event.
case NS_EDIT_ACTION_CASES_ACCESSING_TABLE_DATA_WITHOUT_EDITING:
// If raw level transaction API is used, the API user needs to handle
// both "beforeinput" event and "input" event if it's necessary.
case EditAction::eUnknown:
@ -1389,12 +1371,7 @@ class EditorBase : public nsIEditor,
// for current edit sub action.
EditSubActionData mEditSubActionData;
// mEditAction and mRawEditActions stores edit action. The difference of
// them is, if and only if edit actions are nested and parent edit action
// is one of trying to edit something, but nested one is not so, it's
// overwritten by the parent edit action.
EditAction mEditAction;
EditAction mRawEditAction;
// Different from its data, you can refer "current" AutoEditActionDataSetter
// instance's mTopLevelEditSubAction member since it's copied from the

View File

@ -1384,54 +1384,6 @@ class HTMLEditUtils final {
return nullptr;
}
/**
* GetFirstTableCellElementChild() and GetLastTableCellElementChild()
* return the first/last element child of <tr> element if it's a table
* cell element.
*/
static Element* GetFirstTableCellElementChild(
const Element& aTableRowElement) {
MOZ_ASSERT(aTableRowElement.IsHTMLElement(nsGkAtoms::tr));
Element* firstElementChild = aTableRowElement.GetFirstElementChild();
return firstElementChild && HTMLEditUtils::IsTableCell(firstElementChild)
? firstElementChild
: nullptr;
}
static Element* GetLastTableCellElementChild(
const Element& aTableRowElement) {
MOZ_ASSERT(aTableRowElement.IsHTMLElement(nsGkAtoms::tr));
Element* lastElementChild = aTableRowElement.GetLastElementChild();
return lastElementChild && HTMLEditUtils::IsTableCell(lastElementChild)
? lastElementChild
: nullptr;
}
/**
* GetPreviousTableCellElementSibling() and GetNextTableCellElementSibling()
* return a table cell element of previous/next element sibling of given
* content node if and only if the element sibling is a table cell element.
*/
static Element* GetPreviousTableCellElementSibling(
const nsIContent& aChildOfTableRow) {
MOZ_ASSERT(aChildOfTableRow.GetParentNode());
MOZ_ASSERT(aChildOfTableRow.GetParentNode()->IsHTMLElement(nsGkAtoms::tr));
Element* previousElementSibling =
aChildOfTableRow.GetPreviousElementSibling();
return previousElementSibling &&
HTMLEditUtils::IsTableCell(previousElementSibling)
? previousElementSibling
: nullptr;
}
static Element* GetNextTableCellElementSibling(
const nsIContent& aChildOfTableRow) {
MOZ_ASSERT(aChildOfTableRow.GetParentNode());
MOZ_ASSERT(aChildOfTableRow.GetParentNode()->IsHTMLElement(nsGkAtoms::tr));
Element* nextElementSibling = aChildOfTableRow.GetNextElementSibling();
return nextElementSibling && HTMLEditUtils::IsTableCell(nextElementSibling)
? nextElementSibling
: nullptr;
}
/**
* GetMostDistantAncestorInlineElement() returns the most distant ancestor
* inline element between aContent and the aEditingHost. Even if aEditingHost

View File

@ -1277,7 +1277,7 @@ EditActionResult HTMLEditor::HandleTabKeyPressInTable(
}
// Find enclosing table cell from selection (cell may be selected element)
const RefPtr<Element> cellElement =
Element* cellElement =
GetInclusiveAncestorByTagNameAtSelection(*nsGkAtoms::td);
if (!cellElement) {
NS_WARNING(
@ -1339,19 +1339,18 @@ EditActionResult HTMLEditor::HandleTabKeyPressInTable(
AutoEditActionDataSetter editActionData(*this,
EditAction::eInsertTableRowElement);
rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
if (NS_FAILED(rv)) {
NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
return EditActionHandled(rv);
}
rv = InsertTableRowsWithTransaction(*cellElement, 1,
InsertPosition::eAfterSelectedCell);
rv = InsertTableRowsWithTransaction(1, InsertPosition::eAfterSelectedCell);
if (NS_WARN_IF(Destroyed())) {
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
}
if (NS_FAILED(rv)) {
NS_WARNING(
"HTMLEditor::InsertTableRowsWithTransaction(*cellElement, 1, "
"HTMLEditor::InsertTableRowsWithTransaction(1, "
"InsertPosition::eAfterSelectedCell) failed");
return EditActionHandled(rv);
}
@ -2353,15 +2352,17 @@ nsresult HTMLEditor::GetHTMLBackgroundColorState(bool* aMixed,
*aMixed = false;
aOutColor.Truncate();
Result<RefPtr<Element>, nsresult> cellOrRowOrTableElementOrError =
GetSelectedOrParentTableElement();
if (cellOrRowOrTableElementOrError.isErr()) {
NS_WARNING("HTMLEditor::GetSelectedOrParentTableElement() returned error");
return cellOrRowOrTableElementOrError.unwrapErr();
ErrorResult error;
RefPtr<Element> cellOrRowOrTableElement =
GetSelectedOrParentTableElement(error);
if (error.Failed()) {
NS_WARNING(
"HTMLEditor::GetSelectedOrParentTableElement() returned nullptr");
return error.StealNSResult();
}
for (RefPtr<Element> element = cellOrRowOrTableElementOrError.unwrap();
element; element = element->GetParentElement()) {
for (RefPtr<Element> element = std::move(cellOrRowOrTableElement); element;
element = element->GetParentElement()) {
// We are in a cell or selected table
element->GetAttr(kNameSpaceID_None, nsGkAtoms::bgcolor, aOutColor);
@ -2719,7 +2720,7 @@ Element* HTMLEditor::GetInclusiveAncestorByTagNameAtSelection(
}
Element* HTMLEditor::GetInclusiveAncestorByTagNameInternal(
const nsStaticAtom& aTagName, const nsIContent& aContent) const {
const nsStaticAtom& aTagName, nsIContent& aContent) const {
MOZ_ASSERT(&aTagName != nsGkAtoms::_empty);
Element* currentElement = aContent.GetAsElementOrParentElement();
@ -3296,18 +3297,19 @@ nsresult HTMLEditor::SetHTMLBackgroundColorWithTransaction(
MOZ_ASSERT(IsEditActionDataAvailable());
// Find a selected or enclosing table element to set background on
ErrorResult error;
bool isCellSelected = false;
Result<RefPtr<Element>, nsresult> cellOrRowOrTableElementOrError =
GetSelectedOrParentTableElement(&isCellSelected);
if (cellOrRowOrTableElementOrError.isErr()) {
RefPtr<Element> cellOrRowOrTableElement =
GetSelectedOrParentTableElement(error, &isCellSelected);
if (error.Failed()) {
NS_WARNING("HTMLEditor::GetSelectedOrParentTableElement() failed");
return cellOrRowOrTableElementOrError.unwrapErr();
return error.StealNSResult();
}
bool setColor = !aColor.IsEmpty();
RefPtr<Element> rootElementOfBackgroundColor =
cellOrRowOrTableElementOrError.unwrap();
if (rootElementOfBackgroundColor) {
RefPtr<Element> rootElementOfBackgroundColor;
if (cellOrRowOrTableElement) {
rootElementOfBackgroundColor = std::move(cellOrRowOrTableElement);
// Needs to set or remove background color of each selected cell elements.
// Therefore, just the cell contains selection range, we don't need to
// do this. Note that users can select each cell, but with Selection API,

View File

@ -12,7 +12,6 @@
#include "mozilla/EditorBase.h"
#include "mozilla/EditorForwards.h"
#include "mozilla/EditorUtils.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/HTMLEditHelpers.h"
#include "mozilla/ManualNAC.h"
#include "mozilla/Result.h"
@ -2892,8 +2891,8 @@ class HTMLEditor final : public EditorBase,
* @return If an element which matches aTagName, returns
* an Element. Otherwise, nullptr.
*/
Element* GetInclusiveAncestorByTagNameInternal(
const nsStaticAtom& aTagName, const nsIContent& aContent) const;
Element* GetInclusiveAncestorByTagNameInternal(const nsStaticAtom& aTagName,
nsIContent& aContent) const;
/**
* GetSelectedElement() returns a "selected" element node. "selected" means:
@ -2929,30 +2928,34 @@ class HTMLEditor final : public EditorBase,
/**
* GetFirstTableRowElement() returns the first <tr> element in the most
* nearest ancestor of aTableOrElementInTable or itself.
* When aTableOrElementInTable is neither <table> nor in a <table> element,
* returns NS_ERROR_FAILURE. However, if <table> does not have <tr> element,
* returns nullptr.
*
* @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.
*/
Result<RefPtr<Element>, nsresult> GetFirstTableRowElement(
const Element& aTableOrElementInTable) const;
Element* GetFirstTableRowElement(Element& aTableOrElementInTable,
ErrorResult& aRv) const;
/**
* GetNextTableRowElement() returns next <tr> element of aTableRowElement.
* This won't cross <table> element boundary but may cross table section
* elements like <tbody>.
* Note that if given element is <tr> but there is no next <tr> element, this
* returns nullptr but does not return error.
*
* @param aTableRowElement A <tr> element.
* @param aRv Returns error. If given element is <tr> but
* there is no next <tr> element, this returns
* nullptr but does not return error.
*/
Result<RefPtr<Element>, nsresult> GetNextTableRowElement(
const Element& aTableRowElement) const;
Element* GetNextTableRowElement(Element& aTableRowElement,
ErrorResult& aRv) const;
struct CellData;
@ -3053,13 +3056,6 @@ class HTMLEditor final : public EditorBase,
[[nodiscard]] static CellData AtIndexInTableElement(
const HTMLEditor& aHTMLEditor, const Element& aTableElement,
int32_t aRowIndex, int32_t aColumnIndex);
[[nodiscard]] static CellData AtIndexInTableElement(
const HTMLEditor& aHTMLEditor, const Element& aTableElement,
const CellIndexes& aIndexes) {
MOZ_ASSERT(!aIndexes.isErr());
return AtIndexInTableElement(aHTMLEditor, aTableElement, aIndexes.mRow,
aIndexes.mColumn);
}
/**
* Treated as error if fails to compute current index or first index of the
@ -3247,15 +3243,8 @@ class HTMLEditor final : public EditorBase,
* In #1 and #4, *aIsCellSelected will be set to true (i.e,, when
* a selection range selects a cell element).
*/
Result<RefPtr<Element>, nsresult> GetSelectedOrParentTableElement(
bool* aIsCellSelected = nullptr) const;
/**
* GetFirstSelectedCellElementInTable() returns <td> or <th> element at
* first selection (using GetSelectedOrParentTableElement). If found cell
* element is not in <table> or <tr> element, this returns nullptr.
*/
Result<RefPtr<Element>, nsresult> GetFirstSelectedCellElementInTable() const;
already_AddRefed<Element> GetSelectedOrParentTableElement(
ErrorResult& aRv, bool* aIsCellSelected = nullptr) const;
/**
* PasteInternal() pasts text with replacing selected content.
@ -3472,6 +3461,8 @@ class HTMLEditor final : public EditorBase,
bool* aMixed, nsAString& aOutColor, bool aBlockLevel);
nsresult GetHTMLBackgroundColorState(bool* aMixed, nsAString& outColor);
nsresult GetLastCellInRow(nsINode* aRowNode, nsINode** aCellNode);
/**
* This sets background on the appropriate container element (table, cell,)
* or calls to set the page background.
@ -3590,7 +3581,10 @@ class HTMLEditor final : public EditorBase,
};
/**
* InsertTableCellsWithTransaction() inserts <td> elements at aPointToInsert.
* InsertTableCellsWithTransaction() inserts <td> elements before or after
* a cell element containing first selection range. I.e., if the cell
* spans columns and aInsertPosition is eAfterSelectedCell, new columns
* will be inserted after the right-most column which contains the cell.
* Note that this simply inserts <td> elements, i.e., colspan and rowspan
* around the cell containing selection are not modified. So, for example,
* adding a cell to rectangular table changes non-rectangular table.
@ -3598,41 +3592,45 @@ class HTMLEditor final : public EditorBase,
* it may be moved to right side of the row-spanning cell after inserting
* some cell elements before it. Similarly, colspan won't be adjusted
* for keeping table rectangle.
* Finally, puts caret into previous cell of the insertion point or the
* first inserted cell if aPointToInsert is start of the row.
* If first selection range is not in table cell element, this does nothing
* but does not return error.
*
* @param aPointToInsert The place to insert one or more cell
* elements. The container must be a
* <tr> element.
* @param aNumberOfCellsToInsert Number of cells to insert.
* @param aNumberOfCellssToInsert Number of cells to insert.
* @param aInsertPosition Before or after the target cell which
* contains first selection range.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult InsertTableCellsWithTransaction(
const EditorDOMPoint& aPointToInsert, int32_t aNumberOfCellsToInsert);
MOZ_CAN_RUN_SCRIPT nsresult InsertTableCellsWithTransaction(
int32_t aNumberOfCellsToInsert, InsertPosition aInsertPosition);
/**
* InsertTableColumnsWithTransaction() inserts cell elements to every rows
* at same column index as the cell specified by aPointToInsert.
* InsertTableColumnsWithTransaction() inserts columns before or after
* a cell element containing first selection range. I.e., if the cell
* spans columns and aInsertPosition is eAfterSelectedCell, new columns
* will be inserted after the right-most row which contains the cell.
* If first selection range is not in table cell element, this does nothing
* but does not return error.
*
* @param aNumberOfColumnsToInsert Number of columns to insert.
* @param aInsertPosition Before or after the target cell which
* contains first selection range.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult InsertTableColumnsWithTransaction(
const EditorDOMPoint& aPointToInsert, int32_t aNumberOfColumnsToInsert);
MOZ_CAN_RUN_SCRIPT nsresult InsertTableColumnsWithTransaction(
int32_t aNumberOfColumnsToInsert, InsertPosition aInsertPosition);
/**
* InsertTableRowsWithTransaction() inserts <tr> elements before or after
* aCellElement. When aCellElement spans rows and aInsertPosition is
* eAfterSelectedCell, new rows will be inserted after the most-bottom row
* which contains the cell.
* a cell element containing first selection range. I.e., if the cell
* spans rows and aInsertPosition is eAfterSelectedCell, new rows will be
* inserted after the most-bottom row which contains the cell. If first
* selection range is not in table cell element, this does nothing but
* does not return error.
*
* @param aCellElement The cell element pinting where this will
* insert a row before or after.
* @param aNumberOfRowsToInsert Number of rows to insert.
* @param aInsertPosition Before or after the target cell which
* contains first selection range.
*/
MOZ_CAN_RUN_SCRIPT nsresult InsertTableRowsWithTransaction(
Element& aCellElement, int32_t aNumberOfRowsToInsert,
InsertPosition aInsertPosition);
int32_t aNumberOfRowsToInsert, InsertPosition aInsertPosition);
/**
* Insert a new cell after or before supplied aCell.

View File

@ -209,10 +209,7 @@ nsresult HTMLEditor::DoInlineTableEditingAction(const Element& aElement) {
return NS_OK;
}
if (NS_WARN_IF(!mInlineEditedCell) ||
NS_WARN_IF(!mInlineEditedCell->IsInComposedDoc()) ||
NS_WARN_IF(
!HTMLEditUtils::IsTableRow(mInlineEditedCell->GetParentNode()))) {
if (NS_WARN_IF(!mInlineEditedCell)) {
return NS_ERROR_NOT_AVAILABLE;
}
@ -247,13 +244,12 @@ nsresult HTMLEditor::DoInlineTableEditingAction(const Element& aElement) {
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
return EditorBase::ToGenericNSResult(rv);
}
DebugOnly<nsresult> rvIgnored =
InsertTableColumnsWithTransaction(EditorDOMPoint(mInlineEditedCell), 1);
DebugOnly<nsresult> rvIgnored = InsertTableColumnsWithTransaction(
1, InsertPosition::eBeforeSelectedCell);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"HTMLEditor::InsertTableColumnsWithTransaction("
"EditorDOMPoint(mInlineEditedCell), 1) failed, but ignored");
"HTMLEditor::InsertTableColumnsWithTransaction(1, "
"InsertPosition::eBeforeSelectedCell) failed, but ignored");
} else if (anonclass.EqualsLiteral("mozTableAddColumnAfter")) {
AutoEditActionDataSetter editActionData(*this,
EditAction::eInsertTableColumn);
@ -264,24 +260,12 @@ nsresult HTMLEditor::DoInlineTableEditingAction(const Element& aElement) {
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
return EditorBase::ToGenericNSResult(rv);
}
Element* nextCellElement = nullptr;
for (nsIContent* maybeNextCellElement = mInlineEditedCell->GetNextSibling();
maybeNextCellElement;
maybeNextCellElement = maybeNextCellElement->GetNextSibling()) {
if (HTMLEditUtils::IsTableCell(maybeNextCellElement)) {
nextCellElement = maybeNextCellElement->AsElement();
break;
}
}
DebugOnly<nsresult> rvIgnored = InsertTableColumnsWithTransaction(
nextCellElement
? EditorDOMPoint(nextCellElement)
: EditorDOMPoint::AtEndOf(*mInlineEditedCell->GetParentElement()),
1);
1, InsertPosition::eAfterSelectedCell);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"HTMLEditor::InsertTableColumnsWithTransaction("
"EditorDOMPoint(nextCellElement), 1) failed, but ignored");
"HTMLEditor::InsertTableColumnsWithTransaction(1, "
"InsertPosition::eAfterSelectedCell) failed, but ignored");
} else if (anonclass.EqualsLiteral("mozTableAddRowBefore")) {
AutoEditActionDataSetter editActionData(*this,
EditAction::eInsertTableRowElement);
@ -292,12 +276,11 @@ nsresult HTMLEditor::DoInlineTableEditingAction(const Element& aElement) {
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
return EditorBase::ToGenericNSResult(rv);
}
OwningNonNull<Element> targetCellElement(*mInlineEditedCell);
DebugOnly<nsresult> rvIgnored = InsertTableRowsWithTransaction(
targetCellElement, 1, InsertPosition::eBeforeSelectedCell);
DebugOnly<nsresult> rvIgnored =
InsertTableRowsWithTransaction(1, InsertPosition::eBeforeSelectedCell);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"HTMLEditor::InsertTableRowsWithTransaction(targetCellElement, 1, "
"HTMLEditor::InsertTableRowsWithTransaction(1, "
"InsertPosition::eBeforeSelectedCell) failed, but ignored");
} else if (anonclass.EqualsLiteral("mozTableAddRowAfter")) {
AutoEditActionDataSetter editActionData(*this,
@ -309,12 +292,11 @@ nsresult HTMLEditor::DoInlineTableEditingAction(const Element& aElement) {
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
return EditorBase::ToGenericNSResult(rv);
}
OwningNonNull<Element> targetCellElement(*mInlineEditedCell);
DebugOnly<nsresult> rvIgnored = InsertTableRowsWithTransaction(
targetCellElement, 1, InsertPosition::eAfterSelectedCell);
DebugOnly<nsresult> rvIgnored =
InsertTableRowsWithTransaction(1, InsertPosition::eAfterSelectedCell);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"HTMLEditor::InsertTableRowsWithTransaction(targetCellElement, 1, "
"HTMLEditor::InsertTableRowsWithTransaction(1, "
"InsertPosition::eAfterSelectedCell) failed, but ignored");
} else if (anonclass.EqualsLiteral("mozTableRemoveColumn")) {
AutoEditActionDataSetter editActionData(*this,
@ -352,6 +334,7 @@ nsresult HTMLEditor::DoInlineTableEditingAction(const Element& aElement) {
return NS_OK;
}
// InsertTableRowsWithTransaction() might causes reframe.
if (NS_WARN_IF(Destroyed())) {
return NS_OK;
}

File diff suppressed because it is too large Load Diff

View File

@ -661,6 +661,7 @@ SimpleTest.waitForFocus(() => {
'<tr><td id="select">cell1-1</td><td>cell1-2</td><td>cell1-3</td></tr>' +
"<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" +
"</table>";
editor.scrollTop; // requires layout information.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -683,6 +684,7 @@ SimpleTest.waitForFocus(() => {
'<tr><td id="select">cell1-1</td><td>cell1-2</td><td>cell1-3</td></tr>' +
"<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" +
"</table>";
editor.scrollTop; // requires layout information.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,

View File

@ -262,6 +262,7 @@ SimpleTest.waitForFocus(() => {
"<tr><td>cell2-1</td><td>cell2-2</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // Requires layout information.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,

View File

@ -219,6 +219,7 @@ SimpleTest.waitForFocus(() => {
'<table><tr><td id="select">cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
editor.scrollTop; // Needs to flush pending reflow since we need layout information in this case.
range = document.createRange();
range.selectNode(document.getElementById("select").firstChild);
selection.addRange(range);
@ -237,6 +238,7 @@ SimpleTest.waitForFocus(() => {
'<table><tr><td>cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td id="select">cell2-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
editor.scrollTop; // Needs to flush pending reflow since we need layout information in this case.
range = document.createRange();
range.selectNode(document.getElementById("select").firstChild);
selection.addRange(range);
@ -255,6 +257,7 @@ SimpleTest.waitForFocus(() => {
'<table><tr><td id="select">cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
editor.scrollTop; // Needs to flush pending reflow since we need layout information in this case.
range = document.createRange();
range.selectNode(document.getElementById("select").firstChild);
selection.addRange(range);
@ -273,6 +276,7 @@ SimpleTest.waitForFocus(() => {
'<table><tr><td id="select">cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
editor.scrollTop; // Needs to flush pending reflow since we need layout information in this case.
range = document.createRange();
range.selectNode(document.getElementById("select").firstChild);
selection.addRange(range);
@ -291,6 +295,7 @@ SimpleTest.waitForFocus(() => {
'<table><tr><td>cell1-1</td><td id="select">cell1-2</td><td>cell1-3</td></tr><tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
editor.scrollTop; // Needs to flush pending reflow since we need layout information in this case.
range = document.createRange();
range.selectNode(document.getElementById("select").firstChild);
selection.addRange(range);
@ -309,6 +314,7 @@ SimpleTest.waitForFocus(() => {
'<table><tr><td>cell1-1</td><td>cell1-2</td></tr><tr><td id="select">cell2-1</td><td>cell2-2</td></tr><tr><td>cell3-1</td><td>cell3-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
editor.scrollTop; // Needs to flush pending reflow since we need layout information in this case.
range = document.createRange();
range.selectNode(document.getElementById("select").firstChild);
selection.addRange(range);

View File

@ -217,6 +217,7 @@ SimpleTest.waitForFocus(() => {
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td id="select">cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr></table>';
editor.scrollTop; // Needs to flush pending reflow since we need layout information in this case.
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
@ -235,6 +236,7 @@ SimpleTest.waitForFocus(() => {
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td>cell1-1</td><td>cell1-2</td></tr><tr><td id="select">cell2-1</td><td>cell2-2</td></tr></table>';
editor.scrollTop; // Needs to flush pending reflow since we need layout information in this case.
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
@ -253,6 +255,7 @@ SimpleTest.waitForFocus(() => {
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td id="select">cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr></table>';
editor.scrollTop; // Needs to flush pending reflow since we need layout information in this case.
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
@ -271,6 +274,7 @@ SimpleTest.waitForFocus(() => {
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td id="select">cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr></table>';
editor.scrollTop; // Needs to flush pending reflow since we need layout information in this case.
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
@ -289,6 +293,7 @@ SimpleTest.waitForFocus(() => {
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td>cell1-1</td><td>cell1-2</td></tr><tr><td id="select">cell2-1</td><td>cell2-2</td></tr><tr><td>cell3-1</td><td>cell3-2</td></tr></table>';
editor.scrollTop; // Needs to flush pending reflow since we need layout information in this case.
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
@ -307,6 +312,7 @@ SimpleTest.waitForFocus(() => {
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td>cell1-1</td><td>cell1-2</td></tr><tr><td id="select">cell2-1</td><td>cell2-2</td></tr><tr><td>cell3-1</td><td>cell3-2</td></tr></table>';
editor.scrollTop; // Needs to flush pending reflow since we need layout information in this case.
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();

View File

@ -55,6 +55,7 @@ SimpleTest.waitForFocus(function() {
'<tr><td id="c6-2">cell6-2</td><td id="c6-3">cell6-3</td><td id="c6-4"><p>cell6-4</p></td><td id="c6-5">cell6-5</td></tr>' +
'<tr><td id="c7-2" colspan="4">cell7-2</td></tr>' +
"</table>";
editor.scrollTop; // compute layout now.
const kTestsInParent = [
{ row: 0, column: 0, expected: "c1-1" },

View File

@ -176,6 +176,7 @@ SimpleTest.waitForFocus(function() {
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
reset();
getTableEditor().getCellDataAt(editor.firstChild, 0, 0,
cellElementWrapper,
@ -316,6 +317,7 @@ SimpleTest.waitForFocus(function() {
'<tr><td colspan="3">cell4-1</td><td>cell4-4</td></tr>' +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
reset();
getTableEditor().getCellDataAt(editor.firstChild, 0, 0,
cellElementWrapper,
@ -561,6 +563,7 @@ SimpleTest.waitForFocus(function() {
'<tr><td rowspan="3" colspan="2">cell1-1</td></tr>' +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
reset();
getTableEditor().getCellDataAt(editor.firstChild, 0, 0,
cellElementWrapper,
@ -646,6 +649,7 @@ SimpleTest.waitForFocus(function() {
"<tr><td>cell3-2</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
reset();
getTableEditor().getCellDataAt(editor.firstChild, 0, 0,
cellElementWrapper,
@ -701,6 +705,7 @@ SimpleTest.waitForFocus(function() {
"<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
reset();
getTableEditor().getCellDataAt(editor.firstChild, 0, 0,
cellElementWrapper,

View File

@ -66,6 +66,7 @@ SimpleTest.waitForFocus(function() {
for (const kTest of kTests) {
editor.innerHTML = kTest;
editor.scrollTop; // compute layout now.
let cell = document.getElementById("test");
getTableEditor().getCellIndexes(cell, rowIndex, columnIndex);
is(rowIndex.value.toString(10), cell.getAttribute("data-row"), `Specified cell element directly, row Index value of ${kTest}`);

View File

@ -38,6 +38,7 @@ SimpleTest.waitForFocus(function() {
(function test_without_table() {
editor.innerHTML = "<p>Here is a paragraph</p>";
document.body.scrollTop; // Flush pending layout
selection.collapse(editor.querySelector("p").firstChild, 0);
try {
getTableEditor().getSelectedCellsType(null);
@ -50,6 +51,7 @@ SimpleTest.waitForFocus(function() {
(function test_with_selection_outside_table() {
editor.innerHTML = "<p>Here is a paragraph before the table</p>" +
"<table><tr><td>cell</td></tr></table>";
document.body.scrollTop; // Flush pending layout
selection.collapse(editor.querySelector("p").firstChild, 0);
try {
getTableEditor().getSelectedCellsType(null);
@ -61,6 +63,7 @@ SimpleTest.waitForFocus(function() {
(function test_with_selection_in_text_in_cell() {
editor.innerHTML = "<table><tr><td>cell</td></tr></table>";
document.body.scrollTop; // Flush pending layout
selection.collapse(editor.querySelector("td").firstChild, 0);
is(getTableEditor().getSelectedCellsType(null), kTableSelectionMode_None,
"nsITableEditor.getSelectedCellsType(null) should return None when selection is collapsed in a text node in a cell");
@ -68,6 +71,7 @@ SimpleTest.waitForFocus(function() {
(function test_with_selecting_a_cell_which_is_only_one_cell_in_table() {
editor.innerHTML = "<table><tr><td>cell</td></tr></table>";
document.body.scrollTop; // Flush pending layout
selection.setBaseAndExtent(editor.querySelector("tr"), 0, editor.querySelector("tr"), 1);
is(getTableEditor().getSelectedCellsType(null), kTableSelectionMode_Row,
"nsITableEditor.getSelectedCellsType(null) should return Row when selection selects the cell which is only one in the table");
@ -75,6 +79,7 @@ SimpleTest.waitForFocus(function() {
(function test_with_selecting_a_cell_whose_table_has_one_row() {
editor.innerHTML = "<table><tr><td>cell1</td><td>cell2</td></tr></table>";
document.body.scrollTop; // Flush pending layout
selection.setBaseAndExtent(editor.querySelector("tr"), 0, editor.querySelector("tr"), 1);
is(getTableEditor().getSelectedCellsType(null), kTableSelectionMode_Column,
"nsITableEditor.getSelectedCellsType(null) should return Column when selection selects a cell in the first row which is only one in the table");
@ -82,6 +87,7 @@ SimpleTest.waitForFocus(function() {
(function test_with_selecting_a_cell_whose_table_has_one_column() {
editor.innerHTML = "<table><tr><td>cell1</td></tr><tr><td>cell2</td></tr></table>";
document.body.scrollTop; // Flush pending layout
selection.setBaseAndExtent(editor.querySelector("tr"), 0, editor.querySelector("tr"), 1);
is(getTableEditor().getSelectedCellsType(null), kTableSelectionMode_Row,
"nsITableEditor.getSelectedCellsType(null) should return Row when selection selects a cell in the first row which is only one in the row");
@ -89,6 +95,7 @@ SimpleTest.waitForFocus(function() {
(function test_with_selecting_a_cell_at_1_1_whose_table_has_2x2_cells() {
editor.innerHTML = "<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>";
document.body.scrollTop; // Flush pending layout
selection.setBaseAndExtent(editor.querySelector("tr"), 0, editor.querySelector("tr"), 1);
is(getTableEditor().getSelectedCellsType(null), kTableSelectionMode_Cell,
"nsITableEditor.getSelectedCellsType(null) should return Cell when selection selects a cell at first row and first column");
@ -96,6 +103,7 @@ SimpleTest.waitForFocus(function() {
(function test_with_selecting_a_cell_at_1_2_whose_table_has_2x2_cells() {
editor.innerHTML = "<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>";
document.body.scrollTop; // Flush pending layout
selection.setBaseAndExtent(editor.querySelector("tr"), 1, editor.querySelector("tr"), 2);
is(getTableEditor().getSelectedCellsType(null), kTableSelectionMode_Cell,
"nsITableEditor.getSelectedCellsType(null) should return Cell when selection selects a cell at first row and second column");
@ -103,6 +111,7 @@ SimpleTest.waitForFocus(function() {
(function test_with_selecting_a_cell_at_2_1_whose_table_has_2x2_cells() {
editor.innerHTML = "<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>";
document.body.scrollTop; // Flush pending layout
selection.setBaseAndExtent(editor.querySelector("tr + tr"), 0, editor.querySelector("tr + tr"), 1);
is(getTableEditor().getSelectedCellsType(null), kTableSelectionMode_Cell,
"nsITableEditor.getSelectedCellsType(null) should return Cell when selection selects a cell at second row and first column");
@ -110,6 +119,7 @@ SimpleTest.waitForFocus(function() {
(function test_with_selecting_a_cell_at_2_2_whose_table_has_2x2_cells() {
editor.innerHTML = "<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>";
document.body.scrollTop; // Flush pending layout
selection.setBaseAndExtent(editor.querySelector("tr + tr"), 1, editor.querySelector("tr + tr"), 2);
is(getTableEditor().getSelectedCellsType(null), kTableSelectionMode_Cell,
"nsITableEditor.getSelectedCellsType(null) should return Cell when selection selects a cell at second row and second column");
@ -117,6 +127,7 @@ SimpleTest.waitForFocus(function() {
(function test_with_selecting_a_cell_at_1_1_whose_colspan_2_and_whose_table_has_2x2_cells() {
editor.innerHTML = "<table><tr><td colspan=\"2\">cell1</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>";
document.body.scrollTop; // Flush pending layout
selection.setBaseAndExtent(editor.querySelector("tr"), 0, editor.querySelector("tr"), 1);
is(getTableEditor().getSelectedCellsType(null), kTableSelectionMode_Row,
"nsITableEditor.getSelectedCellsType(null) should return Row when selection selects a cell whose colspan is 2 at first row");
@ -124,6 +135,7 @@ SimpleTest.waitForFocus(function() {
(function test_with_selecting_a_cell_at_1_1_whose_rowspan_2_and_whose_table_has_2x2_cells() {
editor.innerHTML = "<table><tr><td rowspan=\"2\">cell1</td><td>cell2</td></tr><tr><td>cell4</td></tr></table>";
document.body.scrollTop; // Flush pending layout
selection.setBaseAndExtent(editor.querySelector("tr"), 0, editor.querySelector("tr"), 1);
is(getTableEditor().getSelectedCellsType(null), kTableSelectionMode_Column,
"nsITableEditor.getSelectedCellsType(null) should return Column when selection selects a cell whose row is 2 at first column");
@ -131,6 +143,7 @@ SimpleTest.waitForFocus(function() {
(function test_with_selecting_all_cells_in_first_row_whose_table_has_2x2_cells() {
editor.innerHTML = "<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>";
document.body.scrollTop; // Flush pending layout
synthesizeMouseAtCenter(editor.querySelector("td"), {accelKey: true});
synthesizeMouseAtCenter(editor.querySelector("td + td"), {accelKey: true});
is(getTableEditor().getSelectedCellsType(null), kTableSelectionMode_Row,
@ -140,6 +153,7 @@ SimpleTest.waitForFocus(function() {
(function test_with_selecting_all_cells_in_first_column_whose_table_has_2x2_cells() {
selection.removeAllRanges();
editor.innerHTML = "<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>";
document.body.scrollTop; // Flush pending layout
synthesizeMouseAtCenter(editor.querySelector("td"), {accelKey: true});
synthesizeMouseAtCenter(editor.querySelector("tr + tr > td"), {accelKey: true});
is(getTableEditor().getSelectedCellsType(null), kTableSelectionMode_Column,
@ -149,6 +163,7 @@ SimpleTest.waitForFocus(function() {
(function test_with_selecting_all_cells_whose_table_has_2x2_cells() {
selection.removeAllRanges();
editor.innerHTML = "<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>";
document.body.scrollTop; // Flush pending layout
synthesizeMouseAtCenter(editor.querySelector("td"), {accelKey: true});
synthesizeMouseAtCenter(editor.querySelector("td + td"), {accelKey: true});
synthesizeMouseAtCenter(editor.querySelector("tr + tr > td"), {accelKey: true});
@ -159,6 +174,7 @@ SimpleTest.waitForFocus(function() {
(function test_with_selecting_a_raw() {
editor.innerHTML = "<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>";
document.body.scrollTop; // Flush pending layout
selection.setBaseAndExtent(editor.querySelector("tbody"), 0, editor.querySelector("tbody"), 1);
is(getTableEditor().getSelectedCellsType(null), kTableSelectionMode_None,
"nsITableEditor.getSelectedCellsType(null) should return None when selection selects a row");
@ -166,6 +182,7 @@ SimpleTest.waitForFocus(function() {
(function test_with_selecting_a_tbody() {
editor.innerHTML = "<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>";
document.body.scrollTop; // Flush pending layout
selection.setBaseAndExtent(editor.querySelector("table"), 0, editor.querySelector("table"), 1);
is(getTableEditor().getSelectedCellsType(null), kTableSelectionMode_None,
"nsITableEditor.getSelectedCellsType(null) should return None when selection selects a tbody");
@ -173,6 +190,7 @@ SimpleTest.waitForFocus(function() {
(function test_with_selecting_a_table() {
editor.innerHTML = "<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>";
document.body.scrollTop; // Flush pending layout
selection.setBaseAndExtent(editor, 0, editor, 1);
is(getTableEditor().getSelectedCellsType(null), kTableSelectionMode_None,
"nsITableEditor.getSelectedCellsType(null) should return None when selection selects a table");
@ -182,6 +200,7 @@ SimpleTest.waitForFocus(function() {
selection.removeAllRanges();
editor.innerHTML = "<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>" +
"<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>";
document.body.scrollTop; // Flush pending layout
let range = document.createRange();
range.selectNode(editor.querySelector("td"));
selection.addRange(range);
@ -196,6 +215,7 @@ SimpleTest.waitForFocus(function() {
selection.removeAllRanges();
editor.innerHTML = "<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>" +
"<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>";
document.body.scrollTop; // Flush pending layout
let range = document.createRange();
range.selectNode(editor.querySelector("td"));
selection.addRange(range);
@ -207,6 +227,7 @@ SimpleTest.waitForFocus(function() {
selection.removeAllRanges();
editor.innerHTML = "<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>" +
"<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>";
document.body.scrollTop; // Flush pending layout
let range = document.createRange();
range.selectNode(editor.querySelector("tr + tr > td"));
selection.addRange(range);
@ -218,6 +239,7 @@ SimpleTest.waitForFocus(function() {
selection.removeAllRanges();
editor.innerHTML = "<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>" +
"<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>";
document.body.scrollTop; // Flush pending layout
let range = document.createRange();
range.selectNode(editor.querySelector("td"));
selection.addRange(range);
@ -229,6 +251,7 @@ SimpleTest.waitForFocus(function() {
selection.removeAllRanges();
editor.innerHTML = "<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>" +
"<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>";
document.body.scrollTop; // Flush pending layout
let range = document.createRange();
range.selectNode(editor.querySelector("td"));
selection.addRange(range);

View File

@ -63,6 +63,7 @@ SimpleTest.waitForFocus(function() {
for (const kTest of kTests) {
editor.innerHTML = kTest;
editor.scrollTop; // compute layout now.
let element = document.getElementById("test");
getTableEditor().getTableSize(element, rowCount, columnCount);
is(rowCount.value.toString(10), element.getAttribute("data-rows"),

View File

@ -129,52 +129,7 @@ SimpleTest.waitForFocus(() => {
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
"</table>";
editor.focus();
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
document.getElementById("select").firstChild, 0);
getTableEditor().insertTableCell(0, false);
is(editor.innerHTML, "<table><tbody>" +
"<tr><td>cell1-1</td><td>cell1-2</td></tr>" +
'<tr><td id="select">cell2-1</td><td>cell2-2</td></tr>' +
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
"</tbody></table>",
"nsITableEditor.insertTableCell(0, false) should not do nothing without throwing exception");
is(beforeInputEvents.length, 0,
'No "beforeinput" event should be fired when calling nsITableEditor.insertTableCell(0, false)');
is(inputEvents.length, 0,
'No "input" event should be fired when calling nsITableEditor.insertTableCell(0, false)');
selection.removeAllRanges();
editor.innerHTML = "<table><tbody>" +
"<tr><td>cell1-1</td><td>cell1-2</td></tr>" +
'<tr><td id="select">cell2-1</td><td>cell2-2</td></tr>' +
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
"</tbody></table>";
editor.focus();
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
document.getElementById("select").firstChild, 0);
getTableEditor().insertTableCell(0, true);
is(editor.innerHTML, "<table><tbody>" +
"<tr><td>cell1-1</td><td>cell1-2</td></tr>" +
'<tr><td id="select">cell2-1</td><td>cell2-2</td></tr>' +
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
"</tbody></table>",
"nsITableEditor.insertTableCell(0, true) should not do nothing without throwing exception");
is(beforeInputEvents.length, 0,
'No "beforeinput" event should be fired when calling nsITableEditor.insertTableCell(0, true)');
is(inputEvents.length, 0,
'No "input" event should be fired when calling nsITableEditor.insertTableCell(0, true)');
selection.removeAllRanges();
editor.innerHTML = "<table>" +
"<tr><td>cell1-1</td><td>cell1-2</td></tr>" +
'<tr><td id="select">cell2-1</td><td>cell2-2</td></tr>' +
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -200,6 +155,7 @@ SimpleTest.waitForFocus(() => {
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -228,6 +184,7 @@ SimpleTest.waitForFocus(() => {
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -253,6 +210,7 @@ SimpleTest.waitForFocus(() => {
"<tr><td>cell3-1</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -278,6 +236,7 @@ SimpleTest.waitForFocus(() => {
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -303,6 +262,7 @@ SimpleTest.waitForFocus(() => {
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -329,6 +289,7 @@ SimpleTest.waitForFocus(() => {
'<tr><td colspan="2">cell2-1</td><td>cell2-3</td></tr>' +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -352,6 +313,7 @@ SimpleTest.waitForFocus(() => {
'<tr><td colspan="3">cell2-1</td></tr>' +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -375,6 +337,7 @@ SimpleTest.waitForFocus(() => {
'<tr><td id="select" colspan="2">cell2-1</td><td>cell2-3</td></tr>' +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -398,6 +361,7 @@ SimpleTest.waitForFocus(() => {
'<tr><td id="select" colspan="2">cell2-1</td><td>cell2-3</td></tr>' +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,

View File

@ -128,6 +128,7 @@ SimpleTest.waitForFocus(() => {
"<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -151,6 +152,7 @@ SimpleTest.waitForFocus(() => {
"<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -174,6 +176,7 @@ SimpleTest.waitForFocus(() => {
'<tr><td colspan="2">cell2-1</td><td>cell2-3</td></tr>' +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -197,6 +200,7 @@ SimpleTest.waitForFocus(() => {
'<tr><td colspan="3">cell2-1</td></tr>' +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -220,6 +224,7 @@ SimpleTest.waitForFocus(() => {
'<tr><td id="select" colspan="2">cell2-1</td><td>cell2-3</td></tr>' +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -243,6 +248,7 @@ SimpleTest.waitForFocus(() => {
'<tr><td id="select" colspan="2">cell2-1</td><td>cell2-3</td></tr>' +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,

View File

@ -129,6 +129,7 @@ SimpleTest.waitForFocus(() => {
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -155,6 +156,7 @@ SimpleTest.waitForFocus(() => {
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -181,6 +183,7 @@ SimpleTest.waitForFocus(() => {
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -207,6 +210,7 @@ SimpleTest.waitForFocus(() => {
"<tr><td>cell3-1</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -233,6 +237,7 @@ SimpleTest.waitForFocus(() => {
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
@ -260,6 +265,7 @@ SimpleTest.waitForFocus(() => {
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
"</table>";
editor.focus();
editor.scrollTop; // layout information required.
beforeInputEvents = [];
inputEvents = [];
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,

View File

@ -268,7 +268,6 @@ interface nsITableEditor : nsISupports
* number than actual, the value is used
* as this.
*/
[can_run_script]
void getTableSize(in Element aTableOrElementInTable,
out long aRowCount, out long aColCount);
@ -290,7 +289,6 @@ interface nsITableEditor : nsISupports
* is not in any <table> element, throwing an
* exception.
*/
[can_run_script]
Element getCellAt(in Element aTableElement,
in long aRowIndex, in long aColumnIndex);
@ -339,7 +337,6 @@ interface nsITableEditor : nsISupports
* Otherwise, e.g., aCellElement just contains
* selection range, returns false.
*/
[can_run_script]
void getCellDataAt(in Element aTableElement,
in long aRowIndex, in long aColumnIndex,
out Element aCellElement,
@ -366,7 +363,6 @@ interface nsITableEditor : nsISupports
* element if <table> has one or more cells
* but <tr> element is not in the source.
*/
[can_run_script]
Element getFirstRow(in Element aTableElement);
/** Preferred direction to search for neighboring cell
@ -397,7 +393,6 @@ interface nsITableEditor : nsISupports
* and getNextSelectedCell(). I.e., getNextSelectedCell() will
* return second selected cell element.
*/
[can_run_script]
Element getSelectedOrParentTableElement(out AString aTagName,
out long aCount);
@ -455,6 +450,5 @@ interface nsITableEditor : nsISupports
* If second or later ranges do not select only a table cell element, this
* ignores the ranges.
*/
[can_run_script]
Array<Element> getSelectedCells();
};