Index: Source/core/css/StylePropertySet.cpp |
diff --git a/Source/core/css/StylePropertySet.cpp b/Source/core/css/StylePropertySet.cpp |
index 3f84e58ee46f0e76140b808322d65e306dfb528b..78e5fe1621df7a6a18c4ba199da13535d9dcc726 100644 |
--- a/Source/core/css/StylePropertySet.cpp |
+++ b/Source/core/css/StylePropertySet.cpp |
@@ -284,8 +284,15 @@ bool MutableStylePropertySet::setVariableValue(const AtomicString& name, const S |
return removeVariable(name); |
size_t index = findVariableIndex(name); |
- if (index != notFound) { |
- CSSValue* cssValue = m_propertyVector.at(index).value(); |
+ if (index == notFound) { |
+ VariablesIterators* iterators = activeVariablesIterators(); |
+ if (iterators) { |
+ VariablesIterators::iterator end = iterators->end(); |
+ for (VariablesIterators::iterator it = iterators->begin(); it != end; ++it) |
+ (*it)->addedVariable(name); |
+ } |
+ } else { |
+ const CSSValue* cssValue = m_propertyVector.at(index).value(); |
if (toCSSVariableValue(cssValue)->value() == value) |
return false; |
} |
@@ -552,6 +559,12 @@ bool MutableStylePropertySet::removeVariable(const AtomicString& name) |
if (index == notFound) |
return false; |
m_propertyVector.remove(index); |
+ VariablesIterators* iterators = activeVariablesIterators(); |
+ if (iterators) { |
+ VariablesIterators::iterator end = iterators->end(); |
+ for (VariablesIterators::iterator it = iterators->begin(); it != end; ++it) |
+ (*it)->removedVariable(name); |
+ } |
return true; |
} |
@@ -559,7 +572,93 @@ bool MutableStylePropertySet::clearVariables() |
{ |
ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled()); |
CSSPropertyID variablesId = CSSPropertyVariable; |
- return removePropertiesInSet(&variablesId, 1); |
+ bool removed = removePropertiesInSet(&variablesId, 1); |
+ if (removed) { |
+ VariablesIterators* iterators = activeVariablesIterators(); |
+ if (iterators) { |
+ VariablesIterators::iterator end = iterators->end(); |
+ for (VariablesIterators::iterator it = iterators->begin(); it != end; ++it) |
+ (*it)->clearedVariables(); |
+ } |
+ } |
+ return removed; |
+} |
+ |
+PassRefPtr<MutableStylePropertySet::VariablesIterator> MutableStylePropertySet::VariablesIterator::create(MutableStylePropertySet* propertySet) |
+{ |
+ ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled()); |
+ RefPtr<VariablesIterator> iterator = adoptRef(new VariablesIterator(propertySet)); |
+ const size_t propertyCount = propertySet->propertyCount(); |
+ size_t variableCount = 0; |
+ iterator->m_remainingNames.resize(propertyCount); |
+ for (int i = propertyCount; i--;) { |
+ const PropertyReference& property = propertySet->propertyAt(i); |
+ if (property.id() == CSSPropertyVariable) |
+ iterator->m_remainingNames[variableCount++] = toCSSVariableValue(property.value())->name(); |
+ } |
+ iterator->m_remainingNames.shrink(variableCount); |
+ |
+ MutableStylePropertySet::VariablesIteratorsMap* map = MutableStylePropertySet::activeVariablesIteratorsMap(); |
+ if (map->contains(propertySet)) |
+ map->find(propertySet)->value.append(iterator); |
+ else |
+ map->add(propertySet, VariablesIterators()).iterator->value.append(iterator); |
+ |
+ return iterator.release(); |
+} |
+ |
+void MutableStylePropertySet::VariablesIterator::addedVariable(const AtomicString& name) |
+{ |
+ ASSERT(!m_remainingNames.contains(name)); |
+ ASSERT(!m_newNames.contains(name)); |
+ m_newNames.append(name); |
+} |
+ |
+void MutableStylePropertySet::VariablesIterator::removedVariable(const AtomicString& name) |
+{ |
+ size_t index = m_remainingNames.find(name); |
+ if (index != notFound) |
+ m_remainingNames.remove(index); |
+ index = m_newNames.find(name); |
+ if (index != notFound) |
+ m_newNames.remove(index); |
+} |
+ |
+void MutableStylePropertySet::VariablesIterator::clearedVariables() |
+{ |
+ m_remainingNames.clear(); |
+ m_newNames.clear(); |
+} |
+ |
+void MutableStylePropertySet::VariablesIterator::advance() |
+{ |
+ if (!atEnd()) |
+ m_remainingNames.removeLast(); |
+ if (!m_newNames.isEmpty()) { |
+ m_remainingNames.appendVector(m_newNames); |
+ m_newNames.clear(); |
+ } |
+} |
+ |
+MutableStylePropertySet::VariablesIterator::~VariablesIterator() |
+{ |
+ MutableStylePropertySet::VariablesIterators& iterators = MutableStylePropertySet::activeVariablesIteratorsMap()->find(m_propertySet.get())->value; |
+ iterators.remove(iterators.reverseFind(this)); |
+} |
+ |
+MutableStylePropertySet::VariablesIterators* MutableStylePropertySet::activeVariablesIterators() |
+{ |
+ VariablesIteratorsMap* map = activeVariablesIteratorsMap(); |
+ VariablesIteratorsMap::iterator it = map->find(this); |
+ if (it == map->end()) |
+ return 0; |
+ return &it->value; |
+} |
+ |
+MutableStylePropertySet::VariablesIteratorsMap* MutableStylePropertySet::activeVariablesIteratorsMap() |
+{ |
+ DEFINE_STATIC_LOCAL(VariablesIteratorsMap, map, ()); |
+ return ↦ |
} |
PassRefPtr<MutableStylePropertySet> StylePropertySet::mutableCopy() const |
@@ -634,6 +733,11 @@ PassRefPtr<MutableStylePropertySet> MutableStylePropertySet::create(const CSSPro |
return adoptRef(new MutableStylePropertySet(properties, count)); |
} |
+MutableStylePropertySet::~MutableStylePropertySet() |
+{ |
+ activeVariablesIteratorsMap()->remove(this); |
+} |
+ |
String StylePropertySet::PropertyReference::cssName() const |
{ |
if (id() == CSSPropertyVariable) { |