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 /* a presentation of a document, part 1 */
9 #ifndef nsPresContext_h___
10 #define nsPresContext_h___
12 #include "mozilla/AppUnits.h"
13 #include "mozilla/Attributes.h"
14 #include "mozilla/EnumeratedArray.h"
15 #include "mozilla/MediaEmulationData.h"
16 #include "mozilla/MemoryReporting.h"
17 #include "mozilla/NotNull.h"
18 #include "mozilla/PreferenceSheet.h"
19 #include "mozilla/PresShellForwards.h"
20 #include "mozilla/ScrollStyles.h"
21 #include "mozilla/TimeStamp.h"
22 #include "mozilla/UniquePtr.h"
23 #include "mozilla/WeakPtr.h"
24 #include "mozilla/widget/ThemeChangeKind.h"
26 #include "nsCompatibility.h"
29 #include "nsHashKeys.h"
31 #include "nsStringFwd.h"
32 #include "nsTHashtable.h"
34 #include "nsIWidgetListener.h" // for nsSizeMode
35 #include "nsGkAtoms.h"
36 #include "nsCycleCollectionParticipant.h"
37 #include "nsChangeHint.h"
41 #include "nsThreadUtils.h"
45 class nsIPrintSettings
;
55 class gfxFontFeatureValueSet
;
56 class gfxUserFontEntry
;
58 class gfxTextPerfMetrics
;
59 class nsCSSFontFeatureValuesRule
;
60 class nsCSSFrameConstructor
;
61 class nsTransitionManager
;
62 class nsAnimationManager
;
63 class nsRefreshDriver
;
65 class nsDeviceContext
;
66 class gfxMissingFontRecorder
;
67 struct FontMatchingStats
;
70 class AnimationEventDispatcher
;
71 class EffectCompositor
;
73 class EventStateManager
;
74 class CounterStyleManager
;
75 class ManagedPostRefreshObserver
;
80 struct MediaFeatureChange
;
81 enum class MediaFeatureChangePropagation
: uint8_t;
90 } // namespace mozilla
92 // supported values for cached integer pref types
93 enum nsPresContext_CachedIntPrefType
{
94 kPresContext_ScrollbarSide
= 1,
95 kPresContext_BidiDirection
98 // IDs for the default variable and fixed fonts (not to be changed, see
99 // nsFont.h) To be used for Get/SetDefaultFont(). The other IDs in nsFont.h are
102 // kGenericFont_moz_variable
103 const uint8_t kPresContext_DefaultVariableFont_ID
= 0x00;
104 // kGenericFont_moz_fixed
105 const uint8_t kPresContext_DefaultFixedFont_ID
= 0x01;
108 struct nsAutoLayoutPhase
;
110 enum class nsLayoutPhase
: uint8_t {
112 DisplayListBuilding
, // sometimes a subset of the paint phase
119 /* Used by nsPresContext::HasAuthorSpecifiedRules */
120 #define NS_AUTHOR_SPECIFIED_BORDER_OR_BACKGROUND (1 << 0)
121 #define NS_AUTHOR_SPECIFIED_PADDING (1 << 1)
123 class nsRootPresContext
;
125 // An interface for presentation contexts. Presentation contexts are
126 // objects that provide an outer context for a presentation shell.
128 class nsPresContext
: public nsISupports
, public mozilla::SupportsWeakPtr
{
130 using Encoding
= mozilla::Encoding
;
131 template <typename T
>
132 using NotNull
= mozilla::NotNull
<T
>;
133 template <typename T
>
134 using Maybe
= mozilla::Maybe
<T
>;
135 using MediaEmulationData
= mozilla::MediaEmulationData
;
137 typedef mozilla::ScrollStyles ScrollStyles
;
138 using TransactionId
= mozilla::layers::TransactionId
;
140 NS_DECL_CYCLE_COLLECTING_ISUPPORTS_FINAL
141 NS_DECL_CYCLE_COLLECTION_CLASS(nsPresContext
)
143 enum nsPresContextType
: uint8_t {
144 eContext_Galley
, // unpaginated screen presentation
145 eContext_PrintPreview
, // paginated screen presentation
146 eContext_Print
, // paginated printer presentation
147 eContext_PageLayout
// paginated & editable.
150 nsPresContext(mozilla::dom::Document
* aDocument
, nsPresContextType aType
);
153 * Initialize the presentation context from a particular device.
155 nsresult
Init(nsDeviceContext
* aDeviceContext
);
158 * Set and detach presentation shell that this context is bound to.
159 * A presentation context may only be bound to a single shell.
161 void AttachPresShell(mozilla::PresShell
* aPresShell
);
162 void DetachPresShell();
164 nsPresContextType
Type() const { return mType
; }
167 * Get the PresentationShell that this context is bound to.
169 mozilla::PresShell
* PresShell() const {
170 NS_ASSERTION(mPresShell
, "Null pres shell");
174 mozilla::PresShell
* GetPresShell() const { return mPresShell
; }
176 void DocumentCharSetChanged(NotNull
<const Encoding
*> aCharSet
);
179 * Returns the parent prescontext for this one. Returns null if this is a
182 nsPresContext
* GetParentPresContext() const;
185 * Returns the prescontext of the root content document in the same process
186 * that contains this presentation, or null if there isn't one.
188 nsPresContext
* GetInProcessRootContentDocumentPresContext();
191 * Returns the nearest widget for the root frame or view of this.
193 * @param aOffset If non-null the offset from the origin of the root
194 * frame's view to the widget's origin (usually positive)
195 * expressed in appunits of this will be returned in
198 nsIWidget
* GetNearestWidget(nsPoint
* aOffset
= nullptr);
201 * Returns the root widget for this.
203 nsIWidget
* GetRootWidget() const;
206 * Returns the widget which may have native focus and handles text input
207 * like keyboard input, IME, etc.
209 nsIWidget
* GetTextInputHandlingWidget() const {
210 // Currently, root widget for each PresContext handles text input.
211 return GetRootWidget();
215 * Return the presentation context for the root of the view manager
216 * hierarchy that contains this presentation context, or nullptr if it can't
217 * be found (e.g. it's detached).
219 nsRootPresContext
* GetRootPresContext() const;
221 virtual bool IsRoot() { return false; }
223 mozilla::dom::Document
* Document() const {
225 ValidatePresShellAndDocumentReleation();
226 #endif // #ifdef DEBUG
230 inline mozilla::ServoStyleSet
* StyleSet() const;
232 bool HasPendingMediaQueryUpdates() const {
233 return !!mPendingMediaFeatureValuesChange
;
236 inline nsCSSFrameConstructor
* FrameConstructor();
238 mozilla::AnimationEventDispatcher
* AnimationEventDispatcher() {
239 return mAnimationEventDispatcher
;
242 mozilla::EffectCompositor
* EffectCompositor() { return mEffectCompositor
; }
243 nsTransitionManager
* TransitionManager() { return mTransitionManager
.get(); }
244 nsAnimationManager
* AnimationManager() { return mAnimationManager
.get(); }
245 const nsAnimationManager
* AnimationManager() const {
246 return mAnimationManager
.get();
249 nsRefreshDriver
* RefreshDriver() { return mRefreshDriver
; }
251 mozilla::RestyleManager
* RestyleManager() {
252 MOZ_ASSERT(mRestyleManager
);
253 return mRestyleManager
.get();
256 mozilla::CounterStyleManager
* CounterStyleManager() const {
257 return mCounterStyleManager
;
261 * Rebuilds all style data by throwing out the old rule tree and
262 * building a new one, and additionally applying a change hint (which must not
263 * contain nsChangeHint_ReconstructFrame) to the root frame.
265 * For the restyle hint argument, see RestyleManager::RebuildAllStyleData.
266 * Also rebuild the user font set and counter style manager.
268 * FIXME(emilio): The name of this is an utter lie. We should probably call
269 * this PostGlobalStyleChange or something, as it doesn't really rebuild
270 * anything unless you tell it to via the change hint / restyle hint
273 void RebuildAllStyleData(nsChangeHint
, const mozilla::RestyleHint
&);
275 * Just like RebuildAllStyleData, except (1) asynchronous and (2) it
276 * doesn't rebuild the user font set / counter-style manager / etc.
278 void PostRebuildAllStyleDataEvent(nsChangeHint
, const mozilla::RestyleHint
&);
280 void ContentLanguageChanged();
282 /** Returns whether any media query changed. */
283 bool FlushPendingMediaFeatureValuesChanged();
286 * Schedule a media feature change for this document, and potentially for
287 * other subdocuments and images (depending on the arguments).
289 void MediaFeatureValuesChanged(const mozilla::MediaFeatureChange
&,
290 mozilla::MediaFeatureChangePropagation
);
293 * Updates the size mode on all remote children and recursively notifies this
294 * document and all subdocuments (including remote children) that a media
295 * feature value has changed.
297 void SizeModeChanged(nsSizeMode aSizeMode
);
300 * Access compatibility mode for this context. This is the same as
301 * our document's compatibility mode.
303 nsCompatibility
CompatibilityMode() const;
306 * Access the image animation mode for this context
308 uint16_t ImageAnimationMode() const { return mImageAnimationMode
; }
309 void SetImageAnimationMode(uint16_t aMode
);
312 * Get medium of presentation
314 const nsAtom
* Medium() {
316 return mMediaEmulationData
.mMedium
? mMediaEmulationData
.mMedium
.get()
321 * Render the document as if being viewed on a device with the specified
324 * If passed null, it stops emulating.
326 void EmulateMedium(nsAtom
* aMediaType
);
328 /** Get a cached integer pref, by its type */
329 // * - initially created for bugs 30910, 61883, 74186, 84398
330 int32_t GetCachedIntPref(nsPresContext_CachedIntPrefType aPrefType
) const {
331 // If called with a constant parameter, the compiler should optimize
332 // this switch statement away.
334 case kPresContext_ScrollbarSide
:
335 return mPrefScrollbarSide
;
336 case kPresContext_BidiDirection
:
337 return mPrefBidiDirection
;
339 NS_ERROR("invalid arg passed to GetCachedIntPref");
345 const mozilla::PreferenceSheet::Prefs
& PrefSheetPrefs() const {
346 return mozilla::PreferenceSheet::PrefsFor(*mDocument
);
348 nscolor
DefaultBackgroundColor() const {
349 return PrefSheetPrefs().mDefaultBackgroundColor
;
352 nsISupports
* GetContainerWeak() const;
354 nsDocShell
* GetDocShell() const;
357 * Get the visible area associated with this presentation context.
358 * This is the size of the visible area that is used for
359 * presenting the document. The returned value is in the standard
360 * nscoord units (as scaled by the device context).
362 nsRect
GetVisibleArea() const { return mVisibleArea
; }
365 * Set the currently visible area. The units for r are standard
366 * nscoord units (as scaled by the device context).
368 void SetVisibleArea(const nsRect
& r
);
370 nsSize
GetSizeForViewportUnits() const { return mSizeForViewportUnits
; }
373 * Set the maximum height of the dynamic toolbar in nscoord units.
376 void SetDynamicToolbarMaxHeight(mozilla::ScreenIntCoord aHeight
);
378 mozilla::ScreenIntCoord
GetDynamicToolbarMaxHeight() const {
379 MOZ_ASSERT(IsRootContentDocumentCrossProcess());
380 return mDynamicToolbarMaxHeight
;
384 * Returns true if we are using the dynamic toolbar.
386 bool HasDynamicToolbar() const {
387 MOZ_ASSERT(IsRootContentDocumentCrossProcess());
388 return mDynamicToolbarMaxHeight
> 0;
392 * |aOffset| must be offset from the bottom edge of the ICB and it's negative.
394 void UpdateDynamicToolbarOffset(mozilla::ScreenIntCoord aOffset
);
395 mozilla::ScreenIntCoord
GetDynamicToolbarHeight() const {
396 MOZ_ASSERT(IsRootContentDocumentCrossProcess());
397 return mDynamicToolbarHeight
;
401 * Returns the state of the dynamic toolbar.
403 mozilla::DynamicToolbarState
GetDynamicToolbarState() const;
406 * Return true if this presentation context is a paginated
409 bool IsPaginated() const { return mPaginated
; }
412 * Sets whether the presentation context can scroll for a paginated
415 void SetPaginatedScrolling(bool aResult
);
418 * Return true if this presentation context can scroll for paginated
421 bool HasPaginatedScrolling() const { return mCanPaginatedScroll
; }
424 * Get/set the size of a page
426 const nsSize
& GetPageSize() const { return mPageSize
; }
427 const nsMargin
& GetDefaultPageMargin() const { return mDefaultPageMargin
; }
428 void SetPageSize(nsSize aSize
) { mPageSize
= aSize
; }
431 * Get/set whether this document should be treated as having real pages
432 * XXX This raises the obvious question of why a document that isn't a page
433 * is paginated; there isn't a good reason except history
435 bool IsRootPaginatedDocument() { return mIsRootPaginatedDocument
; }
436 void SetIsRootPaginatedDocument(bool aIsRootPaginatedDocument
) {
437 mIsRootPaginatedDocument
= aIsRootPaginatedDocument
;
441 * Get/set the print scaling level; used by nsPageFrame to scale up
442 * pages. Set safe to call before reflow, get guaranteed to be set
443 * properly after reflow.
446 float GetPageScale() { return mPageScale
; }
447 void SetPageScale(float aScale
) { mPageScale
= aScale
; }
450 * Get/set the scaling factor to use when rendering the pages for print
451 * preview. Only safe to get after print preview set up; safe to set anytime.
452 * This is a scaling factor for the display of the print preview. It
453 * does not affect layout. It only affects the size of the onscreen pages
456 * The getter should only be used by the page sequence frame, which is the
457 * frame responsible for applying the scaling. Other callers should use
458 * nsPageSequenceFrame::GetPrintPreviewScale() if needed, instead of this API.
460 * XXX Temporary: see http://wiki.mozilla.org/Gecko:PrintPreview
462 float GetPrintPreviewScaleForSequenceFrame() { return mPPScale
; }
463 void SetPrintPreviewScale(float aScale
) { mPPScale
= aScale
; }
465 nsDeviceContext
* DeviceContext() const { return mDeviceContext
; }
466 mozilla::EventStateManager
* EventStateManager() { return mEventManager
; }
469 * Get/set a text zoom factor that is applied on top of the normal text zoom
470 * set by the front-end/user.
472 float GetSystemFontScale() const { return mSystemFontScale
; }
473 void SetSystemFontScale(float aFontScale
) {
474 MOZ_ASSERT(aFontScale
> 0.0f
, "invalid font scale");
475 if (aFontScale
== mSystemFontScale
|| IsPrintingOrPrintPreview()) {
479 mSystemFontScale
= aFontScale
;
480 UpdateEffectiveTextZoom();
484 * Get/set the text zoom factor in use.
485 * This value should be used if you're interested in the pure text zoom value
486 * controlled by the front-end, e.g. when transferring zoom levels to a new
488 * Code that wants to use this value for layouting and rendering purposes
489 * should consider using EffectiveTextZoom() instead, so as to take the system
490 * font scale into account as well.
492 float TextZoom() const { return mTextZoom
; }
495 * Corresponds to the product of text zoom and system font scale, limited
496 * by zoom.maxPercent and minPercent.
497 * As the system font scale is automatically set by the PresShell, code that
498 * e.g. wants to transfer zoom levels to a new document should use TextZoom()
499 * instead, which corresponds to the text zoom level that was actually set by
500 * the front-end/user.
502 float EffectiveTextZoom() const { return mEffectiveTextZoom
; }
505 * Notify the pres context that the safe area insets have changed.
507 void SetSafeAreaInsets(const mozilla::ScreenIntMargin
& aInsets
);
509 mozilla::ScreenIntMargin
GetSafeAreaInsets() const { return mSafeAreaInsets
; }
511 void RegisterManagedPostRefreshObserver(mozilla::ManagedPostRefreshObserver
*);
512 void UnregisterManagedPostRefreshObserver(
513 mozilla::ManagedPostRefreshObserver
*);
514 void CancelManagedPostRefreshObservers();
517 void UpdateEffectiveTextZoom();
520 void ValidatePresShellAndDocumentReleation() const;
521 #endif // #ifdef DEBUG
523 void SetTextZoom(float aZoom
) {
524 MOZ_ASSERT(aZoom
> 0.0f
, "invalid zoom factor");
525 if (aZoom
== mTextZoom
) return;
528 UpdateEffectiveTextZoom();
530 void SetFullZoom(float aZoom
);
531 void SetOverrideDPPX(float);
534 float GetFullZoom() { return mFullZoom
; }
536 * Device full zoom differs from full zoom because it gets the zoom from
537 * the device context, which may be using a different zoom due to rounding
538 * of app units to device pixels.
540 float GetDeviceFullZoom();
542 float GetOverrideDPPX() const { return mMediaEmulationData
.mDPPX
; }
545 * Recomputes the data dependent on the browsing context, like zoom and text
548 * TODO(emilio): Eventually stuff like the media emulation data, overrideDPPX
549 * and such should also move here.
551 void RecomputeBrowsingContextDependentData();
553 mozilla::CSSCoord
GetAutoQualityMinFontSize() const {
554 return DevPixelsToFloatCSSPixels(mAutoQualityMinFontSizePixelsPref
);
558 * Return the device's screen size in inches, for font size
561 * If |aChanged| is non-null, then aChanged is filled in with whether
562 * the screen size value has changed since either:
563 * a. the last time the function was called with non-null aChanged, or
564 * b. the first time the function was called.
566 gfxSize
ScreenSizeInchesForFontInflation(bool* aChanged
= nullptr);
568 int32_t AppUnitsPerDevPixel() const { return mCurAppUnitsPerDevPixel
; }
570 static nscoord
CSSPixelsToAppUnits(int32_t aPixels
) {
571 return NSToCoordRoundWithClamp(float(aPixels
) *
572 float(mozilla::AppUnitsPerCSSPixel()));
575 static nscoord
CSSPixelsToAppUnits(float aPixels
) {
576 return NSToCoordRoundWithClamp(aPixels
*
577 float(mozilla::AppUnitsPerCSSPixel()));
580 static int32_t AppUnitsToIntCSSPixels(nscoord aAppUnits
) {
581 return NSAppUnitsToIntPixels(aAppUnits
,
582 float(mozilla::AppUnitsPerCSSPixel()));
585 static float AppUnitsToFloatCSSPixels(nscoord aAppUnits
) {
586 return NSAppUnitsToFloatPixels(aAppUnits
,
587 float(mozilla::AppUnitsPerCSSPixel()));
590 static double AppUnitsToDoubleCSSPixels(nscoord aAppUnits
) {
591 return NSAppUnitsToDoublePixels(aAppUnits
,
592 double(mozilla::AppUnitsPerCSSPixel()));
595 nscoord
DevPixelsToAppUnits(int32_t aPixels
) const {
596 return NSIntPixelsToAppUnits(aPixels
, AppUnitsPerDevPixel());
599 int32_t AppUnitsToDevPixels(nscoord aAppUnits
) const {
600 return NSAppUnitsToIntPixels(aAppUnits
, float(AppUnitsPerDevPixel()));
603 float AppUnitsToFloatDevPixels(nscoord aAppUnits
) {
604 return aAppUnits
/ float(AppUnitsPerDevPixel());
607 int32_t CSSPixelsToDevPixels(int32_t aPixels
) {
608 return AppUnitsToDevPixels(CSSPixelsToAppUnits(aPixels
));
611 float CSSPixelsToDevPixels(float aPixels
) {
612 return NSAppUnitsToFloatPixels(CSSPixelsToAppUnits(aPixels
),
613 float(AppUnitsPerDevPixel()));
616 int32_t DevPixelsToIntCSSPixels(int32_t aPixels
) {
617 return AppUnitsToIntCSSPixels(DevPixelsToAppUnits(aPixels
));
620 mozilla::CSSIntPoint
DevPixelsToIntCSSPixels(
621 const mozilla::LayoutDeviceIntPoint
& aPoint
) {
622 return mozilla::CSSIntPoint(
623 AppUnitsToIntCSSPixels(DevPixelsToAppUnits(aPoint
.x
)),
624 AppUnitsToIntCSSPixels(DevPixelsToAppUnits(aPoint
.y
)));
627 float DevPixelsToFloatCSSPixels(int32_t aPixels
) const {
628 return AppUnitsToFloatCSSPixels(DevPixelsToAppUnits(aPixels
));
631 mozilla::CSSToLayoutDeviceScale
CSSToDevPixelScale() const {
632 return mozilla::CSSToLayoutDeviceScale(
633 float(mozilla::AppUnitsPerCSSPixel()) / float(AppUnitsPerDevPixel()));
636 // If there is a remainder, it is rounded to nearest app units.
637 nscoord
GfxUnitsToAppUnits(gfxFloat aGfxUnits
) const;
639 gfxFloat
AppUnitsToGfxUnits(nscoord aAppUnits
) const;
641 gfxRect
AppUnitsToGfxUnits(const nsRect
& aAppRect
) const {
642 return gfxRect(AppUnitsToGfxUnits(aAppRect
.x
),
643 AppUnitsToGfxUnits(aAppRect
.y
),
644 AppUnitsToGfxUnits(aAppRect
.Width()),
645 AppUnitsToGfxUnits(aAppRect
.Height()));
648 static nscoord
CSSTwipsToAppUnits(float aTwips
) {
649 return NSToCoordRoundWithClamp(mozilla::AppUnitsPerCSSInch() *
650 NS_TWIPS_TO_INCHES(aTwips
));
653 // Margin-specific version, since they often need TwipsToAppUnits
654 static nsMargin
CSSTwipsToAppUnits(const nsIntMargin
& marginInTwips
) {
655 return nsMargin(CSSTwipsToAppUnits(float(marginInTwips
.top
)),
656 CSSTwipsToAppUnits(float(marginInTwips
.right
)),
657 CSSTwipsToAppUnits(float(marginInTwips
.bottom
)),
658 CSSTwipsToAppUnits(float(marginInTwips
.left
)));
661 static nscoord
CSSPointsToAppUnits(float aPoints
) {
662 return NSToCoordRound(aPoints
* mozilla::AppUnitsPerCSSInch() /
663 POINTS_PER_INCH_FLOAT
);
666 nscoord
PhysicalMillimetersToAppUnits(float aMM
) const;
668 nscoord
RoundAppUnitsToNearestDevPixels(nscoord aAppUnits
) const {
669 return DevPixelsToAppUnits(AppUnitsToDevPixels(aAppUnits
));
673 * This checks the root element and the HTML BODY, if any, for an "overflow"
674 * property that should be applied to the viewport. If one is found then we
675 * return the element that we took the overflow from (which should then be
676 * treated as "overflow: visible"), and we store the overflow style here.
677 * If the document is in fullscreen, and the fullscreen element is not the
678 * root, the scrollbar of viewport will be suppressed.
679 * @return if scroll was propagated from some content node, the content node
680 * it was propagated from.
682 mozilla::dom::Element
* UpdateViewportScrollStylesOverride();
685 * Returns the cached result from the last call to
686 * UpdateViewportScrollStylesOverride() -- i.e. return the node
687 * whose scrollbar styles we have propagated to the viewport (or nullptr if
688 * there is no such node).
690 mozilla::dom::Element
* GetViewportScrollStylesOverrideElement() const {
691 return mViewportScrollOverrideElement
;
694 const ScrollStyles
& GetViewportScrollStylesOverride() const {
695 return mViewportScrollStyles
;
699 * Check whether the given element would propagate its scrollbar styles to the
700 * viewport in non-paginated mode.
702 bool ElementWouldPropagateScrollStyles(const mozilla::dom::Element
&);
705 * Methods for controlling the background drawing.
707 bool GetBackgroundImageDraw() const { return mDrawImageBackground
; }
708 bool GetBackgroundColorDraw() const { return mDrawColorBackground
; }
711 * Check if bidi enabled (set depending on the presence of RTL
712 * characters or when default directionality is RTL).
713 * If enabled, we should apply the Unicode Bidi Algorithm
717 bool BidiEnabled() const;
720 * Set bidi enabled. This means we should apply the Unicode Bidi Algorithm
724 void SetBidiEnabled() const;
727 * Set visual or implicit mode into the pres context.
729 * Visual directionality is a presentation method that displays text
730 * as if it were a uni-directional, according to the primary display
733 * Implicit directionality is a presentation method in which the
734 * direction is determined by the Bidi algorithm according to the
735 * category of the characters and the category of the adjacent
736 * characters, and according to their primary direction.
740 void SetVisualMode(bool aIsVisual
) { mIsVisual
= aIsVisual
; }
743 * Check whether the content should be treated as visual.
747 bool IsVisualMode() const { return mIsVisual
; }
749 enum class InteractionType
: uint32_t {
752 MouseMoveInteraction
,
756 void RecordInteractionTime(InteractionType aType
,
757 const mozilla::TimeStamp
& aTimeStamp
);
759 void DisableInteractionTimeRecording() { mInteractionTimeEnabled
= false; }
764 * Set the Bidi options for the presentation context
766 void SetBidi(uint32_t aBidiOptions
);
769 * Get the Bidi options for the presentation context
770 * Not inline so consumers of nsPresContext are not forced to
773 uint32_t GetBidi() const;
776 * Obtain a native theme for rendering our widgets (both form controls and
779 * Guaranteed to return non-null.
781 nsITheme
* Theme() MOZ_NONNULL_RETURN
{
782 if (MOZ_LIKELY(mTheme
)) {
785 return EnsureTheme();
789 * Notify the pres context that the theme has changed. An internal switch
790 * means it's one of our Mozilla themes that changed (e.g., Modern to
791 * Classic). Otherwise, the OS is telling us that the native theme for the
792 * platform has changed.
794 void ThemeChanged(mozilla::widget::ThemeChangeKind
);
797 * Notify the pres context that the resolution of the user interface has
798 * changed. This happens if a window is moved between HiDPI and non-HiDPI
799 * displays, so that the ratio of points to device pixels changes.
800 * The notification happens asynchronously.
802 void UIResolutionChanged();
805 * Like UIResolutionChanged() but invalidates values immediately.
807 void UIResolutionChangedSync();
809 /** Printing methods below should only be used for Medium() == print **/
810 void SetPrintSettings(nsIPrintSettings
* aPrintSettings
);
812 nsIPrintSettings
* GetPrintSettings() { return mPrintSettings
; }
814 /* Helper function that ensures that this prescontext is shown in its
815 docshell if it's the most recent prescontext for the docshell. Returns
816 whether the prescontext is now being shown.
818 bool EnsureVisible();
820 #ifdef MOZ_REFLOW_PERF
821 void CountReflows(const char* aName
, nsIFrame
* aFrame
);
824 void ConstructedFrame() { ++mFramesConstructed
; }
825 void ReflowedFrame() { ++mFramesReflowed
; }
827 uint64_t FramesConstructedCount() { return mFramesConstructed
; }
828 uint64_t FramesReflowedCount() { return mFramesReflowed
; }
830 static nscoord
GetBorderWidthForKeyword(unsigned int aBorderWidthKeyword
) {
831 // This table maps border-width enums 'thin', 'medium', 'thick'
832 // to actual nscoord values.
833 static const nscoord kBorderWidths
[] = {
834 CSSPixelsToAppUnits(1), CSSPixelsToAppUnits(3), CSSPixelsToAppUnits(5)};
835 MOZ_ASSERT(size_t(aBorderWidthKeyword
) <
836 mozilla::ArrayLength(kBorderWidths
));
838 return kBorderWidths
[aBorderWidthKeyword
];
841 gfxTextPerfMetrics
* GetTextPerfMetrics() { return mTextPerf
.get(); }
842 FontMatchingStats
* GetFontMatchingStats() { return mFontStats
.get(); }
845 return (mType
== eContext_PageLayout
|| mType
== eContext_Galley
);
848 return (mMedium
== nsGkAtoms::screen
|| mType
== eContext_PageLayout
||
849 mType
== eContext_PrintPreview
);
851 bool IsPrintingOrPrintPreview() {
852 return (mType
== eContext_Print
|| mType
== eContext_PrintPreview
);
855 // Is this presentation in a chrome docshell?
856 bool IsChrome() const;
858 // Public API for native theme code to get style internals.
859 bool HasAuthorSpecifiedRules(const nsIFrame
* aFrame
,
860 uint32_t ruleTypeMask
) const;
862 // Explicitly enable and disable paint flashing.
863 void SetPaintFlashing(bool aPaintFlashing
) {
864 mPaintFlashing
= aPaintFlashing
;
865 mPaintFlashingInitialized
= true;
868 // This method should be used instead of directly accessing mPaintFlashing,
869 // as that value may be out of date when mPaintFlashingInitialized is false.
870 bool GetPaintFlashing() const;
872 bool SuppressingResizeReflow() const { return mSuppressResizeReflow
; }
874 gfxUserFontSet
* GetUserFontSet();
876 // Should be called whenever the set of fonts available in the user
877 // font set changes (e.g., because a new font loads, or because the
878 // user font set is changed and fonts become unavailable).
879 void UserFontSetUpdated(gfxUserFontEntry
* aUpdatedFont
= nullptr);
881 gfxMissingFontRecorder
* MissingFontRecorder() { return mMissingFonts
.get(); }
883 void NotifyMissingFonts();
885 void FlushCounterStyles();
886 void MarkCounterStylesDirty();
888 void FlushFontFeatureValues();
889 void MarkFontFeatureValuesDirty() { mFontFeatureValuesDirty
= true; }
891 // Ensure that it is safe to hand out CSS rules outside the layout
892 // engine by ensuring that all CSS style sheets have unique inners
893 // and, if necessary, synchronously rebuilding all style data.
894 void EnsureSafeToHandOutCSSRules();
896 // Mark an area as invalidated, associated with a given transaction id
897 // (allocated by nsRefreshDriver::GetTransactionId). Invalidated regions will
898 // be dispatched to MozAfterPaint events when NotifyDidPaintForSubtree is
899 // called for the transaction id (or any higher id).
900 void NotifyInvalidation(TransactionId aTransactionId
, const nsRect
& aRect
);
901 // aRect is in device pixels
902 void NotifyInvalidation(TransactionId aTransactionId
, const nsIntRect
& aRect
);
903 void NotifyDidPaintForSubtree(
904 TransactionId aTransactionId
= TransactionId
{0},
905 const mozilla::TimeStamp
& aTimeStamp
= mozilla::TimeStamp());
906 void NotifyRevokingDidPaint(TransactionId aTransactionId
);
907 void FireDOMPaintEvent(nsTArray
<nsRect
>* aList
, TransactionId aTransactionId
,
908 mozilla::TimeStamp aTimeStamp
= mozilla::TimeStamp());
910 // Callback for catching invalidations in ContainerLayers
911 // Passed to LayerProperties::ComputeDifference
912 static void NotifySubDocInvalidation(
913 mozilla::layers::ContainerLayer
* aContainer
, const nsIntRegion
* aRegion
);
914 void SetNotifySubDocInvalidationData(
915 mozilla::layers::ContainerLayer
* aContainer
);
916 static void ClearNotifySubDocInvalidationData(
917 mozilla::layers::ContainerLayer
* aContainer
);
918 bool IsDOMPaintEventPending();
921 * Returns the RestyleManager's restyle generation counter.
923 uint64_t GetRestyleGeneration() const;
924 uint64_t GetUndisplayedRestyleGeneration() const;
927 * Returns whether there are any pending restyles or reflows.
929 bool HasPendingRestyleOrReflow();
932 * Notify the prescontext that the presshell is about to reflow a reflow root.
933 * The single argument indicates whether this reflow should be interruptible.
934 * If aInterruptible is false then CheckForInterrupt and HasPendingInterrupt
935 * will always return false. If aInterruptible is true then CheckForInterrupt
936 * will return true when a pending event is detected. This is for use by the
937 * presshell only. Reflow code wanting to prevent interrupts should use
938 * InterruptPreventer.
940 void ReflowStarted(bool aInterruptible
);
943 * A class that can be used to temporarily disable reflow interruption.
945 class InterruptPreventer
;
946 friend class InterruptPreventer
;
947 class MOZ_STACK_CLASS InterruptPreventer
{
949 explicit InterruptPreventer(nsPresContext
* aCtx
)
951 mInterruptsEnabled(aCtx
->mInterruptsEnabled
),
952 mHasPendingInterrupt(aCtx
->mHasPendingInterrupt
) {
953 mCtx
->mInterruptsEnabled
= false;
954 mCtx
->mHasPendingInterrupt
= false;
956 ~InterruptPreventer() {
957 mCtx
->mInterruptsEnabled
= mInterruptsEnabled
;
958 mCtx
->mHasPendingInterrupt
= mHasPendingInterrupt
;
963 bool mInterruptsEnabled
;
964 bool mHasPendingInterrupt
;
968 * Check for interrupts. This may return true if a pending event is
969 * detected. Once it has returned true, it will keep returning true
970 * until ReflowStarted is called. In all cases where this returns true,
971 * the passed-in frame (which should be the frame whose reflow will be
972 * interrupted if true is returned) will be passed to
973 * PresShell::FrameNeedsToContinueReflow.
975 bool CheckForInterrupt(nsIFrame
* aFrame
);
977 * Returns true if CheckForInterrupt has returned true since the last
978 * ReflowStarted call. Cannot itself trigger an interrupt check.
980 bool HasPendingInterrupt() { return mHasPendingInterrupt
; }
982 * Sets a flag that will trip a reflow interrupt. This only bypasses the
983 * interrupt timeout and the pending event check; other checks such as whether
984 * interrupts are enabled and the interrupt check skipping still take effect.
986 void SetPendingInterruptFromTest() { mPendingInterruptFromTest
= true; }
989 * If we have a presshell, and if the given content's current
990 * document is the same as our presshell's document, return the
991 * content's primary frame. Otherwise, return null. Only use this
992 * if you care about which presshell the primary frame is in.
994 nsIFrame
* GetPrimaryFrameFor(nsIContent
* aContent
);
996 virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf
) const;
997 virtual size_t SizeOfIncludingThis(
998 mozilla::MallocSizeOf aMallocSizeOf
) const {
999 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf
);
1003 * Deprecated. Please use the InProcess or CrossProcess variants
1004 * to specify which behaviour you want.
1006 bool IsRootContentDocument() const;
1009 * We are a root content document in process if: we are not a resource doc, we
1010 * are not chrome, and we either have no parent in the current process or our
1013 bool IsRootContentDocumentInProcess() const;
1016 * We are a root content document cross process if: we are not a resource doc,
1017 * we are not chrome, and we either have no parent in any process or our
1020 bool IsRootContentDocumentCrossProcess() const;
1022 bool HadNonBlankPaint() const { return mHadNonBlankPaint
; }
1023 bool HadContentfulPaint() const { return mHadContentfulPaint
; }
1024 void NotifyNonBlankPaint();
1025 void NotifyContentfulPaint();
1026 void NotifyPaintStatusReset();
1027 void NotifyDOMContentFlushed();
1029 bool HasEverBuiltInvisibleText() const { return mHasEverBuiltInvisibleText
; }
1030 void SetBuiltInvisibleText() { mHasEverBuiltInvisibleText
= true; }
1032 bool UsesExChUnits() const { return mUsesExChUnits
; }
1034 void SetUsesExChUnits(bool aValue
) { mUsesExChUnits
= aValue
; }
1036 bool IsDeviceSizePageSize();
1038 bool HasWarnedAboutPositionedTableParts() const {
1039 return mHasWarnedAboutPositionedTableParts
;
1042 void SetHasWarnedAboutPositionedTableParts() {
1043 mHasWarnedAboutPositionedTableParts
= true;
1046 bool HasWarnedAboutTooLargeDashedOrDottedRadius() const {
1047 return mHasWarnedAboutTooLargeDashedOrDottedRadius
;
1050 void SetHasWarnedAboutTooLargeDashedOrDottedRadius() {
1051 mHasWarnedAboutTooLargeDashedOrDottedRadius
= true;
1054 nsBidi
& GetBidiEngine();
1056 gfxFontFeatureValueSet
* GetFontFeatureValuesLookup() const {
1057 return mFontFeatureValuesLookup
;
1061 friend class nsRunnableMethod
<nsPresContext
>;
1062 void ThemeChangedInternal();
1063 void RefreshSystemMetrics();
1065 // update device context's resolution from the widget
1066 void UIResolutionChangedInternal();
1068 // if aScale > 0.0, use it as resolution scale factor to the device context
1069 // (otherwise get it from the widget)
1070 void UIResolutionChangedInternalScale(double aScale
);
1072 void SetImgAnimations(nsIContent
* aParent
, uint16_t aMode
);
1073 void SetSMILAnimations(mozilla::dom::Document
* aDoc
, uint16_t aNewMode
,
1076 static void PreferenceChanged(const char* aPrefName
, void* aSelf
);
1077 void PreferenceChanged(const char* aPrefName
);
1079 void UpdateAfterPreferencesChanged();
1080 void DispatchPrefChangedRunnableIfNeeded();
1082 void GetUserPreferences();
1084 void UpdateCharSet(NotNull
<const Encoding
*> aCharSet
);
1087 // Used by the PresShell to force a reflow when some aspect of font info
1088 // has been updated, potentially affecting font selection and layout.
1089 void ForceReflowForFontInfoUpdate();
1092 * Checks for MozAfterPaint listeners on the document
1094 bool MayHavePaintEventListener();
1097 * Checks for MozAfterPaint listeners on the document and
1098 * any subdocuments, except for subdocuments that are non-top-level
1099 * content documents.
1101 bool MayHavePaintEventListenerInSubDocument();
1103 void InvalidatePaintedLayers();
1105 uint32_t GetNextFrameRateMultiplier() const {
1106 return mNextFrameRateMultiplier
;
1109 void DidUseFrameRateMultiplier() {
1110 if (!mNextFrameRateMultiplier
) {
1111 mNextFrameRateMultiplier
= 1;
1112 } else if (mNextFrameRateMultiplier
< 8) {
1113 mNextFrameRateMultiplier
= mNextFrameRateMultiplier
* 2;
1118 // May be called multiple times (unlink, destructor)
1121 void AppUnitsPerDevPixelChanged();
1123 bool HavePendingInputEvent();
1125 // Creates a one-shot timer with the given aCallback & aDelay.
1126 // Returns a refcounted pointer to the timer (or nullptr on failure).
1127 already_AddRefed
<nsITimer
> CreateTimer(nsTimerCallbackFunc aCallback
,
1128 const char* aName
, uint32_t aDelay
);
1130 struct TransactionInvalidations
{
1131 TransactionId mTransactionId
;
1132 nsTArray
<nsRect
> mInvalidations
;
1133 bool mIsWaitingForPreviousTransaction
= false;
1135 TransactionInvalidations
* GetInvalidations(TransactionId aTransactionId
);
1137 // This should be called only when we update mVisibleArea or
1138 // mDynamicToolbarMaxHeight or `app units per device pixels` changes.
1139 void AdjustSizeForViewportUnits();
1141 // IMPORTANT: The ownership implicit in the following member variables
1142 // has been explicitly checked. If you add any members to this class,
1143 // please make the ownership explicit (pinkerton, scc).
1145 // the PresShell owns a strong reference to the nsPresContext, and is
1146 // responsible for nulling this pointer before it is destroyed
1147 mozilla::PresShell
* MOZ_NON_OWNING_REF mPresShell
; // [WEAK]
1148 RefPtr
<mozilla::dom::Document
> mDocument
;
1149 RefPtr
<nsDeviceContext
> mDeviceContext
; // [STRONG] could be weak, but
1150 // better safe than sorry.
1151 // Cannot reintroduce cycles
1152 // since there is no dependency
1153 // from gfx back to layout.
1154 RefPtr
<mozilla::EventStateManager
> mEventManager
;
1155 RefPtr
<nsRefreshDriver
> mRefreshDriver
;
1156 RefPtr
<mozilla::AnimationEventDispatcher
> mAnimationEventDispatcher
;
1157 RefPtr
<mozilla::EffectCompositor
> mEffectCompositor
;
1158 mozilla::UniquePtr
<nsTransitionManager
> mTransitionManager
;
1159 mozilla::UniquePtr
<nsAnimationManager
> mAnimationManager
;
1160 mozilla::UniquePtr
<mozilla::RestyleManager
> mRestyleManager
;
1161 RefPtr
<mozilla::CounterStyleManager
> mCounterStyleManager
;
1162 const nsStaticAtom
* mMedium
;
1163 RefPtr
<gfxFontFeatureValueSet
> mFontFeatureValuesLookup
;
1165 // TODO(emilio): Maybe lazily create and put under a UniquePtr if this grows a
1167 MediaEmulationData mMediaEmulationData
;
1169 float mSystemFontScale
; // Internal text zoom factor, defaults to 1.0
1170 float mTextZoom
; // Text zoom, defaults to 1.0
1171 float mEffectiveTextZoom
; // Text zoom * system font scale
1172 float mFullZoom
; // Page zoom, defaults to 1.0
1173 gfxSize mLastFontInflationScreenSize
;
1175 int32_t mCurAppUnitsPerDevPixel
;
1176 int32_t mAutoQualityMinFontSizePixelsPref
;
1178 nsCOMPtr
<nsITheme
> mTheme
;
1179 nsCOMPtr
<nsIPrintSettings
> mPrintSettings
;
1181 mozilla::UniquePtr
<nsBidi
> mBidiEngine
;
1183 AutoTArray
<TransactionInvalidations
, 4> mTransactions
;
1185 // text performance metrics
1186 mozilla::UniquePtr
<gfxTextPerfMetrics
> mTextPerf
;
1188 mozilla::UniquePtr
<FontMatchingStats
> mFontStats
;
1190 mozilla::UniquePtr
<gfxMissingFontRecorder
> mMissingFonts
;
1192 nsRect mVisibleArea
;
1193 // This value is used to resolve viewport units.
1194 // On mobile this size is including the dynamic toolbar maximum height below.
1195 // On desktops this size is pretty much the same as |mVisibleArea|.
1196 nsSize mSizeForViewportUnits
;
1197 // The maximum height of the dynamic toolbar on mobile.
1198 mozilla::ScreenIntCoord mDynamicToolbarMaxHeight
;
1199 mozilla::ScreenIntCoord mDynamicToolbarHeight
;
1200 // Safe area insets support
1201 mozilla::ScreenIntMargin mSafeAreaInsets
;
1204 // The computed page margins from the print settings.
1206 // This margin will be used for each page in the current print operation, by
1207 // default (i.e. unless overridden by @page rules).
1209 // FIXME(emilio): Maybe we could let a global @page rule do that, though it's
1210 // sketchy at best, see https://github.com/w3c/csswg-drafts/issues/5437 for
1212 nsMargin mDefaultPageMargin
;
1216 // This is a non-owning pointer. May be null. If non-null, it's guaranteed to
1217 // be pointing to an element that's still alive, because we'll reset it in
1218 // UpdateViewportScrollStylesOverride() as part of the cleanup code when
1219 // this element is removed from the document. (For <body> and the root
1220 // element, this call happens in nsCSSFrameConstructor::ContentRemoved(). For
1221 // fullscreen elements, it happens in the fullscreen-specific cleanup invoked
1222 // by Element::UnbindFromTree().)
1223 mozilla::dom::Element
* MOZ_NON_OWNING_REF mViewportScrollOverrideElement
;
1225 // Counters for tests and tools that want to detect frame construction
1227 uint64_t mElementsRestyled
;
1228 uint64_t mFramesConstructed
;
1229 uint64_t mFramesReflowed
;
1231 mozilla::TimeStamp mReflowStartTime
;
1233 Maybe
<TransactionId
> mFirstContentfulPaintTransactionId
;
1235 mozilla::UniquePtr
<mozilla::MediaFeatureChange
>
1236 mPendingMediaFeatureValuesChange
;
1238 // Time of various first interaction types, used to report time from
1239 // first paint of the top level content pres shell to first interaction.
1240 mozilla::TimeStamp mFirstNonBlankPaintTime
;
1241 mozilla::TimeStamp mFirstClickTime
;
1242 mozilla::TimeStamp mFirstKeyTime
;
1243 mozilla::TimeStamp mFirstMouseMoveTime
;
1244 mozilla::TimeStamp mFirstScrollTime
;
1246 // last time we did a full style flush
1247 mozilla::TimeStamp mLastStyleUpdateForAllAnimations
;
1249 nsChangeHint mChangeHintForPrefChange
;
1251 uint32_t mInterruptChecksToSkip
;
1253 // During page load we use slower frame rate.
1254 uint32_t mNextFrameRateMultiplier
;
1256 nsTArray
<RefPtr
<mozilla::ManagedPostRefreshObserver
>>
1257 mManagedPostRefreshObservers
;
1259 ScrollStyles mViewportScrollStyles
;
1261 uint16_t mImageAnimationMode
;
1262 uint16_t mImageAnimationModePref
;
1264 nsPresContextType mType
;
1267 // The following are public member variables so that we can use them
1268 // with mozilla::AutoToggle or mozilla::AutoRestore.
1270 // Should we disable font size inflation because we're inside of
1271 // shrink-wrapping calculations on an inflation container?
1272 bool mInflationDisabledForShrinkWrap
;
1275 static constexpr size_t kThemeChangeKindBits
= 2;
1276 static_assert(unsigned(mozilla::widget::ThemeChangeKind::AllBits
) <=
1277 (1u << kThemeChangeKindBits
) - 1,
1278 "theme change kind doesn't fit");
1280 unsigned mInteractionTimeEnabled
: 1;
1281 unsigned mHasPendingInterrupt
: 1;
1282 unsigned mHasEverBuiltInvisibleText
: 1;
1283 unsigned mPendingInterruptFromTest
: 1;
1284 unsigned mInterruptsEnabled
: 1;
1285 unsigned mSendAfterPaintToContent
: 1;
1286 unsigned mDrawImageBackground
: 1;
1287 unsigned mDrawColorBackground
: 1;
1288 unsigned mNeverAnimate
: 1;
1289 unsigned mPaginated
: 1;
1290 unsigned mCanPaginatedScroll
: 1;
1291 unsigned mDoScaledTwips
: 1;
1292 unsigned mIsRootPaginatedDocument
: 1;
1293 unsigned mPrefBidiDirection
: 1;
1294 unsigned mPrefScrollbarSide
: 2;
1295 unsigned mPendingThemeChanged
: 1;
1296 // widget::ThemeChangeKind
1297 unsigned mPendingThemeChangeKind
: kThemeChangeKindBits
;
1298 unsigned mPendingUIResolutionChanged
: 1;
1299 unsigned mPostedPrefChangedRunnable
: 1;
1301 // Are we currently drawing an SVG glyph?
1302 unsigned mIsGlyph
: 1;
1304 // Does the associated document use ex or ch units?
1306 // TODO(emilio): It's a bit weird that this lives here but all the other
1307 // relevant bits live in Device on the rust side.
1308 unsigned mUsesExChUnits
: 1;
1310 // Is the current mCounterStyleManager valid?
1311 unsigned mCounterStylesDirty
: 1;
1313 // Is the current mFontFeatureValuesLookup valid?
1314 unsigned mFontFeatureValuesDirty
: 1;
1316 // resize reflow is suppressed when the only change has been to zoom
1317 // the document rather than to change the document's dimensions
1318 unsigned mSuppressResizeReflow
: 1;
1320 unsigned mIsVisual
: 1;
1322 // Should we paint flash in this context? Do not use this variable directly.
1323 // Use GetPaintFlashing() method instead.
1324 mutable unsigned mPaintFlashing
: 1;
1325 mutable unsigned mPaintFlashingInitialized
: 1;
1327 unsigned mHasWarnedAboutPositionedTableParts
: 1;
1329 unsigned mHasWarnedAboutTooLargeDashedOrDottedRadius
: 1;
1331 // Have we added quirk.css to the style set?
1332 unsigned mQuirkSheetAdded
: 1;
1334 // Has NotifyNonBlankPaint been called on this PresContext?
1335 unsigned mHadNonBlankPaint
: 1;
1336 // Has NotifyContentfulPaint been called on this PresContext?
1337 unsigned mHadContentfulPaint
: 1;
1338 // True when a contentful paint has happened and this paint doesn't
1339 // come from the regular tick process. Usually this means a
1340 // contentful paint was triggered manually.
1341 unsigned mHadNonTickContentfulPaint
: 1;
1343 // Has NotifyDidPaintForSubtree been called for a contentful paint?
1344 unsigned mHadContentfulPaintComposite
: 1;
1347 unsigned mInitialized
: 1;
1351 virtual ~nsPresContext();
1355 nsITheme
* EnsureTheme();
1359 friend struct nsAutoLayoutPhase
;
1360 mozilla::EnumeratedArray
<nsLayoutPhase
, nsLayoutPhase::COUNT
, uint32_t>
1364 uint32_t LayoutPhaseCount(nsLayoutPhase aPhase
) {
1365 return mLayoutPhaseCount
[aPhase
];
1370 class nsRootPresContext final
: public nsPresContext
{
1372 nsRootPresContext(mozilla::dom::Document
* aDocument
, nsPresContextType aType
);
1373 virtual bool IsRoot() override
{ return true; }
1376 * Add a runnable that will get called before the next paint. They will get
1377 * run eventually even if painting doesn't happen. They might run well before
1380 void AddWillPaintObserver(nsIRunnable
* aRunnable
);
1383 * Run all runnables that need to get called before the next paint.
1385 void FlushWillPaintObservers();
1387 virtual size_t SizeOfExcludingThis(
1388 mozilla::MallocSizeOf aMallocSizeOf
) const override
;
1391 class RunWillPaintObservers
: public mozilla::Runnable
{
1393 explicit RunWillPaintObservers(nsRootPresContext
* aPresContext
)
1394 : Runnable("nsPresContextType::RunWillPaintObservers"),
1395 mPresContext(aPresContext
) {}
1396 void Revoke() { mPresContext
= nullptr; }
1397 NS_IMETHOD
Run() override
{
1399 mPresContext
->FlushWillPaintObservers();
1403 // The lifetime of this reference is handled by an nsRevocableEventPtr
1404 nsRootPresContext
* MOZ_NON_OWNING_REF mPresContext
;
1407 friend class nsPresContext
;
1409 nsTArray
<nsCOMPtr
<nsIRunnable
>> mWillPaintObservers
;
1410 nsRevocableEventPtr
<RunWillPaintObservers
> mWillPaintFallbackEvent
;
1413 #ifdef MOZ_REFLOW_PERF
1415 # define DO_GLOBAL_REFLOW_COUNT(_name) \
1416 aPresContext->CountReflows((_name), (nsIFrame*)this);
1418 # define DO_GLOBAL_REFLOW_COUNT(_name)
1419 #endif // MOZ_REFLOW_PERF
1421 #endif /* nsPresContext_h___ */