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/. */
6 
7 /* a presentation of a document, part 2 */
8 
9 #ifndef mozilla_PresShell_h
10 #define mozilla_PresShell_h
11 
12 #include "mozilla/PresShellForwards.h"
13 
14 #include <stdio.h>  // for FILE definition
15 #include "FrameMetrics.h"
16 #include "TouchManager.h"
17 #include "Units.h"
18 #include "Visibility.h"
19 #include "mozilla/ArenaObjectID.h"
20 #include "mozilla/Attributes.h"
21 #include "mozilla/FlushType.h"
22 #include "mozilla/MemoryReporting.h"
23 #include "mozilla/ScrollTypes.h"
24 #include "mozilla/StaticPtr.h"
25 #include "mozilla/UniquePtr.h"
26 #include "mozilla/WeakPtr.h"
27 #include "mozilla/dom/DocumentBinding.h"
28 #include "mozilla/layers/FocusTarget.h"
29 #include "mozilla/layout/LayoutTelemetryTools.h"
30 #include "mozilla/widget/ThemeChangeKind.h"
31 #include "nsColor.h"
32 #include "nsCOMArray.h"
33 #include "nsCoord.h"
34 #include "nsDOMNavigationTiming.h"
35 #include "nsFrameManager.h"
36 #include "nsFrameState.h"
37 #include "nsIContent.h"
38 #include "nsIObserver.h"
39 #include "nsISelectionController.h"
40 #include "nsQueryFrame.h"
41 #include "nsPresArena.h"
42 #include "nsPresContext.h"
43 #include "nsRect.h"
44 #include "nsRefreshObservers.h"
45 #include "nsStringFwd.h"
46 #include "nsStubDocumentObserver.h"
47 #include "nsTHashSet.h"
48 #include "nsThreadUtils.h"
49 #include "nsWeakReference.h"
50 
51 class AutoPointerEventTargetUpdater;
52 class AutoWeakFrame;
53 class gfxContext;
54 class MobileViewportManager;
55 #ifdef ACCESSIBILITY
56 class nsAccessibilityService;
57 #endif
58 class nsAutoCauseReflowNotifier;
59 class nsCanvasFrame;
60 class nsCaret;
61 class nsCSSFrameConstructor;
62 class nsDisplayList;
63 class nsDisplayListBuilder;
64 class nsDocShell;
65 class nsFrameSelection;
66 class nsIDocShell;
67 class nsIFrame;
68 class nsILayoutHistoryState;
69 class nsINode;
70 class nsPageSequenceFrame;
71 class nsIReflowCallback;
72 class nsIScrollableFrame;
73 class nsITimer;
74 class nsPIDOMWindowOuter;
75 class nsPresShellEventCB;
76 class nsRange;
77 class nsRefreshDriver;
78 class nsRegion;
79 class nsView;
80 class nsViewManager;
81 class nsWindowSizes;
82 struct RangePaintInfo;
83 #ifdef MOZ_REFLOW_PERF
84 class ReflowCountMgr;
85 #endif
86 class WeakFrame;
87 class ZoomConstraintsClient;
88 
89 struct nsCallbackEventRequest;
90 
91 namespace mozilla {
92 class AccessibleCaretEventHub;
93 class EventStates;
94 class GeckoMVMContext;
95 class OverflowChangedTracker;
96 class StyleSheet;
97 
98 class ProfileChunkedBuffer;
99 
100 #ifdef ACCESSIBILITY
101 namespace a11y {
102 class DocAccessible;
103 }  // namespace a11y
104 #endif
105 
106 namespace dom {
107 class BrowserParent;
108 class Element;
109 class Event;
110 class HTMLSlotElement;
111 class Selection;
112 }  // namespace dom
113 
114 namespace gfx {
115 class SourceSurface;
116 }  // namespace gfx
117 
118 namespace layers {
119 class LayerManager;
120 struct LayersId;
121 }  // namespace layers
122 
123 namespace layout {
124 class ScrollAnchorContainer;
125 }  // namespace layout
126 
127 // 039d8ffc-fa55-42d7-a53a-388cb129b052
128 #define NS_PRESSHELL_IID                             \
129   {                                                  \
130     0x039d8ffc, 0xfa55, 0x42d7, {                    \
131       0xa5, 0x3a, 0x38, 0x8c, 0xb1, 0x29, 0xb0, 0x52 \
132     }                                                \
133   }
134 
135 #undef NOISY_INTERRUPTIBLE_REFLOW
136 
137 /**
138  * Presentation shell. Presentation shells are the controlling point for
139  * managing the presentation of a document.  The presentation shell holds a
140  * live reference to the document, the presentation context, the style
141  * manager, the style set and the root frame.
142  *
143  * When this object is Release'd, it will release the document, the
144  * presentation context, the style manager, the style set and the root frame.
145  */
146 
147 class PresShell final : public nsStubDocumentObserver,
148                         public nsISelectionController,
149                         public nsIObserver,
150                         public nsSupportsWeakReference {
151   typedef dom::Document Document;
152   typedef dom::Element Element;
153   typedef gfx::SourceSurface SourceSurface;
154   typedef layers::FocusTarget FocusTarget;
155   typedef layers::FrameMetrics FrameMetrics;
156   typedef layers::LayerManager LayerManager;
157 
158   // A set type for tracking visible frames, for use by the visibility code in
159   // PresShell. The set contains nsIFrame* pointers.
160   typedef nsTHashSet<nsIFrame*> VisibleFrames;
161 
162  public:
163   explicit PresShell(Document* aDocument);
164 
165   // nsISupports
166   NS_DECL_ISUPPORTS
167 
168   NS_DECLARE_STATIC_IID_ACCESSOR(NS_PRESSHELL_IID)
169 
170   static bool AccessibleCaretEnabled(nsIDocShell* aDocShell);
171 
172   /**
173    * Return the active content currently capturing the mouse if any.
174    */
GetCapturingContent()175   static nsIContent* GetCapturingContent() {
176     return sCapturingContentInfo.mContent;
177   }
178 
179   /**
180    */
GetCapturingRemoteTarget()181   static dom::BrowserParent* GetCapturingRemoteTarget() {
182     MOZ_ASSERT(XRE_IsParentProcess());
183     return sCapturingContentInfo.mRemoteTarget;
184   }
185 
186   /**
187    * Allow or disallow mouse capturing.
188    */
AllowMouseCapture(bool aAllowed)189   static void AllowMouseCapture(bool aAllowed) {
190     sCapturingContentInfo.mAllowed = aAllowed;
191   }
192 
193   /**
194    * Returns true if there is an active mouse capture that wants to prevent
195    * drags.
196    */
IsMouseCapturePreventingDrag()197   static bool IsMouseCapturePreventingDrag() {
198     return sCapturingContentInfo.mPreventDrag && sCapturingContentInfo.mContent;
199   }
200 
201   static void ClearMouseCaptureOnView(nsView* aView);
202 
203   // If a frame in the subtree rooted at aFrame is capturing the mouse then
204   // clears that capture.
205   static void ClearMouseCapture(nsIFrame* aFrame);
206 
207   // Clear the capture content if it exists in this process.
208   static void ClearMouseCapture();
209 
210 #ifdef ACCESSIBILITY
211   /**
212    * Return the document accessible for this PresShell if there is one.
213    */
GetDocAccessible()214   a11y::DocAccessible* GetDocAccessible() const { return mDocAccessible; }
215 
216   /**
217    * Set the document accessible for this PresShell.
218    */
SetDocAccessible(a11y::DocAccessible * aDocAccessible)219   void SetDocAccessible(a11y::DocAccessible* aDocAccessible) {
220     mDocAccessible = aDocAccessible;
221   }
222 
223   /**
224    * Return true if accessibility is active.
225    */
226   static bool IsAccessibilityActive();
227 
228   /**
229    * Return accessibility service if accessibility is active.
230    */
231   static nsAccessibilityService* GetAccessibilityService();
232 #endif  // #ifdef ACCESSIBILITY
233 
234   void Init(nsPresContext*, nsViewManager*);
235 
236   /**
237    * All callers are responsible for calling |Destroy| after calling
238    * |EndObservingDocument|.  It needs to be separate only because form
239    * controls incorrectly store their data in the frames rather than the
240    * content model and printing calls |EndObservingDocument| multiple
241    * times to make form controls behave nicely when printed.
242    */
243   void Destroy();
244 
IsDestroying()245   bool IsDestroying() { return mIsDestroying; }
246 
247   /**
248    * All frames owned by the shell are allocated from an arena.  They
249    * are also recycled using free lists.  Separate free lists are
250    * maintained for each frame type (aID), which must always correspond
251    * to the same aSize value.  AllocateFrame is infallible and will abort
252    * on out-of-memory.
253    */
AllocateFrame(nsQueryFrame::FrameIID aID,size_t aSize)254   void* AllocateFrame(nsQueryFrame::FrameIID aID, size_t aSize) {
255 #define FRAME_ID(classname, ...)                                  \
256   static_assert(size_t(nsQueryFrame::FrameIID::classname##_id) == \
257                     size_t(eArenaObjectID_##classname),           \
258                 "");
259 #define ABSTRACT_FRAME_ID(classname)                              \
260   static_assert(size_t(nsQueryFrame::FrameIID::classname##_id) == \
261                     size_t(eArenaObjectID_##classname),           \
262                 "");
263 #include "mozilla/FrameIdList.h"
264 #undef FRAME_ID
265 #undef ABSTRACT_FRAME_ID
266     return AllocateByObjectID(ArenaObjectID(size_t(aID)), aSize);
267   }
268 
FreeFrame(nsQueryFrame::FrameIID aID,void * aPtr)269   void FreeFrame(nsQueryFrame::FrameIID aID, void* aPtr) {
270     return FreeByObjectID(ArenaObjectID(size_t(aID)), aPtr);
271   }
272 
AllocateByObjectID(ArenaObjectID aID,size_t aSize)273   void* AllocateByObjectID(ArenaObjectID aID, size_t aSize) {
274     void* result = mFrameArena.Allocate(aID, aSize);
275     RecordAlloc(result);
276     return result;
277   }
278 
FreeByObjectID(ArenaObjectID aID,void * aPtr)279   void FreeByObjectID(ArenaObjectID aID, void* aPtr) {
280     RecordFree(aPtr);
281     if (!mIsDestroying) {
282       mFrameArena.Free(aID, aPtr);
283     }
284   }
285 
GetDocument()286   Document* GetDocument() const { return mDocument; }
287 
GetPresContext()288   nsPresContext* GetPresContext() const { return mPresContext; }
289 
GetViewManager()290   nsViewManager* GetViewManager() const { return mViewManager; }
291 
292   nsRefreshDriver* GetRefreshDriver() const;
293 
FrameConstructor()294   nsCSSFrameConstructor* FrameConstructor() const {
295     return mFrameConstructor.get();
296   }
297 
298   /**
299    * FrameSelection will return the Frame based selection API.
300    * You cannot go back and forth anymore with QI between nsIDOM sel and
301    * nsIFrame sel.
302    */
303   already_AddRefed<nsFrameSelection> FrameSelection();
304 
305   /**
306    * ConstFrameSelection returns an object which methods are safe to use for
307    * example in nsIFrame code.
308    */
ConstFrameSelection()309   const nsFrameSelection* ConstFrameSelection() const { return mSelection; }
310 
311   // Start receiving notifications from our document. If called after Destroy,
312   // this will be ignored.
313   void BeginObservingDocument();
314 
315   // Stop receiving notifications from our document. If called after Destroy,
316   // this will be ignored.
317   void EndObservingDocument();
318 
IsObservingDocument()319   bool IsObservingDocument() const { return mIsObservingDocument; }
320 
321   /**
322    * Return whether Initialize() was previously called.
323    */
DidInitialize()324   bool DidInitialize() const { return mDidInitialize; }
325 
326   /**
327    * Perform initialization. Constructs the frame for the root content
328    * object and then enqueues a reflow of the frame model.
329    *
330    * Callers of this method must hold a reference to this shell that
331    * is guaranteed to survive through arbitrary script execution.
332    * Calling Initialize can execute arbitrary script.
333    */
334   MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult Initialize();
335 
336   /**
337    * Reflow the frame model into a new width and height.  The
338    * coordinates for aWidth and aHeight must be in standard nscoord's.
339    */
340   MOZ_CAN_RUN_SCRIPT nsresult
341   ResizeReflow(nscoord aWidth, nscoord aHeight,
342                ResizeReflowOptions = ResizeReflowOptions::NoOption);
343   MOZ_CAN_RUN_SCRIPT nsresult ResizeReflowIgnoreOverride(nscoord aWidth,
344                                                          nscoord aHeight,
345                                                          ResizeReflowOptions);
346 
347   /**
348    * Add this pres shell to the refresh driver to be observed for resize
349    * event if applicable.
350    */
351   void AddResizeEventFlushObserverIfNeeded();
352 
353   /**
354    * Returns true if the document hosted by this presShell is in a devtools
355    * Responsive Design Mode browsing context.
356    */
357   bool InRDMPane();
358 
359  private:
360   /**
361    * This is what ResizeReflowIgnoreOverride does when not shrink-wrapping (that
362    * is, when ResizeReflowOptions::BSizeLimit is not specified).
363    */
364   void SimpleResizeReflow(nscoord aWidth, nscoord aHeight, ResizeReflowOptions);
365 
366  public:
367   /**
368    * Note that the assumptions that determine whether we need a mobile viewport
369    * manager may have changed.
370    */
371   void MaybeRecreateMobileViewportManager(bool aAfterInitialization);
372 
373   /**
374    * Returns true if this document uses mobile viewport sizing (including
375    * processing of <meta name="viewport"> tags).
376    *
377    * Note that having a MobileViewportManager does not necessarily mean using
378    * mobile viewport sizing, as with desktop zooming we can have a
379    * MobileViewportManager on desktop, but we only want to do mobile viewport
380    * sizing on mobile. (TODO: Rename MobileViewportManager to reflect its more
381    * general role.)
382    */
383   bool UsesMobileViewportSizing() const;
384 
385   /**
386    * Get the MobileViewportManager used to manage the document's mobile
387    * viewport. Will return null in situations where we don't have a mobile
388    * viewport, and for documents that are not the root content document.
389    */
390   RefPtr<MobileViewportManager> GetMobileViewportManager() const;
391 
392   /**
393    * Return true if the presshell expects layout flush.
394    */
395   bool IsLayoutFlushObserver();
396 
397   /**
398    * Called when document load completes.
399    */
400   void LoadComplete();
401   /**
402    * This calls through to the frame manager to get the root frame.
403    */
GetRootFrame()404   nsIFrame* GetRootFrame() const { return mFrameManager->GetRootFrame(); }
405 
406   /*
407    * Get root scroll frame from FrameManager()->GetRootFrame().
408    */
409   nsIFrame* GetRootScrollFrame() const;
410 
411   /*
412    * The same as GetRootScrollFrame, but returns an nsIScrollableFrame
413    */
414   nsIScrollableFrame* GetRootScrollFrameAsScrollable() const;
415 
416   /**
417    * Get the current focused content or DOM selection that should be the
418    * target for scrolling.
419    */
420   already_AddRefed<nsIContent> GetContentForScrolling() const;
421 
422   /**
423    * Get the DOM selection that should be the target for scrolling, if there
424    * is no focused content.
425    */
426   already_AddRefed<nsIContent> GetSelectedContentForScrolling() const;
427 
428   /**
429    * Gets nearest scrollable frame from the specified content node. The frame
430    * is scrollable with overflow:scroll or overflow:auto in some direction when
431    * aDirection is eEither.  Otherwise, this returns a nearest frame that is
432    * scrollable in the specified direction.
433    */
434   nsIScrollableFrame* GetScrollableFrameToScrollForContent(
435       nsIContent* aContent, layers::ScrollDirections aDirections);
436 
437   /**
438    * Gets nearest scrollable frame from current focused content or DOM
439    * selection if there is no focused content. The frame is scrollable with
440    * overflow:scroll or overflow:auto in some direction when aDirection is
441    * eEither.  Otherwise, this returns a nearest frame that is scrollable in
442    * the specified direction.
443    */
444   nsIScrollableFrame* GetScrollableFrameToScroll(
445       layers::ScrollDirections aDirections);
446 
447   /**
448    * Returns the page sequence frame associated with the frame hierarchy.
449    * Returns nullptr if not a paginated view.
450    */
451   nsPageSequenceFrame* GetPageSequenceFrame() const;
452 
453   /**
454    * Returns the canvas frame associated with the frame hierarchy.
455    * Returns nullptr if is XUL document.
456    */
457   nsCanvasFrame* GetCanvasFrame() const;
458 
459   void PostPendingScrollAnchorSelection(
460       layout::ScrollAnchorContainer* aContainer);
461   void FlushPendingScrollAnchorSelections();
462   void PostPendingScrollAnchorAdjustment(
463       layout::ScrollAnchorContainer* aContainer);
464 
465   void CancelAllPendingReflows();
466 
467   MOZ_CAN_RUN_SCRIPT_BOUNDARY void NotifyCounterStylesAreDirty();
468 
469   bool FrameIsAncestorOfDirtyRoot(nsIFrame* aFrame) const;
470 
471   /**
472    * Destroy the frames for aElement, and reconstruct them asynchronously if
473    * needed.
474    *
475    * Note that this may destroy frames for an ancestor instead.
476    */
477   void DestroyFramesForAndRestyle(Element* aElement);
478 
479   /**
480    * Handles all the layout stuff needed when the slot assignment for an element
481    * is about to change.
482    *
483    * Only called when the slot attribute of the element changes, the rest of
484    * the changes should be handled in ShadowRoot.
485    */
486   void SlotAssignmentWillChange(Element& aElement,
487                                 dom::HTMLSlotElement* aOldSlot,
488                                 dom::HTMLSlotElement* aNewSlot);
489 
490   void PostRecreateFramesFor(Element*);
491   void RestyleForAnimation(Element*, RestyleHint);
492 
493   /**
494    * Determine if it is safe to flush all pending notifications.
495    */
496   bool IsSafeToFlush() const;
497 
498   /**
499    * Informs the document's FontFaceSet that the refresh driver ticked,
500    * flushing style and layout.
501    */
502   void NotifyFontFaceSetOnRefresh();
503 
504   // Removes ourself from the list of layout / style / and resize refresh driver
505   // observers.
506   //
507   // Right now this is only used for documents in the BFCache, so if you want to
508   // use this for anything else you need to ensure we don't end up in those
509   // lists after calling this, but before calling StartObservingRefreshDriver
510   // again.
511   //
512   // That is handled by the mDocument->GetBFCacheEntry checks in
513   // DoObserve*Flushes functions, though that could conceivably become a boolean
514   // member in the shell if needed.
515   //
516   // Callers are responsible of manually calling StartObservingRefreshDriver
517   // again.
518   void StopObservingRefreshDriver();
519   void StartObservingRefreshDriver();
520 
ObservingStyleFlushes()521   bool ObservingStyleFlushes() const { return mObservingStyleFlushes; }
ObservingLayoutFlushes()522   bool ObservingLayoutFlushes() const { return mObservingLayoutFlushes; }
523 
ObserveStyleFlushes()524   void ObserveStyleFlushes() {
525     if (!ObservingStyleFlushes()) {
526       DoObserveStyleFlushes();
527     }
528   }
529 
530   /**
531    * Callbacks will be called even if reflow itself fails for
532    * some reason.
533    */
534   nsresult PostReflowCallback(nsIReflowCallback* aCallback);
535   void CancelReflowCallback(nsIReflowCallback* aCallback);
536 
537   void ScheduleBeforeFirstPaint();
538   void UnsuppressAndInvalidate();
539 
540   void ClearFrameRefs(nsIFrame* aFrame);
541 
542   // Clears the selection of the older focused frame selection if any.
543   void FrameSelectionWillTakeFocus(nsFrameSelection&);
544 
545   // Clears and repaint mFocusedFrameSelection if it matches the argument.
546   void FrameSelectionWillLoseFocus(nsFrameSelection&);
547 
548   /**
549    * Get a reference rendering context. This is a context that should not
550    * be rendered to, but is suitable for measuring text and performing
551    * other non-rendering operations. Guaranteed to return non-null.
552    */
553   already_AddRefed<gfxContext> CreateReferenceRenderingContext();
554 
555   /**
556    * Scrolls the view of the document so that the given area of a frame
557    * is visible, if possible. Layout is not flushed before scrolling.
558    *
559    * @param aRect Relative to aFrame. The rect edges will be respected even if
560    * the rect is empty.
561    * @param aVertical see ScrollContentIntoView and ScrollAxis
562    * @param aHorizontal see ScrollContentIntoView and ScrollAxis
563    * @param aScrollFlags if SCROLL_FIRST_ANCESTOR_ONLY is set, only the
564    * nearest scrollable ancestor is scrolled, otherwise all
565    * scrollable ancestors may be scrolled if necessary
566    * if SCROLL_OVERFLOW_HIDDEN is set then we may scroll in a direction
567    * even if overflow:hidden is specified in that direction; otherwise
568    * we will not scroll in that direction when overflow:hidden is
569    * set for that direction
570    * If SCROLL_NO_PARENT_FRAMES is set then we only scroll
571    * nodes in this document, not in any parent documents which
572    * contain this document in a iframe or the like.
573    * If SCROLL_IGNORE_SCROLL_MARGIN_AND_PADDING is set we ignore scroll-margin
574    * value specified for |aFrame| and scroll-padding value for the scroll
575    * container. This option is typically used to locate poped-up frames into
576    * view.
577    * @return true if any scrolling happened, false if no scrolling happened
578    */
579   MOZ_CAN_RUN_SCRIPT
580   bool ScrollFrameRectIntoView(nsIFrame* aFrame, const nsRect& aRect,
581                                const nsMargin& aMargin, ScrollAxis aVertical,
582                                ScrollAxis aHorizontal,
583                                ScrollFlags aScrollFlags);
584 
585   /**
586    * Suppress notification of the frame manager that frames are
587    * being destroyed.
588    */
589   void SetIgnoreFrameDestruction(bool aIgnore);
590 
591   /**
592    * Get the AccessibleCaretEventHub, if it exists. AddRefs it.
593    */
594   already_AddRefed<AccessibleCaretEventHub> GetAccessibleCaretEventHub() const;
595 
596   /**
597    * Get the caret, if it exists. AddRefs it.
598    */
599   already_AddRefed<nsCaret> GetCaret() const;
600 
601   /**
602    * Set the current caret to a new caret. To undo this, call RestoreCaret.
603    */
604   void SetCaret(nsCaret* aNewCaret);
605 
606   /**
607    * Restore the caret to the original caret that this pres shell was created
608    * with.
609    */
610   void RestoreCaret();
611 
612   dom::Selection* GetCurrentSelection(SelectionType aSelectionType);
613 
614   /**
615    * Gets the last selection that took focus in this document. This is basically
616    * the frame selection that's visible to the user.
617    */
618   nsFrameSelection* GetLastFocusedFrameSelection();
619 
620   /**
621    * Interface to dispatch events via the presshell
622    * @note The caller must have a strong reference to the PresShell.
623    */
624   MOZ_CAN_RUN_SCRIPT
625   nsresult HandleEventWithTarget(WidgetEvent* aEvent, nsIFrame* aFrame,
626                                  nsIContent* aContent,
627                                  nsEventStatus* aEventStatus,
628                                  bool aIsHandlingNativeEvent = false,
629                                  nsIContent** aTargetContent = nullptr,
630                                  nsIContent* aOverrideClickTarget = nullptr) {
631     MOZ_ASSERT(aEvent);
632     EventHandler eventHandler(*this);
633     return eventHandler.HandleEventWithTarget(
634         aEvent, aFrame, aContent, aEventStatus, aIsHandlingNativeEvent,
635         aTargetContent, aOverrideClickTarget);
636   }
637 
638   /**
639    * Dispatch event to content only (NOT full processing)
640    */
641   MOZ_CAN_RUN_SCRIPT
642   nsresult HandleDOMEventWithTarget(nsIContent* aTargetContent,
643                                     WidgetEvent* aEvent,
644                                     nsEventStatus* aStatus);
645 
646   /**
647    * Dispatch event to content only (NOT full processing)
648    */
649   MOZ_CAN_RUN_SCRIPT
650   nsresult HandleDOMEventWithTarget(nsIContent* aTargetContent,
651                                     dom::Event* aEvent, nsEventStatus* aStatus);
652 
653   /**
654    * Return whether or not the event is valid to be dispatched
655    */
656   bool CanDispatchEvent(const WidgetGUIEvent* aEvent = nullptr) const;
657 
658   /**
659    * Gets the current target event frame from the PresShell
660    */
661   nsIFrame* GetCurrentEventFrame();
662 
663   /**
664    * Gets the current target event frame from the PresShell
665    */
666   already_AddRefed<nsIContent> GetEventTargetContent(WidgetEvent* aEvent);
667 
668   /**
669    * Get and set the history state for the current document
670    */
671   nsresult CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState);
672 
673   /**
674    * Determine if reflow is currently locked
675    * returns true if reflow is locked, false otherwise
676    */
IsReflowLocked()677   bool IsReflowLocked() const { return mIsReflowing; }
678 
679   /**
680    * Called to find out if painting is suppressed for this presshell.  If it is
681    * suppressd, we don't allow the painting of any layer but the background, and
682    * we don't recur into our children.
683    */
IsPaintingSuppressed()684   bool IsPaintingSuppressed() const { return mPaintingSuppressed; }
685 
686   void UnsuppressPainting();
687   void InitPaintSuppressionTimer();
688   void CancelPaintSuppressionTimer();
689 
690   /**
691    * Reconstruct frames for all elements in the document
692    */
693   MOZ_CAN_RUN_SCRIPT void ReconstructFrames();
694 
695   /**
696    * See if reflow verification is enabled. To enable reflow verification add
697    * "verifyreflow:1" to your MOZ_LOG environment variable (any non-zero
698    * debug level will work). Or, call SetVerifyReflowEnable with true.
699    */
700   static bool GetVerifyReflowEnable();
701 
702   /**
703    * Set the verify-reflow enable flag.
704    */
705   static void SetVerifyReflowEnable(bool aEnabled);
706 
707   nsIFrame* GetAbsoluteContainingBlock(nsIFrame* aFrame);
708 
709 #ifdef MOZ_REFLOW_PERF
710   void DumpReflows();
711   void CountReflows(const char* aName, nsIFrame* aFrame);
712   void PaintCount(const char* aName, gfxContext* aRenderingContext,
713                   nsPresContext* aPresContext, nsIFrame* aFrame,
714                   const nsPoint& aOffset, uint32_t aColor);
715   void SetPaintFrameCount(bool aOn);
716   bool IsPaintingFrameCounts();
717 #endif  // #ifdef MOZ_REFLOW_PERF
718 
719   // Debugging hooks
720 #ifdef DEBUG
721   void ListComputedStyles(FILE* out, int32_t aIndent = 0);
722 #endif
723 #if defined(DEBUG) || defined(MOZ_LAYOUT_DEBUGGER)
724   void ListStyleSheets(FILE* out, int32_t aIndent = 0);
725 #endif
726 
727   /**
728    * Stop all refresh drivers and carets in this presentation and
729    * in the presentations of subdocuments.  Resets painting to a suppressed
730    * state.
731    * XXX this should include image animations
732    */
733   void Freeze(bool aIncludeSubDocuments = true);
IsFrozen()734   bool IsFrozen() { return mFrozen; }
735 
736   /**
737    * Restarts refresh drivers in this presentation and in the
738    * presentations of subdocuments, then do a full invalidate of the content
739    * area.
740    */
741   void Thaw(bool aIncludeSubDocuments = true);
742 
743   void FireOrClearDelayedEvents(bool aFireEvents);
744 
745   /**
746    * When this shell is disconnected from its containing docshell, we
747    * lose our container pointer.  However, we'd still like to be able to target
748    * user events at the docshell's parent.  This pointer allows us to do that.
749    * It should not be used for any other purpose.
750    */
751   void SetForwardingContainer(const WeakPtr<nsDocShell>& aContainer);
752 
753   /**
754    * Render the document into an arbitrary gfxContext
755    * Designed for getting a picture of a document or a piece of a document
756    * Note that callers will generally want to call FlushPendingNotifications
757    * to get an up-to-date view of the document
758    * @param aRect is the region to capture into the offscreen buffer, in the
759    * root frame's coordinate system (if aIgnoreViewportScrolling is false)
760    * or in the root scrolled frame's coordinate system
761    * (if aIgnoreViewportScrolling is true). The coordinates are in appunits.
762    * @param aFlags see below;
763    *   set RenderDocumentFlags::IsUntrusted if the contents may be passed to
764    * malicious agents. E.g. we might choose not to paint the contents of
765    * sensitive widgets such as the file name in a file upload widget, and we
766    * might choose not to paint themes.
767    *   set RenderDocumentFlags::IgnoreViewportScrolling to ignore clipping and
768    *  scrollbar painting due to scrolling in the viewport
769    *   set RenderDocumentFlags::ResetViewportScrolling to temporarily set the
770    * viewport scroll position to 0 so that position:fixed elements are drawn
771    * at their initial position.
772    *   set RenderDocumentFlags::DrawCaret to draw the caret if one would be
773    *  visible (by default the caret is never drawn)
774    *   set RenderDocumentFlags::UseWidgetLayers to force rendering to go
775    *  through the layer manager for the window. This may be unexpectedly slow
776    * (if the layer manager must read back data from the GPU) or low-quality
777    * (if the layer manager reads back pixel data and scales it
778    * instead of rendering using the appropriate scaling). It may also
779    * slow everything down if the area rendered does not correspond to the
780    * normal visible area of the window.
781    *   set RenderDocumentFlags::AsyncDecodeImages to avoid having images
782    * synchronously decoded during rendering.
783    * (by default images decode synchronously with RenderDocument)
784    *   set RenderDocumentFlags::DocumentRelative to render the document as if
785    * there has been no scrolling and interpret |aRect| relative to the document
786    * instead of the CSS viewport. Only considered if
787    * RenderDocumentFlags::IgnoreViewportScrolling is set or the document is in
788    * ignore viewport scrolling mode
789    * (PresShell::SetIgnoreViewportScrolling/IgnoringViewportScrolling).
790    *   set RenderDocumentFlags::UseHighQualityScaling to enable downscale on
791    *   decode for images.
792    * @param aBackgroundColor a background color to render onto
793    * @param aRenderedContext the gfxContext to render to. We render so that
794    * one CSS pixel in the source document is rendered to one unit in the current
795    * transform.
796    */
797   nsresult RenderDocument(const nsRect& aRect, RenderDocumentFlags aFlags,
798                           nscolor aBackgroundColor,
799                           gfxContext* aRenderedContext);
800 
801   /**
802    * Renders a node aNode to a surface and returns it. The aRegion may be used
803    * to clip the rendering. This region is measured in CSS pixels from the
804    * edge of the presshell area. The aPoint, aScreenRect and aFlags arguments
805    * function in a similar manner as RenderSelection.
806    */
807   already_AddRefed<SourceSurface> RenderNode(nsINode* aNode,
808                                              const Maybe<CSSIntRegion>& aRegion,
809                                              const LayoutDeviceIntPoint aPoint,
810                                              LayoutDeviceIntRect* aScreenRect,
811                                              RenderImageFlags aFlags);
812 
813   /**
814    * Renders a selection to a surface and returns it. This method is primarily
815    * intended to create the drag feedback when dragging a selection.
816    *
817    * aScreenRect will be filled in with the bounding rectangle of the
818    * selection area on screen.
819    *
820    * If the area of the selection is large and the RenderImageFlags::AutoScale
821    * is set, the image will be scaled down. The argument aPoint is used in this
822    * case as a reference point when determining the new screen rectangle after
823    * scaling. Typically, this will be the mouse position, so that the screen
824    * rectangle is positioned such that the mouse is over the same point in the
825    * scaled image as in the original. When scaling does not occur, the mouse
826    * point isn't used because the position can be determined from the displayed
827    * frames.
828    */
829   already_AddRefed<SourceSurface> RenderSelection(
830       dom::Selection* aSelection, const LayoutDeviceIntPoint aPoint,
831       LayoutDeviceIntRect* aScreenRect, RenderImageFlags aFlags);
832 
833   void AddAutoWeakFrame(AutoWeakFrame* aWeakFrame);
834   void AddWeakFrame(WeakFrame* aWeakFrame);
835 
836   void RemoveAutoWeakFrame(AutoWeakFrame* aWeakFrame);
837   void RemoveWeakFrame(WeakFrame* aWeakFrame);
838 
839   /**
840    * Stop or restart non synthetic test mouse event handling on *all*
841    * presShells.
842    *
843    * @param aDisable If true, disable all non synthetic test mouse
844    * events on all presShells.  Otherwise, enable them.
845    */
846   void DisableNonTestMouseEvents(bool aDisable);
847 
848   /**
849    * Record the background color of the most recently drawn canvas. This color
850    * is composited on top of the user's default background color and then used
851    * to draw the background color of the canvas. See PresShell::Paint,
852    * PresShell::PaintDefaultBackground, and nsDocShell::SetupNewViewer;
853    * bug 488242, bug 476557 and other bugs mentioned there.
854    */
SetCanvasBackground(nscolor aColor)855   void SetCanvasBackground(nscolor aColor) { mCanvasBackgroundColor = aColor; }
GetCanvasBackground()856   nscolor GetCanvasBackground() { return mCanvasBackgroundColor; }
857 
858   /**
859    * Use the current frame tree (if it exists) to update the background
860    * color of the most recently drawn canvas.
861    */
862   void UpdateCanvasBackground();
863 
864   /**
865    * Add a solid color item to the bottom of aList with frame aFrame and
866    * bounds aBounds representing the dark grey background behind the page of a
867    * print preview presentation.
868    */
869   void AddPrintPreviewBackgroundItem(nsDisplayListBuilder* aBuilder,
870                                      nsDisplayList* aList, nsIFrame* aFrame,
871                                      const nsRect& aBounds);
872 
873   /**
874    * Computes the backstop color for the view: transparent if in a transparent
875    * widget, otherwise the PresContext default background color. This color is
876    * only visible if the contents of the view as a whole are translucent.
877    */
878   nscolor ComputeBackstopColor(nsView* aDisplayRoot);
879 
ObserveNativeAnonMutationsForPrint(bool aObserve)880   void ObserveNativeAnonMutationsForPrint(bool aObserve) {
881     mObservesMutationsForPrint = aObserve;
882   }
ObservesNativeAnonMutationsForPrint()883   bool ObservesNativeAnonMutationsForPrint() {
884     return mObservesMutationsForPrint;
885   }
886 
887   void ActivenessMaybeChanged();
IsActive()888   bool IsActive() const { return mIsActive; }
889 
890   /**
891    * Keep track of how many times this presshell has been rendered to
892    * a window.
893    */
GetPaintCount()894   uint64_t GetPaintCount() { return mPaintCount; }
IncrementPaintCount()895   void IncrementPaintCount() { ++mPaintCount; }
896 
897   /**
898    * Get the root DOM window of this presShell.
899    */
900   already_AddRefed<nsPIDOMWindowOuter> GetRootWindow();
901 
902   /**
903    * This returns the focused DOM window under our top level window.
904    * I.e., when we are deactive, this returns the *last* focused DOM window.
905    */
906   already_AddRefed<nsPIDOMWindowOuter> GetFocusedDOMWindowInOurWindow();
907 
908   /**
909    * Get the focused content under this window.
910    */
911   already_AddRefed<nsIContent> GetFocusedContentInOurWindow() const;
912 
913   /**
914    * Get the layer manager for the widget of the root view, if it has
915    * one.
916    */
917   LayerManager* GetLayerManager();
918 
919   /**
920    * Return true iff there is a widget rendering this presShell and that
921    * widget is APZ-enabled.
922    */
923   bool AsyncPanZoomEnabled();
924 
925   /**
926    * Track whether we're ignoring viewport scrolling for the purposes
927    * of painting.  If we are ignoring, then layers aren't clipped to
928    * the CSS viewport and scrollbars aren't drawn.
929    */
IgnoringViewportScrolling()930   bool IgnoringViewportScrolling() const {
931     return !!(mRenderingStateFlags &
932               RenderingStateFlags::IgnoringViewportScrolling);
933   }
934 
GetResolution()935   float GetResolution() const { return mResolution.valueOr(1.0); }
936   float GetCumulativeResolution() const;
937 
938   /**
939    * Accessors for a flag that tracks whether the most recent change to
940    * the pres shell's resolution was originated by the main thread.
941    */
IsResolutionUpdated()942   bool IsResolutionUpdated() const { return mResolutionUpdated; }
SetResolutionUpdated(bool aUpdated)943   void SetResolutionUpdated(bool aUpdated) { mResolutionUpdated = aUpdated; }
944 
945   /**
946    * Returns true if the resolution has ever been changed by APZ.
947    */
IsResolutionUpdatedByApz()948   bool IsResolutionUpdatedByApz() const { return mResolutionUpdatedByApz; }
949 
950   /**
951    * Used by session restore code to restore a resolution before the first
952    * paint.
953    */
954   void SetRestoreResolution(float aResolution,
955                             LayoutDeviceIntSize aDisplaySize);
956 
957   /**
958    * Returns whether we are in a DrawWindow() call that used the
959    * DRAWWINDOW_DO_NOT_FLUSH flag.
960    */
InDrawWindowNotFlushing()961   bool InDrawWindowNotFlushing() const {
962     return !!(mRenderingStateFlags &
963               RenderingStateFlags::DrawWindowNotFlushing);
964   }
965 
966   /**
967    * Set the isFirstPaint flag.
968    */
SetIsFirstPaint(bool aIsFirstPaint)969   void SetIsFirstPaint(bool aIsFirstPaint) { mIsFirstPaint = aIsFirstPaint; }
970 
971   /**
972    * Get the isFirstPaint flag.
973    */
GetIsFirstPaint()974   bool GetIsFirstPaint() const { return mIsFirstPaint; }
975 
GetPresShellId()976   uint32_t GetPresShellId() { return mPresShellId; }
977 
978   /**
979    * Dispatch a mouse move event based on the most recent mouse position if
980    * this PresShell is visible. This is used when the contents of the page
981    * moved (aFromScroll is false) or scrolled (aFromScroll is true).
982    */
983   void SynthesizeMouseMove(bool aFromScroll);
984 
985   MOZ_CAN_RUN_SCRIPT
986   nsresult HandleEvent(nsIFrame* aFrame, WidgetGUIEvent* aEvent,
987                        bool aDontRetargetEvents, nsEventStatus* aEventStatus);
988   bool ShouldIgnoreInvalidation();
989   /**
990    * Notify that we called Paint with PaintFlags::PaintComposite.
991    * Fires on the presshell for the painted widget.
992    * This is issued at a time when it's safe to modify widget geometry.
993    */
994   MOZ_CAN_RUN_SCRIPT void DidPaintWindow();
995 
996   bool IsVisible() const;
IsUnderHiddenEmbedderElement()997   bool IsUnderHiddenEmbedderElement() const {
998     return mUnderHiddenEmbedderElement;
999   }
1000   void SetIsUnderHiddenEmbedderElement(bool aUnderHiddenEmbedderElement);
1001   MOZ_CAN_RUN_SCRIPT
1002   void DispatchSynthMouseMove(WidgetGUIEvent* aEvent);
1003 
1004   /* Temporarily ignore the Displayport for better paint performance. We
1005    * trigger a repaint once suppression is disabled. Without that
1006    * the displayport may get left at the suppressed size for an extended
1007    * period of time and result in unnecessary checkerboarding (see bug
1008    * 1255054). */
1009   void SuppressDisplayport(bool aEnabled);
1010 
1011   /* Whether or not displayport suppression should be turned on. Note that
1012    * this only affects the return value of |IsDisplayportSuppressed()|, and
1013    * doesn't change the value of the internal counter.
1014    */
1015   void RespectDisplayportSuppression(bool aEnabled);
1016 
1017   /* Whether or not the displayport is currently suppressed. */
1018   bool IsDisplayportSuppressed();
1019 
1020   void AddSizeOfIncludingThis(nsWindowSizes& aWindowSizes) const;
1021 
1022   /**
1023    * Methods that retrieve the cached font inflation preferences.
1024    */
FontSizeInflationEmPerLine()1025   uint32_t FontSizeInflationEmPerLine() const {
1026     return mFontSizeInflationEmPerLine;
1027   }
1028 
FontSizeInflationMinTwips()1029   uint32_t FontSizeInflationMinTwips() const {
1030     return mFontSizeInflationMinTwips;
1031   }
1032 
FontSizeInflationLineThreshold()1033   uint32_t FontSizeInflationLineThreshold() const {
1034     return mFontSizeInflationLineThreshold;
1035   }
1036 
FontSizeInflationForceEnabled()1037   bool FontSizeInflationForceEnabled() const {
1038     return mFontSizeInflationForceEnabled;
1039   }
1040 
FontSizeInflationDisabledInMasterProcess()1041   bool FontSizeInflationDisabledInMasterProcess() const {
1042     return mFontSizeInflationDisabledInMasterProcess;
1043   }
1044 
FontSizeInflationEnabled()1045   bool FontSizeInflationEnabled() const { return mFontSizeInflationEnabled; }
1046 
1047   /**
1048    * Recomputes whether font-size inflation is enabled.
1049    */
1050   void RecomputeFontSizeInflationEnabled();
1051 
1052   /**
1053    * Return true if the most recent interruptible reflow was interrupted.
1054    */
IsReflowInterrupted()1055   bool IsReflowInterrupted() const { return mWasLastReflowInterrupted; }
1056 
1057   /**
1058    * Return true if the the interruptible reflows have to be suppressed.
1059    * This may happen only if if the most recent reflow was interrupted.
1060    */
SuppressInterruptibleReflows()1061   bool SuppressInterruptibleReflows() const {
1062     return mWasLastReflowInterrupted;
1063   }
1064 
1065   //////////////////////////////////////////////////////////////////////////////
1066   // Approximate frame visibility tracking public API.
1067   //////////////////////////////////////////////////////////////////////////////
1068 
1069   /**
1070    * Schedule an update of the list of approximately visible frames "soon".
1071    * This lets the refresh driver know that we want a visibility update in the
1072    * near future. The refresh driver applies its own heuristics and throttling
1073    * to decide when to actually perform the visibility update.
1074    */
1075   void ScheduleApproximateFrameVisibilityUpdateSoon();
1076 
1077   /**
1078    * Schedule an update of the list of approximately visible frames "now". The
1079    * update runs asynchronously, but it will be posted to the event loop
1080    * immediately. Prefer the "soon" variation of this method when possible, as
1081    * this variation ignores the refresh driver's heuristics.
1082    */
1083   void ScheduleApproximateFrameVisibilityUpdateNow();
1084 
1085   /**
1086    * Clears the current list of approximately visible frames on this pres shell
1087    * and replaces it with frames that are in the display list @aList.
1088    */
1089   void RebuildApproximateFrameVisibilityDisplayList(const nsDisplayList& aList);
1090   void RebuildApproximateFrameVisibility(nsRect* aRect = nullptr,
1091                                          bool aRemoveOnly = false);
1092 
1093   /**
1094    * Ensures @aFrame is in the list of approximately visible frames.
1095    */
1096   void EnsureFrameInApproximatelyVisibleList(nsIFrame* aFrame);
1097 
1098   /// Removes @aFrame from the list of approximately visible frames if present.
1099   void RemoveFrameFromApproximatelyVisibleList(nsIFrame* aFrame);
1100 
1101   /// Whether we should assume all frames are visible.
1102   bool AssumeAllFramesVisible();
1103 
1104   /**
1105    * Returns whether the document's style set's rule processor for the
1106    * specified level of the cascade is shared by multiple style sets.
1107    *
1108    * @param aSheetType One of the nsIStyleSheetService.*_SHEET constants.
1109    */
1110   nsresult HasRuleProcessorUsedByMultipleStyleSets(uint32_t aSheetType,
1111                                                    bool* aRetVal);
1112 
1113   /**
1114    * Returns whether or not the document has ever handled user input
1115    */
HasHandledUserInput()1116   bool HasHandledUserInput() const { return mHasHandledUserInput; }
1117 
1118   MOZ_CAN_RUN_SCRIPT void FireResizeEvent();
1119 
1120   void NativeAnonymousContentRemoved(nsIContent* aAnonContent);
1121 
1122   /**
1123    * See HTMLDocument.setKeyPressEventModel() in HTMLDocument.webidl for the
1124    * detail.
1125    */
SetKeyPressEventModel(uint16_t aKeyPressEventModel)1126   void SetKeyPressEventModel(uint16_t aKeyPressEventModel) {
1127     mForceUseLegacyKeyCodeAndCharCodeValues |=
1128         aKeyPressEventModel ==
1129         dom::Document_Binding::KEYPRESS_EVENT_MODEL_SPLIT;
1130   }
1131 
1132   bool AddRefreshObserver(nsARefreshObserver* aObserver, FlushType aFlushType,
1133                           const char* aObserverDescription);
1134   bool RemoveRefreshObserver(nsARefreshObserver* aObserver,
1135                              FlushType aFlushType);
1136 
1137   bool AddPostRefreshObserver(nsAPostRefreshObserver*);
1138   bool AddPostRefreshObserver(mozilla::ManagedPostRefreshObserver*) = delete;
1139   bool RemovePostRefreshObserver(nsAPostRefreshObserver*);
1140   bool RemovePostRefreshObserver(mozilla::ManagedPostRefreshObserver*) = delete;
1141 
1142   // Represents an update to the visual scroll offset that will be sent to APZ.
1143   // The update type is used to determine priority compared to other scroll
1144   // updates.
1145   struct VisualScrollUpdate {
1146     nsPoint mVisualScrollOffset;
1147     FrameMetrics::ScrollOffsetUpdateType mUpdateType;
1148     bool mAcknowledged = false;
1149   };
1150 
1151   // Ask APZ in the next transaction to scroll to the given visual viewport
1152   // offset (relative to the document).
1153   // This is intended to be used when desired in cases where the browser
1154   // internally triggers scrolling; scrolling triggered explicitly by web
1155   // content (such as via window.scrollTo() should scroll the layout viewport
1156   // only).
1157   // If scrolling "far away", i.e. not just within the existing layout
1158   // viewport, it's recommended to use both nsIScrollableFrame.ScrollTo*()
1159   // (via window.scrollTo if calling from JS) *and* this function; otherwise,
1160   // temporary checkerboarding may result. If doing this:
1161   //   * Be sure to call ScrollTo*() first, as a subsequent layout scroll
1162   //     in the same transaction will cancel the pending visual scroll.
1163   //   * Keep in mind that ScrollTo*() can tear down the pres shell and
1164   //     frame tree. Depending on how the pres shell is obtained for the
1165   //     subsequent ScrollToVisual() call, AutoWeakFrame or similar may
1166   //     need to be used.
1167   // Please request APZ review if adding a new call site.
1168   void ScrollToVisual(const nsPoint& aVisualViewportOffset,
1169                       FrameMetrics::ScrollOffsetUpdateType aUpdateType,
1170                       ScrollMode aMode);
1171   void AcknowledgePendingVisualScrollUpdate();
1172   void ClearPendingVisualScrollUpdate();
GetPendingVisualScrollUpdate()1173   const Maybe<VisualScrollUpdate>& GetPendingVisualScrollUpdate() const {
1174     return mPendingVisualScrollUpdate;
1175   }
1176 
1177   nsPoint GetLayoutViewportOffset() const;
1178   nsSize GetLayoutViewportSize() const;
1179 
1180   /**
1181    * Documents belonging to an invisible DocShell must not be painted ever.
1182    */
IsNeverPainting()1183   bool IsNeverPainting() { return mIsNeverPainting; }
1184 
SetNeverPainting(bool aNeverPainting)1185   void SetNeverPainting(bool aNeverPainting) {
1186     mIsNeverPainting = aNeverPainting;
1187   }
1188 
1189   /**
1190    * True if a reflow event has been scheduled, or is going to be scheduled
1191    * to run in the future.
1192    */
HasPendingReflow()1193   bool HasPendingReflow() const {
1194     return mObservingLayoutFlushes || mReflowContinueTimer;
1195   }
1196 
1197   void SyncWindowProperties(nsView* aView);
1198 
1199   Document* GetPrimaryContentDocument();
1200 
1201   struct MOZ_RAII AutoAssertNoFlush {
AutoAssertNoFlushAutoAssertNoFlush1202     explicit AutoAssertNoFlush(PresShell& aPresShell)
1203         : mPresShell(aPresShell), mOldForbidden(mPresShell.mForbiddenToFlush) {
1204       mPresShell.mForbiddenToFlush = true;
1205     }
1206 
~AutoAssertNoFlushAutoAssertNoFlush1207     ~AutoAssertNoFlush() { mPresShell.mForbiddenToFlush = mOldForbidden; }
1208 
1209     PresShell& mPresShell;
1210     const bool mOldForbidden;
1211   };
1212 
1213   NS_IMETHOD GetSelectionFromScript(RawSelectionType aRawSelectionType,
1214                                     dom::Selection** aSelection) override;
1215   dom::Selection* GetSelection(RawSelectionType aRawSelectionType) override;
1216 
1217   NS_IMETHOD SetDisplaySelection(int16_t aToggle) override;
1218   NS_IMETHOD GetDisplaySelection(int16_t* aToggle) override;
1219   NS_IMETHOD ScrollSelectionIntoView(RawSelectionType aRawSelectionType,
1220                                      SelectionRegion aRegion,
1221                                      int16_t aFlags) override;
1222   NS_IMETHOD RepaintSelection(RawSelectionType aRawSelectionType) override;
1223   void SelectionWillTakeFocus() override;
1224   void SelectionWillLoseFocus() override;
1225 
1226   /**
1227    * Set a "resolution" for the document, which if not 1.0 will
1228    * allocate more or fewer pixels for rescalable content by a factor
1229    * of |resolution| in both dimensions.  Return NS_OK iff the
1230    * resolution bounds are sane, and the resolution of this was
1231    * actually updated.
1232    *
1233    * Also increase the scale of the content by the same amount
1234    * (that's the "AndScaleTo" part).
1235    *
1236    * The resolution defaults to 1.0.
1237    *
1238    * |aOrigin| specifies who originated the resolution change. For changes
1239    * sent by APZ, pass ResolutionChangeOrigin::Apz. For changes sent by
1240    * the main thread, pass ResolutionChangeOrigin::MainThreadAdjustment (similar
1241    * to the |aOrigin| parameter of nsIScrollableFrame::ScrollToCSSPixels()).
1242    */
1243   nsresult SetResolutionAndScaleTo(float aResolution,
1244                                    ResolutionChangeOrigin aOrigin);
1245 
GetLastResolutionChangeOrigin()1246   ResolutionChangeOrigin GetLastResolutionChangeOrigin() {
1247     return mLastResolutionChangeOrigin;
1248   }
1249 
1250   // Widget notificiations
1251   void WindowSizeMoveDone();
1252 
ThemeChanged(widget::ThemeChangeKind aChangeKind)1253   void ThemeChanged(widget::ThemeChangeKind aChangeKind) {
1254     mPresContext->ThemeChanged(aChangeKind);
1255   }
1256 
BackingScaleFactorChanged()1257   void BackingScaleFactorChanged() { mPresContext->UIResolutionChangedSync(); }
1258 
1259   MOZ_CAN_RUN_SCRIPT
1260   void Paint(nsView* aViewToPaint, const nsRegion& aDirtyRegion,
1261              PaintFlags aFlags);
1262 
1263   /**
1264    * Notify that we're going to call Paint with PaintFlags::PaintLayers
1265    * on the pres shell for a widget (which might not be this one, since
1266    * WillPaint is called on all presshells in the same toplevel window as the
1267    * painted widget). This is issued at a time when it's safe to modify
1268    * widget geometry.
1269    */
1270   MOZ_CAN_RUN_SCRIPT void WillPaint();
1271 
1272   /**
1273    * Ensures that the refresh driver is running, and schedules a view
1274    * manager flush on the next tick.
1275    *
1276    * @param aType PaintType::DelayedCompress : Schedule a paint to be executed
1277    * after a delay, and put FrameLayerBuilder in 'compressed' mode that avoids
1278    * short cut optimizations.
1279    */
1280   void ScheduleViewManagerFlush(PaintType aType = PaintType::Default);
1281 
1282   // caret handling
1283   NS_IMETHOD SetCaretEnabled(bool aInEnable) override;
1284   NS_IMETHOD SetCaretReadOnly(bool aReadOnly) override;
1285   NS_IMETHOD GetCaretEnabled(bool* aOutEnabled) override;
1286   NS_IMETHOD SetCaretVisibilityDuringSelection(bool aVisibility) override;
1287   NS_IMETHOD GetCaretVisible(bool* _retval) override;
1288 
1289   /**
1290    * Should the images have borders etc.  Actual visual effects are determined
1291    * by the frames.  Visual effects may not effect layout, only display.
1292    * Takes effect on next repaint, does not force a repaint itself.
1293    *
1294    * @param aFlags may be multiple of nsISelectionDisplay::DISPLAY_*.
1295    */
1296   NS_IMETHOD SetSelectionFlags(int16_t aFlags) override;
1297   NS_IMETHOD GetSelectionFlags(int16_t* aFlags) override;
1298 
1299   /**
1300    * Gets the current state of non text selection effects
1301    * @return   current state of non text selection,
1302    *           as set by SetDisplayNonTextSelection
1303    */
GetSelectionFlags()1304   int16_t GetSelectionFlags() const { return mSelectionFlags; }
1305 
1306   // nsISelectionController
1307 
1308   NS_IMETHOD PhysicalMove(int16_t aDirection, int16_t aAmount,
1309                           bool aExtend) override;
1310   NS_IMETHOD CharacterMove(bool aForward, bool aExtend) override;
1311   MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD WordMove(bool aForward,
1312                                                   bool aExtend) override;
1313   MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD LineMove(bool aForward,
1314                                                   bool aExtend) override;
1315   NS_IMETHOD IntraLineMove(bool aForward, bool aExtend) override;
1316   MOZ_CAN_RUN_SCRIPT
1317   NS_IMETHOD PageMove(bool aForward, bool aExtend) override;
1318   NS_IMETHOD ScrollPage(bool aForward) override;
1319   NS_IMETHOD ScrollLine(bool aForward) override;
1320   NS_IMETHOD ScrollCharacter(bool aRight) override;
1321   NS_IMETHOD CompleteScroll(bool aForward) override;
1322   MOZ_CAN_RUN_SCRIPT NS_IMETHOD CompleteMove(bool aForward,
1323                                              bool aExtend) override;
1324   NS_IMETHOD CheckVisibility(nsINode* node, int16_t startOffset,
1325                              int16_t EndOffset, bool* _retval) override;
1326   nsresult CheckVisibilityContent(nsIContent* aNode, int16_t aStartOffset,
1327                                   int16_t aEndOffset, bool* aRetval) override;
1328 
1329   // Notifies that the state of the document has changed.
1330   void DocumentStatesChanged(EventStates);
1331 
1332   // nsIDocumentObserver
1333   NS_DECL_NSIDOCUMENTOBSERVER_BEGINLOAD
1334   NS_DECL_NSIDOCUMENTOBSERVER_ENDLOAD
1335   NS_DECL_NSIDOCUMENTOBSERVER_CONTENTSTATECHANGED
1336 
1337   // nsIMutationObserver
1338   NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
1339   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE
1340   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
1341   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
1342   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
1343   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
1344 
1345   NS_DECL_NSIOBSERVER
1346 
1347   // Inline methods defined in PresShellInlines.h
1348   inline void EnsureStyleFlush();
1349   inline void SetNeedStyleFlush();
1350   inline void SetNeedLayoutFlush();
1351   inline void SetNeedThrottledAnimationFlush();
1352   inline ServoStyleSet* StyleSet() const;
1353 
1354   /**
1355    * Whether we might need a flush for the given flush type.  If this
1356    * function returns false, we definitely don't need to flush.
1357    *
1358    * @param aFlushType The flush type to check.  This must be
1359    *   >= FlushType::Style.  This also returns true if a throttled
1360    *   animation flush is required.
1361    */
NeedFlush(FlushType aType)1362   bool NeedFlush(FlushType aType) const {
1363     // We check mInFlush to handle re-entrant calls to FlushPendingNotifications
1364     // by reporting that we always need a flush in that case.  Otherwise,
1365     // we could end up missing needed flushes, since we clear the mNeedXXXFlush
1366     // flags at the top of FlushPendingNotifications.
1367     MOZ_ASSERT(aType >= FlushType::Style);
1368     return mNeedStyleFlush ||
1369            (mNeedLayoutFlush && aType >= FlushType::InterruptibleLayout) ||
1370            aType >= FlushType::Display || mNeedThrottledAnimationFlush ||
1371            mInFlush;
1372   }
1373 
1374   /**
1375    * Returns true if we might need to flush layout, even if we haven't scheduled
1376    * one yet (as opposed to HasPendingReflow, which returns true if a flush is
1377    * scheduled or will soon be scheduled).
1378    */
NeedLayoutFlush()1379   bool NeedLayoutFlush() const { return mNeedLayoutFlush; }
1380 
NeedStyleFlush()1381   bool NeedStyleFlush() const { return mNeedStyleFlush; }
1382 
1383   /**
1384    * Flush pending notifications of the type specified.  This method
1385    * will not affect the content model; it'll just affect style and
1386    * frames. Callers that actually want up-to-date presentation (other
1387    * than the document itself) should probably be calling
1388    * Document::FlushPendingNotifications.
1389    *
1390    * This method can execute script, which can destroy this presshell object
1391    * unless someone is holding a reference to it on the stack.  The presshell
1392    * itself will ensure it lives up until the method returns, but callers who
1393    * plan to use the presshell after this call should hold a strong ref
1394    * themselves!
1395    *
1396    * @param aType the type of notifications to flush
1397    */
1398   MOZ_CAN_RUN_SCRIPT
FlushPendingNotifications(FlushType aType)1399   void FlushPendingNotifications(FlushType aType) {
1400     if (!NeedFlush(aType)) {
1401       return;
1402     }
1403 
1404     DoFlushPendingNotifications(aType);
1405   }
1406 
1407   MOZ_CAN_RUN_SCRIPT
FlushPendingNotifications(ChangesToFlush aType)1408   void FlushPendingNotifications(ChangesToFlush aType) {
1409     if (!NeedFlush(aType.mFlushType)) {
1410       return;
1411     }
1412 
1413     DoFlushPendingNotifications(aType);
1414   }
1415 
1416   /**
1417    * Tell the pres shell that a frame needs to be marked dirty and needs
1418    * Reflow.  It's OK if this is an ancestor of the frame needing reflow as
1419    * long as the ancestor chain between them doesn't cross a reflow root.
1420    *
1421    * The bit to add should be NS_FRAME_IS_DIRTY, NS_FRAME_HAS_DIRTY_CHILDREN
1422    * or nsFrameState(0); passing 0 means that dirty bits won't be set on the
1423    * frame or its ancestors/descendants, but that intrinsic widths will still
1424    * be marked dirty.  Passing aIntrinsicDirty = eResize and aBitToAdd = 0
1425    * would result in no work being done, so don't do that.
1426    */
1427   void FrameNeedsReflow(
1428       nsIFrame* aFrame, IntrinsicDirty aIntrinsicDirty, nsFrameState aBitToAdd,
1429       ReflowRootHandling aRootHandling = ReflowRootHandling::InferFromBitToAdd);
1430 
1431   /**
1432    * Calls FrameNeedsReflow on all fixed position children of the root frame.
1433    */
1434   void MarkFixedFramesForReflow(IntrinsicDirty aIntrinsicDirty);
1435 
1436   void MaybeReflowForInflationScreenSizeChange();
1437 
1438   // This function handles all the work after VisualViewportSize is set
1439   // or reset.
1440   void CompleteChangeToVisualViewportSize();
1441 
1442   /**
1443    * The return value indicates whether the offset actually changed.
1444    */
1445   bool SetVisualViewportOffset(const nsPoint& aScrollOffset,
1446                                const nsPoint& aPrevLayoutScrollPos);
1447 
GetVisualViewportOffset()1448   nsPoint GetVisualViewportOffset() const {
1449     return mVisualViewportOffset.valueOr(nsPoint());
1450   }
IsVisualViewportOffsetSet()1451   bool IsVisualViewportOffsetSet() const {
1452     return mVisualViewportOffset.isSome();
1453   }
1454 
1455   void SetVisualViewportSize(nscoord aWidth, nscoord aHeight);
1456   void ResetVisualViewportSize();
IsVisualViewportSizeSet()1457   bool IsVisualViewportSizeSet() { return mVisualViewportSizeSet; }
GetVisualViewportSize()1458   nsSize GetVisualViewportSize() {
1459     NS_ASSERTION(mVisualViewportSizeSet,
1460                  "asking for visual viewport size when its not set?");
1461     return mVisualViewportSize;
1462   }
1463 
1464   nsPoint GetVisualViewportOffsetRelativeToLayoutViewport() const;
1465 
1466   // Returns state of the dynamic toolbar.
GetDynamicToolbarState()1467   DynamicToolbarState GetDynamicToolbarState() const {
1468     if (!mPresContext) {
1469       return DynamicToolbarState::None;
1470     }
1471 
1472     return mPresContext->GetDynamicToolbarState();
1473   }
1474   // Returns the visual viewport size during the dynamic toolbar is being
1475   // shown/hidden.
1476   nsSize GetVisualViewportSizeUpdatedByDynamicToolbar() const;
1477 
1478   /* Enable/disable author style level. Disabling author style disables the
1479    * entire author level of the cascade, including the HTML preshint level.
1480    */
1481   // XXX these could easily be inlined, but there is a circular #include
1482   // problem with nsStyleSet.
1483   void SetAuthorStyleDisabled(bool aDisabled);
1484   bool GetAuthorStyleDisabled() const;
1485 
1486   /**
1487    * Update the style set somehow to take into account changed prefs which
1488    * affect document styling.
1489    */
1490   void UpdatePreferenceStyles();
1491 
1492   // aSheetType is one of the nsIStyleSheetService *_SHEET constants.
1493   void NotifyStyleSheetServiceSheetAdded(StyleSheet* aSheet,
1494                                          uint32_t aSheetType);
1495   void NotifyStyleSheetServiceSheetRemoved(StyleSheet* aSheet,
1496                                            uint32_t aSheetType);
1497 
1498   // DoReflow returns whether the reflow finished without interruption
1499   // If aFrame is not the root frame, the caller must pass a non-null
1500   // aOverflowTracker.
1501   bool DoReflow(nsIFrame* aFrame, bool aInterruptible,
1502                 OverflowChangedTracker* aOverflowTracker);
1503 
1504   /**
1505    * Add a solid color item to the bottom of aList with frame aFrame and bounds
1506    * aBounds. Checks first if this needs to be done by checking if aFrame is a
1507    * canvas frame (if the AddCanvasBackgroundColorFlags::ForceDraw is passed
1508    * then this check is skipped). aBackstopColor is composed behind the
1509    * background color of the canvas, it is transparent by default.
1510    *
1511    * We attempt to make the background color part of the scrolled canvas (to
1512    * reduce transparent layers), and if async scrolling is enabled (and the
1513    * background is opaque) then we add a second, unscrolled item to handle the
1514    * checkerboarding case.
1515    *
1516    * AddCanvasBackgroundColorFlags::AddSubDocument should be specified when
1517    * calling this for a subdocument, and LayoutUseContainersForRootFrame might
1518    * cause the whole list to be scrolled. In that case the second unscrolled
1519    * item will be elided.
1520    *
1521    * AddCanvasBackgroundColorFlags::AppendUnscrolledOnly only attempts to add
1522    * the unscrolled item, so that we can add it manually after
1523    * LayoutUseContainersForRootFrame has built the scrolling ContainerLayer.
1524    */
1525   void AddCanvasBackgroundColorItem(
1526       nsDisplayListBuilder* aBuilder, nsDisplayList* aList, nsIFrame* aFrame,
1527       const nsRect& aBounds, nscolor aBackstopColor = NS_RGBA(0, 0, 0, 0),
1528       AddCanvasBackgroundColorFlags aFlags =
1529           AddCanvasBackgroundColorFlags::None);
1530 
1531   size_t SizeOfTextRuns(MallocSizeOf aMallocSizeOf) const;
1532 
SetNextPaintCompressed()1533   void SetNextPaintCompressed() { mNextPaintCompressed = true; }
1534 
1535   static PresShell* GetShellForEventTarget(nsIFrame* aFrame,
1536                                            nsIContent* aContent);
1537   static PresShell* GetShellForTouchEvent(WidgetGUIEvent* aEvent);
1538 
1539   /**
1540    * Informs the pres shell that the document is now at the anchor with
1541    * the given name.  If |aScroll| is true, scrolls the view of the
1542    * document so that the anchor with the specified name is displayed at
1543    * the top of the window.  If |aAnchorName| is empty, then this informs
1544    * the pres shell that there is no current target, and |aScroll| must
1545    * be false.  If |aAdditionalScrollFlags| is ScrollFlags::ScrollSmoothAuto
1546    * and |aScroll| is true, the scrolling may be performed with an animation.
1547    */
1548   MOZ_CAN_RUN_SCRIPT
1549   nsresult GoToAnchor(const nsAString& aAnchorName, bool aScroll,
1550                       ScrollFlags aAdditionalScrollFlags = ScrollFlags::None);
1551 
1552   /**
1553    * Tells the presshell to scroll again to the last anchor scrolled to by
1554    * GoToAnchor, if any. This scroll only happens if the scroll
1555    * position has not changed since the last GoToAnchor (modulo scroll anchoring
1556    * adjustments). This is called by nsDocumentViewer::LoadComplete. This clears
1557    * the last anchor scrolled to by GoToAnchor (we don't want to keep it alive
1558    * if it's removed from the DOM), so don't call this more than once.
1559    */
1560   MOZ_CAN_RUN_SCRIPT nsresult ScrollToAnchor();
1561 
1562   /**
1563    * When scroll anchoring adjusts positions in the root frame during page load,
1564    * it may move our scroll position in the root frame.
1565    *
1566    * While that's generally desirable, when scrolling to an anchor via an id-ref
1567    * we have a more direct target. If the id-ref points to something that cannot
1568    * be selected as a scroll anchor container (like an image or an inline), we
1569    * may select a node following it as a scroll anchor, and if then stuff is
1570    * inserted on top, we may end up moving the id-ref element offscreen to the
1571    * top inadvertently.
1572    *
1573    * On page load, the document viewer will call ScrollToAnchor(), and will only
1574    * scroll to the anchor again if the scroll position is not changed. We don't
1575    * want scroll anchoring adjustments to prevent this, so account for them.
1576    */
RootScrollFrameAdjusted(nscoord aYAdjustment)1577   void RootScrollFrameAdjusted(nscoord aYAdjustment) {
1578     if (mLastAnchorScrolledTo) {
1579       mLastAnchorScrollPositionY += aYAdjustment;
1580     }
1581   }
1582 
1583   /**
1584    * Scrolls the view of the document so that the primary frame of the content
1585    * is displayed in the window. Layout is flushed before scrolling.
1586    *
1587    * @param aContent  The content object of which primary frame should be
1588    *                  scrolled into view.
1589    * @param aVertical How to align the frame vertically and when to do so.
1590    *                  This is a ScrollAxis of Where and When.
1591    * @param aHorizontal How to align the frame horizontally and when to do so.
1592    *                  This is a ScrollAxis of Where and When.
1593    * @param aScrollFlags  If ScrollFlags::ScrollFirstAncestorOnly is set,
1594    *                      only the nearest scrollable ancestor is scrolled,
1595    *                      otherwise all scrollable ancestors may be scrolled
1596    *                      if necessary.  If ScrollFlags::ScrollOverflowHidden
1597    *                      is set then we may scroll in a direction even if
1598    *                      overflow:hidden is specified in that direction;
1599    *                      otherwise we will not scroll in that direction when
1600    *                      overflow:hidden is set for that direction.  If
1601    *                      ScrollFlags::ScrollNoParentFrames is set then we
1602    *                      only scroll nodes in this document, not in any
1603    *                      parent documents which contain this document in a
1604    *                      iframe or the like.  If ScrollFlags::ScrollSmooth
1605    *                      is set and CSSOM-VIEW scroll-behavior is enabled,
1606    *                      we will scroll smoothly using
1607    *                      nsIScrollableFrame::ScrollMode::SMOOTH_MSD;
1608    *                      otherwise, nsIScrollableFrame::ScrollMode::INSTANT
1609    *                      will be used.  If ScrollFlags::ScrollSmoothAuto is
1610    *                      set, the CSSOM-View scroll-behavior attribute is
1611    *                      set to 'smooth' on the scroll frame, and CSSOM-VIEW
1612    *                      scroll-behavior is enabled, we will scroll smoothly
1613    *                      using nsIScrollableFrame::ScrollMode::SMOOTH_MSD;
1614    *                      otherwise, nsIScrollableFrame::ScrollMode::INSTANT
1615    *                      will be used.
1616    */
1617   MOZ_CAN_RUN_SCRIPT
1618   nsresult ScrollContentIntoView(nsIContent* aContent, ScrollAxis aVertical,
1619                                  ScrollAxis aHorizontal,
1620                                  ScrollFlags aScrollFlags);
1621 
1622   /**
1623    * When capturing content is set, it traps all mouse events and retargets
1624    * them at this content node. If capturing is not allowed
1625    * (gCaptureInfo.mAllowed is false), then capturing is not set. However, if
1626    * the CaptureFlags::IgnoreAllowedState is set, the allowed state is ignored
1627    * and capturing is set regardless. To disable capture, pass null for the
1628    * value of aContent.
1629    *
1630    * If CaptureFlags::RetargetedToElement is set, all mouse events are
1631    * targeted at aContent only. Otherwise, mouse events are targeted at
1632    * aContent or its descendants. That is, descendants of aContent receive
1633    * mouse events as they normally would, but mouse events outside of aContent
1634    * are retargeted to aContent.
1635    *
1636    * If CaptureFlags::PreventDragStart is set then drags are prevented from
1637    * starting while this capture is active.
1638    *
1639    * If CaptureFlags::PointerLock is set, similar to
1640    * CaptureFlags::RetargetToElement, then events are targeted at aContent,
1641    * but capturing is held more strongly (i.e., calls to SetCapturingContent()
1642    * won't unlock unless CaptureFlags::PointerLock is set again).
1643    */
1644   static void SetCapturingContent(nsIContent* aContent, CaptureFlags aFlags,
1645                                   WidgetEvent* aEvent = nullptr);
1646 
1647   /**
1648    * Alias for SetCapturingContent(nullptr, CaptureFlags::None) for making
1649    * callers what they do clearer.
1650    */
ReleaseCapturingContent()1651   static void ReleaseCapturingContent() {
1652     PresShell::SetCapturingContent(nullptr, CaptureFlags::None);
1653   }
1654 
ReleaseCapturingRemoteTarget(dom::BrowserParent * aBrowserParent)1655   static void ReleaseCapturingRemoteTarget(dom::BrowserParent* aBrowserParent) {
1656     MOZ_ASSERT(XRE_IsParentProcess());
1657     if (sCapturingContentInfo.mRemoteTarget == aBrowserParent) {
1658       sCapturingContentInfo.mRemoteTarget = nullptr;
1659     }
1660   }
1661 
1662   // Called at the end of nsLayoutUtils::PaintFrame() if we were painting to
1663   // the widget.
1664   // This is used to clear any pending visual scroll updates that have been
1665   // acknowledged, to make sure they don't stick around for the next paint.
1666   void EndPaint();
1667 
1668   /**
1669    * Tell the presshell that the given frame's reflow was interrupted.  This
1670    * will mark as having dirty children a path from the given frame (inclusive)
1671    * to the nearest ancestor with a dirty subtree, or to the reflow root
1672    * currently being reflowed if no such ancestor exists (inclusive).  This is
1673    * to be done immediately after reflow of the current reflow root completes.
1674    * This method must only be called during reflow, and the frame it's being
1675    * called on must be in the process of being reflowed when it's called.  This
1676    * method doesn't mark any intrinsic widths dirty and doesn't add any bits
1677    * other than NS_FRAME_HAS_DIRTY_CHILDREN.
1678    */
1679   void FrameNeedsToContinueReflow(nsIFrame* aFrame);
1680 
1681   /**
1682    * Notification sent by a frame informing the pres shell that it is about to
1683    * be destroyed.
1684    * This allows any outstanding references to the frame to be cleaned up
1685    */
1686   void NotifyDestroyingFrame(nsIFrame* aFrame);
1687 
1688 #ifdef DEBUG
GetDrawEventTargetFrame()1689   nsIFrame* GetDrawEventTargetFrame() { return mDrawEventTargetFrame; }
1690 #endif
1691 
1692   bool GetZoomableByAPZ() const;
1693 
1694  private:
1695   ~PresShell();
1696 
1697   void SetIsActive(bool aIsActive);
1698   bool ShouldBeActive() const;
1699 
1700 
1701   /**
1702    * Refresh observer management.
1703    */
1704   void DoObserveStyleFlushes();
1705   void DoObserveLayoutFlushes();
1706 
1707   /**
1708    * Does the actual work of figuring out the current state of font size
1709    * inflation.
1710    */
1711   bool DetermineFontSizeInflationState();
1712 
RecordAlloc(void * aPtr)1713   void RecordAlloc(void* aPtr) {
1714 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
1715     MOZ_DIAGNOSTIC_ASSERT(!mAllocatedPointers.Contains(aPtr));
1716     mAllocatedPointers.Insert(aPtr);
1717 #endif
1718   }
1719 
RecordFree(void * aPtr)1720   void RecordFree(void* aPtr) {
1721 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
1722     MOZ_DIAGNOSTIC_ASSERT(mAllocatedPointers.Contains(aPtr));
1723     mAllocatedPointers.Remove(aPtr);
1724 #endif
1725   }
1726 
1727   void PushCurrentEventInfo(nsIFrame* aFrame, nsIContent* aContent);
1728   void PopCurrentEventInfo();
1729   nsIContent* GetCurrentEventContent();
1730 
1731   friend class ::nsRefreshDriver;
1732   friend class ::nsAutoCauseReflowNotifier;
1733 
1734   void WillCauseReflow();
1735   MOZ_CAN_RUN_SCRIPT void DidCauseReflow();
1736 
1737   void CancelPostedReflowCallbacks();
1738   void FlushPendingScrollAnchorAdjustments();
1739 
1740   void SetPendingVisualScrollUpdate(
1741       const nsPoint& aVisualViewportOffset,
1742       FrameMetrics::ScrollOffsetUpdateType aUpdateType);
1743 
1744 #ifdef MOZ_REFLOW_PERF
1745   UniquePtr<ReflowCountMgr> mReflowCountMgr;
1746 #endif
1747 
1748   void WillDoReflow();
1749 
1750   // This data is stored as a content property (nsGkAtoms::scrolling) on
1751   // mContentToScrollTo when we have a pending ScrollIntoView.
1752   struct ScrollIntoViewData {
1753     ScrollAxis mContentScrollVAxis;
1754     ScrollAxis mContentScrollHAxis;
1755     ScrollFlags mContentToScrollToFlags;
1756   };
1757 
1758   static LazyLogModule gLog;
1759 
1760   DOMHighResTimeStamp GetPerformanceNowUnclamped();
1761 
1762   // The callback for the mReflowContinueTimer timer.
1763   static void sReflowContinueCallback(nsITimer* aTimer, void* aPresShell);
1764   bool ScheduleReflowOffTimer();
1765   // MaybeScheduleReflow checks if posting a reflow is needed, then checks if
1766   // the last reflow was interrupted. In the interrupted case ScheduleReflow is
1767   // called off a timer, otherwise it is called directly.
1768   void MaybeScheduleReflow();
1769   // Actually schedules a reflow.  This should only be called by
1770   // MaybeScheduleReflow and the reflow timer ScheduleReflowOffTimer
1771   // sets up.
1772   void ScheduleReflow();
1773 
1774   friend class ::AutoPointerEventTargetUpdater;
1775 
1776   // ProcessReflowCommands returns whether we processed all our dirty roots
1777   // without interruptions.
1778   MOZ_CAN_RUN_SCRIPT bool ProcessReflowCommands(bool aInterruptible);
1779 
1780   /**
1781    * Callback handler for whether reflow happened.
1782    *
1783    * @param aInterruptible Whether or not reflow interruption is allowed.
1784    */
1785   MOZ_CAN_RUN_SCRIPT void DidDoReflow(bool aInterruptible);
1786 
1787   MOZ_CAN_RUN_SCRIPT void HandlePostedReflowCallbacks(bool aInterruptible);
1788 
1789   /**
1790    * Helper for ScrollContentIntoView()
1791    */
1792   MOZ_CAN_RUN_SCRIPT void DoScrollContentIntoView();
1793 
1794   /**
1795    * Methods to handle changes to user and UA sheet lists that we get
1796    * notified about.
1797    */
1798   void AddUserSheet(StyleSheet*);
1799   void AddAgentSheet(StyleSheet*);
1800   void AddAuthorSheet(StyleSheet*);
1801   void RemovePreferenceStyles();
1802 
1803   /**
1804    * Initialize cached font inflation preference values and do an initial
1805    * computation to determine if font inflation is enabled.
1806    *
1807    * @see nsLayoutUtils::sFontSizeInflationEmPerLine
1808    * @see nsLayoutUtils::sFontSizeInflationMinTwips
1809    * @see nsLayoutUtils::sFontSizeInflationLineThreshold
1810    */
1811   void SetupFontInflation();
1812 
1813   /**
1814    * Implementation methods for FlushPendingNotifications.
1815    */
1816   MOZ_CAN_RUN_SCRIPT void DoFlushPendingNotifications(FlushType aType);
1817   MOZ_CAN_RUN_SCRIPT void DoFlushPendingNotifications(ChangesToFlush aType);
1818 
1819   struct RenderingState {
RenderingStateRenderingState1820     explicit RenderingState(PresShell* aPresShell)
1821         : mResolution(aPresShell->mResolution),
1822           mRenderingStateFlags(aPresShell->mRenderingStateFlags) {}
1823     Maybe<float> mResolution;
1824     RenderingStateFlags mRenderingStateFlags;
1825   };
1826 
1827   struct AutoSaveRestoreRenderingState {
AutoSaveRestoreRenderingStateAutoSaveRestoreRenderingState1828     explicit AutoSaveRestoreRenderingState(PresShell* aPresShell)
1829         : mPresShell(aPresShell), mOldState(aPresShell) {}
1830 
~AutoSaveRestoreRenderingStateAutoSaveRestoreRenderingState1831     ~AutoSaveRestoreRenderingState() {
1832       mPresShell->mRenderingStateFlags = mOldState.mRenderingStateFlags;
1833       mPresShell->mResolution = mOldState.mResolution;
1834     }
1835 
1836     PresShell* mPresShell;
1837     RenderingState mOldState;
1838   };
1839   void SetRenderingState(const RenderingState& aState);
1840 
1841   friend class ::nsPresShellEventCB;
1842 
1843   // methods for painting a range to an offscreen buffer
1844 
1845   // given a display list, clip the items within the list to
1846   // the range
1847   nsRect ClipListToRange(nsDisplayListBuilder* aBuilder, nsDisplayList* aList,
1848                          nsRange* aRange);
1849 
1850   // create a RangePaintInfo for the range aRange containing the
1851   // display list needed to paint the range to a surface
1852   UniquePtr<RangePaintInfo> CreateRangePaintInfo(nsRange* aRange,
1853                                                  nsRect& aSurfaceRect,
1854                                                  bool aForPrimarySelection);
1855 
1856   /*
1857    * Paint the items to a new surface and return it.
1858    *
1859    * aSelection - selection being painted, if any
1860    * aRegion - clip region, if any
1861    * aArea - area that the surface occupies, relative to the root frame
1862    * aPoint - reference point, typically the mouse position
1863    * aScreenRect - [out] set to the area of the screen the painted area should
1864    *               be displayed at
1865    * aFlags - set RenderImageFlags::AutoScale to scale down large images, but
1866    * it must not be set if a custom image was specified
1867    */
1868   already_AddRefed<SourceSurface> PaintRangePaintInfo(
1869       const nsTArray<UniquePtr<RangePaintInfo>>& aItems,
1870       dom::Selection* aSelection, const Maybe<CSSIntRegion>& aRegion,
1871       nsRect aArea, const LayoutDeviceIntPoint aPoint,
1872       LayoutDeviceIntRect* aScreenRect, RenderImageFlags aFlags);
1873 
1874   // Hide a view if it is a popup
1875   void HideViewIfPopup(nsView* aView);
1876 
1877   // Utility method to restore the root scrollframe state
1878   void RestoreRootScrollPosition();
1879 
1880   MOZ_CAN_RUN_SCRIPT_BOUNDARY void MaybeReleaseCapturingContent();
1881 
1882   class DelayedEvent {
1883    public:
1884     virtual ~DelayedEvent() = default;
Dispatch()1885     virtual void Dispatch() {}
IsKeyPressEvent()1886     virtual bool IsKeyPressEvent() { return false; }
1887   };
1888 
1889   class DelayedInputEvent : public DelayedEvent {
1890    public:
1891     void Dispatch() override;
1892 
1893    protected:
1894     DelayedInputEvent();
1895     ~DelayedInputEvent() override;
1896 
1897     WidgetInputEvent* mEvent;
1898   };
1899 
1900   class DelayedMouseEvent : public DelayedInputEvent {
1901    public:
1902     explicit DelayedMouseEvent(WidgetMouseEvent* aEvent);
1903   };
1904 
1905   class DelayedKeyEvent : public DelayedInputEvent {
1906    public:
1907     explicit DelayedKeyEvent(WidgetKeyboardEvent* aEvent);
1908     bool IsKeyPressEvent() override;
1909   };
1910 
1911   // Check if aEvent is a mouse event and record the mouse location for later
1912   // synth mouse moves.
1913   void RecordMouseLocation(WidgetGUIEvent* aEvent);
1914   inline bool MouseLocationWasSetBySynthesizedMouseEventForTests() const;
1915   class nsSynthMouseMoveEvent final : public nsARefreshObserver {
1916    public:
nsSynthMouseMoveEvent(PresShell * aPresShell,bool aFromScroll)1917     nsSynthMouseMoveEvent(PresShell* aPresShell, bool aFromScroll)
1918         : mPresShell(aPresShell), mFromScroll(aFromScroll) {
1919       NS_ASSERTION(mPresShell, "null parameter");
1920     }
1921 
1922    private:
1923     // Private destructor, to discourage deletion outside of Release():
~nsSynthMouseMoveEvent()1924     ~nsSynthMouseMoveEvent() { Revoke(); }
1925 
1926    public:
1927     NS_INLINE_DECL_REFCOUNTING(nsSynthMouseMoveEvent, override)
1928 
1929     void Revoke();
1930 
1931     MOZ_CAN_RUN_SCRIPT
WillRefresh(TimeStamp aTime)1932     void WillRefresh(TimeStamp aTime) override {
1933       if (mPresShell) {
1934         RefPtr<PresShell> shell = mPresShell;
1935         shell->ProcessSynthMouseMoveEvent(mFromScroll);
1936       }
1937     }
1938 
1939    private:
1940     PresShell* mPresShell;
1941     bool mFromScroll;
1942   };
1943   MOZ_CAN_RUN_SCRIPT void ProcessSynthMouseMoveEvent(bool aFromScroll);
1944 
1945   void UpdateImageLockingState();
1946 
1947   already_AddRefed<PresShell> GetParentPresShellForEventHandling();
1948 
1949   /**
1950    * EventHandler is implementation of PresShell::HandleEvent().
1951    */
1952   class MOZ_STACK_CLASS EventHandler final {
1953    public:
1954     EventHandler() = delete;
1955     EventHandler(const EventHandler& aOther) = delete;
EventHandler(PresShell & aPresShell)1956     explicit EventHandler(PresShell& aPresShell)
1957         : mPresShell(aPresShell), mCurrentEventInfoSetter(nullptr) {}
EventHandler(RefPtr<PresShell> && aPresShell)1958     explicit EventHandler(RefPtr<PresShell>&& aPresShell)
1959         : mPresShell(std::move(aPresShell)), mCurrentEventInfoSetter(nullptr) {}
1960 
1961     /**
1962      * HandleEvent() may dispatch aGUIEvent.  This may redirect the event to
1963      * another PresShell, or the event may be handled by other classes like
1964      * AccessibleCaretEventHub, or discarded.  Otherwise, this sets current
1965      * event info of mPresShell and calls HandleEventWithCurrentEventInfo()
1966      * to dispatch the event into the DOM tree.
1967      *
1968      * @param aFrameForPresShell        The frame for PresShell.  If PresShell
1969      *                                  has root frame, it should be set.
1970      *                                  Otherwise, a frame which contains the
1971      *                                  PresShell should be set instead.  I.e.,
1972      *                                  in the latter case, the frame is in
1973      *                                  a parent document.
1974      * @param aGUIEvent                 Event to be handled.  Must be a trusted
1975      *                                  event.
1976      * @param aDontRetargetEvents       true if this shouldn't redirect the
1977      *                                  event to different PresShell.
1978      *                                  false if this can redirect the event to
1979      *                                  different PresShell.
1980      * @param aEventStatus              [in/out] EventStatus of aGUIEvent.
1981      */
1982     MOZ_CAN_RUN_SCRIPT
1983     nsresult HandleEvent(nsIFrame* aFrameForPresShell,
1984                          WidgetGUIEvent* aGUIEvent, bool aDontRetargetEvents,
1985                          nsEventStatus* aEventStatus);
1986 
1987     /**
1988      * HandleEventWithTarget() tries to dispatch aEvent on aContent after
1989      * setting current event target content to aNewEventContent and current
1990      * event frame to aNewEventFrame temporarily.  Note that this supports
1991      * WidgetEvent, not WidgetGUIEvent.  So, you can dispatch a simple event
1992      * with this.
1993      *
1994      * @param aEvent                    Event to be dispatched.  Must be a
1995      *                                  trusted event.
1996      * @param aNewEventFrame            Temporal new event frame.
1997      * @param aNewEventContent          Temporal new event content.
1998      * @param aEventStatus              [in/out] EventStuatus of aEvent.
1999      * @param aIsHandlingNativeEvent    true if aEvent represents a native
2000      *                                  event.
2001      * @param aTargetContent            This is used only when aEvent is a
2002      *                                  pointer event.  If
2003      *                                  PresShell::mPointerEventTarget is
2004      *                                  changed during dispatching aEvent,
2005      *                                  this is set to the new target.
2006      * @param aOverrideClickTarget      Override click event target.
2007      */
2008     MOZ_CAN_RUN_SCRIPT
2009     nsresult HandleEventWithTarget(WidgetEvent* aEvent,
2010                                    nsIFrame* aNewEventFrame,
2011                                    nsIContent* aNewEventContent,
2012                                    nsEventStatus* aEventStatus,
2013                                    bool aIsHandlingNativeEvent,
2014                                    nsIContent** aTargetContent,
2015                                    nsIContent* aOverrideClickTarget);
2016 
2017     /**
2018      * OnPresShellDestroy() is called when every PresShell instance is being
2019      * destroyed.
2020      */
2021     static inline void OnPresShellDestroy(Document* aDocument);
2022 
2023    private:
2024     static bool InZombieDocument(nsIContent* aContent);
2025     static nsIFrame* GetNearestFrameContainingPresShell(PresShell* aPresShell);
2026     static nsIPrincipal* GetDocumentPrincipalToCompareWithBlacklist(
2027         PresShell& aPresShell);
2028 
2029     /**
2030      * HandleEventUsingCoordinates() handles aGUIEvent whose
2031      * IsUsingCoordinates() returns true with the following helper methods.
2032      *
2033      * @param aFrameForPresShell        The frame for PresShell.  See
2034      *                                  explanation of HandleEvent() for the
2035      *                                  details.
2036      * @param aGUIEvent                 The handling event.  Make sure that
2037      *                                  its IsUsingCoordinates() returns true.
2038      * @param aEventStatus              The status of aGUIEvent.
2039      * @param aDontRetargetEvents       true if we've already retarget document.
2040      *                                  Otherwise, false.
2041      */
2042     MOZ_CAN_RUN_SCRIPT
2043     nsresult HandleEventUsingCoordinates(nsIFrame* aFrameForPresShell,
2044                                          WidgetGUIEvent* aGUIEvent,
2045                                          nsEventStatus* aEventStatus,
2046                                          bool aDontRetargetEvents);
2047 
2048     /**
2049      * EventTargetData struct stores a set of a PresShell (event handler),
2050      * a frame (to handle the event) and a content (event target for the frame).
2051      */
2052     struct MOZ_STACK_CLASS EventTargetData final {
2053       EventTargetData() = delete;
2054       EventTargetData(const EventTargetData& aOther) = delete;
EventTargetDatafinal2055       explicit EventTargetData(nsIFrame* aFrameToHandleEvent) {
2056         SetFrameAndComputePresShell(aFrameToHandleEvent);
2057       }
2058 
2059       void SetFrameAndComputePresShell(nsIFrame* aFrameToHandleEvent);
2060       void SetFrameAndComputePresShellAndContent(nsIFrame* aFrameToHandleEvent,
2061                                                  WidgetGUIEvent* aGUIEvent);
2062       void SetContentForEventFromFrame(WidgetGUIEvent* aGUIEvent);
2063 
GetPresContextfinal2064       nsPresContext* GetPresContext() const {
2065         return mPresShell ? mPresShell->GetPresContext() : nullptr;
2066       };
GetEventStateManagerfinal2067       EventStateManager* GetEventStateManager() const {
2068         nsPresContext* presContext = GetPresContext();
2069         return presContext ? presContext->EventStateManager() : nullptr;
2070       }
GetDocumentfinal2071       Document* GetDocument() const {
2072         return mPresShell ? mPresShell->GetDocument() : nullptr;
2073       }
2074       nsIContent* GetFrameContent() const;
2075 
2076       /**
2077        * MaybeRetargetToActiveDocument() tries retarget aGUIEvent into
2078        * active document if there is.  Note that this does not support to
2079        * retarget mContent.  Make sure it is nullptr before calling this.
2080        *
2081        * @param aGUIEvent       The handling event.
2082        * @return                true if retargetted.
2083        */
2084       bool MaybeRetargetToActiveDocument(WidgetGUIEvent* aGUIEvent);
2085 
2086       /**
2087        * ComputeElementFromFrame() computes mContent for aGUIEvent.  If
2088        * mContent is set by this method, mContent is always nullptr or an
2089        * Element.
2090        *
2091        * @param aGUIEvent       The handling event.
2092        * @return                true if caller can keep handling the event.
2093        *                        Otherwise, false.
2094        *                        Note that even if this returns true, mContent
2095        *                        may be nullptr.
2096        */
2097       bool ComputeElementFromFrame(WidgetGUIEvent* aGUIEvent);
2098 
2099       /**
2100        * UpdateTouchEventTarget() updates mFrame, mPresShell and mContent if
2101        * aGUIEvent is a touch event and there is new proper target.
2102        *
2103        * @param aGUIEvent       The handled event.  If it's not a touch event,
2104        *                        this method does nothing.
2105        */
2106       void UpdateTouchEventTarget(WidgetGUIEvent* aGUIEvent);
2107 
2108       RefPtr<PresShell> mPresShell;
2109       nsIFrame* mFrame = nullptr;
2110       nsCOMPtr<nsIContent> mContent;
2111       nsCOMPtr<nsIContent> mOverrideClickTarget;
2112     };
2113 
2114     /**
2115      * MaybeFlushPendingNotifications() maybe flush pending notifications if
2116      * aGUIEvent should be handled with the latest layout.
2117      *
2118      * @param aGUIEvent                 The handling event.
2119      * @return                          true if this actually flushes pending
2120      *                                  layout and that has caused changing the
2121      *                                  layout.
2122      */
2123     MOZ_CAN_RUN_SCRIPT
2124     bool MaybeFlushPendingNotifications(WidgetGUIEvent* aGUIEvent);
2125 
2126     /**
2127      * GetFrameToHandleNonTouchEvent() returns a frame to handle the event.
2128      * This may flush pending layout if the target is in child PresShell.
2129      *
2130      * @param aRootFrameToHandleEvent   The root frame to handle the event.
2131      * @param aGUIEvent                 The handling event.
2132      * @return                          The frame which should handle the
2133      *                                  event.  nullptr if the caller should
2134      *                                  stop handling the event.
2135      */
2136     MOZ_CAN_RUN_SCRIPT
2137     nsIFrame* GetFrameToHandleNonTouchEvent(nsIFrame* aRootFrameToHandleEvent,
2138                                             WidgetGUIEvent* aGUIEvent);
2139 
2140     /**
2141      * ComputeEventTargetFrameAndPresShellAtEventPoint() computes event
2142      * target frame at the event point of aGUIEvent and set it to
2143      * aEventTargetData.
2144      *
2145      * @param aRootFrameToHandleEvent   The root frame to handle aGUIEvent.
2146      * @param aGUIEvent                 The handling event.
2147      * @param aEventTargetData          [out] Its frame and PresShell will
2148      *                                  be set.
2149      * @return                          true if the caller can handle the
2150      *                                  event.  Otherwise, false.
2151      */
2152     MOZ_CAN_RUN_SCRIPT
2153     bool ComputeEventTargetFrameAndPresShellAtEventPoint(
2154         nsIFrame* aRootFrameToHandleEvent, WidgetGUIEvent* aGUIEvent,
2155         EventTargetData* aEventTargetData);
2156 
2157     /**
2158      * DispatchPrecedingPointerEvent() dispatches preceding pointer event for
2159      * aGUIEvent if Pointer Events is enabled.
2160      *
2161      * @param aFrameForPresShell        The frame for PresShell.  See
2162      *                                  explanation of HandleEvent() for the
2163      *                                  details.
2164      * @param aGUIEvent                 The handled event.
2165      * @param aPointerCapturingContent  The content which is capturing pointer
2166      *                                  events if there is.  Otherwise, nullptr.
2167      * @param aDontRetargetEvents       Set aDontRetargetEvents of
2168      *                                  HandleEvent() which called this method.
2169      * @param aEventTargetData          [in/out] Event target data of
2170      *                                  aGUIEvent.  If pointer event listeners
2171      *                                  change the DOM tree or reframe the
2172      *                                  target, updated by this method.
2173      * @param aEventStatus              [in/out] The event status of aGUIEvent.
2174      * @return                          true if the caller can handle the
2175      *                                  event.  Otherwise, false.
2176      */
2177     MOZ_CAN_RUN_SCRIPT
2178     bool DispatchPrecedingPointerEvent(nsIFrame* aFrameForPresShell,
2179                                        WidgetGUIEvent* aGUIEvent,
2180                                        nsIContent* aPointerCapturingContent,
2181                                        bool aDontRetargetEvents,
2182                                        EventTargetData* aEventTargetData,
2183                                        nsEventStatus* aEventStatus);
2184 
2185     /**
2186      * MaybeDiscardEvent() checks whether it's safe to handle aGUIEvent right
2187      * now.  If it's not safe, this may notify somebody of discarding event if
2188      * necessary.
2189      *
2190      * @param aGUIEvent   Handling event.
2191      * @return            true if it's not safe to handle the event.
2192      */
2193     bool MaybeDiscardEvent(WidgetGUIEvent* aGUIEvent);
2194 
2195     /**
2196      * GetCapturingContentFor() returns capturing content for aGUIEvent.
2197      * If aGUIEvent is not related to capturing, this returns nullptr.
2198      */
2199     static nsIContent* GetCapturingContentFor(WidgetGUIEvent* aGUIEvent);
2200 
2201     /**
2202      * GetRetargetEventDocument() returns a document if aGUIEvent should be
2203      * handled in another document.
2204      *
2205      * @param aGUIEvent                 Handling event.
2206      * @param aRetargetEventDocument    Document which should handle aGUIEvent.
2207      * @return                          true if caller can keep handling
2208      *                                  aGUIEvent.
2209      */
2210     bool GetRetargetEventDocument(WidgetGUIEvent* aGUIEvent,
2211                                   Document** aRetargetEventDocument);
2212 
2213     /**
2214      * GetFrameForHandlingEventWith() returns a frame which should be used as
2215      * aFrameForPresShell of HandleEvent().  See @return for the details.
2216      *
2217      * @param aGUIEvent                 Handling event.
2218      * @param aRetargetDocument         Document which aGUIEvent should be
2219      *                                  fired on.  Typically, should be result
2220      *                                  of GetRetargetEventDocument().
2221      * @param aFrameForPresShell        The frame for PresShell.  See
2222      *                                  explanation of HandleEvent() for the
2223      *                                  details.
2224      * @return                          nullptr if caller should stop handling
2225      *                                  the event.
2226      *                                  aFrameForPresShell if caller should
2227      *                                  keep handling the event by itself.
2228      *                                  Otherwise, caller should handle it with
2229      *                                  another PresShell which is result of
2230      *                                  nsIFrame::PresContext()->GetPresShell().
2231      */
2232     nsIFrame* GetFrameForHandlingEventWith(WidgetGUIEvent* aGUIEvent,
2233                                            Document* aRetargetDocument,
2234                                            nsIFrame* aFrameForPresShell);
2235 
2236     /**
2237      * MaybeHandleEventWithAnotherPresShell() may handle aGUIEvent with another
2238      * PresShell.
2239      *
2240      * @param aFrameForPresShell        The frame for PresShell.  See
2241      *                                  explanation of HandleEvent() for the
2242      *                                  details.
2243      * @param aGUIEvent                 Handling event.
2244      * @param aEventStatus              [in/out] EventStatus of aGUIEvent.
2245      * @param aRv                       [out] Returns error if this gets an
2246      *                                  error handling the event.
2247      * @return                          false if caller needs to keep handling
2248      *                                  the event by itself.
2249      *                                  true if caller shouldn't keep handling
2250      *                                  the event.  Note that when no PresShell
2251      *                                  can handle the event, this returns true.
2252      */
2253     MOZ_CAN_RUN_SCRIPT
2254     bool MaybeHandleEventWithAnotherPresShell(nsIFrame* aFrameForPresShell,
2255                                               WidgetGUIEvent* aGUIEvent,
2256                                               nsEventStatus* aEventStatus,
2257                                               nsresult* aRv);
2258 
2259     MOZ_CAN_RUN_SCRIPT
2260     nsresult RetargetEventToParent(WidgetGUIEvent* aGUIEvent,
2261                                    nsEventStatus* aEventStatus);
2262 
2263     /**
2264      * MaybeHandleEventWithAccessibleCaret() may handle aGUIEvent with
2265      * AccessibleCaretEventHub if it's necessary.
2266      *
2267      * @param aFrameForPresShell The frame for PresShell. See explanation of
2268      *                           HandleEvent() for the details.
2269      * @param aGUIEvent         Event may be handled by AccessibleCaretEventHub.
2270      * @param aEventStatus      [in/out] EventStatus of aGUIEvent.
2271      * @return                  true if AccessibleCaretEventHub handled the
2272      *                          event and caller shouldn't keep handling it.
2273      */
2274     MOZ_CAN_RUN_SCRIPT
2275     bool MaybeHandleEventWithAccessibleCaret(nsIFrame* aFrameForPresShell,
2276                                              WidgetGUIEvent* aGUIEvent,
2277                                              nsEventStatus* aEventStatus);
2278 
2279     /**
2280      * MaybeDiscardOrDelayKeyboardEvent() may discared or put aGUIEvent into
2281      * the delayed event queue if it's a keyboard event and if we should do so.
2282      * If aGUIEvent is not a keyboard event, this does nothing.
2283      *
2284      * @param aGUIEvent         The handling event.
2285      * @return                  true if this method discard the event or
2286      *                          put it into the delayed event queue.
2287      */
2288     bool MaybeDiscardOrDelayKeyboardEvent(WidgetGUIEvent* aGUIEvent);
2289 
2290     /**
2291      * MaybeDiscardOrDelayMouseEvent() may discard or put aGUIEvent into the
2292      * delayed event queue if it's a mouse event and if we should do so.
2293      * If aGUIEvent is not a mouse event, this does nothing.
2294      * If there is suppressed event listener like debugger of devtools, this
2295      * notifies it of the event after discard or put it into the delayed
2296      * event queue.
2297      *
2298      * @param aFrameToHandleEvent       The frame to handle aGUIEvent.
2299      * @param aGUIEvent                 The handling event.
2300      * @return                          true if this method discard the event
2301      *                                  or put it into the delayed event queue.
2302      */
2303     bool MaybeDiscardOrDelayMouseEvent(nsIFrame* aFrameToHandleEvent,
2304                                        WidgetGUIEvent* aGUIEvent);
2305 
2306     /**
2307      * MaybeFlushThrottledStyles() tries to flush pending animation.  If it's
2308      * flushed and then aFrameForPresShell is destroyed, returns new frame
2309      * which contains mPresShell.
2310      *
2311      * @param aFrameForPresShell        The frame for PresShell.  See
2312      *                                  explanation of HandleEvent() for the
2313      *                                  details.  This can be nullptr.
2314      * @return                          Maybe new frame for mPresShell.
2315      *                                  If aFrameForPresShell is not nullptr
2316      *                                  and hasn't been destroyed, returns
2317      *                                  aFrameForPresShell as-is.
2318      */
2319     MOZ_CAN_RUN_SCRIPT
2320     nsIFrame* MaybeFlushThrottledStyles(nsIFrame* aFrameForPresShell);
2321 
2322     /**
2323      * ComputeRootFrameToHandleEvent() returns root frame to handle the event.
2324      * For example, if there is a popup, this returns the popup frame.
2325      * If there is capturing content and it's in a scrolled frame, returns
2326      * the scrolled frame.
2327      *
2328      * @param aFrameForPresShell                The frame for PresShell.  See
2329      *                                          explanation of HandleEvent() for
2330      *                                          the details.
2331      * @param aGUIEvent                         The handling event.
2332      * @param aCapturingContent                 Capturing content if there is.
2333      *                                          nullptr, otherwise.
2334      * @param aIsCapturingContentIgnored        [out] true if aCapturingContent
2335      *                                          is not nullptr but it should be
2336      *                                          ignored to handle the event.
2337      * @param aIsCaptureRetargeted              [out] true if aCapturingContent
2338      *                                          is not nullptr but it's
2339      *                                          retargeted.
2340      * @return                                  Root frame to handle the event.
2341      */
2342     nsIFrame* ComputeRootFrameToHandleEvent(nsIFrame* aFrameForPresShell,
2343                                             WidgetGUIEvent* aGUIEvent,
2344                                             nsIContent* aCapturingContent,
2345                                             bool* aIsCapturingContentIgnored,
2346                                             bool* aIsCaptureRetargeted);
2347 
2348     /**
2349      * ComputeRootFrameToHandleEventWithPopup() returns popup frame if there
2350      * is a popup and we should handle the event in it.  Otherwise, returns
2351      * aRootFrameToHandleEvent.
2352      *
2353      * @param aRootFrameToHandleEvent           Candidate root frame to handle
2354      *                                          the event.
2355      * @param aGUIEvent                         The handling event.
2356      * @param aCapturingContent                 Capturing content if there is.
2357      *                                          nullptr, otherwise.
2358      * @param aIsCapturingContentIgnored        [out] true if aCapturingContent
2359      *                                          is not nullptr but it should be
2360      *                                          ignored to handle the event.
2361      * @return                                  A popup frame if there is a
2362      *                                          popup and we should handle the
2363      *                                          event in it.  Otherwise,
2364      *                                          aRootFrameToHandleEvent.
2365      *                                          I.e., never returns nullptr.
2366      */
2367     nsIFrame* ComputeRootFrameToHandleEventWithPopup(
2368         nsIFrame* aRootFrameToHandleEvent, WidgetGUIEvent* aGUIEvent,
2369         nsIContent* aCapturingContent, bool* aIsCapturingContentIgnored);
2370 
2371     /**
2372      * ComputeRootFrameToHandleEventWithCapturingContent() returns root frame
2373      * to handle event for the capturing content, or aRootFrameToHandleEvent
2374      * if it should be ignored.
2375      *
2376      * @param aRootFrameToHandleEvent           Candidate root frame to handle
2377      *                                          the event.
2378      * @param aCapturingContent                 Capturing content.  nullptr is
2379      *                                          not allowed.
2380      * @param aIsCapturingContentIgnored        [out] true if aCapturingContent
2381      *                                          is not nullptr but it should be
2382      *                                          ignored to handle the event.
2383      * @param aIsCaptureRetargeted              [out] true if aCapturingContent
2384      *                                          is not nullptr but it's
2385      *                                          retargeted.
2386      * @return                                  A popup frame if there is a
2387      *                                          popup and we should handle the
2388      *                                          event in it.  Otherwise,
2389      *                                          aRootFrameToHandleEvent.
2390      *                                          I.e., never returns nullptr.
2391      */
2392     nsIFrame* ComputeRootFrameToHandleEventWithCapturingContent(
2393         nsIFrame* aRootFrameToHandleEvent, nsIContent* aCapturingContent,
2394         bool* aIsCapturingContentIgnored, bool* aIsCaptureRetargeted);
2395 
2396     /**
2397      * HandleEventWithPointerCapturingContentWithoutItsFrame() handles
2398      * aGUIEvent with aPointerCapturingContent when it does not have primary
2399      * frame.
2400      *
2401      * @param aFrameForPresShell        The frame for PresShell.  See
2402      *                                  explanation of HandleEvent() for the
2403      *                                  details.
2404      * @param aGUIEvent                 The handling event.
2405      * @param aPointerCapturingContent  Current pointer capturing content.
2406      *                                  Must not be nullptr.
2407      * @param aEventStatus              [in/out] The event status of aGUIEvent.
2408      * @return                          Basically, result of
2409      *                                  HandeEventWithTraget().
2410      */
2411     MOZ_CAN_RUN_SCRIPT
2412     nsresult HandleEventWithPointerCapturingContentWithoutItsFrame(
2413         nsIFrame* aFrameForPresShell, WidgetGUIEvent* aGUIEvent,
2414         nsIContent* aPointerCapturingContent, nsEventStatus* aEventStatus);
2415 
2416     /**
2417      * HandleEventAtFocusedContent() handles aGUIEvent at focused content.
2418      *
2419      * @param aGUIEvent         The handling event which should be handled at
2420      *                          focused content.
2421      * @param aEventStatus      [in/out] The event status of aGUIEvent.
2422      */
2423     MOZ_CAN_RUN_SCRIPT
2424     nsresult HandleEventAtFocusedContent(WidgetGUIEvent* aGUIEvent,
2425                                          nsEventStatus* aEventStatus);
2426 
2427     /**
2428      * ComputeFocusedEventTargetElement() returns event target element for
2429      * aGUIEvent which should be handled with focused content.
2430      * This may set/unset sLastKeyDownEventTarget if necessary.
2431      *
2432      * @param aGUIEvent                 The handling event.
2433      * @return                          The element which should be the event
2434      *                                  target of aGUIEvent.
2435      */
2436     dom::Element* ComputeFocusedEventTargetElement(WidgetGUIEvent* aGUIEvent);
2437 
2438     /**
2439      * MaybeHandleEventWithAnotherPresShell() may handle aGUIEvent with another
2440      * PresShell.
2441      *
2442      * @param aEventTargetElement       The event target element of aGUIEvent.
2443      * @param aGUIEvent                 Handling event.
2444      * @param aEventStatus              [in/out] EventStatus of aGUIEvent.
2445      * @param aRv                       [out] Returns error if this gets an
2446      *                                  error handling the event.
2447      * @return                          false if caller needs to keep handling
2448      *                                  the event by itself.
2449      *                                  true if caller shouldn't keep handling
2450      *                                  the event.  Note that when no PresShell
2451      *                                  can handle the event, this returns true.
2452      */
2453     MOZ_CAN_RUN_SCRIPT
2454     bool MaybeHandleEventWithAnotherPresShell(dom::Element* aEventTargetElement,
2455                                               WidgetGUIEvent* aGUIEvent,
2456                                               nsEventStatus* aEventStatus,
2457                                               nsresult* aRv);
2458 
2459     /**
2460      * HandleRetargetedEvent() dispatches aGUIEvent on the PresShell without
2461      * retargetting.  This should be used only when caller computes final
2462      * target of aGUIEvent.
2463      *
2464      * @param aGUIEvent         Event to be dispatched.
2465      * @param aEventStatus      [in/out] EventStatus of aGUIEvent.
2466      * @param aTarget           The final target of aGUIEvent.
2467      */
2468     MOZ_CAN_RUN_SCRIPT
HandleRetargetedEvent(WidgetGUIEvent * aGUIEvent,nsEventStatus * aEventStatus,nsIContent * aTarget)2469     nsresult HandleRetargetedEvent(WidgetGUIEvent* aGUIEvent,
2470                                    nsEventStatus* aEventStatus,
2471                                    nsIContent* aTarget) {
2472       AutoCurrentEventInfoSetter eventInfoSetter(*this, nullptr, aTarget);
2473       if (!mPresShell->GetCurrentEventFrame()) {
2474         return NS_OK;
2475       }
2476       nsCOMPtr<nsIContent> overrideClickTarget;
2477       return HandleEventWithCurrentEventInfo(aGUIEvent, aEventStatus, true,
2478                                              overrideClickTarget);
2479     }
2480 
2481     /**
2482      * HandleEventWithFrameForPresShell() handles aGUIEvent with the frame
2483      * for mPresShell.
2484      *
2485      * @param aFrameForPresShell        The frame for mPresShell.
2486      * @param aGUIEvent                 The handling event.  It shouldn't be
2487      *                                  handled with using coordinates nor
2488      *                                  handled at focused content.
2489      * @param aEventStatus              [in/out] The status of aGUIEvent.
2490      */
2491     MOZ_CAN_RUN_SCRIPT
2492     nsresult HandleEventWithFrameForPresShell(nsIFrame* aFrameForPresShell,
2493                                               WidgetGUIEvent* aGUIEvent,
2494                                               nsEventStatus* aEventStatus);
2495 
2496     /**
2497      * HandleEventWithCurrentEventInfo() prepares to dispatch aEvent into the
2498      * DOM, dispatches aEvent into the DOM with using current event info of
2499      * mPresShell and notifies EventStateManager of that.
2500      *
2501      * @param aEvent                    Event to be dispatched.
2502      * @param aEventStatus              [in/out] EventStatus of aEvent.
2503      * @param aIsHandlingNativeEvent    true if aGUIEvent represents a native
2504      *                                  event.
2505      * @param aOverrideClickTarget      Override click event target.
2506      */
2507     MOZ_CAN_RUN_SCRIPT
2508     nsresult HandleEventWithCurrentEventInfo(WidgetEvent* aEvent,
2509                                              nsEventStatus* aEventStatus,
2510                                              bool aIsHandlingNativeEvent,
2511                                              nsIContent* aOverrideClickTarget);
2512 
2513     /**
2514      * HandlingTimeAccumulator() may accumulate handling time of telemetry
2515      * for each type of events.
2516      */
2517     class MOZ_STACK_CLASS HandlingTimeAccumulator final {
2518      public:
2519       HandlingTimeAccumulator() = delete;
2520       HandlingTimeAccumulator(const HandlingTimeAccumulator& aOther) = delete;
2521       HandlingTimeAccumulator(const EventHandler& aEventHandler,
2522                               const WidgetEvent* aEvent);
2523       ~HandlingTimeAccumulator();
2524 
2525      private:
2526       const EventHandler& mEventHandler;
2527       const WidgetEvent* mEvent;
2528       TimeStamp mHandlingStartTime;
2529     };
2530 
2531     /**
2532      * RecordEventPreparationPerformance() records event preparation performance
2533      * with telemetry only when aEvent is a trusted event.
2534      *
2535      * @param aEvent            The handling event which we've finished
2536      *                          preparing something to dispatch.
2537      */
2538     void RecordEventPreparationPerformance(const WidgetEvent* aEvent);
2539 
2540     /**
2541      * RecordEventHandlingResponsePerformance() records event handling response
2542      * performance with telemetry.
2543      *
2544      * @param aEvent            The handled event.
2545      */
2546     void RecordEventHandlingResponsePerformance(const WidgetEvent* aEvent);
2547 
2548     /**
2549      * PrepareToDispatchEvent() prepares to dispatch aEvent.
2550      *
2551      * @param aEvent                    The handling event.
2552      * @param aEventStatus              [in/out] The status of aEvent.
2553      * @param aTouchIsNew               [out] Set to true if the event is an
2554      *                                  eTouchMove event and it represents new
2555      *                                  touch.  Otherwise, set to false.
2556      * @return                          true if the caller can dispatch the
2557      *                                  event into the DOM.
2558      */
2559     MOZ_CAN_RUN_SCRIPT
2560     bool PrepareToDispatchEvent(WidgetEvent* aEvent,
2561                                 nsEventStatus* aEventStatus, bool* aTouchIsNew);
2562 
2563     /**
2564      * MaybeHandleKeyboardEventBeforeDispatch() may handle aKeyboardEvent
2565      * if it should do something before dispatched into the DOM.
2566      *
2567      * @param aKeyboardEvent    The handling keyboard event.
2568      */
2569     MOZ_CAN_RUN_SCRIPT
2570     void MaybeHandleKeyboardEventBeforeDispatch(
2571         WidgetKeyboardEvent* aKeyboardEvent);
2572 
2573     /**
2574      * This and the next two helper methods are used to target and position the
2575      * context menu when the keyboard shortcut is used to open it.
2576      *
2577      * If another menu is open, the context menu is opened relative to the
2578      * active menuitem within the menu, or the menu itself if no item is active.
2579      * Otherwise, if the caret is visible, the menu is opened near the caret.
2580      * Otherwise, if a selectable list such as a listbox is focused, the
2581      * current item within the menu is opened relative to this item.
2582      * Otherwise, the context menu is opened at the topleft corner of the
2583      * view.
2584      *
2585      * Returns true if the context menu event should fire and false if it should
2586      * not.
2587      */
2588     MOZ_CAN_RUN_SCRIPT
2589     bool AdjustContextMenuKeyEvent(WidgetMouseEvent* aMouseEvent);
2590 
2591     MOZ_CAN_RUN_SCRIPT
2592     bool PrepareToUseCaretPosition(nsIWidget* aEventWidget,
2593                                    LayoutDeviceIntPoint& aTargetPt);
2594 
2595     /**
2596      * Get the selected item and coordinates in device pixels relative to root
2597      * document's root view for element, first ensuring the element is onscreen.
2598      */
2599     MOZ_CAN_RUN_SCRIPT
2600     void GetCurrentItemAndPositionForElement(dom::Element* aFocusedElement,
2601                                              nsIContent** aTargetToUse,
2602                                              LayoutDeviceIntPoint& aTargetPt,
2603                                              nsIWidget* aRootWidget);
2604 
2605     nsIContent* GetOverrideClickTarget(WidgetGUIEvent* aGUIEvent,
2606                                        nsIFrame* aFrame);
2607 
2608     /**
2609      * DispatchEvent() tries to dispatch aEvent and notifies aEventStateManager
2610      * of doing it.
2611      *
2612      * @param aEventStateManager        EventStateManager which should handle
2613      *                                  the event before/after dispatching
2614      *                                  aEvent into the DOM.
2615      * @param aEvent                    The handling event.
2616      * @param aTouchIsNew               Set this to true when the message is
2617      *                                  eTouchMove and it's newly touched.
2618      *                                  Then, the "touchmove" event becomes
2619      *                                  cancelable.
2620      * @param aEventStatus              [in/out] The status of aEvent.
2621      * @param aOverrideClickTarget      Override click event target.
2622      */
2623     MOZ_CAN_RUN_SCRIPT nsresult
2624     DispatchEvent(EventStateManager* aEventStateManager, WidgetEvent* aEvent,
2625                   bool aTouchIsNew, nsEventStatus* aEventStatus,
2626                   nsIContent* aOverrideClickTarget);
2627 
2628     /**
2629      * DispatchEventToDOM() actually dispatches aEvent into the DOM tree.
2630      *
2631      * @param aEvent            Event to be dispatched into the DOM tree.
2632      * @param aEventStatus      [in/out] EventStatus of aEvent.
2633      * @param aEventCB          The callback kicked when the event moves
2634      *                          from the default group to the system group.
2635      */
2636     MOZ_CAN_RUN_SCRIPT nsresult
2637     DispatchEventToDOM(WidgetEvent* aEvent, nsEventStatus* aEventStatus,
2638                        nsPresShellEventCB* aEventCB);
2639 
2640     /**
2641      * DispatchTouchEventToDOM() dispatches touch events into the DOM tree.
2642      *
2643      * @param aEvent            The source of events to be dispatched into the
2644      *                          DOM tree.
2645      * @param aEventStatus      [in/out] EventStatus of aEvent.
2646      * @param aEventCB          The callback kicked when the events move
2647      *                          from the default group to the system group.
2648      * @param aTouchIsNew       Set this to true when the message is eTouchMove
2649      *                          and it's newly touched.  Then, the "touchmove"
2650      *                          event becomes cancelable.
2651      */
2652     MOZ_CAN_RUN_SCRIPT void DispatchTouchEventToDOM(
2653         WidgetEvent* aEvent, nsEventStatus* aEventStatus,
2654         nsPresShellEventCB* aEventCB, bool aTouchIsNew);
2655 
2656     /**
2657      * FinalizeHandlingEvent() should be called after calling DispatchEvent()
2658      * and then, this cleans up the state of mPresShell and aEvent.
2659      *
2660      * @param aEvent            The handled event.
2661      */
2662     void FinalizeHandlingEvent(WidgetEvent* aEvent);
2663 
2664     /**
2665      * AutoCurrentEventInfoSetter() pushes and pops current event info of
2666      * aEventHandler.mPresShell.
2667      */
2668     struct MOZ_STACK_CLASS AutoCurrentEventInfoSetter final {
AutoCurrentEventInfoSetterfinal2669       explicit AutoCurrentEventInfoSetter(EventHandler& aEventHandler)
2670           : mEventHandler(aEventHandler) {
2671         MOZ_DIAGNOSTIC_ASSERT(!mEventHandler.mCurrentEventInfoSetter);
2672         mEventHandler.mCurrentEventInfoSetter = this;
2673         mEventHandler.mPresShell->PushCurrentEventInfo(nullptr, nullptr);
2674       }
AutoCurrentEventInfoSetterfinal2675       AutoCurrentEventInfoSetter(EventHandler& aEventHandler, nsIFrame* aFrame,
2676                                  nsIContent* aContent)
2677           : mEventHandler(aEventHandler) {
2678         MOZ_DIAGNOSTIC_ASSERT(!mEventHandler.mCurrentEventInfoSetter);
2679         mEventHandler.mCurrentEventInfoSetter = this;
2680         mEventHandler.mPresShell->PushCurrentEventInfo(aFrame, aContent);
2681       }
AutoCurrentEventInfoSetterfinal2682       AutoCurrentEventInfoSetter(EventHandler& aEventHandler,
2683                                  EventTargetData& aEventTargetData)
2684           : mEventHandler(aEventHandler) {
2685         MOZ_DIAGNOSTIC_ASSERT(!mEventHandler.mCurrentEventInfoSetter);
2686         mEventHandler.mCurrentEventInfoSetter = this;
2687         mEventHandler.mPresShell->PushCurrentEventInfo(
2688             aEventTargetData.mFrame, aEventTargetData.mContent);
2689       }
~AutoCurrentEventInfoSetterfinal2690       ~AutoCurrentEventInfoSetter() {
2691         mEventHandler.mPresShell->PopCurrentEventInfo();
2692         mEventHandler.mCurrentEventInfoSetter = nullptr;
2693       }
2694 
2695      private:
2696       EventHandler& mEventHandler;
2697     };
2698 
2699     /**
2700      * Wrapper methods to access methods of mPresShell.
2701      */
GetPresContext()2702     nsPresContext* GetPresContext() const {
2703       return mPresShell->GetPresContext();
2704     }
GetDocument()2705     Document* GetDocument() const { return mPresShell->GetDocument(); }
FrameConstructor()2706     nsCSSFrameConstructor* FrameConstructor() const {
2707       return mPresShell->FrameConstructor();
2708     }
GetFocusedDOMWindowInOurWindow()2709     already_AddRefed<nsPIDOMWindowOuter> GetFocusedDOMWindowInOurWindow() {
2710       return mPresShell->GetFocusedDOMWindowInOurWindow();
2711     }
GetParentPresShellForEventHandling()2712     already_AddRefed<PresShell> GetParentPresShellForEventHandling() {
2713       return mPresShell->GetParentPresShellForEventHandling();
2714     }
2715     OwningNonNull<PresShell> mPresShell;
2716     AutoCurrentEventInfoSetter* mCurrentEventInfoSetter;
2717     static TimeStamp sLastInputCreated;
2718     static TimeStamp sLastInputProcessed;
2719     static StaticRefPtr<dom::Element> sLastKeyDownEventTargetElement;
2720   };
2721 
2722   PresShell* GetRootPresShell() const;
2723 
2724   nscolor GetDefaultBackgroundColorToDraw();
2725 
2726   //////////////////////////////////////////////////////////////////////////////
2727   // Approximate frame visibility tracking implementation.
2728   //////////////////////////////////////////////////////////////////////////////
2729 
2730   void UpdateApproximateFrameVisibility();
2731   void DoUpdateApproximateFrameVisibility(bool aRemoveOnly);
2732 
2733   void ClearApproximatelyVisibleFramesList(
2734       const Maybe<OnNonvisible>& aNonvisibleAction = Nothing());
2735   static void ClearApproximateFrameVisibilityVisited(nsView* aView,
2736                                                      bool aClear);
2737   static void MarkFramesInListApproximatelyVisible(const nsDisplayList& aList);
2738   void MarkFramesInSubtreeApproximatelyVisible(nsIFrame* aFrame,
2739                                                const nsRect& aRect,
2740                                                bool aRemoveOnly = false);
2741 
2742   void DecApproximateVisibleCount(
2743       VisibleFrames& aFrames,
2744       const Maybe<OnNonvisible>& aNonvisibleAction = Nothing());
2745 
2746   nsRevocableEventPtr<nsRunnableMethod<PresShell>>
2747       mUpdateApproximateFrameVisibilityEvent;
2748 
2749   // A set of frames that were visible or could be visible soon at the time
2750   // that we last did an approximate frame visibility update.
2751   VisibleFrames mApproximatelyVisibleFrames;
2752 
2753 #ifdef DEBUG
2754   MOZ_CAN_RUN_SCRIPT_BOUNDARY bool VerifyIncrementalReflow();
2755   MOZ_CAN_RUN_SCRIPT_BOUNDARY void DoVerifyReflow();
2756   void VerifyHasDirtyRootAncestor(nsIFrame* aFrame);
2757   void ShowEventTargetDebug();
2758 
2759   bool mInVerifyReflow = false;
2760   // The reflow root under which we're currently reflowing.  Null when
2761   // not in reflow.
2762   nsIFrame* mCurrentReflowRoot = nullptr;
2763 
2764   nsIFrame* mDrawEventTargetFrame = nullptr;
2765 #endif  // #ifdef DEBUG
2766 
2767   // Send, and reset, the current per tick telemetry. This includes:
2768   // * non-zero number of style and layout flushes
2769   // * non-zero ms duration spent in style and reflow since the last tick.
2770   void PingPerTickTelemetry(FlushType aFlushType);
2771 
2772  private:
2773   // IMPORTANT: The ownership implicit in the following member variables
2774   // has been explicitly checked.  If you add any members to this class,
2775   // please make the ownership explicit (pinkerton, scc).
2776 
2777   // These are the same Document and PresContext owned by the DocViewer.
2778   // we must share ownership.
2779   // mDocument and mPresContext should've never been cleared nor swapped with
2780   // another instance while PresShell instance is alive so that it's safe to
2781   // call their can-run- script methods without local RefPtr variables.
2782   RefPtr<Document> const mDocument;
2783   RefPtr<nsPresContext> const mPresContext;
2784   // The document's style set owns it but we maintain a ref, may be null.
2785   RefPtr<StyleSheet> mPrefStyleSheet;
2786   UniquePtr<nsCSSFrameConstructor> mFrameConstructor;
2787   nsViewManager* mViewManager;  // [WEAK] docViewer owns it so I don't have to
2788   RefPtr<nsFrameSelection> mSelection;
2789   // The frame selection that last took focus on this shell, which we need to
2790   // hide if we focus another selection. May or may not be the same as
2791   // `mSelection`.
2792   RefPtr<nsFrameSelection> mFocusedFrameSelection;
2793   RefPtr<nsCaret> mCaret;
2794   RefPtr<nsCaret> mOriginalCaret;
2795   RefPtr<AccessibleCaretEventHub> mAccessibleCaretEventHub;
2796   // Pointer into mFrameConstructor - this is purely so that GetRootFrame() can
2797   // be inlined:
2798   nsFrameManager* mFrameManager;
2799   WeakPtr<nsDocShell> mForwardingContainer;
2800 
2801   // The `performance.now()` value when we last started to process reflows.
2802   DOMHighResTimeStamp mLastReflowStart{0.0};
2803 
2804   // At least on Win32 and Mac after interupting a reflow we need to post
2805   // the resume reflow event off a timer to avoid event starvation because
2806   // posted messages are processed before other messages when the modal
2807   // moving/sizing loop is running, see bug 491700 for details.
2808   nsCOMPtr<nsITimer> mReflowContinueTimer;
2809 
2810 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
2811   // We track allocated pointers in a debug-only hashtable to assert against
2812   // missing/double frees.
2813   nsTHashSet<void*> mAllocatedPointers;
2814 #endif
2815 
2816   // A list of stack weak frames. This is a pointer to the last item in the
2817   // list.
2818   AutoWeakFrame* mAutoWeakFrames;
2819 
2820   // A hash table of heap allocated weak frames.
2821   nsTHashSet<WeakFrame*> mWeakFrames;
2822 
2823   class DirtyRootsList {
2824    public:
2825     // Add a dirty root.
2826     void Add(nsIFrame* aFrame);
2827     // Remove this frame if present.
2828     void Remove(nsIFrame* aFrame);
2829     // Remove and return one of the shallowest dirty roots from the list.
2830     // (If two roots are at the same depth, order is indeterminate.)
2831     nsIFrame* PopShallowestRoot();
2832     // Remove all dirty roots.
2833     void Clear();
2834     // Is this frame one of the dirty roots?
2835     bool Contains(nsIFrame* aFrame) const;
2836     // Are there no dirty roots?
2837     bool IsEmpty() const;
2838     // Is the given frame an ancestor of any dirty root?
2839     bool FrameIsAncestorOfDirtyRoot(nsIFrame* aFrame) const;
2840 
2841    private:
2842     struct FrameAndDepth {
2843       nsIFrame* mFrame;
2844       const uint32_t mDepth;
2845 
2846       // Easy conversion to nsIFrame*, as it's the most likely need.
2847       operator nsIFrame*() const { return mFrame; }
2848 
2849       // Used to sort by reverse depths, i.e., deeper < shallower.
2850       class CompareByReverseDepth {
2851        public:
EqualsFrameAndDepth2852         bool Equals(const FrameAndDepth& aA, const FrameAndDepth& aB) const {
2853           return aA.mDepth == aB.mDepth;
2854         }
LessThanFrameAndDepth2855         bool LessThan(const FrameAndDepth& aA, const FrameAndDepth& aB) const {
2856           // Reverse depth! So '>' instead of '<'.
2857           return aA.mDepth > aB.mDepth;
2858         }
2859       };
2860     };
2861     // List of all known dirty roots, sorted by decreasing depths.
2862     nsTArray<FrameAndDepth> mList;
2863   };
2864 
2865   // Reflow roots that need to be reflowed.
2866   DirtyRootsList mDirtyRoots;
2867 
2868   // These two fields capture call stacks of any changes that require a restyle
2869   // or a reflow. Only the first change per restyle / reflow is recorded (the
2870   // one that caused a call to SetNeedStyleFlush() / SetNeedLayoutFlush()).
2871   UniquePtr<ProfileChunkedBuffer> mStyleCause;
2872   UniquePtr<ProfileChunkedBuffer> mReflowCause;
2873 
2874   nsTArray<UniquePtr<DelayedEvent>> mDelayedEvents;
2875 
2876   nsRevocableEventPtr<nsSynthMouseMoveEvent> mSynthMouseMoveEvent;
2877 
2878   TouchManager mTouchManager;
2879 
2880   RefPtr<ZoomConstraintsClient> mZoomConstraintsClient;
2881   RefPtr<GeckoMVMContext> mMVMContext;
2882   RefPtr<MobileViewportManager> mMobileViewportManager;
2883 
2884   // This timer controls painting suppression.  Until it fires
2885   // or all frames are constructed, we won't paint anything but
2886   // our <body> background and scrollbars.
2887   nsCOMPtr<nsITimer> mPaintSuppressionTimer;
2888 
2889   nsCOMPtr<nsITimer> mDelayedPaintTimer;
2890 
2891   // Information about live content (which still stay in DOM tree).
2892   // Used in case we need re-dispatch event after sending pointer event,
2893   // when target of pointer event was deleted during executing user handlers.
2894   nsCOMPtr<nsIContent> mPointerEventTarget;
2895 
2896   nsCOMPtr<nsIContent> mLastAnchorScrolledTo;
2897 
2898   // Information needed to properly handle scrolling content into view if the
2899   // pre-scroll reflow flush can be interrupted.  mContentToScrollTo is non-null
2900   // between the initial scroll attempt and the first time we finish processing
2901   // all our dirty roots.  mContentToScrollTo has a content property storing the
2902   // details for the scroll operation, see ScrollIntoViewData above.
2903   nsCOMPtr<nsIContent> mContentToScrollTo;
2904 
2905 #ifdef ACCESSIBILITY
2906   a11y::DocAccessible* mDocAccessible;
2907 #endif  // #ifdef ACCESSIBILITY
2908 
2909   nsIFrame* mCurrentEventFrame;
2910   nsCOMPtr<nsIContent> mCurrentEventContent;
2911   nsTArray<nsIFrame*> mCurrentEventFrameStack;
2912   nsCOMArray<nsIContent> mCurrentEventContentStack;
2913   // Set of frames that we should mark with NS_FRAME_HAS_DIRTY_CHILDREN after
2914   // we finish reflowing mCurrentReflowRoot.
2915   nsTHashSet<nsIFrame*> mFramesToDirty;
2916   nsTHashSet<nsIScrollableFrame*> mPendingScrollAnchorSelection;
2917   nsTHashSet<nsIScrollableFrame*> mPendingScrollAnchorAdjustment;
2918 
2919   nsCallbackEventRequest* mFirstCallbackEventRequest = nullptr;
2920   nsCallbackEventRequest* mLastCallbackEventRequest = nullptr;
2921 
2922   // This is used for synthetic mouse events that are sent when what is under
2923   // the mouse pointer may have changed without the mouse moving (eg scrolling,
2924   // change to the document contents).
2925   // It is set only on a presshell for a root document, this value represents
2926   // the last observed location of the mouse relative to that root document,
2927   // in visual coordinates. It is set to (NS_UNCONSTRAINEDSIZE,
2928   // NS_UNCONSTRAINEDSIZE) if the mouse isn't over our window or there is no
2929   // last observed mouse location for some reason.
2930   nsPoint mMouseLocation;
2931   // This is an APZ state variable that tracks the target guid for the last
2932   // mouse event that was processed (corresponding to mMouseLocation). This is
2933   // needed for the synthetic mouse events.
2934   layers::ScrollableLayerGuid mMouseEventTargetGuid;
2935 
2936   // Only populated on root content documents.
2937   nsSize mVisualViewportSize;
2938 
2939   // The focus information needed for async keyboard scrolling
2940   FocusTarget mAPZFocusTarget;
2941 
2942   using Arena = nsPresArena<8192, ArenaObjectID, eArenaObjectID_COUNT>;
2943   Arena mFrameArena;
2944 
2945   Maybe<nsPoint> mVisualViewportOffset;
2946 
2947   // A pending visual scroll offset that we will ask APZ to scroll to
2948   // during the next transaction. Cleared when we send the transaction.
2949   // Only applicable to the RCD pres shell.
2950   Maybe<VisualScrollUpdate> mPendingVisualScrollUpdate;
2951 
2952   // Used to force allocation and rendering of proportionally more or
2953   // less pixels in both dimensions.
2954   Maybe<float> mResolution;
2955   ResolutionChangeOrigin mLastResolutionChangeOrigin;
2956 
2957   TimeStamp mLoadBegin;  // used to time loads
2958 
2959   TimeStamp mLastOSWake;
2960 
2961   // Count of the number of times this presshell has been painted to a window.
2962   uint64_t mPaintCount;
2963 
2964   // The focus sequence number of the last processed input event
2965   uint64_t mAPZFocusSequenceNumber;
2966 
2967   nscoord mLastAnchorScrollPositionY = 0;
2968 
2969   // Most recent canvas background color.
2970   nscolor mCanvasBackgroundColor;
2971 
2972   int32_t mActiveSuppressDisplayport;
2973 
2974   uint32_t mPresShellId;
2975 
2976   // Cached font inflation values. This is done to prevent changing of font
2977   // inflation until a page is reloaded.
2978   uint32_t mFontSizeInflationEmPerLine;
2979   uint32_t mFontSizeInflationMinTwips;
2980   uint32_t mFontSizeInflationLineThreshold;
2981 
2982   // Can be multiple of nsISelectionDisplay::DISPLAY_*.
2983   int16_t mSelectionFlags;
2984 
2985   // This is used to protect ourselves from triggering reflow while in the
2986   // middle of frame construction and the like... it really shouldn't be
2987   // needed, one hopes, but it is for now.
2988   uint16_t mChangeNestCount;
2989 
2990   // Flags controlling how our document is rendered.  These persist
2991   // between paints and so are tied with retained layer pixels.
2992   // PresShell flushes retained layers when the rendering state
2993   // changes in a way that prevents us from being able to (usefully)
2994   // re-use old pixels.
2995   RenderingStateFlags mRenderingStateFlags;
2996 
2997   // Whether we're currently under a FlushPendingNotifications.
2998   // This is used to handle flush reentry correctly.
2999   // NOTE: This can't be a bitfield since AutoRestore has a reference to this
3000   // variable.
3001   bool mInFlush;
3002 
3003   bool mCaretEnabled : 1;
3004 
3005   // True if a layout flush might not be a no-op
3006   bool mNeedLayoutFlush : 1;
3007 
3008   // True if a style flush might not be a no-op
3009   bool mNeedStyleFlush : 1;
3010 
3011   // True if there are throttled animations that would be processed when
3012   // performing a flush with mFlushAnimations == true.
3013   bool mNeedThrottledAnimationFlush : 1;
3014 
3015   bool mVisualViewportSizeSet : 1;
3016 
3017   bool mDidInitialize : 1;
3018   bool mIsDestroying : 1;
3019   bool mIsReflowing : 1;
3020   bool mIsObservingDocument : 1;
3021 
3022   // Whether we shouldn't ever get to FlushPendingNotifications. This flag is
3023   // meant only to sanity-check / assert that FlushPendingNotifications doesn't
3024   // happen during certain periods of time. It shouldn't be made public nor used
3025   // for other purposes.
3026   bool mForbiddenToFlush : 1;
3027 
3028   // We've been disconnected from the document.  We will refuse to paint the
3029   // document until either our timer fires or all frames are constructed.
3030   bool mIsDocumentGone : 1;
3031   bool mHaveShutDown : 1;
3032 
3033   // For all documents we initially lock down painting.
3034   bool mPaintingSuppressed : 1;
3035 
3036   bool mLastRootReflowHadUnconstrainedBSize : 1;
3037 
3038   // Indicates that it is safe to unlock painting once all pending reflows
3039   // have been processed.
3040   bool mShouldUnsuppressPainting : 1;
3041 
3042   bool mIgnoreFrameDestruction : 1;
3043 
3044   bool mIsActive : 1;
3045   bool mFrozen : 1;
3046   bool mIsFirstPaint : 1;
3047   bool mObservesMutationsForPrint : 1;
3048 
3049   // Whether the most recent interruptible reflow was actually interrupted:
3050   bool mWasLastReflowInterrupted : 1;
3051 
3052   // True if we're observing the refresh driver for style flushes.
3053   bool mObservingStyleFlushes : 1;
3054 
3055   // True if we're observing the refresh driver for layout flushes, that is, if
3056   // we have a reflow scheduled.
3057   //
3058   // Guaranteed to be false if mReflowContinueTimer is non-null.
3059   bool mObservingLayoutFlushes : 1;
3060 
3061   bool mResizeEventPending : 1;
3062 
3063   bool mFontSizeInflationForceEnabled : 1;
3064   bool mFontSizeInflationDisabledInMasterProcess : 1;
3065   bool mFontSizeInflationEnabled : 1;
3066 
3067   // If a document belongs to an invisible DocShell, this flag must be set
3068   // to true, so we can avoid any paint calls for widget related to this
3069   // presshell.
3070   bool mIsNeverPainting : 1;
3071 
3072   // Whether the most recent change to the pres shell resolution was
3073   // originated by the main thread.
3074   bool mResolutionUpdated : 1;
3075 
3076   // True if the resolution has been ever changed by APZ.
3077   bool mResolutionUpdatedByApz : 1;
3078 
3079   // Whether this presshell is hidden by 'vibility:hidden' on an ancestor
3080   // nsSubDocumentFrame.
3081   bool mUnderHiddenEmbedderElement : 1;
3082 
3083   bool mDocumentLoading : 1;
3084   bool mNoDelayedMouseEvents : 1;
3085   bool mNoDelayedKeyEvents : 1;
3086 
3087   bool mApproximateFrameVisibilityVisited : 1;
3088 
3089   bool mNextPaintCompressed : 1;
3090 
3091   bool mHasCSSBackgroundColor : 1;
3092 
3093   // Whether the last chrome-only escape key event is consumed.
3094   bool mIsLastChromeOnlyEscapeKeyConsumed : 1;
3095 
3096   // Whether the widget has received a paint message yet.
3097   bool mHasReceivedPaintMessage : 1;
3098 
3099   bool mIsLastKeyDownCanceled : 1;
3100 
3101   // Whether we have ever handled a user input event
3102   bool mHasHandledUserInput : 1;
3103 
3104   // Whether we should dispatch keypress events even for non-printable keys
3105   // for keeping backward compatibility.
3106   bool mForceDispatchKeyPressEventsForNonPrintableKeys : 1;
3107   // Whether we should set keyCode or charCode value of keypress events whose
3108   // value is zero to the other value or not.  When this is set to true, we
3109   // should keep using legacy keyCode and charCode values (i.e., one of them
3110   // is always 0).
3111   bool mForceUseLegacyKeyCodeAndCharCodeValues : 1;
3112   // Whether mForceDispatchKeyPressEventsForNonPrintableKeys and
3113   // mForceUseLegacyKeyCodeAndCharCodeValues are initialized.
3114   bool mInitializedWithKeyPressEventDispatchingBlacklist : 1;
3115 
3116   // Whether we should dispatch click events for non-primary mouse buttons.
3117   bool mForceUseLegacyNonPrimaryDispatch : 1;
3118   // Whether mForceUseLegacyNonPrimaryDispatch is initialised.
3119   bool mInitializedWithClickEventDispatchingBlacklist : 1;
3120 
3121   // Set to true if mMouseLocation is set by a mouse event which is synthesized
3122   // for tests.
3123   bool mMouseLocationWasSetBySynthesizedMouseEventForTests : 1;
3124 
3125   struct CapturingContentInfo final {
CapturingContentInfofinal3126     CapturingContentInfo()
3127         : mRemoteTarget(nullptr),
3128           mAllowed(false),
3129           mPointerLock(false),
3130           mRetargetToElement(false),
3131           mPreventDrag(false) {}
3132 
3133     // capture should only be allowed during a mousedown event
3134     StaticRefPtr<nsIContent> mContent;
3135     dom::BrowserParent* mRemoteTarget;
3136     bool mAllowed;
3137     bool mPointerLock;
3138     bool mRetargetToElement;
3139     bool mPreventDrag;
3140   };
3141   static CapturingContentInfo sCapturingContentInfo;
3142 
3143   static bool sDisableNonTestMouseEvents;
3144 
3145   static bool sProcessInteractable;
3146 
3147   layout_telemetry::Data mLayoutTelemetry;
3148 };
3149 
3150 NS_DEFINE_STATIC_IID_ACCESSOR(PresShell, NS_PRESSHELL_IID)
3151 
3152 }  // namespace mozilla
3153 
3154 #endif  // mozilla_PresShell_h
3155