Bug 1540029 - part 5: Replace HTMLEditRules::GetListState() with new stack class r=m_kato

It takes a lot of `bool` out arguments.  Therefore, we should make it a
stack only class and caller should retrieve only necessary information.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Masayuki Nakano 2019-09-18 03:39:00 +00:00
parent b3115e6972
commit 320d1209c9
7 changed files with 80 additions and 48 deletions

View File

@ -81,6 +81,7 @@ class IMEContentObserver;
class InsertNodeTransaction;
class InsertTextTransaction;
class JoinNodeTransaction;
class ListElementSelectionState;
class PlaceholderTransaction;
class PresShell;
class SplitNodeResult;
@ -2669,6 +2670,7 @@ class EditorBase : public nsIEditor,
friend class InsertNodeTransaction;
friend class InsertTextTransaction;
friend class JoinNodeTransaction;
friend class ListElementSelectionState;
friend class SplitNodeTransaction;
friend class TextEditRules;
friend class TypeInState;

View File

@ -747,59 +747,62 @@ EditActionResult HTMLEditor::CanHandleHTMLEditSubAction() const {
return EditActionIgnored();
}
nsresult HTMLEditRules::GetListState(bool* aMixed, bool* aOL, bool* aUL,
bool* aDL) {
NS_ENSURE_TRUE(aMixed && aOL && aUL && aDL, NS_ERROR_NULL_POINTER);
*aMixed = false;
*aOL = false;
*aUL = false;
*aDL = false;
bool bNonList = false;
ListElementSelectionState::ListElementSelectionState(HTMLEditor& aHTMLEditor,
ErrorResult& aRv) {
MOZ_ASSERT(!aRv.Failed());
if (NS_WARN_IF(!CanHandleEditAction())) {
return NS_ERROR_EDITOR_DESTROYED;
if (NS_WARN_IF(aHTMLEditor.Destroyed())) {
aRv.Throw(NS_ERROR_EDITOR_DESTROYED);
return;
}
AutoSafeEditorData setData(*this, *mHTMLEditor);
// XXX Should we create another constructor which won't create
// AutoEditActionDataSetter? Or should we create another
// AutoEditActionDataSetter which won't nest edit action?
EditorBase::AutoEditActionDataSetter editActionData(aHTMLEditor,
EditAction::eNotEditing);
if (NS_WARN_IF(!editActionData.CanHandle())) {
aRv = EditorBase::ToGenericNSResult(NS_ERROR_EDITOR_DESTROYED);
return;
}
AutoTArray<OwningNonNull<nsINode>, 64> arrayOfNodes;
nsresult rv = HTMLEditorRef().CollectEditTargetNodesInExtendedSelectionRanges(
nsresult rv = aHTMLEditor.CollectEditTargetNodesInExtendedSelectionRanges(
arrayOfNodes, EditSubAction::eCreateOrChangeList,
HTMLEditor::CollectNonEditableNodes::No);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
aRv = EditorBase::ToGenericNSResult(rv);
return;
}
// Examine list type for nodes in selection.
for (const auto& curNode : arrayOfNodes) {
if (!curNode->IsElement()) {
bNonList = true;
mIsOtherContentSelected = true;
} else if (curNode->IsHTMLElement(nsGkAtoms::ul)) {
*aUL = true;
mIsULElementSelected = true;
} else if (curNode->IsHTMLElement(nsGkAtoms::ol)) {
*aOL = true;
mIsOLElementSelected = true;
} else if (curNode->IsHTMLElement(nsGkAtoms::li)) {
if (dom::Element* parent = curNode->GetParentElement()) {
if (Element* parent = curNode->GetParentElement()) {
if (parent->IsHTMLElement(nsGkAtoms::ul)) {
*aUL = true;
mIsULElementSelected = true;
} else if (parent->IsHTMLElement(nsGkAtoms::ol)) {
*aOL = true;
mIsOLElementSelected = true;
}
}
} else if (curNode->IsAnyOfHTMLElements(nsGkAtoms::dl, nsGkAtoms::dt,
nsGkAtoms::dd)) {
*aDL = true;
mIsDLElementSelected = true;
} else {
bNonList = true;
mIsOtherContentSelected = true;
}
if (mIsULElementSelected && mIsOLElementSelected && mIsDLElementSelected &&
mIsOtherContentSelected) {
break;
}
}
// hokey arithmetic with booleans
if ((*aUL + *aOL + *aDL + bNonList) > 1) {
*aMixed = true;
}
return NS_OK;
}
nsresult HTMLEditRules::GetListItemState(bool* aMixed, bool* aLI, bool* aDT,

View File

@ -59,8 +59,6 @@ class HTMLEditRules : public TextEditRules {
virtual nsresult Init(TextEditor* aTextEditor) override;
virtual nsresult DetachEditor() override;
MOZ_CAN_RUN_SCRIPT
nsresult GetListState(bool* aMixed, bool* aOL, bool* aUL, bool* aDL);
MOZ_CAN_RUN_SCRIPT
nsresult GetListItemState(bool* aMixed, bool* aLI, bool* aDT, bool* aDD);
MOZ_CAN_RUN_SCRIPT

View File

@ -2041,17 +2041,21 @@ HTMLEditor::GetListState(bool* aMixed, bool* aOL, bool* aUL, bool* aDL) {
NS_WARN_IF(!aDL)) {
return NS_ERROR_INVALID_ARG;
}
if (!mRules) {
if (!mInitSucceeded) {
return NS_ERROR_NOT_INITIALIZED;
}
AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
if (NS_WARN_IF(!editActionData.CanHandle())) {
return NS_ERROR_NOT_INITIALIZED;
ErrorResult error;
ListElementSelectionState state(*this, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
RefPtr<HTMLEditRules> htmlRules(mRules->AsHTMLEditRules());
return htmlRules->GetListState(aMixed, aOL, aUL, aDL);
*aMixed = state.IsNotOneTypeListElementSelected();
*aOL = state.IsOLElementSelected();
*aUL = state.IsULElementSelected();
*aDL = state.IsDLElementSelected();
return NS_OK;
}
NS_IMETHODIMP

View File

@ -44,6 +44,7 @@ class AutoSelectionSetterAfterTableEdit;
class AutoSetTemporaryAncestorLimiter;
class EditActionResult;
class EmptyEditableFunctor;
class ListElementSelectionState;
class MoveNodeResult;
class ResizerSelectionListener;
class SplitRangeOffFromNodeResult;
@ -4364,12 +4365,37 @@ class HTMLEditor final : public TextEditor,
friend class EditorBase;
friend class EmptyEditableFunctor;
friend class HTMLEditRules;
friend class ListElementSelectionState;
friend class SlurpBlobEventListener;
friend class TextEditor;
friend class WSRunObject;
friend class WSRunScanner;
};
/**
* ListElementSelectionState class gets which list element is selected right
* now.
*/
class MOZ_STACK_CLASS ListElementSelectionState final {
public:
ListElementSelectionState() = delete;
ListElementSelectionState(HTMLEditor& aHTMLEditor, ErrorResult& aRv);
bool IsOLElementSelected() const { return mIsOLElementSelected; }
bool IsULElementSelected() const { return mIsULElementSelected; }
bool IsDLElementSelected() const { return mIsDLElementSelected; }
bool IsNotOneTypeListElementSelected() const {
return (mIsOLElementSelected + mIsULElementSelected + mIsDLElementSelected +
mIsOtherContentSelected) > 1;
}
private:
bool mIsOLElementSelected = false;
bool mIsULElementSelected = false;
bool mIsDLElementSelected = false;
bool mIsOtherContentSelected = false;
};
} // namespace mozilla
mozilla::HTMLEditor* nsIEditor::AsHTMLEditor() {

View File

@ -29,7 +29,6 @@ namespace mozilla {
using dom::Element;
// prototype
MOZ_CAN_RUN_SCRIPT
static nsresult GetListState(HTMLEditor* aHTMLEditor, bool* aMixed,
nsAString& aLocalName);
@ -1315,27 +1314,28 @@ nsresult InsertTagCommand::GetCommandStateParams(
*****************************************************************************/
static nsresult GetListState(HTMLEditor* aHTMLEditor, bool* aMixed,
nsAString& aLocalName)
MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
nsAString& aLocalName) {
MOZ_ASSERT(aHTMLEditor);
MOZ_ASSERT(aMixed);
*aMixed = false;
aLocalName.Truncate();
bool bOL, bUL, bDL;
nsresult rv = aHTMLEditor->GetListState(aMixed, &bOL, &bUL, &bDL);
NS_ENSURE_SUCCESS(rv, rv);
if (*aMixed) {
ErrorResult error;
ListElementSelectionState state(*aHTMLEditor, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
if (state.IsNotOneTypeListElementSelected()) {
*aMixed = true;
return NS_OK;
}
if (bOL) {
if (state.IsOLElementSelected()) {
aLocalName.AssignLiteral("ol");
} else if (bUL) {
} else if (state.IsULElementSelected()) {
aLocalName.AssignLiteral("ul");
} else if (bDL) {
} else if (state.IsDLElementSelected()) {
aLocalName.AssignLiteral("dl");
}
return NS_OK;

View File

@ -253,7 +253,6 @@ interface nsIHTMLEditor : nsISupports
* @param aUL true if an "ul" list is selected.
* @param aDL true if a "dl" list is selected.
*/
[can_run_script]
void getListState(out boolean aMixed, out boolean aOL, out boolean aUL,
out boolean aDL);