1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set tw=78 expandtab softtabstop=2 ts=2 sw=2: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* DOM object returned from element.getComputedStyle() */
9 #include "nsComputedDOMStyle.h"
11 #include "mozilla/ArrayUtils.h"
12 #include "mozilla/Preferences.h"
15 #include "nsDOMString.h"
16 #include "nsIDOMCSSPrimitiveValue.h"
18 #include "nsIFrameInlines.h"
19 #include "nsStyleContext.h"
20 #include "nsIScrollableFrame.h"
21 #include "nsContentUtils.h"
22 #include "nsIContent.h"
24 #include "nsDOMCSSRect.h"
25 #include "nsDOMCSSRGBColor.h"
26 #include "nsDOMCSSValueList.h"
27 #include "nsFlexContainerFrame.h"
28 #include "nsGkAtoms.h"
29 #include "nsHTMLReflowState.h"
30 #include "nsStyleUtil.h"
31 #include "nsStyleStructInlines.h"
32 #include "nsROCSSPrimitiveValue.h"
34 #include "nsPresContext.h"
35 #include "nsIDocument.h"
37 #include "nsCSSPseudoElements.h"
38 #include "nsStyleSet.h"
39 #include "imgIRequest.h"
40 #include "nsLayoutUtils.h"
41 #include "nsCSSKeywords.h"
42 #include "nsStyleCoord.h"
43 #include "nsDisplayList.h"
44 #include "nsDOMCSSDeclaration.h"
45 #include "nsStyleTransformMatrix.h"
46 #include "mozilla/dom/Element.h"
48 #include "nsWrapperCacheInlines.h"
49 #include "mozilla/AppUnits.h"
52 using namespace mozilla
;
53 using namespace mozilla::dom
;
54 typedef const nsStyleBackground::Position Position
;
55 typedef const nsStyleBackground::Position::PositionCoord PositionCoord
;
57 #if defined(DEBUG_bzbarsky) || defined(DEBUG_caillon)
58 #define DEBUG_ComputedDOMStyle
62 * This is the implementation of the readonly CSSStyleDeclaration that is
63 * returned by the getComputedStyle() function.
66 already_AddRefed
<nsComputedDOMStyle
>
67 NS_NewComputedDOMStyle(dom::Element
* aElement
, const nsAString
& aPseudoElt
,
68 nsIPresShell
* aPresShell
,
69 nsComputedDOMStyle::StyleType aStyleType
)
71 nsRefPtr
<nsComputedDOMStyle
> computedStyle
;
72 computedStyle
= new nsComputedDOMStyle(aElement
, aPseudoElt
, aPresShell
,
74 return computedStyle
.forget();
78 * An object that represents the ordered set of properties that are exposed on
79 * an nsComputedDOMStyle object and how their computed values can be obtained.
81 struct nsComputedStyleMap
83 friend class nsComputedDOMStyle
;
87 // Create a pointer-to-member-function type.
88 typedef mozilla::dom::CSSValue
* (nsComputedDOMStyle::*ComputeMethod
)();
90 nsCSSProperty mProperty
;
91 ComputeMethod mGetter
;
93 bool IsLayoutFlushNeeded() const
95 return nsCSSProps::PropHasFlags(mProperty
,
96 CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH
);
99 bool IsEnabled() const
101 return nsCSSProps::IsEnabled(mProperty
);
105 // We define this enum just to count the total number of properties that can
106 // be exposed on an nsComputedDOMStyle, including properties that may be
109 #define COMPUTED_STYLE_PROP(prop_, method_) \
110 eComputedStyleProperty_##prop_,
111 #include "nsComputedDOMStylePropertyList.h"
112 #undef COMPUTED_STYLE_PROP
113 eComputedStyleProperty_COUNT
117 * Returns the number of properties that should be exposed on an
118 * nsComputedDOMStyle, ecxluding any disabled properties.
123 return mExposedPropertyCount
;
127 * Returns the property at the given index in the list of properties
128 * that should be exposed on an nsComputedDOMStyle, excluding any
129 * disabled properties.
131 nsCSSProperty
PropertyAt(uint32_t aIndex
)
134 return kEntries
[EntryIndex(aIndex
)].mProperty
;
138 * Searches for and returns the computed style map entry for the given
139 * property, or nullptr if the property is not exposed on nsComputedDOMStyle
140 * or is currently disabled.
142 const Entry
* FindEntryForProperty(nsCSSProperty aPropID
)
145 for (uint32_t i
= 0; i
< mExposedPropertyCount
; i
++) {
146 const Entry
* entry
= &kEntries
[EntryIndex(i
)];
147 if (entry
->mProperty
== aPropID
) {
155 * Records that mIndexMap needs updating, due to prefs changing that could
156 * affect the set of properties exposed on an nsComputedDOMStyle.
158 void MarkDirty() { mExposedPropertyCount
= 0; }
160 // The member variables are public so that we can use an initializer in
161 // nsComputedDOMStyle::GetComputedStyleMap. Use the member functions
162 // above to get information from this object.
165 * An entry for each property that can be exposed on an nsComputedDOMStyle.
167 const Entry kEntries
[eComputedStyleProperty_COUNT
];
170 * The number of properties that should be exposed on an nsComputedDOMStyle.
171 * This will be less than eComputedStyleProperty_COUNT if some property
172 * prefs are disabled. A value of 0 indicates that it and mIndexMap are out
175 uint32_t mExposedPropertyCount
;
178 * A map of indexes on the nsComputedDOMStyle object to indexes into kEntries.
180 uint32_t mIndexMap
[eComputedStyleProperty_COUNT
];
184 * Returns whether mExposedPropertyCount and mIndexMap are out of date.
186 bool IsDirty() { return mExposedPropertyCount
== 0; }
189 * Updates mExposedPropertyCount and mIndexMap to take into account properties
190 * whose prefs are currently disabled.
195 * Maps an nsComputedDOMStyle indexed getter index to an index into kEntries.
197 uint32_t EntryIndex(uint32_t aIndex
) const
199 MOZ_ASSERT(aIndex
< mExposedPropertyCount
);
200 return mIndexMap
[aIndex
];
205 nsComputedStyleMap::Update()
212 for (uint32_t i
= 0; i
< eComputedStyleProperty_COUNT
; i
++) {
213 if (kEntries
[i
].IsEnabled()) {
214 mIndexMap
[index
++] = i
;
217 mExposedPropertyCount
= index
;
220 nsComputedDOMStyle::nsComputedDOMStyle(dom::Element
* aElement
,
221 const nsAString
& aPseudoElt
,
222 nsIPresShell
* aPresShell
,
223 StyleType aStyleType
)
224 : mDocumentWeak(nullptr), mOuterFrame(nullptr),
225 mInnerFrame(nullptr), mPresShell(nullptr),
226 mStyleType(aStyleType
),
227 mExposeVisitedStyle(false)
229 MOZ_ASSERT(aElement
&& aPresShell
);
231 mDocumentWeak
= do_GetWeakReference(aPresShell
->GetDocument());
235 if (!DOMStringIsNull(aPseudoElt
) && !aPseudoElt
.IsEmpty() &&
236 aPseudoElt
.First() == char16_t(':')) {
237 // deal with two-colon forms of aPseudoElt
238 nsAString::const_iterator start
, end
;
239 aPseudoElt
.BeginReading(start
);
240 aPseudoElt
.EndReading(end
);
241 NS_ASSERTION(start
!= end
, "aPseudoElt is not empty!");
243 bool haveTwoColons
= true;
244 if (start
== end
|| *start
!= char16_t(':')) {
246 haveTwoColons
= false;
248 mPseudo
= do_GetAtom(Substring(start
, end
));
251 // There aren't any non-CSS2 pseudo-elements with a single ':'
252 if (!haveTwoColons
&&
253 (!nsCSSPseudoElements::IsPseudoElement(mPseudo
) ||
254 !nsCSSPseudoElements::IsCSS2PseudoElement(mPseudo
))) {
255 // XXXbz I'd really rather we threw an exception or something, but
256 // the DOM spec sucks.
261 MOZ_ASSERT(aPresShell
->GetPresContext());
265 nsComputedDOMStyle::~nsComputedDOMStyle()
269 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsComputedDOMStyle
, mContent
)
271 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsComputedDOMStyle
)
272 return tmp
->IsBlack();
273 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
275 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsComputedDOMStyle
)
276 return tmp
->IsBlack();
277 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
279 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsComputedDOMStyle
)
280 return tmp
->IsBlack();
281 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
283 // QueryInterface implementation for nsComputedDOMStyle
284 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsComputedDOMStyle
)
285 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
286 NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration
)
289 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsComputedDOMStyle
)
290 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsComputedDOMStyle
)
293 nsComputedDOMStyle::GetPropertyValue(const nsCSSProperty aPropID
,
296 // This is mostly to avoid code duplication with GetPropertyCSSValue(); if
297 // perf ever becomes an issue here (doubtful), we can look into changing
299 return GetPropertyValue(
300 NS_ConvertASCIItoUTF16(nsCSSProps::GetStringValue(aPropID
)),
305 nsComputedDOMStyle::SetPropertyValue(const nsCSSProperty aPropID
,
306 const nsAString
& aValue
)
308 return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR
;
313 nsComputedDOMStyle::GetCssText(nsAString
& aCssText
)
322 nsComputedDOMStyle::SetCssText(const nsAString
& aCssText
)
324 return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR
;
329 nsComputedDOMStyle::GetLength(uint32_t* aLength
)
331 NS_PRECONDITION(aLength
, "Null aLength! Prepare to die!");
333 uint32_t length
= GetComputedStyleMap()->Length();
335 // Make sure we have up to date style so that we can include custom
337 UpdateCurrentStyleSources(false);
338 if (mStyleContextHolder
) {
339 length
+= StyleVariables()->mVariables
.Count();
344 ClearCurrentStyleSources();
351 nsComputedDOMStyle::GetParentRule(nsIDOMCSSRule
** aParentRule
)
353 *aParentRule
= nullptr;
360 nsComputedDOMStyle::GetPropertyValue(const nsAString
& aPropertyName
,
366 nsRefPtr
<CSSValue
> val
= GetPropertyCSSValue(aPropertyName
, error
);
367 if (error
.Failed()) {
368 return error
.ErrorCode();
373 val
->GetCssText(text
, error
);
374 aReturn
.Assign(text
);
375 return error
.ErrorCode();
382 nsComputedDOMStyle::GetAuthoredPropertyValue(const nsAString
& aPropertyName
,
385 // Authored style doesn't make sense to return from computed DOM style,
386 // so just return whatever GetPropertyValue() returns.
387 return GetPropertyValue(aPropertyName
, aReturn
);
391 already_AddRefed
<nsStyleContext
>
392 nsComputedDOMStyle::GetStyleContextForElement(Element
* aElement
,
394 nsIPresShell
* aPresShell
,
395 StyleType aStyleType
)
397 // If the content has a pres shell, we must use it. Otherwise we'd
398 // potentially mix rule trees by using the wrong pres shell's style
399 // set. Using the pres shell from the content also means that any
400 // content that's actually *in* a document will get the style from the
402 nsCOMPtr
<nsIPresShell
> presShell
= GetPresShellForContent(aElement
);
404 presShell
= aPresShell
;
409 presShell
->FlushPendingNotifications(Flush_Style
);
411 return GetStyleContextForElementNoFlush(aElement
, aPseudo
, presShell
,
416 already_AddRefed
<nsStyleContext
>
417 nsComputedDOMStyle::GetStyleContextForElementNoFlush(Element
* aElement
,
419 nsIPresShell
* aPresShell
,
420 StyleType aStyleType
)
422 NS_ABORT_IF_FALSE(aElement
, "NULL element");
423 // If the content has a pres shell, we must use it. Otherwise we'd
424 // potentially mix rule trees by using the wrong pres shell's style
425 // set. Using the pres shell from the content also means that any
426 // content that's actually *in* a document will get the style from the
428 nsIPresShell
*presShell
= GetPresShellForContent(aElement
);
430 presShell
= aPresShell
;
435 if (!aPseudo
&& aStyleType
== eAll
) {
436 nsIFrame
* frame
= nsLayoutUtils::GetStyleFrame(aElement
);
438 nsStyleContext
* result
= frame
->StyleContext();
439 // Don't use the style context if it was influenced by
440 // pseudo-elements, since then it's not the primary style
442 if (!result
->HasPseudoElementData()) {
443 // this function returns an addrefed style context
444 nsRefPtr
<nsStyleContext
> ret
= result
;
450 // No frame has been created, or we have a pseudo, or we're looking
451 // for the default style, so resolve the style ourselves.
452 nsRefPtr
<nsStyleContext
> parentContext
;
453 nsIContent
* parent
= aPseudo
? aElement
: aElement
->GetParent();
454 // Don't resolve parent context for document fragments.
455 if (parent
&& parent
->IsElement())
456 parentContext
= GetStyleContextForElementNoFlush(parent
->AsElement(),
460 nsPresContext
*presContext
= presShell
->GetPresContext();
464 nsStyleSet
*styleSet
= presShell
->StyleSet();
466 nsRefPtr
<nsStyleContext
> sc
;
468 nsCSSPseudoElements::Type type
= nsCSSPseudoElements::GetPseudoType(aPseudo
);
469 if (type
>= nsCSSPseudoElements::ePseudo_PseudoElementCount
) {
472 nsIFrame
* frame
= nsLayoutUtils::GetStyleFrame(aElement
);
473 Element
* pseudoElement
= frame
? frame
->GetPseudoElement(type
) : nullptr;
474 sc
= styleSet
->ResolvePseudoElementStyle(aElement
, type
, parentContext
,
477 sc
= styleSet
->ResolveStyleFor(aElement
, parentContext
);
480 if (aStyleType
== eDefaultOnly
) {
481 // We really only want the user and UA rules. Filter out the other ones.
482 nsTArray
< nsCOMPtr
<nsIStyleRule
> > rules
;
483 for (nsRuleNode
* ruleNode
= sc
->RuleNode();
485 ruleNode
= ruleNode
->GetParent()) {
486 if (ruleNode
->GetLevel() == nsStyleSet::eAgentSheet
||
487 ruleNode
->GetLevel() == nsStyleSet::eUserSheet
) {
488 rules
.AppendElement(ruleNode
->GetRule());
492 // We want to build a list of user/ua rules that is in order from least to
493 // most important, so we have to reverse the list.
494 // Integer division to get "stop" is purposeful here: if length is odd, we
495 // don't have to do anything with the middle element of the array.
496 for (uint32_t i
= 0, length
= rules
.Length(), stop
= length
/ 2;
498 rules
[i
].swap(rules
[length
- i
- 1]);
501 sc
= styleSet
->ResolveStyleForRules(parentContext
, rules
);
508 nsComputedDOMStyle::GetAdjustedValuesForBoxSizing()
510 // We want the width/height of whatever parts 'width' or 'height' controls,
511 // which can be different depending on the value of the 'box-sizing' property.
512 const nsStylePosition
* stylePos
= StylePosition();
515 switch(stylePos
->mBoxSizing
) {
516 case NS_STYLE_BOX_SIZING_BORDER
:
517 adjustment
+= mInnerFrame
->GetUsedBorder();
520 case NS_STYLE_BOX_SIZING_PADDING
:
521 adjustment
+= mInnerFrame
->GetUsedPadding();
529 nsComputedDOMStyle::GetPresShellForContent(nsIContent
* aContent
)
531 nsIDocument
* composedDoc
= aContent
->GetComposedDoc();
535 return composedDoc
->GetShell();
538 // nsDOMCSSDeclaration abstract methods which should never be called
539 // on a nsComputedDOMStyle object, but must be defined to avoid
542 nsComputedDOMStyle::GetCSSDeclaration(bool)
544 NS_RUNTIMEABORT("called nsComputedDOMStyle::GetCSSDeclaration");
549 nsComputedDOMStyle::SetCSSDeclaration(css::Declaration
*)
551 NS_RUNTIMEABORT("called nsComputedDOMStyle::SetCSSDeclaration");
552 return NS_ERROR_FAILURE
;
556 nsComputedDOMStyle::DocToUpdate()
558 NS_RUNTIMEABORT("called nsComputedDOMStyle::DocToUpdate");
563 nsComputedDOMStyle::GetCSSParsingEnvironment(CSSParsingEnvironment
& aCSSParseEnv
)
565 NS_RUNTIMEABORT("called nsComputedDOMStyle::GetCSSParsingEnvironment");
566 // Just in case NS_RUNTIMEABORT ever stops killing us for some reason
567 aCSSParseEnv
.mPrincipal
= nullptr;
571 nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush
)
573 MOZ_ASSERT(!mStyleContextHolder
);
575 nsCOMPtr
<nsIDocument
> document
= do_QueryReferent(mDocumentWeak
);
580 document
->FlushPendingLinkUpdates();
582 // Flush _before_ getting the presshell, since that could create a new
583 // presshell. Also note that we want to flush the style on the document
584 // we're computing style in, not on the document mContent is in -- the two
586 document
->FlushPendingNotifications(
587 aNeedsLayoutFlush
? Flush_Layout
: Flush_Style
);
589 mFlushedPendingReflows
= aNeedsLayoutFlush
;
592 mPresShell
= document
->GetShell();
593 if (!mPresShell
|| !mPresShell
->GetPresContext()) {
597 if (!mPseudo
&& mStyleType
== eAll
) {
598 mOuterFrame
= mContent
->GetPrimaryFrame();
599 mInnerFrame
= mOuterFrame
;
601 nsIAtom
* type
= mOuterFrame
->GetType();
602 if (type
== nsGkAtoms::tableOuterFrame
) {
603 // If the frame is an outer table frame then we should get the style
604 // from the inner table frame.
605 mInnerFrame
= mOuterFrame
->GetFirstPrincipalChild();
606 NS_ASSERTION(mInnerFrame
, "Outer table must have an inner");
607 NS_ASSERTION(!mInnerFrame
->GetNextSibling(),
608 "Outer table frames should have just one child, "
612 mStyleContextHolder
= mInnerFrame
->StyleContext();
613 NS_ASSERTION(mStyleContextHolder
, "Frame without style context?");
617 if (!mStyleContextHolder
|| mStyleContextHolder
->HasPseudoElementData()) {
619 if (mStyleContextHolder
) {
620 // We want to check that going through this path because of
621 // HasPseudoElementData is rare, because it slows us down a good
622 // bit. So check that we're really inside something associated
623 // with a pseudo-element that contains elements.
624 nsStyleContext
*topWithPseudoElementData
= mStyleContextHolder
;
625 while (topWithPseudoElementData
->GetParent()->HasPseudoElementData()) {
626 topWithPseudoElementData
= topWithPseudoElementData
->GetParent();
628 nsCSSPseudoElements::Type pseudo
=
629 topWithPseudoElementData
->GetPseudoType();
630 nsIAtom
* pseudoAtom
= nsCSSPseudoElements::GetPseudoAtom(pseudo
);
631 nsAutoString
assertMsg(
632 NS_LITERAL_STRING("we should be in a pseudo-element that is expected to contain elements ("));
633 assertMsg
.Append(nsDependentString(pseudoAtom
->GetUTF16String()));
634 assertMsg
.Append(')');
635 NS_ASSERTION(nsCSSPseudoElements::PseudoElementContainsElements(pseudo
),
636 NS_LossyConvertUTF16toASCII(assertMsg
).get());
639 // Need to resolve a style context
640 mStyleContextHolder
=
641 nsComputedDOMStyle::GetStyleContextForElement(mContent
->AsElement(),
645 if (!mStyleContextHolder
) {
649 NS_ASSERTION(mPseudo
|| !mStyleContextHolder
->HasPseudoElementData(),
650 "should not have pseudo-element data");
653 // mExposeVisitedStyle is set to true only by testing APIs that
654 // require chrome privilege.
655 NS_ABORT_IF_FALSE(!mExposeVisitedStyle
||
656 nsContentUtils::IsCallerChrome(),
657 "mExposeVisitedStyle set incorrectly");
658 if (mExposeVisitedStyle
&& mStyleContextHolder
->RelevantLinkVisited()) {
659 nsStyleContext
*styleIfVisited
= mStyleContextHolder
->GetStyleIfVisited();
660 if (styleIfVisited
) {
661 mStyleContextHolder
= styleIfVisited
;
667 nsComputedDOMStyle::ClearCurrentStyleSources()
669 mOuterFrame
= nullptr;
670 mInnerFrame
= nullptr;
671 mPresShell
= nullptr;
673 // Release the current style context for it should be re-resolved
674 // whenever a frame is not available.
675 mStyleContextHolder
= nullptr;
678 already_AddRefed
<CSSValue
>
679 nsComputedDOMStyle::GetPropertyCSSValue(const nsAString
& aPropertyName
, ErrorResult
& aRv
)
681 nsCSSProperty prop
= nsCSSProps::LookupProperty(aPropertyName
,
682 nsCSSProps::eEnabledForAllContent
);
684 bool needsLayoutFlush
;
685 nsComputedStyleMap::Entry::ComputeMethod getter
;
687 if (prop
== eCSSPropertyExtra_variable
) {
688 needsLayoutFlush
= false;
691 // We don't (for now, anyway, though it may make sense to change it
692 // for all aliases, including those in nsCSSPropAliasList) want
693 // aliases to be enumerable (via GetLength and IndexedGetter), so
694 // handle them here rather than adding entries to
695 // GetQueryablePropertyMap.
696 if (prop
!= eCSSProperty_UNKNOWN
&&
697 nsCSSProps::PropHasFlags(prop
, CSS_PROPERTY_IS_ALIAS
)) {
698 const nsCSSProperty
* subprops
= nsCSSProps::SubpropertyEntryFor(prop
);
699 NS_ABORT_IF_FALSE(subprops
[1] == eCSSProperty_UNKNOWN
,
700 "must have list of length 1");
704 const nsComputedStyleMap::Entry
* propEntry
=
705 GetComputedStyleMap()->FindEntryForProperty(prop
);
708 #ifdef DEBUG_ComputedDOMStyle
709 NS_WARNING(PromiseFlatCString(NS_ConvertUTF16toUTF8(aPropertyName
) +
710 NS_LITERAL_CSTRING(" is not queryable!")).get());
713 // NOTE: For branches, we should flush here for compatibility!
717 needsLayoutFlush
= propEntry
->IsLayoutFlushNeeded();
718 getter
= propEntry
->mGetter
;
721 UpdateCurrentStyleSources(needsLayoutFlush
);
722 if (!mStyleContextHolder
) {
723 aRv
.Throw(NS_ERROR_NOT_AVAILABLE
);
727 nsRefPtr
<CSSValue
> val
;
728 if (prop
== eCSSPropertyExtra_variable
) {
729 val
= DoGetCustomProperty(aPropertyName
);
731 // Call our pointer-to-member-function.
732 val
= (this->*getter
)();
735 ClearCurrentStyleSources();
742 nsComputedDOMStyle::RemoveProperty(const nsAString
& aPropertyName
,
745 return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR
;
750 nsComputedDOMStyle::GetPropertyPriority(const nsAString
& aPropertyName
,
760 nsComputedDOMStyle::SetProperty(const nsAString
& aPropertyName
,
761 const nsAString
& aValue
,
762 const nsAString
& aPriority
)
764 return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR
;
769 nsComputedDOMStyle::Item(uint32_t aIndex
, nsAString
& aReturn
)
771 return nsDOMCSSDeclaration::Item(aIndex
, aReturn
);
775 nsComputedDOMStyle::IndexedGetter(uint32_t aIndex
, bool& aFound
,
776 nsAString
& aPropName
)
778 nsComputedStyleMap
* map
= GetComputedStyleMap();
779 uint32_t length
= map
->Length();
781 if (aIndex
< length
) {
783 CopyASCIItoUTF16(nsCSSProps::GetStringValue(map
->PropertyAt(aIndex
)),
788 // Custom properties are exposed with indexed properties just after all
789 // of the built-in properties.
790 UpdateCurrentStyleSources(false);
791 if (!mStyleContextHolder
) {
796 const nsStyleVariables
* variables
= StyleVariables();
797 if (aIndex
- length
< variables
->mVariables
.Count()) {
800 variables
->mVariables
.GetVariableAt(aIndex
- length
, varName
);
801 aPropName
.AssignLiteral("--");
802 aPropName
.Append(varName
);
807 ClearCurrentStyleSources();
810 // Property getters...
813 nsComputedDOMStyle::DoGetBinding()
815 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
817 const nsStyleDisplay
* display
= StyleDisplay();
819 if (display
->mBinding
) {
820 val
->SetURI(display
->mBinding
->GetURI());
822 val
->SetIdent(eCSSKeyword_none
);
829 nsComputedDOMStyle::DoGetClear()
831 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
832 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mBreakType
,
833 nsCSSProps::kClearKTable
));
838 nsComputedDOMStyle::DoGetFloat()
840 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
841 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mFloats
,
842 nsCSSProps::kFloatKTable
));
847 nsComputedDOMStyle::DoGetBottom()
849 return GetOffsetWidthFor(NS_SIDE_BOTTOM
);
853 nsComputedDOMStyle::DoGetStackSizing()
855 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
856 val
->SetIdent(StyleXUL()->mStretchStack
? eCSSKeyword_stretch_to_fit
:
862 nsComputedDOMStyle::SetToRGBAColor(nsROCSSPrimitiveValue
* aValue
,
865 if (NS_GET_A(aColor
) == 0) {
866 aValue
->SetIdent(eCSSKeyword_transparent
);
870 nsROCSSPrimitiveValue
*red
= new nsROCSSPrimitiveValue
;
871 nsROCSSPrimitiveValue
*green
= new nsROCSSPrimitiveValue
;
872 nsROCSSPrimitiveValue
*blue
= new nsROCSSPrimitiveValue
;
873 nsROCSSPrimitiveValue
*alpha
= new nsROCSSPrimitiveValue
;
875 uint8_t a
= NS_GET_A(aColor
);
876 nsDOMCSSRGBColor
*rgbColor
=
877 new nsDOMCSSRGBColor(red
, green
, blue
, alpha
, a
< 255);
879 red
->SetNumber(NS_GET_R(aColor
));
880 green
->SetNumber(NS_GET_G(aColor
));
881 blue
->SetNumber(NS_GET_B(aColor
));
882 alpha
->SetNumber(nsStyleUtil::ColorComponentToFloat(a
));
884 aValue
->SetColor(rgbColor
);
888 nsComputedDOMStyle::DoGetColor()
890 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
891 SetToRGBAColor(val
, StyleColor()->mColor
);
896 nsComputedDOMStyle::DoGetOpacity()
898 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
899 val
->SetNumber(StyleDisplay()->mOpacity
);
904 nsComputedDOMStyle::DoGetColumnCount()
906 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
908 const nsStyleColumn
* column
= StyleColumn();
910 if (column
->mColumnCount
== NS_STYLE_COLUMN_COUNT_AUTO
) {
911 val
->SetIdent(eCSSKeyword_auto
);
913 val
->SetNumber(column
->mColumnCount
);
920 nsComputedDOMStyle::DoGetColumnWidth()
922 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
924 // XXX fix the auto case. When we actually have a column frame, I think
925 // we should return the computed column width.
926 SetValueToCoord(val
, StyleColumn()->mColumnWidth
, true);
931 nsComputedDOMStyle::DoGetColumnGap()
933 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
935 const nsStyleColumn
* column
= StyleColumn();
936 if (column
->mColumnGap
.GetUnit() == eStyleUnit_Normal
) {
937 val
->SetAppUnits(StyleFont()->mFont
.size
);
939 SetValueToCoord(val
, StyleColumn()->mColumnGap
, true);
946 nsComputedDOMStyle::DoGetColumnFill()
948 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
950 nsCSSProps::ValueToKeywordEnum(StyleColumn()->mColumnFill
,
951 nsCSSProps::kColumnFillKTable
));
956 nsComputedDOMStyle::DoGetColumnRuleWidth()
958 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
959 val
->SetAppUnits(StyleColumn()->GetComputedColumnRuleWidth());
964 nsComputedDOMStyle::DoGetColumnRuleStyle()
966 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
968 nsCSSProps::ValueToKeywordEnum(StyleColumn()->mColumnRuleStyle
,
969 nsCSSProps::kBorderStyleKTable
));
974 nsComputedDOMStyle::DoGetColumnRuleColor()
976 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
978 const nsStyleColumn
* column
= StyleColumn();
980 if (column
->mColumnRuleColorIsForeground
) {
981 ruleColor
= StyleColor()->mColor
;
983 ruleColor
= column
->mColumnRuleColor
;
986 SetToRGBAColor(val
, ruleColor
);
991 nsComputedDOMStyle::DoGetContent()
993 const nsStyleContent
*content
= StyleContent();
995 if (content
->ContentCount() == 0) {
996 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
997 val
->SetIdent(eCSSKeyword_none
);
1001 if (content
->ContentCount() == 1 &&
1002 content
->ContentAt(0).mType
== eStyleContentType_AltContent
) {
1003 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
1004 val
->SetIdent(eCSSKeyword__moz_alt_content
);
1008 nsDOMCSSValueList
*valueList
= GetROCSSValueList(false);
1010 for (uint32_t i
= 0, i_end
= content
->ContentCount(); i
< i_end
; ++i
) {
1011 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1012 valueList
->AppendCSSValue(val
);
1014 const nsStyleContentData
&data
= content
->ContentAt(i
);
1015 switch (data
.mType
) {
1016 case eStyleContentType_String
:
1019 nsStyleUtil::AppendEscapedCSSString(
1020 nsDependentString(data
.mContent
.mString
), str
);
1021 val
->SetString(str
);
1024 case eStyleContentType_Image
:
1026 nsCOMPtr
<nsIURI
> uri
;
1027 if (data
.mContent
.mImage
) {
1028 data
.mContent
.mImage
->GetURI(getter_AddRefs(uri
));
1033 case eStyleContentType_Attr
:
1036 nsStyleUtil::AppendEscapedCSSIdent(
1037 nsDependentString(data
.mContent
.mString
), str
);
1038 val
->SetString(str
, nsIDOMCSSPrimitiveValue::CSS_ATTR
);
1041 case eStyleContentType_Counter
:
1042 case eStyleContentType_Counters
:
1044 /* FIXME: counters should really use an object */
1046 if (data
.mType
== eStyleContentType_Counter
) {
1047 str
.AppendLiteral("counter(");
1050 str
.AppendLiteral("counters(");
1053 nsCSSValue::Array
*a
= data
.mContent
.mCounters
;
1055 nsStyleUtil::AppendEscapedCSSIdent(
1056 nsDependentString(a
->Item(0).GetStringBufferValue()), str
);
1057 int32_t typeItem
= 1;
1058 if (data
.mType
== eStyleContentType_Counters
) {
1060 str
.AppendLiteral(", ");
1061 nsStyleUtil::AppendEscapedCSSString(
1062 nsDependentString(a
->Item(1).GetStringBufferValue()), str
);
1064 NS_ABORT_IF_FALSE(eCSSUnit_None
!= a
->Item(typeItem
).GetUnit(),
1065 "'none' should be handled as identifier value");
1067 a
->Item(typeItem
).AppendToString(eCSSProperty_list_style_type
,
1068 type
, nsCSSValue::eNormalized
);
1069 if (!type
.LowerCaseEqualsLiteral("decimal")) {
1070 str
.AppendLiteral(", ");
1074 str
.Append(char16_t(')'));
1075 val
->SetString(str
, nsIDOMCSSPrimitiveValue::CSS_COUNTER
);
1078 case eStyleContentType_OpenQuote
:
1079 val
->SetIdent(eCSSKeyword_open_quote
);
1081 case eStyleContentType_CloseQuote
:
1082 val
->SetIdent(eCSSKeyword_close_quote
);
1084 case eStyleContentType_NoOpenQuote
:
1085 val
->SetIdent(eCSSKeyword_no_open_quote
);
1087 case eStyleContentType_NoCloseQuote
:
1088 val
->SetIdent(eCSSKeyword_no_close_quote
);
1090 case eStyleContentType_AltContent
:
1092 NS_NOTREACHED("unexpected type");
1101 nsComputedDOMStyle::DoGetCounterIncrement()
1103 const nsStyleContent
*content
= StyleContent();
1105 if (content
->CounterIncrementCount() == 0) {
1106 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
1107 val
->SetIdent(eCSSKeyword_none
);
1111 nsDOMCSSValueList
*valueList
= GetROCSSValueList(false);
1113 for (uint32_t i
= 0, i_end
= content
->CounterIncrementCount(); i
< i_end
; ++i
) {
1114 nsROCSSPrimitiveValue
* name
= new nsROCSSPrimitiveValue
;
1115 valueList
->AppendCSSValue(name
);
1117 nsROCSSPrimitiveValue
* value
= new nsROCSSPrimitiveValue
;
1118 valueList
->AppendCSSValue(value
);
1120 const nsStyleCounterData
*data
= content
->GetCounterIncrementAt(i
);
1121 nsAutoString escaped
;
1122 nsStyleUtil::AppendEscapedCSSIdent(data
->mCounter
, escaped
);
1123 name
->SetString(escaped
);
1124 value
->SetNumber(data
->mValue
); // XXX This should really be integer
1130 /* Convert the stored representation into a list of two values and then hand
1134 nsComputedDOMStyle::DoGetTransformOrigin()
1136 /* We need to build up a list of two values. We'll call them
1140 /* Store things as a value list */
1141 nsDOMCSSValueList
* valueList
= GetROCSSValueList(false);
1143 /* Now, get the values. */
1144 const nsStyleDisplay
* display
= StyleDisplay();
1146 nsROCSSPrimitiveValue
* width
= new nsROCSSPrimitiveValue
;
1147 SetValueToCoord(width
, display
->mTransformOrigin
[0], false,
1148 &nsComputedDOMStyle::GetFrameBoundsWidthForTransform
);
1149 valueList
->AppendCSSValue(width
);
1151 nsROCSSPrimitiveValue
* height
= new nsROCSSPrimitiveValue
;
1152 SetValueToCoord(height
, display
->mTransformOrigin
[1], false,
1153 &nsComputedDOMStyle::GetFrameBoundsHeightForTransform
);
1154 valueList
->AppendCSSValue(height
);
1156 if (display
->mTransformOrigin
[2].GetUnit() != eStyleUnit_Coord
||
1157 display
->mTransformOrigin
[2].GetCoordValue() != 0) {
1158 nsROCSSPrimitiveValue
* depth
= new nsROCSSPrimitiveValue
;
1159 SetValueToCoord(depth
, display
->mTransformOrigin
[2], false,
1161 valueList
->AppendCSSValue(depth
);
1167 /* Convert the stored representation into a list of two values and then hand
1171 nsComputedDOMStyle::DoGetPerspectiveOrigin()
1173 /* We need to build up a list of two values. We'll call them
1177 /* Store things as a value list */
1178 nsDOMCSSValueList
* valueList
= GetROCSSValueList(false);
1180 /* Now, get the values. */
1181 const nsStyleDisplay
* display
= StyleDisplay();
1183 nsROCSSPrimitiveValue
* width
= new nsROCSSPrimitiveValue
;
1184 SetValueToCoord(width
, display
->mPerspectiveOrigin
[0], false,
1185 &nsComputedDOMStyle::GetFrameBoundsWidthForTransform
);
1186 valueList
->AppendCSSValue(width
);
1188 nsROCSSPrimitiveValue
* height
= new nsROCSSPrimitiveValue
;
1189 SetValueToCoord(height
, display
->mPerspectiveOrigin
[1], false,
1190 &nsComputedDOMStyle::GetFrameBoundsHeightForTransform
);
1191 valueList
->AppendCSSValue(height
);
1197 nsComputedDOMStyle::DoGetPerspective()
1199 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1200 SetValueToCoord(val
, StyleDisplay()->mChildPerspective
, false);
1205 nsComputedDOMStyle::DoGetBackfaceVisibility()
1207 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1209 nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mBackfaceVisibility
,
1210 nsCSSProps::kBackfaceVisibilityKTable
));
1215 nsComputedDOMStyle::DoGetTransformStyle()
1217 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
1219 nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mTransformStyle
,
1220 nsCSSProps::kTransformStyleKTable
));
1224 /* If the property is "none", hand back "none" wrapped in a value.
1225 * Otherwise, compute the aggregate transform matrix and hands it back in a
1229 nsComputedDOMStyle::DoGetTransform()
1231 /* First, get the display data. We'll need it. */
1232 const nsStyleDisplay
* display
= StyleDisplay();
1234 /* If there are no transforms, then we should construct a single-element
1235 * entry and hand it back.
1237 if (!display
->mSpecifiedTransform
) {
1238 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1240 /* Set it to "none." */
1241 val
->SetIdent(eCSSKeyword_none
);
1245 /* Otherwise, we need to compute the current value of the transform matrix,
1246 * store it in a string, and hand it back to the caller.
1249 /* Use the inner frame for width and height. If we fail, assume zero.
1250 * TODO: There is no good way for us to represent the case where there's no
1251 * frame, which is problematic. The reason is that when we have percentage
1252 * transforms, there are a total of four stored matrix entries that influence
1253 * the transform based on the size of the element. However, this poses a
1254 * problem, because only two of these values can be explicitly referenced
1255 * using the named transforms. Until a real solution is found, we'll just
1256 * use this approach.
1259 (mInnerFrame
? nsDisplayTransform::GetFrameBoundsForTransform(mInnerFrame
) :
1260 nsRect(0, 0, 0, 0));
1263 gfx3DMatrix matrix
=
1264 nsStyleTransformMatrix::ReadTransforms(display
->mSpecifiedTransform
->mHead
,
1265 mStyleContextHolder
,
1266 mStyleContextHolder
->PresContext(),
1269 float(mozilla::AppUnitsPerCSSPixel()));
1271 return MatrixToCSSValue(matrix
);
1274 /* static */ nsROCSSPrimitiveValue
*
1275 nsComputedDOMStyle::MatrixToCSSValue(gfx3DMatrix
& matrix
)
1277 bool is3D
= !matrix
.Is2D();
1279 nsAutoString
resultString(NS_LITERAL_STRING("matrix"));
1281 resultString
.AppendLiteral("3d");
1284 resultString
.Append('(');
1285 resultString
.AppendFloat(matrix
._11
);
1286 resultString
.AppendLiteral(", ");
1287 resultString
.AppendFloat(matrix
._12
);
1288 resultString
.AppendLiteral(", ");
1290 resultString
.AppendFloat(matrix
._13
);
1291 resultString
.AppendLiteral(", ");
1292 resultString
.AppendFloat(matrix
._14
);
1293 resultString
.AppendLiteral(", ");
1295 resultString
.AppendFloat(matrix
._21
);
1296 resultString
.AppendLiteral(", ");
1297 resultString
.AppendFloat(matrix
._22
);
1298 resultString
.AppendLiteral(", ");
1300 resultString
.AppendFloat(matrix
._23
);
1301 resultString
.AppendLiteral(", ");
1302 resultString
.AppendFloat(matrix
._24
);
1303 resultString
.AppendLiteral(", ");
1304 resultString
.AppendFloat(matrix
._31
);
1305 resultString
.AppendLiteral(", ");
1306 resultString
.AppendFloat(matrix
._32
);
1307 resultString
.AppendLiteral(", ");
1308 resultString
.AppendFloat(matrix
._33
);
1309 resultString
.AppendLiteral(", ");
1310 resultString
.AppendFloat(matrix
._34
);
1311 resultString
.AppendLiteral(", ");
1313 resultString
.AppendFloat(matrix
._41
);
1314 resultString
.AppendLiteral(", ");
1315 resultString
.AppendFloat(matrix
._42
);
1317 resultString
.AppendLiteral(", ");
1318 resultString
.AppendFloat(matrix
._43
);
1319 resultString
.AppendLiteral(", ");
1320 resultString
.AppendFloat(matrix
._44
);
1322 resultString
.Append(')');
1324 /* Create a value to hold our result. */
1325 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1327 val
->SetString(resultString
);
1332 nsComputedDOMStyle::DoGetCounterReset()
1334 const nsStyleContent
*content
= StyleContent();
1336 if (content
->CounterResetCount() == 0) {
1337 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
1338 val
->SetIdent(eCSSKeyword_none
);
1342 nsDOMCSSValueList
*valueList
= GetROCSSValueList(false);
1344 for (uint32_t i
= 0, i_end
= content
->CounterResetCount(); i
< i_end
; ++i
) {
1345 nsROCSSPrimitiveValue
* name
= new nsROCSSPrimitiveValue
;
1346 valueList
->AppendCSSValue(name
);
1348 nsROCSSPrimitiveValue
* value
= new nsROCSSPrimitiveValue
;
1349 valueList
->AppendCSSValue(value
);
1351 const nsStyleCounterData
*data
= content
->GetCounterResetAt(i
);
1352 nsAutoString escaped
;
1353 nsStyleUtil::AppendEscapedCSSIdent(data
->mCounter
, escaped
);
1354 name
->SetString(escaped
);
1355 value
->SetNumber(data
->mValue
); // XXX This should really be integer
1362 nsComputedDOMStyle::DoGetQuotes()
1364 const nsStyleQuotes
*quotes
= StyleQuotes();
1366 if (quotes
->QuotesCount() == 0) {
1367 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
1368 val
->SetIdent(eCSSKeyword_none
);
1372 nsDOMCSSValueList
*valueList
= GetROCSSValueList(false);
1374 for (uint32_t i
= 0, i_end
= quotes
->QuotesCount(); i
< i_end
; ++i
) {
1375 nsROCSSPrimitiveValue
* openVal
= new nsROCSSPrimitiveValue
;
1376 valueList
->AppendCSSValue(openVal
);
1378 nsROCSSPrimitiveValue
* closeVal
= new nsROCSSPrimitiveValue
;
1379 valueList
->AppendCSSValue(closeVal
);
1382 nsStyleUtil::AppendEscapedCSSString(*quotes
->OpenQuoteAt(i
), s
);
1383 openVal
->SetString(s
);
1385 nsStyleUtil::AppendEscapedCSSString(*quotes
->CloseQuoteAt(i
), s
);
1386 closeVal
->SetString(s
);
1393 nsComputedDOMStyle::DoGetFontFamily()
1395 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1397 const nsStyleFont
* font
= StyleFont();
1398 nsAutoString fontlistStr
;
1399 nsStyleUtil::AppendEscapedCSSFontFamilyList(font
->mFont
.fontlist
,
1401 val
->SetString(fontlistStr
);
1406 nsComputedDOMStyle::DoGetFontSize()
1408 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1410 // Note: StyleFont()->mSize is the 'computed size';
1411 // StyleFont()->mFont.size is the 'actual size'
1412 val
->SetAppUnits(StyleFont()->mSize
);
1417 nsComputedDOMStyle::DoGetFontSizeAdjust()
1419 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
1421 const nsStyleFont
*font
= StyleFont();
1423 if (font
->mFont
.sizeAdjust
) {
1424 val
->SetNumber(font
->mFont
.sizeAdjust
);
1426 val
->SetIdent(eCSSKeyword_none
);
1433 nsComputedDOMStyle::DoGetOSXFontSmoothing()
1435 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1436 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont
.smoothing
,
1437 nsCSSProps::kFontSmoothingKTable
));
1442 nsComputedDOMStyle::DoGetFontStretch()
1444 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1446 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont
.stretch
,
1447 nsCSSProps::kFontStretchKTable
));
1453 nsComputedDOMStyle::DoGetFontStyle()
1455 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1456 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont
.style
,
1457 nsCSSProps::kFontStyleKTable
));
1462 nsComputedDOMStyle::DoGetFontWeight()
1464 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1466 const nsStyleFont
* font
= StyleFont();
1468 uint16_t weight
= font
->mFont
.weight
;
1469 NS_ASSERTION(weight
% 100 == 0, "unexpected value of font-weight");
1470 val
->SetNumber(weight
);
1476 nsComputedDOMStyle::DoGetFontFeatureSettings()
1478 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1480 const nsStyleFont
* font
= StyleFont();
1481 if (font
->mFont
.fontFeatureSettings
.IsEmpty()) {
1482 val
->SetIdent(eCSSKeyword_normal
);
1484 nsAutoString result
;
1485 nsStyleUtil::AppendFontFeatureSettings(font
->mFont
.fontFeatureSettings
,
1487 val
->SetString(result
);
1493 nsComputedDOMStyle::DoGetFontKerning()
1495 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1497 nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont
.kerning
,
1498 nsCSSProps::kFontKerningKTable
));
1503 nsComputedDOMStyle::DoGetFontLanguageOverride()
1505 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1507 const nsStyleFont
* font
= StyleFont();
1508 if (font
->mFont
.languageOverride
.IsEmpty()) {
1509 val
->SetIdent(eCSSKeyword_normal
);
1512 nsStyleUtil::AppendEscapedCSSString(font
->mFont
.languageOverride
, str
);
1513 val
->SetString(str
);
1519 nsComputedDOMStyle::DoGetFontSynthesis()
1521 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1523 int32_t intValue
= StyleFont()->mFont
.synthesis
;
1525 if (0 == intValue
) {
1526 val
->SetIdent(eCSSKeyword_none
);
1528 nsAutoString valueStr
;
1530 nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_synthesis
,
1531 intValue
, NS_FONT_SYNTHESIS_WEIGHT
,
1532 NS_FONT_SYNTHESIS_STYLE
, valueStr
);
1533 val
->SetString(valueStr
);
1539 // return a value *only* for valid longhand values from CSS 2.1, either
1540 // normal or small-caps only
1542 nsComputedDOMStyle::DoGetFontVariant()
1544 const nsFont
& f
= StyleFont()->mFont
;
1546 // if any of the other font-variant subproperties other than
1547 // font-variant-caps are not normal then can't calculate a computed value
1548 if (f
.variantAlternates
|| f
.variantEastAsian
|| f
.variantLigatures
||
1549 f
.variantNumeric
|| f
.variantPosition
) {
1553 nsCSSKeyword keyword
;
1554 switch (f
.variantCaps
) {
1556 keyword
= eCSSKeyword_normal
;
1558 case NS_FONT_VARIANT_CAPS_SMALLCAPS
:
1559 keyword
= eCSSKeyword_small_caps
;
1565 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1566 val
->SetIdent(keyword
);
1571 nsComputedDOMStyle::DoGetFontVariantAlternates()
1573 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1575 int32_t intValue
= StyleFont()->mFont
.variantAlternates
;
1577 if (0 == intValue
) {
1578 val
->SetIdent(eCSSKeyword_normal
);
1582 // first, include enumerated values
1583 nsAutoString valueStr
;
1585 nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_alternates
,
1586 intValue
& NS_FONT_VARIANT_ALTERNATES_ENUMERATED_MASK
,
1587 NS_FONT_VARIANT_ALTERNATES_HISTORICAL
,
1588 NS_FONT_VARIANT_ALTERNATES_HISTORICAL
, valueStr
);
1590 // next, include functional values if present
1591 if (intValue
& NS_FONT_VARIANT_ALTERNATES_FUNCTIONAL_MASK
) {
1592 nsStyleUtil::SerializeFunctionalAlternates(StyleFont()->mFont
.alternateValues
,
1596 val
->SetString(valueStr
);
1601 nsComputedDOMStyle::DoGetFontVariantCaps()
1603 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1605 int32_t intValue
= StyleFont()->mFont
.variantCaps
;
1607 if (0 == intValue
) {
1608 val
->SetIdent(eCSSKeyword_normal
);
1611 nsCSSProps::ValueToKeywordEnum(intValue
,
1612 nsCSSProps::kFontVariantCapsKTable
));
1619 nsComputedDOMStyle::DoGetFontVariantEastAsian()
1621 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1623 int32_t intValue
= StyleFont()->mFont
.variantEastAsian
;
1625 if (0 == intValue
) {
1626 val
->SetIdent(eCSSKeyword_normal
);
1628 nsAutoString valueStr
;
1630 nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_east_asian
,
1631 intValue
, NS_FONT_VARIANT_EAST_ASIAN_JIS78
,
1632 NS_FONT_VARIANT_EAST_ASIAN_RUBY
, valueStr
);
1633 val
->SetString(valueStr
);
1640 nsComputedDOMStyle::DoGetFontVariantLigatures()
1642 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1644 int32_t intValue
= StyleFont()->mFont
.variantLigatures
;
1646 if (0 == intValue
) {
1647 val
->SetIdent(eCSSKeyword_normal
);
1648 } else if (NS_FONT_VARIANT_LIGATURES_NONE
== intValue
) {
1649 val
->SetIdent(eCSSKeyword_none
);
1651 nsAutoString valueStr
;
1653 nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_ligatures
,
1654 intValue
, NS_FONT_VARIANT_LIGATURES_NONE
,
1655 NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL
, valueStr
);
1656 val
->SetString(valueStr
);
1663 nsComputedDOMStyle::DoGetFontVariantNumeric()
1665 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1667 int32_t intValue
= StyleFont()->mFont
.variantNumeric
;
1669 if (0 == intValue
) {
1670 val
->SetIdent(eCSSKeyword_normal
);
1672 nsAutoString valueStr
;
1674 nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_numeric
,
1675 intValue
, NS_FONT_VARIANT_NUMERIC_LINING
,
1676 NS_FONT_VARIANT_NUMERIC_ORDINAL
, valueStr
);
1677 val
->SetString(valueStr
);
1684 nsComputedDOMStyle::DoGetFontVariantPosition()
1686 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1688 int32_t intValue
= StyleFont()->mFont
.variantPosition
;
1690 if (0 == intValue
) {
1691 val
->SetIdent(eCSSKeyword_normal
);
1694 nsCSSProps::ValueToKeywordEnum(intValue
,
1695 nsCSSProps::kFontVariantPositionKTable
));
1702 nsComputedDOMStyle::GetBackgroundList(uint8_t nsStyleBackground::Layer::* aMember
,
1703 uint32_t nsStyleBackground::* aCount
,
1704 const KTableValue aTable
[])
1706 const nsStyleBackground
* bg
= StyleBackground();
1708 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
1710 for (uint32_t i
= 0, i_end
= bg
->*aCount
; i
< i_end
; ++i
) {
1711 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
1712 valueList
->AppendCSSValue(val
);
1713 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(bg
->mLayers
[i
].*aMember
,
1721 nsComputedDOMStyle::DoGetBackgroundAttachment()
1723 return GetBackgroundList(&nsStyleBackground::Layer::mAttachment
,
1724 &nsStyleBackground::mAttachmentCount
,
1725 nsCSSProps::kBackgroundAttachmentKTable
);
1729 nsComputedDOMStyle::DoGetBackgroundClip()
1731 return GetBackgroundList(&nsStyleBackground::Layer::mClip
,
1732 &nsStyleBackground::mClipCount
,
1733 nsCSSProps::kBackgroundOriginKTable
);
1737 nsComputedDOMStyle::DoGetBackgroundColor()
1739 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
1740 SetToRGBAColor(val
, StyleBackground()->mBackgroundColor
);
1746 SetValueToCalc(const nsStyleCoord::CalcValue
*aCalc
, nsROCSSPrimitiveValue
*aValue
)
1748 nsRefPtr
<nsROCSSPrimitiveValue
> val
= new nsROCSSPrimitiveValue
;
1749 nsAutoString tmp
, result
;
1751 result
.AppendLiteral("calc(");
1753 val
->SetAppUnits(aCalc
->mLength
);
1754 val
->GetCssText(tmp
);
1757 if (aCalc
->mHasPercent
) {
1758 result
.AppendLiteral(" + ");
1760 val
->SetPercent(aCalc
->mPercent
);
1761 val
->GetCssText(tmp
);
1767 aValue
->SetString(result
); // not really SetString
1771 AppendCSSGradientLength(const nsStyleCoord
& aValue
,
1772 nsROCSSPrimitiveValue
* aPrimitive
,
1775 nsAutoString tokenString
;
1776 if (aValue
.IsCalcUnit())
1777 SetValueToCalc(aValue
.GetCalcValue(), aPrimitive
);
1778 else if (aValue
.GetUnit() == eStyleUnit_Coord
)
1779 aPrimitive
->SetAppUnits(aValue
.GetCoordValue());
1781 aPrimitive
->SetPercent(aValue
.GetPercentValue());
1782 aPrimitive
->GetCssText(tokenString
);
1783 aString
.Append(tokenString
);
1787 AppendCSSGradientToBoxPosition(const nsStyleGradient
* aGradient
,
1791 float xValue
= aGradient
->mBgPosX
.GetPercentValue();
1792 float yValue
= aGradient
->mBgPosY
.GetPercentValue();
1794 if (yValue
== 1.0f
&& xValue
== 0.5f
) {
1798 NS_ASSERTION(yValue
!= 0.5f
|| xValue
!= 0.5f
, "invalid box position");
1800 aString
.AppendLiteral("to");
1802 if (yValue
== 0.0f
) {
1803 aString
.AppendLiteral(" top");
1804 } else if (yValue
== 1.0f
) {
1805 aString
.AppendLiteral(" bottom");
1806 } else if (yValue
!= 0.5f
) { // do not write "center" keyword
1807 NS_NOTREACHED("invalid box position");
1810 if (xValue
== 0.0f
) {
1811 aString
.AppendLiteral(" left");
1812 } else if (xValue
== 1.0f
) {
1813 aString
.AppendLiteral(" right");
1814 } else if (xValue
!= 0.5f
) { // do not write "center" keyword
1815 NS_NOTREACHED("invalid box position");
1822 nsComputedDOMStyle::GetCSSGradientString(const nsStyleGradient
* aGradient
,
1825 if (!aGradient
->mLegacySyntax
) {
1828 aString
.AssignLiteral("-moz-");
1830 if (aGradient
->mRepeating
) {
1831 aString
.AppendLiteral("repeating-");
1833 bool isRadial
= aGradient
->mShape
!= NS_STYLE_GRADIENT_SHAPE_LINEAR
;
1835 aString
.AppendLiteral("radial-gradient(");
1837 aString
.AppendLiteral("linear-gradient(");
1840 bool needSep
= false;
1841 nsAutoString tokenString
;
1842 nsRefPtr
<nsROCSSPrimitiveValue
> tmpVal
= new nsROCSSPrimitiveValue
;
1844 if (isRadial
&& !aGradient
->mLegacySyntax
) {
1845 if (aGradient
->mSize
!= NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE
) {
1846 if (aGradient
->mShape
== NS_STYLE_GRADIENT_SHAPE_CIRCULAR
) {
1847 aString
.AppendLiteral("circle");
1850 if (aGradient
->mSize
!= NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER
) {
1852 aString
.Append(' ');
1854 AppendASCIItoUTF16(nsCSSProps::
1855 ValueToKeyword(aGradient
->mSize
,
1856 nsCSSProps::kRadialGradientSizeKTable
),
1861 AppendCSSGradientLength(aGradient
->mRadiusX
, tmpVal
, aString
);
1862 if (aGradient
->mShape
!= NS_STYLE_GRADIENT_SHAPE_CIRCULAR
) {
1863 aString
.Append(' ');
1864 AppendCSSGradientLength(aGradient
->mRadiusY
, tmpVal
, aString
);
1869 if (aGradient
->mBgPosX
.GetUnit() != eStyleUnit_None
) {
1870 MOZ_ASSERT(aGradient
->mBgPosY
.GetUnit() != eStyleUnit_None
);
1871 if (!isRadial
&& !aGradient
->mLegacySyntax
) {
1872 AppendCSSGradientToBoxPosition(aGradient
, aString
, needSep
);
1873 } else if (aGradient
->mBgPosX
.GetUnit() != eStyleUnit_Percent
||
1874 aGradient
->mBgPosX
.GetPercentValue() != 0.5f
||
1875 aGradient
->mBgPosY
.GetUnit() != eStyleUnit_Percent
||
1876 aGradient
->mBgPosY
.GetPercentValue() != (isRadial
? 0.5f
: 1.0f
)) {
1877 if (isRadial
&& !aGradient
->mLegacySyntax
) {
1879 aString
.Append(' ');
1881 aString
.AppendLiteral("at ");
1884 AppendCSSGradientLength(aGradient
->mBgPosX
, tmpVal
, aString
);
1885 if (aGradient
->mBgPosY
.GetUnit() != eStyleUnit_None
) {
1886 aString
.Append(' ');
1887 AppendCSSGradientLength(aGradient
->mBgPosY
, tmpVal
, aString
);
1892 if (aGradient
->mAngle
.GetUnit() != eStyleUnit_None
) {
1893 MOZ_ASSERT(!isRadial
|| aGradient
->mLegacySyntax
);
1895 aString
.Append(' ');
1897 nsStyleUtil::AppendAngleValue(aGradient
->mAngle
, aString
);
1901 if (isRadial
&& aGradient
->mLegacySyntax
&&
1902 (aGradient
->mShape
== NS_STYLE_GRADIENT_SHAPE_CIRCULAR
||
1903 aGradient
->mSize
!= NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER
)) {
1904 MOZ_ASSERT(aGradient
->mSize
!= NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE
);
1906 aString
.AppendLiteral(", ");
1909 if (aGradient
->mShape
== NS_STYLE_GRADIENT_SHAPE_CIRCULAR
) {
1910 aString
.AppendLiteral("circle");
1913 if (aGradient
->mSize
!= NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER
) {
1915 aString
.Append(' ');
1917 AppendASCIItoUTF16(nsCSSProps::
1918 ValueToKeyword(aGradient
->mSize
,
1919 nsCSSProps::kRadialGradientSizeKTable
),
1927 for (uint32_t i
= 0; i
< aGradient
->mStops
.Length(); ++i
) {
1929 aString
.AppendLiteral(", ");
1932 const auto& stop
= aGradient
->mStops
[i
];
1933 if (!stop
.mIsInterpolationHint
) {
1934 SetToRGBAColor(tmpVal
, stop
.mColor
);
1935 tmpVal
->GetCssText(tokenString
);
1936 aString
.Append(tokenString
);
1939 if (stop
.mLocation
.GetUnit() != eStyleUnit_None
) {
1940 if (!stop
.mIsInterpolationHint
) {
1941 aString
.Append(' ');
1943 AppendCSSGradientLength(stop
.mLocation
, tmpVal
, aString
);
1948 aString
.Append(')');
1951 // -moz-image-rect(<uri>, <top>, <right>, <bottom>, <left>)
1953 nsComputedDOMStyle::GetImageRectString(nsIURI
* aURI
,
1954 const nsStyleSides
& aCropRect
,
1957 nsRefPtr
<nsDOMCSSValueList
> valueList
= GetROCSSValueList(true);
1960 nsROCSSPrimitiveValue
*valURI
= new nsROCSSPrimitiveValue
;
1961 valueList
->AppendCSSValue(valURI
);
1962 valURI
->SetURI(aURI
);
1964 // <top>, <right>, <bottom>, <left>
1965 NS_FOR_CSS_SIDES(side
) {
1966 nsROCSSPrimitiveValue
*valSide
= new nsROCSSPrimitiveValue
;
1967 valueList
->AppendCSSValue(valSide
);
1968 SetValueToCoord(valSide
, aCropRect
.Get(side
), false);
1971 nsAutoString argumentString
;
1972 valueList
->GetCssText(argumentString
);
1974 aString
= NS_LITERAL_STRING("-moz-image-rect(") +
1976 NS_LITERAL_STRING(")");
1980 nsComputedDOMStyle::SetValueToStyleImage(const nsStyleImage
& aStyleImage
,
1981 nsROCSSPrimitiveValue
* aValue
)
1983 switch (aStyleImage
.GetType()) {
1984 case eStyleImageType_Image
:
1986 imgIRequest
*req
= aStyleImage
.GetImageData();
1987 nsCOMPtr
<nsIURI
> uri
;
1988 req
->GetURI(getter_AddRefs(uri
));
1990 const nsStyleSides
* cropRect
= aStyleImage
.GetCropRect();
1992 nsAutoString imageRectString
;
1993 GetImageRectString(uri
, *cropRect
, imageRectString
);
1994 aValue
->SetString(imageRectString
);
1996 aValue
->SetURI(uri
);
2000 case eStyleImageType_Gradient
:
2002 nsAutoString gradientString
;
2003 GetCSSGradientString(aStyleImage
.GetGradientData(),
2005 aValue
->SetString(gradientString
);
2008 case eStyleImageType_Element
:
2010 nsAutoString elementId
;
2011 nsStyleUtil::AppendEscapedCSSIdent(
2012 nsDependentString(aStyleImage
.GetElementId()), elementId
);
2013 nsAutoString elementString
= NS_LITERAL_STRING("-moz-element(#") +
2015 NS_LITERAL_STRING(")");
2016 aValue
->SetString(elementString
);
2019 case eStyleImageType_Null
:
2020 aValue
->SetIdent(eCSSKeyword_none
);
2023 NS_NOTREACHED("unexpected image type");
2029 nsComputedDOMStyle::DoGetBackgroundImage()
2031 const nsStyleBackground
* bg
= StyleBackground();
2033 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
2035 for (uint32_t i
= 0, i_end
= bg
->mImageCount
; i
< i_end
; ++i
) {
2036 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
2037 valueList
->AppendCSSValue(val
);
2039 const nsStyleImage
& image
= bg
->mLayers
[i
].mImage
;
2040 SetValueToStyleImage(image
, val
);
2047 nsComputedDOMStyle::DoGetBackgroundBlendMode()
2049 return GetBackgroundList(&nsStyleBackground::Layer::mBlendMode
,
2050 &nsStyleBackground::mBlendModeCount
,
2051 nsCSSProps::kBlendModeKTable
);
2055 nsComputedDOMStyle::DoGetBackgroundOrigin()
2057 return GetBackgroundList(&nsStyleBackground::Layer::mOrigin
,
2058 &nsStyleBackground::mOriginCount
,
2059 nsCSSProps::kBackgroundOriginKTable
);
2063 nsComputedDOMStyle::SetValueToPositionCoord(const PositionCoord
& aCoord
,
2064 nsROCSSPrimitiveValue
* aValue
)
2066 if (!aCoord
.mHasPercent
) {
2067 NS_ABORT_IF_FALSE(aCoord
.mPercent
== 0.0f
,
2068 "Shouldn't have mPercent!");
2069 aValue
->SetAppUnits(aCoord
.mLength
);
2070 } else if (aCoord
.mLength
== 0) {
2071 aValue
->SetPercent(aCoord
.mPercent
);
2073 SetValueToCalc(&aCoord
, aValue
);
2078 nsComputedDOMStyle::SetValueToPosition(const Position
& aPosition
,
2079 nsDOMCSSValueList
* aValueList
)
2081 nsROCSSPrimitiveValue
* valX
= new nsROCSSPrimitiveValue
;
2082 aValueList
->AppendCSSValue(valX
);
2083 SetValueToPositionCoord(aPosition
.mXPosition
, valX
);
2085 nsROCSSPrimitiveValue
* valY
= new nsROCSSPrimitiveValue
;
2086 aValueList
->AppendCSSValue(valY
);
2087 SetValueToPositionCoord(aPosition
.mYPosition
, valY
);
2091 nsComputedDOMStyle::DoGetBackgroundPosition()
2093 const nsStyleBackground
* bg
= StyleBackground();
2095 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
2097 for (uint32_t i
= 0, i_end
= bg
->mPositionCount
; i
< i_end
; ++i
) {
2098 nsDOMCSSValueList
*itemList
= GetROCSSValueList(false);
2099 valueList
->AppendCSSValue(itemList
);
2101 SetValueToPosition(bg
->mLayers
[i
].mPosition
, itemList
);
2108 nsComputedDOMStyle::DoGetBackgroundRepeat()
2110 const nsStyleBackground
* bg
= StyleBackground();
2112 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
2114 for (uint32_t i
= 0, i_end
= bg
->mRepeatCount
; i
< i_end
; ++i
) {
2115 nsDOMCSSValueList
*itemList
= GetROCSSValueList(false);
2116 valueList
->AppendCSSValue(itemList
);
2118 nsROCSSPrimitiveValue
*valX
= new nsROCSSPrimitiveValue
;
2119 itemList
->AppendCSSValue(valX
);
2121 const uint8_t& xRepeat
= bg
->mLayers
[i
].mRepeat
.mXRepeat
;
2122 const uint8_t& yRepeat
= bg
->mLayers
[i
].mRepeat
.mYRepeat
;
2124 bool hasContraction
= true;
2125 unsigned contraction
;
2126 if (xRepeat
== yRepeat
) {
2127 contraction
= xRepeat
;
2128 } else if (xRepeat
== NS_STYLE_BG_REPEAT_REPEAT
&&
2129 yRepeat
== NS_STYLE_BG_REPEAT_NO_REPEAT
) {
2130 contraction
= NS_STYLE_BG_REPEAT_REPEAT_X
;
2131 } else if (xRepeat
== NS_STYLE_BG_REPEAT_NO_REPEAT
&&
2132 yRepeat
== NS_STYLE_BG_REPEAT_REPEAT
) {
2133 contraction
= NS_STYLE_BG_REPEAT_REPEAT_Y
;
2135 hasContraction
= false;
2138 if (hasContraction
) {
2139 valX
->SetIdent(nsCSSProps::ValueToKeywordEnum(contraction
,
2140 nsCSSProps::kBackgroundRepeatKTable
));
2142 nsROCSSPrimitiveValue
*valY
= new nsROCSSPrimitiveValue
;
2143 itemList
->AppendCSSValue(valY
);
2145 valX
->SetIdent(nsCSSProps::ValueToKeywordEnum(xRepeat
,
2146 nsCSSProps::kBackgroundRepeatKTable
));
2147 valY
->SetIdent(nsCSSProps::ValueToKeywordEnum(yRepeat
,
2148 nsCSSProps::kBackgroundRepeatKTable
));
2156 nsComputedDOMStyle::DoGetBackgroundSize()
2158 const nsStyleBackground
* bg
= StyleBackground();
2160 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
2162 for (uint32_t i
= 0, i_end
= bg
->mSizeCount
; i
< i_end
; ++i
) {
2163 const nsStyleBackground::Size
&size
= bg
->mLayers
[i
].mSize
;
2165 switch (size
.mWidthType
) {
2166 case nsStyleBackground::Size::eContain
:
2167 case nsStyleBackground::Size::eCover
: {
2168 NS_ABORT_IF_FALSE(size
.mWidthType
== size
.mHeightType
,
2170 nsCSSKeyword keyword
= size
.mWidthType
== nsStyleBackground::Size::eContain
2171 ? eCSSKeyword_contain
2172 : eCSSKeyword_cover
;
2173 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
2174 valueList
->AppendCSSValue(val
);
2175 val
->SetIdent(keyword
);
2179 nsDOMCSSValueList
*itemList
= GetROCSSValueList(false);
2180 valueList
->AppendCSSValue(itemList
);
2182 nsROCSSPrimitiveValue
* valX
= new nsROCSSPrimitiveValue
;
2183 itemList
->AppendCSSValue(valX
);
2184 nsROCSSPrimitiveValue
* valY
= new nsROCSSPrimitiveValue
;
2185 itemList
->AppendCSSValue(valY
);
2187 if (size
.mWidthType
== nsStyleBackground::Size::eAuto
) {
2188 valX
->SetIdent(eCSSKeyword_auto
);
2190 NS_ABORT_IF_FALSE(size
.mWidthType
==
2191 nsStyleBackground::Size::eLengthPercentage
,
2193 if (!size
.mWidth
.mHasPercent
&&
2194 // negative values must have come from calc()
2195 size
.mWidth
.mLength
>= 0) {
2196 NS_ABORT_IF_FALSE(size
.mWidth
.mPercent
== 0.0f
,
2197 "Shouldn't have mPercent");
2198 valX
->SetAppUnits(size
.mWidth
.mLength
);
2199 } else if (size
.mWidth
.mLength
== 0 &&
2200 // negative values must have come from calc()
2201 size
.mWidth
.mPercent
>= 0.0f
) {
2202 valX
->SetPercent(size
.mWidth
.mPercent
);
2204 SetValueToCalc(&size
.mWidth
, valX
);
2208 if (size
.mHeightType
== nsStyleBackground::Size::eAuto
) {
2209 valY
->SetIdent(eCSSKeyword_auto
);
2211 NS_ABORT_IF_FALSE(size
.mHeightType
==
2212 nsStyleBackground::Size::eLengthPercentage
,
2214 if (!size
.mHeight
.mHasPercent
&&
2215 // negative values must have come from calc()
2216 size
.mHeight
.mLength
>= 0) {
2217 NS_ABORT_IF_FALSE(size
.mHeight
.mPercent
== 0.0f
,
2218 "Shouldn't have mPercent");
2219 valY
->SetAppUnits(size
.mHeight
.mLength
);
2220 } else if (size
.mHeight
.mLength
== 0 &&
2221 // negative values must have come from calc()
2222 size
.mHeight
.mPercent
>= 0.0f
) {
2223 valY
->SetPercent(size
.mHeight
.mPercent
);
2225 SetValueToCalc(&size
.mHeight
, valY
);
2237 nsComputedDOMStyle::DoGetGridTemplateAreas()
2239 const css::GridTemplateAreasValue
* areas
=
2240 StylePosition()->mGridTemplateAreas
;
2242 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
2243 val
->SetIdent(eCSSKeyword_none
);
2247 MOZ_ASSERT(!areas
->mTemplates
.IsEmpty(),
2248 "Unexpected empty array in GridTemplateAreasValue");
2249 nsDOMCSSValueList
*valueList
= GetROCSSValueList(false);
2250 for (uint32_t i
= 0; i
< areas
->mTemplates
.Length(); i
++) {
2252 nsStyleUtil::AppendEscapedCSSString(areas
->mTemplates
[i
], str
);
2253 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
2254 val
->SetString(str
);
2255 valueList
->AppendCSSValue(val
);
2260 // aLineNames must not be empty
2262 nsComputedDOMStyle::GetGridLineNames(const nsTArray
<nsString
>& aLineNames
)
2264 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
2265 nsAutoString lineNamesString
;
2266 uint32_t i_end
= aLineNames
.Length();
2267 lineNamesString
.Assign('(');
2269 for (uint32_t i
= 0;;) {
2270 nsStyleUtil::AppendEscapedCSSIdent(aLineNames
[i
], lineNamesString
);
2274 lineNamesString
.Append(' ');
2277 lineNamesString
.Append(')');
2278 val
->SetString(lineNamesString
);
2283 nsComputedDOMStyle::GetGridTrackSize(const nsStyleCoord
& aMinValue
,
2284 const nsStyleCoord
& aMaxValue
)
2286 // FIXME bug 978212: for grid-template-columns and grid-template-rows
2287 // (not grid-auto-columns and grid-auto-rows), if we have frame,
2288 // every <track-size> should be resolved into 'px' here,
2289 // based on layout results.
2290 if (aMinValue
== aMaxValue
) {
2291 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
2292 SetValueToCoord(val
, aMinValue
, true,
2293 nullptr, nsCSSProps::kGridTrackBreadthKTable
);
2297 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
2298 nsAutoString argumentStr
, minmaxStr
;
2299 minmaxStr
.AppendLiteral("minmax(");
2301 SetValueToCoord(val
, aMinValue
, true,
2302 nullptr, nsCSSProps::kGridTrackBreadthKTable
);
2303 val
->GetCssText(argumentStr
);
2304 minmaxStr
.Append(argumentStr
);
2306 minmaxStr
.AppendLiteral(", ");
2308 SetValueToCoord(val
, aMaxValue
, true,
2309 nullptr, nsCSSProps::kGridTrackBreadthKTable
);
2310 val
->GetCssText(argumentStr
);
2311 minmaxStr
.Append(argumentStr
);
2313 minmaxStr
.Append(char16_t(')'));
2314 val
->SetString(minmaxStr
);
2319 nsComputedDOMStyle::GetGridTemplateColumnsRows(const nsStyleGridTemplate
& aTrackList
)
2321 if (aTrackList
.mIsSubgrid
) {
2322 NS_ASSERTION(aTrackList
.mMinTrackSizingFunctions
.IsEmpty() &&
2323 aTrackList
.mMaxTrackSizingFunctions
.IsEmpty(),
2324 "Unexpected sizing functions with subgrid");
2325 nsDOMCSSValueList
* valueList
= GetROCSSValueList(false);
2327 nsROCSSPrimitiveValue
* subgridKeyword
= new nsROCSSPrimitiveValue
;
2328 subgridKeyword
->SetIdent(eCSSKeyword_subgrid
);
2329 valueList
->AppendCSSValue(subgridKeyword
);
2331 for (uint32_t i
= 0; i
< aTrackList
.mLineNameLists
.Length(); i
++) {
2332 valueList
->AppendCSSValue(GetGridLineNames(aTrackList
.mLineNameLists
[i
]));
2337 uint32_t numSizes
= aTrackList
.mMinTrackSizingFunctions
.Length();
2338 MOZ_ASSERT(aTrackList
.mMaxTrackSizingFunctions
.Length() == numSizes
,
2339 "Different number of min and max track sizing functions");
2340 // An empty <track-list> is represented as "none" in syntax.
2341 if (numSizes
== 0) {
2342 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
2343 val
->SetIdent(eCSSKeyword_none
);
2347 nsDOMCSSValueList
* valueList
= GetROCSSValueList(false);
2348 // Delimiting N tracks requires N+1 lines:
2349 // one before each track, plus one at the very end.
2350 MOZ_ASSERT(aTrackList
.mLineNameLists
.Length() == numSizes
+ 1,
2351 "Unexpected number of line name lists");
2352 for (uint32_t i
= 0;; i
++) {
2353 const nsTArray
<nsString
>& lineNames
= aTrackList
.mLineNameLists
[i
];
2354 if (!lineNames
.IsEmpty()) {
2355 valueList
->AppendCSSValue(GetGridLineNames(lineNames
));
2357 if (i
== numSizes
) {
2360 valueList
->AppendCSSValue(GetGridTrackSize(aTrackList
.mMinTrackSizingFunctions
[i
],
2361 aTrackList
.mMaxTrackSizingFunctions
[i
]));
2368 nsComputedDOMStyle::DoGetGridAutoFlow()
2371 nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_grid_auto_flow
,
2372 StylePosition()->mGridAutoFlow
,
2373 NS_STYLE_GRID_AUTO_FLOW_ROW
,
2374 NS_STYLE_GRID_AUTO_FLOW_DENSE
,
2376 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
2377 val
->SetString(str
);
2382 nsComputedDOMStyle::DoGetGridAutoColumns()
2384 return GetGridTrackSize(StylePosition()->mGridAutoColumnsMin
,
2385 StylePosition()->mGridAutoColumnsMax
);
2389 nsComputedDOMStyle::DoGetGridAutoRows()
2391 return GetGridTrackSize(StylePosition()->mGridAutoRowsMin
,
2392 StylePosition()->mGridAutoRowsMax
);
2396 nsComputedDOMStyle::DoGetGridTemplateColumns()
2398 return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateColumns
);
2402 nsComputedDOMStyle::DoGetGridTemplateRows()
2404 return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateRows
);
2408 nsComputedDOMStyle::GetGridLine(const nsStyleGridLine
& aGridLine
)
2410 if (aGridLine
.IsAuto()) {
2411 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
2412 val
->SetIdent(eCSSKeyword_auto
);
2416 nsDOMCSSValueList
* valueList
= GetROCSSValueList(false);
2418 if (aGridLine
.mHasSpan
) {
2419 nsROCSSPrimitiveValue
* span
= new nsROCSSPrimitiveValue
;
2420 span
->SetIdent(eCSSKeyword_span
);
2421 valueList
->AppendCSSValue(span
);
2424 if (aGridLine
.mInteger
!= 0) {
2425 nsROCSSPrimitiveValue
* integer
= new nsROCSSPrimitiveValue
;
2426 integer
->SetNumber(aGridLine
.mInteger
);
2427 valueList
->AppendCSSValue(integer
);
2430 if (!aGridLine
.mLineName
.IsEmpty()) {
2431 nsROCSSPrimitiveValue
* lineName
= new nsROCSSPrimitiveValue
;
2432 nsString escapedLineName
;
2433 nsStyleUtil::AppendEscapedCSSIdent(aGridLine
.mLineName
, escapedLineName
);
2434 lineName
->SetString(escapedLineName
);
2435 valueList
->AppendCSSValue(lineName
);
2438 NS_ASSERTION(valueList
->Length() > 0,
2439 "Should have appended at least one value");
2444 nsComputedDOMStyle::DoGetGridColumnStart()
2446 return GetGridLine(StylePosition()->mGridColumnStart
);
2450 nsComputedDOMStyle::DoGetGridColumnEnd()
2452 return GetGridLine(StylePosition()->mGridColumnEnd
);
2456 nsComputedDOMStyle::DoGetGridRowStart()
2458 return GetGridLine(StylePosition()->mGridRowStart
);
2462 nsComputedDOMStyle::DoGetGridRowEnd()
2464 return GetGridLine(StylePosition()->mGridRowEnd
);
2468 nsComputedDOMStyle::DoGetPaddingTop()
2470 return GetPaddingWidthFor(NS_SIDE_TOP
);
2474 nsComputedDOMStyle::DoGetPaddingBottom()
2476 return GetPaddingWidthFor(NS_SIDE_BOTTOM
);
2480 nsComputedDOMStyle::DoGetPaddingLeft()
2482 return GetPaddingWidthFor(NS_SIDE_LEFT
);
2486 nsComputedDOMStyle::DoGetPaddingRight()
2488 return GetPaddingWidthFor(NS_SIDE_RIGHT
);
2492 nsComputedDOMStyle::DoGetBorderCollapse()
2494 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
2496 nsCSSProps::ValueToKeywordEnum(StyleTableBorder()->mBorderCollapse
,
2497 nsCSSProps::kBorderCollapseKTable
));
2502 nsComputedDOMStyle::DoGetBorderSpacing()
2504 nsDOMCSSValueList
*valueList
= GetROCSSValueList(false);
2506 nsROCSSPrimitiveValue
* xSpacing
= new nsROCSSPrimitiveValue
;
2507 valueList
->AppendCSSValue(xSpacing
);
2509 nsROCSSPrimitiveValue
* ySpacing
= new nsROCSSPrimitiveValue
;
2510 valueList
->AppendCSSValue(ySpacing
);
2512 const nsStyleTableBorder
*border
= StyleTableBorder();
2513 xSpacing
->SetAppUnits(border
->mBorderSpacingX
);
2514 ySpacing
->SetAppUnits(border
->mBorderSpacingY
);
2520 nsComputedDOMStyle::DoGetCaptionSide()
2522 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
2524 nsCSSProps::ValueToKeywordEnum(StyleTableBorder()->mCaptionSide
,
2525 nsCSSProps::kCaptionSideKTable
));
2530 nsComputedDOMStyle::DoGetEmptyCells()
2532 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
2534 nsCSSProps::ValueToKeywordEnum(StyleTableBorder()->mEmptyCells
,
2535 nsCSSProps::kEmptyCellsKTable
));
2540 nsComputedDOMStyle::DoGetTableLayout()
2542 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
2544 nsCSSProps::ValueToKeywordEnum(StyleTable()->mLayoutStrategy
,
2545 nsCSSProps::kTableLayoutKTable
));
2550 nsComputedDOMStyle::DoGetBorderTopStyle()
2552 return GetBorderStyleFor(NS_SIDE_TOP
);
2556 nsComputedDOMStyle::DoGetBorderBottomStyle()
2558 return GetBorderStyleFor(NS_SIDE_BOTTOM
);
2562 nsComputedDOMStyle::DoGetBorderLeftStyle()
2564 return GetBorderStyleFor(NS_SIDE_LEFT
);
2568 nsComputedDOMStyle::DoGetBorderRightStyle()
2570 return GetBorderStyleFor(NS_SIDE_RIGHT
);
2574 nsComputedDOMStyle::DoGetBorderBottomColors()
2576 return GetBorderColorsFor(NS_SIDE_BOTTOM
);
2580 nsComputedDOMStyle::DoGetBorderLeftColors()
2582 return GetBorderColorsFor(NS_SIDE_LEFT
);
2586 nsComputedDOMStyle::DoGetBorderRightColors()
2588 return GetBorderColorsFor(NS_SIDE_RIGHT
);
2593 nsComputedDOMStyle::DoGetBorderTopColors()
2595 return GetBorderColorsFor(NS_SIDE_TOP
);
2599 nsComputedDOMStyle::DoGetBorderBottomLeftRadius()
2601 return GetEllipseRadii(StyleBorder()->mBorderRadius
,
2602 NS_CORNER_BOTTOM_LEFT
, true);
2606 nsComputedDOMStyle::DoGetBorderBottomRightRadius()
2608 return GetEllipseRadii(StyleBorder()->mBorderRadius
,
2609 NS_CORNER_BOTTOM_RIGHT
, true);
2613 nsComputedDOMStyle::DoGetBorderTopLeftRadius()
2615 return GetEllipseRadii(StyleBorder()->mBorderRadius
,
2616 NS_CORNER_TOP_LEFT
, true);
2620 nsComputedDOMStyle::DoGetBorderTopRightRadius()
2622 return GetEllipseRadii(StyleBorder()->mBorderRadius
,
2623 NS_CORNER_TOP_RIGHT
, true);
2627 nsComputedDOMStyle::DoGetBorderTopWidth()
2629 return GetBorderWidthFor(NS_SIDE_TOP
);
2633 nsComputedDOMStyle::DoGetBorderBottomWidth()
2635 return GetBorderWidthFor(NS_SIDE_BOTTOM
);
2639 nsComputedDOMStyle::DoGetBorderLeftWidth()
2641 return GetBorderWidthFor(NS_SIDE_LEFT
);
2645 nsComputedDOMStyle::DoGetBorderRightWidth()
2647 return GetBorderWidthFor(NS_SIDE_RIGHT
);
2651 nsComputedDOMStyle::DoGetBorderTopColor()
2653 return GetBorderColorFor(NS_SIDE_TOP
);
2657 nsComputedDOMStyle::DoGetBorderBottomColor()
2659 return GetBorderColorFor(NS_SIDE_BOTTOM
);
2663 nsComputedDOMStyle::DoGetBorderLeftColor()
2665 return GetBorderColorFor(NS_SIDE_LEFT
);
2669 nsComputedDOMStyle::DoGetBorderRightColor()
2671 return GetBorderColorFor(NS_SIDE_RIGHT
);
2675 nsComputedDOMStyle::DoGetMarginTopWidth()
2677 return GetMarginWidthFor(NS_SIDE_TOP
);
2681 nsComputedDOMStyle::DoGetMarginBottomWidth()
2683 return GetMarginWidthFor(NS_SIDE_BOTTOM
);
2687 nsComputedDOMStyle::DoGetMarginLeftWidth()
2689 return GetMarginWidthFor(NS_SIDE_LEFT
);
2693 nsComputedDOMStyle::DoGetMarginRightWidth()
2695 return GetMarginWidthFor(NS_SIDE_RIGHT
);
2699 nsComputedDOMStyle::DoGetMarkerOffset()
2701 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
2702 SetValueToCoord(val
, StyleContent()->mMarkerOffset
, false);
2707 nsComputedDOMStyle::DoGetOrient()
2709 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
2711 nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mOrient
,
2712 nsCSSProps::kOrientKTable
));
2717 nsComputedDOMStyle::DoGetScrollBehavior()
2719 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
2721 nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mScrollBehavior
,
2722 nsCSSProps::kScrollBehaviorKTable
));
2727 nsComputedDOMStyle::DoGetOutlineWidth()
2729 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
2731 const nsStyleOutline
* outline
= StyleOutline();
2734 if (outline
->GetOutlineStyle() == NS_STYLE_BORDER_STYLE_NONE
) {
2735 NS_ASSERTION(outline
->GetOutlineWidth(width
) && width
== 0,
2736 "unexpected width");
2742 outline
->GetOutlineWidth(width
);
2743 NS_ASSERTION(res
, "percent outline doesn't exist");
2745 val
->SetAppUnits(width
);
2751 nsComputedDOMStyle::DoGetOutlineStyle()
2753 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
2755 nsCSSProps::ValueToKeywordEnum(StyleOutline()->GetOutlineStyle(),
2756 nsCSSProps::kOutlineStyleKTable
));
2761 nsComputedDOMStyle::DoGetOutlineOffset()
2763 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
2764 val
->SetAppUnits(StyleOutline()->mOutlineOffset
);
2769 nsComputedDOMStyle::DoGetOutlineRadiusBottomLeft()
2771 return GetEllipseRadii(StyleOutline()->mOutlineRadius
,
2772 NS_CORNER_BOTTOM_LEFT
, false);
2776 nsComputedDOMStyle::DoGetOutlineRadiusBottomRight()
2778 return GetEllipseRadii(StyleOutline()->mOutlineRadius
,
2779 NS_CORNER_BOTTOM_RIGHT
, false);
2783 nsComputedDOMStyle::DoGetOutlineRadiusTopLeft()
2785 return GetEllipseRadii(StyleOutline()->mOutlineRadius
,
2786 NS_CORNER_TOP_LEFT
, false);
2790 nsComputedDOMStyle::DoGetOutlineRadiusTopRight()
2792 return GetEllipseRadii(StyleOutline()->mOutlineRadius
,
2793 NS_CORNER_TOP_RIGHT
, false);
2797 nsComputedDOMStyle::DoGetOutlineColor()
2799 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
2802 if (!StyleOutline()->GetOutlineColor(color
))
2803 color
= StyleColor()->mColor
;
2805 SetToRGBAColor(val
, color
);
2810 nsComputedDOMStyle::GetEllipseRadii(const nsStyleCorners
& aRadius
,
2811 uint8_t aFullCorner
,
2812 bool aIsBorder
) // else outline
2814 nsStyleCoord radiusX
, radiusY
;
2815 if (mInnerFrame
&& aIsBorder
) {
2817 mInnerFrame
->GetBorderRadii(radii
);
2818 radiusX
.SetCoordValue(radii
[NS_FULL_TO_HALF_CORNER(aFullCorner
, false)]);
2819 radiusY
.SetCoordValue(radii
[NS_FULL_TO_HALF_CORNER(aFullCorner
, true)]);
2821 radiusX
= aRadius
.Get(NS_FULL_TO_HALF_CORNER(aFullCorner
, false));
2822 radiusY
= aRadius
.Get(NS_FULL_TO_HALF_CORNER(aFullCorner
, true));
2825 // We need to convert to absolute coordinates before doing the
2826 // equality check below.
2829 v
= StyleCoordToNSCoord(radiusX
,
2830 &nsComputedDOMStyle::GetFrameBorderRectWidth
,
2832 radiusX
.SetCoordValue(v
);
2834 v
= StyleCoordToNSCoord(radiusY
,
2835 &nsComputedDOMStyle::GetFrameBorderRectHeight
,
2837 radiusY
.SetCoordValue(v
);
2841 // for compatibility, return a single value if X and Y are equal
2842 if (radiusX
== radiusY
) {
2843 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
2845 SetValueToCoord(val
, radiusX
, true);
2850 nsDOMCSSValueList
*valueList
= GetROCSSValueList(false);
2852 nsROCSSPrimitiveValue
*valX
= new nsROCSSPrimitiveValue
;
2853 valueList
->AppendCSSValue(valX
);
2855 nsROCSSPrimitiveValue
*valY
= new nsROCSSPrimitiveValue
;
2856 valueList
->AppendCSSValue(valY
);
2858 SetValueToCoord(valX
, radiusX
, true);
2859 SetValueToCoord(valY
, radiusY
, true);
2865 nsComputedDOMStyle::GetCSSShadowArray(nsCSSShadowArray
* aArray
,
2866 const nscolor
& aDefaultColor
,
2870 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
2871 val
->SetIdent(eCSSKeyword_none
);
2875 static nscoord
nsCSSShadowItem::* const shadowValuesNoSpread
[] = {
2876 &nsCSSShadowItem::mXOffset
,
2877 &nsCSSShadowItem::mYOffset
,
2878 &nsCSSShadowItem::mRadius
2881 static nscoord
nsCSSShadowItem::* const shadowValuesWithSpread
[] = {
2882 &nsCSSShadowItem::mXOffset
,
2883 &nsCSSShadowItem::mYOffset
,
2884 &nsCSSShadowItem::mRadius
,
2885 &nsCSSShadowItem::mSpread
2888 nscoord
nsCSSShadowItem::* const * shadowValues
;
2889 uint32_t shadowValuesLength
;
2891 shadowValues
= shadowValuesWithSpread
;
2892 shadowValuesLength
= ArrayLength(shadowValuesWithSpread
);
2894 shadowValues
= shadowValuesNoSpread
;
2895 shadowValuesLength
= ArrayLength(shadowValuesNoSpread
);
2898 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
2900 for (nsCSSShadowItem
*item
= aArray
->ShadowAt(0),
2901 *item_end
= item
+ aArray
->Length();
2902 item
< item_end
; ++item
) {
2903 nsDOMCSSValueList
*itemList
= GetROCSSValueList(false);
2904 valueList
->AppendCSSValue(itemList
);
2906 // Color is either the specified shadow color or the foreground color
2907 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
2908 itemList
->AppendCSSValue(val
);
2909 nscolor shadowColor
;
2910 if (item
->mHasColor
) {
2911 shadowColor
= item
->mColor
;
2913 shadowColor
= aDefaultColor
;
2915 SetToRGBAColor(val
, shadowColor
);
2917 // Set the offsets, blur radius, and spread if available
2918 for (uint32_t i
= 0; i
< shadowValuesLength
; ++i
) {
2919 val
= new nsROCSSPrimitiveValue
;
2920 itemList
->AppendCSSValue(val
);
2921 val
->SetAppUnits(item
->*(shadowValues
[i
]));
2924 if (item
->mInset
&& aIsBoxShadow
) {
2925 // This is an inset box-shadow
2926 val
= new nsROCSSPrimitiveValue
;
2927 itemList
->AppendCSSValue(val
);
2929 nsCSSProps::ValueToKeywordEnum(NS_STYLE_BOX_SHADOW_INSET
,
2930 nsCSSProps::kBoxShadowTypeKTable
));
2938 nsComputedDOMStyle::DoGetBoxDecorationBreak()
2940 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
2942 nsCSSProps::ValueToKeywordEnum(StyleBorder()->mBoxDecorationBreak
,
2943 nsCSSProps::kBoxDecorationBreakKTable
));
2948 nsComputedDOMStyle::DoGetBoxShadow()
2950 return GetCSSShadowArray(StyleBorder()->mBoxShadow
,
2951 StyleColor()->mColor
,
2956 nsComputedDOMStyle::DoGetZIndex()
2958 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
2959 SetValueToCoord(val
, StylePosition()->mZIndex
, false);
2964 nsComputedDOMStyle::DoGetListStyleImage()
2966 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
2968 const nsStyleList
* list
= StyleList();
2970 if (!list
->GetListStyleImage()) {
2971 val
->SetIdent(eCSSKeyword_none
);
2973 nsCOMPtr
<nsIURI
> uri
;
2974 if (list
->GetListStyleImage()) {
2975 list
->GetListStyleImage()->GetURI(getter_AddRefs(uri
));
2984 nsComputedDOMStyle::DoGetListStylePosition()
2986 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
2988 nsCSSProps::ValueToKeywordEnum(StyleList()->mListStylePosition
,
2989 nsCSSProps::kListStylePositionKTable
));
2994 nsComputedDOMStyle::DoGetListStyleType()
2996 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
2997 CounterStyle
* style
= StyleList()->GetCounterStyle();
2998 AnonymousCounterStyle
* anonymous
= style
->AsAnonymous();
3002 StyleList()->GetListStyleType(type
);
3004 nsStyleUtil::AppendEscapedCSSIdent(type
, value
);
3005 val
->SetString(value
);
3008 tmp
.AppendLiteral("symbols(");
3010 uint8_t system
= anonymous
->GetSystem();
3011 NS_ASSERTION(system
== NS_STYLE_COUNTER_SYSTEM_CYCLIC
||
3012 system
== NS_STYLE_COUNTER_SYSTEM_NUMERIC
||
3013 system
== NS_STYLE_COUNTER_SYSTEM_ALPHABETIC
||
3014 system
== NS_STYLE_COUNTER_SYSTEM_SYMBOLIC
||
3015 system
== NS_STYLE_COUNTER_SYSTEM_FIXED
,
3016 "Invalid system for anonymous counter style.");
3017 if (system
!= NS_STYLE_COUNTER_SYSTEM_SYMBOLIC
) {
3018 AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(
3019 system
, nsCSSProps::kCounterSystemKTable
), tmp
);
3023 const nsTArray
<nsString
>& symbols
= anonymous
->GetSymbols();
3024 NS_ASSERTION(symbols
.Length() > 0,
3025 "No symbols in the anonymous counter style");
3026 for (size_t i
= 0, iend
= symbols
.Length(); i
< iend
; i
++) {
3027 nsStyleUtil::AppendEscapedCSSString(symbols
[i
], tmp
);
3030 tmp
.Replace(tmp
.Length() - 1, 1, char16_t(')'));
3031 val
->SetString(tmp
);
3037 nsComputedDOMStyle::DoGetImageRegion()
3039 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3041 const nsStyleList
* list
= StyleList();
3043 if (list
->mImageRegion
.width
<= 0 || list
->mImageRegion
.height
<= 0) {
3044 val
->SetIdent(eCSSKeyword_auto
);
3046 // create the cssvalues for the sides, stick them in the rect object
3047 nsROCSSPrimitiveValue
*topVal
= new nsROCSSPrimitiveValue
;
3048 nsROCSSPrimitiveValue
*rightVal
= new nsROCSSPrimitiveValue
;
3049 nsROCSSPrimitiveValue
*bottomVal
= new nsROCSSPrimitiveValue
;
3050 nsROCSSPrimitiveValue
*leftVal
= new nsROCSSPrimitiveValue
;
3051 nsDOMCSSRect
* domRect
= new nsDOMCSSRect(topVal
, rightVal
,
3052 bottomVal
, leftVal
);
3053 topVal
->SetAppUnits(list
->mImageRegion
.y
);
3054 rightVal
->SetAppUnits(list
->mImageRegion
.width
+ list
->mImageRegion
.x
);
3055 bottomVal
->SetAppUnits(list
->mImageRegion
.height
+ list
->mImageRegion
.y
);
3056 leftVal
->SetAppUnits(list
->mImageRegion
.x
);
3057 val
->SetRect(domRect
);
3064 nsComputedDOMStyle::DoGetLineHeight()
3066 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3069 if (GetLineHeightCoord(lineHeight
)) {
3070 val
->SetAppUnits(lineHeight
);
3072 SetValueToCoord(val
, StyleText()->mLineHeight
, true,
3073 nullptr, nsCSSProps::kLineHeightKTable
);
3080 nsComputedDOMStyle::DoGetRubyPosition()
3082 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3083 int32_t intValue
= StyleText()->mRubyPosition
;
3084 nsAutoString valueStr
;
3085 nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_ruby_position
,
3087 NS_STYLE_RUBY_POSITION_OVER
,
3088 NS_STYLE_RUBY_POSITION_LEFT
, valueStr
);
3089 val
->SetString(valueStr
);
3094 nsComputedDOMStyle::DoGetVerticalAlign()
3096 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3097 SetValueToCoord(val
, StyleTextReset()->mVerticalAlign
, false,
3098 &nsComputedDOMStyle::GetLineHeightCoord
,
3099 nsCSSProps::kVerticalAlignKTable
);
3104 nsComputedDOMStyle::CreateTextAlignValue(uint8_t aAlign
, bool aAlignTrue
,
3105 const KTableValue aTable
[])
3107 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3108 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(aAlign
, aTable
));
3113 nsROCSSPrimitiveValue
* first
= new nsROCSSPrimitiveValue
;
3114 first
->SetIdent(eCSSKeyword_true
);
3116 nsDOMCSSValueList
* valueList
= GetROCSSValueList(false);
3117 valueList
->AppendCSSValue(first
);
3118 valueList
->AppendCSSValue(val
);
3123 nsComputedDOMStyle::DoGetTextAlign()
3125 const nsStyleText
* style
= StyleText();
3126 return CreateTextAlignValue(style
->mTextAlign
, style
->mTextAlignTrue
,
3127 nsCSSProps::kTextAlignKTable
);
3131 nsComputedDOMStyle::DoGetTextAlignLast()
3133 const nsStyleText
* style
= StyleText();
3134 return CreateTextAlignValue(style
->mTextAlignLast
, style
->mTextAlignLastTrue
,
3135 nsCSSProps::kTextAlignLastKTable
);
3139 nsComputedDOMStyle::DoGetTextCombineUpright()
3141 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3142 uint8_t tch
= StyleText()->mTextCombineUpright
;
3144 if (tch
<= NS_STYLE_TEXT_COMBINE_UPRIGHT_ALL
) {
3146 nsCSSProps::ValueToKeywordEnum(tch
,
3147 nsCSSProps::kTextCombineUprightKTable
));
3148 } else if (tch
<= NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_2
) {
3149 val
->SetString(NS_LITERAL_STRING("digits 2"));
3150 } else if (tch
<= NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_3
) {
3151 val
->SetString(NS_LITERAL_STRING("digits 3"));
3153 val
->SetString(NS_LITERAL_STRING("digits 4"));
3160 nsComputedDOMStyle::DoGetTextDecoration()
3162 const nsStyleTextReset
* textReset
= StyleTextReset();
3164 bool isInitialStyle
=
3165 textReset
->GetDecorationStyle() == NS_STYLE_TEXT_DECORATION_STYLE_SOLID
;
3167 bool isForegroundColor
;
3168 textReset
->GetDecorationColor(color
, isForegroundColor
);
3170 if (isInitialStyle
&& isForegroundColor
) {
3171 return DoGetTextDecorationLine();
3174 nsDOMCSSValueList
*valueList
= GetROCSSValueList(false);
3176 valueList
->AppendCSSValue(DoGetTextDecorationLine());
3177 if (!isInitialStyle
) {
3178 valueList
->AppendCSSValue(DoGetTextDecorationStyle());
3180 if (!isForegroundColor
) {
3181 valueList
->AppendCSSValue(DoGetTextDecorationColor());
3188 nsComputedDOMStyle::DoGetTextDecorationColor()
3190 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3194 StyleTextReset()->GetDecorationColor(color
, isForeground
);
3196 color
= StyleColor()->mColor
;
3199 SetToRGBAColor(val
, color
);
3205 nsComputedDOMStyle::DoGetTextDecorationLine()
3207 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3209 int32_t intValue
= StyleTextReset()->mTextDecorationLine
;
3211 if (NS_STYLE_TEXT_DECORATION_LINE_NONE
== intValue
) {
3212 val
->SetIdent(eCSSKeyword_none
);
3214 nsAutoString decorationLineString
;
3215 // Clear the -moz-anchor-decoration bit and the OVERRIDE_ALL bits -- we
3216 // don't want these to appear in the computed style.
3217 intValue
&= ~(NS_STYLE_TEXT_DECORATION_LINE_PREF_ANCHORS
|
3218 NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL
);
3219 nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_text_decoration_line
,
3220 intValue
, NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE
,
3221 NS_STYLE_TEXT_DECORATION_LINE_BLINK
, decorationLineString
);
3222 val
->SetString(decorationLineString
);
3229 nsComputedDOMStyle::DoGetTextDecorationStyle()
3231 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3234 nsCSSProps::ValueToKeywordEnum(StyleTextReset()->GetDecorationStyle(),
3235 nsCSSProps::kTextDecorationStyleKTable
));
3241 nsComputedDOMStyle::DoGetTextIndent()
3243 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3244 SetValueToCoord(val
, StyleText()->mTextIndent
, false,
3245 &nsComputedDOMStyle::GetCBContentWidth
);
3250 nsComputedDOMStyle::DoGetTextOrientation()
3252 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3254 nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mTextOrientation
,
3255 nsCSSProps::kTextOrientationKTable
));
3260 nsComputedDOMStyle::DoGetTextOverflow()
3262 const nsStyleTextReset
*style
= StyleTextReset();
3263 nsROCSSPrimitiveValue
*first
= new nsROCSSPrimitiveValue
;
3264 const nsStyleTextOverflowSide
*side
= style
->mTextOverflow
.GetFirstValue();
3265 if (side
->mType
== NS_STYLE_TEXT_OVERFLOW_STRING
) {
3267 nsStyleUtil::AppendEscapedCSSString(side
->mString
, str
);
3268 first
->SetString(str
);
3271 nsCSSProps::ValueToKeywordEnum(side
->mType
,
3272 nsCSSProps::kTextOverflowKTable
));
3274 side
= style
->mTextOverflow
.GetSecondValue();
3278 nsROCSSPrimitiveValue
*second
= new nsROCSSPrimitiveValue
;
3279 if (side
->mType
== NS_STYLE_TEXT_OVERFLOW_STRING
) {
3281 nsStyleUtil::AppendEscapedCSSString(side
->mString
, str
);
3282 second
->SetString(str
);
3285 nsCSSProps::ValueToKeywordEnum(side
->mType
,
3286 nsCSSProps::kTextOverflowKTable
));
3289 nsDOMCSSValueList
*valueList
= GetROCSSValueList(false);
3290 valueList
->AppendCSSValue(first
);
3291 valueList
->AppendCSSValue(second
);
3296 nsComputedDOMStyle::DoGetTextShadow()
3298 return GetCSSShadowArray(StyleText()->mTextShadow
,
3299 StyleColor()->mColor
,
3304 nsComputedDOMStyle::DoGetTextTransform()
3306 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3308 nsCSSProps::ValueToKeywordEnum(StyleText()->mTextTransform
,
3309 nsCSSProps::kTextTransformKTable
));
3314 nsComputedDOMStyle::DoGetTabSize()
3316 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3317 val
->SetNumber(StyleText()->mTabSize
);
3322 nsComputedDOMStyle::DoGetLetterSpacing()
3324 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3325 SetValueToCoord(val
, StyleText()->mLetterSpacing
, false);
3330 nsComputedDOMStyle::DoGetWordSpacing()
3332 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3333 val
->SetAppUnits(StyleText()->mWordSpacing
);
3338 nsComputedDOMStyle::DoGetWhiteSpace()
3340 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3342 nsCSSProps::ValueToKeywordEnum(StyleText()->mWhiteSpace
,
3343 nsCSSProps::kWhitespaceKTable
));
3348 nsComputedDOMStyle::DoGetWindowDragging()
3350 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3352 nsCSSProps::ValueToKeywordEnum(StyleUserInterface()->mWindowDragging
,
3353 nsCSSProps::kWindowDraggingKTable
));
3358 nsComputedDOMStyle::DoGetWindowShadow()
3360 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3362 nsCSSProps::ValueToKeywordEnum(StyleUIReset()->mWindowShadow
,
3363 nsCSSProps::kWindowShadowKTable
));
3368 nsComputedDOMStyle::DoGetWordBreak()
3370 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3372 nsCSSProps::ValueToKeywordEnum(StyleText()->mWordBreak
,
3373 nsCSSProps::kWordBreakKTable
));
3378 nsComputedDOMStyle::DoGetWordWrap()
3380 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3382 nsCSSProps::ValueToKeywordEnum(StyleText()->mWordWrap
,
3383 nsCSSProps::kWordWrapKTable
));
3388 nsComputedDOMStyle::DoGetHyphens()
3390 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3392 nsCSSProps::ValueToKeywordEnum(StyleText()->mHyphens
,
3393 nsCSSProps::kHyphensKTable
));
3398 nsComputedDOMStyle::DoGetTextSizeAdjust()
3400 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3401 switch (StyleText()->mTextSizeAdjust
) {
3403 NS_NOTREACHED("unexpected value");
3405 case NS_STYLE_TEXT_SIZE_ADJUST_AUTO
:
3406 val
->SetIdent(eCSSKeyword_auto
);
3408 case NS_STYLE_TEXT_SIZE_ADJUST_NONE
:
3409 val
->SetIdent(eCSSKeyword_none
);
3416 nsComputedDOMStyle::DoGetPointerEvents()
3418 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3420 nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mPointerEvents
,
3421 nsCSSProps::kPointerEventsKTable
));
3426 nsComputedDOMStyle::DoGetVisibility()
3428 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3429 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mVisible
,
3430 nsCSSProps::kVisibilityKTable
));
3435 nsComputedDOMStyle::DoGetWritingMode()
3437 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3439 nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mWritingMode
,
3440 nsCSSProps::kWritingModeKTable
));
3445 nsComputedDOMStyle::DoGetDirection()
3447 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3449 nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mDirection
,
3450 nsCSSProps::kDirectionKTable
));
3454 static_assert(NS_STYLE_UNICODE_BIDI_NORMAL
== 0,
3455 "unicode-bidi style constants not as expected");
3458 nsComputedDOMStyle::DoGetUnicodeBidi()
3460 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3462 nsCSSProps::ValueToKeywordEnum(StyleTextReset()->mUnicodeBidi
,
3463 nsCSSProps::kUnicodeBidiKTable
));
3468 nsComputedDOMStyle::DoGetCursor()
3470 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
3472 const nsStyleUserInterface
*ui
= StyleUserInterface();
3474 for (nsCursorImage
*item
= ui
->mCursorArray
,
3475 *item_end
= ui
->mCursorArray
+ ui
->mCursorArrayLength
;
3476 item
< item_end
; ++item
) {
3477 nsDOMCSSValueList
*itemList
= GetROCSSValueList(false);
3478 valueList
->AppendCSSValue(itemList
);
3480 nsCOMPtr
<nsIURI
> uri
;
3481 item
->GetImage()->GetURI(getter_AddRefs(uri
));
3483 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3484 itemList
->AppendCSSValue(val
);
3487 if (item
->mHaveHotspot
) {
3488 nsROCSSPrimitiveValue
*valX
= new nsROCSSPrimitiveValue
;
3489 itemList
->AppendCSSValue(valX
);
3490 nsROCSSPrimitiveValue
*valY
= new nsROCSSPrimitiveValue
;
3491 itemList
->AppendCSSValue(valY
);
3493 valX
->SetNumber(item
->mHotspotX
);
3494 valY
->SetNumber(item
->mHotspotY
);
3498 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3499 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(ui
->mCursor
,
3500 nsCSSProps::kCursorKTable
));
3501 valueList
->AppendCSSValue(val
);
3506 nsComputedDOMStyle::DoGetAppearance()
3508 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3509 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mAppearance
,
3510 nsCSSProps::kAppearanceKTable
));
3516 nsComputedDOMStyle::DoGetBoxAlign()
3518 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3519 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleXUL()->mBoxAlign
,
3520 nsCSSProps::kBoxAlignKTable
));
3525 nsComputedDOMStyle::DoGetBoxDirection()
3527 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3529 nsCSSProps::ValueToKeywordEnum(StyleXUL()->mBoxDirection
,
3530 nsCSSProps::kBoxDirectionKTable
));
3535 nsComputedDOMStyle::DoGetBoxFlex()
3537 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3538 val
->SetNumber(StyleXUL()->mBoxFlex
);
3543 nsComputedDOMStyle::DoGetBoxOrdinalGroup()
3545 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3546 val
->SetNumber(StyleXUL()->mBoxOrdinal
);
3551 nsComputedDOMStyle::DoGetBoxOrient()
3553 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3555 nsCSSProps::ValueToKeywordEnum(StyleXUL()->mBoxOrient
,
3556 nsCSSProps::kBoxOrientKTable
));
3561 nsComputedDOMStyle::DoGetBoxPack()
3563 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3564 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleXUL()->mBoxPack
,
3565 nsCSSProps::kBoxPackKTable
));
3570 nsComputedDOMStyle::DoGetBoxSizing()
3572 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3574 nsCSSProps::ValueToKeywordEnum(StylePosition()->mBoxSizing
,
3575 nsCSSProps::kBoxSizingKTable
));
3579 /* Border image properties */
3582 nsComputedDOMStyle::DoGetBorderImageSource()
3584 const nsStyleBorder
* border
= StyleBorder();
3586 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3587 const nsStyleImage
& image
= border
->mBorderImageSource
;
3588 SetValueToStyleImage(image
, val
);
3594 nsComputedDOMStyle::DoGetBorderImageSlice()
3596 nsDOMCSSValueList
* valueList
= GetROCSSValueList(false);
3598 const nsStyleBorder
* border
= StyleBorder();
3599 // Four slice numbers.
3600 NS_FOR_CSS_SIDES (side
) {
3601 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3602 valueList
->AppendCSSValue(val
);
3603 SetValueToCoord(val
, border
->mBorderImageSlice
.Get(side
), true, nullptr);
3607 if (NS_STYLE_BORDER_IMAGE_SLICE_FILL
== border
->mBorderImageFill
) {
3608 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3609 valueList
->AppendCSSValue(val
);
3610 val
->SetIdent(eCSSKeyword_fill
);
3617 nsComputedDOMStyle::DoGetBorderImageWidth()
3619 const nsStyleBorder
* border
= StyleBorder();
3620 nsDOMCSSValueList
* valueList
= GetROCSSValueList(false);
3621 NS_FOR_CSS_SIDES (side
) {
3622 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3623 valueList
->AppendCSSValue(val
);
3624 SetValueToCoord(val
, border
->mBorderImageWidth
.Get(side
),
3632 nsComputedDOMStyle::DoGetBorderImageOutset()
3634 nsDOMCSSValueList
*valueList
= GetROCSSValueList(false);
3636 const nsStyleBorder
* border
= StyleBorder();
3637 // four slice numbers
3638 NS_FOR_CSS_SIDES (side
) {
3639 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3640 valueList
->AppendCSSValue(val
);
3641 SetValueToCoord(val
, border
->mBorderImageOutset
.Get(side
),
3649 nsComputedDOMStyle::DoGetBorderImageRepeat()
3651 nsDOMCSSValueList
* valueList
= GetROCSSValueList(false);
3653 const nsStyleBorder
* border
= StyleBorder();
3655 // horizontal repeat
3656 nsROCSSPrimitiveValue
* valX
= new nsROCSSPrimitiveValue
;
3657 valueList
->AppendCSSValue(valX
);
3659 nsCSSProps::ValueToKeywordEnum(border
->mBorderImageRepeatH
,
3660 nsCSSProps::kBorderImageRepeatKTable
));
3663 nsROCSSPrimitiveValue
* valY
= new nsROCSSPrimitiveValue
;
3664 valueList
->AppendCSSValue(valY
);
3666 nsCSSProps::ValueToKeywordEnum(border
->mBorderImageRepeatV
,
3667 nsCSSProps::kBorderImageRepeatKTable
));
3672 nsComputedDOMStyle::DoGetAlignContent()
3674 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3676 nsCSSProps::ValueToKeywordEnum(StylePosition()->mAlignContent
,
3677 nsCSSProps::kAlignContentKTable
));
3682 nsComputedDOMStyle::DoGetAlignItems()
3684 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3686 nsCSSProps::ValueToKeywordEnum(StylePosition()->mAlignItems
,
3687 nsCSSProps::kAlignItemsKTable
));
3692 nsComputedDOMStyle::DoGetAlignSelf()
3694 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3695 uint8_t computedAlignSelf
= StylePosition()->mAlignSelf
;
3697 if (computedAlignSelf
== NS_STYLE_ALIGN_SELF_AUTO
) {
3698 // "align-self: auto" needs to compute to parent's align-items value.
3699 nsStyleContext
* parentStyleContext
= mStyleContextHolder
->GetParent();
3700 if (parentStyleContext
) {
3702 parentStyleContext
->StylePosition()->mAlignItems
;
3704 // No parent --> use default.
3705 computedAlignSelf
= NS_STYLE_ALIGN_ITEMS_INITIAL_VALUE
;
3709 NS_ABORT_IF_FALSE(computedAlignSelf
!= NS_STYLE_ALIGN_SELF_AUTO
,
3710 "Should have swapped out 'auto' for something non-auto");
3712 nsCSSProps::ValueToKeywordEnum(computedAlignSelf
,
3713 nsCSSProps::kAlignSelfKTable
));
3718 nsComputedDOMStyle::DoGetFlexBasis()
3720 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3722 // XXXdholbert We could make this more automagic and resolve percentages
3723 // if we wanted, by passing in a PercentageBaseGetter instead of nullptr
3724 // below. Logic would go like this:
3725 // if (i'm a flex item) {
3726 // if (my flex container is horizontal) {
3727 // percentageBaseGetter = &nsComputedDOMStyle::GetCBContentWidth;
3729 // percentageBaseGetter = &nsComputedDOMStyle::GetCBContentHeight;
3733 SetValueToCoord(val
, StylePosition()->mFlexBasis
, true,
3734 nullptr, nsCSSProps::kWidthKTable
);
3739 nsComputedDOMStyle::DoGetFlexDirection()
3741 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3743 nsCSSProps::ValueToKeywordEnum(StylePosition()->mFlexDirection
,
3744 nsCSSProps::kFlexDirectionKTable
));
3749 nsComputedDOMStyle::DoGetFlexGrow()
3751 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3752 val
->SetNumber(StylePosition()->mFlexGrow
);
3757 nsComputedDOMStyle::DoGetFlexShrink()
3759 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3760 val
->SetNumber(StylePosition()->mFlexShrink
);
3765 nsComputedDOMStyle::DoGetFlexWrap()
3767 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3769 nsCSSProps::ValueToKeywordEnum(StylePosition()->mFlexWrap
,
3770 nsCSSProps::kFlexWrapKTable
));
3775 nsComputedDOMStyle::DoGetOrder()
3777 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3778 val
->SetNumber(StylePosition()->mOrder
);
3783 nsComputedDOMStyle::DoGetJustifyContent()
3785 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3787 nsCSSProps::ValueToKeywordEnum(StylePosition()->mJustifyContent
,
3788 nsCSSProps::kJustifyContentKTable
));
3793 nsComputedDOMStyle::DoGetFloatEdge()
3795 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3797 nsCSSProps::ValueToKeywordEnum(StyleBorder()->mFloatEdge
,
3798 nsCSSProps::kFloatEdgeKTable
));
3803 nsComputedDOMStyle::DoGetForceBrokenImageIcon()
3805 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3806 val
->SetNumber(StyleUIReset()->mForceBrokenImageIcon
);
3811 nsComputedDOMStyle::DoGetImageOrientation()
3813 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3814 nsAutoString string
;
3815 nsStyleImageOrientation orientation
= StyleVisibility()->mImageOrientation
;
3817 if (orientation
.IsFromImage()) {
3818 string
.AppendLiteral("from-image");
3820 nsStyleUtil::AppendAngleValue(orientation
.AngleAsCoord(), string
);
3822 if (orientation
.IsFlipped()) {
3823 string
.AppendLiteral(" flip");
3827 val
->SetString(string
);
3832 nsComputedDOMStyle::DoGetIMEMode()
3834 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3836 nsCSSProps::ValueToKeywordEnum(StyleUIReset()->mIMEMode
,
3837 nsCSSProps::kIMEModeKTable
));
3842 nsComputedDOMStyle::DoGetUserFocus()
3844 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3846 nsCSSProps::ValueToKeywordEnum(StyleUserInterface()->mUserFocus
,
3847 nsCSSProps::kUserFocusKTable
));
3852 nsComputedDOMStyle::DoGetUserInput()
3854 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3856 nsCSSProps::ValueToKeywordEnum(StyleUserInterface()->mUserInput
,
3857 nsCSSProps::kUserInputKTable
));
3862 nsComputedDOMStyle::DoGetUserModify()
3864 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3866 nsCSSProps::ValueToKeywordEnum(StyleUserInterface()->mUserModify
,
3867 nsCSSProps::kUserModifyKTable
));
3872 nsComputedDOMStyle::DoGetUserSelect()
3874 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3876 nsCSSProps::ValueToKeywordEnum(StyleUIReset()->mUserSelect
,
3877 nsCSSProps::kUserSelectKTable
));
3882 nsComputedDOMStyle::DoGetDisplay()
3884 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3885 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mDisplay
,
3886 nsCSSProps::kDisplayKTable
));
3891 nsComputedDOMStyle::DoGetPosition()
3893 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3894 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mPosition
,
3895 nsCSSProps::kPositionKTable
));
3900 nsComputedDOMStyle::DoGetClip()
3902 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3904 const nsStyleDisplay
* display
= StyleDisplay();
3906 if (display
->mClipFlags
== NS_STYLE_CLIP_AUTO
) {
3907 val
->SetIdent(eCSSKeyword_auto
);
3909 // create the cssvalues for the sides, stick them in the rect object
3910 nsROCSSPrimitiveValue
*topVal
= new nsROCSSPrimitiveValue
;
3911 nsROCSSPrimitiveValue
*rightVal
= new nsROCSSPrimitiveValue
;
3912 nsROCSSPrimitiveValue
*bottomVal
= new nsROCSSPrimitiveValue
;
3913 nsROCSSPrimitiveValue
*leftVal
= new nsROCSSPrimitiveValue
;
3914 nsDOMCSSRect
* domRect
= new nsDOMCSSRect(topVal
, rightVal
,
3915 bottomVal
, leftVal
);
3916 if (display
->mClipFlags
& NS_STYLE_CLIP_TOP_AUTO
) {
3917 topVal
->SetIdent(eCSSKeyword_auto
);
3919 topVal
->SetAppUnits(display
->mClip
.y
);
3922 if (display
->mClipFlags
& NS_STYLE_CLIP_RIGHT_AUTO
) {
3923 rightVal
->SetIdent(eCSSKeyword_auto
);
3925 rightVal
->SetAppUnits(display
->mClip
.width
+ display
->mClip
.x
);
3928 if (display
->mClipFlags
& NS_STYLE_CLIP_BOTTOM_AUTO
) {
3929 bottomVal
->SetIdent(eCSSKeyword_auto
);
3931 bottomVal
->SetAppUnits(display
->mClip
.height
+ display
->mClip
.y
);
3934 if (display
->mClipFlags
& NS_STYLE_CLIP_LEFT_AUTO
) {
3935 leftVal
->SetIdent(eCSSKeyword_auto
);
3937 leftVal
->SetAppUnits(display
->mClip
.x
);
3939 val
->SetRect(domRect
);
3946 nsComputedDOMStyle::DoGetWillChange()
3948 const nsTArray
<nsString
>& willChange
= StyleDisplay()->mWillChange
;
3950 if (willChange
.IsEmpty()) {
3951 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
3952 val
->SetIdent(eCSSKeyword_auto
);
3956 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
3957 for (size_t i
= 0; i
< willChange
.Length(); i
++) {
3958 const nsString
& willChangeIdentifier
= willChange
[i
];
3959 nsROCSSPrimitiveValue
* property
= new nsROCSSPrimitiveValue
;
3960 valueList
->AppendCSSValue(property
);
3961 property
->SetString(willChangeIdentifier
);
3968 nsComputedDOMStyle::DoGetOverflow()
3970 const nsStyleDisplay
* display
= StyleDisplay();
3972 if (display
->mOverflowX
!= display
->mOverflowY
) {
3973 // No value to return. We can't express this combination of
3974 // values as a shorthand.
3978 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3979 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(display
->mOverflowX
,
3980 nsCSSProps::kOverflowKTable
));
3985 nsComputedDOMStyle::DoGetOverflowX()
3987 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3989 nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mOverflowX
,
3990 nsCSSProps::kOverflowSubKTable
));
3995 nsComputedDOMStyle::DoGetOverflowY()
3997 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
3999 nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mOverflowY
,
4000 nsCSSProps::kOverflowSubKTable
));
4005 nsComputedDOMStyle::DoGetOverflowClipBox()
4007 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
4009 nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mOverflowClipBox
,
4010 nsCSSProps::kOverflowClipBoxKTable
));
4015 nsComputedDOMStyle::DoGetResize()
4017 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
4018 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mResize
,
4019 nsCSSProps::kResizeKTable
));
4025 nsComputedDOMStyle::DoGetPageBreakAfter()
4027 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
4029 const nsStyleDisplay
*display
= StyleDisplay();
4031 if (display
->mBreakAfter
) {
4032 val
->SetIdent(eCSSKeyword_always
);
4034 val
->SetIdent(eCSSKeyword_auto
);
4041 nsComputedDOMStyle::DoGetPageBreakBefore()
4043 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
4045 const nsStyleDisplay
*display
= StyleDisplay();
4047 if (display
->mBreakBefore
) {
4048 val
->SetIdent(eCSSKeyword_always
);
4050 val
->SetIdent(eCSSKeyword_auto
);
4057 nsComputedDOMStyle::DoGetPageBreakInside()
4059 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
4060 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mBreakInside
,
4061 nsCSSProps::kPageBreakInsideKTable
));
4066 nsComputedDOMStyle::DoGetTouchAction()
4068 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
4070 int32_t intValue
= StyleDisplay()->mTouchAction
;
4072 // None and Auto and Manipulation values aren't allowed
4073 // to be in conjunction with other values.
4074 // But there are all checks in CSSParserImpl::ParseTouchAction
4075 nsAutoString valueStr
;
4076 nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_touch_action
, intValue
,
4077 NS_STYLE_TOUCH_ACTION_NONE
, NS_STYLE_TOUCH_ACTION_MANIPULATION
,
4079 val
->SetString(valueStr
);
4084 nsComputedDOMStyle::DoGetHeight()
4086 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
4088 bool calcHeight
= false;
4093 const nsStyleDisplay
* displayData
= StyleDisplay();
4094 if (displayData
->mDisplay
== NS_STYLE_DISPLAY_INLINE
&&
4095 !(mInnerFrame
->IsFrameOfType(nsIFrame::eReplaced
)) &&
4096 // An outer SVG frame should behave the same as eReplaced in this case
4097 mInnerFrame
->GetType() != nsGkAtoms::svgOuterSVGFrame
) {
4104 AssertFlushedPendingReflows();
4105 nsMargin adjustedValues
= GetAdjustedValuesForBoxSizing();
4106 val
->SetAppUnits(mInnerFrame
->GetContentRect().height
+
4107 adjustedValues
.TopBottom());
4109 const nsStylePosition
*positionData
= StylePosition();
4112 StyleCoordToNSCoord(positionData
->mMinHeight
,
4113 &nsComputedDOMStyle::GetCBContentHeight
, 0, true);
4116 StyleCoordToNSCoord(positionData
->mMaxHeight
,
4117 &nsComputedDOMStyle::GetCBContentHeight
,
4120 SetValueToCoord(val
, positionData
->mHeight
, true, nullptr, nullptr,
4121 minHeight
, maxHeight
);
4128 nsComputedDOMStyle::DoGetWidth()
4130 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
4132 bool calcWidth
= false;
4137 const nsStyleDisplay
*displayData
= StyleDisplay();
4138 if (displayData
->mDisplay
== NS_STYLE_DISPLAY_INLINE
&&
4139 !(mInnerFrame
->IsFrameOfType(nsIFrame::eReplaced
)) &&
4140 // An outer SVG frame should behave the same as eReplaced in this case
4141 mInnerFrame
->GetType() != nsGkAtoms::svgOuterSVGFrame
) {
4148 AssertFlushedPendingReflows();
4149 nsMargin adjustedValues
= GetAdjustedValuesForBoxSizing();
4150 val
->SetAppUnits(mInnerFrame
->GetContentRect().width
+
4151 adjustedValues
.LeftRight());
4153 const nsStylePosition
*positionData
= StylePosition();
4156 StyleCoordToNSCoord(positionData
->mMinWidth
,
4157 &nsComputedDOMStyle::GetCBContentWidth
, 0, true);
4160 StyleCoordToNSCoord(positionData
->mMaxWidth
,
4161 &nsComputedDOMStyle::GetCBContentWidth
,
4164 SetValueToCoord(val
, positionData
->mWidth
, true, nullptr,
4165 nsCSSProps::kWidthKTable
, minWidth
, maxWidth
);
4172 nsComputedDOMStyle::DoGetMaxHeight()
4174 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
4175 SetValueToCoord(val
, StylePosition()->mMaxHeight
, true,
4176 &nsComputedDOMStyle::GetCBContentHeight
);
4181 nsComputedDOMStyle::DoGetMaxWidth()
4183 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
4184 SetValueToCoord(val
, StylePosition()->mMaxWidth
, true,
4185 &nsComputedDOMStyle::GetCBContentWidth
,
4186 nsCSSProps::kWidthKTable
);
4191 nsComputedDOMStyle::DoGetMinHeight()
4193 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
4194 nsStyleCoord minHeight
= StylePosition()->mMinHeight
;
4196 if (eStyleUnit_Auto
== minHeight
.GetUnit()) {
4197 // In non-flexbox contexts, "min-height: auto" means "min-height: 0"
4198 // XXXdholbert For flex items, we should set |minHeight| to the
4199 // -moz-min-content keyword, instead of 0, once we support -moz-min-content
4200 // as a height value.
4201 minHeight
.SetCoordValue(0);
4204 SetValueToCoord(val
, minHeight
, true,
4205 &nsComputedDOMStyle::GetCBContentHeight
);
4210 nsComputedDOMStyle::DoGetMinWidth()
4212 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
4214 nsStyleCoord minWidth
= StylePosition()->mMinWidth
;
4216 if (eStyleUnit_Auto
== minWidth
.GetUnit()) {
4217 // "min-width: auto" means "0", unless we're a flex item in a horizontal
4218 // flex container, in which case it means "min-content"
4219 minWidth
.SetCoordValue(0);
4220 if (mOuterFrame
&& mOuterFrame
->IsFlexItem()) {
4221 nsIFrame
* flexContainer
= mOuterFrame
->GetParent();
4222 MOZ_ASSERT(flexContainer
&&
4223 flexContainer
->GetType() == nsGkAtoms::flexContainerFrame
,
4224 "IsFlexItem() lied...?");
4226 if (static_cast<nsFlexContainerFrame
*>(flexContainer
)->IsHorizontal()) {
4227 minWidth
.SetIntValue(NS_STYLE_WIDTH_MIN_CONTENT
, eStyleUnit_Enumerated
);
4231 SetValueToCoord(val
, minWidth
, true,
4232 &nsComputedDOMStyle::GetCBContentWidth
,
4233 nsCSSProps::kWidthKTable
);
4238 nsComputedDOMStyle::DoGetMixBlendMode()
4240 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
4241 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mMixBlendMode
,
4242 nsCSSProps::kBlendModeKTable
));
4247 nsComputedDOMStyle::DoGetIsolation()
4249 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
4250 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mIsolation
,
4251 nsCSSProps::kIsolationKTable
));
4256 nsComputedDOMStyle::DoGetObjectFit()
4258 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
4259 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(StylePosition()->mObjectFit
,
4260 nsCSSProps::kObjectFitKTable
));
4265 nsComputedDOMStyle::DoGetObjectPosition()
4267 nsDOMCSSValueList
* valueList
= GetROCSSValueList(false);
4268 SetValueToPosition(StylePosition()->mObjectPosition
, valueList
);
4273 nsComputedDOMStyle::DoGetLeft()
4275 return GetOffsetWidthFor(NS_SIDE_LEFT
);
4279 nsComputedDOMStyle::DoGetRight()
4281 return GetOffsetWidthFor(NS_SIDE_RIGHT
);
4285 nsComputedDOMStyle::DoGetTop()
4287 return GetOffsetWidthFor(NS_SIDE_TOP
);
4291 nsComputedDOMStyle::GetROCSSValueList(bool aCommaDelimited
)
4293 return new nsDOMCSSValueList(aCommaDelimited
, true);
4297 nsComputedDOMStyle::GetOffsetWidthFor(mozilla::css::Side aSide
)
4299 const nsStyleDisplay
* display
= StyleDisplay();
4301 AssertFlushedPendingReflows();
4303 uint8_t position
= display
->mPosition
;
4305 // GetRelativeOffset and GetAbsoluteOffset don't handle elements
4306 // without frames in any sensible way. GetStaticOffset, however,
4307 // is perfect for that case.
4308 position
= NS_STYLE_POSITION_STATIC
;
4312 case NS_STYLE_POSITION_STATIC
:
4313 return GetStaticOffset(aSide
);
4314 case NS_STYLE_POSITION_RELATIVE
:
4315 return GetRelativeOffset(aSide
);
4316 case NS_STYLE_POSITION_STICKY
:
4317 return GetStickyOffset(aSide
);
4318 case NS_STYLE_POSITION_ABSOLUTE
:
4319 case NS_STYLE_POSITION_FIXED
:
4320 return GetAbsoluteOffset(aSide
);
4322 NS_ERROR("Invalid position");
4328 nsComputedDOMStyle::GetAbsoluteOffset(mozilla::css::Side aSide
)
4330 MOZ_ASSERT(mOuterFrame
, "need a frame, so we can call GetContainingBlock()");
4332 nsIFrame
* container
= mOuterFrame
->GetContainingBlock();
4333 nsMargin margin
= mOuterFrame
->GetUsedMargin();
4334 nsMargin border
= container
->GetUsedBorder();
4335 nsMargin
scrollbarSizes(0, 0, 0, 0);
4336 nsRect rect
= mOuterFrame
->GetRect();
4337 nsRect containerRect
= container
->GetRect();
4339 if (container
->GetType() == nsGkAtoms::viewportFrame
) {
4340 // For absolutely positioned frames scrollbars are taken into
4341 // account by virtue of getting a containing block that does
4342 // _not_ include the scrollbars. For fixed positioned frames,
4343 // the containing block is the viewport, which _does_ include
4344 // scrollbars. We have to do some extra work.
4345 // the first child in the default frame list is what we want
4346 nsIFrame
* scrollingChild
= container
->GetFirstPrincipalChild();
4347 nsIScrollableFrame
*scrollFrame
= do_QueryFrame(scrollingChild
);
4349 scrollbarSizes
= scrollFrame
->GetActualScrollbarSizes();
4356 offset
= rect
.y
- margin
.top
- border
.top
- scrollbarSizes
.top
;
4360 offset
= containerRect
.width
- rect
.width
-
4361 rect
.x
- margin
.right
- border
.right
- scrollbarSizes
.right
;
4364 case NS_SIDE_BOTTOM
:
4365 offset
= containerRect
.height
- rect
.height
-
4366 rect
.y
- margin
.bottom
- border
.bottom
- scrollbarSizes
.bottom
;
4370 offset
= rect
.x
- margin
.left
- border
.left
- scrollbarSizes
.left
;
4374 NS_ERROR("Invalid side");
4378 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
4379 val
->SetAppUnits(offset
);
4383 static_assert(NS_SIDE_TOP
== 0 && NS_SIDE_RIGHT
== 1 &&
4384 NS_SIDE_BOTTOM
== 2 && NS_SIDE_LEFT
== 3,
4385 "box side constants not as expected for NS_OPPOSITE_SIDE");
4386 #define NS_OPPOSITE_SIDE(s_) mozilla::css::Side(((s_) + 2) & 3)
4389 nsComputedDOMStyle::GetRelativeOffset(mozilla::css::Side aSide
)
4391 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
4393 const nsStylePosition
* positionData
= StylePosition();
4395 nsStyleCoord coord
= positionData
->mOffset
.Get(aSide
);
4397 NS_ASSERTION(coord
.GetUnit() == eStyleUnit_Coord
||
4398 coord
.GetUnit() == eStyleUnit_Percent
||
4399 coord
.GetUnit() == eStyleUnit_Auto
||
4403 if (coord
.GetUnit() == eStyleUnit_Auto
) {
4404 coord
= positionData
->mOffset
.Get(NS_OPPOSITE_SIDE(aSide
));
4407 PercentageBaseGetter baseGetter
;
4408 if (aSide
== NS_SIDE_LEFT
|| aSide
== NS_SIDE_RIGHT
) {
4409 baseGetter
= &nsComputedDOMStyle::GetCBContentWidth
;
4411 baseGetter
= &nsComputedDOMStyle::GetCBContentHeight
;
4414 val
->SetAppUnits(sign
* StyleCoordToNSCoord(coord
, baseGetter
, 0, false));
4419 nsComputedDOMStyle::GetStickyOffset(mozilla::css::Side aSide
)
4421 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
4423 const nsStylePosition
* positionData
= StylePosition();
4424 nsStyleCoord coord
= positionData
->mOffset
.Get(aSide
);
4426 NS_ASSERTION(coord
.GetUnit() == eStyleUnit_Coord
||
4427 coord
.GetUnit() == eStyleUnit_Percent
||
4428 coord
.GetUnit() == eStyleUnit_Auto
||
4432 if (coord
.GetUnit() == eStyleUnit_Auto
) {
4433 val
->SetIdent(eCSSKeyword_auto
);
4436 PercentageBaseGetter baseGetter
;
4437 if (aSide
== NS_SIDE_LEFT
|| aSide
== NS_SIDE_RIGHT
) {
4438 baseGetter
= &nsComputedDOMStyle::GetScrollFrameContentWidth
;
4440 baseGetter
= &nsComputedDOMStyle::GetScrollFrameContentHeight
;
4443 val
->SetAppUnits(StyleCoordToNSCoord(coord
, baseGetter
, 0, false));
4449 nsComputedDOMStyle::GetStaticOffset(mozilla::css::Side aSide
)
4452 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
4453 SetValueToCoord(val
, StylePosition()->mOffset
.Get(aSide
), false);
4458 nsComputedDOMStyle::GetPaddingWidthFor(mozilla::css::Side aSide
)
4460 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
4463 SetValueToCoord(val
, StylePadding()->mPadding
.Get(aSide
), true);
4465 AssertFlushedPendingReflows();
4467 val
->SetAppUnits(mInnerFrame
->GetUsedPadding().Side(aSide
));
4474 nsComputedDOMStyle::GetLineHeightCoord(nscoord
& aCoord
)
4476 AssertFlushedPendingReflows();
4478 nscoord blockHeight
= NS_AUTOHEIGHT
;
4479 if (StyleText()->mLineHeight
.GetUnit() == eStyleUnit_Enumerated
) {
4483 if (nsLayoutUtils::IsNonWrapperBlock(mInnerFrame
)) {
4484 blockHeight
= mInnerFrame
->GetContentRect().height
;
4486 GetCBContentHeight(blockHeight
);
4490 // lie about font size inflation since we lie about font size (since
4491 // the inflation only applies to text)
4492 aCoord
= nsHTMLReflowState::CalcLineHeight(mContent
, mStyleContextHolder
,
4495 // CalcLineHeight uses font->mFont.size, but we want to use
4496 // font->mSize as the font size. Adjust for that. Also adjust for
4497 // the text zoom, if any.
4498 const nsStyleFont
* font
= StyleFont();
4499 float fCoord
= float(aCoord
);
4500 if (font
->mAllowZoom
) {
4501 fCoord
/= mPresShell
->GetPresContext()->TextZoom();
4503 if (font
->mFont
.size
!= font
->mSize
) {
4504 fCoord
= fCoord
* (float(font
->mSize
) / float(font
->mFont
.size
));
4506 aCoord
= NSToCoordRound(fCoord
);
4512 nsComputedDOMStyle::GetBorderColorsFor(mozilla::css::Side aSide
)
4514 const nsStyleBorder
*border
= StyleBorder();
4516 if (border
->mBorderColors
) {
4517 nsBorderColors
* borderColors
= border
->mBorderColors
[aSide
];
4519 nsDOMCSSValueList
*valueList
= GetROCSSValueList(false);
4522 nsROCSSPrimitiveValue
*primitive
= new nsROCSSPrimitiveValue
;
4524 SetToRGBAColor(primitive
, borderColors
->mColor
);
4526 valueList
->AppendCSSValue(primitive
);
4527 borderColors
= borderColors
->mNext
;
4528 } while (borderColors
);
4534 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
4535 val
->SetIdent(eCSSKeyword_none
);
4540 nsComputedDOMStyle::GetBorderWidthFor(mozilla::css::Side aSide
)
4542 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
4546 AssertFlushedPendingReflows();
4547 width
= mInnerFrame
->GetUsedBorder().Side(aSide
);
4549 width
= StyleBorder()->GetComputedBorderWidth(aSide
);
4551 val
->SetAppUnits(width
);
4557 nsComputedDOMStyle::GetBorderColorFor(mozilla::css::Side aSide
)
4559 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
4563 StyleBorder()->GetBorderColor(aSide
, color
, foreground
);
4565 color
= StyleColor()->mColor
;
4568 SetToRGBAColor(val
, color
);
4573 nsComputedDOMStyle::GetMarginWidthFor(mozilla::css::Side aSide
)
4575 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
4578 SetValueToCoord(val
, StyleMargin()->mMargin
.Get(aSide
), false);
4580 AssertFlushedPendingReflows();
4582 // For tables, GetUsedMargin always returns an empty margin, so we
4583 // should read the margin from the outer table frame instead.
4584 val
->SetAppUnits(mOuterFrame
->GetUsedMargin().Side(aSide
));
4585 NS_ASSERTION(mOuterFrame
== mInnerFrame
||
4586 mInnerFrame
->GetUsedMargin() == nsMargin(0, 0, 0, 0),
4587 "Inner tables must have zero margins");
4594 nsComputedDOMStyle::GetBorderStyleFor(mozilla::css::Side aSide
)
4596 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
4598 nsCSSProps::ValueToKeywordEnum(StyleBorder()->GetBorderStyle(aSide
),
4599 nsCSSProps::kBorderStyleKTable
));
4604 nsComputedDOMStyle::SetValueToCoord(nsROCSSPrimitiveValue
* aValue
,
4605 const nsStyleCoord
& aCoord
,
4606 bool aClampNegativeCalc
,
4607 PercentageBaseGetter aPercentageBaseGetter
,
4608 const KTableValue aTable
[],
4609 nscoord aMinAppUnits
,
4610 nscoord aMaxAppUnits
)
4612 NS_PRECONDITION(aValue
, "Must have a value to work with");
4614 switch (aCoord
.GetUnit()) {
4615 case eStyleUnit_Normal
:
4616 aValue
->SetIdent(eCSSKeyword_normal
);
4619 case eStyleUnit_Auto
:
4620 aValue
->SetIdent(eCSSKeyword_auto
);
4623 case eStyleUnit_Percent
:
4625 nscoord percentageBase
;
4626 if (aPercentageBaseGetter
&&
4627 (this->*aPercentageBaseGetter
)(percentageBase
)) {
4628 nscoord val
= NSCoordSaturatingMultiply(percentageBase
,
4629 aCoord
.GetPercentValue());
4630 aValue
->SetAppUnits(std::max(aMinAppUnits
, std::min(val
, aMaxAppUnits
)));
4632 aValue
->SetPercent(aCoord
.GetPercentValue());
4637 case eStyleUnit_Factor
:
4638 aValue
->SetNumber(aCoord
.GetFactorValue());
4641 case eStyleUnit_Coord
:
4643 nscoord val
= aCoord
.GetCoordValue();
4644 aValue
->SetAppUnits(std::max(aMinAppUnits
, std::min(val
, aMaxAppUnits
)));
4648 case eStyleUnit_Integer
:
4649 aValue
->SetNumber(aCoord
.GetIntValue());
4652 case eStyleUnit_Enumerated
:
4653 NS_ASSERTION(aTable
, "Must have table to handle this case");
4654 aValue
->SetIdent(nsCSSProps::ValueToKeywordEnum(aCoord
.GetIntValue(),
4658 case eStyleUnit_None
:
4659 aValue
->SetIdent(eCSSKeyword_none
);
4662 case eStyleUnit_Calc
:
4663 nscoord percentageBase
;
4664 if (!aCoord
.CalcHasPercent()) {
4665 nscoord val
= nsRuleNode::ComputeCoordPercentCalc(aCoord
, 0);
4666 if (aClampNegativeCalc
&& val
< 0) {
4667 NS_ABORT_IF_FALSE(aCoord
.IsCalcUnit(),
4668 "parser should have rejected value");
4671 aValue
->SetAppUnits(std::max(aMinAppUnits
, std::min(val
, aMaxAppUnits
)));
4672 } else if (aPercentageBaseGetter
&&
4673 (this->*aPercentageBaseGetter
)(percentageBase
)) {
4675 nsRuleNode::ComputeCoordPercentCalc(aCoord
, percentageBase
);
4676 if (aClampNegativeCalc
&& val
< 0) {
4677 NS_ABORT_IF_FALSE(aCoord
.IsCalcUnit(),
4678 "parser should have rejected value");
4681 aValue
->SetAppUnits(std::max(aMinAppUnits
, std::min(val
, aMaxAppUnits
)));
4683 nsStyleCoord::Calc
*calc
= aCoord
.GetCalcValue();
4684 SetValueToCalc(calc
, aValue
);
4688 case eStyleUnit_Degree
:
4689 aValue
->SetDegree(aCoord
.GetAngleValue());
4692 case eStyleUnit_Grad
:
4693 aValue
->SetGrad(aCoord
.GetAngleValue());
4696 case eStyleUnit_Radian
:
4697 aValue
->SetRadian(aCoord
.GetAngleValue());
4700 case eStyleUnit_Turn
:
4701 aValue
->SetTurn(aCoord
.GetAngleValue());
4704 case eStyleUnit_FlexFraction
: {
4705 nsAutoString tmpStr
;
4706 nsStyleUtil::AppendCSSNumber(aCoord
.GetFlexFractionValue(), tmpStr
);
4707 tmpStr
.AppendLiteral("fr");
4708 aValue
->SetString(tmpStr
);
4713 NS_ERROR("Can't handle this unit");
4719 nsComputedDOMStyle::StyleCoordToNSCoord(const nsStyleCoord
& aCoord
,
4720 PercentageBaseGetter aPercentageBaseGetter
,
4721 nscoord aDefaultValue
,
4722 bool aClampNegativeCalc
)
4724 NS_PRECONDITION(aPercentageBaseGetter
, "Must have a percentage base getter");
4725 if (aCoord
.GetUnit() == eStyleUnit_Coord
) {
4726 return aCoord
.GetCoordValue();
4728 if (aCoord
.GetUnit() == eStyleUnit_Percent
|| aCoord
.IsCalcUnit()) {
4729 nscoord percentageBase
;
4730 if ((this->*aPercentageBaseGetter
)(percentageBase
)) {
4732 nsRuleNode::ComputeCoordPercentCalc(aCoord
, percentageBase
);
4733 if (aClampNegativeCalc
&& result
< 0) {
4734 NS_ABORT_IF_FALSE(aCoord
.IsCalcUnit(),
4735 "parser should have rejected value");
4740 // Fall through to returning aDefaultValue if we have no percentage base.
4743 return aDefaultValue
;
4747 nsComputedDOMStyle::GetCBContentWidth(nscoord
& aWidth
)
4753 AssertFlushedPendingReflows();
4755 nsIFrame
* container
= mOuterFrame
->GetContainingBlock();
4756 aWidth
= container
->GetContentRect().width
;
4761 nsComputedDOMStyle::GetCBContentHeight(nscoord
& aHeight
)
4767 AssertFlushedPendingReflows();
4769 nsIFrame
* container
= mOuterFrame
->GetContainingBlock();
4770 aHeight
= container
->GetContentRect().height
;
4775 nsComputedDOMStyle::GetScrollFrameContentWidth(nscoord
& aWidth
)
4781 AssertFlushedPendingReflows();
4783 nsIScrollableFrame
* scrollableFrame
=
4784 nsLayoutUtils::GetNearestScrollableFrame(mOuterFrame
->GetParent(),
4785 nsLayoutUtils::SCROLLABLE_SAME_DOC
|
4786 nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN
);
4788 if (!scrollableFrame
) {
4792 scrollableFrame
->GetScrolledFrame()->GetContentRectRelativeToSelf().width
;
4797 nsComputedDOMStyle::GetScrollFrameContentHeight(nscoord
& aHeight
)
4803 AssertFlushedPendingReflows();
4805 nsIScrollableFrame
* scrollableFrame
=
4806 nsLayoutUtils::GetNearestScrollableFrame(mOuterFrame
->GetParent(),
4807 nsLayoutUtils::SCROLLABLE_SAME_DOC
|
4808 nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN
);
4810 if (!scrollableFrame
) {
4814 scrollableFrame
->GetScrolledFrame()->GetContentRectRelativeToSelf().height
;
4819 nsComputedDOMStyle::GetFrameBorderRectWidth(nscoord
& aWidth
)
4825 AssertFlushedPendingReflows();
4827 aWidth
= mInnerFrame
->GetSize().width
;
4832 nsComputedDOMStyle::GetFrameBorderRectHeight(nscoord
& aHeight
)
4838 AssertFlushedPendingReflows();
4840 aHeight
= mInnerFrame
->GetSize().height
;
4845 nsComputedDOMStyle::GetFrameBoundsWidthForTransform(nscoord
& aWidth
)
4847 // We need a frame to work with.
4852 AssertFlushedPendingReflows();
4854 aWidth
= nsDisplayTransform::GetFrameBoundsForTransform(mInnerFrame
).width
;
4859 nsComputedDOMStyle::GetFrameBoundsHeightForTransform(nscoord
& aHeight
)
4861 // We need a frame to work with.
4866 AssertFlushedPendingReflows();
4868 aHeight
= nsDisplayTransform::GetFrameBoundsForTransform(mInnerFrame
).height
;
4873 nsComputedDOMStyle::GetSVGPaintFor(bool aFill
)
4875 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
4877 const nsStyleSVG
* svg
= StyleSVG();
4878 const nsStyleSVGPaint
* paint
= nullptr;
4881 paint
= &svg
->mFill
;
4883 paint
= &svg
->mStroke
;
4885 nsAutoString paintString
;
4887 switch (paint
->mType
) {
4888 case eStyleSVGPaintType_None
:
4890 val
->SetIdent(eCSSKeyword_none
);
4893 case eStyleSVGPaintType_Color
:
4895 SetToRGBAColor(val
, paint
->mPaint
.mColor
);
4898 case eStyleSVGPaintType_Server
:
4900 nsDOMCSSValueList
*valueList
= GetROCSSValueList(false);
4901 valueList
->AppendCSSValue(val
);
4903 nsROCSSPrimitiveValue
* fallback
= new nsROCSSPrimitiveValue
;
4904 valueList
->AppendCSSValue(fallback
);
4906 val
->SetURI(paint
->mPaint
.mPaintServer
);
4907 SetToRGBAColor(fallback
, paint
->mFallbackColor
);
4910 case eStyleSVGPaintType_ContextFill
:
4912 val
->SetIdent(eCSSKeyword_context_fill
);
4915 case eStyleSVGPaintType_ContextStroke
:
4917 val
->SetIdent(eCSSKeyword_context_stroke
);
4926 nsComputedDOMStyle::DoGetFill()
4928 return GetSVGPaintFor(true);
4932 nsComputedDOMStyle::DoGetStroke()
4934 return GetSVGPaintFor(false);
4938 nsComputedDOMStyle::DoGetMarkerEnd()
4940 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
4942 const nsStyleSVG
* svg
= StyleSVG();
4944 if (svg
->mMarkerEnd
)
4945 val
->SetURI(svg
->mMarkerEnd
);
4947 val
->SetIdent(eCSSKeyword_none
);
4953 nsComputedDOMStyle::DoGetMarkerMid()
4955 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
4957 const nsStyleSVG
* svg
= StyleSVG();
4959 if (svg
->mMarkerMid
)
4960 val
->SetURI(svg
->mMarkerMid
);
4962 val
->SetIdent(eCSSKeyword_none
);
4968 nsComputedDOMStyle::DoGetMarkerStart()
4970 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
4972 const nsStyleSVG
* svg
= StyleSVG();
4974 if (svg
->mMarkerStart
)
4975 val
->SetURI(svg
->mMarkerStart
);
4977 val
->SetIdent(eCSSKeyword_none
);
4983 nsComputedDOMStyle::DoGetStrokeDasharray()
4985 const nsStyleSVG
* svg
= StyleSVG();
4987 if (!svg
->mStrokeDasharrayLength
|| !svg
->mStrokeDasharray
) {
4988 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
4989 val
->SetIdent(eCSSKeyword_none
);
4993 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
4995 for (uint32_t i
= 0; i
< svg
->mStrokeDasharrayLength
; i
++) {
4996 nsROCSSPrimitiveValue
* dash
= new nsROCSSPrimitiveValue
;
4997 valueList
->AppendCSSValue(dash
);
4999 SetValueToCoord(dash
, svg
->mStrokeDasharray
[i
], true);
5006 nsComputedDOMStyle::DoGetStrokeDashoffset()
5008 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
5009 SetValueToCoord(val
, StyleSVG()->mStrokeDashoffset
, false);
5014 nsComputedDOMStyle::DoGetStrokeWidth()
5016 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
5017 SetValueToCoord(val
, StyleSVG()->mStrokeWidth
, true);
5022 nsComputedDOMStyle::DoGetVectorEffect()
5024 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5025 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleSVGReset()->mVectorEffect
,
5026 nsCSSProps::kVectorEffectKTable
));
5031 nsComputedDOMStyle::DoGetFillOpacity()
5033 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5034 val
->SetNumber(StyleSVG()->mFillOpacity
);
5039 nsComputedDOMStyle::DoGetFloodOpacity()
5041 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5042 val
->SetNumber(StyleSVGReset()->mFloodOpacity
);
5047 nsComputedDOMStyle::DoGetStopOpacity()
5049 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5050 val
->SetNumber(StyleSVGReset()->mStopOpacity
);
5055 nsComputedDOMStyle::DoGetStrokeMiterlimit()
5057 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5058 val
->SetNumber(StyleSVG()->mStrokeMiterlimit
);
5063 nsComputedDOMStyle::DoGetStrokeOpacity()
5065 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5066 val
->SetNumber(StyleSVG()->mStrokeOpacity
);
5071 nsComputedDOMStyle::DoGetClipRule()
5073 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5074 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(
5075 StyleSVG()->mClipRule
, nsCSSProps::kFillRuleKTable
));
5080 nsComputedDOMStyle::DoGetFillRule()
5082 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5083 val
->SetIdent(nsCSSProps::ValueToKeywordEnum(
5084 StyleSVG()->mFillRule
, nsCSSProps::kFillRuleKTable
));
5089 nsComputedDOMStyle::DoGetStrokeLinecap()
5091 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5093 nsCSSProps::ValueToKeywordEnum(StyleSVG()->mStrokeLinecap
,
5094 nsCSSProps::kStrokeLinecapKTable
));
5099 nsComputedDOMStyle::DoGetStrokeLinejoin()
5101 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5103 nsCSSProps::ValueToKeywordEnum(StyleSVG()->mStrokeLinejoin
,
5104 nsCSSProps::kStrokeLinejoinKTable
));
5109 nsComputedDOMStyle::DoGetTextAnchor()
5111 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5113 nsCSSProps::ValueToKeywordEnum(StyleSVG()->mTextAnchor
,
5114 nsCSSProps::kTextAnchorKTable
));
5119 nsComputedDOMStyle::DoGetColorInterpolation()
5121 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5123 nsCSSProps::ValueToKeywordEnum(StyleSVG()->mColorInterpolation
,
5124 nsCSSProps::kColorInterpolationKTable
));
5129 nsComputedDOMStyle::DoGetColorInterpolationFilters()
5131 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5133 nsCSSProps::ValueToKeywordEnum(StyleSVG()->mColorInterpolationFilters
,
5134 nsCSSProps::kColorInterpolationKTable
));
5139 nsComputedDOMStyle::DoGetDominantBaseline()
5141 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5143 nsCSSProps::ValueToKeywordEnum(StyleSVGReset()->mDominantBaseline
,
5144 nsCSSProps::kDominantBaselineKTable
));
5149 nsComputedDOMStyle::DoGetImageRendering()
5151 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5153 nsCSSProps::ValueToKeywordEnum(StyleSVG()->mImageRendering
,
5154 nsCSSProps::kImageRenderingKTable
));
5159 nsComputedDOMStyle::DoGetShapeRendering()
5161 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5163 nsCSSProps::ValueToKeywordEnum(StyleSVG()->mShapeRendering
,
5164 nsCSSProps::kShapeRenderingKTable
));
5169 nsComputedDOMStyle::DoGetTextRendering()
5171 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5173 nsCSSProps::ValueToKeywordEnum(StyleSVG()->mTextRendering
,
5174 nsCSSProps::kTextRenderingKTable
));
5179 nsComputedDOMStyle::DoGetFloodColor()
5181 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5182 SetToRGBAColor(val
, StyleSVGReset()->mFloodColor
);
5187 nsComputedDOMStyle::DoGetLightingColor()
5189 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5190 SetToRGBAColor(val
, StyleSVGReset()->mLightingColor
);
5195 nsComputedDOMStyle::DoGetStopColor()
5197 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5198 SetToRGBAColor(val
, StyleSVGReset()->mStopColor
);
5202 inline void AppendBasicShapeTypeToString(nsStyleBasicShape::Type aType
,
5203 nsAutoString
& aString
)
5205 nsCSSKeyword functionName
;
5207 case nsStyleBasicShape::Type::ePolygon
:
5208 functionName
= eCSSKeyword_polygon
;
5210 case nsStyleBasicShape::Type::eCircle
:
5211 functionName
= eCSSKeyword_circle
;
5213 case nsStyleBasicShape::Type::eEllipse
:
5214 functionName
= eCSSKeyword_ellipse
;
5216 case nsStyleBasicShape::Type::eInset
:
5217 functionName
= eCSSKeyword_inset
;
5220 functionName
= eCSSKeyword_UNKNOWN
;
5221 NS_NOTREACHED("unexpected type");
5223 AppendASCIItoUTF16(nsCSSKeywords::GetStringValue(functionName
),
5228 nsComputedDOMStyle::BoxValuesToString(nsAString
& aString
,
5229 const nsTArray
<nsStyleCoord
>& aBoxValues
)
5231 NS_ABORT_IF_FALSE(aBoxValues
.Length() == 4, "wrong number of box values");
5232 nsAutoString value1
, value2
, value3
, value4
;
5233 SetCssTextToCoord(value1
, aBoxValues
[0]);
5234 SetCssTextToCoord(value2
, aBoxValues
[1]);
5235 SetCssTextToCoord(value3
, aBoxValues
[2]);
5236 SetCssTextToCoord(value4
, aBoxValues
[3]);
5238 // nsROCSSPrimitiveValue do not have binary comparison operators.
5239 // Compare string results instead.
5240 aString
.Append(value1
);
5241 if (value1
!= value2
|| value1
!= value3
|| value1
!= value4
) {
5242 aString
.Append(' ');
5243 aString
.Append(value2
);
5244 if (value1
!= value3
|| value2
!= value4
) {
5245 aString
.Append(' ');
5246 aString
.Append(value3
);
5247 if (value2
!= value4
) {
5248 aString
.Append(' ');
5249 aString
.Append(value4
);
5256 nsComputedDOMStyle::BasicShapeRadiiToString(nsAString
& aCssText
,
5257 const nsStyleCorners
& aCorners
)
5259 nsTArray
<nsStyleCoord
> horizontal
, vertical
;
5260 nsAutoString horizontalString
, verticalString
;
5261 NS_FOR_CSS_FULL_CORNERS(corner
) {
5262 horizontal
.AppendElement(
5263 aCorners
.Get(NS_FULL_TO_HALF_CORNER(corner
, false)));
5264 vertical
.AppendElement(
5265 aCorners
.Get(NS_FULL_TO_HALF_CORNER(corner
, true)));
5267 BoxValuesToString(horizontalString
, horizontal
);
5268 BoxValuesToString(verticalString
, vertical
);
5269 aCssText
.Append(horizontalString
);
5270 if (horizontalString
== verticalString
) {
5273 aCssText
.AppendLiteral(" / ");
5274 aCssText
.Append(verticalString
);
5278 nsComputedDOMStyle::CreatePrimitiveValueForClipPath(
5279 const nsStyleBasicShape
* aStyleBasicShape
, uint8_t aSizingBox
)
5281 nsDOMCSSValueList
* valueList
= GetROCSSValueList(false);
5282 if (aStyleBasicShape
) {
5283 nsStyleBasicShape::Type type
= aStyleBasicShape
->GetShapeType();
5284 // Shape function name and opening parenthesis.
5285 nsAutoString shapeFunctionString
;
5286 AppendBasicShapeTypeToString(type
, shapeFunctionString
);
5287 shapeFunctionString
.Append('(');
5289 case nsStyleBasicShape::Type::ePolygon
: {
5290 bool hasEvenOdd
= aStyleBasicShape
->GetFillRule() ==
5291 NS_STYLE_FILL_RULE_EVENODD
;
5293 shapeFunctionString
.AppendLiteral("evenodd");
5296 i
< aStyleBasicShape
->Coordinates().Length(); i
+= 2) {
5297 nsAutoString coordString
;
5298 if (i
> 0 || hasEvenOdd
) {
5299 shapeFunctionString
.AppendLiteral(", ");
5301 SetCssTextToCoord(coordString
,
5302 aStyleBasicShape
->Coordinates()[i
]);
5303 shapeFunctionString
.Append(coordString
);
5304 shapeFunctionString
.Append(' ');
5305 SetCssTextToCoord(coordString
,
5306 aStyleBasicShape
->Coordinates()[i
+ 1]);
5307 shapeFunctionString
.Append(coordString
);
5311 case nsStyleBasicShape::Type::eCircle
:
5312 case nsStyleBasicShape::Type::eEllipse
: {
5313 const nsTArray
<nsStyleCoord
>& radii
= aStyleBasicShape
->Coordinates();
5314 NS_ABORT_IF_FALSE(radii
.Length() ==
5315 (nsStyleBasicShape::Type::eCircle
? 1 : 2),
5316 "wrong number of radii");
5317 for (size_t i
= 0; i
< radii
.Length(); ++i
) {
5318 nsAutoString radius
;
5319 nsRefPtr
<nsROCSSPrimitiveValue
> value
= new nsROCSSPrimitiveValue
;
5320 bool clampNegativeCalc
= true;
5321 SetValueToCoord(value
, radii
[i
], clampNegativeCalc
, nullptr,
5322 nsCSSProps::kShapeRadiusKTable
);
5323 value
->GetCssText(radius
);
5324 shapeFunctionString
.Append(radius
);
5325 shapeFunctionString
.Append(' ');
5327 shapeFunctionString
.AppendLiteral("at ");
5329 nsRefPtr
<nsDOMCSSValueList
> position
= GetROCSSValueList(false);
5330 nsAutoString positionString
;
5331 SetValueToPosition(aStyleBasicShape
->GetPosition(), position
);
5332 position
->GetCssText(positionString
);
5333 shapeFunctionString
.Append(positionString
);
5336 case nsStyleBasicShape::Type::eInset
: {
5337 BoxValuesToString(shapeFunctionString
, aStyleBasicShape
->Coordinates());
5338 if (aStyleBasicShape
->HasRadius()) {
5339 shapeFunctionString
.AppendLiteral(" round ");
5340 nsAutoString radiiString
;
5341 BasicShapeRadiiToString(radiiString
, aStyleBasicShape
->GetRadius());
5342 shapeFunctionString
.Append(radiiString
);
5347 NS_NOTREACHED("unexpected type");
5349 shapeFunctionString
.Append(')');
5350 nsROCSSPrimitiveValue
* functionValue
= new nsROCSSPrimitiveValue
;
5351 functionValue
->SetString(shapeFunctionString
);
5352 valueList
->AppendCSSValue(functionValue
);
5355 if (aSizingBox
== NS_STYLE_CLIP_SHAPE_SIZING_NOBOX
) {
5359 nsAutoString boxString
;
5361 nsCSSProps::ValueToKeyword(aSizingBox
,
5362 nsCSSProps::kClipShapeSizingKTable
),
5364 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
5365 val
->SetString(boxString
);
5366 valueList
->AppendCSSValue(val
);
5372 nsComputedDOMStyle::DoGetClipPath()
5374 const nsStyleSVGReset
* svg
= StyleSVGReset();
5375 switch (svg
->mClipPath
.GetType()) {
5376 case NS_STYLE_CLIP_PATH_SHAPE
:
5377 return CreatePrimitiveValueForClipPath(svg
->mClipPath
.GetBasicShape(),
5378 svg
->mClipPath
.GetSizingBox());
5379 case NS_STYLE_CLIP_PATH_BOX
:
5380 return CreatePrimitiveValueForClipPath(nullptr,
5381 svg
->mClipPath
.GetSizingBox());
5382 case NS_STYLE_CLIP_PATH_URL
: {
5383 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
5384 val
->SetURI(svg
->mClipPath
.GetURL());
5387 case NS_STYLE_CLIP_PATH_NONE
: {
5388 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
5389 val
->SetIdent(eCSSKeyword_none
);
5393 NS_NOTREACHED("unexpected type");
5399 nsComputedDOMStyle::SetCssTextToCoord(nsAString
& aCssText
,
5400 const nsStyleCoord
& aCoord
)
5402 nsRefPtr
<nsROCSSPrimitiveValue
> value
= new nsROCSSPrimitiveValue
;
5403 bool clampNegativeCalc
= true;
5404 SetValueToCoord(value
, aCoord
, clampNegativeCalc
);
5405 value
->GetCssText(aCssText
);
5409 nsComputedDOMStyle::CreatePrimitiveValueForStyleFilter(
5410 const nsStyleFilter
& aStyleFilter
)
5412 nsROCSSPrimitiveValue
* value
= new nsROCSSPrimitiveValue
;
5414 if (aStyleFilter
.GetType() == NS_STYLE_FILTER_URL
) {
5415 value
->SetURI(aStyleFilter
.GetURL());
5419 // Filter function name and opening parenthesis.
5420 nsAutoString filterFunctionString
;
5422 nsCSSProps::ValueToKeyword(aStyleFilter
.GetType(),
5423 nsCSSProps::kFilterFunctionKTable
),
5424 filterFunctionString
);
5425 filterFunctionString
.Append('(');
5427 nsAutoString argumentString
;
5428 if (aStyleFilter
.GetType() == NS_STYLE_FILTER_DROP_SHADOW
) {
5429 // Handle drop-shadow()
5430 nsRefPtr
<CSSValue
> shadowValue
=
5431 GetCSSShadowArray(aStyleFilter
.GetDropShadow(),
5432 StyleColor()->mColor
,
5435 shadowValue
->GetCssText(argumentString
, dummy
);
5437 // Filter function argument.
5438 SetCssTextToCoord(argumentString
, aStyleFilter
.GetFilterParameter());
5440 filterFunctionString
.Append(argumentString
);
5442 // Filter function closing parenthesis.
5443 filterFunctionString
.Append(')');
5445 value
->SetString(filterFunctionString
);
5450 nsComputedDOMStyle::DoGetFilter()
5452 const nsTArray
<nsStyleFilter
>& filters
= StyleSVGReset()->mFilters
;
5454 if (filters
.IsEmpty()) {
5455 nsROCSSPrimitiveValue
* value
= new nsROCSSPrimitiveValue
;
5456 value
->SetIdent(eCSSKeyword_none
);
5460 nsDOMCSSValueList
* valueList
= GetROCSSValueList(false);
5461 for(uint32_t i
= 0; i
< filters
.Length(); i
++) {
5462 CSSValue
* value
= CreatePrimitiveValueForStyleFilter(filters
[i
]);
5463 valueList
->AppendCSSValue(value
);
5469 nsComputedDOMStyle::DoGetMask()
5471 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
5473 const nsStyleSVGReset
* svg
= StyleSVGReset();
5476 val
->SetURI(svg
->mMask
);
5478 val
->SetIdent(eCSSKeyword_none
);
5484 nsComputedDOMStyle::DoGetMaskType()
5486 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5488 nsCSSProps::ValueToKeywordEnum(StyleSVGReset()->mMaskType
,
5489 nsCSSProps::kMaskTypeKTable
));
5494 nsComputedDOMStyle::DoGetPaintOrder()
5496 nsROCSSPrimitiveValue
*val
= new nsROCSSPrimitiveValue
;
5497 nsAutoString string
;
5498 uint8_t paintOrder
= StyleSVG()->mPaintOrder
;
5499 nsStyleUtil::AppendPaintOrderValue(paintOrder
, string
);
5500 val
->SetString(string
);
5505 nsComputedDOMStyle::DoGetTransitionDelay()
5507 const nsStyleDisplay
* display
= StyleDisplay();
5509 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
5511 NS_ABORT_IF_FALSE(display
->mTransitionDelayCount
> 0,
5512 "first item must be explicit");
5515 const StyleTransition
*transition
= &display
->mTransitions
[i
];
5516 nsROCSSPrimitiveValue
* delay
= new nsROCSSPrimitiveValue
;
5517 valueList
->AppendCSSValue(delay
);
5518 delay
->SetTime((float)transition
->GetDelay() / (float)PR_MSEC_PER_SEC
);
5519 } while (++i
< display
->mTransitionDelayCount
);
5525 nsComputedDOMStyle::DoGetTransitionDuration()
5527 const nsStyleDisplay
* display
= StyleDisplay();
5529 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
5531 NS_ABORT_IF_FALSE(display
->mTransitionDurationCount
> 0,
5532 "first item must be explicit");
5535 const StyleTransition
*transition
= &display
->mTransitions
[i
];
5536 nsROCSSPrimitiveValue
* duration
= new nsROCSSPrimitiveValue
;
5537 valueList
->AppendCSSValue(duration
);
5539 duration
->SetTime((float)transition
->GetDuration() / (float)PR_MSEC_PER_SEC
);
5540 } while (++i
< display
->mTransitionDurationCount
);
5546 nsComputedDOMStyle::DoGetTransitionProperty()
5548 const nsStyleDisplay
* display
= StyleDisplay();
5550 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
5552 NS_ABORT_IF_FALSE(display
->mTransitionPropertyCount
> 0,
5553 "first item must be explicit");
5556 const StyleTransition
*transition
= &display
->mTransitions
[i
];
5557 nsROCSSPrimitiveValue
* property
= new nsROCSSPrimitiveValue
;
5558 valueList
->AppendCSSValue(property
);
5559 nsCSSProperty cssprop
= transition
->GetProperty();
5560 if (cssprop
== eCSSPropertyExtra_all_properties
)
5561 property
->SetIdent(eCSSKeyword_all
);
5562 else if (cssprop
== eCSSPropertyExtra_no_properties
)
5563 property
->SetIdent(eCSSKeyword_none
);
5564 else if (cssprop
== eCSSProperty_UNKNOWN
)
5566 nsAutoString escaped
;
5567 nsStyleUtil::AppendEscapedCSSIdent(
5568 nsDependentAtomString(transition
->GetUnknownProperty()), escaped
);
5569 property
->SetString(escaped
); // really want SetIdent
5572 property
->SetString(nsCSSProps::GetStringValue(cssprop
));
5573 } while (++i
< display
->mTransitionPropertyCount
);
5579 nsComputedDOMStyle::AppendTimingFunction(nsDOMCSSValueList
*aValueList
,
5580 const nsTimingFunction
& aTimingFunction
)
5582 nsROCSSPrimitiveValue
* timingFunction
= new nsROCSSPrimitiveValue
;
5583 aValueList
->AppendCSSValue(timingFunction
);
5587 if (aTimingFunction
.mType
== nsTimingFunction::Function
) {
5588 // set the value from the cubic-bezier control points
5589 // (We could try to regenerate the keywords if we want.)
5590 tmp
.AppendLiteral("cubic-bezier(");
5591 tmp
.AppendFloat(aTimingFunction
.mFunc
.mX1
);
5592 tmp
.AppendLiteral(", ");
5593 tmp
.AppendFloat(aTimingFunction
.mFunc
.mY1
);
5594 tmp
.AppendLiteral(", ");
5595 tmp
.AppendFloat(aTimingFunction
.mFunc
.mX2
);
5596 tmp
.AppendLiteral(", ");
5597 tmp
.AppendFloat(aTimingFunction
.mFunc
.mY2
);
5600 tmp
.AppendLiteral("steps(");
5601 tmp
.AppendInt(aTimingFunction
.mSteps
);
5602 if (aTimingFunction
.mType
== nsTimingFunction::StepStart
) {
5603 tmp
.AppendLiteral(", start)");
5605 tmp
.AppendLiteral(", end)");
5608 timingFunction
->SetString(tmp
);
5612 nsComputedDOMStyle::DoGetTransitionTimingFunction()
5614 const nsStyleDisplay
* display
= StyleDisplay();
5616 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
5618 NS_ABORT_IF_FALSE(display
->mTransitionTimingFunctionCount
> 0,
5619 "first item must be explicit");
5622 AppendTimingFunction(valueList
,
5623 display
->mTransitions
[i
].GetTimingFunction());
5624 } while (++i
< display
->mTransitionTimingFunctionCount
);
5630 nsComputedDOMStyle::DoGetAnimationName()
5632 const nsStyleDisplay
* display
= StyleDisplay();
5634 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
5636 NS_ABORT_IF_FALSE(display
->mAnimationNameCount
> 0,
5637 "first item must be explicit");
5640 const StyleAnimation
*animation
= &display
->mAnimations
[i
];
5641 nsROCSSPrimitiveValue
* property
= new nsROCSSPrimitiveValue
;
5642 valueList
->AppendCSSValue(property
);
5644 const nsString
& name
= animation
->GetName();
5645 if (name
.IsEmpty()) {
5646 property
->SetIdent(eCSSKeyword_none
);
5648 nsAutoString escaped
;
5649 nsStyleUtil::AppendEscapedCSSIdent(animation
->GetName(), escaped
);
5650 property
->SetString(escaped
); // really want SetIdent
5652 } while (++i
< display
->mAnimationNameCount
);
5658 nsComputedDOMStyle::DoGetAnimationDelay()
5660 const nsStyleDisplay
* display
= StyleDisplay();
5662 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
5664 NS_ABORT_IF_FALSE(display
->mAnimationDelayCount
> 0,
5665 "first item must be explicit");
5668 const StyleAnimation
*animation
= &display
->mAnimations
[i
];
5669 nsROCSSPrimitiveValue
* delay
= new nsROCSSPrimitiveValue
;
5670 valueList
->AppendCSSValue(delay
);
5671 delay
->SetTime((float)animation
->GetDelay() / (float)PR_MSEC_PER_SEC
);
5672 } while (++i
< display
->mAnimationDelayCount
);
5678 nsComputedDOMStyle::DoGetAnimationDuration()
5680 const nsStyleDisplay
* display
= StyleDisplay();
5682 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
5684 NS_ABORT_IF_FALSE(display
->mAnimationDurationCount
> 0,
5685 "first item must be explicit");
5688 const StyleAnimation
*animation
= &display
->mAnimations
[i
];
5689 nsROCSSPrimitiveValue
* duration
= new nsROCSSPrimitiveValue
;
5690 valueList
->AppendCSSValue(duration
);
5692 duration
->SetTime((float)animation
->GetDuration() / (float)PR_MSEC_PER_SEC
);
5693 } while (++i
< display
->mAnimationDurationCount
);
5699 nsComputedDOMStyle::DoGetAnimationTimingFunction()
5701 const nsStyleDisplay
* display
= StyleDisplay();
5703 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
5705 NS_ABORT_IF_FALSE(display
->mAnimationTimingFunctionCount
> 0,
5706 "first item must be explicit");
5709 AppendTimingFunction(valueList
,
5710 display
->mAnimations
[i
].GetTimingFunction());
5711 } while (++i
< display
->mAnimationTimingFunctionCount
);
5717 nsComputedDOMStyle::DoGetAnimationDirection()
5719 const nsStyleDisplay
* display
= StyleDisplay();
5721 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
5723 NS_ABORT_IF_FALSE(display
->mAnimationDirectionCount
> 0,
5724 "first item must be explicit");
5727 const StyleAnimation
*animation
= &display
->mAnimations
[i
];
5728 nsROCSSPrimitiveValue
* direction
= new nsROCSSPrimitiveValue
;
5729 valueList
->AppendCSSValue(direction
);
5730 direction
->SetIdent(
5731 nsCSSProps::ValueToKeywordEnum(animation
->GetDirection(),
5732 nsCSSProps::kAnimationDirectionKTable
));
5733 } while (++i
< display
->mAnimationDirectionCount
);
5739 nsComputedDOMStyle::DoGetAnimationFillMode()
5741 const nsStyleDisplay
* display
= StyleDisplay();
5743 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
5745 NS_ABORT_IF_FALSE(display
->mAnimationFillModeCount
> 0,
5746 "first item must be explicit");
5749 const StyleAnimation
*animation
= &display
->mAnimations
[i
];
5750 nsROCSSPrimitiveValue
* fillMode
= new nsROCSSPrimitiveValue
;
5751 valueList
->AppendCSSValue(fillMode
);
5753 nsCSSProps::ValueToKeywordEnum(animation
->GetFillMode(),
5754 nsCSSProps::kAnimationFillModeKTable
));
5755 } while (++i
< display
->mAnimationFillModeCount
);
5761 nsComputedDOMStyle::DoGetAnimationIterationCount()
5763 const nsStyleDisplay
* display
= StyleDisplay();
5765 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
5767 NS_ABORT_IF_FALSE(display
->mAnimationIterationCountCount
> 0,
5768 "first item must be explicit");
5771 const StyleAnimation
*animation
= &display
->mAnimations
[i
];
5772 nsROCSSPrimitiveValue
* iterationCount
= new nsROCSSPrimitiveValue
;
5773 valueList
->AppendCSSValue(iterationCount
);
5775 float f
= animation
->GetIterationCount();
5776 /* Need a nasty hack here to work around an optimizer bug in gcc
5777 4.2 on Mac, which somehow gets confused when directly comparing
5778 a float to the return value of NS_IEEEPositiveInfinity when
5779 building 32-bit builds. */
5783 float inf
= NS_IEEEPositiveInfinity();
5785 iterationCount
->SetIdent(eCSSKeyword_infinite
);
5787 iterationCount
->SetNumber(f
);
5789 } while (++i
< display
->mAnimationIterationCountCount
);
5795 nsComputedDOMStyle::DoGetAnimationPlayState()
5797 const nsStyleDisplay
* display
= StyleDisplay();
5799 nsDOMCSSValueList
*valueList
= GetROCSSValueList(true);
5801 NS_ABORT_IF_FALSE(display
->mAnimationPlayStateCount
> 0,
5802 "first item must be explicit");
5805 const StyleAnimation
*animation
= &display
->mAnimations
[i
];
5806 nsROCSSPrimitiveValue
* playState
= new nsROCSSPrimitiveValue
;
5807 valueList
->AppendCSSValue(playState
);
5808 playState
->SetIdent(
5809 nsCSSProps::ValueToKeywordEnum(animation
->GetPlayState(),
5810 nsCSSProps::kAnimationPlayStateKTable
));
5811 } while (++i
< display
->mAnimationPlayStateCount
);
5817 MarkComputedStyleMapDirty(const char* aPref
, void* aData
)
5819 static_cast<nsComputedStyleMap
*>(aData
)->MarkDirty();
5823 nsComputedDOMStyle::DoGetCustomProperty(const nsAString
& aPropertyName
)
5825 MOZ_ASSERT(nsCSSProps::IsCustomPropertyName(aPropertyName
));
5827 const nsStyleVariables
* variables
= StyleVariables();
5829 nsString variableValue
;
5830 const nsAString
& name
= Substring(aPropertyName
,
5831 CSS_CUSTOM_NAME_PREFIX_LENGTH
);
5832 if (!variables
->mVariables
.Get(name
, variableValue
)) {
5836 nsROCSSPrimitiveValue
* val
= new nsROCSSPrimitiveValue
;
5837 val
->SetString(variableValue
);
5842 /* static */ nsComputedStyleMap
*
5843 nsComputedDOMStyle::GetComputedStyleMap()
5845 static nsComputedStyleMap map
= {
5847 #define COMPUTED_STYLE_PROP(prop_, method_) \
5848 { eCSSProperty_##prop_, &nsComputedDOMStyle::DoGet##method_ },
5849 #include "nsComputedDOMStylePropertyList.h"
5850 #undef COMPUTED_STYLE_PROP
5857 nsComputedDOMStyle::RegisterPrefChangeCallbacks()
5859 // Note that this will register callbacks for all properties with prefs, not
5860 // just those that are implemented on computed style objects, as it's not
5861 // easy to grab specific property data from nsCSSPropList.h based on the
5862 // entries iterated in nsComputedDOMStylePropertyList.h.
5863 nsComputedStyleMap
* data
= GetComputedStyleMap();
5864 #define REGISTER_CALLBACK(pref_) \
5866 Preferences::RegisterCallback(MarkComputedStyleMapDirty, pref_, data); \
5868 #define CSS_PROP(prop_, id_, method_, flags_, pref_, parsevariant_, \
5869 kwtable_, stylestruct_, stylestructoffset_, animtype_) \
5870 REGISTER_CALLBACK(pref_)
5871 #include "nsCSSPropList.h"
5873 #undef REGISTER_CALLBACK
5877 nsComputedDOMStyle::UnregisterPrefChangeCallbacks()
5879 nsComputedStyleMap
* data
= GetComputedStyleMap();
5880 #define UNREGISTER_CALLBACK(pref_) \
5882 Preferences::UnregisterCallback(MarkComputedStyleMapDirty, pref_, data); \
5884 #define CSS_PROP(prop_, id_, method_, flags_, pref_, parsevariant_, \
5885 kwtable_, stylestruct_, stylestructoffset_, animtype_) \
5886 UNREGISTER_CALLBACK(pref_)
5887 #include "nsCSSPropList.h"
5889 #undef UNREGISTER_CALLBACK