Bug 1460509 - part 18: Make HTMLEditRules::ChangeIndentation() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato
Additionally, this patch renames it to ChangeMarginStart() for making its
job clearer and add two inline wrapper methods.
MozReview-Commit-ID: L2GfLKhT6sa
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -4457,17 +4457,21 @@ HTMLEditRules::WillCSSIndent(bool* aCanc
RefPtr<Element> theBlock =
HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::div,
splitNodeResult.SplitPoint());
if (NS_WARN_IF(!theBlock)) {
return NS_ERROR_FAILURE;
}
// remember our new block for postprocessing
mNewBlock = theBlock;
- ChangeIndentation(*theBlock, Change::plus);
+ nsresult rv = IncreaseMarginToIndent(*theBlock);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
+ NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to increase indentation");
// delete anything that was in the list of nodes
while (!arrayOfNodes.IsEmpty()) {
OwningNonNull<nsINode> curNode = arrayOfNodes[0];
rv = HTMLEditorRef().DeleteNodeWithTransaction(*curNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
arrayOfNodes.RemoveElementAt(0);
@@ -4572,17 +4576,21 @@ HTMLEditRules::WillCSSIndent(bool* aCanc
return rv;
}
continue;
}
// Not a list item.
if (IsBlockNode(*curNode)) {
- ChangeIndentation(*curNode->AsElement(), Change::plus);
+ nsresult rv = IncreaseMarginToIndent(*curNode->AsElement());
+ if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
+ NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to inrease indentation");
curQuote = nullptr;
continue;
}
if (!curQuote) {
// First, check that our element can contain a div.
if (!HTMLEditorRef().CanContainTag(*atCurNode.GetContainer(),
*nsGkAtoms::div)) {
@@ -4595,17 +4603,21 @@ HTMLEditRules::WillCSSIndent(bool* aCanc
return splitNodeResult.Rv();
}
curQuote =
HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::div,
splitNodeResult.SplitPoint());
if (NS_WARN_IF(!curQuote)) {
return NS_ERROR_FAILURE;
}
- ChangeIndentation(*curQuote, Change::plus);
+ nsresult rv = IncreaseMarginToIndent(*curQuote);
+ if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
+ NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to increase indentation");
// remember our new block for postprocessing
mNewBlock = curQuote;
// curQuote is now the correct thing to put curNode in
}
// tuck the node into the end of the active blockquote
rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
*curQuote);
@@ -4971,17 +4983,22 @@ HTMLEditRules::WillOutdent(bool* aCancel
if (useCSS && IsBlockNode(curNode)) {
nsAtom& marginProperty = MarginPropertyAtomForIndent(curNode);
nsAutoString value;
CSSEditUtils::GetSpecifiedProperty(curNode, marginProperty, value);
float f;
RefPtr<nsAtom> unit;
CSSEditUtils::ParseLength(value, &f, getter_AddRefs(unit));
if (f > 0) {
- ChangeIndentation(*curNode->AsElement(), Change::minus);
+ nsresult rv = DecreaseMarginToOutdent(*curNode->AsElement());
+ if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
+ NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
+ "Failed to decrease indentation");
continue;
}
}
// Is it a list item?
if (HTMLEditUtils::IsListItem(curNode)) {
// If it is a list item, that means we are not outdenting whole list.
// So we need to finish up dealing with any curBlockQuote, and then pop
// this list item.
@@ -5109,17 +5126,22 @@ HTMLEditRules::WillOutdent(bool* aCancel
nsCOMPtr<Element> element;
if (curNode->GetAsText()) {
// We want to outdent the parent of text nodes
element = curNode->GetParentElement();
} else if (curNode->IsElement()) {
element = curNode->AsElement();
}
if (element) {
- ChangeIndentation(*element, Change::minus);
+ nsresult rv = DecreaseMarginToOutdent(*element);
+ if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
+ NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
+ "Failed to decrease indentation");
}
}
}
}
if (curBlockQuote) {
// We have a blockquote we haven't finished handling
rv = OutdentPartOfBlock(*curBlockQuote, *firstBQChild, *lastBQChild,
curBlockQuoteIsIndentedWithCSS,
@@ -5278,17 +5300,17 @@ HTMLEditRules::OutdentPartOfBlock(Elemen
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
if (middleNode->IsElement()) {
// We do nothing if middleNode isn't an element
- nsresult rv = ChangeIndentation(*middleNode->AsElement(), Change::minus);
+ nsresult rv = DecreaseMarginToOutdent(*middleNode->AsElement());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
return NS_OK;
}
@@ -9877,33 +9899,36 @@ HTMLEditRules::AlignBlock(Element& aElem
aAlignType, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult
-HTMLEditRules::ChangeIndentation(Element& aElement,
- Change aChange)
+HTMLEditRules::ChangeMarginStart(Element& aElement,
+ bool aIncrease)
{
MOZ_ASSERT(IsEditorDataAvailable());
nsAtom& marginProperty = MarginPropertyAtomForIndent(aElement);
nsAutoString value;
CSSEditUtils::GetSpecifiedProperty(aElement, marginProperty, value);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
float f;
RefPtr<nsAtom> unit;
CSSEditUtils::ParseLength(value, &f, getter_AddRefs(unit));
if (!f) {
nsAutoString defaultLengthUnit;
CSSEditUtils::GetDefaultLengthUnit(defaultLengthUnit);
unit = NS_Atomize(defaultLengthUnit);
}
- int8_t multiplier = aChange == Change::plus ? +1 : -1;
+ int8_t multiplier = aIncrease ? +1 : -1;
if (nsGkAtoms::in == unit) {
f += NS_EDITOR_INDENT_INCREMENT_IN * multiplier;
} else if (nsGkAtoms::cm == unit) {
f += NS_EDITOR_INDENT_INCREMENT_CM * multiplier;
} else if (nsGkAtoms::mm == unit) {
f += NS_EDITOR_INDENT_INCREMENT_MM * multiplier;
} else if (nsGkAtoms::pt == unit) {
f += NS_EDITOR_INDENT_INCREMENT_PT * multiplier;
@@ -9920,31 +9945,40 @@ HTMLEditRules::ChangeIndentation(Element
}
if (0 < f) {
nsAutoString newValue;
newValue.AppendFloat(f);
newValue.Append(nsDependentAtomString(unit));
HTMLEditorRef().mCSSEditUtils->SetCSSProperty(aElement, marginProperty,
newValue);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
return NS_OK;
}
HTMLEditorRef().mCSSEditUtils->RemoveCSSProperty(aElement, marginProperty,
value);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
// Remove unnecessary divs
if (!aElement.IsHTMLElement(nsGkAtoms::div) ||
&aElement == HTMLEditorRef().GetActiveEditingHost() ||
!HTMLEditorRef().IsDescendantOfEditorRoot(&aElement) ||
HTMLEditor::HasAttributes(&aElement)) {
return NS_OK;
}
nsresult rv = HTMLEditorRef().RemoveContainerWithTransaction(aElement);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult
HTMLEditRules::WillAbsolutePosition(bool* aCancel,
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -588,18 +588,53 @@ protected:
bool IsEmptyInline(nsINode& aNode);
bool ListIsEmptyLine(nsTArray<OwningNonNull<nsINode>>& arrayOfNodes);
nsresult RemoveAlignment(nsINode& aNode, const nsAString& aAlignType,
bool aChildrenOnly);
nsresult MakeSureElemStartsOrEndsOnCR(nsINode& aNode, bool aStarts);
enum class ContentsOnly { no, yes };
nsresult AlignBlock(Element& aElement,
const nsAString& aAlignType, ContentsOnly aContentsOnly);
- enum class Change { minus, plus };
- nsresult ChangeIndentation(Element& aElement, Change aChange);
+
+ /**
+ * IncreaseMarginToIndent() increases the margin of aElement. See the
+ * document of ChangeMarginStart() for the detail.
+ * XXX This is not aware of vertical writing-mode.
+ *
+ * @param aElement The element to be indented.
+ */
+ MOZ_MUST_USE nsresult IncreaseMarginToIndent(Element& aElement)
+ {
+ return ChangeMarginStart(aElement, true);
+ }
+
+ /**
+ * DecreaseMarginToOutdent() decreases the margin of aElement. See the
+ * document of ChangeMarginStart() for the detail.
+ * XXX This is not aware of vertical writing-mode.
+ *
+ * @param aElement The element to be outdented.
+ */
+ MOZ_MUST_USE nsresult DecreaseMarginToOutdent(Element& aElement)
+ {
+ return ChangeMarginStart(aElement, false);
+ }
+
+ /**
+ * ChangeMarginStart() changes margin of aElement to indent or outdent.
+ * However, use IncreaseMarginToIndent() and DecreaseMarginToOutdent()
+ * instead. If it's rtl text, margin-right will be changed. Otherwise,
+ * margin-left.
+ * XXX This is not aware of vertical writing-mode.
+ *
+ * @param aElement The element to be indented or outdented.
+ * @param aIncrease true for indent, false for outdent.
+ */
+ MOZ_MUST_USE nsresult ChangeMarginStart(Element& aElement, bool aIncrease);
+
void DocumentModifiedWorker();
/**
* InitStyleCacheArray() initializes aStyleCache for usable with
* GetInlineStyles().
*/
void InitStyleCacheArray(StyleCache aStyleCache[SIZE_STYLE_TABLE]);