Bug 1184842. Restyling should consider only the classes that have changed. r=heycam

This commit is contained in:
Robert O'Callahan 2015-07-25 17:56:58 +12:00
parent c0b6fcd9ee
commit 727bfb81dc

View File

@ -55,6 +55,7 @@
#include "mozilla/Likely.h"
#include "mozilla/TypedEnumBits.h"
#include "RuleProcessorCache.h"
#include "nsIDOMMutationEvent.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -2802,17 +2803,39 @@ nsCSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData
}
if (aData->mAttribute == nsGkAtoms::_class) {
const nsAttrValue* otherClasses = aData->mOtherValue;
NS_ASSERTION(otherClasses ||
aData->mModType == nsIDOMMutationEvent::REMOVAL,
"All class values should be StoresOwnData and parsed"
"via Element::BeforeSetAttr, so available here");
// For WillChange, enumerate classes that will be removed to see which
// rules apply before the change.
// For Changed, enumerate classes that have been added to see which rules
// apply after the change.
// In both cases we're interested in the classes that are currently on
// the element but not in mOtherValue.
const nsAttrValue* elementClasses = aData->mElement->GetClasses();
if (elementClasses) {
int32_t atomCount = elementClasses->GetAtomCount();
for (int32_t i = 0; i < atomCount; ++i) {
nsIAtom* curClass = elementClasses->AtomAt(i);
AtomSelectorEntry *entry =
static_cast<AtomSelectorEntry*>
(PL_DHashTableSearch(&cascade->mClassSelectors,
curClass));
if (entry) {
EnumerateSelectors(entry->mSelectors, &data);
if (atomCount > 0) {
nsTHashtable<nsPtrHashKey<nsIAtom>> otherClassesTable;
if (otherClasses) {
int32_t otherClassesCount = otherClasses->GetAtomCount();
for (int32_t i = 0; i < otherClassesCount; ++i) {
otherClassesTable.PutEntry(otherClasses->AtomAt(i));
}
}
for (int32_t i = 0; i < atomCount; ++i) {
nsIAtom* curClass = elementClasses->AtomAt(i);
if (!otherClassesTable.Contains(curClass)) {
AtomSelectorEntry *entry =
static_cast<AtomSelectorEntry*>
(PL_DHashTableSearch(&cascade->mClassSelectors,
curClass));
if (entry) {
EnumerateSelectors(entry->mSelectors, &data);
}
}
}
}
}