Merge mozilla-central to autoland. a=merge CLOSED TREE
[gecko.git] / layout / base / PresShell.h
blob482ace1421cdadb07248ad680bdf4d624e3904c8
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 2 */
9 #ifndef mozilla_PresShell_h
10 #define mozilla_PresShell_h
12 #include "DepthOrderedFrameList.h"
13 #include "mozilla/PresShellForwards.h"
15 #include <stdio.h> // for FILE definition
16 #include "FrameMetrics.h"
17 #include "LayoutConstants.h"
18 #include "TouchManager.h"
19 #include "Units.h"
20 #include "Visibility.h"
21 #include "mozilla/ArenaObjectID.h"
22 #include "mozilla/Attributes.h"
23 #include "mozilla/FlushType.h"
24 #include "mozilla/Logging.h"
25 #include "mozilla/MemoryReporting.h"
26 #include "mozilla/ScrollTypes.h"
27 #include "mozilla/StaticPtr.h"
28 #include "mozilla/UniquePtr.h"
29 #include "mozilla/WeakPtr.h"
30 #include "mozilla/dom/DocumentBinding.h"
31 #include "mozilla/layers/FocusTarget.h"
32 #include "mozilla/layout/LayoutTelemetryTools.h"
33 #include "mozilla/widget/ThemeChangeKind.h"
34 #include "nsColor.h"
35 #include "nsCOMArray.h"
36 #include "nsCoord.h"
37 #include "nsDOMNavigationTiming.h"
38 #include "nsFrameManager.h"
39 #include "nsFrameState.h"
40 #include "nsIContent.h"
41 #include "nsIObserver.h"
42 #include "nsISelectionController.h"
43 #include "nsQueryFrame.h"
44 #include "nsPresArena.h"
45 #include "nsPresContext.h"
46 #include "nsRect.h"
47 #include "nsRefreshObservers.h"
48 #include "nsStringFwd.h"
49 #include "nsStubDocumentObserver.h"
50 #include "nsTHashSet.h"
51 #include "nsThreadUtils.h"
52 #include "nsWeakReference.h"
53 #ifdef ACCESSIBILITY
54 # include "nsAccessibilityService.h"
55 #endif
57 class AutoPointerEventTargetUpdater;
58 class AutoWeakFrame;
59 class gfxContext;
60 class MobileViewportManager;
61 class nsAutoCauseReflowNotifier;
62 class nsCanvasFrame;
63 class nsCaret;
64 class nsCSSFrameConstructor;
65 class nsDocShell;
66 class nsFrameSelection;
67 class nsIDocShell;
68 class nsIFrame;
69 class nsILayoutHistoryState;
70 class nsINode;
71 class nsPageSequenceFrame;
72 class nsIReflowCallback;
73 class nsIScrollableFrame;
74 class nsITimer;
75 class nsPIDOMWindowOuter;
76 class nsPresShellEventCB;
77 class nsRange;
78 class nsRefreshDriver;
79 class nsRegion;
80 class nsView;
81 class nsViewManager;
82 class nsWindowSizes;
83 struct RangePaintInfo;
84 #ifdef MOZ_REFLOW_PERF
85 class ReflowCountMgr;
86 #endif
87 class WeakFrame;
88 class nsTextFrame;
89 class ZoomConstraintsClient;
91 struct nsCallbackEventRequest;
93 namespace mozilla {
94 class nsDisplayList;
95 class nsDisplayListBuilder;
96 class FallbackRenderer;
98 class AccessibleCaretEventHub;
99 class GeckoMVMContext;
100 class OverflowChangedTracker;
101 class StyleSheet;
103 class ProfileChunkedBuffer;
105 #ifdef ACCESSIBILITY
106 namespace a11y {
107 class DocAccessible;
108 } // namespace a11y
109 #endif
111 namespace dom {
112 class BrowserParent;
113 class Element;
114 class Event;
115 class HTMLSlotElement;
116 class Selection;
117 class PerformanceMainThread;
118 } // namespace dom
120 namespace gfx {
121 class SourceSurface;
122 } // namespace gfx
124 namespace layers {
125 class LayerManager;
126 struct LayersId;
127 } // namespace layers
129 namespace layout {
130 class ScrollAnchorContainer;
131 } // namespace layout
133 // 039d8ffc-fa55-42d7-a53a-388cb129b052
134 #define NS_PRESSHELL_IID \
136 0x039d8ffc, 0xfa55, 0x42d7, { \
137 0xa5, 0x3a, 0x38, 0x8c, 0xb1, 0x29, 0xb0, 0x52 \
141 #undef NOISY_INTERRUPTIBLE_REFLOW
144 * Presentation shell. Presentation shells are the controlling point for
145 * managing the presentation of a document. The presentation shell holds a
146 * live reference to the document, the presentation context, the style
147 * manager, the style set and the root frame.
149 * When this object is Release'd, it will release the document, the
150 * presentation context, the style manager, the style set and the root frame.
153 class PresShell final : public nsStubDocumentObserver,
154 public nsISelectionController,
155 public nsIObserver,
156 public nsSupportsWeakReference {
157 typedef dom::Document Document;
158 typedef dom::Element Element;
159 typedef gfx::SourceSurface SourceSurface;
160 typedef layers::FocusTarget FocusTarget;
161 typedef layers::FrameMetrics FrameMetrics;
162 typedef layers::LayerManager LayerManager;
164 // A set type for tracking visible frames, for use by the visibility code in
165 // PresShell. The set contains nsIFrame* pointers.
166 typedef nsTHashSet<nsIFrame*> VisibleFrames;
168 public:
169 explicit PresShell(Document* aDocument);
171 // nsISupports
172 NS_DECL_ISUPPORTS
174 NS_DECLARE_STATIC_IID_ACCESSOR(NS_PRESSHELL_IID)
176 static bool AccessibleCaretEnabled(nsIDocShell* aDocShell);
179 * Return the active content currently capturing the mouse if any.
181 static nsIContent* GetCapturingContent() {
182 return sCapturingContentInfo.mContent;
187 static dom::BrowserParent* GetCapturingRemoteTarget() {
188 MOZ_ASSERT(XRE_IsParentProcess());
189 return sCapturingContentInfo.mRemoteTarget;
193 * Allow or disallow mouse capturing.
195 static void AllowMouseCapture(bool aAllowed) {
196 sCapturingContentInfo.mAllowed = aAllowed;
200 * Returns true if there is an active mouse capture that wants to prevent
201 * drags.
203 static bool IsMouseCapturePreventingDrag() {
204 return sCapturingContentInfo.mPreventDrag && sCapturingContentInfo.mContent;
207 static void ClearMouseCaptureOnView(nsView* aView);
209 // Clear the capture content if it exists in this process.
210 static void ClearMouseCapture();
212 // If a frame in the subtree rooted at aFrame is capturing the mouse then
213 // clears that capture.
215 // NOTE(emilio): This is needed only so that mouse events captured by a remote
216 // frame don't remain being captured by the frame while hidden, see
217 // dom/events/test/browser_mouse_enterleave_switch_tab.js, which is the only
218 // test that meaningfully exercises this code path.
220 // We could consider maybe removing this, since the capturing content gets
221 // reset on mouse/pointerdown? Or maybe exposing an API so that the front-end
222 // does this.
223 static void ClearMouseCapture(nsIFrame* aFrame);
225 #ifdef ACCESSIBILITY
227 * Return the document accessible for this PresShell if there is one.
229 a11y::DocAccessible* GetDocAccessible() const { return mDocAccessible; }
232 * Set the document accessible for this PresShell.
234 void SetDocAccessible(a11y::DocAccessible* aDocAccessible) {
235 mDocAccessible = aDocAccessible;
237 #endif // #ifdef ACCESSIBILITY
240 * See `mLastOverWindowPointerLocation`.
242 const nsPoint& GetLastOverWindowPointerLocation() const {
243 return mLastOverWindowPointerLocation;
246 MOZ_CAN_RUN_SCRIPT void Init(nsPresContext*, nsViewManager*);
249 * All callers are responsible for calling |Destroy| after calling
250 * |EndObservingDocument|. It needs to be separate only because form
251 * controls incorrectly store their data in the frames rather than the
252 * content model and printing calls |EndObservingDocument| multiple
253 * times to make form controls behave nicely when printed.
255 void Destroy();
257 bool IsDestroying() { return mIsDestroying; }
260 * All frames owned by the shell are allocated from an arena. They
261 * are also recycled using free lists. Separate free lists are
262 * maintained for each frame type (aID), which must always correspond
263 * to the same aSize value. AllocateFrame is infallible and will abort
264 * on out-of-memory.
266 void* AllocateFrame(nsQueryFrame::FrameIID aID, size_t aSize) {
267 #define FRAME_ID(classname, ...) \
268 static_assert(size_t(nsQueryFrame::FrameIID::classname##_id) == \
269 size_t(eArenaObjectID_##classname), \
270 "");
271 #define ABSTRACT_FRAME_ID(classname) \
272 static_assert(size_t(nsQueryFrame::FrameIID::classname##_id) == \
273 size_t(eArenaObjectID_##classname), \
274 "");
275 #include "mozilla/FrameIdList.h"
276 #undef FRAME_ID
277 #undef ABSTRACT_FRAME_ID
278 return AllocateByObjectID(ArenaObjectID(size_t(aID)), aSize);
281 void FreeFrame(nsQueryFrame::FrameIID aID, void* aPtr) {
282 return FreeByObjectID(ArenaObjectID(size_t(aID)), aPtr);
285 void* AllocateByObjectID(ArenaObjectID aID, size_t aSize) {
286 void* result = mFrameArena.Allocate(aID, aSize);
287 RecordAlloc(result);
288 return result;
291 void FreeByObjectID(ArenaObjectID aID, void* aPtr) {
292 RecordFree(aPtr);
293 if (!mIsDestroying) {
294 mFrameArena.Free(aID, aPtr);
298 Document* GetDocument() const { return mDocument; }
300 nsPresContext* GetPresContext() const { return mPresContext; }
302 nsViewManager* GetViewManager() const { return mViewManager; }
304 nsRefreshDriver* GetRefreshDriver() const;
306 nsCSSFrameConstructor* FrameConstructor() const {
307 return mFrameConstructor.get();
311 * FrameSelection will return the Frame based selection API.
312 * You cannot go back and forth anymore with QI between nsIDOM sel and
313 * nsIFrame sel.
315 already_AddRefed<nsFrameSelection> FrameSelection();
318 * ConstFrameSelection returns an object which methods are safe to use for
319 * example in nsIFrame code.
321 const nsFrameSelection* ConstFrameSelection() const { return mSelection; }
323 // Start receiving notifications from our document. If called after Destroy,
324 // this will be ignored.
325 void BeginObservingDocument();
327 // Stop receiving notifications from our document. If called after Destroy,
328 // this will be ignored.
329 void EndObservingDocument();
331 bool IsObservingDocument() const { return mIsObservingDocument; }
334 * Return whether Initialize() was previously called.
336 bool DidInitialize() const { return mDidInitialize; }
339 * Perform initialization. Constructs the frame for the root content
340 * object and then enqueues a reflow of the frame model.
342 * Callers of this method must hold a reference to this shell that
343 * is guaranteed to survive through arbitrary script execution.
344 * Calling Initialize can execute arbitrary script.
346 MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult Initialize();
349 * Schedule a reflow for the frame model into a new width and height. The
350 * coordinates for aWidth and aHeight must be in standard nscoord's.
352 * Returns whether layout might have changed.
354 MOZ_CAN_RUN_SCRIPT void ResizeReflow(
355 nscoord aWidth, nscoord aHeight,
356 ResizeReflowOptions = ResizeReflowOptions::NoOption);
357 MOZ_CAN_RUN_SCRIPT bool ResizeReflowIgnoreOverride(
358 nscoord aWidth, nscoord aHeight,
359 ResizeReflowOptions = ResizeReflowOptions::NoOption);
360 MOZ_CAN_RUN_SCRIPT void ForceResizeReflowWithCurrentDimensions();
363 * Add this pres shell to the refresh driver to be observed for resize
364 * event if applicable.
366 void AddResizeEventFlushObserverIfNeeded();
369 * Returns true if the document hosted by this presShell is in a devtools
370 * Responsive Design Mode browsing context.
372 bool InRDMPane();
374 #if defined(MOZ_WIDGET_ANDROID)
376 * If the dynamic toolbar is not expanded, notify the app to do so.
378 void MaybeNotifyShowDynamicToolbar();
379 #endif // defined(MOZ_WIDGET_ANDROID)
381 void RefreshZoomConstraintsForScreenSizeChange();
383 private:
385 * This is what ResizeReflowIgnoreOverride does when not shrink-wrapping (that
386 * is, when ResizeReflowOptions::BSizeLimit is not specified).
388 bool SimpleResizeReflow(nscoord aWidth, nscoord aHeight);
390 bool CanHandleUserInputEvents(WidgetGUIEvent* aGUIEvent);
392 public:
394 * Updates pending layout, assuming reasonable (up-to-date, or mid-update for
395 * container queries) styling of the page. Returns whether a reflow did not
396 * get interrupted (and thus layout should be considered fully up-to-date).
398 MOZ_CAN_RUN_SCRIPT_BOUNDARY bool DoFlushLayout(bool aInterruptible);
401 * Note that the assumptions that determine whether we need a mobile viewport
402 * manager may have changed.
404 MOZ_CAN_RUN_SCRIPT void MaybeRecreateMobileViewportManager(
405 bool aAfterInitialization);
408 * Returns true if this document uses mobile viewport sizing (including
409 * processing of <meta name="viewport"> tags).
411 * Note that having a MobileViewportManager does not necessarily mean using
412 * mobile viewport sizing, as with desktop zooming we can have a
413 * MobileViewportManager on desktop, but we only want to do mobile viewport
414 * sizing on mobile. (TODO: Rename MobileViewportManager to reflect its more
415 * general role.)
417 bool UsesMobileViewportSizing() const;
420 * Get the MobileViewportManager used to manage the document's mobile
421 * viewport. Will return null in situations where we don't have a mobile
422 * viewport, and for documents that are not the root content document.
424 RefPtr<MobileViewportManager> GetMobileViewportManager() const;
427 * Return true if the presshell expects layout flush.
429 bool IsLayoutFlushObserver();
432 * Called when document load completes.
434 void LoadComplete();
436 * This calls through to the frame manager to get the root frame.
438 nsIFrame* GetRootFrame() const { return mFrameManager->GetRootFrame(); }
441 * Get root scroll frame from FrameManager()->GetRootFrame().
443 nsIFrame* GetRootScrollFrame() const;
446 * The same as GetRootScrollFrame, but returns an nsIScrollableFrame
448 nsIScrollableFrame* GetRootScrollFrameAsScrollable() const;
451 * Get the current focused content or DOM selection that should be the
452 * target for scrolling.
454 already_AddRefed<nsIContent> GetContentForScrolling() const;
457 * Get the DOM selection that should be the target for scrolling, if there
458 * is no focused content.
460 already_AddRefed<nsIContent> GetSelectedContentForScrolling() const;
463 * Gets nearest scrollable frame from the specified content node. The frame
464 * is scrollable with overflow:scroll or overflow:auto in some direction when
465 * aDirection is eEither. Otherwise, this returns a nearest frame that is
466 * scrollable in the specified direction.
468 nsIScrollableFrame* GetScrollableFrameToScrollForContent(
469 nsIContent* aContent, layers::ScrollDirections aDirections);
472 * Gets nearest scrollable frame from current focused content or DOM
473 * selection if there is no focused content. The frame is scrollable with
474 * overflow:scroll or overflow:auto in some direction when aDirection is
475 * eEither. Otherwise, this returns a nearest frame that is scrollable in
476 * the specified direction.
478 nsIScrollableFrame* GetScrollableFrameToScroll(
479 layers::ScrollDirections aDirections);
482 * Returns the page sequence frame associated with the frame hierarchy.
483 * Returns nullptr if not a paginated view.
485 nsPageSequenceFrame* GetPageSequenceFrame() const;
488 * Returns the canvas frame associated with the frame hierarchy.
489 * Returns nullptr if is XUL document.
491 nsCanvasFrame* GetCanvasFrame() const;
493 void PostPendingScrollAnchorSelection(
494 layout::ScrollAnchorContainer* aContainer);
495 void FlushPendingScrollAnchorSelections();
496 void PostPendingScrollAnchorAdjustment(
497 layout::ScrollAnchorContainer* aContainer);
499 void PostPendingScrollResnap(nsIScrollableFrame* aScrollableFrame);
500 void FlushPendingScrollResnap();
502 void CancelAllPendingReflows();
504 MOZ_CAN_RUN_SCRIPT_BOUNDARY void NotifyCounterStylesAreDirty();
506 bool FrameIsAncestorOfDirtyRoot(nsIFrame* aFrame) const;
509 * Destroy the frames for aElement, and reconstruct them asynchronously if
510 * needed.
512 * Note that this may destroy frames for an arbitrary ancestor, depending on
513 * the frame tree structure.
515 void DestroyFramesForAndRestyle(Element* aElement);
518 * Called when a ShadowRoot will be attached to an element (and thus the flat
519 * tree children will go away).
521 void ShadowRootWillBeAttached(Element& aElement);
524 * Handles all the layout stuff needed when the slot assignment for an element
525 * is about to change.
527 * Only called when the slot attribute of the element changes, the rest of
528 * the changes should be handled in ShadowRoot.
530 void SlotAssignmentWillChange(Element& aElement,
531 dom::HTMLSlotElement* aOldSlot,
532 dom::HTMLSlotElement* aNewSlot);
534 void PostRecreateFramesFor(Element*);
535 void RestyleForAnimation(Element*, RestyleHint);
538 * Determine if it is safe to flush all pending notifications.
540 bool IsSafeToFlush() const;
543 * Informs the document's FontFaceSet that the refresh driver ticked,
544 * flushing style and layout.
546 void NotifyFontFaceSetOnRefresh();
548 // Removes ourself from the list of layout / style / and resize refresh driver
549 // observers.
551 // Right now this is only used for documents in the BFCache, so if you want to
552 // use this for anything else you need to ensure we don't end up in those
553 // lists after calling this, but before calling StartObservingRefreshDriver
554 // again.
556 // That is handled by the mDocument->GetBFCacheEntry checks in
557 // DoObserve*Flushes functions, though that could conceivably become a boolean
558 // member in the shell if needed.
560 // Callers are responsible of manually calling StartObservingRefreshDriver
561 // again.
562 void StopObservingRefreshDriver();
563 void StartObservingRefreshDriver();
565 bool ObservingStyleFlushes() const { return mObservingStyleFlushes; }
566 bool ObservingLayoutFlushes() const { return mObservingLayoutFlushes; }
568 void ObserveStyleFlushes() {
569 if (!ObservingStyleFlushes()) {
570 DoObserveStyleFlushes();
575 * Callbacks will be called even if reflow itself fails for
576 * some reason.
578 nsresult PostReflowCallback(nsIReflowCallback* aCallback);
579 void CancelReflowCallback(nsIReflowCallback* aCallback);
581 void ScheduleBeforeFirstPaint();
582 void UnsuppressAndInvalidate();
584 void ClearFrameRefs(nsIFrame* aFrame);
586 // Clears the selection of the older focused frame selection if any.
587 void FrameSelectionWillTakeFocus(nsFrameSelection&);
589 // Clears and repaint mFocusedFrameSelection if it matches the argument.
590 void FrameSelectionWillLoseFocus(nsFrameSelection&);
593 * Get a reference rendering context. This is a context that should not
594 * be rendered to, but is suitable for measuring text and performing
595 * other non-rendering operations. Guaranteed to return non-null.
597 mozilla::UniquePtr<gfxContext> CreateReferenceRenderingContext();
600 * Scrolls the view of the document so that the given area of a frame
601 * is visible, if possible. Layout is not flushed before scrolling.
603 * @param aRect Relative to aTargetFrame. If none, the bounding box of
604 * aTargetFrame will be used. The rect edges will be respected even if the
605 * rect is empty.
606 * @param aVertical see ScrollContentIntoView and ScrollAxis
607 * @param aHorizontal see ScrollContentIntoView and ScrollAxis
608 * @param aScrollFlags if ScrollFirstAncestorOnly is set, only the
609 * nearest scrollable ancestor is scrolled, otherwise all
610 * scrollable ancestors may be scrolled if necessary
611 * if ScrollOverflowHidden is set then we may scroll in a direction
612 * even if overflow:hidden is specified in that direction; otherwise
613 * we will not scroll in that direction when overflow:hidden is
614 * set for that direction
615 * If ScrollNoParentFrames is set then we only scroll
616 * nodes in this document, not in any parent documents which
617 * contain this document in a iframe or the like.
618 * @return true if any scrolling happened, false if no scrolling happened
620 MOZ_CAN_RUN_SCRIPT
621 bool ScrollFrameIntoView(nsIFrame* aTargetFrame,
622 const Maybe<nsRect>& aKnownRectRelativeToTarget,
623 ScrollAxis aVertical, ScrollAxis aHorizontal,
624 ScrollFlags aScrollFlags);
627 * Suppress notification of the frame manager that frames are
628 * being destroyed.
630 void SetIgnoreFrameDestruction(bool aIgnore);
633 * Get the AccessibleCaretEventHub, if it exists. AddRefs it.
635 already_AddRefed<AccessibleCaretEventHub> GetAccessibleCaretEventHub() const;
638 * Get the caret, if it exists. AddRefs it.
640 already_AddRefed<nsCaret> GetCaret() const;
643 * Set the current caret to a new caret. To undo this, call RestoreCaret.
645 void SetCaret(nsCaret* aNewCaret);
648 * Restore the caret to the original caret that this pres shell was created
649 * with.
651 void RestoreCaret();
653 dom::Selection* GetCurrentSelection(SelectionType aSelectionType);
656 * Gets the last selection that took focus in this document. This is basically
657 * the frame selection that's visible to the user.
659 nsFrameSelection* GetLastFocusedFrameSelection();
662 * Interface to dispatch events via the presshell
663 * @note The caller must have a strong reference to the PresShell.
665 MOZ_CAN_RUN_SCRIPT
666 nsresult HandleEventWithTarget(WidgetEvent* aEvent, nsIFrame* aFrame,
667 nsIContent* aContent,
668 nsEventStatus* aEventStatus,
669 bool aIsHandlingNativeEvent = false,
670 nsIContent** aTargetContent = nullptr,
671 nsIContent* aOverrideClickTarget = nullptr) {
672 MOZ_ASSERT(aEvent);
673 EventHandler eventHandler(*this);
674 return eventHandler.HandleEventWithTarget(
675 aEvent, aFrame, aContent, aEventStatus, aIsHandlingNativeEvent,
676 aTargetContent, aOverrideClickTarget);
680 * Dispatch event to content only (NOT full processing)
682 MOZ_CAN_RUN_SCRIPT
683 nsresult HandleDOMEventWithTarget(nsIContent* aTargetContent,
684 WidgetEvent* aEvent,
685 nsEventStatus* aStatus);
688 * Dispatch event to content only (NOT full processing)
690 MOZ_CAN_RUN_SCRIPT
691 nsresult HandleDOMEventWithTarget(nsIContent* aTargetContent,
692 dom::Event* aEvent, nsEventStatus* aStatus);
695 * Return whether or not the event is valid to be dispatched
697 bool CanDispatchEvent(const WidgetGUIEvent* aEvent = nullptr) const;
700 * Gets the current target event frame from the PresShell
702 nsIFrame* GetCurrentEventFrame();
705 * Gets the current target event frame from the PresShell
707 already_AddRefed<nsIContent> GetEventTargetContent(WidgetEvent* aEvent);
710 * Get and set the history state for the current document
712 nsresult CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState);
715 * Determine if reflow is currently locked
716 * returns true if reflow is locked, false otherwise
718 bool IsReflowLocked() const { return mIsReflowing; }
721 * Called to find out if painting is suppressed for this presshell. If it is
722 * suppressd, we don't allow the painting of any layer but the background, and
723 * we don't recur into our children.
725 bool IsPaintingSuppressed() const { return mPaintingSuppressed; }
727 void TryUnsuppressPaintingSoon();
729 void UnsuppressPainting();
730 void InitPaintSuppressionTimer();
731 void CancelPaintSuppressionTimer();
734 * Reconstruct frames for all elements in the document
736 MOZ_CAN_RUN_SCRIPT void ReconstructFrames();
739 * See if reflow verification is enabled. To enable reflow verification add
740 * "verifyreflow:1" to your MOZ_LOG environment variable (any non-zero
741 * debug level will work). Or, call SetVerifyReflowEnable with true.
743 static bool GetVerifyReflowEnable();
746 * Set the verify-reflow enable flag.
748 static void SetVerifyReflowEnable(bool aEnabled);
750 nsIFrame* GetAbsoluteContainingBlock(nsIFrame* aFrame);
752 #ifdef MOZ_REFLOW_PERF
753 void DumpReflows();
754 void CountReflows(const char* aName, nsIFrame* aFrame);
755 void PaintCount(const char* aName, gfxContext* aRenderingContext,
756 nsPresContext* aPresContext, nsIFrame* aFrame,
757 const nsPoint& aOffset, uint32_t aColor);
758 void SetPaintFrameCount(bool aOn);
759 bool IsPaintingFrameCounts();
760 #endif // #ifdef MOZ_REFLOW_PERF
762 // Debugging hooks
763 #ifdef DEBUG
764 void ListComputedStyles(FILE* out, int32_t aIndent = 0);
765 #endif
766 #if defined(DEBUG) || defined(MOZ_LAYOUT_DEBUGGER)
767 void ListStyleSheets(FILE* out, int32_t aIndent = 0);
768 #endif
771 * Stop all refresh drivers and carets in this presentation and
772 * in the presentations of subdocuments. Resets painting to a suppressed
773 * state.
774 * XXX this should include image animations
776 void Freeze(bool aIncludeSubDocuments = true);
777 bool IsFrozen() { return mFrozen; }
780 * Restarts refresh drivers in this presentation and in the
781 * presentations of subdocuments, then do a full invalidate of the content
782 * area.
784 void Thaw(bool aIncludeSubDocuments = true);
786 void FireOrClearDelayedEvents(bool aFireEvents);
789 * When this shell is disconnected from its containing docshell, we
790 * lose our container pointer. However, we'd still like to be able to target
791 * user events at the docshell's parent. This pointer allows us to do that.
792 * It should not be used for any other purpose.
794 void SetForwardingContainer(const WeakPtr<nsDocShell>& aContainer);
797 * Render the document into an arbitrary gfxContext
798 * Designed for getting a picture of a document or a piece of a document
799 * Note that callers will generally want to call FlushPendingNotifications
800 * to get an up-to-date view of the document
801 * @param aRect is the region to capture into the offscreen buffer, in the
802 * root frame's coordinate system (if aIgnoreViewportScrolling is false)
803 * or in the root scrolled frame's coordinate system
804 * (if aIgnoreViewportScrolling is true). The coordinates are in appunits.
805 * @param aFlags see below;
806 * set RenderDocumentFlags::IsUntrusted if the contents may be passed to
807 * malicious agents. E.g. we might choose not to paint the contents of
808 * sensitive widgets such as the file name in a file upload widget, and we
809 * might choose not to paint themes.
810 * set RenderDocumentFlags::IgnoreViewportScrolling to ignore clipping and
811 * scrollbar painting due to scrolling in the viewport
812 * set RenderDocumentFlags::ResetViewportScrolling to temporarily set the
813 * viewport scroll position to 0 so that position:fixed elements are drawn
814 * at their initial position.
815 * set RenderDocumentFlags::DrawCaret to draw the caret if one would be
816 * visible (by default the caret is never drawn)
817 * set RenderDocumentFlags::UseWidgetLayers to force rendering to go
818 * through the layer manager for the window. This may be unexpectedly slow
819 * (if the layer manager must read back data from the GPU) or low-quality
820 * (if the layer manager reads back pixel data and scales it
821 * instead of rendering using the appropriate scaling). It may also
822 * slow everything down if the area rendered does not correspond to the
823 * normal visible area of the window.
824 * set RenderDocumentFlags::AsyncDecodeImages to avoid having images
825 * synchronously decoded during rendering.
826 * (by default images decode synchronously with RenderDocument)
827 * set RenderDocumentFlags::DocumentRelative to render the document as if
828 * there has been no scrolling and interpret |aRect| relative to the document
829 * instead of the CSS viewport. Only considered if
830 * RenderDocumentFlags::IgnoreViewportScrolling is set or the document is in
831 * ignore viewport scrolling mode
832 * (PresShell::SetIgnoreViewportScrolling/IgnoringViewportScrolling).
833 * set RenderDocumentFlags::UseHighQualityScaling to enable downscale on
834 * decode for images.
835 * @param aBackgroundColor a background color to render onto
836 * @param aRenderedContext the gfxContext to render to. We render so that
837 * one CSS pixel in the source document is rendered to one unit in the current
838 * transform.
840 nsresult RenderDocument(const nsRect& aRect, RenderDocumentFlags aFlags,
841 nscolor aBackgroundColor,
842 gfxContext* aRenderedContext);
845 * Renders a node aNode to a surface and returns it. The aRegion may be used
846 * to clip the rendering. This region is measured in CSS pixels from the
847 * edge of the presshell area. The aPoint, aScreenRect and aFlags arguments
848 * function in a similar manner as RenderSelection.
850 already_AddRefed<SourceSurface> RenderNode(nsINode* aNode,
851 const Maybe<CSSIntRegion>& aRegion,
852 const LayoutDeviceIntPoint aPoint,
853 LayoutDeviceIntRect* aScreenRect,
854 RenderImageFlags aFlags);
857 * Renders a selection to a surface and returns it. This method is primarily
858 * intended to create the drag feedback when dragging a selection.
860 * aScreenRect will be filled in with the bounding rectangle of the
861 * selection area on screen.
863 * If the area of the selection is large and the RenderImageFlags::AutoScale
864 * is set, the image will be scaled down. The argument aPoint is used in this
865 * case as a reference point when determining the new screen rectangle after
866 * scaling. Typically, this will be the mouse position, so that the screen
867 * rectangle is positioned such that the mouse is over the same point in the
868 * scaled image as in the original. When scaling does not occur, the mouse
869 * point isn't used because the position can be determined from the displayed
870 * frames.
872 already_AddRefed<SourceSurface> RenderSelection(
873 dom::Selection* aSelection, const LayoutDeviceIntPoint aPoint,
874 LayoutDeviceIntRect* aScreenRect, RenderImageFlags aFlags);
876 void AddAutoWeakFrame(AutoWeakFrame* aWeakFrame);
877 void AddWeakFrame(WeakFrame* aWeakFrame);
879 void RemoveAutoWeakFrame(AutoWeakFrame* aWeakFrame);
880 void RemoveWeakFrame(WeakFrame* aWeakFrame);
883 * Stop or restart non synthetic test mouse event handling on *all*
884 * presShells.
886 * @param aDisable If true, disable all non synthetic test mouse
887 * events on all presShells. Otherwise, enable them.
889 void DisableNonTestMouseEvents(bool aDisable);
892 * Record the background color of the most recently drawn canvas. This color
893 * is composited on top of the user's default background color and then used
894 * to draw the background color of the canvas. See PresShell::Paint,
895 * PresShell::PaintDefaultBackground, and nsDocShell::SetupNewViewer;
896 * bug 488242, bug 476557 and other bugs mentioned there.
898 void SetCanvasBackground(nscolor aColor) {
899 mCanvasBackground.mViewportColor = aColor;
901 nscolor GetCanvasBackground() const {
902 return mCanvasBackground.mViewportColor;
905 struct CanvasBackground {
906 // The canvas frame background for the whole viewport.
907 nscolor mViewportColor = 0;
908 // The canvas frame background for a printed page. Note that when
909 // print-previewing / in paged mode we have multiple canvas frames (one for
910 // the viewport, one for each page).
911 nscolor mPageColor = 0;
912 bool mCSSSpecified = false;
915 // Use the current frame tree (if it exists) to update the background color of
916 // the canvas frames.
917 CanvasBackground ComputeCanvasBackground() const;
918 void UpdateCanvasBackground();
921 * Computes the backstop color for the view: transparent if in a transparent
922 * widget, otherwise the PresContext default background color. This color is
923 * only visible if the contents of the view as a whole are translucent.
925 nscolor ComputeBackstopColor(nsView* aDisplayRoot);
927 void ObserveNativeAnonMutationsForPrint(bool aObserve) {
928 mObservesMutationsForPrint = aObserve;
930 bool ObservesNativeAnonMutationsForPrint() {
931 return mObservesMutationsForPrint;
934 void ActivenessMaybeChanged();
935 bool IsActive() const { return mIsActive; }
938 * Keep track of how many times this presshell has been rendered to
939 * a window.
941 uint64_t GetPaintCount() { return mPaintCount; }
942 void IncrementPaintCount() { ++mPaintCount; }
945 * Get the root DOM window of this presShell.
947 already_AddRefed<nsPIDOMWindowOuter> GetRootWindow();
950 * This returns the focused DOM window under our top level window.
951 * I.e., when we are deactive, this returns the *last* focused DOM window.
953 already_AddRefed<nsPIDOMWindowOuter> GetFocusedDOMWindowInOurWindow();
956 * Get the focused content under this window.
958 already_AddRefed<nsIContent> GetFocusedContentInOurWindow() const;
961 * Get the window renderer for the widget of the root view, if it has
962 * one.
964 WindowRenderer* GetWindowRenderer();
967 * Return true iff there is a widget rendering this presShell and that
968 * widget is APZ-enabled.
970 bool AsyncPanZoomEnabled();
973 * Track whether we're ignoring viewport scrolling for the purposes
974 * of painting. If we are ignoring, then layers aren't clipped to
975 * the CSS viewport and scrollbars aren't drawn.
977 bool IgnoringViewportScrolling() const {
978 return !!(mRenderingStateFlags &
979 RenderingStateFlags::IgnoringViewportScrolling);
982 float GetResolution() const { return mResolution.valueOr(1.0); }
983 float GetCumulativeResolution() const;
986 * Accessors for a flag that tracks whether the most recent change to
987 * the pres shell's resolution was originated by the main thread.
989 bool IsResolutionUpdated() const { return mResolutionUpdated; }
990 void SetResolutionUpdated(bool aUpdated) { mResolutionUpdated = aUpdated; }
993 * Returns true if the resolution has ever been changed by APZ.
995 bool IsResolutionUpdatedByApz() const { return mResolutionUpdatedByApz; }
998 * Used by session restore code to restore a resolution before the first
999 * paint.
1001 void SetRestoreResolution(float aResolution,
1002 LayoutDeviceIntSize aDisplaySize);
1005 * Returns whether we are in a DrawWindow() call that used the
1006 * DRAWWINDOW_DO_NOT_FLUSH flag.
1008 bool InDrawWindowNotFlushing() const {
1009 return !!(mRenderingStateFlags &
1010 RenderingStateFlags::DrawWindowNotFlushing);
1014 * Set the isFirstPaint flag.
1016 void SetIsFirstPaint(bool aIsFirstPaint) { mIsFirstPaint = aIsFirstPaint; }
1019 * Get the isFirstPaint flag.
1021 bool GetIsFirstPaint() const { return mIsFirstPaint; }
1023 uint32_t GetPresShellId() { return mPresShellId; }
1026 * Dispatch a mouse move event based on the most recent mouse position if
1027 * this PresShell is visible. This is used when the contents of the page
1028 * moved (aFromScroll is false) or scrolled (aFromScroll is true).
1030 void SynthesizeMouseMove(bool aFromScroll);
1032 MOZ_CAN_RUN_SCRIPT
1033 nsresult HandleEvent(nsIFrame* aFrame, WidgetGUIEvent* aEvent,
1034 bool aDontRetargetEvents, nsEventStatus* aEventStatus);
1035 bool ShouldIgnoreInvalidation();
1037 * Notify that we called Paint with PaintFlags::PaintComposite.
1038 * Fires on the presshell for the painted widget.
1039 * This is issued at a time when it's safe to modify widget geometry.
1041 MOZ_CAN_RUN_SCRIPT void DidPaintWindow();
1043 bool IsVisible() const;
1044 bool IsUnderHiddenEmbedderElement() const {
1045 return mUnderHiddenEmbedderElement;
1047 void SetIsUnderHiddenEmbedderElement(bool aUnderHiddenEmbedderElement) {
1048 mUnderHiddenEmbedderElement = aUnderHiddenEmbedderElement;
1051 MOZ_CAN_RUN_SCRIPT
1052 void DispatchSynthMouseMove(WidgetGUIEvent* aEvent);
1054 /* Temporarily ignore the Displayport for better paint performance. We
1055 * trigger a repaint once suppression is disabled. Without that
1056 * the displayport may get left at the suppressed size for an extended
1057 * period of time and result in unnecessary checkerboarding (see bug
1058 * 1255054). */
1059 void SuppressDisplayport(bool aEnabled);
1061 /* Whether or not displayport suppression should be turned on. Note that
1062 * this only affects the return value of |IsDisplayportSuppressed()|, and
1063 * doesn't change the value of the internal counter.
1065 void RespectDisplayportSuppression(bool aEnabled);
1067 /* Whether or not the displayport is currently suppressed. */
1068 bool IsDisplayportSuppressed();
1070 void AddSizeOfIncludingThis(nsWindowSizes& aWindowSizes) const;
1073 * Methods that retrieve the cached font inflation preferences.
1075 uint32_t FontSizeInflationEmPerLine() const {
1076 return mFontSizeInflationEmPerLine;
1079 uint32_t FontSizeInflationMinTwips() const {
1080 return mFontSizeInflationMinTwips;
1083 uint32_t FontSizeInflationLineThreshold() const {
1084 return mFontSizeInflationLineThreshold;
1087 bool FontSizeInflationForceEnabled() const {
1088 return mFontSizeInflationForceEnabled;
1091 bool FontSizeInflationDisabledInMasterProcess() const {
1092 return mFontSizeInflationDisabledInMasterProcess;
1095 bool FontSizeInflationEnabled() const { return mFontSizeInflationEnabled; }
1098 * Recomputes whether font-size inflation is enabled.
1100 void RecomputeFontSizeInflationEnabled();
1103 * Return true if the most recent interruptible reflow was interrupted.
1105 bool IsReflowInterrupted() const { return mWasLastReflowInterrupted; }
1108 * Return true if the the interruptible reflows have to be suppressed.
1109 * This may happen only if if the most recent reflow was interrupted.
1111 bool SuppressInterruptibleReflows() const {
1112 return mWasLastReflowInterrupted;
1115 //////////////////////////////////////////////////////////////////////////////
1116 // Approximate frame visibility tracking public API.
1117 //////////////////////////////////////////////////////////////////////////////
1120 * Schedule an update of the list of approximately visible frames "soon".
1121 * This lets the refresh driver know that we want a visibility update in the
1122 * near future. The refresh driver applies its own heuristics and throttling
1123 * to decide when to actually perform the visibility update.
1125 void ScheduleApproximateFrameVisibilityUpdateSoon();
1128 * Schedule an update of the list of approximately visible frames "now". The
1129 * update runs asynchronously, but it will be posted to the event loop
1130 * immediately. Prefer the "soon" variation of this method when possible, as
1131 * this variation ignores the refresh driver's heuristics.
1133 void ScheduleApproximateFrameVisibilityUpdateNow();
1136 * Clears the current list of approximately visible frames on this pres shell
1137 * and replaces it with frames that are in the display list @aList.
1139 void RebuildApproximateFrameVisibilityDisplayList(const nsDisplayList& aList);
1140 void RebuildApproximateFrameVisibility(nsRect* aRect = nullptr,
1141 bool aRemoveOnly = false);
1144 * Ensures @aFrame is in the list of approximately visible frames.
1146 void EnsureFrameInApproximatelyVisibleList(nsIFrame* aFrame);
1148 /// Removes @aFrame from the list of approximately visible frames if present.
1149 void RemoveFrameFromApproximatelyVisibleList(nsIFrame* aFrame);
1151 /// Whether we should assume all frames are visible.
1152 bool AssumeAllFramesVisible();
1155 * Returns whether the document's style set's rule processor for the
1156 * specified level of the cascade is shared by multiple style sets.
1158 * @param aSheetType One of the nsIStyleSheetService.*_SHEET constants.
1160 nsresult HasRuleProcessorUsedByMultipleStyleSets(uint32_t aSheetType,
1161 bool* aRetVal);
1164 * Returns whether or not the document has ever handled user input
1166 bool HasHandledUserInput() const { return mHasHandledUserInput; }
1168 MOZ_CAN_RUN_SCRIPT void FireResizeEvent();
1169 MOZ_CAN_RUN_SCRIPT void FireResizeEventSync();
1171 void NativeAnonymousContentRemoved(nsIContent* aAnonContent);
1174 * See HTMLDocument.setKeyPressEventModel() in HTMLDocument.webidl for the
1175 * detail.
1177 void SetKeyPressEventModel(uint16_t aKeyPressEventModel) {
1178 mForceUseLegacyKeyCodeAndCharCodeValues |=
1179 aKeyPressEventModel ==
1180 dom::Document_Binding::KEYPRESS_EVENT_MODEL_SPLIT;
1183 bool AddRefreshObserver(nsARefreshObserver* aObserver, FlushType aFlushType,
1184 const char* aObserverDescription);
1185 bool RemoveRefreshObserver(nsARefreshObserver* aObserver,
1186 FlushType aFlushType);
1188 bool AddPostRefreshObserver(nsAPostRefreshObserver*);
1189 bool AddPostRefreshObserver(mozilla::ManagedPostRefreshObserver*) = delete;
1190 bool RemovePostRefreshObserver(nsAPostRefreshObserver*);
1191 bool RemovePostRefreshObserver(mozilla::ManagedPostRefreshObserver*) = delete;
1193 // Represents an update to the visual scroll offset that will be sent to APZ.
1194 // The update type is used to determine priority compared to other scroll
1195 // updates.
1196 struct VisualScrollUpdate {
1197 nsPoint mVisualScrollOffset;
1198 FrameMetrics::ScrollOffsetUpdateType mUpdateType;
1199 bool mAcknowledged = false;
1202 // Ask APZ in the next transaction to scroll to the given visual viewport
1203 // offset (relative to the document).
1204 // This is intended to be used when desired in cases where the browser
1205 // internally triggers scrolling; scrolling triggered explicitly by web
1206 // content (such as via window.scrollTo() should scroll the layout viewport
1207 // only).
1208 // If scrolling "far away", i.e. not just within the existing layout
1209 // viewport, it's recommended to use both nsIScrollableFrame.ScrollTo*()
1210 // (via window.scrollTo if calling from JS) *and* this function; otherwise,
1211 // temporary checkerboarding may result. If doing this:
1212 // * Be sure to call ScrollTo*() first, as a subsequent layout scroll
1213 // in the same transaction will cancel the pending visual scroll.
1214 // * Keep in mind that ScrollTo*() can tear down the pres shell and
1215 // frame tree. Depending on how the pres shell is obtained for the
1216 // subsequent ScrollToVisual() call, AutoWeakFrame or similar may
1217 // need to be used.
1218 // Please request APZ review if adding a new call site.
1219 void ScrollToVisual(const nsPoint& aVisualViewportOffset,
1220 FrameMetrics::ScrollOffsetUpdateType aUpdateType,
1221 ScrollMode aMode);
1222 void AcknowledgePendingVisualScrollUpdate();
1223 void ClearPendingVisualScrollUpdate();
1224 const Maybe<VisualScrollUpdate>& GetPendingVisualScrollUpdate() const {
1225 return mPendingVisualScrollUpdate;
1228 nsPoint GetLayoutViewportOffset() const;
1229 nsSize GetLayoutViewportSize() const;
1232 * Documents belonging to an invisible DocShell must not be painted ever.
1234 bool IsNeverPainting() { return mIsNeverPainting; }
1236 void SetNeverPainting(bool aNeverPainting) {
1237 mIsNeverPainting = aNeverPainting;
1241 * True if a reflow event has been scheduled, or is going to be scheduled
1242 * to run in the future.
1244 bool HasPendingReflow() const {
1245 return mObservingLayoutFlushes || mReflowContinueTimer;
1248 void SyncWindowProperties(bool aSync);
1249 struct WindowSizeConstraints {
1250 nsSize mMinSize;
1251 nsSize mMaxSize;
1253 WindowSizeConstraints GetWindowSizeConstraints();
1255 Document* GetPrimaryContentDocument();
1257 struct MOZ_RAII AutoAssertNoFlush {
1258 explicit AutoAssertNoFlush(PresShell& aPresShell)
1259 : mPresShell(aPresShell), mOldForbidden(mPresShell.mForbiddenToFlush) {
1260 mPresShell.mForbiddenToFlush = true;
1263 ~AutoAssertNoFlush() { mPresShell.mForbiddenToFlush = mOldForbidden; }
1265 PresShell& mPresShell;
1266 const bool mOldForbidden;
1269 NS_IMETHOD GetSelectionFromScript(RawSelectionType aRawSelectionType,
1270 dom::Selection** aSelection) override;
1271 dom::Selection* GetSelection(RawSelectionType aRawSelectionType) override;
1273 NS_IMETHOD SetDisplaySelection(int16_t aToggle) override;
1274 NS_IMETHOD GetDisplaySelection(int16_t* aToggle) override;
1275 NS_IMETHOD ScrollSelectionIntoView(RawSelectionType aRawSelectionType,
1276 SelectionRegion aRegion,
1277 int16_t aFlags) override;
1278 NS_IMETHOD RepaintSelection(RawSelectionType aRawSelectionType) override;
1279 void SelectionWillTakeFocus() override;
1280 void SelectionWillLoseFocus() override;
1282 // Implements the "focus fix-up rule". Returns true if the focus moved (in
1283 // which case we might need to update layout again).
1284 // See https://github.com/whatwg/html/issues/8225
1285 MOZ_CAN_RUN_SCRIPT bool FixUpFocus();
1288 * Set a "resolution" for the document, which if not 1.0 will
1289 * allocate more or fewer pixels for rescalable content by a factor
1290 * of |resolution| in both dimensions. Return NS_OK iff the
1291 * resolution bounds are sane, and the resolution of this was
1292 * actually updated.
1294 * Also increase the scale of the content by the same amount
1295 * (that's the "AndScaleTo" part).
1297 * The resolution defaults to 1.0.
1299 * |aOrigin| specifies who originated the resolution change. For changes
1300 * sent by APZ, pass ResolutionChangeOrigin::Apz. For changes sent by
1301 * the main thread, pass ResolutionChangeOrigin::MainThreadAdjustment (similar
1302 * to the |aOrigin| parameter of nsIScrollableFrame::ScrollToCSSPixels()).
1304 nsresult SetResolutionAndScaleTo(float aResolution,
1305 ResolutionChangeOrigin aOrigin);
1307 ResolutionChangeOrigin GetLastResolutionChangeOrigin() {
1308 return mLastResolutionChangeOrigin;
1311 // Widget notificiations
1312 void WindowSizeMoveDone();
1314 void BackingScaleFactorChanged() { mPresContext->UIResolutionChangedSync(); }
1317 * Does any painting work required to update retained paint state, and pushes
1318 * it the compositor (if any). Requests a composite, either by scheduling a
1319 * remote composite, or invalidating the widget so that we get a call to
1320 * SyncPaintFallback from the widget paint event.
1322 MOZ_CAN_RUN_SCRIPT
1323 void PaintAndRequestComposite(nsView* aView, PaintFlags aFlags);
1326 * Does an immediate paint+composite using the FallbackRenderer (which must
1327 * be the current WindowRenderer for the root frame's widget).
1329 MOZ_CAN_RUN_SCRIPT
1330 void SyncPaintFallback(nsView* aView);
1333 * Notify that we're going to call Paint with PaintFlags::PaintLayers
1334 * on the pres shell for a widget (which might not be this one, since
1335 * WillPaint is called on all presshells in the same toplevel window as the
1336 * painted widget). This is issued at a time when it's safe to modify
1337 * widget geometry.
1339 MOZ_CAN_RUN_SCRIPT void WillPaint();
1342 * Ensures that the refresh driver is running, and schedules a view
1343 * manager flush on the next tick.
1345 void ScheduleViewManagerFlush();
1347 // caret handling
1348 NS_IMETHOD SetCaretEnabled(bool aInEnable) override;
1349 NS_IMETHOD SetCaretReadOnly(bool aReadOnly) override;
1350 NS_IMETHOD GetCaretEnabled(bool* aOutEnabled) override;
1351 NS_IMETHOD SetCaretVisibilityDuringSelection(bool aVisibility) override;
1352 NS_IMETHOD GetCaretVisible(bool* _retval) override;
1355 * Should the images have borders etc. Actual visual effects are determined
1356 * by the frames. Visual effects may not effect layout, only display.
1357 * Takes effect on next repaint, does not force a repaint itself.
1359 * @param aFlags may be multiple of nsISelectionDisplay::DISPLAY_*.
1361 NS_IMETHOD SetSelectionFlags(int16_t aFlags) override;
1362 NS_IMETHOD GetSelectionFlags(int16_t* aFlags) override;
1365 * Gets the current state of non text selection effects
1366 * @return current state of non text selection,
1367 * as set by SetDisplayNonTextSelection
1369 int16_t GetSelectionFlags() const { return mSelectionFlags; }
1371 // nsISelectionController
1373 NS_IMETHOD PhysicalMove(int16_t aDirection, int16_t aAmount,
1374 bool aExtend) override;
1375 NS_IMETHOD CharacterMove(bool aForward, bool aExtend) override;
1376 MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD WordMove(bool aForward,
1377 bool aExtend) override;
1378 MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD LineMove(bool aForward,
1379 bool aExtend) override;
1380 NS_IMETHOD IntraLineMove(bool aForward, bool aExtend) override;
1381 MOZ_CAN_RUN_SCRIPT
1382 NS_IMETHOD PageMove(bool aForward, bool aExtend) override;
1383 NS_IMETHOD ScrollPage(bool aForward) override;
1384 NS_IMETHOD ScrollLine(bool aForward) override;
1385 NS_IMETHOD ScrollCharacter(bool aRight) override;
1386 NS_IMETHOD CompleteScroll(bool aForward) override;
1387 MOZ_CAN_RUN_SCRIPT NS_IMETHOD CompleteMove(bool aForward,
1388 bool aExtend) override;
1390 // Notifies that the state of the document has changed.
1391 void DocumentStatesChanged(dom::DocumentState);
1393 // nsIDocumentObserver
1394 NS_DECL_NSIDOCUMENTOBSERVER_BEGINLOAD
1395 NS_DECL_NSIDOCUMENTOBSERVER_ENDLOAD
1396 NS_DECL_NSIDOCUMENTOBSERVER_CONTENTSTATECHANGED
1398 // nsIMutationObserver
1399 NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
1400 NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE
1401 NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
1402 NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
1403 NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
1404 NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
1406 NS_DECL_NSIOBSERVER
1408 // Inline methods defined in PresShellInlines.h
1409 inline void EnsureStyleFlush();
1410 inline void SetNeedStyleFlush();
1411 inline void SetNeedLayoutFlush();
1412 inline void SetNeedThrottledAnimationFlush();
1413 inline ServoStyleSet* StyleSet() const;
1416 * Whether we might need a flush for the given flush type. If this
1417 * function returns false, we definitely don't need to flush.
1419 * @param aFlushType The flush type to check. This must be
1420 * >= FlushType::Style. This also returns true if a throttled
1421 * animation flush is required.
1423 bool NeedFlush(FlushType aType) const {
1424 // We check mInFlush to handle re-entrant calls to FlushPendingNotifications
1425 // by reporting that we always need a flush in that case. Otherwise,
1426 // we could end up missing needed flushes, since we clear the mNeedXXXFlush
1427 // flags at the top of FlushPendingNotifications.
1428 MOZ_ASSERT(aType >= FlushType::Style);
1429 return mNeedStyleFlush ||
1430 (mNeedLayoutFlush && aType >= FlushType::InterruptibleLayout) ||
1431 aType >= FlushType::Display || mNeedThrottledAnimationFlush ||
1432 mInFlush;
1436 * Returns true if we might need to flush layout, even if we haven't scheduled
1437 * one yet (as opposed to HasPendingReflow, which returns true if a flush is
1438 * scheduled or will soon be scheduled).
1440 bool NeedLayoutFlush() const { return mNeedLayoutFlush; }
1442 bool NeedStyleFlush() const { return mNeedStyleFlush; }
1445 * Flush pending notifications of the type specified. This method
1446 * will not affect the content model; it'll just affect style and
1447 * frames. Callers that actually want up-to-date presentation (other
1448 * than the document itself) should probably be calling
1449 * Document::FlushPendingNotifications.
1451 * This method can execute script, which can destroy this presshell object
1452 * unless someone is holding a reference to it on the stack. The presshell
1453 * itself will ensure it lives up until the method returns, but callers who
1454 * plan to use the presshell after this call should hold a strong ref
1455 * themselves!
1457 * @param aType the type of notifications to flush
1459 MOZ_CAN_RUN_SCRIPT
1460 void FlushPendingNotifications(FlushType aType) {
1461 if (!NeedFlush(aType)) {
1462 return;
1465 DoFlushPendingNotifications(aType);
1468 MOZ_CAN_RUN_SCRIPT
1469 void FlushPendingNotifications(ChangesToFlush aType) {
1470 if (!NeedFlush(aType.mFlushType)) {
1471 return;
1474 DoFlushPendingNotifications(aType);
1478 * Tell the pres shell that a frame needs to be marked dirty and needs
1479 * Reflow. It's OK if this is an ancestor of the frame needing reflow as
1480 * long as the ancestor chain between them doesn't cross a reflow root.
1482 * The bit to add should be NS_FRAME_IS_DIRTY, NS_FRAME_HAS_DIRTY_CHILDREN
1483 * or nsFrameState(0); passing 0 means that dirty bits won't be set on the
1484 * frame or its ancestors/descendants, but that intrinsic widths will still
1485 * be marked dirty. Passing aIntrinsicDirty = eResize and aBitToAdd = 0
1486 * would result in no work being done, so don't do that.
1488 void FrameNeedsReflow(
1489 nsIFrame* aFrame, IntrinsicDirty aIntrinsicDirty, nsFrameState aBitToAdd,
1490 ReflowRootHandling aRootHandling = ReflowRootHandling::InferFromBitToAdd);
1493 * Calls FrameNeedsReflow on all fixed position children of the root frame.
1495 void MarkFixedFramesForReflow(IntrinsicDirty aIntrinsicDirty);
1497 void MaybeReflowForInflationScreenSizeChange();
1499 // This function handles all the work after VisualViewportSize is set
1500 // or reset.
1501 void CompleteChangeToVisualViewportSize();
1504 * The return value indicates whether the offset actually changed.
1506 bool SetVisualViewportOffset(const nsPoint& aScrollOffset,
1507 const nsPoint& aPrevLayoutScrollPos);
1509 void ResetVisualViewportOffset();
1510 nsPoint GetVisualViewportOffset() const {
1511 if (mVisualViewportOffset.isSome()) {
1512 return *mVisualViewportOffset;
1514 return GetLayoutViewportOffset();
1516 bool IsVisualViewportOffsetSet() const {
1517 return mVisualViewportOffset.isSome();
1520 void SetVisualViewportSize(nscoord aWidth, nscoord aHeight);
1521 void ResetVisualViewportSize();
1522 bool IsVisualViewportSizeSet() { return mVisualViewportSizeSet; }
1523 nsSize GetVisualViewportSize() {
1524 NS_ASSERTION(mVisualViewportSizeSet,
1525 "asking for visual viewport size when its not set?");
1526 return mVisualViewportSize;
1529 nsPoint GetVisualViewportOffsetRelativeToLayoutViewport() const;
1531 // Returns state of the dynamic toolbar.
1532 DynamicToolbarState GetDynamicToolbarState() const {
1533 if (!mPresContext) {
1534 return DynamicToolbarState::None;
1537 return mPresContext->GetDynamicToolbarState();
1539 // Returns the visual viewport size during the dynamic toolbar is being
1540 // shown/hidden.
1541 nsSize GetVisualViewportSizeUpdatedByDynamicToolbar() const;
1543 /* Enable/disable author style level. Disabling author style disables the
1544 * entire author level of the cascade, including the HTML preshint level.
1546 // XXX these could easily be inlined, but there is a circular #include
1547 // problem with nsStyleSet.
1548 void SetAuthorStyleDisabled(bool aDisabled);
1549 bool GetAuthorStyleDisabled() const;
1551 // aSheetType is one of the nsIStyleSheetService *_SHEET constants.
1552 void NotifyStyleSheetServiceSheetAdded(StyleSheet* aSheet,
1553 uint32_t aSheetType);
1554 void NotifyStyleSheetServiceSheetRemoved(StyleSheet* aSheet,
1555 uint32_t aSheetType);
1557 // DoReflow returns whether the reflow finished without interruption
1558 // If aFrame is not the root frame, the caller must pass a non-null
1559 // aOverflowTracker.
1560 bool DoReflow(nsIFrame* aFrame, bool aInterruptible,
1561 OverflowChangedTracker* aOverflowTracker);
1564 * Add a solid color item to the bottom of aList with frame aFrame and bounds
1565 * aBounds. aBackstopColor is composed behind the background color of the
1566 * canvas, and it is transparent by default.
1568 * We attempt to make the background color part of the scrolled canvas (to
1569 * reduce transparent layers), and if async scrolling is enabled (and the
1570 * background is opaque) then we add a second, unscrolled item to handle the
1571 * checkerboarding case.
1573 void AddCanvasBackgroundColorItem(
1574 nsDisplayListBuilder* aBuilder, nsDisplayList* aList, nsIFrame* aFrame,
1575 const nsRect& aBounds, nscolor aBackstopColor = NS_RGBA(0, 0, 0, 0));
1577 size_t SizeOfTextRuns(MallocSizeOf aMallocSizeOf) const;
1579 static PresShell* GetShellForEventTarget(nsIFrame* aFrame,
1580 nsIContent* aContent);
1581 static PresShell* GetShellForTouchEvent(WidgetGUIEvent* aEvent);
1584 * Informs the pres shell that the document is now at the anchor with
1585 * the given name. If |aScroll| is true, scrolls the view of the
1586 * document so that the anchor with the specified name is displayed at
1587 * the top of the window. If |aAnchorName| is empty, then this informs
1588 * the pres shell that there is no current target, and |aScroll| must
1589 * be false. If |aAdditionalScrollFlags| is ScrollFlags::ScrollSmoothAuto
1590 * and |aScroll| is true, the scrolling may be performed with an animation.
1592 MOZ_CAN_RUN_SCRIPT
1593 nsresult GoToAnchor(const nsAString& aAnchorName, bool aScroll,
1594 ScrollFlags aAdditionalScrollFlags = ScrollFlags::None);
1597 * Tells the presshell to scroll again to the last anchor scrolled to by
1598 * GoToAnchor, if any. This scroll only happens if the scroll
1599 * position has not changed since the last GoToAnchor (modulo scroll anchoring
1600 * adjustments). This is called by nsDocumentViewer::LoadComplete. This clears
1601 * the last anchor scrolled to by GoToAnchor (we don't want to keep it alive
1602 * if it's removed from the DOM), so don't call this more than once.
1604 MOZ_CAN_RUN_SCRIPT nsresult ScrollToAnchor();
1607 * When scroll anchoring adjusts positions in the root frame during page load,
1608 * it may move our scroll position in the root frame.
1610 * While that's generally desirable, when scrolling to an anchor via an id-ref
1611 * we have a more direct target. If the id-ref points to something that cannot
1612 * be selected as a scroll anchor container (like an image or an inline), we
1613 * may select a node following it as a scroll anchor, and if then stuff is
1614 * inserted on top, we may end up moving the id-ref element offscreen to the
1615 * top inadvertently.
1617 * On page load, the document viewer will call ScrollToAnchor(), and will only
1618 * scroll to the anchor again if the scroll position is not changed. We don't
1619 * want scroll anchoring adjustments to prevent this, so account for them.
1621 void RootScrollFrameAdjusted(nscoord aYAdjustment) {
1622 if (mLastAnchorScrolledTo) {
1623 mLastAnchorScrollPositionY += aYAdjustment;
1628 * Scrolls the view of the document so that the primary frame of the content
1629 * is displayed in the window. Layout is flushed before scrolling.
1631 * @param aContent The content object of which primary frame should be
1632 * scrolled into view.
1633 * @param aVertical How to align the frame vertically and when to do so.
1634 * This is a ScrollAxis of Where and When.
1635 * @param aHorizontal How to align the frame horizontally and when to do so.
1636 * This is a ScrollAxis of Where and When.
1637 * @param aScrollFlags If ScrollFlags::ScrollFirstAncestorOnly is set,
1638 * only the nearest scrollable ancestor is scrolled,
1639 * otherwise all scrollable ancestors may be scrolled
1640 * if necessary. If ScrollFlags::ScrollOverflowHidden
1641 * is set then we may scroll in a direction even if
1642 * overflow:hidden is specified in that direction;
1643 * otherwise we will not scroll in that direction when
1644 * overflow:hidden is set for that direction. If
1645 * ScrollFlags::ScrollNoParentFrames is set then we
1646 * only scroll nodes in this document, not in any
1647 * parent documents which contain this document in a
1648 * iframe or the like. If ScrollFlags::ScrollSmooth
1649 * is set and CSSOM-VIEW scroll-behavior is enabled,
1650 * we will scroll smoothly using
1651 * nsIScrollableFrame::ScrollMode::SMOOTH_MSD;
1652 * otherwise, nsIScrollableFrame::ScrollMode::INSTANT
1653 * will be used. If ScrollFlags::ScrollSmoothAuto is
1654 * set, the CSSOM-View scroll-behavior attribute is
1655 * set to 'smooth' on the scroll frame, and CSSOM-VIEW
1656 * scroll-behavior is enabled, we will scroll smoothly
1657 * using nsIScrollableFrame::ScrollMode::SMOOTH_MSD;
1658 * otherwise, nsIScrollableFrame::ScrollMode::INSTANT
1659 * will be used.
1661 MOZ_CAN_RUN_SCRIPT
1662 nsresult ScrollContentIntoView(nsIContent* aContent, ScrollAxis aVertical,
1663 ScrollAxis aHorizontal,
1664 ScrollFlags aScrollFlags);
1667 * When capturing content is set, it traps all mouse events and retargets
1668 * them at this content node. If capturing is not allowed
1669 * (gCaptureInfo.mAllowed is false), then capturing is not set. However, if
1670 * the CaptureFlags::IgnoreAllowedState is set, the allowed state is ignored
1671 * and capturing is set regardless. To disable capture, pass null for the
1672 * value of aContent.
1674 * If CaptureFlags::RetargetedToElement is set, all mouse events are
1675 * targeted at aContent only. Otherwise, mouse events are targeted at
1676 * aContent or its descendants. That is, descendants of aContent receive
1677 * mouse events as they normally would, but mouse events outside of aContent
1678 * are retargeted to aContent.
1680 * If CaptureFlags::PreventDragStart is set then drags are prevented from
1681 * starting while this capture is active.
1683 * If CaptureFlags::PointerLock is set, similar to
1684 * CaptureFlags::RetargetToElement, then events are targeted at aContent,
1685 * but capturing is held more strongly (i.e., calls to SetCapturingContent()
1686 * won't unlock unless CaptureFlags::PointerLock is set again).
1688 static void SetCapturingContent(nsIContent* aContent, CaptureFlags aFlags,
1689 WidgetEvent* aEvent = nullptr);
1692 * Alias for SetCapturingContent(nullptr, CaptureFlags::None) for making
1693 * callers what they do clearer.
1695 static void ReleaseCapturingContent() {
1696 PresShell::SetCapturingContent(nullptr, CaptureFlags::None);
1699 static void ReleaseCapturingRemoteTarget(dom::BrowserParent* aBrowserParent) {
1700 MOZ_ASSERT(XRE_IsParentProcess());
1701 if (sCapturingContentInfo.mRemoteTarget == aBrowserParent) {
1702 sCapturingContentInfo.mRemoteTarget = nullptr;
1706 // Called at the end of nsLayoutUtils::PaintFrame() if we were painting to
1707 // the widget.
1708 // This is used to clear any pending visual scroll updates that have been
1709 // acknowledged, to make sure they don't stick around for the next paint.
1710 void EndPaint();
1713 * Tell the presshell that the given frame's reflow was interrupted. This
1714 * will mark as having dirty children a path from the given frame (inclusive)
1715 * to the nearest ancestor with a dirty subtree, or to the reflow root
1716 * currently being reflowed if no such ancestor exists (inclusive). This is
1717 * to be done immediately after reflow of the current reflow root completes.
1718 * This method must only be called during reflow, and the frame it's being
1719 * called on must be in the process of being reflowed when it's called. This
1720 * method doesn't mark any intrinsic widths dirty and doesn't add any bits
1721 * other than NS_FRAME_HAS_DIRTY_CHILDREN.
1723 void FrameNeedsToContinueReflow(nsIFrame* aFrame);
1726 * Notification sent by a frame informing the pres shell that it is about to
1727 * be destroyed.
1728 * This allows any outstanding references to the frame to be cleaned up
1730 void NotifyDestroyingFrame(nsIFrame* aFrame);
1732 bool GetZoomableByAPZ() const;
1734 bool ReflowForHiddenContentIfNeeded();
1735 void UpdateHiddenContentInForcedLayout(nsIFrame*);
1737 * If this frame has content hidden via `content-visibilty` that has a pending
1738 * reflow, force the content to reflow immediately.
1740 void EnsureReflowIfFrameHasHiddenContent(nsIFrame*);
1743 * Whether or not this presshell is is forcing a reflow of hidden content in
1744 * this frame via EnsureReflowIfFrameHasHiddenContent().
1746 bool IsForcingLayoutForHiddenContent(const nsIFrame*) const;
1748 void RegisterContentVisibilityAutoFrame(nsIFrame* aFrame) {
1749 mContentVisibilityAutoFrames.Insert(aFrame);
1751 void UnregisterContentVisibilityAutoFrame(nsIFrame* aFrame) {
1752 mContentVisibilityAutoFrames.Remove(aFrame);
1754 bool HasContentVisibilityAutoFrames() const {
1755 return !mContentVisibilityAutoFrames.IsEmpty();
1758 void UpdateRelevancyOfContentVisibilityAutoFrames();
1759 void ScheduleContentRelevancyUpdate(ContentRelevancyReason aReason);
1760 void UpdateContentRelevancyImmediately(ContentRelevancyReason aReason);
1762 // Determination of proximity to the viewport.
1763 // Refer to "update the rendering: step 14", see
1764 // https://html.spec.whatwg.org/#update-the-rendering
1765 struct ProximityToViewportResult {
1766 bool mHadInitialDetermination = false;
1767 bool mAnyScrollIntoViewFlag = false;
1769 ProximityToViewportResult DetermineProximityToViewport();
1771 void ClearTemporarilyVisibleForScrolledIntoViewDescendantFlags() const;
1773 private:
1774 ~PresShell();
1776 void SetIsActive(bool aIsActive);
1777 bool ComputeActiveness() const;
1779 MOZ_CAN_RUN_SCRIPT
1780 void PaintInternal(nsView* aViewToPaint, PaintInternalFlags aFlags);
1783 * Refresh observer management.
1785 void DoObserveStyleFlushes();
1786 void DoObserveLayoutFlushes();
1789 * Does the actual work of figuring out the current state of font size
1790 * inflation.
1792 bool DetermineFontSizeInflationState();
1794 void RecordAlloc(void* aPtr) {
1795 #ifdef DEBUG
1796 if (!mAllocatedPointers) {
1797 return; // Hash set was presumably freed to avert OOM.
1799 MOZ_ASSERT(!mAllocatedPointers->Contains(aPtr));
1800 if (!mAllocatedPointers->Insert(aPtr, fallible)) {
1801 // Yikes! We're nearly out of memory, and this insertion would've pushed
1802 // us over the ledge. At this point, we discard & stop using this set,
1803 // since we don't have enough memory to keep it accurate from this point
1804 // onwards. Hopefully this helps relieve the memory pressure a bit, too.
1805 mAllocatedPointers = nullptr;
1807 #endif
1810 void RecordFree(void* aPtr) {
1811 #ifdef DEBUG
1812 if (!mAllocatedPointers) {
1813 return; // Hash set was presumably freed to avert OOM.
1815 MOZ_ASSERT(mAllocatedPointers->Contains(aPtr));
1816 mAllocatedPointers->Remove(aPtr);
1817 #endif
1820 void PushCurrentEventInfo(nsIFrame* aFrame, nsIContent* aContent);
1821 void PopCurrentEventInfo();
1822 nsIContent* GetCurrentEventContent();
1824 friend class ::nsRefreshDriver;
1825 friend class ::nsAutoCauseReflowNotifier;
1827 void WillCauseReflow();
1828 MOZ_CAN_RUN_SCRIPT void DidCauseReflow();
1830 void CancelPostedReflowCallbacks();
1831 void FlushPendingScrollAnchorAdjustments();
1833 void SetPendingVisualScrollUpdate(
1834 const nsPoint& aVisualViewportOffset,
1835 FrameMetrics::ScrollOffsetUpdateType aUpdateType);
1837 #ifdef MOZ_REFLOW_PERF
1838 UniquePtr<ReflowCountMgr> mReflowCountMgr;
1839 #endif
1841 void WillDoReflow();
1843 // This data is stored as a content property (nsGkAtoms::scrolling) on
1844 // mContentToScrollTo when we have a pending ScrollIntoView.
1845 struct ScrollIntoViewData {
1846 ScrollAxis mContentScrollVAxis;
1847 ScrollAxis mContentScrollHAxis;
1848 ScrollFlags mContentToScrollToFlags;
1851 static LazyLogModule gLog;
1853 DOMHighResTimeStamp GetPerformanceNowUnclamped();
1855 // The callback for the mReflowContinueTimer timer.
1856 static void sReflowContinueCallback(nsITimer* aTimer, void* aPresShell);
1857 bool ScheduleReflowOffTimer();
1858 // MaybeScheduleReflow checks if posting a reflow is needed, then checks if
1859 // the last reflow was interrupted. In the interrupted case ScheduleReflow is
1860 // called off a timer, otherwise it is called directly.
1861 void MaybeScheduleReflow();
1862 // Actually schedules a reflow. This should only be called by
1863 // MaybeScheduleReflow and the reflow timer ScheduleReflowOffTimer
1864 // sets up.
1865 void ScheduleReflow();
1867 friend class ::AutoPointerEventTargetUpdater;
1869 // ProcessReflowCommands returns whether we processed all our dirty roots
1870 // without interruptions.
1871 MOZ_CAN_RUN_SCRIPT bool ProcessReflowCommands(bool aInterruptible);
1874 * Callback handler for whether reflow happened.
1876 * @param aInterruptible Whether or not reflow interruption is allowed.
1878 MOZ_CAN_RUN_SCRIPT void DidDoReflow(bool aInterruptible);
1880 MOZ_CAN_RUN_SCRIPT void HandlePostedReflowCallbacks(bool aInterruptible);
1883 * Helper for ScrollContentIntoView()
1885 MOZ_CAN_RUN_SCRIPT void DoScrollContentIntoView();
1888 * Methods to handle changes to user and UA sheet lists that we get
1889 * notified about.
1891 void AddUserSheet(StyleSheet*);
1892 void AddAgentSheet(StyleSheet*);
1893 void AddAuthorSheet(StyleSheet*);
1896 * Initialize cached font inflation preference values and do an initial
1897 * computation to determine if font inflation is enabled.
1899 * @see nsLayoutUtils::sFontSizeInflationEmPerLine
1900 * @see nsLayoutUtils::sFontSizeInflationMinTwips
1901 * @see nsLayoutUtils::sFontSizeInflationLineThreshold
1903 void SetupFontInflation();
1906 * Implementation methods for FlushPendingNotifications.
1908 MOZ_CAN_RUN_SCRIPT void DoFlushPendingNotifications(FlushType aType);
1909 MOZ_CAN_RUN_SCRIPT void DoFlushPendingNotifications(ChangesToFlush aType);
1911 struct RenderingState {
1912 explicit RenderingState(PresShell* aPresShell)
1913 : mResolution(aPresShell->mResolution),
1914 mRenderingStateFlags(aPresShell->mRenderingStateFlags) {}
1915 Maybe<float> mResolution;
1916 RenderingStateFlags mRenderingStateFlags;
1919 struct AutoSaveRestoreRenderingState {
1920 explicit AutoSaveRestoreRenderingState(PresShell* aPresShell)
1921 : mPresShell(aPresShell), mOldState(aPresShell) {}
1923 ~AutoSaveRestoreRenderingState() {
1924 mPresShell->mRenderingStateFlags = mOldState.mRenderingStateFlags;
1925 mPresShell->mResolution = mOldState.mResolution;
1926 #ifdef ACCESSIBILITY
1927 if (nsAccessibilityService* accService = GetAccService()) {
1928 accService->NotifyOfResolutionChange(mPresShell,
1929 mPresShell->GetResolution());
1931 #endif
1934 PresShell* mPresShell;
1935 RenderingState mOldState;
1937 void SetRenderingState(const RenderingState& aState);
1939 friend class ::nsPresShellEventCB;
1941 // methods for painting a range to an offscreen buffer
1943 // given a display list, clip the items within the list to
1944 // the range
1945 nsRect ClipListToRange(nsDisplayListBuilder* aBuilder, nsDisplayList* aList,
1946 nsRange* aRange);
1948 // create a RangePaintInfo for the range aRange containing the
1949 // display list needed to paint the range to a surface
1950 UniquePtr<RangePaintInfo> CreateRangePaintInfo(nsRange* aRange,
1951 nsRect& aSurfaceRect,
1952 bool aForPrimarySelection);
1955 * Paint the items to a new surface and return it.
1957 * aSelection - selection being painted, if any
1958 * aRegion - clip region, if any
1959 * aArea - area that the surface occupies, relative to the root frame
1960 * aPoint - reference point, typically the mouse position
1961 * aScreenRect - [out] set to the area of the screen the painted area should
1962 * be displayed at
1963 * aFlags - set RenderImageFlags::AutoScale to scale down large images, but
1964 * it must not be set if a custom image was specified
1966 already_AddRefed<SourceSurface> PaintRangePaintInfo(
1967 const nsTArray<UniquePtr<RangePaintInfo>>& aItems,
1968 dom::Selection* aSelection, const Maybe<CSSIntRegion>& aRegion,
1969 nsRect aArea, const LayoutDeviceIntPoint aPoint,
1970 LayoutDeviceIntRect* aScreenRect, RenderImageFlags aFlags);
1972 // Hide a view if it is a popup
1973 void HideViewIfPopup(nsView* aView);
1975 // Utility method to restore the root scrollframe state
1976 void RestoreRootScrollPosition();
1978 MOZ_CAN_RUN_SCRIPT_BOUNDARY void MaybeReleaseCapturingContent();
1980 class DelayedEvent {
1981 public:
1982 virtual ~DelayedEvent() = default;
1983 virtual void Dispatch() {}
1984 virtual bool IsKeyPressEvent() { return false; }
1987 class DelayedInputEvent : public DelayedEvent {
1988 public:
1989 void Dispatch() override;
1991 protected:
1992 DelayedInputEvent();
1993 ~DelayedInputEvent() override;
1995 WidgetInputEvent* mEvent;
1998 class DelayedMouseEvent : public DelayedInputEvent {
1999 public:
2000 explicit DelayedMouseEvent(WidgetMouseEvent* aEvent);
2003 class DelayedKeyEvent : public DelayedInputEvent {
2004 public:
2005 explicit DelayedKeyEvent(WidgetKeyboardEvent* aEvent);
2006 bool IsKeyPressEvent() override;
2010 * return the nsPoint represents the location of the mouse event relative to
2011 * the root document in visual coordinates
2013 nsPoint GetEventLocation(const WidgetMouseEvent& aEvent) const;
2015 // Check if aEvent is a mouse event and record the mouse location for later
2016 // synth mouse moves.
2017 void RecordPointerLocation(WidgetGUIEvent* aEvent);
2018 inline bool MouseLocationWasSetBySynthesizedMouseEventForTests() const;
2019 class nsSynthMouseMoveEvent final : public nsARefreshObserver {
2020 public:
2021 nsSynthMouseMoveEvent(PresShell* aPresShell, bool aFromScroll)
2022 : mPresShell(aPresShell), mFromScroll(aFromScroll) {
2023 NS_ASSERTION(mPresShell, "null parameter");
2026 private:
2027 // Private destructor, to discourage deletion outside of Release():
2028 ~nsSynthMouseMoveEvent() { Revoke(); }
2030 public:
2031 NS_INLINE_DECL_REFCOUNTING(nsSynthMouseMoveEvent, override)
2033 void Revoke();
2035 MOZ_CAN_RUN_SCRIPT
2036 void WillRefresh(TimeStamp aTime) override { Run(); }
2038 MOZ_CAN_RUN_SCRIPT void Run() {
2039 if (mPresShell) {
2040 RefPtr<PresShell> shell = mPresShell;
2041 shell->ProcessSynthMouseMoveEvent(mFromScroll);
2045 private:
2046 PresShell* mPresShell;
2047 bool mFromScroll;
2049 MOZ_CAN_RUN_SCRIPT void ProcessSynthMouseMoveEvent(bool aFromScroll);
2051 void UpdateImageLockingState();
2053 already_AddRefed<PresShell> GetParentPresShellForEventHandling();
2056 * EventHandler is implementation of PresShell::HandleEvent().
2058 class MOZ_STACK_CLASS EventHandler final {
2059 public:
2060 EventHandler() = delete;
2061 EventHandler(const EventHandler& aOther) = delete;
2062 explicit EventHandler(PresShell& aPresShell)
2063 : mPresShell(aPresShell), mCurrentEventInfoSetter(nullptr) {}
2064 explicit EventHandler(RefPtr<PresShell>&& aPresShell)
2065 : mPresShell(std::move(aPresShell)), mCurrentEventInfoSetter(nullptr) {}
2068 * HandleEvent() may dispatch aGUIEvent. This may redirect the event to
2069 * another PresShell, or the event may be handled by other classes like
2070 * AccessibleCaretEventHub, or discarded. Otherwise, this sets current
2071 * event info of mPresShell and calls HandleEventWithCurrentEventInfo()
2072 * to dispatch the event into the DOM tree.
2074 * @param aFrameForPresShell The frame for PresShell. If PresShell
2075 * has root frame, it should be set.
2076 * Otherwise, a frame which contains the
2077 * PresShell should be set instead. I.e.,
2078 * in the latter case, the frame is in
2079 * a parent document.
2080 * @param aGUIEvent Event to be handled. Must be a trusted
2081 * event.
2082 * @param aDontRetargetEvents true if this shouldn't redirect the
2083 * event to different PresShell.
2084 * false if this can redirect the event to
2085 * different PresShell.
2086 * @param aEventStatus [in/out] EventStatus of aGUIEvent.
2088 MOZ_CAN_RUN_SCRIPT
2089 nsresult HandleEvent(nsIFrame* aFrameForPresShell,
2090 WidgetGUIEvent* aGUIEvent, bool aDontRetargetEvents,
2091 nsEventStatus* aEventStatus);
2094 * HandleEventWithTarget() tries to dispatch aEvent on aContent after
2095 * setting current event target content to aNewEventContent and current
2096 * event frame to aNewEventFrame temporarily. Note that this supports
2097 * WidgetEvent, not WidgetGUIEvent. So, you can dispatch a simple event
2098 * with this.
2100 * @param aEvent Event to be dispatched. Must be a
2101 * trusted event.
2102 * @param aNewEventFrame Temporal new event frame.
2103 * @param aNewEventContent Temporal new event content.
2104 * @param aEventStatus [in/out] EventStuatus of aEvent.
2105 * @param aIsHandlingNativeEvent true if aEvent represents a native
2106 * event.
2107 * @param aTargetContent This is used only when aEvent is a
2108 * pointer event. If
2109 * PresShell::mPointerEventTarget is
2110 * changed during dispatching aEvent,
2111 * this is set to the new target.
2112 * @param aOverrideClickTarget Override click event target.
2114 MOZ_CAN_RUN_SCRIPT
2115 nsresult HandleEventWithTarget(WidgetEvent* aEvent,
2116 nsIFrame* aNewEventFrame,
2117 nsIContent* aNewEventContent,
2118 nsEventStatus* aEventStatus,
2119 bool aIsHandlingNativeEvent,
2120 nsIContent** aTargetContent,
2121 nsIContent* aOverrideClickTarget);
2124 * OnPresShellDestroy() is called when every PresShell instance is being
2125 * destroyed.
2127 static inline void OnPresShellDestroy(Document* aDocument);
2129 private:
2130 static bool InZombieDocument(nsIContent* aContent);
2131 static nsIFrame* GetNearestFrameContainingPresShell(PresShell* aPresShell);
2132 static nsIPrincipal* GetDocumentPrincipalToCompareWithBlacklist(
2133 PresShell& aPresShell);
2136 * HandleEventUsingCoordinates() handles aGUIEvent whose
2137 * IsUsingCoordinates() returns true with the following helper methods.
2139 * @param aFrameForPresShell The frame for PresShell. See
2140 * explanation of HandleEvent() for the
2141 * details.
2142 * @param aGUIEvent The handling event. Make sure that
2143 * its IsUsingCoordinates() returns true.
2144 * @param aEventStatus The status of aGUIEvent.
2145 * @param aDontRetargetEvents true if we've already retarget document.
2146 * Otherwise, false.
2148 MOZ_CAN_RUN_SCRIPT
2149 nsresult HandleEventUsingCoordinates(nsIFrame* aFrameForPresShell,
2150 WidgetGUIEvent* aGUIEvent,
2151 nsEventStatus* aEventStatus,
2152 bool aDontRetargetEvents);
2155 * EventTargetData struct stores a set of a PresShell (event handler),
2156 * a frame (to handle the event) and a content (event target for the frame).
2158 struct MOZ_STACK_CLASS EventTargetData final {
2159 EventTargetData() = delete;
2160 EventTargetData(const EventTargetData& aOther) = delete;
2161 explicit EventTargetData(nsIFrame* aFrameToHandleEvent) {
2162 SetFrameAndComputePresShell(aFrameToHandleEvent);
2165 void SetFrameAndComputePresShell(nsIFrame* aFrameToHandleEvent);
2166 void SetFrameAndComputePresShellAndContent(nsIFrame* aFrameToHandleEvent,
2167 WidgetGUIEvent* aGUIEvent);
2168 void SetContentForEventFromFrame(WidgetGUIEvent* aGUIEvent);
2170 nsPresContext* GetPresContext() const {
2171 return mPresShell ? mPresShell->GetPresContext() : nullptr;
2173 EventStateManager* GetEventStateManager() const {
2174 nsPresContext* presContext = GetPresContext();
2175 return presContext ? presContext->EventStateManager() : nullptr;
2177 Document* GetDocument() const {
2178 return mPresShell ? mPresShell->GetDocument() : nullptr;
2182 * Return content of the frame if and only if a frame is set.
2183 * I.e., this may return non-element node even when GetContent() returns
2184 * an element node.
2186 nsIContent* GetFrameContent() const;
2188 nsIFrame* GetFrame() const { return mFrame; }
2189 nsIContent* GetContent() const { return mContent; }
2192 * Set the event target content and the topmost frame at the event point.
2193 * This checks whether the relation is correct if aContent is not nullptr.
2194 * If you set aGUIEvent, the check is done with strict way, but otherwise,
2195 * it checks whether aContent is a proper inclusive ancestor of
2196 * mFrame->GetContent() or not.
2198 void SetFrameAndContent(nsIFrame* aFrame, nsIContent* aContent = nullptr,
2199 const WidgetGUIEvent* aGUIEvent = nullptr) {
2200 mFrame = aFrame;
2201 mContent = aContent ? aContent : GetFrameContent();
2202 AssertIfEventTargetContentAndFrameContentMismatch(aGUIEvent);
2206 * Set the event target content and clear the frame.
2208 void SetContent(nsIContent* aContent) {
2209 mContent = aContent;
2210 if (mFrame && GetFrameContent() != aContent) {
2211 mFrame = nullptr;
2216 * MaybeRetargetToActiveDocument() tries retarget aGUIEvent into
2217 * active document if there is. Note that this does not support to
2218 * retarget mContent. Make sure it is nullptr before calling this.
2220 * @param aGUIEvent The handling event.
2221 * @return true if retargetted.
2223 bool MaybeRetargetToActiveDocument(WidgetGUIEvent* aGUIEvent);
2226 * ComputeElementFromFrame() computes mContent for aGUIEvent. If
2227 * mContent is set by this method, mContent is always nullptr or an
2228 * Element.
2230 * @param aGUIEvent The handling event.
2231 * @return true if caller can keep handling the event.
2232 * Otherwise, false.
2233 * Note that even if this returns true, mContent
2234 * may be nullptr.
2236 bool ComputeElementFromFrame(WidgetGUIEvent* aGUIEvent);
2239 * UpdateTouchEventTarget() updates mFrame, mPresShell and mContent if
2240 * aGUIEvent is a touch event and there is new proper target.
2242 * @param aGUIEvent The handled event. If it's not a touch event,
2243 * this method does nothing.
2245 void UpdateTouchEventTarget(WidgetGUIEvent* aGUIEvent);
2248 * UpdateWheelEventTarget() updates mFrame, mPresShell, and mContent if
2249 * aGUIEvent is a wheel event and aGUIEvent should be grouped with prior
2250 * wheel events.
2252 * @param aGUIEvent The handled event. If it's not a wheel event,
2253 * this method does nothing.
2255 void UpdateWheelEventTarget(WidgetGUIEvent* aGUIEvent);
2257 private:
2258 void AssertIfEventTargetContentAndFrameContentMismatch(
2259 const WidgetGUIEvent* aGUIEvent = nullptr) const;
2261 public:
2262 RefPtr<PresShell> mPresShell;
2263 nsCOMPtr<nsIContent> mOverrideClickTarget;
2265 private:
2266 nsIFrame* mFrame = nullptr;
2267 // mContent is the event target content for mFrame->GetContent().
2268 // This may be nullptr even if mFrame is not nullptr.
2269 // This may be an ancestor element of mFrame->GetContent() or native
2270 // anonymous root content parent.
2271 // This may be not an ancestor element of mFrame->GetContent() if
2272 // mFrame->GetContentForEvent() returns such element. E.g., clicking in
2273 // <area>, mContent is the <area> but mFrame->GetContent() is an <img>.
2274 nsCOMPtr<nsIContent> mContent;
2278 * MaybeFlushPendingNotifications() maybe flush pending notifications if
2279 * aGUIEvent should be handled with the latest layout.
2281 * @param aGUIEvent The handling event.
2282 * @return true if this actually flushes pending
2283 * layout and that has caused changing the
2284 * layout.
2286 MOZ_CAN_RUN_SCRIPT
2287 bool MaybeFlushPendingNotifications(WidgetGUIEvent* aGUIEvent);
2290 * GetFrameToHandleNonTouchEvent() returns a frame to handle the event.
2291 * This may flush pending layout if the target is in child PresShell.
2293 * @param aRootFrameToHandleEvent The root frame to handle the event.
2294 * @param aGUIEvent The handling event.
2295 * @return The frame which should handle the
2296 * event. nullptr if the caller should
2297 * stop handling the event.
2299 MOZ_CAN_RUN_SCRIPT
2300 nsIFrame* GetFrameToHandleNonTouchEvent(nsIFrame* aRootFrameToHandleEvent,
2301 WidgetGUIEvent* aGUIEvent);
2304 * ComputeEventTargetFrameAndPresShellAtEventPoint() computes event
2305 * target frame at the event point of aGUIEvent and set it to
2306 * aEventTargetData.
2308 * @param aRootFrameToHandleEvent The root frame to handle aGUIEvent.
2309 * @param aGUIEvent The handling event.
2310 * @param aEventTargetData [out] Its frame and PresShell will
2311 * be set.
2312 * @return true if the caller can handle the
2313 * event. Otherwise, false.
2315 MOZ_CAN_RUN_SCRIPT
2316 bool ComputeEventTargetFrameAndPresShellAtEventPoint(
2317 nsIFrame* aRootFrameToHandleEvent, WidgetGUIEvent* aGUIEvent,
2318 EventTargetData* aEventTargetData);
2321 * DispatchPrecedingPointerEvent() dispatches preceding pointer event for
2322 * aGUIEvent if Pointer Events is enabled.
2324 * @param aFrameForPresShell The frame for PresShell. See
2325 * explanation of HandleEvent() for the
2326 * details.
2327 * @param aGUIEvent The handled event.
2328 * @param aPointerCapturingContent The content which is capturing pointer
2329 * events if there is. Otherwise, nullptr.
2330 * @param aDontRetargetEvents Set aDontRetargetEvents of
2331 * HandleEvent() which called this method.
2332 * @param aEventTargetData [in/out] Event target data of
2333 * aGUIEvent. If pointer event listeners
2334 * change the DOM tree or reframe the
2335 * target, updated by this method.
2336 * @param aEventStatus [in/out] The event status of aGUIEvent.
2337 * @return true if the caller can handle the
2338 * event. Otherwise, false.
2340 MOZ_CAN_RUN_SCRIPT
2341 bool DispatchPrecedingPointerEvent(nsIFrame* aFrameForPresShell,
2342 WidgetGUIEvent* aGUIEvent,
2343 nsIContent* aPointerCapturingContent,
2344 bool aDontRetargetEvents,
2345 EventTargetData* aEventTargetData,
2346 nsEventStatus* aEventStatus);
2349 * MaybeDiscardEvent() checks whether it's safe to handle aGUIEvent right
2350 * now. If it's not safe, this may notify somebody of discarding event if
2351 * necessary.
2353 * @param aGUIEvent Handling event.
2354 * @return true if it's not safe to handle the event.
2356 bool MaybeDiscardEvent(WidgetGUIEvent* aGUIEvent);
2359 * GetCapturingContentFor() returns capturing content for aGUIEvent.
2360 * If aGUIEvent is not related to capturing, this returns nullptr.
2362 static nsIContent* GetCapturingContentFor(WidgetGUIEvent* aGUIEvent);
2365 * GetRetargetEventDocument() returns a document if aGUIEvent should be
2366 * handled in another document.
2368 * @param aGUIEvent Handling event.
2369 * @param aRetargetEventDocument Document which should handle aGUIEvent.
2370 * @return true if caller can keep handling
2371 * aGUIEvent.
2373 bool GetRetargetEventDocument(WidgetGUIEvent* aGUIEvent,
2374 Document** aRetargetEventDocument);
2377 * GetFrameForHandlingEventWith() returns a frame which should be used as
2378 * aFrameForPresShell of HandleEvent(). See @return for the details.
2380 * @param aGUIEvent Handling event.
2381 * @param aRetargetDocument Document which aGUIEvent should be
2382 * fired on. Typically, should be result
2383 * of GetRetargetEventDocument().
2384 * @param aFrameForPresShell The frame for PresShell. See
2385 * explanation of HandleEvent() for the
2386 * details.
2387 * @return nullptr if caller should stop handling
2388 * the event.
2389 * aFrameForPresShell if caller should
2390 * keep handling the event by itself.
2391 * Otherwise, caller should handle it with
2392 * another PresShell which is result of
2393 * nsIFrame::PresContext()->GetPresShell().
2395 nsIFrame* GetFrameForHandlingEventWith(WidgetGUIEvent* aGUIEvent,
2396 Document* aRetargetDocument,
2397 nsIFrame* aFrameForPresShell);
2400 * MaybeHandleEventWithAnotherPresShell() may handle aGUIEvent with another
2401 * PresShell.
2403 * @param aFrameForPresShell The frame for PresShell. See
2404 * explanation of HandleEvent() for the
2405 * details.
2406 * @param aGUIEvent Handling event.
2407 * @param aEventStatus [in/out] EventStatus of aGUIEvent.
2408 * @param aRv [out] Returns error if this gets an
2409 * error handling the event.
2410 * @return false if caller needs to keep handling
2411 * the event by itself.
2412 * true if caller shouldn't keep handling
2413 * the event. Note that when no PresShell
2414 * can handle the event, this returns true.
2416 MOZ_CAN_RUN_SCRIPT
2417 bool MaybeHandleEventWithAnotherPresShell(nsIFrame* aFrameForPresShell,
2418 WidgetGUIEvent* aGUIEvent,
2419 nsEventStatus* aEventStatus,
2420 nsresult* aRv);
2422 MOZ_CAN_RUN_SCRIPT
2423 nsresult RetargetEventToParent(WidgetGUIEvent* aGUIEvent,
2424 nsEventStatus* aEventStatus);
2427 * MaybeHandleEventWithAccessibleCaret() may handle aGUIEvent with
2428 * AccessibleCaretEventHub if it's necessary.
2430 * @param aFrameForPresShell The frame for PresShell. See explanation of
2431 * HandleEvent() for the details.
2432 * @param aGUIEvent Event may be handled by AccessibleCaretEventHub.
2433 * @param aEventStatus [in/out] EventStatus of aGUIEvent.
2434 * @return true if AccessibleCaretEventHub handled the
2435 * event and caller shouldn't keep handling it.
2437 MOZ_CAN_RUN_SCRIPT
2438 bool MaybeHandleEventWithAccessibleCaret(nsIFrame* aFrameForPresShell,
2439 WidgetGUIEvent* aGUIEvent,
2440 nsEventStatus* aEventStatus);
2443 * Maybe dispatch mouse events for aTouchEnd. This should be called after
2444 * aTouchEndEvent is dispatched into the DOM.
2446 MOZ_CAN_RUN_SCRIPT void MaybeSynthesizeCompatMouseEventsForTouchEnd(
2447 const WidgetTouchEvent* aTouchEndEvent,
2448 const nsEventStatus* aStatus) const;
2451 * MaybeDiscardOrDelayKeyboardEvent() may discared or put aGUIEvent into
2452 * the delayed event queue if it's a keyboard event and if we should do so.
2453 * If aGUIEvent is not a keyboard event, this does nothing.
2455 * @param aGUIEvent The handling event.
2456 * @return true if this method discard the event or
2457 * put it into the delayed event queue.
2459 bool MaybeDiscardOrDelayKeyboardEvent(WidgetGUIEvent* aGUIEvent);
2462 * MaybeDiscardOrDelayMouseEvent() may discard or put aGUIEvent into the
2463 * delayed event queue if it's a mouse event and if we should do so.
2464 * If aGUIEvent is not a mouse event, this does nothing.
2465 * If there is suppressed event listener like debugger of devtools, this
2466 * notifies it of the event after discard or put it into the delayed
2467 * event queue.
2469 * @param aFrameToHandleEvent The frame to handle aGUIEvent.
2470 * @param aGUIEvent The handling event.
2471 * @return true if this method discard the event
2472 * or put it into the delayed event queue.
2474 bool MaybeDiscardOrDelayMouseEvent(nsIFrame* aFrameToHandleEvent,
2475 WidgetGUIEvent* aGUIEvent);
2478 * MaybeFlushThrottledStyles() tries to flush pending animation. If it's
2479 * flushed and then aFrameForPresShell is destroyed, returns new frame
2480 * which contains mPresShell.
2482 * @param aFrameForPresShell The frame for PresShell. See
2483 * explanation of HandleEvent() for the
2484 * details. This can be nullptr.
2485 * @return Maybe new frame for mPresShell.
2486 * If aFrameForPresShell is not nullptr
2487 * and hasn't been destroyed, returns
2488 * aFrameForPresShell as-is.
2490 MOZ_CAN_RUN_SCRIPT
2491 nsIFrame* MaybeFlushThrottledStyles(nsIFrame* aFrameForPresShell);
2494 * ComputeRootFrameToHandleEvent() returns root frame to handle the event.
2495 * For example, if there is a popup, this returns the popup frame.
2496 * If there is capturing content and it's in a scrolled frame, returns
2497 * the scrolled frame.
2499 * @param aFrameForPresShell The frame for PresShell. See
2500 * explanation of HandleEvent() for
2501 * the details.
2502 * @param aGUIEvent The handling event.
2503 * @param aCapturingContent Capturing content if there is.
2504 * nullptr, otherwise.
2505 * @param aIsCapturingContentIgnored [out] true if aCapturingContent
2506 * is not nullptr but it should be
2507 * ignored to handle the event.
2508 * @param aIsCaptureRetargeted [out] true if aCapturingContent
2509 * is not nullptr but it's
2510 * retargeted.
2511 * @return Root frame to handle the event.
2513 nsIFrame* ComputeRootFrameToHandleEvent(nsIFrame* aFrameForPresShell,
2514 WidgetGUIEvent* aGUIEvent,
2515 nsIContent* aCapturingContent,
2516 bool* aIsCapturingContentIgnored,
2517 bool* aIsCaptureRetargeted);
2520 * ComputeRootFrameToHandleEventWithPopup() returns popup frame if there
2521 * is a popup and we should handle the event in it. Otherwise, returns
2522 * aRootFrameToHandleEvent.
2524 * @param aRootFrameToHandleEvent Candidate root frame to handle
2525 * the event.
2526 * @param aGUIEvent The handling event.
2527 * @param aCapturingContent Capturing content if there is.
2528 * nullptr, otherwise.
2529 * @param aIsCapturingContentIgnored [out] true if aCapturingContent
2530 * is not nullptr but it should be
2531 * ignored to handle the event.
2532 * @return A popup frame if there is a
2533 * popup and we should handle the
2534 * event in it. Otherwise,
2535 * aRootFrameToHandleEvent.
2536 * I.e., never returns nullptr.
2538 nsIFrame* ComputeRootFrameToHandleEventWithPopup(
2539 nsIFrame* aRootFrameToHandleEvent, WidgetGUIEvent* aGUIEvent,
2540 nsIContent* aCapturingContent, bool* aIsCapturingContentIgnored);
2543 * ComputeRootFrameToHandleEventWithCapturingContent() returns root frame
2544 * to handle event for the capturing content, or aRootFrameToHandleEvent
2545 * if it should be ignored.
2547 * @param aRootFrameToHandleEvent Candidate root frame to handle
2548 * the event.
2549 * @param aCapturingContent Capturing content. nullptr is
2550 * not allowed.
2551 * @param aIsCapturingContentIgnored [out] true if aCapturingContent
2552 * is not nullptr but it should be
2553 * ignored to handle the event.
2554 * @param aIsCaptureRetargeted [out] true if aCapturingContent
2555 * is not nullptr but it's
2556 * retargeted.
2557 * @return A popup frame if there is a
2558 * popup and we should handle the
2559 * event in it. Otherwise,
2560 * aRootFrameToHandleEvent.
2561 * I.e., never returns nullptr.
2563 nsIFrame* ComputeRootFrameToHandleEventWithCapturingContent(
2564 nsIFrame* aRootFrameToHandleEvent, nsIContent* aCapturingContent,
2565 bool* aIsCapturingContentIgnored, bool* aIsCaptureRetargeted);
2568 * HandleEventWithPointerCapturingContentWithoutItsFrame() handles
2569 * aGUIEvent with aPointerCapturingContent when it does not have primary
2570 * frame.
2572 * @param aFrameForPresShell The frame for PresShell. See
2573 * explanation of HandleEvent() for the
2574 * details.
2575 * @param aGUIEvent The handling event.
2576 * @param aPointerCapturingContent Current pointer capturing content.
2577 * Must not be nullptr.
2578 * @param aEventStatus [in/out] The event status of aGUIEvent.
2579 * @return Basically, result of
2580 * HandeEventWithTraget().
2582 MOZ_CAN_RUN_SCRIPT
2583 nsresult HandleEventWithPointerCapturingContentWithoutItsFrame(
2584 nsIFrame* aFrameForPresShell, WidgetGUIEvent* aGUIEvent,
2585 nsIContent* aPointerCapturingContent, nsEventStatus* aEventStatus);
2588 * HandleEventAtFocusedContent() handles aGUIEvent at focused content.
2590 * @param aGUIEvent The handling event which should be handled at
2591 * focused content.
2592 * @param aEventStatus [in/out] The event status of aGUIEvent.
2594 MOZ_CAN_RUN_SCRIPT
2595 nsresult HandleEventAtFocusedContent(WidgetGUIEvent* aGUIEvent,
2596 nsEventStatus* aEventStatus);
2599 * ComputeFocusedEventTargetElement() returns event target element for
2600 * aGUIEvent which should be handled with focused content.
2601 * This may set/unset sLastKeyDownEventTarget if necessary.
2603 * @param aGUIEvent The handling event.
2604 * @return The element which should be the event
2605 * target of aGUIEvent.
2607 dom::Element* ComputeFocusedEventTargetElement(WidgetGUIEvent* aGUIEvent);
2610 * MaybeHandleEventWithAnotherPresShell() may handle aGUIEvent with another
2611 * PresShell.
2613 * @param aEventTargetElement The event target element of aGUIEvent.
2614 * @param aGUIEvent Handling event.
2615 * @param aEventStatus [in/out] EventStatus of aGUIEvent.
2616 * @param aRv [out] Returns error if this gets an
2617 * error handling the event.
2618 * @return false if caller needs to keep handling
2619 * the event by itself.
2620 * true if caller shouldn't keep handling
2621 * the event. Note that when no PresShell
2622 * can handle the event, this returns true.
2624 MOZ_CAN_RUN_SCRIPT
2625 bool MaybeHandleEventWithAnotherPresShell(dom::Element* aEventTargetElement,
2626 WidgetGUIEvent* aGUIEvent,
2627 nsEventStatus* aEventStatus,
2628 nsresult* aRv);
2631 * HandleRetargetedEvent() dispatches aGUIEvent on the PresShell without
2632 * retargetting. This should be used only when caller computes final
2633 * target of aGUIEvent.
2635 * @param aGUIEvent Event to be dispatched.
2636 * @param aEventStatus [in/out] EventStatus of aGUIEvent.
2637 * @param aTarget The final target of aGUIEvent.
2639 MOZ_CAN_RUN_SCRIPT
2640 nsresult HandleRetargetedEvent(WidgetGUIEvent* aGUIEvent,
2641 nsEventStatus* aEventStatus,
2642 nsIContent* aTarget) {
2643 AutoCurrentEventInfoSetter eventInfoSetter(*this, nullptr, aTarget);
2644 if (!mPresShell->GetCurrentEventFrame()) {
2645 return NS_OK;
2647 nsCOMPtr<nsIContent> overrideClickTarget;
2648 return HandleEventWithCurrentEventInfo(aGUIEvent, aEventStatus, true,
2649 overrideClickTarget);
2653 * HandleEventWithFrameForPresShell() handles aGUIEvent with the frame
2654 * for mPresShell.
2656 * @param aFrameForPresShell The frame for mPresShell.
2657 * @param aGUIEvent The handling event. It shouldn't be
2658 * handled with using coordinates nor
2659 * handled at focused content.
2660 * @param aEventStatus [in/out] The status of aGUIEvent.
2662 MOZ_CAN_RUN_SCRIPT
2663 nsresult HandleEventWithFrameForPresShell(nsIFrame* aFrameForPresShell,
2664 WidgetGUIEvent* aGUIEvent,
2665 nsEventStatus* aEventStatus);
2668 * HandleEventWithCurrentEventInfo() prepares to dispatch aEvent into the
2669 * DOM, dispatches aEvent into the DOM with using current event info of
2670 * mPresShell and notifies EventStateManager of that.
2672 * @param aEvent Event to be dispatched.
2673 * @param aEventStatus [in/out] EventStatus of aEvent.
2674 * @param aIsHandlingNativeEvent true if aGUIEvent represents a native
2675 * event.
2676 * @param aOverrideClickTarget Override click event target.
2678 MOZ_CAN_RUN_SCRIPT
2679 nsresult HandleEventWithCurrentEventInfo(WidgetEvent* aEvent,
2680 nsEventStatus* aEventStatus,
2681 bool aIsHandlingNativeEvent,
2682 nsIContent* aOverrideClickTarget);
2685 * HandlingTimeAccumulator() may accumulate handling time of telemetry
2686 * for each type of events.
2688 class MOZ_STACK_CLASS HandlingTimeAccumulator final {
2689 public:
2690 HandlingTimeAccumulator() = delete;
2691 HandlingTimeAccumulator(const HandlingTimeAccumulator& aOther) = delete;
2692 HandlingTimeAccumulator(const EventHandler& aEventHandler,
2693 const WidgetEvent* aEvent);
2694 ~HandlingTimeAccumulator();
2696 private:
2697 const EventHandler& mEventHandler;
2698 const WidgetEvent* mEvent;
2699 TimeStamp mHandlingStartTime;
2703 * RecordEventPreparationPerformance() records event preparation performance
2704 * with telemetry only when aEvent is a trusted event.
2706 * @param aEvent The handling event which we've finished
2707 * preparing something to dispatch.
2709 void RecordEventPreparationPerformance(const WidgetEvent* aEvent);
2712 * RecordEventHandlingResponsePerformance() records event handling response
2713 * performance with telemetry.
2715 * @param aEvent The handled event.
2717 void RecordEventHandlingResponsePerformance(const WidgetEvent* aEvent);
2720 * PrepareToDispatchEvent() prepares to dispatch aEvent.
2722 * @param aEvent The handling event.
2723 * @param aEventStatus [in/out] The status of aEvent.
2724 * @param aTouchIsNew [out] Set to true if the event is an
2725 * eTouchMove event and it represents new
2726 * touch. Otherwise, set to false.
2727 * @return true if the caller can dispatch the
2728 * event into the DOM.
2730 MOZ_CAN_RUN_SCRIPT
2731 bool PrepareToDispatchEvent(WidgetEvent* aEvent,
2732 nsEventStatus* aEventStatus, bool* aTouchIsNew);
2735 * MaybeHandleKeyboardEventBeforeDispatch() may handle aKeyboardEvent
2736 * if it should do something before dispatched into the DOM.
2738 * @param aKeyboardEvent The handling keyboard event.
2740 MOZ_CAN_RUN_SCRIPT
2741 void MaybeHandleKeyboardEventBeforeDispatch(
2742 WidgetKeyboardEvent* aKeyboardEvent);
2745 * This and the next two helper methods are used to target and position the
2746 * context menu when the keyboard shortcut is used to open it.
2748 * If another menu is open, the context menu is opened relative to the
2749 * active menuitem within the menu, or the menu itself if no item is active.
2750 * Otherwise, if the caret is visible, the menu is opened near the caret.
2751 * Otherwise, if a selectable list such as a listbox is focused, the
2752 * current item within the menu is opened relative to this item.
2753 * Otherwise, the context menu is opened at the topleft corner of the
2754 * view.
2756 * Returns true if the context menu event should fire and false if it should
2757 * not.
2759 MOZ_CAN_RUN_SCRIPT
2760 bool AdjustContextMenuKeyEvent(WidgetMouseEvent* aMouseEvent);
2762 MOZ_CAN_RUN_SCRIPT
2763 bool PrepareToUseCaretPosition(nsIWidget* aEventWidget,
2764 LayoutDeviceIntPoint& aTargetPt);
2767 * Get the selected item and coordinates in device pixels relative to root
2768 * document's root view for element, first ensuring the element is onscreen.
2770 MOZ_CAN_RUN_SCRIPT
2771 void GetCurrentItemAndPositionForElement(dom::Element* aFocusedElement,
2772 nsIContent** aTargetToUse,
2773 LayoutDeviceIntPoint& aTargetPt,
2774 nsIWidget* aRootWidget);
2776 nsIContent* GetOverrideClickTarget(WidgetGUIEvent* aGUIEvent,
2777 nsIFrame* aFrame);
2780 * DispatchEvent() tries to dispatch aEvent and notifies aEventStateManager
2781 * of doing it.
2783 * @param aEventStateManager EventStateManager which should handle
2784 * the event before/after dispatching
2785 * aEvent into the DOM.
2786 * @param aEvent The handling event.
2787 * @param aTouchIsNew Set this to true when the message is
2788 * eTouchMove and it's newly touched.
2789 * Then, the "touchmove" event becomes
2790 * cancelable.
2791 * @param aEventStatus [in/out] The status of aEvent.
2792 * @param aOverrideClickTarget Override click event target.
2794 MOZ_CAN_RUN_SCRIPT nsresult
2795 DispatchEvent(EventStateManager* aEventStateManager, WidgetEvent* aEvent,
2796 bool aTouchIsNew, nsEventStatus* aEventStatus,
2797 nsIContent* aOverrideClickTarget);
2800 * DispatchEventToDOM() actually dispatches aEvent into the DOM tree.
2802 * @param aEvent Event to be dispatched into the DOM tree.
2803 * @param aEventStatus [in/out] EventStatus of aEvent.
2804 * @param aEventCB The callback kicked when the event moves
2805 * from the default group to the system group.
2807 MOZ_CAN_RUN_SCRIPT nsresult
2808 DispatchEventToDOM(WidgetEvent* aEvent, nsEventStatus* aEventStatus,
2809 nsPresShellEventCB* aEventCB);
2812 * DispatchTouchEventToDOM() dispatches touch events into the DOM tree.
2814 * @param aEvent The source of events to be dispatched into the
2815 * DOM tree.
2816 * @param aEventStatus [in/out] EventStatus of aEvent.
2817 * @param aEventCB The callback kicked when the events move
2818 * from the default group to the system group.
2819 * @param aTouchIsNew Set this to true when the message is eTouchMove
2820 * and it's newly touched. Then, the "touchmove"
2821 * event becomes cancelable.
2823 MOZ_CAN_RUN_SCRIPT void DispatchTouchEventToDOM(
2824 WidgetEvent* aEvent, nsEventStatus* aEventStatus,
2825 nsPresShellEventCB* aEventCB, bool aTouchIsNew);
2828 * FinalizeHandlingEvent() should be called after calling DispatchEvent()
2829 * and then, this cleans up the state of mPresShell and aEvent.
2831 * @param aEvent The handled event.
2832 * @param aStatus The status of aEvent. Must not be nullptr.
2834 MOZ_CAN_RUN_SCRIPT void FinalizeHandlingEvent(WidgetEvent* aEvent,
2835 const nsEventStatus* aStatus);
2838 * AutoCurrentEventInfoSetter() pushes and pops current event info of
2839 * aEventHandler.mPresShell.
2841 struct MOZ_STACK_CLASS AutoCurrentEventInfoSetter final {
2842 explicit AutoCurrentEventInfoSetter(EventHandler& aEventHandler)
2843 : mEventHandler(aEventHandler) {
2844 MOZ_DIAGNOSTIC_ASSERT(!mEventHandler.mCurrentEventInfoSetter);
2845 mEventHandler.mCurrentEventInfoSetter = this;
2846 mEventHandler.mPresShell->PushCurrentEventInfo(nullptr, nullptr);
2848 AutoCurrentEventInfoSetter(EventHandler& aEventHandler, nsIFrame* aFrame,
2849 nsIContent* aContent)
2850 : mEventHandler(aEventHandler) {
2851 MOZ_DIAGNOSTIC_ASSERT(!mEventHandler.mCurrentEventInfoSetter);
2852 mEventHandler.mCurrentEventInfoSetter = this;
2853 mEventHandler.mPresShell->PushCurrentEventInfo(aFrame, aContent);
2855 AutoCurrentEventInfoSetter(EventHandler& aEventHandler,
2856 EventTargetData& aEventTargetData)
2857 : mEventHandler(aEventHandler) {
2858 MOZ_DIAGNOSTIC_ASSERT(!mEventHandler.mCurrentEventInfoSetter);
2859 mEventHandler.mCurrentEventInfoSetter = this;
2860 mEventHandler.mPresShell->PushCurrentEventInfo(
2861 aEventTargetData.GetFrame(), aEventTargetData.GetContent());
2863 ~AutoCurrentEventInfoSetter() {
2864 mEventHandler.mPresShell->PopCurrentEventInfo();
2865 mEventHandler.mCurrentEventInfoSetter = nullptr;
2868 private:
2869 EventHandler& mEventHandler;
2873 * Wrapper methods to access methods of mPresShell.
2875 nsPresContext* GetPresContext() const {
2876 return mPresShell->GetPresContext();
2878 Document* GetDocument() const { return mPresShell->GetDocument(); }
2879 nsCSSFrameConstructor* FrameConstructor() const {
2880 return mPresShell->FrameConstructor();
2882 already_AddRefed<nsPIDOMWindowOuter> GetFocusedDOMWindowInOurWindow() {
2883 return mPresShell->GetFocusedDOMWindowInOurWindow();
2885 already_AddRefed<PresShell> GetParentPresShellForEventHandling() {
2886 return mPresShell->GetParentPresShellForEventHandling();
2888 OwningNonNull<PresShell> mPresShell;
2889 AutoCurrentEventInfoSetter* mCurrentEventInfoSetter;
2890 static TimeStamp sLastInputCreated;
2891 static TimeStamp sLastInputProcessed;
2892 static StaticRefPtr<dom::Element> sLastKeyDownEventTargetElement;
2895 PresShell* GetRootPresShell() const;
2897 bool IsTransparentContainerElement() const;
2898 ColorScheme DefaultBackgroundColorScheme() const;
2899 nscolor GetDefaultBackgroundColorToDraw() const;
2901 //////////////////////////////////////////////////////////////////////////////
2902 // Approximate frame visibility tracking implementation.
2903 //////////////////////////////////////////////////////////////////////////////
2905 void UpdateApproximateFrameVisibility();
2906 void DoUpdateApproximateFrameVisibility(bool aRemoveOnly);
2908 void ClearApproximatelyVisibleFramesList(
2909 const Maybe<OnNonvisible>& aNonvisibleAction = Nothing());
2910 static void ClearApproximateFrameVisibilityVisited(nsView* aView,
2911 bool aClear);
2912 static void MarkFramesInListApproximatelyVisible(const nsDisplayList& aList);
2913 void MarkFramesInSubtreeApproximatelyVisible(nsIFrame* aFrame,
2914 const nsRect& aRect,
2915 bool aRemoveOnly = false);
2917 void DecApproximateVisibleCount(
2918 VisibleFrames& aFrames,
2919 const Maybe<OnNonvisible>& aNonvisibleAction = Nothing());
2921 nsRevocableEventPtr<nsRunnableMethod<PresShell>>
2922 mUpdateApproximateFrameVisibilityEvent;
2924 // A set of frames that were visible or could be visible soon at the time
2925 // that we last did an approximate frame visibility update.
2926 VisibleFrames mApproximatelyVisibleFrames;
2928 #ifdef DEBUG
2929 MOZ_CAN_RUN_SCRIPT_BOUNDARY bool VerifyIncrementalReflow();
2930 MOZ_CAN_RUN_SCRIPT_BOUNDARY void DoVerifyReflow();
2931 void VerifyHasDirtyRootAncestor(nsIFrame* aFrame);
2933 bool mInVerifyReflow = false;
2934 // The reflow root under which we're currently reflowing. Null when
2935 // not in reflow.
2936 nsIFrame* mCurrentReflowRoot = nullptr;
2937 #endif // #ifdef DEBUG
2939 // Send, and reset, the current per tick telemetry. This includes:
2940 // * non-zero number of style and layout flushes
2941 // * non-zero ms duration spent in style and reflow since the last tick.
2942 void PingPerTickTelemetry(FlushType aFlushType);
2944 private:
2945 // IMPORTANT: The ownership implicit in the following member variables
2946 // has been explicitly checked. If you add any members to this class,
2947 // please make the ownership explicit (pinkerton, scc).
2949 // These are the same Document and PresContext owned by the DocViewer.
2950 // we must share ownership.
2951 // mDocument and mPresContext should've never been cleared nor swapped with
2952 // another instance while PresShell instance is alive so that it's safe to
2953 // call their can-run- script methods without local RefPtr variables.
2954 MOZ_KNOWN_LIVE RefPtr<Document> const mDocument;
2955 MOZ_KNOWN_LIVE RefPtr<nsPresContext> const mPresContext;
2956 UniquePtr<nsCSSFrameConstructor> mFrameConstructor;
2957 nsViewManager* mViewManager; // [WEAK] docViewer owns it so I don't have to
2958 RefPtr<nsFrameSelection> mSelection;
2959 // The frame selection that last took focus on this shell, which we need to
2960 // hide if we focus another selection. May or may not be the same as
2961 // `mSelection`.
2962 RefPtr<nsFrameSelection> mFocusedFrameSelection;
2963 RefPtr<nsCaret> mCaret;
2964 RefPtr<nsCaret> mOriginalCaret;
2965 RefPtr<AccessibleCaretEventHub> mAccessibleCaretEventHub;
2966 // Pointer into mFrameConstructor - this is purely so that GetRootFrame() can
2967 // be inlined:
2968 nsFrameManager* mFrameManager;
2969 WeakPtr<nsDocShell> mForwardingContainer;
2971 // The `performance.now()` value when we last started to process reflows.
2972 DOMHighResTimeStamp mLastReflowStart{0.0};
2974 // At least on Win32 and Mac after interupting a reflow we need to post
2975 // the resume reflow event off a timer to avoid event starvation because
2976 // posted messages are processed before other messages when the modal
2977 // moving/sizing loop is running, see bug 491700 for details.
2978 nsCOMPtr<nsITimer> mReflowContinueTimer;
2980 #ifdef DEBUG
2981 // We track allocated pointers in a diagnostic hash set, to assert against
2982 // missing/double frees. This set is allocated infallibly in the PresShell
2983 // constructor's initialization list. The set can get quite large, so we use
2984 // fallible allocation when inserting into it; and if these operations ever
2985 // fail, then we just get rid of the set and stop using this diagnostic from
2986 // that point on. (There's not much else we can do, when the set grows
2987 // larger than the available memory.)
2988 UniquePtr<nsTHashSet<void*>> mAllocatedPointers{
2989 MakeUnique<nsTHashSet<void*>>()};
2990 #endif
2992 // A list of stack weak frames. This is a pointer to the last item in the
2993 // list.
2994 AutoWeakFrame* mAutoWeakFrames;
2996 // A hash table of heap allocated weak frames.
2997 nsTHashSet<WeakFrame*> mWeakFrames;
2999 // Reflow roots that need to be reflowed.
3000 DepthOrderedFrameList mDirtyRoots;
3002 // These two fields capture call stacks of any changes that require a restyle
3003 // or a reflow. Only the first change per restyle / reflow is recorded (the
3004 // one that caused a call to SetNeedStyleFlush() / SetNeedLayoutFlush()).
3005 UniquePtr<ProfileChunkedBuffer> mStyleCause;
3006 UniquePtr<ProfileChunkedBuffer> mReflowCause;
3008 nsTArray<UniquePtr<DelayedEvent>> mDelayedEvents;
3010 nsRevocableEventPtr<nsSynthMouseMoveEvent> mSynthMouseMoveEvent;
3012 TouchManager mTouchManager;
3014 RefPtr<ZoomConstraintsClient> mZoomConstraintsClient;
3015 RefPtr<GeckoMVMContext> mMVMContext;
3016 RefPtr<MobileViewportManager> mMobileViewportManager;
3018 // This timer controls painting suppression. Until it fires
3019 // or all frames are constructed, we won't paint anything but
3020 // our <body> background and scrollbars.
3021 nsCOMPtr<nsITimer> mPaintSuppressionTimer;
3023 // Information about live content (which still stay in DOM tree).
3024 // Used in case we need re-dispatch event after sending pointer event,
3025 // when target of pointer event was deleted during executing user handlers.
3026 nsCOMPtr<nsIContent> mPointerEventTarget;
3028 nsCOMPtr<nsIContent> mLastAnchorScrolledTo;
3030 // Information needed to properly handle scrolling content into view if the
3031 // pre-scroll reflow flush can be interrupted. mContentToScrollTo is non-null
3032 // between the initial scroll attempt and the first time we finish processing
3033 // all our dirty roots. mContentToScrollTo has a content property storing the
3034 // details for the scroll operation, see ScrollIntoViewData above.
3035 nsCOMPtr<nsIContent> mContentToScrollTo;
3037 #ifdef ACCESSIBILITY
3038 a11y::DocAccessible* mDocAccessible;
3039 #endif // #ifdef ACCESSIBILITY
3041 nsIFrame* mCurrentEventFrame;
3042 nsCOMPtr<nsIContent> mCurrentEventContent;
3043 nsTArray<nsIFrame*> mCurrentEventFrameStack;
3044 nsCOMArray<nsIContent> mCurrentEventContentStack;
3045 // Set of frames that we should mark with NS_FRAME_HAS_DIRTY_CHILDREN after
3046 // we finish reflowing mCurrentReflowRoot.
3047 nsTHashSet<nsIFrame*> mFramesToDirty;
3048 nsTHashSet<nsIScrollableFrame*> mPendingScrollAnchorSelection;
3049 nsTHashSet<nsIScrollableFrame*> mPendingScrollAnchorAdjustment;
3050 nsTHashSet<nsIScrollableFrame*> mPendingScrollResnap;
3052 nsTHashSet<nsIContent*> mHiddenContentInForcedLayout;
3054 nsTHashSet<nsIFrame*> mContentVisibilityAutoFrames;
3056 // The type of content relevancy to update the next time content relevancy
3057 // updates are triggered for `content-visibility: auto` frames.
3058 ContentRelevancy mContentVisibilityRelevancyToUpdate;
3060 nsCallbackEventRequest* mFirstCallbackEventRequest = nullptr;
3061 nsCallbackEventRequest* mLastCallbackEventRequest = nullptr;
3063 // This is used for synthetic mouse events that are sent when what is under
3064 // the mouse pointer may have changed without the mouse moving (eg scrolling,
3065 // change to the document contents).
3066 // It is set only on a presshell for a root document, this value represents
3067 // the last observed location of the mouse relative to that root document,
3068 // in visual coordinates. It is set to (NS_UNCONSTRAINEDSIZE,
3069 // NS_UNCONSTRAINEDSIZE) if the mouse isn't over our window or there is no
3070 // last observed mouse location for some reason.
3071 nsPoint mMouseLocation;
3072 // This is used for the synthetic mouse events too. This is set when a mouse
3073 // event is dispatched into the DOM.
3074 static int16_t sMouseButtons;
3075 // The last observed pointer location relative to that root document in visual
3076 // coordinates.
3077 nsPoint mLastOverWindowPointerLocation;
3078 // This is an APZ state variable that tracks the target guid for the last
3079 // mouse event that was processed (corresponding to mMouseLocation). This is
3080 // needed for the synthetic mouse events.
3081 layers::ScrollableLayerGuid mMouseEventTargetGuid;
3083 // Only populated on root content documents.
3084 nsSize mVisualViewportSize;
3086 // The focus information needed for async keyboard scrolling
3087 FocusTarget mAPZFocusTarget;
3089 using Arena = nsPresArena<8192, ArenaObjectID, eArenaObjectID_COUNT>;
3090 Arena mFrameArena;
3092 Maybe<nsPoint> mVisualViewportOffset;
3094 // A pending visual scroll offset that we will ask APZ to scroll to
3095 // during the next transaction. Cleared when we send the transaction.
3096 // Only applicable to the RCD pres shell.
3097 Maybe<VisualScrollUpdate> mPendingVisualScrollUpdate;
3099 // Used to force allocation and rendering of proportionally more or
3100 // less pixels in both dimensions.
3101 Maybe<float> mResolution;
3102 ResolutionChangeOrigin mLastResolutionChangeOrigin;
3104 TimeStamp mLoadBegin; // used to time loads
3106 TimeStamp mLastOSWake;
3108 // Count of the number of times this presshell has been painted to a window.
3109 uint64_t mPaintCount;
3111 // The focus sequence number of the last processed input event
3112 uint64_t mAPZFocusSequenceNumber;
3114 nscoord mLastAnchorScrollPositionY = 0;
3116 // Most recent canvas background color.
3117 CanvasBackground mCanvasBackground;
3119 int32_t mActiveSuppressDisplayport;
3121 uint32_t mPresShellId;
3123 // Cached font inflation values. This is done to prevent changing of font
3124 // inflation until a page is reloaded.
3125 uint32_t mFontSizeInflationEmPerLine;
3126 uint32_t mFontSizeInflationMinTwips;
3127 uint32_t mFontSizeInflationLineThreshold;
3129 // Can be multiple of nsISelectionDisplay::DISPLAY_*.
3130 int16_t mSelectionFlags;
3132 // This is used to protect ourselves from triggering reflow while in the
3133 // middle of frame construction and the like... it really shouldn't be
3134 // needed, one hopes, but it is for now.
3135 uint16_t mChangeNestCount;
3137 // Flags controlling how our document is rendered. These persist
3138 // between paints and so are tied with retained layer pixels.
3139 // PresShell flushes retained layers when the rendering state
3140 // changes in a way that prevents us from being able to (usefully)
3141 // re-use old pixels.
3142 RenderingStateFlags mRenderingStateFlags;
3144 // Whether we're currently under a FlushPendingNotifications.
3145 // This is used to handle flush reentry correctly.
3146 // NOTE: This can't be a bitfield since AutoRestore has a reference to this
3147 // variable.
3148 bool mInFlush;
3150 bool mCaretEnabled : 1;
3152 // True if a layout flush might not be a no-op
3153 bool mNeedLayoutFlush : 1;
3155 // True if a style flush might not be a no-op
3156 bool mNeedStyleFlush : 1;
3158 // True if there are throttled animations that would be processed when
3159 // performing a flush with mFlushAnimations == true.
3160 bool mNeedThrottledAnimationFlush : 1;
3162 bool mVisualViewportSizeSet : 1;
3164 bool mDidInitialize : 1;
3165 bool mIsDestroying : 1;
3166 bool mIsReflowing : 1;
3167 bool mIsObservingDocument : 1;
3169 // Whether we shouldn't ever get to FlushPendingNotifications. This flag is
3170 // meant only to sanity-check / assert that FlushPendingNotifications doesn't
3171 // happen during certain periods of time. It shouldn't be made public nor used
3172 // for other purposes.
3173 bool mForbiddenToFlush : 1;
3175 // We've been disconnected from the document. We will refuse to paint the
3176 // document until either our timer fires or all frames are constructed.
3177 bool mIsDocumentGone : 1;
3178 bool mHaveShutDown : 1;
3180 // For all documents we initially lock down painting.
3181 bool mPaintingSuppressed : 1;
3183 bool mLastRootReflowHadUnconstrainedBSize : 1;
3185 // Indicates that it is safe to unlock painting once all pending reflows
3186 // have been processed.
3187 bool mShouldUnsuppressPainting : 1;
3189 bool mIgnoreFrameDestruction : 1;
3191 bool mIsActive : 1;
3192 bool mFrozen : 1;
3193 bool mIsFirstPaint : 1;
3194 bool mObservesMutationsForPrint : 1;
3196 // Whether the most recent interruptible reflow was actually interrupted:
3197 bool mWasLastReflowInterrupted : 1;
3199 // True if we're observing the refresh driver for style flushes.
3200 bool mObservingStyleFlushes : 1;
3202 // True if we're observing the refresh driver for layout flushes, that is, if
3203 // we have a reflow scheduled.
3205 // Guaranteed to be false if mReflowContinueTimer is non-null.
3206 bool mObservingLayoutFlushes : 1;
3208 bool mResizeEventPending : 1;
3210 bool mFontSizeInflationForceEnabled : 1;
3211 bool mFontSizeInflationDisabledInMasterProcess : 1;
3212 bool mFontSizeInflationEnabled : 1;
3214 // If a document belongs to an invisible DocShell, this flag must be set
3215 // to true, so we can avoid any paint calls for widget related to this
3216 // presshell.
3217 bool mIsNeverPainting : 1;
3219 // Whether the most recent change to the pres shell resolution was
3220 // originated by the main thread.
3221 bool mResolutionUpdated : 1;
3223 // True if the resolution has been ever changed by APZ.
3224 bool mResolutionUpdatedByApz : 1;
3226 // Whether this presshell is hidden by 'vibility:hidden' on an ancestor
3227 // nsSubDocumentFrame.
3228 bool mUnderHiddenEmbedderElement : 1;
3230 bool mDocumentLoading : 1;
3231 bool mNoDelayedMouseEvents : 1;
3232 bool mNoDelayedKeyEvents : 1;
3234 bool mApproximateFrameVisibilityVisited : 1;
3236 // Whether the last chrome-only escape key event is consumed.
3237 bool mIsLastChromeOnlyEscapeKeyConsumed : 1;
3239 // Whether the widget has received a paint message yet.
3240 bool mHasReceivedPaintMessage : 1;
3242 bool mIsLastKeyDownCanceled : 1;
3244 // Whether we have ever handled a user input event
3245 bool mHasHandledUserInput : 1;
3247 // Whether we should dispatch keypress events even for non-printable keys
3248 // for keeping backward compatibility.
3249 bool mForceDispatchKeyPressEventsForNonPrintableKeys : 1;
3250 // Whether we should set keyCode or charCode value of keypress events whose
3251 // value is zero to the other value or not. When this is set to true, we
3252 // should keep using legacy keyCode and charCode values (i.e., one of them
3253 // is always 0).
3254 bool mForceUseLegacyKeyCodeAndCharCodeValues : 1;
3255 // Whether mForceDispatchKeyPressEventsForNonPrintableKeys and
3256 // mForceUseLegacyKeyCodeAndCharCodeValues are initialized.
3257 bool mInitializedWithKeyPressEventDispatchingBlacklist : 1;
3259 // Set to true if mMouseLocation is set by a mouse event which is synthesized
3260 // for tests.
3261 bool mMouseLocationWasSetBySynthesizedMouseEventForTests : 1;
3263 bool mHasTriedFastUnsuppress : 1;
3265 bool mProcessingReflowCommands : 1;
3266 bool mPendingDidDoReflow : 1;
3268 struct CapturingContentInfo final {
3269 CapturingContentInfo()
3270 : mRemoteTarget(nullptr),
3271 mAllowed(false),
3272 mPointerLock(false),
3273 mRetargetToElement(false),
3274 mPreventDrag(false) {}
3276 // capture should only be allowed during a mousedown event
3277 StaticRefPtr<nsIContent> mContent;
3278 dom::BrowserParent* mRemoteTarget;
3279 bool mAllowed;
3280 bool mPointerLock;
3281 bool mRetargetToElement;
3282 bool mPreventDrag;
3284 static CapturingContentInfo sCapturingContentInfo;
3286 static bool sDisableNonTestMouseEvents;
3288 static bool sProcessInteractable;
3290 layout_telemetry::Data mLayoutTelemetry;
3293 NS_DEFINE_STATIC_IID_ACCESSOR(PresShell, NS_PRESSHELL_IID)
3295 } // namespace mozilla
3297 #endif // mozilla_PresShell_h