зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
c963ad97d8
Коммит
053194d8bd
|
@ -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();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче