Bug 1530208. Fix isEqualNode to not do a bunch of string-copying. r=mccr8

Differential Revision: https://phabricator.services.mozilla.com/D21824

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Boris Zbarsky 2019-03-04 19:43:47 +00:00
Родитель c963ad97d8
Коммит 053194d8bd
4 изменённых файлов: 61 добавлений и 5 удалений

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

@ -208,6 +208,14 @@ class CharacterData : public nsIContent {
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_INHERITED(
CharacterData, nsIContent)
/**
* Compare two CharacterData nodes for text equality.
*/
MOZ_MUST_USE
bool TextEquals(const CharacterData* aOther) const {
return mText.TextEquals(aOther->mText);
}
protected:
virtual ~CharacterData();

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

@ -816,6 +816,12 @@ bool nsINode::IsEqualNode(nsINode* aOther) {
return false;
}
// Might as well do a quick check to avoid walking our kids if we're
// obviously the same.
if (aOther == this) {
return true;
}
nsAutoString string1, string2;
nsINode* node1 = this;
@ -868,12 +874,10 @@ bool nsINode::IsEqualNode(nsINode* aOther) {
case PROCESSING_INSTRUCTION_NODE: {
MOZ_ASSERT(node1->IsCharacterData());
MOZ_ASSERT(node2->IsCharacterData());
string1.Truncate();
static_cast<CharacterData*>(node1)->AppendTextTo(string1);
string2.Truncate();
static_cast<CharacterData*>(node2)->AppendTextTo(string2);
auto* data1 = static_cast<CharacterData*>(node1);
auto* data2 = static_cast<CharacterData*>(node2);
if (!string1.Equals(string2)) {
if (!data1->TextEquals(data2)) {
return false;
}

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

@ -490,3 +490,41 @@ void nsTextFragment::UpdateBidiFlag(const char16_t* aBuffer, uint32_t aLength) {
}
}
}
bool nsTextFragment::TextEquals(const nsTextFragment& aOther) const {
if (!Is2b()) {
// We're 1-byte.
if (!aOther.Is2b()) {
nsDependentCSubstring ourStr(Get1b(), GetLength());
return ourStr.Equals(
nsDependentCSubstring(aOther.Get1b(), aOther.GetLength()));
}
// We're 1-byte, the other thing is 2-byte. Instead of implementing a
// separate codepath for this, just use our code below.
return aOther.TextEquals(*this);
}
nsDependentSubstring ourStr(Get2b(), GetLength());
if (aOther.Is2b()) {
return ourStr.Equals(
nsDependentSubstring(aOther.Get2b(), aOther.GetLength()));
}
// We can't use EqualsASCII here, because the other string might not
// actually be ASCII. Just roll our own compare; do it in the simple way.
// Bug 1532356 tracks not having to roll our own.
if (GetLength() != aOther.GetLength()) {
return false;
}
const char16_t* ourChars = Get2b();
const char* otherChars = aOther.Get1b();
for (uint32_t i = 0; i < GetLength(); ++i) {
if (ourChars[i] != static_cast<char16_t>(otherChars[i])) {
return false;
}
}
return true;
}

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

@ -236,6 +236,12 @@ class nsTextFragment final {
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
/**
* Check whether the text in this fragment is the same as the text in the
* other fragment.
*/
MOZ_MUST_USE bool TextEquals(const nsTextFragment& aOther) const;
private:
void ReleaseText();