Bug 1574852 - part 90: Move HTMLEditRules::ConfirmSelectionInBody() to HTMLEditor r=m_kato

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Masayuki Nakano 2019-09-10 03:52:44 +00:00
parent a2c5d981ee
commit 24f1d9a9b3
3 changed files with 37 additions and 25 deletions

View File

@ -365,10 +365,14 @@ nsresult HTMLEditRules::BeforeEdit() {
}
// Check that selection is in subtree defined by body node
nsresult rv = ConfirmSelectionInBody();
nsresult rv =
MOZ_KnownLive(HTMLEditorRef()).EnsureSelectionInBodyOrDocumentElement();
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
return NS_ERROR_EDITOR_DESTROYED;
}
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rv),
"EnsureSelectionInBodyOrDocumentElement() failed, but ignored");
return NS_OK;
}
@ -419,11 +423,14 @@ nsresult HTMLEditRules::AfterEdit() {
nsresult HTMLEditRules::AfterEditInner() {
MOZ_ASSERT(IsEditorDataAvailable());
nsresult rv = ConfirmSelectionInBody();
nsresult rv =
MOZ_KnownLive(HTMLEditorRef()).EnsureSelectionInBodyOrDocumentElement();
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
return NS_ERROR_EDITOR_DESTROYED;
}
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to normalize Selection");
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rv),
"EnsureSelectionInBodyOrDocumentElement() failed, but ignored");
switch (HTMLEditorRef().GetTopLevelEditSubAction()) {
case EditSubAction::eReplaceHeadWithHTMLSource:
case EditSubAction::eCreatePaddingBRElementForEmptyEditor:
@ -10292,12 +10299,12 @@ nsresult HTMLEditor::DestroyListStructureRecursively(Element& aListElement) {
return NS_OK;
}
nsresult HTMLEditRules::ConfirmSelectionInBody() {
MOZ_ASSERT(IsEditorDataAvailable());
nsresult HTMLEditor::EnsureSelectionInBodyOrDocumentElement() {
MOZ_ASSERT(IsEditActionDataAvailable());
Element* rootElement = HTMLEditorRef().GetRoot();
if (NS_WARN_IF(!rootElement)) {
return NS_ERROR_UNEXPECTED;
RefPtr<Element> bodyOrDocumentElement = GetRoot();
if (NS_WARN_IF(!bodyOrDocumentElement)) {
return NS_ERROR_FAILURE;
}
EditorRawDOMPoint selectionStartPoint(
@ -10306,6 +10313,12 @@ nsresult HTMLEditRules::ConfirmSelectionInBody() {
return NS_ERROR_FAILURE;
}
// XXX This does wrong things. Web apps can put any elements as sibling
// of `<body>` element. Therefore, this collapses `Selection` into
// the `<body>` element which `HTMLDocument.body` is set to. So,
// this makes users impossible to modify content outside of the
// `<body>` element even if caret is in an editing host.
// Check that selection start container is inside the <body> element.
// XXXsmaug this code is insane.
nsINode* temp = selectionStartPoint.GetContainer();
@ -10316,13 +10329,14 @@ nsresult HTMLEditRules::ConfirmSelectionInBody() {
// If we aren't in the <body> element, force the issue.
if (!temp) {
IgnoredErrorResult ignoredError;
SelectionRefPtr()->Collapse(RawRangeBoundary(rootElement, 0), ignoredError);
if (NS_WARN_IF(!CanHandleEditAction())) {
SelectionRefPtr()->Collapse(RawRangeBoundary(bodyOrDocumentElement, 0),
ignoredError);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
NS_WARNING_ASSERTION(
!ignoredError.Failed(),
"Failed to collapse selection at start of the root element");
"Selection::Collapse() with start of editing host failed, but ignored");
return NS_OK;
}
@ -10342,13 +10356,14 @@ nsresult HTMLEditRules::ConfirmSelectionInBody() {
// If we aren't in the <body> element, force the issue.
if (!temp) {
IgnoredErrorResult ignoredError;
SelectionRefPtr()->Collapse(RawRangeBoundary(rootElement, 0), ignoredError);
if (NS_WARN_IF(!CanHandleEditAction())) {
SelectionRefPtr()->Collapse(RawRangeBoundary(bodyOrDocumentElement, 0),
ignoredError);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
NS_WARNING_ASSERTION(
!ignoredError.Failed(),
"Failed to collapse selection at start of the root element");
"Selection::Collapse() with start of editing host failed, but ignored");
}
return NS_OK;

View File

@ -222,17 +222,6 @@ class HTMLEditRules : public TextEditRules {
MOZ_CAN_RUN_SCRIPT
MOZ_MUST_USE nsresult RemoveEmptyNodesInChangedRange();
/**
* ConfirmSelectionInBody() makes sure that Selection is in editor root
* element typically <body> element (see HTMLEditor::UpdateRootElement())
* and only one Selection range.
* XXX This method is not necessary because even if selection is outside the
* <body> element, elements outside the <body> element should be
* editable, e.g., any element can be inserted siblings as <body> element
* and other browsers allow to edit such elements.
*/
MOZ_MUST_USE nsresult ConfirmSelectionInBody();
/**
* DocumentModifiedWorker() is called by DocumentModified() either
* synchronously or asynchronously.

View File

@ -2603,6 +2603,14 @@ class HTMLEditor final : public TextEditor,
AdjustCaretPositionAndEnsurePaddingBRElement(
nsIEditor::EDirection aDirectionAndAmount);
/**
* EnsureSelectionInBodyOrDocumentElement() collapse `Selection` to the
* primary `<body>` element or document element when `Selection` crosses
* `<body>` element's boundary.
*/
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult
EnsureSelectionInBodyOrDocumentElement();
protected: // Called by helper classes.
virtual void OnStartToHandleTopLevelEditSubAction(
EditSubAction aEditSubAction, nsIEditor::EDirection aDirection) override;