bool Element::classChangeNeedsStyleRecalc(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses) { // Class vectors tend to be very short. This is faster than using a hash table. BitVector remainingClassBits; remainingClassBits.ensureSize(oldClasses.size()); for (unsigned i = 0; i < newClasses.size(); ++i) { bool found = false; for (unsigned j = 0; j < oldClasses.size(); ++j) { if (newClasses[i] == oldClasses[j]) { // Mark each class that is still in the newClasses so we can skip doing // an n^2 search below when looking for removals. We can't break from // this loop early since a class can appear more than once. remainingClassBits.quickSet(j); found = true; } } // Class was added. if (!found && affectedByClassSelector(newClasses[i])) return true; } for (unsigned i = 0; i < oldClasses.size(); ++i) { if (remainingClassBits.quickGet(i)) continue; // Class was removed. if (affectedByClassSelector(oldClasses[i])) return true; } return false; }
void RuleFeatureSet::scheduleStyleInvalidationForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, Element& element) { if (!oldClasses.size()) scheduleStyleInvalidationForClassChange(newClasses, element); // Class vectors tend to be very short. This is faster than using a hash table. BitVector remainingClassBits; remainingClassBits.ensureSize(oldClasses.size()); for (unsigned i = 0; i < newClasses.size(); ++i) { bool found = false; for (unsigned j = 0; j < oldClasses.size(); ++j) { if (newClasses[i] == oldClasses[j]) { // Mark each class that is still in the newClasses so we can skip doing // an n^2 search below when looking for removals. We can't break from // this loop early since a class can appear more than once. remainingClassBits.quickSet(j); found = true; } } // Class was added. if (!found) addClassToInvalidationSet(newClasses[i], element); } for (unsigned i = 0; i < oldClasses.size(); ++i) { if (remainingClassBits.quickGet(i)) continue; // Class was removed. addClassToInvalidationSet(oldClasses[i], element); } }
void StyleEngine::classChangedForElement(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, Element& element) { ASSERT(isMaster()); InvalidationSetVector invalidationSets; if (!oldClasses.size()) { classChangedForElement(newClasses, element); return; } // Class vectors tend to be very short. This is faster than using a hash table. BitVector remainingClassBits; remainingClassBits.ensureSize(oldClasses.size()); RuleFeatureSet& ruleFeatureSet = ensureResolver().ensureUpdatedRuleFeatureSet(); for (unsigned i = 0; i < newClasses.size(); ++i) { bool found = false; for (unsigned j = 0; j < oldClasses.size(); ++j) { if (newClasses[i] == oldClasses[j]) { // Mark each class that is still in the newClasses so we can skip doing // an n^2 search below when looking for removals. We can't break from // this loop early since a class can appear more than once. remainingClassBits.quickSet(j); found = true; } } // Class was added. if (!found) ruleFeatureSet.collectInvalidationSetsForClass(invalidationSets, element, newClasses[i]); } for (unsigned i = 0; i < oldClasses.size(); ++i) { if (remainingClassBits.quickGet(i)) continue; // Class was removed. ruleFeatureSet.collectInvalidationSetsForClass(invalidationSets, element, oldClasses[i]); } scheduleInvalidationSetsForElement(invalidationSets, element); }