Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / core / css / PropertySetCSSStyleDeclaration.cpp
blob04d3ecaa3fea7098ada32a441e825f28418b4f70
1 /*
2 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
4 * Copyright (C) 2011 Research In Motion Limited. All rights reserved.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
22 #include "config.h"
23 #include "core/css/PropertySetCSSStyleDeclaration.h"
25 #include "bindings/core/v8/ExceptionState.h"
26 #include "core/HTMLNames.h"
27 #include "core/css/CSSKeyframesRule.h"
28 #include "core/css/CSSStyleSheet.h"
29 #include "core/css/StylePropertySet.h"
30 #include "core/dom/Element.h"
31 #include "core/dom/MutationObserverInterestGroup.h"
32 #include "core/dom/MutationRecord.h"
33 #include "core/inspector/InspectorInstrumentation.h"
34 #include "platform/RuntimeEnabledFeatures.h"
36 namespace blink {
38 namespace {
40 class StyleAttributeMutationScope {
41 WTF_MAKE_NONCOPYABLE(StyleAttributeMutationScope);
42 STACK_ALLOCATED();
43 public:
44 StyleAttributeMutationScope(AbstractPropertySetCSSStyleDeclaration* decl)
46 ++s_scopeCount;
48 if (s_scopeCount != 1) {
49 ASSERT(s_currentDecl == decl);
50 return;
53 ASSERT(!s_currentDecl);
54 s_currentDecl = decl;
56 if (!s_currentDecl->parentElement())
57 return;
59 bool shouldReadOldValue = false;
61 m_mutationRecipients = MutationObserverInterestGroup::createForAttributesMutation(*s_currentDecl->parentElement(), HTMLNames::styleAttr);
62 if (m_mutationRecipients && m_mutationRecipients->isOldValueRequested())
63 shouldReadOldValue = true;
65 AtomicString oldValue;
66 if (shouldReadOldValue)
67 oldValue = s_currentDecl->parentElement()->getAttribute(HTMLNames::styleAttr);
69 if (m_mutationRecipients) {
70 AtomicString requestedOldValue = m_mutationRecipients->isOldValueRequested() ? oldValue : nullAtom;
71 m_mutation = MutationRecord::createAttributes(s_currentDecl->parentElement(), HTMLNames::styleAttr, requestedOldValue);
75 ~StyleAttributeMutationScope()
77 --s_scopeCount;
78 if (s_scopeCount)
79 return;
81 if (m_mutation && s_shouldDeliver)
82 m_mutationRecipients->enqueueMutationRecord(m_mutation);
84 s_shouldDeliver = false;
86 // We have to clear internal state before calling Inspector's code.
87 AbstractPropertySetCSSStyleDeclaration* localCopyStyleDecl = s_currentDecl;
88 s_currentDecl = 0;
90 if (!s_shouldNotifyInspector)
91 return;
93 s_shouldNotifyInspector = false;
94 if (localCopyStyleDecl->parentElement())
95 InspectorInstrumentation::didInvalidateStyleAttr(localCopyStyleDecl->parentElement());
98 void enqueueMutationRecord()
100 s_shouldDeliver = true;
103 void didInvalidateStyleAttr()
105 s_shouldNotifyInspector = true;
108 private:
109 static unsigned s_scopeCount;
110 static AbstractPropertySetCSSStyleDeclaration* s_currentDecl;
111 static bool s_shouldNotifyInspector;
112 static bool s_shouldDeliver;
114 OwnPtrWillBeMember<MutationObserverInterestGroup> m_mutationRecipients;
115 RefPtrWillBeMember<MutationRecord> m_mutation;
118 unsigned StyleAttributeMutationScope::s_scopeCount = 0;
119 AbstractPropertySetCSSStyleDeclaration* StyleAttributeMutationScope::s_currentDecl = 0;
120 bool StyleAttributeMutationScope::s_shouldNotifyInspector = false;
121 bool StyleAttributeMutationScope::s_shouldDeliver = false;
123 } // namespace
125 #if !ENABLE(OILPAN)
126 void PropertySetCSSStyleDeclaration::ref()
128 m_propertySet->ref();
131 void PropertySetCSSStyleDeclaration::deref()
133 m_propertySet->deref();
135 #endif
137 DEFINE_TRACE(PropertySetCSSStyleDeclaration)
139 visitor->trace(m_propertySet);
140 AbstractPropertySetCSSStyleDeclaration::trace(visitor);
143 unsigned AbstractPropertySetCSSStyleDeclaration::length() const
145 return propertySet().propertyCount();
148 String AbstractPropertySetCSSStyleDeclaration::item(unsigned i) const
150 if (i >= propertySet().propertyCount())
151 return "";
152 return getPropertyName(propertySet().propertyAt(i).id());
155 String AbstractPropertySetCSSStyleDeclaration::cssText() const
157 return propertySet().asText();
160 void AbstractPropertySetCSSStyleDeclaration::setCSSText(const String& text, ExceptionState&)
162 StyleAttributeMutationScope mutationScope(this);
163 willMutate();
165 propertySet().parseDeclarationList(text, contextStyleSheet());
167 didMutate(PropertyChanged);
169 mutationScope.enqueueMutationRecord();
172 String AbstractPropertySetCSSStyleDeclaration::getPropertyValue(const String &propertyName)
174 CSSPropertyID propertyID = cssPropertyID(propertyName);
175 if (!propertyID)
176 return String();
177 return propertySet().getPropertyValue(propertyID);
180 String AbstractPropertySetCSSStyleDeclaration::getPropertyPriority(const String& propertyName)
182 CSSPropertyID propertyID = cssPropertyID(propertyName);
183 if (!propertyID)
184 return String();
185 return propertySet().propertyIsImportant(propertyID) ? "important" : "";
188 String AbstractPropertySetCSSStyleDeclaration::getPropertyShorthand(const String& propertyName)
190 CSSPropertyID propertyID = cssPropertyID(propertyName);
191 if (!propertyID)
192 return String();
193 CSSPropertyID shorthandID = propertySet().getPropertyShorthand(propertyID);
194 if (!shorthandID)
195 return String();
196 return getPropertyNameString(shorthandID);
199 bool AbstractPropertySetCSSStyleDeclaration::isPropertyImplicit(const String& propertyName)
201 CSSPropertyID propertyID = cssPropertyID(propertyName);
202 if (!propertyID)
203 return false;
204 return propertySet().isPropertyImplicit(propertyID);
207 void AbstractPropertySetCSSStyleDeclaration::setProperty(const String& propertyName, const String& value, const String& priority, ExceptionState& exceptionState)
209 CSSPropertyID propertyID = unresolvedCSSPropertyID(propertyName);
210 if (!propertyID)
211 return;
213 bool important = equalIgnoringCase(priority, "important");
214 if (!important && !priority.isEmpty())
215 return;
217 setPropertyInternal(propertyID, value, important, exceptionState);
220 String AbstractPropertySetCSSStyleDeclaration::removeProperty(const String& propertyName, ExceptionState& exceptionState)
222 StyleAttributeMutationScope mutationScope(this);
223 CSSPropertyID propertyID = cssPropertyID(propertyName);
224 if (!propertyID)
225 return String();
227 willMutate();
229 String result;
230 bool changed = propertySet().removeProperty(propertyID, &result);
232 didMutate(changed ? PropertyChanged : NoChanges);
234 if (changed)
235 mutationScope.enqueueMutationRecord();
236 return result;
239 PassRefPtrWillBeRawPtr<CSSValue> AbstractPropertySetCSSStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
241 return propertySet().getPropertyCSSValue(propertyID);
244 String AbstractPropertySetCSSStyleDeclaration::getPropertyValueInternal(CSSPropertyID propertyID)
246 return propertySet().getPropertyValue(propertyID);
249 void AbstractPropertySetCSSStyleDeclaration::setPropertyInternal(CSSPropertyID unresolvedProperty, const String& value, bool important, ExceptionState&)
251 StyleAttributeMutationScope mutationScope(this);
252 willMutate();
254 bool changed = propertySet().setProperty(unresolvedProperty, value, important, contextStyleSheet());
256 didMutate(changed ? PropertyChanged : NoChanges);
258 if (changed)
259 mutationScope.enqueueMutationRecord();
262 StyleSheetContents* AbstractPropertySetCSSStyleDeclaration::contextStyleSheet() const
264 CSSStyleSheet* cssStyleSheet = parentStyleSheet();
265 return cssStyleSheet ? cssStyleSheet->contents() : nullptr;
268 bool AbstractPropertySetCSSStyleDeclaration::cssPropertyMatches(CSSPropertyID propertyID, const CSSValue* propertyValue) const
270 return propertySet().propertyMatches(propertyID, propertyValue);
273 DEFINE_TRACE(AbstractPropertySetCSSStyleDeclaration)
275 CSSStyleDeclaration::trace(visitor);
278 StyleRuleCSSStyleDeclaration::StyleRuleCSSStyleDeclaration(MutableStylePropertySet& propertySetArg, CSSRule* parentRule)
279 : PropertySetCSSStyleDeclaration(propertySetArg)
280 #if !ENABLE(OILPAN)
281 , m_refCount(1)
282 #endif
283 , m_parentRule(parentRule)
285 #if !ENABLE(OILPAN)
286 m_propertySet->ref();
287 #endif
290 StyleRuleCSSStyleDeclaration::~StyleRuleCSSStyleDeclaration()
292 #if !ENABLE(OILPAN)
293 m_propertySet->deref();
294 #endif
297 #if !ENABLE(OILPAN)
298 void StyleRuleCSSStyleDeclaration::ref()
300 ++m_refCount;
303 void StyleRuleCSSStyleDeclaration::deref()
305 ASSERT(m_refCount);
306 if (!--m_refCount)
307 delete this;
309 #endif
311 void StyleRuleCSSStyleDeclaration::willMutate()
313 if (m_parentRule && m_parentRule->parentStyleSheet())
314 m_parentRule->parentStyleSheet()->willMutateRules();
317 void StyleRuleCSSStyleDeclaration::didMutate(MutationType type)
319 // Style sheet mutation needs to be signaled even if the change failed. willMutateRules/didMutateRules must pair.
320 if (m_parentRule && m_parentRule->parentStyleSheet())
321 m_parentRule->parentStyleSheet()->didMutateRules();
324 CSSStyleSheet* StyleRuleCSSStyleDeclaration::parentStyleSheet() const
326 return m_parentRule ? m_parentRule->parentStyleSheet() : nullptr;
329 void StyleRuleCSSStyleDeclaration::reattach(MutableStylePropertySet& propertySet)
331 #if !ENABLE(OILPAN)
332 m_propertySet->deref();
333 #endif
334 m_propertySet = &propertySet;
335 #if !ENABLE(OILPAN)
336 m_propertySet->ref();
337 #endif
340 DEFINE_TRACE(StyleRuleCSSStyleDeclaration)
342 visitor->trace(m_parentRule);
343 PropertySetCSSStyleDeclaration::trace(visitor);
346 MutableStylePropertySet& InlineCSSStyleDeclaration::propertySet() const
348 return m_parentElement->ensureMutableInlineStyle();
351 void InlineCSSStyleDeclaration::didMutate(MutationType type)
353 if (type == NoChanges)
354 return;
356 if (!m_parentElement)
357 return;
359 m_parentElement->clearMutableInlineStyleIfEmpty();
360 m_parentElement->setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::InlineCSSStyleMutated));
361 m_parentElement->invalidateStyleAttribute();
362 StyleAttributeMutationScope(this).didInvalidateStyleAttr();
365 CSSStyleSheet* InlineCSSStyleDeclaration::parentStyleSheet() const
367 return m_parentElement ? &m_parentElement->document().elementSheet() : nullptr;
370 #if !ENABLE(OILPAN)
371 void InlineCSSStyleDeclaration::ref()
373 m_parentElement->ref();
376 void InlineCSSStyleDeclaration::deref()
378 m_parentElement->deref();
380 #endif
382 DEFINE_TRACE(InlineCSSStyleDeclaration)
384 visitor->trace(m_parentElement);
385 AbstractPropertySetCSSStyleDeclaration::trace(visitor);
388 } // namespace blink