Skip to content

Commit

Permalink
Bug 1484128 - part 1: Create HTMLEditor::GetFirstSelectedTableCellEle…
Browse files Browse the repository at this point in the history
…ment() for internal use of HTMLEditor::GetFirstSelectedCell() r=m_kato

HTMLEditor::GetFirstSelectedCell() is an XPCOM method, but used internally a
lot.  Therefore, we should create a non-virtual method for internal use.

This patch creates HTMLEditor::GetFirstSelectedTableCellElement(), and it
won't return NS_SUCCESS_EDITOR_ELEMENT_NOT_FOUND since nobody needs the
value.  It's enough to check whether the result is nullptr without error for
any callers.

Differential Revision: https://phabricator.services.mozilla.com/D4060
  • Loading branch information
masayuki-nakano committed Aug 24, 2018
1 parent ce81633 commit d671fc6
Show file tree
Hide file tree
Showing 6 changed files with 256 additions and 128 deletions.
18 changes: 11 additions & 7 deletions editor/libeditor/HTMLEditRules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2350,18 +2350,21 @@ HTMLEditRules::WillDeleteSelection(nsIEditor::EDirection aAction,
}

// First check for table selection mode. If so, hand off to table editor.
RefPtr<Element> cell;
nsresult rv =
HTMLEditorRef().GetFirstSelectedCell(nullptr, getter_AddRefs(cell));
if (NS_SUCCEEDED(rv) && cell) {
rv = HTMLEditorRef().DeleteTableCellContents();
ErrorResult error;
RefPtr<Element> cellElement =
HTMLEditorRef().GetFirstSelectedTableCellElement(SelectionRef(),
error);
if (cellElement) {
error.SuppressException();
nsresult rv = HTMLEditorRef().DeleteTableCellContents();
if (NS_WARN_IF(!CanHandleEditAction())) {
return NS_ERROR_EDITOR_DESTROYED;
}
*aHandled = true;
return rv;
}
cell = nullptr;
nsresult rv = error.StealNSResult();
cellElement = nullptr;

// origCollapsed is used later to determine whether we should join blocks. We
// don't really care about bCollapsed because it will be modified by
Expand Down Expand Up @@ -2443,7 +2446,8 @@ HTMLEditRules::WillDeleteSelection(nsIEditor::EDirection aAction,
if (!visNode) {
// Can't find anything to delete!
*aCancel = true;
// XXX This is the result of HTMLEditorRef().GetFirstSelectedCell().
// XXX This is the result of
// HTMLEditorRef().GetFirstSelectedTableCellElement().
// The value could be both an error and NS_OK.
return rv;
}
Expand Down
31 changes: 22 additions & 9 deletions editor/libeditor/HTMLEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3003,18 +3003,31 @@ HTMLEditor::SetHTMLBackgroundColorWithTransaction(const nsAString& aColor)
RefPtr<nsAtom> bgColorAtom = NS_Atomize("bgcolor");
if (element) {
if (selectedCount > 0) {
// Traverse all selected cells
RefPtr<Element> cell;
rv = GetFirstSelectedCell(nullptr, getter_AddRefs(cell));
if (NS_SUCCEEDED(rv) && cell) {
while (cell) {
rv = setColor ?
SetAttributeWithTransaction(*cell, *bgColorAtom, aColor) :
RemoveAttributeWithTransaction(*cell, *bgColorAtom);
RefPtr<Selection> selection = GetSelection();
if (NS_WARN_IF(!selection)) {
return NS_ERROR_FAILURE;
}
IgnoredErrorResult ignoredError;
RefPtr<Element> cellElement =
GetFirstSelectedTableCellElement(*selection, ignoredError);
if (cellElement) {
if (setColor) {
while (cellElement) {
rv =
SetAttributeWithTransaction(*cellElement, *bgColorAtom, aColor);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
GetNextSelectedCell(nullptr, getter_AddRefs(cellElement));
}
return NS_OK;
}
while (cellElement) {
rv = RemoveAttributeWithTransaction(*cellElement, *bgColorAtom);
if (NS_FAILED(rv)) {
return rv;
}
GetNextSelectedCell(nullptr, getter_AddRefs(cell));
GetNextSelectedCell(nullptr, getter_AddRefs(cellElement));
}
return NS_OK;
}
Expand Down
29 changes: 26 additions & 3 deletions editor/libeditor/HTMLEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,28 @@ class HTMLEditor final : public TextEditor
*/
Element* GetSelectionContainerElement(Selection& aSelection) const;

/**
* GetFirstSelectedTableCellElement() returns a <td> or <th> element if
* first range of Selection (i.e., result of Selection::GetRangeAt(0))
* selects a <td> element or <th> element. Even if Selection is in
* a cell element, this returns nullptr. And even if 2nd or later
* range of Selection selects a cell element, also returns nullptr.
* Note that when this looks for a cell element, this resets the internal
* index of ranges of Selection. When you call GetNextSelectedCell() after
* a call of this, it'll return 2nd selected cell if there is.
*
* @param aSelection Selection for this editor.
* @param aRv Returns error if there is no selection or
* first range of Selection is unexpected.
* @return A <td> or <th> element is selected by first
* range of Selection. Note that the range must
* be: startContaienr and endContainer are same
* <tr> element, startOffset + 1 equals endOffset.
*/
already_AddRefed<Element>
GetFirstSelectedTableCellElement(Selection& aSelection,
ErrorResult& aRv) const;

void IsNextCharInNodeWhitespace(nsIContent* aContent,
int32_t aOffset,
bool* outIsSpace,
Expand Down Expand Up @@ -1214,7 +1236,7 @@ class HTMLEditor final : public TextEditor
nsresult GetLastCellInRow(nsINode* aRowNode,
nsINode** aCellNode);

nsresult GetCellFromRange(nsRange* aRange, Element** aCell);
static nsresult GetCellFromRange(nsRange* aRange, Element** aCell);

/**
* This sets background on the appropriate container element (table, cell,)
Expand Down Expand Up @@ -1855,8 +1877,9 @@ class HTMLEditor final : public TextEditor
bool mCSSAware;
UniquePtr<CSSEditUtils> mCSSEditUtils;

// Used by GetFirstSelectedCell and GetNextSelectedCell
int32_t mSelectedCellIndex;
// mSelectedCellIndex is reset by GetFirstSelectedTableCellElement(),
// then, it'll be referred and incremented by GetNextSelectedCell().
mutable int32_t mSelectedCellIndex;

nsString mLastStyleSheetURL;
nsString mLastOverrideStyleSheetURL;
Expand Down
11 changes: 7 additions & 4 deletions editor/libeditor/HTMLEditorDataTransfer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,9 @@ HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString,

// Get selection
RefPtr<Selection> selection = GetSelection();
NS_ENSURE_STATE(selection);
if (NS_WARN_IF(!selection)) {
return NS_ERROR_FAILURE;
}

// create a dom document fragment that represents the structure to paste
nsCOMPtr<nsINode> fragmentAsNode, streamStartParent, streamEndParent;
Expand Down Expand Up @@ -282,9 +284,10 @@ HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString,
// Are there any table elements in the list?
// check for table cell selection mode
bool cellSelectionMode = false;
RefPtr<Element> cell;
rv = GetFirstSelectedCell(nullptr, getter_AddRefs(cell));
if (NS_SUCCEEDED(rv) && cell) {
IgnoredErrorResult ignoredError;
RefPtr<Element> cellElement =
GetFirstSelectedTableCellElement(*selection, ignoredError);
if (cellElement) {
cellSelectionMode = true;
}

Expand Down
Loading

0 comments on commit d671fc6

Please sign in to comment.