Bug 1408227 - part 3: Redesign WSRunObject::FindRun() with EditorRawDOMPoint r=m_kato

WSRunObject::FindRun() finds the nearest run from aPoint to specified direction.
So, it uses nsContentUtils::ComparePoints() a lot.  Therefore, it should use
an overload which takes RawRangeBoundary.  Although, it's not optimized for
RawRangeBoundary, but if it'd be optimized, this method becomes faster.

And this patch renames it to FindNearestRun().

MozReview-Commit-ID: 2NkR5E1st6d

--HG--
extra : rebase_source : 387ecc9d483c7cd88306197391fc2940b2000e28
This commit is contained in:
Masayuki Nakano 2017-11-21 19:03:03 +09:00
Родитель 3ad91ac0fd
Коммит 304f2a7e0f
2 изменённых файлов: 84 добавлений и 63 удалений

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

@ -180,11 +180,8 @@ WSRunObject::InsertBreak(Selection& aSelection,
// 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);
{
@ -273,15 +270,11 @@ WSRunObject::InsertText(nsIDocument& aDocument,
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
@ -510,8 +503,7 @@ WSRunObject::PriorVisibleNode(nsINode* aNode,
// 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) {
@ -552,8 +544,7 @@ WSRunObject::NextVisibleNode(nsINode* aNode,
// 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) {
@ -1193,9 +1184,8 @@ WSRunObject::PrepareToDeleteRangePriv(WSRunObject* aEndObject)
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)) {
@ -1253,9 +1243,8 @@ WSRunObject::PrepareToSplitAcrossBlocksPriv()
// 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) {
@ -1552,55 +1541,43 @@ WSRunObject::GetAsciiWSBounds(int16_t aDir,
*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

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

@ -317,6 +317,15 @@ protected:
, 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
@ -372,8 +381,30 @@ protected:
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);
@ -386,6 +417,19 @@ protected:
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.