mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 22:32:46 +00:00
Bug 1649980 - part 2: Move WSRunScanner::GetEditableBlockParentOrTopmotEditableInlineContent()
to HTMLEditUtils
r=m_kato
Depends on D82693 Differential Revision: https://phabricator.services.mozilla.com/D82694
This commit is contained in:
parent
7121f0a1fb
commit
444700f8d1
@ -5,11 +5,12 @@
|
|||||||
|
|
||||||
#include "HTMLEditUtils.h"
|
#include "HTMLEditUtils.h"
|
||||||
|
|
||||||
#include "CSSEditUtils.h" // for CSSEditUtils
|
#include "CSSEditUtils.h" // for CSSEditUtils
|
||||||
#include "mozilla/ArrayUtils.h" // for ArrayLength
|
#include "mozilla/ArrayUtils.h" // for ArrayLength
|
||||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc.
|
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc.
|
||||||
#include "mozilla/EditAction.h" // for EditAction
|
#include "mozilla/EditAction.h" // for EditAction
|
||||||
#include "mozilla/EditorBase.h" // for EditorBase
|
#include "mozilla/EditorBase.h" // for EditorBase, EditorType
|
||||||
|
#include "mozilla/EditorUtils.h" // for EditorUtils
|
||||||
#include "mozilla/dom/HTMLAnchorElement.h"
|
#include "mozilla/dom/HTMLAnchorElement.h"
|
||||||
#include "mozilla/dom/Element.h" // for Element, nsINode
|
#include "mozilla/dom/Element.h" // for Element, nsINode
|
||||||
#include "nsAString.h" // for nsAString::IsEmpty
|
#include "nsAString.h" // for nsAString::IsEmpty
|
||||||
@ -27,6 +28,8 @@
|
|||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
using EditorType = EditorBase::EditorType;
|
||||||
|
|
||||||
bool HTMLEditUtils::CanContentsBeJoined(const nsIContent& aLeftContent,
|
bool HTMLEditUtils::CanContentsBeJoined(const nsIContent& aLeftContent,
|
||||||
const nsIContent& aRightContent,
|
const nsIContent& aRightContent,
|
||||||
StyleDifference aStyleDifference) {
|
StyleDifference aStyleDifference) {
|
||||||
@ -654,6 +657,24 @@ bool HTMLEditUtils::IsSingleLineContainer(nsINode& aNode) {
|
|||||||
aNode.IsAnyOfHTMLElements(nsGkAtoms::li, nsGkAtoms::dt, nsGkAtoms::dd);
|
aNode.IsAnyOfHTMLElements(nsGkAtoms::li, nsGkAtoms::dt, nsGkAtoms::dd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
Element*
|
||||||
|
HTMLEditUtils::GetInclusiveAncestorEditableBlockElementOrInlineEditingHost(
|
||||||
|
nsIContent& aContent) {
|
||||||
|
MOZ_ASSERT(EditorUtils::IsEditableContent(aContent, EditorType::HTML));
|
||||||
|
Element* maybeInlineEditingHost = nullptr;
|
||||||
|
for (Element* element : aContent.InclusiveAncestorsOfType<Element>()) {
|
||||||
|
if (!EditorUtils::IsEditableContent(*element, EditorType::HTML)) {
|
||||||
|
return maybeInlineEditingHost;
|
||||||
|
}
|
||||||
|
if (HTMLEditUtils::IsBlockElement(*element)) {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
maybeInlineEditingHost = element;
|
||||||
|
}
|
||||||
|
return maybeInlineEditingHost;
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
Element* HTMLEditUtils::GetClosestAncestorAnyListElement(
|
Element* HTMLEditUtils::GetClosestAncestorAnyListElement(
|
||||||
const nsIContent& aContent) {
|
const nsIContent& aContent) {
|
||||||
|
@ -528,6 +528,13 @@ class HTMLEditUtils final {
|
|||||||
return GetAncestorBlockElement(aContent, aAncestorLimiter);
|
return GetAncestorBlockElement(aContent, aAncestorLimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetInclusiveAncestorEditableBlockElementOrInlineEditingHost() returns
|
||||||
|
* inclusive block ancestor element of aContent. If aContent is in inline
|
||||||
|
* editing host, returns the editing host instead.
|
||||||
|
*/
|
||||||
|
static Element* GetInclusiveAncestorEditableBlockElementOrInlineEditingHost(
|
||||||
|
nsIContent& aContent);
|
||||||
/**
|
/**
|
||||||
* GetClosestAncestorTableElement() returns the nearest inclusive ancestor
|
* GetClosestAncestorTableElement() returns the nearest inclusive ancestor
|
||||||
* <table> element of aContent.
|
* <table> element of aContent.
|
||||||
|
@ -800,30 +800,6 @@ nsresult WSRunObject::NormalizeWhiteSpacesAround(
|
|||||||
// protected methods
|
// protected methods
|
||||||
//--------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
nsIContent* WSRunScanner::GetEditableBlockParentOrTopmotEditableInlineContent(
|
|
||||||
nsIContent* aContent) const {
|
|
||||||
if (NS_WARN_IF(!aContent)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
NS_ASSERTION(EditorUtils::IsEditableContent(*aContent, EditorType::HTML),
|
|
||||||
"Given content is not editable");
|
|
||||||
// XXX What should we do if scan range crosses block boundary? Currently,
|
|
||||||
// it's not collapsed only when inserting composition string so that
|
|
||||||
// it's possible but shouldn't occur actually.
|
|
||||||
nsIContent* editableBlockParentOrTopmotEditableInlineContent = nullptr;
|
|
||||||
for (nsIContent* content : aContent->InclusiveAncestorsOfType<nsIContent>()) {
|
|
||||||
if (!EditorUtils::IsEditableContent(*content, EditorType::HTML)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
editableBlockParentOrTopmotEditableInlineContent = content;
|
|
||||||
if (HTMLEditUtils::IsBlockElement(
|
|
||||||
*editableBlockParentOrTopmotEditableInlineContent)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return editableBlockParentOrTopmotEditableInlineContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult WSRunScanner::GetWSNodes() {
|
nsresult WSRunScanner::GetWSNodes() {
|
||||||
// collect up an array of nodes that are contiguous with the insertion point
|
// collect up an array of nodes that are contiguous with the insertion point
|
||||||
// and which contain only white-space. Stop if you reach non-ws text or a new
|
// and which contain only white-space. Stop if you reach non-ws text or a new
|
||||||
@ -837,9 +813,21 @@ nsresult WSRunScanner::GetWSNodes() {
|
|||||||
// direct child of Document node.
|
// direct child of Document node.
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
// XXX What should we do if scan range crosses block boundary? Currently,
|
||||||
|
// it's not collapsed only when inserting composition string so that
|
||||||
|
// it's possible but shouldn't occur actually.
|
||||||
|
NS_ASSERTION(
|
||||||
|
EditorUtils::IsEditableContent(*scanStartContent, EditorType::HTML),
|
||||||
|
"Given content is not editable");
|
||||||
|
NS_ASSERTION(scanStartContent->GetAsElementOrParentElement(),
|
||||||
|
"Given content is not an element and an orphan node");
|
||||||
nsIContent* editableBlockParentOrTopmotEditableInlineContent =
|
nsIContent* editableBlockParentOrTopmotEditableInlineContent =
|
||||||
GetEditableBlockParentOrTopmotEditableInlineContent(scanStartContent);
|
EditorUtils::IsEditableContent(*scanStartContent, EditorType::HTML)
|
||||||
if (NS_WARN_IF(!editableBlockParentOrTopmotEditableInlineContent)) {
|
? HTMLEditUtils::
|
||||||
|
GetInclusiveAncestorEditableBlockElementOrInlineEditingHost(
|
||||||
|
*scanStartContent)
|
||||||
|
: nullptr;
|
||||||
|
if (!editableBlockParentOrTopmotEditableInlineContent) {
|
||||||
// Meaning that the container of `mScanStartPoint` is not editable.
|
// Meaning that the container of `mScanStartPoint` is not editable.
|
||||||
editableBlockParentOrTopmotEditableInlineContent = scanStartContent;
|
editableBlockParentOrTopmotEditableInlineContent = scanStartContent;
|
||||||
}
|
}
|
||||||
@ -1548,9 +1536,20 @@ EditorDOMPointInText WSRunScanner::GetInclusiveNextEditableCharPoint(
|
|||||||
return EditorDOMPointInText();
|
return EditorDOMPointInText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_ASSERTION(EditorUtils::IsEditableContent(
|
||||||
|
*mScanStartPoint.ContainerAsContent(), EditorType::HTML),
|
||||||
|
"Given content is not editable");
|
||||||
|
NS_ASSERTION(
|
||||||
|
mScanStartPoint.ContainerAsContent()->GetAsElementOrParentElement(),
|
||||||
|
"Given content is not an element and an orphan node");
|
||||||
nsIContent* editableBlockParentOrTopmotEditableInlineContent =
|
nsIContent* editableBlockParentOrTopmotEditableInlineContent =
|
||||||
GetEditableBlockParentOrTopmotEditableInlineContent(
|
mScanStartPoint.ContainerAsContent() &&
|
||||||
mScanStartPoint.ContainerAsContent());
|
EditorUtils::IsEditableContent(
|
||||||
|
*mScanStartPoint.ContainerAsContent(), EditorType::HTML)
|
||||||
|
? HTMLEditUtils::
|
||||||
|
GetInclusiveAncestorEditableBlockElementOrInlineEditingHost(
|
||||||
|
*mScanStartPoint.ContainerAsContent())
|
||||||
|
: nullptr;
|
||||||
if (NS_WARN_IF(!editableBlockParentOrTopmotEditableInlineContent)) {
|
if (NS_WARN_IF(!editableBlockParentOrTopmotEditableInlineContent)) {
|
||||||
// Meaning that the container of `mScanStartPoint` is not editable.
|
// Meaning that the container of `mScanStartPoint` is not editable.
|
||||||
editableBlockParentOrTopmotEditableInlineContent =
|
editableBlockParentOrTopmotEditableInlineContent =
|
||||||
@ -1616,9 +1615,20 @@ EditorDOMPointInText WSRunScanner::GetPreviousEditableCharPoint(
|
|||||||
return EditorDOMPointInText();
|
return EditorDOMPointInText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_ASSERTION(EditorUtils::IsEditableContent(
|
||||||
|
*mScanStartPoint.ContainerAsContent(), EditorType::HTML),
|
||||||
|
"Given content is not editable");
|
||||||
|
NS_ASSERTION(
|
||||||
|
mScanStartPoint.ContainerAsContent()->GetAsElementOrParentElement(),
|
||||||
|
"Given content is not an element and an orphan node");
|
||||||
nsIContent* editableBlockParentOrTopmotEditableInlineContent =
|
nsIContent* editableBlockParentOrTopmotEditableInlineContent =
|
||||||
GetEditableBlockParentOrTopmotEditableInlineContent(
|
mScanStartPoint.ContainerAsContent() &&
|
||||||
mScanStartPoint.ContainerAsContent());
|
EditorUtils::IsEditableContent(
|
||||||
|
*mScanStartPoint.ContainerAsContent(), EditorType::HTML)
|
||||||
|
? HTMLEditUtils::
|
||||||
|
GetInclusiveAncestorEditableBlockElementOrInlineEditingHost(
|
||||||
|
*mScanStartPoint.ContainerAsContent())
|
||||||
|
: nullptr;
|
||||||
if (NS_WARN_IF(!editableBlockParentOrTopmotEditableInlineContent)) {
|
if (NS_WARN_IF(!editableBlockParentOrTopmotEditableInlineContent)) {
|
||||||
// Meaning that the container of `mScanStartPoint` is not editable.
|
// Meaning that the container of `mScanStartPoint` is not editable.
|
||||||
editableBlockParentOrTopmotEditableInlineContent =
|
editableBlockParentOrTopmotEditableInlineContent =
|
||||||
@ -1874,9 +1884,20 @@ nsresult WSRunObject::NormalizeWhiteSpacesAtEndOf(
|
|||||||
bool insertBRElement = HTMLEditUtils::IsBlockElement(
|
bool insertBRElement = HTMLEditUtils::IsBlockElement(
|
||||||
*mScanStartPoint.ContainerAsContent());
|
*mScanStartPoint.ContainerAsContent());
|
||||||
if (!insertBRElement) {
|
if (!insertBRElement) {
|
||||||
|
NS_ASSERTION(
|
||||||
|
EditorUtils::IsEditableContent(
|
||||||
|
*mScanStartPoint.ContainerAsContent(), EditorType::HTML),
|
||||||
|
"Given content is not editable");
|
||||||
|
NS_ASSERTION(mScanStartPoint.ContainerAsContent()
|
||||||
|
->GetAsElementOrParentElement(),
|
||||||
|
"Given content is not an element and an orphan node");
|
||||||
nsIContent* blockParentOrTopmostEditableInlineContent =
|
nsIContent* blockParentOrTopmostEditableInlineContent =
|
||||||
GetEditableBlockParentOrTopmotEditableInlineContent(
|
EditorUtils::IsEditableContent(
|
||||||
mScanStartPoint.ContainerAsContent());
|
*mScanStartPoint.ContainerAsContent(), EditorType::HTML)
|
||||||
|
? HTMLEditUtils::
|
||||||
|
GetInclusiveAncestorEditableBlockElementOrInlineEditingHost(
|
||||||
|
*mScanStartPoint.ContainerAsContent())
|
||||||
|
: nullptr;
|
||||||
insertBRElement = blockParentOrTopmostEditableInlineContent &&
|
insertBRElement = blockParentOrTopmostEditableInlineContent &&
|
||||||
HTMLEditUtils::IsBlockElement(
|
HTMLEditUtils::IsBlockElement(
|
||||||
*blockParentOrTopmostEditableInlineContent);
|
*blockParentOrTopmostEditableInlineContent);
|
||||||
|
@ -577,13 +577,6 @@ class MOZ_STACK_CLASS WSRunScanner {
|
|||||||
|
|
||||||
nsresult GetWSNodes();
|
nsresult GetWSNodes();
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a current block element for aContent or a topmost editable inline
|
|
||||||
* element if aContent is not in editable block element.
|
|
||||||
*/
|
|
||||||
nsIContent* GetEditableBlockParentOrTopmotEditableInlineContent(
|
|
||||||
nsIContent* aContent) const;
|
|
||||||
|
|
||||||
EditorDOMPointInText GetPreviousCharPointFromPointInText(
|
EditorDOMPointInText GetPreviousCharPointFromPointInText(
|
||||||
const EditorDOMPointInText& aPoint) const;
|
const EditorDOMPointInText& aPoint) const;
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ function checks(msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
SimpleTest.expectAssertions(3); // Detect odd orphan editable node in `WSRunScanner::GetWSNodes()`
|
||||||
SimpleTest.waitForFocus(function() {
|
SimpleTest.waitForFocus(function() {
|
||||||
// Put selection after the "y" and backspace
|
// Put selection after the "y" and backspace
|
||||||
reset();
|
reset();
|
||||||
|
Loading…
Reference in New Issue
Block a user