This source file includes following definitions.
- enqueueMutationRecord
- didInvalidateStyleAttr
- ref
- deref
- length
- item
- cssText
- setCSSText
- getPropertyCSSValue
- getPropertyValue
- getPropertyPriority
- getPropertyShorthand
- isPropertyImplicit
- setProperty
- removeProperty
- getPropertyCSSValueInternal
- getPropertyValueInternal
- setPropertyInternal
- cloneAndCacheForCSSOM
- contextStyleSheet
- copyProperties
- cssPropertyMatches
- m_parentRule
- ref
- deref
- willMutate
- didMutate
- parentStyleSheet
- reattach
- propertySet
- didMutate
- parentStyleSheet
- ref
- deref
#include "config.h"
#include "core/css/PropertySetCSSStyleDeclaration.h"
#include "HTMLNames.h"
#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionState.h"
#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/Element.h"
#include "core/dom/MutationObserverInterestGroup.h"
#include "core/dom/MutationRecord.h"
#include "core/inspector/InspectorInstrumentation.h"
using namespace std;
namespace WebCore {
namespace {
class StyleAttributeMutationScope {
WTF_MAKE_NONCOPYABLE(StyleAttributeMutationScope);
public:
StyleAttributeMutationScope(AbstractPropertySetCSSStyleDeclaration* decl)
{
InspectorInstrumentation::willMutateStyle(decl);
++s_scopeCount;
if (s_scopeCount != 1) {
ASSERT(s_currentDecl == decl);
return;
}
ASSERT(!s_currentDecl);
s_currentDecl = decl;
if (!s_currentDecl->parentElement())
return;
bool shouldReadOldValue = false;
m_mutationRecipients = MutationObserverInterestGroup::createForAttributesMutation(*s_currentDecl->parentElement(), HTMLNames::styleAttr);
if (m_mutationRecipients && m_mutationRecipients->isOldValueRequested())
shouldReadOldValue = true;
AtomicString oldValue;
if (shouldReadOldValue)
oldValue = s_currentDecl->parentElement()->getAttribute(HTMLNames::styleAttr);
if (m_mutationRecipients) {
AtomicString requestedOldValue = m_mutationRecipients->isOldValueRequested() ? oldValue : nullAtom;
m_mutation = MutationRecord::createAttributes(s_currentDecl->parentElement(), HTMLNames::styleAttr, requestedOldValue);
}
}
~StyleAttributeMutationScope()
{
--s_scopeCount;
if (s_scopeCount)
return;
if (m_mutation && s_shouldDeliver)
m_mutationRecipients->enqueueMutationRecord(m_mutation);
s_shouldDeliver = false;
AbstractPropertySetCSSStyleDeclaration* localCopyStyleDecl = s_currentDecl;
s_currentDecl = 0;
InspectorInstrumentation::didMutateStyle(localCopyStyleDecl, localCopyStyleDecl->parentElement());
if (!s_shouldNotifyInspector)
return;
s_shouldNotifyInspector = false;
if (localCopyStyleDecl->parentElement())
InspectorInstrumentation::didInvalidateStyleAttr(localCopyStyleDecl->parentElement());
}
void enqueueMutationRecord()
{
s_shouldDeliver = true;
}
void didInvalidateStyleAttr()
{
s_shouldNotifyInspector = true;
}
private:
static unsigned s_scopeCount;
static AbstractPropertySetCSSStyleDeclaration* s_currentDecl;
static bool s_shouldNotifyInspector;
static bool s_shouldDeliver;
OwnPtr<MutationObserverInterestGroup> m_mutationRecipients;
RefPtr<MutationRecord> m_mutation;
};
unsigned StyleAttributeMutationScope::s_scopeCount = 0;
AbstractPropertySetCSSStyleDeclaration* StyleAttributeMutationScope::s_currentDecl = 0;
bool StyleAttributeMutationScope::s_shouldNotifyInspector = false;
bool StyleAttributeMutationScope::s_shouldDeliver = false;
}
void PropertySetCSSStyleDeclaration::ref()
{
m_propertySet->ref();
}
void PropertySetCSSStyleDeclaration::deref()
{
m_propertySet->deref();
}
unsigned AbstractPropertySetCSSStyleDeclaration::length() const
{
return propertySet().propertyCount();
}
String AbstractPropertySetCSSStyleDeclaration::item(unsigned i) const
{
if (i >= propertySet().propertyCount())
return "";
return propertySet().propertyAt(i).cssName();
}
String AbstractPropertySetCSSStyleDeclaration::cssText() const
{
return propertySet().asText();
}
void AbstractPropertySetCSSStyleDeclaration::setCSSText(const String& text, ExceptionState& exceptionState)
{
StyleAttributeMutationScope mutationScope(this);
willMutate();
propertySet().parseDeclaration(text, contextStyleSheet());
didMutate(PropertyChanged);
mutationScope.enqueueMutationRecord();
}
PassRefPtrWillBeRawPtr<CSSValue> AbstractPropertySetCSSStyleDeclaration::getPropertyCSSValue(const String& propertyName)
{
CSSPropertyID propertyID = cssPropertyID(propertyName);
if (!propertyID)
return nullptr;
return cloneAndCacheForCSSOM(propertySet().getPropertyCSSValue(propertyID).get());
}
String AbstractPropertySetCSSStyleDeclaration::getPropertyValue(const String &propertyName)
{
CSSPropertyID propertyID = cssPropertyID(propertyName);
if (!propertyID)
return String();
return propertySet().getPropertyValue(propertyID);
}
String AbstractPropertySetCSSStyleDeclaration::getPropertyPriority(const String& propertyName)
{
CSSPropertyID propertyID = cssPropertyID(propertyName);
if (!propertyID)
return String();
return propertySet().propertyIsImportant(propertyID) ? "important" : "";
}
String AbstractPropertySetCSSStyleDeclaration::getPropertyShorthand(const String& propertyName)
{
CSSPropertyID propertyID = cssPropertyID(propertyName);
if (!propertyID)
return String();
CSSPropertyID shorthandID = propertySet().getPropertyShorthand(propertyID);
if (!shorthandID)
return String();
return getPropertyNameString(shorthandID);
}
bool AbstractPropertySetCSSStyleDeclaration::isPropertyImplicit(const String& propertyName)
{
CSSPropertyID propertyID = cssPropertyID(propertyName);
if (!propertyID)
return false;
return propertySet().isPropertyImplicit(propertyID);
}
void AbstractPropertySetCSSStyleDeclaration::setProperty(const String& propertyName, const String& value, const String& priority, ExceptionState& exceptionState)
{
CSSPropertyID propertyID = cssPropertyID(propertyName);
if (!propertyID)
return;
bool important = equalIgnoringCase(priority, "important");
if (!important && !priority.isEmpty())
return;
setPropertyInternal(propertyID, value, important, exceptionState);
}
String AbstractPropertySetCSSStyleDeclaration::removeProperty(const String& propertyName, ExceptionState& exceptionState)
{
StyleAttributeMutationScope mutationScope(this);
CSSPropertyID propertyID = cssPropertyID(propertyName);
if (!propertyID)
return String();
willMutate();
String result;
bool changed = propertySet().removeProperty(propertyID, &result);
didMutate(changed ? PropertyChanged : NoChanges);
if (changed)
mutationScope.enqueueMutationRecord();
return result;
}
PassRefPtrWillBeRawPtr<CSSValue> AbstractPropertySetCSSStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
{
return propertySet().getPropertyCSSValue(propertyID);
}
String AbstractPropertySetCSSStyleDeclaration::getPropertyValueInternal(CSSPropertyID propertyID)
{
return propertySet().getPropertyValue(propertyID);
}
void AbstractPropertySetCSSStyleDeclaration::setPropertyInternal(CSSPropertyID propertyID, const String& value, bool important, ExceptionState&)
{
StyleAttributeMutationScope mutationScope(this);
willMutate();
bool changed = propertySet().setProperty(propertyID, value, important, contextStyleSheet());
didMutate(changed ? PropertyChanged : NoChanges);
if (changed)
mutationScope.enqueueMutationRecord();
}
CSSValue* AbstractPropertySetCSSStyleDeclaration::cloneAndCacheForCSSOM(CSSValue* internalValue)
{
if (!internalValue)
return 0;
if (!m_cssomCSSValueClones)
m_cssomCSSValueClones = adoptPtrWillBeNoop(new WillBeHeapHashMap<CSSValue*, RefPtrWillBeMember<CSSValue> >);
RefPtrWillBeMember<CSSValue>& clonedValue = m_cssomCSSValueClones->add(internalValue, RefPtrWillBeMember<CSSValue>()).storedValue->value;
if (!clonedValue)
clonedValue = internalValue->cloneForCSSOM();
return clonedValue.get();
}
StyleSheetContents* AbstractPropertySetCSSStyleDeclaration::contextStyleSheet() const
{
CSSStyleSheet* cssStyleSheet = parentStyleSheet();
return cssStyleSheet ? cssStyleSheet->contents() : 0;
}
PassRefPtrWillBeRawPtr<MutableStylePropertySet> AbstractPropertySetCSSStyleDeclaration::copyProperties() const
{
return propertySet().mutableCopy();
}
bool AbstractPropertySetCSSStyleDeclaration::cssPropertyMatches(CSSPropertyID propertyID, const CSSValue* propertyValue) const
{
return propertySet().propertyMatches(propertyID, propertyValue);
}
StyleRuleCSSStyleDeclaration::StyleRuleCSSStyleDeclaration(MutableStylePropertySet& propertySetArg, CSSRule* parentRule)
: PropertySetCSSStyleDeclaration(propertySetArg)
, m_refCount(1)
, m_parentRule(parentRule)
{
m_propertySet->ref();
}
StyleRuleCSSStyleDeclaration::~StyleRuleCSSStyleDeclaration()
{
m_propertySet->deref();
}
void StyleRuleCSSStyleDeclaration::ref()
{
++m_refCount;
}
void StyleRuleCSSStyleDeclaration::deref()
{
ASSERT(m_refCount);
if (!--m_refCount)
delete this;
}
void StyleRuleCSSStyleDeclaration::willMutate()
{
if (m_parentRule && m_parentRule->parentStyleSheet())
m_parentRule->parentStyleSheet()->willMutateRules();
}
void StyleRuleCSSStyleDeclaration::didMutate(MutationType type)
{
if (type == PropertyChanged)
m_cssomCSSValueClones.clear();
if (m_parentRule && m_parentRule->parentStyleSheet())
m_parentRule->parentStyleSheet()->didMutateRules();
}
CSSStyleSheet* StyleRuleCSSStyleDeclaration::parentStyleSheet() const
{
return m_parentRule ? m_parentRule->parentStyleSheet() : 0;
}
void StyleRuleCSSStyleDeclaration::reattach(MutableStylePropertySet& propertySet)
{
m_propertySet->deref();
m_propertySet = &propertySet;
m_propertySet->ref();
}
MutableStylePropertySet& InlineCSSStyleDeclaration::propertySet() const
{
return m_parentElement->ensureMutableInlineStyle();
}
void InlineCSSStyleDeclaration::didMutate(MutationType type)
{
if (type == NoChanges)
return;
m_cssomCSSValueClones.clear();
if (!m_parentElement)
return;
m_parentElement->clearMutableInlineStyleIfEmpty();
m_parentElement->setNeedsStyleRecalc(LocalStyleChange);
m_parentElement->invalidateStyleAttribute();
StyleAttributeMutationScope(this).didInvalidateStyleAttr();
}
CSSStyleSheet* InlineCSSStyleDeclaration::parentStyleSheet() const
{
return m_parentElement ? &m_parentElement->document().elementSheet() : 0;
}
void InlineCSSStyleDeclaration::ref()
{
m_parentElement->ref();
}
void InlineCSSStyleDeclaration::deref()
{
m_parentElement->deref();
}
}