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:
Masayuki Nakano 2020-03-31 15:46:56 +00:00
Родитель 85e5b5f208
Коммит 37f3ac6663
2 изменённых файлов: 130 добавлений и 166 удалений

Просмотреть файл

@ -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;
}; };