1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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 #ifndef nsComputedDOMStyle_h__
10 #define nsComputedDOMStyle_h__
12 #include "mozilla/Attributes.h"
13 #include "mozilla/StyleColorInlines.h"
14 #include "mozilla/UniquePtr.h"
16 #include "nsContentUtils.h"
18 #include "nsDOMCSSDeclaration.h"
19 #include "mozilla/ComputedStyle.h"
20 #include "nsIWeakReferenceUtils.h"
21 #include "mozilla/gfx/Types.h"
24 #include "nsStubMutationObserver.h"
25 #include "nsStyleStruct.h"
26 #include "mozilla/WritingModes.h"
28 // XXX Avoid including this here by moving function bodies to the cpp file
29 #include "mozilla/dom/Element.h"
32 enum class FlushType
: uint8_t;
39 struct ComputedGridTrackInfo
;
40 } // namespace mozilla
42 struct ComputedStyleMap
;
43 struct nsCSSKTableEntry
;
45 class nsDOMCSSValueList
;
47 class nsROCSSPrimitiveValue
;
48 class nsStyleGradient
;
50 class nsComputedDOMStyle final
: public nsDOMCSSDeclaration
,
51 public nsStubMutationObserver
{
53 // Convenience typedefs:
55 using Span
= mozilla::Span
<T
>;
56 using KTableEntry
= nsCSSKTableEntry
;
57 using CSSValue
= mozilla::dom::CSSValue
;
58 using StyleGeometryBox
= mozilla::StyleGeometryBox
;
59 using Element
= mozilla::dom::Element
;
60 using Document
= mozilla::dom::Document
;
61 using LengthPercentage
= mozilla::LengthPercentage
;
62 using LengthPercentageOrAuto
= mozilla::LengthPercentageOrAuto
;
63 using ComputedStyle
= mozilla::ComputedStyle
;
66 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
67 NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(
68 nsComputedDOMStyle
, nsICSSDeclaration
)
70 NS_DECL_NSIDOMCSSSTYLEDECLARATION_HELPER
71 nsresult
GetPropertyValue(const nsCSSPropertyID aPropID
,
72 nsACString
& aValue
) override
;
73 void SetPropertyValue(const nsCSSPropertyID aPropID
, const nsACString
& aValue
,
74 nsIPrincipal
* aSubjectPrincipal
,
75 mozilla::ErrorResult
& aRv
) override
;
77 void IndexedGetter(uint32_t aIndex
, bool& aFound
,
78 nsACString
& aPropName
) final
;
81 eDefaultOnly
, // Only includes UA and user sheets
82 eAll
// Includes all stylesheets
85 nsComputedDOMStyle(Element
* aElement
, const nsAString
& aPseudoElt
,
86 Document
* aDocument
, StyleType aStyleType
);
88 nsINode
* GetAssociatedNode() const override
{ return mElement
; }
89 nsINode
* GetParentObject() const override
{ return mElement
; }
91 static already_AddRefed
<ComputedStyle
> GetComputedStyle(
92 Element
* aElement
, nsAtom
* aPseudo
, StyleType aStyleType
= eAll
);
94 static already_AddRefed
<ComputedStyle
> GetComputedStyleNoFlush(
95 const Element
* aElement
, nsAtom
* aPseudo
, StyleType aStyleType
= eAll
) {
96 return DoGetComputedStyleNoFlush(
97 aElement
, aPseudo
, nsContentUtils::GetPresShellForContent(aElement
),
101 static already_AddRefed
<ComputedStyle
> GetUnanimatedComputedStyleNoFlush(
102 Element
* aElement
, nsAtom
* aPseudo
);
104 // Helper for nsDOMWindowUtils::GetVisitedDependentComputedStyle
105 void SetExposeVisitedStyle(bool aExpose
) {
106 NS_ASSERTION(aExpose
!= mExposeVisitedStyle
, "should always be changing");
107 mExposeVisitedStyle
= aExpose
;
110 void GetCSSImageURLs(const nsACString
& aPropertyName
,
111 nsTArray
<nsCString
>& aImageURLs
,
112 mozilla::ErrorResult
& aRv
) final
;
114 // nsDOMCSSDeclaration abstract methods which should never be called
115 // on a nsComputedDOMStyle object, but must be defined to avoid
117 mozilla::DeclarationBlock
* GetOrCreateCSSDeclaration(
118 Operation aOperation
, mozilla::DeclarationBlock
** aCreated
) final
;
119 virtual nsresult
SetCSSDeclaration(mozilla::DeclarationBlock
*,
120 mozilla::MutationClosureData
*) override
;
121 virtual mozilla::dom::Document
* DocToUpdate() override
;
123 nsDOMCSSDeclaration::ParsingEnvironment
GetParsingEnvironment(
124 nsIPrincipal
* aSubjectPrincipal
) const final
;
126 static already_AddRefed
<nsROCSSPrimitiveValue
> MatrixToCSSValue(
127 const mozilla::gfx::Matrix4x4
& aMatrix
);
128 static void SetToRGBAColor(nsROCSSPrimitiveValue
* aValue
, nscolor aColor
);
130 static void RegisterPrefChangeCallbacks();
131 static void UnregisterPrefChangeCallbacks();
133 // nsIMutationObserver
134 NS_DECL_NSIMUTATIONOBSERVER_PARENTCHAINCHANGED
137 nsresult
GetPropertyValue(const nsCSSPropertyID aPropID
,
138 const nsACString
& aMaybeCustomPropertyNme
,
141 virtual ~nsComputedDOMStyle();
143 void AssertFlushedPendingReflows() {
144 NS_ASSERTION(mFlushedPendingReflows
,
145 "property getter should have been marked layout-dependent");
148 nsMargin
GetAdjustedValuesForBoxSizing();
150 // This indicates error by leaving mComputedStyle null.
151 void UpdateCurrentStyleSources(nsCSSPropertyID
);
152 void ClearCurrentStyleSources();
154 // Helper functions called by UpdateCurrentStyleSources.
155 void ClearComputedStyle();
156 void SetResolvedComputedStyle(RefPtr
<ComputedStyle
>&& aContext
,
157 uint64_t aGeneration
);
158 void SetFrameComputedStyle(ComputedStyle
* aStyle
, uint64_t aGeneration
);
160 static already_AddRefed
<ComputedStyle
> DoGetComputedStyleNoFlush(
161 const Element
* aElement
, nsAtom
* aPseudo
, mozilla::PresShell
* aPresShell
,
162 StyleType aStyleType
);
164 #define STYLE_STRUCT(name_) \
165 const nsStyle##name_* Style##name_() { \
166 return mComputedStyle->Style##name_(); \
168 #include "nsStyleStructList.h"
172 * A method to get a percentage base for a percentage value. Returns true
173 * if a percentage base value was determined, false otherwise.
175 typedef bool (nsComputedDOMStyle::*PercentageBaseGetter
)(nscoord
&);
177 already_AddRefed
<CSSValue
> GetOffsetWidthFor(mozilla::Side
);
178 already_AddRefed
<CSSValue
> GetAbsoluteOffset(mozilla::Side
);
179 nscoord
GetUsedAbsoluteOffset(mozilla::Side
);
180 already_AddRefed
<CSSValue
> GetNonStaticPositionOffset(
181 mozilla::Side aSide
, bool aResolveAuto
, PercentageBaseGetter aWidthGetter
,
182 PercentageBaseGetter aHeightGetter
);
184 already_AddRefed
<CSSValue
> GetStaticOffset(mozilla::Side aSide
);
186 already_AddRefed
<CSSValue
> GetPaddingWidthFor(mozilla::Side aSide
);
188 already_AddRefed
<CSSValue
> GetBorderWidthFor(mozilla::Side aSide
);
190 already_AddRefed
<CSSValue
> GetMarginWidthFor(mozilla::Side aSide
);
192 already_AddRefed
<CSSValue
> GetTransformValue(const mozilla::StyleTransform
&);
194 already_AddRefed
<nsROCSSPrimitiveValue
> GetGridTrackSize(
195 const mozilla::StyleTrackSize
&);
196 already_AddRefed
<nsROCSSPrimitiveValue
> GetGridTrackBreadth(
197 const mozilla::StyleTrackBreadth
&);
198 void SetValueToTrackBreadth(nsROCSSPrimitiveValue
*,
199 const mozilla::StyleTrackBreadth
&);
200 already_AddRefed
<CSSValue
> GetGridTemplateColumnsRows(
201 const mozilla::StyleGridTemplateComponent
& aTrackList
,
202 const mozilla::ComputedGridTrackInfo
& aTrackInfo
);
204 bool GetLineHeightCoord(nscoord
& aCoord
);
206 bool ShouldHonorMinSizeAutoInAxis(mozilla::PhysicalAxis aAxis
);
208 /* Properties queryable as CSSValues.
209 * To avoid a name conflict with nsIDOM*CSS2Properties, these are all
210 * DoGetXXX instead of GetXXX.
215 already_AddRefed
<CSSValue
> DoGetWidth();
216 already_AddRefed
<CSSValue
> DoGetHeight();
217 already_AddRefed
<CSSValue
> DoGetMaxHeight();
218 already_AddRefed
<CSSValue
> DoGetMaxWidth();
219 already_AddRefed
<CSSValue
> DoGetMinHeight();
220 already_AddRefed
<CSSValue
> DoGetMinWidth();
221 already_AddRefed
<CSSValue
> DoGetLeft();
222 already_AddRefed
<CSSValue
> DoGetTop();
223 already_AddRefed
<CSSValue
> DoGetRight();
224 already_AddRefed
<CSSValue
> DoGetBottom();
226 /* Font properties */
227 already_AddRefed
<CSSValue
> DoGetOsxFontSmoothing();
229 /* Grid properties */
230 already_AddRefed
<CSSValue
> DoGetGridTemplateColumns();
231 already_AddRefed
<CSSValue
> DoGetGridTemplateRows();
233 /* StyleImageLayer properties */
234 already_AddRefed
<CSSValue
> DoGetImageLayerPosition(
235 const nsStyleImageLayers
& aLayers
);
237 /* Mask properties */
238 already_AddRefed
<CSSValue
> DoGetMask();
240 /* Padding properties */
241 already_AddRefed
<CSSValue
> DoGetPaddingTop();
242 already_AddRefed
<CSSValue
> DoGetPaddingBottom();
243 already_AddRefed
<CSSValue
> DoGetPaddingLeft();
244 already_AddRefed
<CSSValue
> DoGetPaddingRight();
246 /* Table Properties */
247 already_AddRefed
<CSSValue
> DoGetBorderSpacing();
249 /* Border Properties */
250 already_AddRefed
<CSSValue
> DoGetBorderTopWidth();
251 already_AddRefed
<CSSValue
> DoGetBorderBottomWidth();
252 already_AddRefed
<CSSValue
> DoGetBorderLeftWidth();
253 already_AddRefed
<CSSValue
> DoGetBorderRightWidth();
255 /* Margin Properties */
256 already_AddRefed
<CSSValue
> DoGetMarginTopWidth();
257 already_AddRefed
<CSSValue
> DoGetMarginBottomWidth();
258 already_AddRefed
<CSSValue
> DoGetMarginLeftWidth();
259 already_AddRefed
<CSSValue
> DoGetMarginRightWidth();
261 /* Text Properties */
262 already_AddRefed
<CSSValue
> DoGetLineHeight();
263 already_AddRefed
<CSSValue
> DoGetTextDecoration();
265 /* Display properties */
266 already_AddRefed
<CSSValue
> DoGetTransform();
267 already_AddRefed
<CSSValue
> DoGetTransformOrigin();
268 already_AddRefed
<CSSValue
> DoGetPerspectiveOrigin();
270 /* Column properties */
271 already_AddRefed
<CSSValue
> DoGetColumnRuleWidth();
273 // For working around a MSVC bug. See related comment in
274 // GenerateComputedDOMStyleGenerated.py.
275 already_AddRefed
<CSSValue
> DummyGetter();
277 /* Helper functions */
278 void SetValueFromComplexColor(nsROCSSPrimitiveValue
* aValue
,
279 const mozilla::StyleColor
& aColor
);
280 void SetValueToPosition(const mozilla::Position
& aPosition
,
281 nsDOMCSSValueList
* aValueList
);
282 void SetValueToURLValue(const mozilla::StyleComputedUrl
* aURL
,
283 nsROCSSPrimitiveValue
* aValue
);
285 void SetValueToSize(nsROCSSPrimitiveValue
* aValue
, const mozilla::StyleSize
&);
287 void SetValueToLengthPercentageOrAuto(nsROCSSPrimitiveValue
* aValue
,
288 const LengthPercentageOrAuto
&,
289 bool aClampNegativeCalc
);
291 void SetValueToLengthPercentage(nsROCSSPrimitiveValue
* aValue
,
292 const LengthPercentage
&,
293 bool aClampNegativeCalc
);
295 void SetValueToMaxSize(nsROCSSPrimitiveValue
* aValue
,
296 const mozilla::StyleMaxSize
&);
298 bool GetCBContentWidth(nscoord
& aWidth
);
299 bool GetCBContentHeight(nscoord
& aHeight
);
300 bool GetCBPaddingRectWidth(nscoord
& aWidth
);
301 bool GetCBPaddingRectHeight(nscoord
& aHeight
);
302 bool GetScrollFrameContentWidth(nscoord
& aWidth
);
303 bool GetScrollFrameContentHeight(nscoord
& aHeight
);
304 bool GetFrameBorderRectWidth(nscoord
& aWidth
);
305 bool GetFrameBorderRectHeight(nscoord
& aHeight
);
307 // Find out if we can safely skip flushing (i.e. pending restyles do not
308 // affect our element).
309 bool NeedsToFlushStyle(nsCSSPropertyID
) const;
310 // Find out if we need to flush layout of the document, depending on the
311 // property that was requested.
312 bool NeedsToFlushLayout(nsCSSPropertyID
) const;
313 // Flushes the given document, which must be our document, and potentially the
314 // mElement's document.
315 void Flush(Document
&, mozilla::FlushType
);
316 nsIFrame
* GetOuterFrame() const;
318 static ComputedStyleMap
* GetComputedStyleMap();
320 // We don't really have a good immutable representation of "presentation".
321 // Given the way GetComputedStyle is currently used, we should just grab the
322 // presshell, if any, from the document.
323 nsWeakPtr mDocumentWeak
;
324 RefPtr
<Element
> mElement
;
327 * Strong reference to the ComputedStyle we access data from. This can be
328 * either a ComputedStyle we resolved ourselves or a ComputedStyle we got
331 * If we got the ComputedStyle from the frame, we clear out mComputedStyle
332 * in ClearCurrentStyleSources. If we resolved one ourselves, then
333 * ClearCurrentStyleSources leaves it in mComputedStyle for use the next
334 * time this nsComputedDOMStyle object is queried. UpdateCurrentStyleSources
335 * in this case will check that the ComputedStyle is still valid to be used,
336 * by checking whether flush styles results in any restyles having been
339 RefPtr
<ComputedStyle
> mComputedStyle
;
340 RefPtr
<nsAtom
> mPseudo
;
343 * While computing style data, the primary frame for mContent --- named
344 * "outer" because we should use it to compute positioning data. Null
347 nsIFrame
* mOuterFrame
;
349 * While computing style data, the "inner frame" for mContent --- the frame
350 * which we should use to compute margin, border, padding and content data.
353 nsIFrame
* mInnerFrame
;
355 * While computing style data, the presshell we're working with. Null
358 mozilla::PresShell
* mPresShell
;
361 * The kind of styles we should be returning.
363 StyleType mStyleType
;
366 * The nsComputedDOMStyle generation at the time we last resolved a style
367 * context and stored it in mComputedStyle, and the pres shell we got the
368 * style from. Should only be used together.
370 uint64_t mComputedStyleGeneration
= 0;
372 uint32_t mPresShellId
= 0;
374 bool mExposeVisitedStyle
;
377 * Whether we resolved a ComputedStyle last time we called
378 * UpdateCurrentStyleSources. Initially false.
380 bool mResolvedComputedStyle
;
383 bool mFlushedPendingReflows
= false;
386 friend struct ComputedStyleMap
;
389 already_AddRefed
<nsComputedDOMStyle
> NS_NewComputedDOMStyle(
390 mozilla::dom::Element
* aElement
, const nsAString
& aPseudoElt
,
391 mozilla::dom::Document
* aDocument
,
392 nsComputedDOMStyle::StyleType aStyleType
= nsComputedDOMStyle::eAll
);
394 #endif /* nsComputedDOMStyle_h__ */