Bug 1742933 - part 11: Create a pref to get back the traditional behavior r=m_kato
For avoiding simple back-out of the patches when we get serious regression reports, we should have a pref to disable the new pref. Differential Revision: https://phabricator.services.mozilla.com/D140475
This commit is contained in:
@@ -3052,15 +3052,21 @@ EditActionResult HTMLEditor::ChangeSelectedHardLinesToList(
|
||||
[&](Element& aListElement) MOZ_CAN_RUN_SCRIPT_BOUNDARY {
|
||||
Result<RefPtr<Element>, nsresult> listItemElementOrError =
|
||||
CreateAndInsertElement(
|
||||
WithTransaction::No, aListItemElementTagName,
|
||||
aListElement.IsInComposedDoc() ? WithTransaction::Yes
|
||||
: WithTransaction::No,
|
||||
aListItemElementTagName,
|
||||
EditorDOMPoint(&aListElement, 0u),
|
||||
[](Element& aListItemElement) -> nsresult {
|
||||
return NS_OK;
|
||||
});
|
||||
if (listItemElementOrError.isErr()) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::CreateAndInsertElement(WithTransaction::Yes) "
|
||||
"failed");
|
||||
NS_WARNING(nsPrintfCString(
|
||||
"HTMLEditor::CreateAndInsertElement(%s) failed",
|
||||
ToString(aListElement.IsInComposedDoc()
|
||||
? WithTransaction::Yes
|
||||
: WithTransaction::No)
|
||||
.c_str())
|
||||
.get());
|
||||
return listItemElementOrError.unwrapErr();
|
||||
}
|
||||
MOZ_ASSERT(listItemElementOrError.inspect());
|
||||
@@ -5707,13 +5713,17 @@ nsresult HTMLEditor::AlignBlockContentsWithDivElement(
|
||||
WithTransaction::Yes, *nsGkAtoms::div, EditorDOMPoint(&aBlockElement, 0u),
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY due to bug 1758868
|
||||
[&](Element& aDivElement) MOZ_CAN_RUN_SCRIPT_BOUNDARY {
|
||||
// aDivElement has not been connected yet so that we do not need
|
||||
// transaction of setting align attribute here.
|
||||
nsresult rv = SetAttributeOrEquivalent(&aDivElement, nsGkAtoms::align,
|
||||
aAlignType, false);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"EditorBase::SetAttributeOrEquivalent("
|
||||
"nsGkAtoms::align) failed");
|
||||
// If aDivElement has not been connected yet, we do not need transaction
|
||||
// of setting align attribute here.
|
||||
nsresult rv =
|
||||
SetAttributeOrEquivalent(&aDivElement, nsGkAtoms::align, aAlignType,
|
||||
!aDivElement.IsInComposedDoc());
|
||||
NS_WARNING_ASSERTION(
|
||||
NS_SUCCEEDED(rv),
|
||||
nsPrintfCString("EditorBase::SetAttributeOrEquivalent(nsGkAtoms:: "
|
||||
"align, \"...\", %s) failed",
|
||||
!aDivElement.IsInComposedDoc() ? "true" : "false")
|
||||
.get());
|
||||
return rv;
|
||||
});
|
||||
if (maybeNewDivElement.isErr()) {
|
||||
@@ -6953,15 +6963,23 @@ nsresult HTMLEditor::HandleInsertParagraphInHeadingElement(
|
||||
[&](Element& aDivOrParagraphElement) MOZ_CAN_RUN_SCRIPT_BOUNDARY {
|
||||
// We don't make inserting new <br> element undoable
|
||||
// because removing the new element from the DOM tree
|
||||
// gets same result for the user.
|
||||
// gets same result for the user if aDivOrParagraphElement
|
||||
// has not been connected yet.
|
||||
Result<RefPtr<Element>, nsresult> brElementOrError =
|
||||
InsertBRElement(
|
||||
WithTransaction::No,
|
||||
aDivOrParagraphElement.IsInComposedDoc()
|
||||
? WithTransaction::Yes
|
||||
: WithTransaction::No,
|
||||
EditorDOMPoint(&aDivOrParagraphElement, 0u));
|
||||
if (brElementOrError.isErr()) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::InsertBRElement(WithTransaction::No) "
|
||||
"failed");
|
||||
nsPrintfCString(
|
||||
"HTMLEditor::InsertBRElement(%s) failed",
|
||||
ToString(aDivOrParagraphElement.IsInComposedDoc()
|
||||
? WithTransaction::Yes
|
||||
: WithTransaction::No)
|
||||
.c_str())
|
||||
.get());
|
||||
return brElementOrError.unwrapErr();
|
||||
}
|
||||
return NS_OK;
|
||||
@@ -7392,13 +7410,20 @@ nsresult HTMLEditor::HandleInsertParagraphInListItemElement(
|
||||
[&](Element& aDivOrParagraphElement) MOZ_CAN_RUN_SCRIPT_BOUNDARY {
|
||||
// We don't make inserting new <br> element undoable because
|
||||
// removing the new element from the DOM tree gets same result for
|
||||
// the user.
|
||||
// the user if aDivOrParagraphElement has not been connected yet.
|
||||
Result<RefPtr<Element>, nsresult> brElementOrError =
|
||||
InsertBRElement(WithTransaction::No,
|
||||
InsertBRElement(aDivOrParagraphElement.IsInComposedDoc()
|
||||
? WithTransaction::Yes
|
||||
: WithTransaction::No,
|
||||
EditorDOMPoint(&aDivOrParagraphElement, 0u));
|
||||
if (brElementOrError.isErr()) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::InsertBRElement(WithTransaction::No) failed");
|
||||
NS_WARNING(nsPrintfCString(
|
||||
"HTMLEditor::InsertBRElement(%s) failed",
|
||||
ToString(aDivOrParagraphElement.IsInComposedDoc()
|
||||
? WithTransaction::Yes
|
||||
: WithTransaction::No)
|
||||
.c_str())
|
||||
.get());
|
||||
return brElementOrError.unwrapErr();
|
||||
}
|
||||
return NS_OK;
|
||||
|
||||
@@ -473,21 +473,29 @@ NS_IMETHODIMP HTMLEditor::SetDocumentCharacterSet(
|
||||
CreateAndInsertElement(
|
||||
WithTransaction::Yes, *nsGkAtoms::meta,
|
||||
EditorDOMPoint(primaryHeadElement, 0), [&](Element& aMetaElement) {
|
||||
DebugOnly<nsresult> rvIgnored =
|
||||
aMetaElement.SetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv,
|
||||
u"Content-Type"_ns, false);
|
||||
DebugOnly<nsresult> rvIgnored = aMetaElement.SetAttr(
|
||||
kNameSpaceID_None, nsGkAtoms::httpEquiv, u"Content-Type"_ns,
|
||||
aMetaElement.IsInComposedDoc());
|
||||
NS_WARNING_ASSERTION(
|
||||
NS_SUCCEEDED(rvIgnored),
|
||||
"Element::SetAttr(nsGkAtoms::httpEquiv, Content-Type) "
|
||||
"failed, but ignored");
|
||||
nsPrintfCString(
|
||||
"Element::SetAttr(nsGkAtoms::httpEquiv, \"Content-Type\", "
|
||||
"%s) failed, but ignored",
|
||||
aMetaElement.IsInComposedDoc() ? "true" : "false")
|
||||
.get());
|
||||
rvIgnored =
|
||||
aMetaElement.SetAttr(kNameSpaceID_None, nsGkAtoms::content,
|
||||
u"text/html;charset="_ns +
|
||||
NS_ConvertASCIItoUTF16(aCharacterSet),
|
||||
false);
|
||||
aMetaElement.IsInComposedDoc());
|
||||
NS_WARNING_ASSERTION(
|
||||
NS_SUCCEEDED(rvIgnored),
|
||||
"Element::SetAttr(nsGkAtoms::content) failed, but ignored");
|
||||
nsPrintfCString(
|
||||
"Element::SetAttr(nsGkAtoms::content, "
|
||||
"\"text/html;charset=%s\", %s) failed, but ignored",
|
||||
nsPromiseFlatCString(aCharacterSet).get(),
|
||||
aMetaElement.IsInComposedDoc() ? "true" : "false")
|
||||
.get());
|
||||
return NS_OK;
|
||||
});
|
||||
if (maybeNewMetaElement.isErr()) {
|
||||
@@ -2975,9 +2983,8 @@ Result<RefPtr<Element>, nsresult> HTMLEditor::CreateAndInsertElement(
|
||||
// CreatElementTransaction since we can use InsertNodeTransaction
|
||||
// instead.
|
||||
|
||||
RefPtr<Element> newElement;
|
||||
nsresult rv;
|
||||
newElement = CreateHTMLContent(&aTagName);
|
||||
RefPtr<Element> newElement = CreateHTMLContent(&aTagName);
|
||||
NS_WARNING_ASSERTION(newElement, "EditorBase::CreateHTMLContent() failed");
|
||||
if (MOZ_LIKELY(newElement)) {
|
||||
rv = MarkElementDirty(*newElement);
|
||||
@@ -2988,12 +2995,14 @@ Result<RefPtr<Element>, nsresult> HTMLEditor::CreateAndInsertElement(
|
||||
NS_WARNING_ASSERTION(
|
||||
NS_SUCCEEDED(rv),
|
||||
"EditorBase::MarkElementDirty() failed, but ignored");
|
||||
if (StaticPrefs::editor_initialize_element_before_connect()) {
|
||||
rv = aInitializer(*newElement);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "aInitializer failed");
|
||||
if (MOZ_UNLIKELY(rv != NS_ERROR_EDITOR_DESTROYED &&
|
||||
NS_WARN_IF(Destroyed()))) {
|
||||
rv = NS_ERROR_EDITOR_DESTROYED;
|
||||
}
|
||||
}
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
RefPtr<InsertNodeTransaction> transaction =
|
||||
InsertNodeTransaction::Create(*this, *newElement, aPointToInsert);
|
||||
@@ -3046,6 +3055,18 @@ Result<RefPtr<Element>, nsresult> HTMLEditor::CreateAndInsertElement(
|
||||
return Err(rv);
|
||||
}
|
||||
|
||||
if (!StaticPrefs::editor_initialize_element_before_connect() && newElement) {
|
||||
rv = aInitializer(*newElement);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "aInitializer failed");
|
||||
if (MOZ_UNLIKELY(rv != NS_ERROR_EDITOR_DESTROYED &&
|
||||
NS_WARN_IF(Destroyed()))) {
|
||||
rv = NS_ERROR_EDITOR_DESTROYED;
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
return Err(rv);
|
||||
}
|
||||
}
|
||||
|
||||
return newElement;
|
||||
}
|
||||
|
||||
|
||||
@@ -1498,10 +1498,10 @@ class HTMLEditor final : public EditorBase,
|
||||
* Note that this point will be invalid once this
|
||||
* method inserts the new element.
|
||||
* @param aInitializer A function to initialize the new element before
|
||||
* connecting the element into the DOM tree.
|
||||
* Note that this should not touch outside given
|
||||
* element because doing it would break range
|
||||
* updater's result.
|
||||
* or after (depends on the pref) connecting the
|
||||
* element into the DOM tree. Note that this should
|
||||
* not touch outside given element because doing it
|
||||
* would break range updater's result.
|
||||
* @return The created new element node or an error.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<RefPtr<Element>, nsresult>
|
||||
@@ -1545,10 +1545,10 @@ class HTMLEditor final : public EditorBase,
|
||||
* kept if and only if a <br> element follows
|
||||
* split point.
|
||||
* @param aInitializer A function to initialize the new element before
|
||||
* connecting the element into the DOM tree.
|
||||
* Note that this should not touch outside given
|
||||
* element because doing it would break range
|
||||
* updater's result.
|
||||
* or after (depends on the pref) connecting the
|
||||
* element into the DOM tree. Note that this should
|
||||
* not touch outside given element because doing it
|
||||
* would break range updater's result.
|
||||
*/
|
||||
enum class BRElementNextToSplitPoint { Keep, Delete };
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<RefPtr<Element>, nsresult>
|
||||
@@ -3428,10 +3428,10 @@ class HTMLEditor final : public EditorBase,
|
||||
*
|
||||
* @param aTag The element name to be created.
|
||||
* @param aInitializer A function to initialize the new element before
|
||||
* connecting the element into the DOM tree.
|
||||
* Note that this should not touch outside given
|
||||
* element because doing it would break range
|
||||
* updater's result.
|
||||
* or after (depends on the pref) connecting the
|
||||
* element into the DOM tree. Note that this should
|
||||
* not touch outside given element because doing it
|
||||
* would break range updater's result.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT Result<RefPtr<Element>, nsresult>
|
||||
DeleteSelectionAndCreateElement(
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
#include "nsLinebreakConverter.h"
|
||||
#include "nsLiteralString.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsRange.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
@@ -2485,10 +2486,15 @@ nsresult HTMLEditor::PasteAsQuotationAsAction(int32_t aClipboardType,
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY due to bug 1758868
|
||||
[&](Element& aBlockquoteElement) MOZ_CAN_RUN_SCRIPT_BOUNDARY {
|
||||
DebugOnly<nsresult> rvIgnored = aBlockquoteElement.SetAttr(
|
||||
kNameSpaceID_None, nsGkAtoms::type, u"cite"_ns, false);
|
||||
kNameSpaceID_None, nsGkAtoms::type, u"cite"_ns,
|
||||
aBlockquoteElement.IsInComposedDoc());
|
||||
NS_WARNING_ASSERTION(
|
||||
NS_SUCCEEDED(rvIgnored),
|
||||
"Element::SetAttr(nsGkAtoms::type, cite) failed, but ignored");
|
||||
nsPrintfCString(
|
||||
"Element::SetAttr(nsGkAtoms::type, \"cite\", %s) "
|
||||
"failed, but ignored",
|
||||
aBlockquoteElement.IsInComposedDoc() ? "true" : "false")
|
||||
.get());
|
||||
return NS_OK;
|
||||
});
|
||||
if (MOZ_UNLIKELY(blockquoteElementOrError.isErr() ||
|
||||
@@ -2892,10 +2898,15 @@ nsresult HTMLEditor::InsertAsPlaintextQuotation(const nsAString& aQuotedText,
|
||||
*nsGkAtoms::span, [](Element& aSpanElement) {
|
||||
// Add an attribute on the pre node so we'll know it's a quotation.
|
||||
DebugOnly<nsresult> rvIgnored = aSpanElement.SetAttr(
|
||||
kNameSpaceID_None, nsGkAtoms::mozquote, u"true"_ns, false);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
|
||||
"Element::SetAttr(nsGkAtoms::mozquote, "
|
||||
"\"true\", false) failed");
|
||||
kNameSpaceID_None, nsGkAtoms::mozquote, u"true"_ns,
|
||||
aSpanElement.IsInComposedDoc());
|
||||
NS_WARNING_ASSERTION(
|
||||
NS_SUCCEEDED(rvIgnored),
|
||||
nsPrintfCString(
|
||||
"Element::SetAttr(nsGkAtoms::mozquote, \"true\", %s) "
|
||||
"failed",
|
||||
aSpanElement.IsInComposedDoc() ? "true" : "false")
|
||||
.get());
|
||||
// Allow wrapping on spans so long lines get wrapped to the screen.
|
||||
if (aSpanElement.GetParent() &&
|
||||
aSpanElement.GetParent()->IsHTMLElement(nsGkAtoms::body)) {
|
||||
@@ -3151,16 +3162,26 @@ nsresult HTMLEditor::InsertAsCitedQuotationInternal(
|
||||
[&](Element& aBlockquoteElement) MOZ_CAN_RUN_SCRIPT_BOUNDARY {
|
||||
// Try to set type=cite. Ignore it if this fails.
|
||||
DebugOnly<nsresult> rvIgnored = aBlockquoteElement.SetAttr(
|
||||
kNameSpaceID_None, nsGkAtoms::type, u"cite"_ns, false);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
|
||||
"Element::SetAttr(nsGkAtoms::type, "
|
||||
"\"cite\", false) failed, but ignored");
|
||||
kNameSpaceID_None, nsGkAtoms::type, u"cite"_ns,
|
||||
aBlockquoteElement.IsInComposedDoc());
|
||||
NS_WARNING_ASSERTION(
|
||||
NS_SUCCEEDED(rvIgnored),
|
||||
nsPrintfCString(
|
||||
"Element::SetAttr(nsGkAtoms::type, \"cite\", %s) failed, "
|
||||
"but ignored",
|
||||
aBlockquoteElement.IsInComposedDoc() ? "true" : "false")
|
||||
.get());
|
||||
if (!aCitation.IsEmpty()) {
|
||||
DebugOnly<nsresult> rvIgnored = aBlockquoteElement.SetAttr(
|
||||
kNameSpaceID_None, nsGkAtoms::cite, aCitation, false);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
|
||||
"Element::SetAttr(nsGkAtoms::cite, "
|
||||
"\"...\", false) failed, but ignored");
|
||||
kNameSpaceID_None, nsGkAtoms::cite, aCitation,
|
||||
aBlockquoteElement.IsInComposedDoc());
|
||||
NS_WARNING_ASSERTION(
|
||||
NS_SUCCEEDED(rvIgnored),
|
||||
nsPrintfCString(
|
||||
"Element::SetAttr(nsGkAtoms::cite, \"...\", %s) failed, "
|
||||
"but ignored",
|
||||
aBlockquoteElement.IsInComposedDoc() ? "true" : "false")
|
||||
.get());
|
||||
}
|
||||
return NS_OK;
|
||||
});
|
||||
|
||||
@@ -4422,6 +4422,13 @@
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
# Whether editor initializes attributes and/or child nodes of newly inserting
|
||||
# element before or after connecting to the DOM tree.
|
||||
- name: editor.initialize_element_before_connect
|
||||
type: bool
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
# Delay to mask last input character in password fields.
|
||||
# If negative value, to use platform's default behavior.
|
||||
# If 0, no delay to mask password.
|
||||
|
||||
Reference in New Issue
Block a user