зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1625633
- part 4: Move `WSType` into `WSRunScanner` to hide it from `HTMLEditor` r=m_kato
Now, `WSType` is used only by `WSRunScanner`, `WSRunObject` and `WSScanResult`. We should hide this mysterious `enum` from other classes for making other developers easier to understand. Therefore, this patch moves `WSType` into `WSScanResult` and share it with `WSRunScanner` with making them friends. Depends on D68675 Differential Revision: https://phabricator.services.mozilla.com/D68676 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
85e5b5f208
Коммит
37f3ac6663
|
@ -68,8 +68,8 @@ WSRunScanner::WSRunScanner(const HTMLEditor* aHTMLEditor,
|
||||||
mStartRun(nullptr),
|
mStartRun(nullptr),
|
||||||
mEndRun(nullptr),
|
mEndRun(nullptr),
|
||||||
mHTMLEditor(aHTMLEditor),
|
mHTMLEditor(aHTMLEditor),
|
||||||
mStartReason(WSType::none),
|
mStartReason(WSType::NotInitialized),
|
||||||
mEndReason(WSType::none) {
|
mEndReason(WSType::NotInitialized) {
|
||||||
MOZ_ASSERT(
|
MOZ_ASSERT(
|
||||||
*nsContentUtils::ComparePoints(aScanStartPoint.ToRawRangeBoundary(),
|
*nsContentUtils::ComparePoints(aScanStartPoint.ToRawRangeBoundary(),
|
||||||
aScanEndPoint.ToRawRangeBoundary()) <= 0);
|
aScanEndPoint.ToRawRangeBoundary()) <= 0);
|
||||||
|
@ -586,8 +586,8 @@ WSScanResult WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundaryFrom(
|
||||||
return WSScanResult(
|
return WSScanResult(
|
||||||
atPreviousChar.NextPoint(),
|
atPreviousChar.NextPoint(),
|
||||||
atPreviousChar.IsCharASCIISpace() || atPreviousChar.IsCharNBSP()
|
atPreviousChar.IsCharASCIISpace() || atPreviousChar.IsCharNBSP()
|
||||||
? WSType::normalWS
|
? WSType::NormalWhiteSpaces
|
||||||
: WSType::text);
|
: WSType::NormalText);
|
||||||
}
|
}
|
||||||
// If no text node, keep looking. We should eventually fall out of loop
|
// If no text node, keep looking. We should eventually fall out of loop
|
||||||
}
|
}
|
||||||
|
@ -621,8 +621,8 @@ WSScanResult WSRunScanner::ScanNextVisibleNodeOrBlockBoundaryFrom(
|
||||||
atNextChar,
|
atNextChar,
|
||||||
!atNextChar.IsEndOfContainer() &&
|
!atNextChar.IsEndOfContainer() &&
|
||||||
(atNextChar.IsCharASCIISpace() || atNextChar.IsCharNBSP())
|
(atNextChar.IsCharASCIISpace() || atNextChar.IsCharNBSP())
|
||||||
? WSType::normalWS
|
? WSType::NormalWhiteSpaces
|
||||||
: WSType::text);
|
: WSType::NormalText);
|
||||||
}
|
}
|
||||||
// If no text node, keep looking. We should eventually fall out of loop
|
// If no text node, keep looking. We should eventually fall out of loop
|
||||||
}
|
}
|
||||||
|
@ -719,7 +719,7 @@ nsresult WSRunScanner::GetWSNodes() {
|
||||||
if (theChar != kNBSP) {
|
if (theChar != kNBSP) {
|
||||||
mStartNode = textNode;
|
mStartNode = textNode;
|
||||||
mStartOffset = i;
|
mStartOffset = i;
|
||||||
mStartReason = WSType::text;
|
mStartReason = WSType::NormalText;
|
||||||
mStartReasonContent = textNode;
|
mStartReasonContent = textNode;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -745,7 +745,7 @@ nsresult WSRunScanner::GetWSNodes() {
|
||||||
if (IsBlockNode(priorNode)) {
|
if (IsBlockNode(priorNode)) {
|
||||||
mStartNode = start.GetContainer();
|
mStartNode = start.GetContainer();
|
||||||
mStartOffset = start.Offset();
|
mStartOffset = start.Offset();
|
||||||
mStartReason = WSType::otherBlock;
|
mStartReason = WSType::OtherBlockBoundary;
|
||||||
mStartReasonContent = priorNode;
|
mStartReasonContent = priorNode;
|
||||||
} else if (priorNode->IsText() && priorNode->IsEditable()) {
|
} else if (priorNode->IsText() && priorNode->IsEditable()) {
|
||||||
RefPtr<Text> textNode = priorNode->AsText();
|
RefPtr<Text> textNode = priorNode->AsText();
|
||||||
|
@ -769,7 +769,7 @@ nsresult WSRunScanner::GetWSNodes() {
|
||||||
if (theChar != kNBSP) {
|
if (theChar != kNBSP) {
|
||||||
mStartNode = textNode;
|
mStartNode = textNode;
|
||||||
mStartOffset = pos + 1;
|
mStartOffset = pos + 1;
|
||||||
mStartReason = WSType::text;
|
mStartReason = WSType::NormalText;
|
||||||
mStartReasonContent = textNode;
|
mStartReasonContent = textNode;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -791,9 +791,9 @@ nsresult WSRunScanner::GetWSNodes() {
|
||||||
mStartNode = start.GetContainer();
|
mStartNode = start.GetContainer();
|
||||||
mStartOffset = start.Offset();
|
mStartOffset = start.Offset();
|
||||||
if (priorNode->IsHTMLElement(nsGkAtoms::br)) {
|
if (priorNode->IsHTMLElement(nsGkAtoms::br)) {
|
||||||
mStartReason = WSType::br;
|
mStartReason = WSType::BRElement;
|
||||||
} else {
|
} else {
|
||||||
mStartReason = WSType::special;
|
mStartReason = WSType::SpecialContent;
|
||||||
}
|
}
|
||||||
mStartReasonContent = priorNode;
|
mStartReasonContent = priorNode;
|
||||||
}
|
}
|
||||||
|
@ -802,7 +802,7 @@ nsresult WSRunScanner::GetWSNodes() {
|
||||||
// editableBlockParentOrTopmotEditableInlineContent
|
// editableBlockParentOrTopmotEditableInlineContent
|
||||||
mStartNode = start.GetContainer();
|
mStartNode = start.GetContainer();
|
||||||
mStartOffset = start.Offset();
|
mStartOffset = start.Offset();
|
||||||
mStartReason = WSType::thisBlock;
|
mStartReason = WSType::CurrentBlockBoundary;
|
||||||
// mStartReasonContent can be either a block element or any non-editable
|
// mStartReasonContent can be either a block element or any non-editable
|
||||||
// content in this case.
|
// content in this case.
|
||||||
mStartReasonContent = editableBlockParentOrTopmotEditableInlineContent;
|
mStartReasonContent = editableBlockParentOrTopmotEditableInlineContent;
|
||||||
|
@ -825,7 +825,7 @@ nsresult WSRunScanner::GetWSNodes() {
|
||||||
if (theChar != kNBSP) {
|
if (theChar != kNBSP) {
|
||||||
mEndNode = textNode;
|
mEndNode = textNode;
|
||||||
mEndOffset = i;
|
mEndOffset = i;
|
||||||
mEndReason = WSType::text;
|
mEndReason = WSType::NormalText;
|
||||||
mEndReasonContent = textNode;
|
mEndReasonContent = textNode;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -852,7 +852,7 @@ nsresult WSRunScanner::GetWSNodes() {
|
||||||
// we encountered a new block. therefore no more ws.
|
// we encountered a new block. therefore no more ws.
|
||||||
mEndNode = end.GetContainer();
|
mEndNode = end.GetContainer();
|
||||||
mEndOffset = end.Offset();
|
mEndOffset = end.Offset();
|
||||||
mEndReason = WSType::otherBlock;
|
mEndReason = WSType::OtherBlockBoundary;
|
||||||
mEndReasonContent = nextNode;
|
mEndReasonContent = nextNode;
|
||||||
} else if (nextNode->IsText() && nextNode->IsEditable()) {
|
} else if (nextNode->IsText() && nextNode->IsEditable()) {
|
||||||
RefPtr<Text> textNode = nextNode->AsText();
|
RefPtr<Text> textNode = nextNode->AsText();
|
||||||
|
@ -876,7 +876,7 @@ nsresult WSRunScanner::GetWSNodes() {
|
||||||
if (theChar != kNBSP) {
|
if (theChar != kNBSP) {
|
||||||
mEndNode = textNode;
|
mEndNode = textNode;
|
||||||
mEndOffset = pos;
|
mEndOffset = pos;
|
||||||
mEndReason = WSType::text;
|
mEndReason = WSType::NormalText;
|
||||||
mEndReasonContent = textNode;
|
mEndReasonContent = textNode;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -899,9 +899,9 @@ nsresult WSRunScanner::GetWSNodes() {
|
||||||
mEndNode = end.GetContainer();
|
mEndNode = end.GetContainer();
|
||||||
mEndOffset = end.Offset();
|
mEndOffset = end.Offset();
|
||||||
if (nextNode->IsHTMLElement(nsGkAtoms::br)) {
|
if (nextNode->IsHTMLElement(nsGkAtoms::br)) {
|
||||||
mEndReason = WSType::br;
|
mEndReason = WSType::BRElement;
|
||||||
} else {
|
} else {
|
||||||
mEndReason = WSType::special;
|
mEndReason = WSType::SpecialContent;
|
||||||
}
|
}
|
||||||
mEndReasonContent = nextNode;
|
mEndReasonContent = nextNode;
|
||||||
}
|
}
|
||||||
|
@ -910,7 +910,7 @@ nsresult WSRunScanner::GetWSNodes() {
|
||||||
// editableBlockParentOrTopmotEditableInlineContent
|
// editableBlockParentOrTopmotEditableInlineContent
|
||||||
mEndNode = end.GetContainer();
|
mEndNode = end.GetContainer();
|
||||||
mEndOffset = end.Offset();
|
mEndOffset = end.Offset();
|
||||||
mEndReason = WSType::thisBlock;
|
mEndReason = WSType::CurrentBlockBoundary;
|
||||||
// mEndReasonContent can be either a block element or any non-editable
|
// mEndReasonContent can be either a block element or any non-editable
|
||||||
// content in this case.
|
// content in this case.
|
||||||
mEndReasonContent = editableBlockParentOrTopmotEditableInlineContent;
|
mEndReasonContent = editableBlockParentOrTopmotEditableInlineContent;
|
||||||
|
|
|
@ -40,102 +40,7 @@ namespace mozilla {
|
||||||
// both spaces count as NormalWS. Together, they render as the one visible
|
// both spaces count as NormalWS. Together, they render as the one visible
|
||||||
// space.
|
// space.
|
||||||
|
|
||||||
/**
|
class WSRunScanner;
|
||||||
* A type-safe bitfield indicating various types of whitespace or other things.
|
|
||||||
* Used as a member variable in WSRunObject and WSFragment.
|
|
||||||
*
|
|
||||||
* XXX: If this idea is useful in other places, we should generalize it using a
|
|
||||||
* template.
|
|
||||||
*/
|
|
||||||
class WSType {
|
|
||||||
public:
|
|
||||||
enum Enum {
|
|
||||||
none = 0,
|
|
||||||
leadingWS = 1, // leading insignificant ws, ie, after block or br
|
|
||||||
trailingWS = 1 << 1, // trailing insignificant ws, ie, before block
|
|
||||||
normalWS = 1 << 2, // normal significant ws, ie, after text, image, ...
|
|
||||||
text = 1 << 3, // indicates regular (non-ws) text
|
|
||||||
special = 1 << 4, // indicates an inline non-container, like image
|
|
||||||
br = 1 << 5, // indicates a br node
|
|
||||||
otherBlock = 1 << 6, // indicates a block other than one ws run is in
|
|
||||||
thisBlock = 1 << 7, // indicates the block ws run is in
|
|
||||||
block = otherBlock | thisBlock // block found
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implicit constructor, because the enums are logically just WSTypes
|
|
||||||
* themselves, and are only a separate type because there's no other obvious
|
|
||||||
* way to name specific WSType values.
|
|
||||||
*/
|
|
||||||
MOZ_IMPLICIT WSType(const Enum& aEnum = none) : mEnum(aEnum) {}
|
|
||||||
|
|
||||||
// operator==, &, and | need to access mEnum
|
|
||||||
friend bool operator==(const WSType& aLeft, const WSType& aRight);
|
|
||||||
friend const WSType operator&(const WSType& aLeft, const WSType& aRight);
|
|
||||||
friend const WSType operator|(const WSType& aLeft, const WSType& aRight);
|
|
||||||
WSType& operator=(const WSType& aOther) {
|
|
||||||
// This handles self-assignment fine
|
|
||||||
mEnum = aOther.mEnum;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
WSType& operator&=(const WSType& aOther) {
|
|
||||||
mEnum &= aOther.mEnum;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
WSType& operator|=(const WSType& aOther) {
|
|
||||||
mEnum |= aOther.mEnum;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint16_t mEnum;
|
|
||||||
void bool_conversion_helper() {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Allow boolean conversion with no numeric conversion
|
|
||||||
typedef void (WSType::*bool_type)();
|
|
||||||
operator bool_type() const {
|
|
||||||
return mEnum ? &WSType::bool_conversion_helper : nullptr;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* These are declared as global functions so "WSType::Enum == WSType" et al.
|
|
||||||
* will work using the implicit constructor.
|
|
||||||
*/
|
|
||||||
inline bool operator==(const WSType& aLeft, const WSType& aRight) {
|
|
||||||
return aLeft.mEnum == aRight.mEnum;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const WSType& aLeft, const WSType& aRight) {
|
|
||||||
return !(aLeft == aRight);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const WSType operator&(const WSType& aLeft, const WSType& aRight) {
|
|
||||||
WSType ret;
|
|
||||||
ret.mEnum = aLeft.mEnum & aRight.mEnum;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const WSType operator|(const WSType& aLeft, const WSType& aRight) {
|
|
||||||
WSType ret;
|
|
||||||
ret.mEnum = aLeft.mEnum | aRight.mEnum;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make sure that & and | of WSType::Enum creates a WSType instead of an int,
|
|
||||||
* because operators between WSType and int shouldn't work
|
|
||||||
*/
|
|
||||||
inline const WSType operator&(const WSType::Enum& aLeft,
|
|
||||||
const WSType::Enum& aRight) {
|
|
||||||
return WSType(aLeft) & WSType(aRight);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const WSType operator|(const WSType::Enum& aLeft,
|
|
||||||
const WSType::Enum& aRight) {
|
|
||||||
return WSType(aLeft) | WSType(aRight);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WSScanResult is result of ScanNextVisibleNodeOrBlockBoundaryFrom(),
|
* WSScanResult is result of ScanNextVisibleNodeOrBlockBoundaryFrom(),
|
||||||
|
@ -145,6 +50,29 @@ inline const WSType operator|(const WSType::Enum& aLeft,
|
||||||
* start of scanner.
|
* start of scanner.
|
||||||
*/
|
*/
|
||||||
class MOZ_STACK_CLASS WSScanResult final {
|
class MOZ_STACK_CLASS WSScanResult final {
|
||||||
|
private:
|
||||||
|
enum class WSType : uint8_t {
|
||||||
|
NotInitialized,
|
||||||
|
// The run is maybe collapsible white spaces at start of a hard line.
|
||||||
|
LeadingWhiteSpaces,
|
||||||
|
// The run is maybe collapsible white spaces at end of a hard line.
|
||||||
|
TrailingWhiteSpaces,
|
||||||
|
// Normal (perhaps, meaning visible) white spaces.
|
||||||
|
NormalWhiteSpaces,
|
||||||
|
// Normal text, not white spaces.
|
||||||
|
NormalText,
|
||||||
|
// Special content such as `<img>`, etc.
|
||||||
|
SpecialContent,
|
||||||
|
// <br> element.
|
||||||
|
BRElement,
|
||||||
|
// Other block's boundary (child block of current block, maybe).
|
||||||
|
OtherBlockBoundary,
|
||||||
|
// Current block's boundary.
|
||||||
|
CurrentBlockBoundary,
|
||||||
|
};
|
||||||
|
|
||||||
|
friend class WSRunScanner; // Because of WSType.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WSScanResult() = delete;
|
WSScanResult() = delete;
|
||||||
MOZ_NEVER_INLINE_DEBUG WSScanResult(nsIContent* aContent, WSType aReason)
|
MOZ_NEVER_INLINE_DEBUG WSScanResult(nsIContent* aContent, WSType aReason)
|
||||||
|
@ -161,27 +89,30 @@ class MOZ_STACK_CLASS WSScanResult final {
|
||||||
|
|
||||||
MOZ_NEVER_INLINE_DEBUG void AssertIfInvalidData() const {
|
MOZ_NEVER_INLINE_DEBUG void AssertIfInvalidData() const {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
MOZ_ASSERT(mReason == WSType::text || mReason == WSType::normalWS ||
|
MOZ_ASSERT(
|
||||||
mReason == WSType::br || mReason == WSType::special ||
|
mReason == WSType::NormalText || mReason == WSType::NormalWhiteSpaces ||
|
||||||
mReason == WSType::thisBlock || mReason == WSType::otherBlock);
|
mReason == WSType::BRElement || mReason == WSType::SpecialContent ||
|
||||||
MOZ_ASSERT_IF(mReason == WSType::text || mReason == WSType::normalWS,
|
mReason == WSType::CurrentBlockBoundary ||
|
||||||
mContent && mContent->IsText());
|
mReason == WSType::OtherBlockBoundary);
|
||||||
MOZ_ASSERT_IF(mReason == WSType::br,
|
MOZ_ASSERT_IF(
|
||||||
|
mReason == WSType::NormalText || mReason == WSType::NormalWhiteSpaces,
|
||||||
|
mContent && mContent->IsText());
|
||||||
|
MOZ_ASSERT_IF(mReason == WSType::BRElement,
|
||||||
mContent && mContent->IsHTMLElement(nsGkAtoms::br));
|
mContent && mContent->IsHTMLElement(nsGkAtoms::br));
|
||||||
MOZ_ASSERT_IF(
|
MOZ_ASSERT_IF(
|
||||||
mReason == WSType::special,
|
mReason == WSType::SpecialContent,
|
||||||
mContent && ((mContent->IsText() && !mContent->IsEditable()) ||
|
mContent && ((mContent->IsText() && !mContent->IsEditable()) ||
|
||||||
(!mContent->IsHTMLElement(nsGkAtoms::br) &&
|
(!mContent->IsHTMLElement(nsGkAtoms::br) &&
|
||||||
!HTMLEditor::NodeIsBlockStatic(*mContent))));
|
!HTMLEditor::NodeIsBlockStatic(*mContent))));
|
||||||
MOZ_ASSERT_IF(mReason == WSType::otherBlock,
|
MOZ_ASSERT_IF(mReason == WSType::OtherBlockBoundary,
|
||||||
mContent && HTMLEditor::NodeIsBlockStatic(*mContent));
|
mContent && HTMLEditor::NodeIsBlockStatic(*mContent));
|
||||||
// If mReason is WSType::thisBlock, mContent can be any content. In most
|
// If mReason is WSType::CurrentBlockBoundary, mContent can be any content.
|
||||||
// cases, it's current block element which is editable. However, if there
|
// In most cases, it's current block element which is editable. However, if
|
||||||
// is no editable block parent, this is topmost editable inline content.
|
// there is no editable block parent, this is topmost editable inline
|
||||||
// Additionally, if there is no editable content, this is the container
|
// content. Additionally, if there is no editable content, this is the
|
||||||
// start of scanner and is not editable.
|
// container start of scanner and is not editable.
|
||||||
MOZ_ASSERT_IF(
|
MOZ_ASSERT_IF(
|
||||||
mReason == WSType::thisBlock,
|
mReason == WSType::CurrentBlockBoundary,
|
||||||
!mContent || !mContent->GetParentElement() ||
|
!mContent || !mContent->GetParentElement() ||
|
||||||
HTMLEditor::NodeIsBlockStatic(*mContent) ||
|
HTMLEditor::NodeIsBlockStatic(*mContent) ||
|
||||||
HTMLEditor::NodeIsBlockStatic(*mContent->GetParentElement()) ||
|
HTMLEditor::NodeIsBlockStatic(*mContent->GetParentElement()) ||
|
||||||
|
@ -273,29 +204,34 @@ class MOZ_STACK_CLASS WSScanResult final {
|
||||||
* The scanner reached <img> or something which is inline and is not a
|
* The scanner reached <img> or something which is inline and is not a
|
||||||
* container.
|
* container.
|
||||||
*/
|
*/
|
||||||
bool ReachedSpecialContent() const { return mReason == WSType::special; }
|
bool ReachedSpecialContent() const {
|
||||||
|
return mReason == WSType::SpecialContent;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The point is in normal whitespaces or text.
|
* The point is in normal whitespaces or text.
|
||||||
*/
|
*/
|
||||||
bool InNormalWhiteSpacesOrText() const {
|
bool InNormalWhiteSpacesOrText() const {
|
||||||
return mReason == WSType::normalWS || mReason == WSType::text;
|
return mReason == WSType::NormalWhiteSpaces ||
|
||||||
|
mReason == WSType::NormalText;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The point is in normal whitespaces.
|
* The point is in normal whitespaces.
|
||||||
*/
|
*/
|
||||||
bool InNormalWhiteSpaces() const { return mReason == WSType::normalWS; }
|
bool InNormalWhiteSpaces() const {
|
||||||
|
return mReason == WSType::NormalWhiteSpaces;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The point is in normal text.
|
* The point is in normal text.
|
||||||
*/
|
*/
|
||||||
bool InNormalText() const { return mReason == WSType::text; }
|
bool InNormalText() const { return mReason == WSType::NormalText; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The scanner reached a <br> element.
|
* The scanner reached a <br> element.
|
||||||
*/
|
*/
|
||||||
bool ReachedBRElement() const { return mReason == WSType::br; }
|
bool ReachedBRElement() const { return mReason == WSType::BRElement; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The scanner reached a <hr> element.
|
* The scanner reached a <hr> element.
|
||||||
|
@ -307,20 +243,23 @@ class MOZ_STACK_CLASS WSScanResult final {
|
||||||
/**
|
/**
|
||||||
* The scanner reached current block boundary or other block element.
|
* The scanner reached current block boundary or other block element.
|
||||||
*/
|
*/
|
||||||
bool ReachedBlockBoundary() const { return !!(mReason & WSType::block); }
|
bool ReachedBlockBoundary() const {
|
||||||
|
return mReason == WSType::CurrentBlockBoundary ||
|
||||||
|
mReason == WSType::OtherBlockBoundary;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The scanner reached current block element boundary.
|
* The scanner reached current block element boundary.
|
||||||
*/
|
*/
|
||||||
bool ReachedCurrentBlockBoundary() const {
|
bool ReachedCurrentBlockBoundary() const {
|
||||||
return mReason == WSType::thisBlock;
|
return mReason == WSType::CurrentBlockBoundary;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The scanner reached other block element.
|
* The scanner reached other block element.
|
||||||
*/
|
*/
|
||||||
bool ReachedOtherBlockElement() const {
|
bool ReachedOtherBlockElement() const {
|
||||||
return mReason == WSType::otherBlock;
|
return mReason == WSType::OtherBlockBoundary;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -336,6 +275,7 @@ class MOZ_STACK_CLASS WSScanResult final {
|
||||||
|
|
||||||
class MOZ_STACK_CLASS WSRunScanner {
|
class MOZ_STACK_CLASS WSRunScanner {
|
||||||
public:
|
public:
|
||||||
|
using WSType = WSScanResult::WSType;
|
||||||
/**
|
/**
|
||||||
* The constructors take 2 DOM points. They represent a range in an editing
|
* The constructors take 2 DOM points. They represent a range in an editing
|
||||||
* host. aScanEndPoint (aScanEndNode and aScanEndOffset) must be later
|
* host. aScanEndPoint (aScanEndNode and aScanEndOffset) must be later
|
||||||
|
@ -403,40 +343,50 @@ class MOZ_STACK_CLASS WSRunScanner {
|
||||||
* forward. If there was whitespaces or text from the point, returns the
|
* forward. If there was whitespaces or text from the point, returns the
|
||||||
* text node. Otherwise, returns an element which is explained by the
|
* text node. Otherwise, returns an element which is explained by the
|
||||||
* following methods. Note that when the reason is
|
* following methods. Note that when the reason is
|
||||||
* WSType::thisBlock, In most cases, it's current block element which is
|
* WSType::CurrentBlockBoundary, In most cases, it's current block element
|
||||||
* editable, but also may be non-element and/or non-editable. See
|
* which is editable, but also may be non-element and/or non-editable. See
|
||||||
* MOZ_ASSERT_IF()s in WSScanResult::AssertIfInvalidData() for the detail.
|
* MOZ_ASSERT_IF()s in WSScanResult::AssertIfInvalidData() for the detail.
|
||||||
*/
|
*/
|
||||||
nsIContent* GetStartReasonContent() const { return mStartReasonContent; }
|
nsIContent* GetStartReasonContent() const { return mStartReasonContent; }
|
||||||
nsIContent* GetEndReasonContent() const { return mEndReasonContent; }
|
nsIContent* GetEndReasonContent() const { return mEndReasonContent; }
|
||||||
|
|
||||||
bool StartsFromNormalText() const { return mStartReason == WSType::text; }
|
bool StartsFromNormalText() const {
|
||||||
bool StartsFromSpecialContent() const {
|
return mStartReason == WSType::NormalText;
|
||||||
return mStartReason == WSType::special;
|
|
||||||
}
|
}
|
||||||
bool StartsFromBRElement() const { return mStartReason == WSType::br; }
|
bool StartsFromSpecialContent() const {
|
||||||
|
return mStartReason == WSType::SpecialContent;
|
||||||
|
}
|
||||||
|
bool StartsFromBRElement() const { return mStartReason == WSType::BRElement; }
|
||||||
bool StartsFromCurrentBlockBoundary() const {
|
bool StartsFromCurrentBlockBoundary() const {
|
||||||
return mStartReason == WSType::thisBlock;
|
return mStartReason == WSType::CurrentBlockBoundary;
|
||||||
}
|
}
|
||||||
bool StartsFromOtherBlockElement() const {
|
bool StartsFromOtherBlockElement() const {
|
||||||
return mStartReason == WSType::otherBlock;
|
return mStartReason == WSType::OtherBlockBoundary;
|
||||||
}
|
}
|
||||||
bool StartsFromBlockBoundary() const {
|
bool StartsFromBlockBoundary() const {
|
||||||
return !!(mStartReason & WSType::block);
|
return mStartReason == WSType::CurrentBlockBoundary ||
|
||||||
|
mStartReason == WSType::OtherBlockBoundary;
|
||||||
}
|
}
|
||||||
bool StartsFromHardLineBreak() const {
|
bool StartsFromHardLineBreak() const {
|
||||||
return !!(mStartReason & (WSType::block | WSType::br));
|
return mStartReason == WSType::CurrentBlockBoundary ||
|
||||||
|
mStartReason == WSType::OtherBlockBoundary ||
|
||||||
|
mStartReason == WSType::BRElement;
|
||||||
}
|
}
|
||||||
bool EndsByNormalText() const { return mEndReason == WSType::text; }
|
bool EndsByNormalText() const { return mEndReason == WSType::NormalText; }
|
||||||
bool EndsBySpecialContent() const { return mEndReason == WSType::special; }
|
bool EndsBySpecialContent() const {
|
||||||
bool EndsByBRElement() const { return mEndReason == WSType::br; }
|
return mEndReason == WSType::SpecialContent;
|
||||||
|
}
|
||||||
|
bool EndsByBRElement() const { return mEndReason == WSType::BRElement; }
|
||||||
bool EndsByCurrentBlockBoundary() const {
|
bool EndsByCurrentBlockBoundary() const {
|
||||||
return mEndReason == WSType::thisBlock;
|
return mEndReason == WSType::CurrentBlockBoundary;
|
||||||
}
|
}
|
||||||
bool EndsByOtherBlockElement() const {
|
bool EndsByOtherBlockElement() const {
|
||||||
return mEndReason == WSType::otherBlock;
|
return mEndReason == WSType::OtherBlockBoundary;
|
||||||
|
}
|
||||||
|
bool EndsByBlockBoundary() const {
|
||||||
|
return mEndReason == WSType::CurrentBlockBoundary ||
|
||||||
|
mEndReason == WSType::OtherBlockBoundary;
|
||||||
}
|
}
|
||||||
bool EndsByBlockBoundary() const { return !!(mEndReason & WSType::block); }
|
|
||||||
|
|
||||||
MOZ_NEVER_INLINE_DEBUG dom::Element* StartReasonOtherBlockElementPtr() const {
|
MOZ_NEVER_INLINE_DEBUG dom::Element* StartReasonOtherBlockElementPtr() const {
|
||||||
MOZ_DIAGNOSTIC_ASSERT(mStartReasonContent->IsElement());
|
MOZ_DIAGNOSTIC_ASSERT(mStartReasonContent->IsElement());
|
||||||
|
@ -477,6 +427,8 @@ class MOZ_STACK_CLASS WSRunScanner {
|
||||||
mEndOffset(0),
|
mEndOffset(0),
|
||||||
mLeft(nullptr),
|
mLeft(nullptr),
|
||||||
mRight(nullptr),
|
mRight(nullptr),
|
||||||
|
mLeftWSType(WSType::NotInitialized),
|
||||||
|
mRightWSType(WSType::NotInitialized),
|
||||||
mIsVisible(Visible::No),
|
mIsVisible(Visible::No),
|
||||||
mIsStartOfHardLine(StartOfHardLine::No),
|
mIsStartOfHardLine(StartOfHardLine::No),
|
||||||
mIsEndOfHardLine(EndOfHardLine::No) {}
|
mIsEndOfHardLine(EndOfHardLine::No) {}
|
||||||
|
@ -518,11 +470,17 @@ class MOZ_STACK_CLASS WSRunScanner {
|
||||||
* previous content type of the fragment).
|
* previous content type of the fragment).
|
||||||
*/
|
*/
|
||||||
void SetStartFrom(WSType aLeftWSType) { mLeftWSType = aLeftWSType; }
|
void SetStartFrom(WSType aLeftWSType) { mLeftWSType = aLeftWSType; }
|
||||||
void SetStartFromLeadingWhiteSpaces() { mLeftWSType = WSType::leadingWS; }
|
void SetStartFromLeadingWhiteSpaces() {
|
||||||
void SetStartFromNormalWhiteSpaces() { mLeftWSType = WSType::normalWS; }
|
mLeftWSType = WSType::LeadingWhiteSpaces;
|
||||||
bool StartsFromNormalText() const { return mLeftWSType == WSType::text; }
|
}
|
||||||
|
void SetStartFromNormalWhiteSpaces() {
|
||||||
|
mLeftWSType = WSType::NormalWhiteSpaces;
|
||||||
|
}
|
||||||
|
bool StartsFromNormalText() const {
|
||||||
|
return mLeftWSType == WSType::NormalText;
|
||||||
|
}
|
||||||
bool StartsFromSpecialContent() const {
|
bool StartsFromSpecialContent() const {
|
||||||
return mLeftWSType == WSType::special;
|
return mLeftWSType == WSType::SpecialContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -530,15 +488,20 @@ class MOZ_STACK_CLASS WSRunScanner {
|
||||||
* next content type of the fragment).
|
* next content type of the fragment).
|
||||||
*/
|
*/
|
||||||
void SetEndBy(WSType aRightWSType) { mRightWSType = aRightWSType; }
|
void SetEndBy(WSType aRightWSType) { mRightWSType = aRightWSType; }
|
||||||
void SetEndByNormalWiteSpaces() { mRightWSType = WSType::normalWS; }
|
void SetEndByNormalWiteSpaces() {
|
||||||
void SetEndByTrailingWhiteSpaces() { mRightWSType = WSType::trailingWS; }
|
mRightWSType = WSType::NormalWhiteSpaces;
|
||||||
bool EndsByNormalText() const { return mRightWSType == WSType::text; }
|
|
||||||
bool EndsBySpecialContent() const {
|
|
||||||
return mRightWSType == WSType::special;
|
|
||||||
}
|
}
|
||||||
bool EndsByBRElement() const { return mRightWSType == WSType::br; }
|
void SetEndByTrailingWhiteSpaces() {
|
||||||
|
mRightWSType = WSType::TrailingWhiteSpaces;
|
||||||
|
}
|
||||||
|
bool EndsByNormalText() const { return mRightWSType == WSType::NormalText; }
|
||||||
|
bool EndsBySpecialContent() const {
|
||||||
|
return mRightWSType == WSType::SpecialContent;
|
||||||
|
}
|
||||||
|
bool EndsByBRElement() const { return mRightWSType == WSType::BRElement; }
|
||||||
bool EndsByBlockBoundary() const {
|
bool EndsByBlockBoundary() const {
|
||||||
return !!(mRightWSType & WSType::block);
|
return mRightWSType == WSType::CurrentBlockBoundary ||
|
||||||
|
mRightWSType == WSType::OtherBlockBoundary;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -687,9 +650,10 @@ class MOZ_STACK_CLASS WSRunScanner {
|
||||||
const HTMLEditor* mHTMLEditor;
|
const HTMLEditor* mHTMLEditor;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Must be one of WSType::text, WSType::special, WSType::br,
|
// Must be one of WSType::NotInitialized, WSType::NormalText,
|
||||||
// WSType::thisBlock or WSType::otherBlock. Access these values with
|
// WSType::SpecialContent, WSType::BRElement, WSType::CurrentBlockBoundary or
|
||||||
// StartsFrom*() and EndsBy*() accessors.
|
// WSType::OtherBlockBoundary. Access these values with StartsFrom*() and
|
||||||
|
// EndsBy*() accessors.
|
||||||
WSType mStartReason;
|
WSType mStartReason;
|
||||||
WSType mEndReason;
|
WSType mEndReason;
|
||||||
};
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче