--- a/editor/libeditor/WSRunObject.cpp
+++ b/editor/libeditor/WSRunObject.cpp
@@ -175,21 +175,18 @@ WSRunObject::InsertBreak(Selection& aSel
if (NS_WARN_IF(!aPointToInsert.IsSet())) {
return nullptr;
}
// MOOSE: for now, we always assume non-PRE formatting. Fix this later.
// meanwhile, the pre case is handled in WillInsertText in
// HTMLEditRules.cpp
- WSFragment *beforeRun, *afterRun;
- FindRun(aPointToInsert.Container(), aPointToInsert.Offset(),
- &beforeRun, false);
- FindRun(aPointToInsert.Container(), aPointToInsert.Offset(),
- &afterRun, true);
+ WSFragment* beforeRun = FindNearestRun(aPointToInsert, false);
+ WSFragment* afterRun = FindNearestRun(aPointToInsert, true);
EditorDOMPoint pointToInsert(aPointToInsert);
{
// Some scoping for AutoTrackDOMPoint. This will track our insertion
// point while we tweak any surrounding whitespace
AutoTrackDOMPoint tracker(mHTMLEditor->mRangeUpdater, &pointToInsert);
// Handle any changes needed to ws run after inserted br
@@ -268,25 +265,21 @@ WSRunObject::InsertText(nsIDocument& aDo
if (aStringToInsert.IsEmpty()) {
if (aPointAfterInsertedString) {
*aPointAfterInsertedString = aPointToInsert;
}
return NS_OK;
}
+ WSFragment* beforeRun = FindNearestRun(aPointToInsert, false);
+ WSFragment* afterRun = FindNearestRun(aPointToInsert, true);
+
EditorDOMPoint pointToInsert(aPointToInsert);
nsAutoString theString(aStringToInsert);
-
- WSFragment *beforeRun, *afterRun;
- FindRun(pointToInsert.Container(), pointToInsert.Offset(),
- &beforeRun, false);
- FindRun(pointToInsert.Container(), pointToInsert.Offset(),
- &afterRun, true);
-
{
// Some scoping for AutoTrackDOMPoint. This will track our insertion
// point while we tweak any surrounding whitespace
AutoTrackDOMPoint tracker(mHTMLEditor->mRangeUpdater, &pointToInsert);
// Handle any changes needed to ws run after inserted text
if (!afterRun || afterRun->mType & WSType::trailingWS) {
// Don't need to do anything. Just insert text. ws won't change.
@@ -505,18 +498,17 @@ WSRunObject::PriorVisibleNode(nsINode* a
int32_t* outVisOffset,
WSType* outType)
{
// Find first visible thing before the point. Position
// outVisNode/outVisOffset just _after_ that thing. If we don't find
// anything return start of ws.
MOZ_ASSERT(aNode && outVisNode && outVisOffset && outType);
- WSFragment* run;
- FindRun(aNode, aOffset, &run, false);
+ WSFragment* run = FindNearestRun(EditorRawDOMPoint(aNode, aOffset), false);
// Is there a visible run there or earlier?
for (; run; run = run->mLeft) {
if (run->mType == WSType::normalWS) {
WSPoint point = GetCharBefore(aNode, aOffset);
// When it's a non-empty text node, return it.
if (point.mTextNode && point.mTextNode->Length()) {
*outVisNode = point.mTextNode;
@@ -547,18 +539,17 @@ WSRunObject::NextVisibleNode(nsINode* aN
int32_t* outVisOffset,
WSType* outType)
{
// Find first visible thing after the point. Position
// outVisNode/outVisOffset just _before_ that thing. If we don't find
// anything return end of ws.
MOZ_ASSERT(aNode && outVisNode && outVisOffset && outType);
- WSFragment* run;
- FindRun(aNode, aOffset, &run, true);
+ WSFragment* run = FindNearestRun(EditorRawDOMPoint(aNode, aOffset), true);
// Is there a visible run there or later?
for (; run; run = run->mRight) {
if (run->mType == WSType::normalWS) {
WSPoint point = GetCharAfter(aNode, aOffset);
// When it's a non-empty text node, return it.
if (point.mTextNode && point.mTextNode->Length()) {
*outVisNode = point.mTextNode;
@@ -1188,19 +1179,18 @@ WSRunObject::PrepareToDeleteRangePriv(WS
// intervening content is deleted. It's overly agressive right
// now. There might be a block boundary remaining between them after
// the deletion, in which case these adjstments are unneeded (though
// I don't think they can ever be harmful?)
NS_ENSURE_TRUE(aEndObject, NS_ERROR_NULL_POINTER);
// get the runs before and after selection
- WSFragment *beforeRun, *afterRun;
- FindRun(mNode, mOffset, &beforeRun, false);
- aEndObject->FindRun(aEndObject->mNode, aEndObject->mOffset, &afterRun, true);
+ WSFragment* beforeRun = FindNearestRun(Point(), false);
+ WSFragment* afterRun = aEndObject->FindNearestRun(aEndObject->Point(), true);
// trim after run of any leading ws
if (afterRun && (afterRun->mType & WSType::leadingWS)) {
nsresult rv =
aEndObject->DeleteChars(aEndObject->mNode, aEndObject->mOffset,
afterRun->mEndNode, afterRun->mEndOffset);
NS_ENSURE_SUCCESS(rv, rv);
}
@@ -1248,19 +1238,18 @@ WSRunObject::PrepareToDeleteRangePriv(WS
nsresult
WSRunObject::PrepareToSplitAcrossBlocksPriv()
{
// used to prepare ws to be split across two blocks. The main issue
// here is make sure normalWS doesn't end up becoming non-significant
// leading or trailing ws after the split.
// get the runs before and after selection
- WSFragment *beforeRun, *afterRun;
- FindRun(mNode, mOffset, &beforeRun, false);
- FindRun(mNode, mOffset, &afterRun, true);
+ WSFragment* beforeRun = FindNearestRun(Point(), false);
+ WSFragment* afterRun = FindNearestRun(Point(), true);
// adjust normal ws in afterRun if needed
if (afterRun && afterRun->mType == WSType::normalWS) {
// make sure leading char of following ws is an nbsp, so that it will show up
WSPoint point = GetCharAfter(mNode, mOffset);
if (point.mTextNode && nsCRT::IsAsciiSpace(point.mChar)) {
nsresult rv = ConvertToNBSP(point);
NS_ENSURE_SUCCESS(rv, rv);
@@ -1547,65 +1536,53 @@ WSRunObject::GetAsciiWSBounds(int16_t aD
}
startNode.forget(outStartNode);
*outStartOffset = startOffset;
endNode.forget(outEndNode);
*outEndOffset = endOffset;
}
-/**
- * Given a dompoint, find the ws run that is before or after it, as caller
- * needs
- */
-void
-WSRunObject::FindRun(nsINode* aNode,
- int32_t aOffset,
- WSFragment** outRun,
- bool after)
+WSRunObject::WSFragment*
+WSRunObject::FindNearestRun(const EditorRawDOMPoint& aPoint,
+ bool aForward)
{
- MOZ_ASSERT(aNode && outRun);
- *outRun = nullptr;
+ MOZ_ASSERT(aPoint.IsSetAndValid());
for (WSFragment* run = mStartRun; run; run = run->mRight) {
- int32_t comp = run->mStartNode ? nsContentUtils::ComparePoints(aNode,
- aOffset, run->mStartNode, run->mStartOffset) : -1;
+ int32_t comp = run->mStartNode ?
+ nsContentUtils::ComparePoints(aPoint, run->StartPoint()) : -1;
if (comp <= 0) {
- if (after) {
- *outRun = run;
- } else {
- // before
- *outRun = nullptr;
- }
- return;
+ // aPoint equals or before start of the run. Return the run if we're
+ // scanning forward, otherwise, nullptr.
+ return aForward ? run : nullptr;
}
- comp = run->mEndNode ? nsContentUtils::ComparePoints(aNode, aOffset,
- run->mEndNode, run->mEndOffset) : -1;
+
+ comp = run->mEndNode ?
+ nsContentUtils::ComparePoints(aPoint, run->EndPoint()) : -1;
if (comp < 0) {
- *outRun = run;
- return;
- } else if (!comp) {
- if (after) {
- *outRun = run->mRight;
- } else {
- // before
- *outRun = run;
- }
- return;
+ // If aPoint is in the run, return the run.
+ return run;
}
+
+ if (!comp) {
+ // If aPoint is at end of the run, return next run if we're scanning
+ // forward, otherwise, return the run.
+ return aForward ? run->mRight : run;
+ }
+
if (!run->mRight) {
- if (after) {
- *outRun = nullptr;
- } else {
- // before
- *outRun = run;
- }
- return;
+ // If the run is the last run and aPoint is after end of the last run,
+ // return nullptr if we're scanning forward, otherwise, return this
+ // last run.
+ return aForward ? nullptr : run;
}
}
+
+ return nullptr;
}
char16_t
WSRunObject::GetCharAt(Text* aTextNode,
int32_t aOffset)
{
// return 0 if we can't get a char, for whatever reason
NS_ENSURE_TRUE(aTextNode, 0);
--- a/editor/libeditor/WSRunObject.h
+++ b/editor/libeditor/WSRunObject.h
@@ -312,16 +312,25 @@ protected:
WSFragment *mLeft, *mRight;
WSFragment()
: mStartOffset(0)
, mEndOffset(0)
, mLeft(nullptr)
, mRight(nullptr)
{}
+
+ EditorRawDOMPoint StartPoint() const
+ {
+ return EditorRawDOMPoint(mStartNode, mStartOffset);
+ }
+ EditorRawDOMPoint EndPoint() const
+ {
+ return EditorRawDOMPoint(mEndNode, mEndOffset);
+ }
};
// A WSPoint struct represents a unique location within the ws run. It is
// always within a textnode that is one of the nodes stored in the list
// in the wsRunObject. For convenience, the character at that point is also
// stored in the struct.
struct MOZ_STACK_CLASS WSPoint final
{
@@ -367,30 +376,65 @@ protected:
WSPoint GetCharAfter(nsINode* aNode, int32_t aOffset);
WSPoint GetCharBefore(nsINode* aNode, int32_t aOffset);
WSPoint GetCharAfter(const WSPoint& aPoint);
WSPoint GetCharBefore(const WSPoint& aPoint);
nsresult ConvertToNBSP(WSPoint aPoint);
void GetAsciiWSBounds(int16_t aDir, nsINode* aNode, int32_t aOffset,
dom::Text** outStartNode, int32_t* outStartOffset,
dom::Text** outEndNode, int32_t* outEndOffset);
- void FindRun(nsINode* aNode, int32_t aOffset, WSFragment** outRun,
- bool after);
+
+ /**
+ * FindNearestRun() looks for a WSFragment which is closest to specified
+ * direction from aPoint.
+ *
+ * @param aPoint The point to start to look for.
+ * @param aForward true if caller needs to look for a WSFragment after the
+ * point in the DOM tree. Otherwise, i.e., before the
+ * point, false.
+ * @return Found WSFragment instance.
+ * If aForward is true and:
+ * if aPoint is end of a run, returns next run.
+ * if aPoint is start of a run, returns the run.
+ * if aPoint is before the first run, returns the first
+ * run.
+ * If aPoint is after the last run, returns nullptr.
+ * If aForward is false and:
+ * if aPoint is end of a run, returns the run.
+ * if aPoint is start of a run, returns its next run.
+ * if aPoint is before the first run, returns nullptr.
+ * if aPoint is after the last run, returns the last run.
+ */
+ WSFragment* FindNearestRun(const EditorRawDOMPoint& aPoint, bool aForward);
+
char16_t GetCharAt(dom::Text* aTextNode, int32_t aOffset);
WSPoint GetWSPointAfter(nsINode* aNode, int32_t aOffset);
WSPoint GetWSPointBefore(nsINode* aNode, int32_t aOffset);
nsresult CheckTrailingNBSPOfRun(WSFragment *aRun);
nsresult CheckTrailingNBSP(WSFragment* aRun, nsINode* aNode,
int32_t aOffset);
nsresult CheckLeadingNBSP(WSFragment* aRun, nsINode* aNode,
int32_t aOffset);
nsresult Scrub();
bool IsBlockNode(nsINode* aNode);
+ EditorRawDOMPoint Point() const
+ {
+ return EditorRawDOMPoint(mNode, mOffset);
+ }
+ EditorRawDOMPoint StartPoint() const
+ {
+ return EditorRawDOMPoint(mStartNode, mStartOffset);
+ }
+ EditorRawDOMPoint EndPoint() const
+ {
+ return EditorRawDOMPoint(mEndNode, mEndOffset);
+ }
+
// The node passed to our constructor.
nsCOMPtr<nsINode> mNode;
// The offset passed to our contructor.
int32_t mOffset;
// Together, the above represent the point at which we are building up ws info.
// true if we are in preformatted whitespace context.
bool mPRE;