зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1920647 - part 2: Make `nsITableEditor` methods do not modify the DOM if editing host is `plaintext-only` r=m_kato
Differential Revision: https://phabricator.services.mozilla.com/D223670
This commit is contained in:
Родитель
ef73f35608
Коммит
7fe5d3ae1c
|
@ -20,6 +20,7 @@
|
|||
#include "mozilla/PresShell.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/ElementInlines.h"
|
||||
#include "nsAString.h"
|
||||
#include "nsAlgorithm.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
@ -323,10 +324,21 @@ NS_IMETHODIMP HTMLEditor::InsertTableCell(int32_t aNumberOfCellsToInsert,
|
|||
|
||||
AutoEditActionDataSetter editActionData(*this,
|
||||
EditAction::eInsertTableCellElement);
|
||||
nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CanHandleAndFlushPendingNotifications() failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
const RefPtr<Element> editingHost =
|
||||
ComputeEditingHost(LimitInBodyElement::No);
|
||||
if (NS_WARN_IF(editingHost &&
|
||||
editingHost->IsContentEditablePlainTextOnly())) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
rv = editActionData.MaybeDispatchBeforeInputEvent();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,
|
||||
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
|
||||
"MaybeDispatchBeforeInputEvent(), failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
|
@ -476,7 +488,7 @@ NS_IMETHODIMP HTMLEditor::GetFirstRow(Element* aTableOrElementInTable,
|
|||
|
||||
AutoEditActionDataSetter editActionData(*this, EditAction::eGetFirstRow);
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::GetFirstRow() couldn't handle the job");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
@ -593,10 +605,21 @@ NS_IMETHODIMP HTMLEditor::InsertTableColumn(int32_t aNumberOfColumnsToInsert,
|
|||
|
||||
AutoEditActionDataSetter editActionData(*this,
|
||||
EditAction::eInsertTableColumn);
|
||||
nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CanHandleAndFlushPendingNotifications() failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
const RefPtr<Element> editingHost =
|
||||
ComputeEditingHost(LimitInBodyElement::No);
|
||||
if (NS_WARN_IF(editingHost &&
|
||||
editingHost->IsContentEditablePlainTextOnly())) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
rv = editActionData.MaybeDispatchBeforeInputEvent();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,
|
||||
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
|
||||
"MaybeDispatchBeforeInputEvent(), failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
|
@ -863,10 +886,21 @@ NS_IMETHODIMP HTMLEditor::InsertTableRow(int32_t aNumberOfRowsToInsert,
|
|||
|
||||
AutoEditActionDataSetter editActionData(*this,
|
||||
EditAction::eInsertTableRowElement);
|
||||
nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CanHandleAndFlushPendingNotifications() failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
const RefPtr<Element> editingHost =
|
||||
ComputeEditingHost(LimitInBodyElement::No);
|
||||
if (NS_WARN_IF(editingHost &&
|
||||
editingHost->IsContentEditablePlainTextOnly())) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
rv = editActionData.MaybeDispatchBeforeInputEvent();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,
|
||||
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
|
||||
"MaybeDispatchBeforeInputEvent(), failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
|
@ -1248,10 +1282,21 @@ nsresult HTMLEditor::DeleteTableElementAndChildrenWithTransaction(
|
|||
NS_IMETHODIMP HTMLEditor::DeleteTable() {
|
||||
AutoEditActionDataSetter editActionData(*this,
|
||||
EditAction::eRemoveTableElement);
|
||||
nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CanHandleAndFlushPendingNotifications() failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
const RefPtr<Element> editingHost =
|
||||
ComputeEditingHost(LimitInBodyElement::No);
|
||||
if (NS_WARN_IF(editingHost &&
|
||||
editingHost->IsContentEditablePlainTextOnly())) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
rv = editActionData.MaybeDispatchBeforeInputEvent();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,
|
||||
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
|
||||
"MaybeDispatchBeforeInputEvent(), failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
|
@ -1279,10 +1324,21 @@ NS_IMETHODIMP HTMLEditor::DeleteTable() {
|
|||
NS_IMETHODIMP HTMLEditor::DeleteTableCell(int32_t aNumberOfCellsToDelete) {
|
||||
AutoEditActionDataSetter editActionData(*this,
|
||||
EditAction::eRemoveTableCellElement);
|
||||
nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CanHandleAndFlushPendingNotifications() failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
const RefPtr<Element> editingHost =
|
||||
ComputeEditingHost(LimitInBodyElement::No);
|
||||
if (NS_WARN_IF(editingHost &&
|
||||
editingHost->IsContentEditablePlainTextOnly())) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
rv = editActionData.MaybeDispatchBeforeInputEvent();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,
|
||||
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
|
||||
"MaybeDispatchBeforeInputEvent(), failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
|
@ -1570,10 +1626,21 @@ nsresult HTMLEditor::DeleteTableCellWithTransaction(
|
|||
NS_IMETHODIMP HTMLEditor::DeleteTableCellContents() {
|
||||
AutoEditActionDataSetter editActionData(*this,
|
||||
EditAction::eDeleteTableCellContents);
|
||||
nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CanHandleAndFlushPendingNotifications() failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
const RefPtr<Element> editingHost =
|
||||
ComputeEditingHost(LimitInBodyElement::No);
|
||||
if (NS_WARN_IF(editingHost &&
|
||||
editingHost->IsContentEditablePlainTextOnly())) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
rv = editActionData.MaybeDispatchBeforeInputEvent();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,
|
||||
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
|
||||
"MaybeDispatchBeforeInputEvent(), failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
|
@ -1661,10 +1728,21 @@ nsresult HTMLEditor::DeleteTableCellContentsWithTransaction() {
|
|||
NS_IMETHODIMP HTMLEditor::DeleteTableColumn(int32_t aNumberOfColumnsToDelete) {
|
||||
AutoEditActionDataSetter editActionData(*this,
|
||||
EditAction::eRemoveTableColumn);
|
||||
nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CanHandleAndFlushPendingNotifications() failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
const RefPtr<Element> editingHost =
|
||||
ComputeEditingHost(LimitInBodyElement::No);
|
||||
if (NS_WARN_IF(editingHost &&
|
||||
editingHost->IsContentEditablePlainTextOnly())) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
rv = editActionData.MaybeDispatchBeforeInputEvent();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,
|
||||
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
|
||||
"MaybeDispatchBeforeInputEvent(), failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
|
@ -1911,10 +1989,21 @@ nsresult HTMLEditor::DeleteTableColumnWithTransaction(Element& aTableElement,
|
|||
NS_IMETHODIMP HTMLEditor::DeleteTableRow(int32_t aNumberOfRowsToDelete) {
|
||||
AutoEditActionDataSetter editActionData(*this,
|
||||
EditAction::eRemoveTableRowElement);
|
||||
nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CanHandleAndFlushPendingNotifications() failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
const RefPtr<Element> editingHost =
|
||||
ComputeEditingHost(LimitInBodyElement::No);
|
||||
if (NS_WARN_IF(editingHost &&
|
||||
editingHost->IsContentEditablePlainTextOnly())) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
rv = editActionData.MaybeDispatchBeforeInputEvent();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,
|
||||
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
|
||||
"MaybeDispatchBeforeInputEvent(), failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
|
@ -2197,7 +2286,7 @@ nsresult HTMLEditor::DeleteTableRowWithTransaction(Element& aTableElement,
|
|||
NS_IMETHODIMP HTMLEditor::SelectTable() {
|
||||
AutoEditActionDataSetter editActionData(*this, EditAction::eSelectTable);
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::SelectTable() couldn't handle the job");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
@ -2225,7 +2314,7 @@ NS_IMETHODIMP HTMLEditor::SelectTable() {
|
|||
NS_IMETHODIMP HTMLEditor::SelectTableCell() {
|
||||
AutoEditActionDataSetter editActionData(*this, EditAction::eSelectTableCell);
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::SelectTableCell() couldn't handle the job");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
@ -2255,7 +2344,7 @@ NS_IMETHODIMP HTMLEditor::SelectAllTableCells() {
|
|||
AutoEditActionDataSetter editActionData(*this,
|
||||
EditAction::eSelectAllTableCells);
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::SelectAllTableCells() couldn't handle the job");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
@ -2355,7 +2444,7 @@ NS_IMETHODIMP HTMLEditor::SelectAllTableCells() {
|
|||
NS_IMETHODIMP HTMLEditor::SelectTableRow() {
|
||||
AutoEditActionDataSetter editActionData(*this, EditAction::eSelectTableRow);
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::SelectTableRow() couldn't handle the job");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
@ -2475,7 +2564,7 @@ NS_IMETHODIMP HTMLEditor::SelectTableColumn() {
|
|||
AutoEditActionDataSetter editActionData(*this,
|
||||
EditAction::eSelectTableColumn);
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::SelectTableColumn() couldn't handle the job");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
@ -2590,10 +2679,21 @@ NS_IMETHODIMP HTMLEditor::SelectTableColumn() {
|
|||
NS_IMETHODIMP HTMLEditor::SplitTableCell() {
|
||||
AutoEditActionDataSetter editActionData(*this,
|
||||
EditAction::eSplitTableCellElement);
|
||||
nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CanHandleAndFlushPendingNotifications() failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
const RefPtr<Element> editingHost =
|
||||
ComputeEditingHost(LimitInBodyElement::No);
|
||||
if (NS_WARN_IF(editingHost &&
|
||||
editingHost->IsContentEditablePlainTextOnly())) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
rv = editActionData.MaybeDispatchBeforeInputEvent();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,
|
||||
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
|
||||
"MaybeDispatchBeforeInputEvent(), failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
|
@ -2890,10 +2990,21 @@ NS_IMETHODIMP HTMLEditor::SwitchTableCellHeaderType(Element* aSourceCell,
|
|||
|
||||
AutoEditActionDataSetter editActionData(*this,
|
||||
EditAction::eSetTableCellElementType);
|
||||
nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CanHandleAndFlushPendingNotifications() failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
const RefPtr<Element> editingHost =
|
||||
ComputeEditingHost(LimitInBodyElement::No);
|
||||
if (NS_WARN_IF(editingHost &&
|
||||
editingHost->IsContentEditablePlainTextOnly())) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
rv = editActionData.MaybeDispatchBeforeInputEvent();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,
|
||||
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
|
||||
"MaybeDispatchBeforeInputEvent(), failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
|
@ -2945,10 +3056,21 @@ NS_IMETHODIMP HTMLEditor::SwitchTableCellHeaderType(Element* aSourceCell,
|
|||
NS_IMETHODIMP HTMLEditor::JoinTableCells(bool aMergeNonContiguousContents) {
|
||||
AutoEditActionDataSetter editActionData(*this,
|
||||
EditAction::eJoinTableCellElements);
|
||||
nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CanHandleAndFlushPendingNotifications() failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
const RefPtr<Element> editingHost =
|
||||
ComputeEditingHost(LimitInBodyElement::No);
|
||||
if (NS_WARN_IF(editingHost &&
|
||||
editingHost->IsContentEditablePlainTextOnly())) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
rv = editActionData.MaybeDispatchBeforeInputEvent();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,
|
||||
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
|
||||
"MaybeDispatchBeforeInputEvent(), failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
|
@ -3588,10 +3710,19 @@ nsresult HTMLEditor::FixBadColSpan(Element* aTable, int32_t aColIndex,
|
|||
|
||||
NS_IMETHODIMP HTMLEditor::NormalizeTable(Element* aTableOrElementInTable) {
|
||||
AutoEditActionDataSetter editActionData(*this, EditAction::eNormalizeTable);
|
||||
nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
if (NS_WARN_IF(!editActionData.CanHandle())) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
const RefPtr<Element> editingHost =
|
||||
ComputeEditingHost(LimitInBodyElement::No);
|
||||
if (NS_WARN_IF(editingHost &&
|
||||
editingHost->IsContentEditablePlainTextOnly())) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
nsresult rv = editActionData.MaybeDispatchBeforeInputEvent();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,
|
||||
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
|
||||
"MaybeDispatchBeforeInputEvent(), failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
|
@ -3727,7 +3858,7 @@ NS_IMETHODIMP HTMLEditor::GetCellIndexes(Element* aCellElement,
|
|||
|
||||
AutoEditActionDataSetter editActionData(*this, EditAction::eGetCellIndexes);
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::GetCellIndexes() couldn't handle the job");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
@ -3806,7 +3937,7 @@ NS_IMETHODIMP HTMLEditor::GetTableSize(Element* aTableOrElementInTable,
|
|||
|
||||
AutoEditActionDataSetter editActionData(*this, EditAction::eGetTableSize);
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::GetTableSize() couldn't handle the job");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
@ -3850,7 +3981,7 @@ NS_IMETHODIMP HTMLEditor::GetCellDataAt(
|
|||
|
||||
AutoEditActionDataSetter editActionData(*this, EditAction::eGetCellDataAt);
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::GetCellDataAt() couldn't handle the job");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
@ -3904,7 +4035,7 @@ NS_IMETHODIMP HTMLEditor::GetCellAt(Element* aTableElement, int32_t aRowIndex,
|
|||
|
||||
AutoEditActionDataSetter editActionData(*this, EditAction::eGetCellAt);
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::GetCellAt() couldn't handle the job");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
@ -4078,7 +4209,7 @@ NS_IMETHODIMP HTMLEditor::GetSelectedCells(
|
|||
|
||||
AutoEditActionDataSetter editActionData(*this, EditAction::eGetSelectedCells);
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::GetSelectedCells() couldn't handle the job");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
@ -4106,7 +4237,7 @@ NS_IMETHODIMP HTMLEditor::GetFirstSelectedCellInTable(int32_t* aRowIndex,
|
|||
AutoEditActionDataSetter editActionData(
|
||||
*this, EditAction::eGetFirstSelectedCellInTable);
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::GetFirstSelectedCellInTable() couldn't handle the job");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
|
@ -4234,7 +4365,7 @@ NS_IMETHODIMP HTMLEditor::GetSelectedOrParentTableElement(
|
|||
AutoEditActionDataSetter editActionData(
|
||||
*this, EditAction::eGetSelectedOrParentTableElement);
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::GetSelectedOrParentTableElement() couldn't handle the "
|
||||
"job");
|
||||
|
@ -4392,7 +4523,7 @@ NS_IMETHODIMP HTMLEditor::GetSelectedCellsType(Element* aElement,
|
|||
AutoEditActionDataSetter editActionData(*this,
|
||||
EditAction::eGetSelectedCellsType);
|
||||
nsresult rv = editActionData.CanHandleAndFlushPendingNotifications();
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::GetSelectedCellsType() couldn't handle the job");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
|
|
@ -559,6 +559,8 @@ skip-if = ["xorigin"] # Testing internal API for comm-central
|
|||
|
||||
["test_nsITableEditor_getTableSize.html"]
|
||||
|
||||
["test_nsITableEditor_in_plaintext-only.html"]
|
||||
|
||||
["test_nsITableEditor_insertTableCell.html"]
|
||||
|
||||
["test_nsITableEditor_insertTableColumn.html"]
|
||||
|
|
|
@ -0,0 +1,503 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title></title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(async () => {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["dom.element.contenteditable.plaintext-only.enabled", true]],
|
||||
});
|
||||
document.body.contentEditable = "plaintext-only";
|
||||
document.body.focus();
|
||||
const tableEditor = getHTMLEditor();
|
||||
|
||||
await (async function test_insertTableCell() {
|
||||
document.body.innerHTML = "<table><td><br></td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.insertTableCell(1, true);
|
||||
ok(false, "insertTableCell should fail in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
is(
|
||||
e.name,
|
||||
"NS_ERROR_NOT_AVAILABLE",
|
||||
"insertTableCell should throw NS_ERROR_NOT_AVAILABLE exception"
|
||||
);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "insertTableCell shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_insertTableColumn() {
|
||||
document.body.innerHTML = "<table><td><br></td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.insertTableColumn(1, true);
|
||||
ok(false, "insertTableColumn should fail in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
is(
|
||||
e.name,
|
||||
"NS_ERROR_NOT_AVAILABLE",
|
||||
"insertTableColumn should throw NS_ERROR_NOT_AVAILABLE exception"
|
||||
);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "insertTableColumn shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_insertTableRow() {
|
||||
document.body.innerHTML = "<table><td><br></td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.insertTableRow(1, true);
|
||||
ok(false, "insertTableRow should fail in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
is(
|
||||
e.name,
|
||||
"NS_ERROR_NOT_AVAILABLE",
|
||||
"insertTableRow should throw NS_ERROR_NOT_AVAILABLE exception"
|
||||
);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "insertTableRow shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_deleteTableCellContents() {
|
||||
document.body.innerHTML = "<table><td>abc</td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().selectAllChildren(td);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.deleteTableCellContents();
|
||||
ok(false, "deleteTableCellContents should fail in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
is(
|
||||
e.name,
|
||||
"NS_ERROR_NOT_AVAILABLE",
|
||||
"deleteTableCellContents should throw NS_ERROR_NOT_AVAILABLE exception"
|
||||
);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "deleteTableCellContents shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_deleteTableCell() {
|
||||
document.body.innerHTML = "<table><td><br></td><td><br></td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.deleteTableCell(1);
|
||||
ok(false, "deleteTableCell should fail in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
is(
|
||||
e.name,
|
||||
"NS_ERROR_NOT_AVAILABLE",
|
||||
"deleteTableCell should throw NS_ERROR_NOT_AVAILABLE exception"
|
||||
);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "deleteTableCell shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_deleteTableColumn() {
|
||||
document.body.innerHTML = "<table><td><br></td><td><br></td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.deleteTableColumn(1);
|
||||
ok(false, "deleteTableColumn should fail in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
is(
|
||||
e.name,
|
||||
"NS_ERROR_NOT_AVAILABLE",
|
||||
"deleteTableColumn should throw NS_ERROR_NOT_AVAILABLE exception"
|
||||
);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "deleteTableColumn shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_deleteTableRow() {
|
||||
document.body.innerHTML = "<table><tr><td><br></td></tr><tr><td><br></td></tr></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.deleteTableRow(1);
|
||||
ok(false, "deleteTableRow should fail in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
is(
|
||||
e.name,
|
||||
"NS_ERROR_NOT_AVAILABLE",
|
||||
"deleteTableRow should throw NS_ERROR_NOT_AVAILABLE exception"
|
||||
);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "deleteTableRow shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_selectTableCell() {
|
||||
document.body.innerHTML = "<table><td>abc</td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td.firstChild, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.selectTableCell();
|
||||
ok(true, "selectTableCell should succeed even in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
ok(false, `selectTableCell shouldn't fail in contenteditable=plaintext-only (${e.message})`);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "selectTableCell shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_selectTableRow() {
|
||||
document.body.innerHTML = "<table><td>abc</td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td.firstChild, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.selectTableRow();
|
||||
ok(true, "selectTableRow should succeed even in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
ok(false, `selectTableRow shouldn't fail in contenteditable=plaintext-only (${e.message})`);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "selectTableRow shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_selectTableColumn() {
|
||||
document.body.innerHTML = "<table><td>abc</td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td.firstChild, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.selectTableColumn();
|
||||
ok(true, "selectTableColumn should succeed even in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
ok(false, `selectTableColumn shouldn't fail in contenteditable=plaintext-only (${e.message})`);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "selectTableColumn shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_selectTable() {
|
||||
document.body.innerHTML = "<table><td>abc</td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td.firstChild, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.selectTable();
|
||||
ok(true, "selectTable should succeed even in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
ok(false, `selectTable shouldn't fail in contenteditable=plaintext-only (${e.message})`);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "selectTable shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_selectAllTableCells() {
|
||||
document.body.innerHTML = "<table><td>abc</td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td.firstChild, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.selectAllTableCells();
|
||||
ok(true, "selectAllTableCells should succeed even in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
ok(false, `selectAllTableCells shouldn't fail in contenteditable=plaintext-only (${e.message})`);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "selectAllTableCells shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_switchTableCellHeaderType() {
|
||||
document.body.innerHTML = "<table><td><br></td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.switchTableCellHeaderType(td);
|
||||
ok(false, "switchTableCellHeaderType should fail in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
is(
|
||||
e.name,
|
||||
"NS_ERROR_NOT_AVAILABLE",
|
||||
"switchTableCellHeaderType should throw NS_ERROR_NOT_AVAILABLE exception"
|
||||
);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "switchTableCellHeaderType shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_joinTableCells() {
|
||||
document.body.innerHTML = "<table><td><br></td><td><br></td></table>";
|
||||
const td1 = document.querySelector("td");
|
||||
const td2 = document.querySelector("td + td");
|
||||
td1.getBoundingClientRect();
|
||||
const range1 = document.createRange();
|
||||
range1.selectNode(td1);
|
||||
const range2 = document.createRange();
|
||||
range2.selectNode(td2);
|
||||
getSelection().removeAllRanges();
|
||||
getSelection().addRange(range1);
|
||||
getSelection().addRange(range2);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.joinTableCells(true);
|
||||
ok(false, "joinTableCells should fail in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
is(
|
||||
e.name,
|
||||
"NS_ERROR_NOT_AVAILABLE",
|
||||
"joinTableCells should throw NS_ERROR_NOT_AVAILABLE exception"
|
||||
);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "joinTableCells shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_splitTableCell() {
|
||||
document.body.innerHTML = "<table><tr><td colspan=\"2\" rowspan=\"2\"><br></td><td><br></td></tr><tr><td><br></td></tr></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.splitTableCell();
|
||||
ok(false, "splitTableCell should fail in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
is(
|
||||
e.name,
|
||||
"NS_ERROR_NOT_AVAILABLE",
|
||||
"splitTableCell should throw NS_ERROR_NOT_AVAILABLE exception"
|
||||
);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "splitTableCell shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_normalizeTable() {
|
||||
document.body.innerHTML = "<table><tr><td><br></td><td><br></td></tr><tr><td><br></td></tr></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.normalizeTable(document.querySelector("table"));
|
||||
ok(false, "normalizeTable should fail in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
is(
|
||||
e.name,
|
||||
"NS_ERROR_NOT_AVAILABLE",
|
||||
"normalizeTable should throw NS_ERROR_NOT_AVAILABLE exception"
|
||||
);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "normalizeTable shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_getCellIndexes() {
|
||||
document.body.innerHTML = "<table><td><br></td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
const rowIndex = {};
|
||||
const colIndex = {};
|
||||
tableEditor.getCellIndexes(td, rowIndex, colIndex);
|
||||
ok(true, "getCellIndexes should succeed even in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
ok(false, `getCellIndexes shouldn't fail in contenteditable=plaintext-only (${e.message})`);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "getCellIndexes shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_getTableSize() {
|
||||
document.body.innerHTML = "<table><td><br></td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
const rowSize = {};
|
||||
const colSize = {};
|
||||
tableEditor.getTableSize(td, rowSize, colSize);
|
||||
ok(true, "getTableSize should succeed even in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
ok(false, `getTableSize shouldn't fail in contenteditable=plaintext-only (${e.message})`);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "getTableSize shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_getCellAt() {
|
||||
document.body.innerHTML = "<table><td><br></td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.getCellAt(document.querySelector("table"), 0, 0);
|
||||
ok(true, "getCellAt should succeed even in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
ok(false, `getCellAt shouldn't fail in contenteditable=plaintext-only (${e.message})`);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "getCellAt shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_getCellDataAt() {
|
||||
document.body.innerHTML = "<table><td><br></td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
const cellElement = {},
|
||||
rowIndex = {}, colIndex = {},
|
||||
rowSpan = {}, colSpan = {},
|
||||
effectiveRowSpan = {}, effectiveColSpan = {},
|
||||
isSelected = {};
|
||||
tableEditor.getCellDataAt(
|
||||
document.querySelector("table"),
|
||||
0, 0,
|
||||
cellElement,
|
||||
rowIndex, colIndex,
|
||||
rowSpan, colSpan,
|
||||
effectiveRowSpan, effectiveColSpan,
|
||||
isSelected
|
||||
);
|
||||
ok(true, "getCellDataAt should succeed even in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
ok(false, `getCellDataAt shouldn't fail in contenteditable=plaintext-only (${e.message})`);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "getCellDataAt shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_getFirstRow() {
|
||||
document.body.innerHTML = "<table><td><br></td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.getFirstRow(document.querySelector("table"));
|
||||
ok(true, "getFirstRow should succeed even in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
ok(false, `getFirstRow shouldn't fail in contenteditable=plaintext-only (${e.message})`);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "getFirstRow shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_getSelectedOrParentTableElement() {
|
||||
document.body.innerHTML = "<table><td><br></td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
const tagName = {}, count = {};
|
||||
tableEditor.getSelectedOrParentTableElement(document.querySelector("table"), tagName, count);
|
||||
ok(true, "getSelectedOrParentTableElement should succeed even in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
ok(false, `getSelectedOrParentTableElement shouldn't fail in contenteditable=plaintext-only (${e.message})`);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "getSelectedOrParentTableElement shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_getSelectedCellsType() {
|
||||
document.body.innerHTML = "<table><td><br></td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.getSelectedCellsType(td);
|
||||
ok(true, "getSelectedCellsType should succeed even in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
ok(false, `getSelectedCellsType shouldn't fail in contenteditable=plaintext-only (${e.message})`);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "getSelectedCellsType shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_getFirstSelectedCellInTable() {
|
||||
document.body.innerHTML = "<table><td><br></td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
const rowIndex = {}, colIndex = {};
|
||||
tableEditor.getFirstSelectedCellInTable(document.querySelector("table"), rowIndex, colIndex);
|
||||
ok(true, "getFirstSelectedCellInTable should succeed even in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
ok(false, `getFirstSelectedCellInTable shouldn't fail in contenteditable=plaintext-only (${e.message})`);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "getFirstSelectedCellInTable shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
await (async function test_getSelectedCells() {
|
||||
document.body.innerHTML = "<table><td><br></td></table>";
|
||||
const td = document.querySelector("td");
|
||||
td.getBoundingClientRect();
|
||||
getSelection().collapse(td, 0);
|
||||
const innerHTML = document.body.innerHTML;
|
||||
try {
|
||||
tableEditor.getSelectedCells();
|
||||
ok(true, "getSelectedCells should succeed even in contenteditable=plaintext-only");
|
||||
} catch (e) {
|
||||
ok(false, `getSelectedCells shouldn't fail in contenteditable=plaintext-only (${e.message})`);
|
||||
}
|
||||
await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
|
||||
is(document.body.innerHTML, innerHTML, "getSelectedCells shouldn't change the DOM");
|
||||
})();
|
||||
|
||||
document.body.removeAttribute("contenteditable");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
function getHTMLEditor() {
|
||||
const Ci = SpecialPowers.Ci;
|
||||
const editingSession = SpecialPowers.wrap(window).docShell.editingSession;
|
||||
return editingSession.getEditorForWindow(window)
|
||||
.QueryInterface(Ci.nsITableEditor);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче