mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
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:
parent
b3115e6972
commit
320d1209c9
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user