author David Anderson <>
Thu, 18 Jun 2015 13:42:39 -0700
changeset 249637 451e24d7ed64df2afbd669a7a9732f520f7e9a3f
parent 249376 dc009c8ce7c31d516969ad9db32b24a395b78bc0
child 249865 a7c6c582c96f23f250259be16ebd01ac34357d46
permissions -rw-r--r--
Add an observer service notification for the first widget paint message. (bug 1173117 part 2, r=roc)

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=2 sw=2 et tw=78:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at
 * This Original Code has been modified by IBM Corporation.
 * Modifications made by IBM described herein are
 * Copyright (c) International Business Machines
 * Corporation, 2000
 * Modifications to Mozilla code or documentation
 * identified per MPL Section 3.3
 * Date         Modified by     Description of modification
 * 05/03/2000   IBM Corp.       Observer events for reflow states

/* a presentation of a document, part 2 */

#ifndef nsPresShell_h_
#define nsPresShell_h_

#include "nsIPresShell.h"
#include "nsStubDocumentObserver.h"
#include "nsISelectionController.h"
#include "nsIObserver.h"
#include "nsWeakReference.h"
#include "nsCRT.h"
#include "nsAutoPtr.h"
#include "nsIWidget.h"
#include "nsStyleSet.h"
#include "nsContentUtils.h" // For AddScriptBlocker().
#include "nsRefreshDriver.h"
#include "TouchManager.h"
#include "mozilla/Attributes.h"
#include "mozilla/EventForwards.h"
#include "mozilla/MemoryReporting.h"
#include "ZoomConstraintsClient.h"

class nsRange;

struct RangePaintInfo;
struct nsCallbackEventRequest;
class ReflowCountMgr;

class nsPresShellEventCB;
class nsAutoCauseReflowNotifier;

namespace mozilla {
class CSSStyleSheet;
class EventDispatchingCallback;
} // namespace mozilla

// 250ms.  This is actually pref-controlled, but we use this value if we fail
// to get the pref for any reason.

class PresShell final : public nsIPresShell,
                        public nsStubDocumentObserver,
                        public nsISelectionController,
                        public nsIObserver,
                        public nsSupportsWeakReference


  // nsISupports

  // Touch caret preference
  static bool TouchCaretPrefEnabled();

  // Selection caret preference
  static bool SelectionCaretPrefEnabled();

  static bool AccessibleCaretEnabled();

  // BeforeAfterKeyboardEvent preference
  static bool BeforeAfterKeyboardEventEnabled();

  void Init(nsIDocument* aDocument, nsPresContext* aPresContext,
            nsViewManager* aViewManager, nsStyleSet* aStyleSet,
            nsCompatibility aCompatMode);
  virtual void Destroy() override;
  virtual void MakeZombie() override;

  virtual void UpdatePreferenceStyles() override;

  NS_IMETHOD GetSelection(SelectionType aType, nsISelection** aSelection) override;
  virtual mozilla::dom::Selection* GetCurrentSelection(SelectionType aType) override;

  NS_IMETHOD SetDisplaySelection(int16_t aToggle) override;
  NS_IMETHOD GetDisplaySelection(int16_t *aToggle) override;
  NS_IMETHOD ScrollSelectionIntoView(SelectionType aType, SelectionRegion aRegion,
                                     int16_t aFlags) override;
  NS_IMETHOD RepaintSelection(SelectionType aType) override;

  virtual void BeginObservingDocument() override;
  virtual void EndObservingDocument() override;
  virtual nsresult Initialize(nscoord aWidth, nscoord aHeight) override;
  virtual nsresult ResizeReflow(nscoord aWidth, nscoord aHeight) override;
  virtual nsresult ResizeReflowOverride(nscoord aWidth, nscoord aHeight) override;
  virtual nsIPageSequenceFrame* GetPageSequenceFrame() const override;
  virtual nsCanvasFrame* GetCanvasFrame() const override;
  virtual nsIFrame* GetRealPrimaryFrameFor(nsIContent* aContent) const override;

  virtual nsIFrame* GetPlaceholderFrameFor(nsIFrame* aFrame) const override;
  virtual void FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty,
                                            nsFrameState aBitToAdd) override;
  virtual void FrameNeedsToContinueReflow(nsIFrame *aFrame) override;
  virtual void CancelAllPendingReflows() override;
  virtual bool IsSafeToFlush() const override;
  virtual void FlushPendingNotifications(mozFlushType aType) override;
  virtual void FlushPendingNotifications(mozilla::ChangesToFlush aType) override;
  virtual void DestroyFramesFor(nsIContent*  aContent,
                                nsIContent** aDestroyedFramesFor) override;
  virtual void CreateFramesFor(nsIContent* aContent) override;

   * Recreates the frames for a node
  virtual nsresult RecreateFramesFor(nsIContent* aContent) override;

   * Post a callback that should be handled after reflow has finished.
  virtual nsresult PostReflowCallback(nsIReflowCallback* aCallback) override;
  virtual void CancelReflowCallback(nsIReflowCallback* aCallback) override;

  virtual void ClearFrameRefs(nsIFrame* aFrame) override;
  virtual already_AddRefed<gfxContext> CreateReferenceRenderingContext() override;
  virtual nsresult GoToAnchor(const nsAString& aAnchorName, bool aScroll,
                              uint32_t aAdditionalScrollFlags = 0) override;
  virtual nsresult ScrollToAnchor() override;

  virtual nsresult ScrollContentIntoView(nsIContent* aContent,
                                                     ScrollAxis  aVertical,
                                                     ScrollAxis  aHorizontal,
                                                     uint32_t    aFlags) override;
  virtual bool ScrollFrameRectIntoView(nsIFrame*     aFrame,
                                       const nsRect& aRect,
                                       ScrollAxis    aVertical,
                                       ScrollAxis    aHorizontal,
                                       uint32_t      aFlags) override;
  virtual nsRectVisibility GetRectVisibility(nsIFrame *aFrame,
                                             const nsRect &aRect,
                                             nscoord aMinTwips) const override;

  virtual void SetIgnoreFrameDestruction(bool aIgnore) override;
  virtual void NotifyDestroyingFrame(nsIFrame* aFrame) override;

  virtual nsresult CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState) override;

  virtual void UnsuppressPainting() override;

  virtual nsresult GetAgentStyleSheets(nsCOMArray<nsIStyleSheet>& aSheets) override;
  virtual nsresult SetAgentStyleSheets(const nsCOMArray<nsIStyleSheet>& aSheets) override;

  virtual nsresult AddOverrideStyleSheet(nsIStyleSheet *aSheet) override;
  virtual nsresult RemoveOverrideStyleSheet(nsIStyleSheet *aSheet) override;

  virtual nsresult HandleEventWithTarget(
                                 mozilla::WidgetEvent* aEvent,
                                 nsIFrame* aFrame,
                                 nsIContent* aContent,
                                 nsEventStatus* aStatus) override;
  virtual nsIFrame* GetEventTargetFrame() override;
  virtual already_AddRefed<nsIContent> GetEventTargetContent(
                                                     mozilla::WidgetEvent* aEvent) override;

  virtual void NotifyCounterStylesAreDirty() override;

  virtual nsresult ReconstructFrames(void) override;
  virtual void Freeze() override;
  virtual void Thaw() override;
  virtual void FireOrClearDelayedEvents(bool aFireEvents) override;

  virtual nsresult RenderDocument(const nsRect& aRect, uint32_t aFlags,
                                              nscolor aBackgroundColor,
                                              gfxContext* aThebesContext) override;

  virtual mozilla::TemporaryRef<SourceSurface>
  RenderNode(nsIDOMNode* aNode,
             nsIntRegion* aRegion,
             nsIntPoint& aPoint,
             nsIntRect* aScreenRect) override;

  virtual mozilla::TemporaryRef<SourceSurface>
  RenderSelection(nsISelection* aSelection,
                  nsIntPoint& aPoint,
                  nsIntRect* aScreenRect) override;

  virtual already_AddRefed<nsPIDOMWindow> GetRootWindow() override;

  virtual LayerManager* GetLayerManager() override;

  virtual bool AsyncPanZoomEnabled() override;

  virtual void SetIgnoreViewportScrolling(bool aIgnore) override;

  virtual nsresult SetResolution(float aResolution) override {
    return SetResolutionImpl(aResolution, /* aScaleToResolution = */ false);
  virtual nsresult SetResolutionAndScaleTo(float aResolution) override {
    return SetResolutionImpl(aResolution, /* aScaleToResolution = */ true);
  virtual bool ScaleToResolution() const override;
  virtual float GetCumulativeResolution() override;

  //nsIViewObserver interface

  virtual void Paint(nsView* aViewToPaint, const nsRegion& aDirtyRegion,
                     uint32_t aFlags) override;
  virtual nsresult HandleEvent(nsIFrame* aFrame,
                               mozilla::WidgetGUIEvent* aEvent,
                               bool aDontRetargetEvents,
                               nsEventStatus* aEventStatus,
                               nsIContent** aTargetContent) override;
  virtual nsresult HandleDOMEventWithTarget(
                                 nsIContent* aTargetContent,
                                 mozilla::WidgetEvent* aEvent,
                                 nsEventStatus* aStatus) override;
  virtual nsresult HandleDOMEventWithTarget(nsIContent* aTargetContent,
                                                        nsIDOMEvent* aEvent,
                                                        nsEventStatus* aStatus) override;
  virtual bool ShouldIgnoreInvalidation() override;
  virtual void WillPaint() override;
  virtual void WillPaintWindow() override;
  virtual void DidPaintWindow() override;
  virtual void ScheduleViewManagerFlush(PaintType aType = PAINT_DEFAULT) override;
  virtual void DispatchSynthMouseMove(mozilla::WidgetGUIEvent* aEvent,
                                      bool aFlushOnHoverChange) override;
  virtual void ClearMouseCaptureOnView(nsView* aView) override;
  virtual bool IsVisible() override;

  // touch caret
  virtual already_AddRefed<mozilla::TouchCaret> GetTouchCaret() const override;
  virtual mozilla::dom::Element* GetTouchCaretElement() const override;
  // selection caret
  virtual already_AddRefed<mozilla::SelectionCarets> GetSelectionCarets() const override;
  virtual mozilla::dom::Element* GetSelectionCaretsStartElement() const override;
  virtual mozilla::dom::Element* GetSelectionCaretsEndElement() const override;

  virtual already_AddRefed<mozilla::AccessibleCaretEventHub> GetAccessibleCaretEventHub() const override;

  // caret handling
  virtual already_AddRefed<nsCaret> GetCaret() const override;
  NS_IMETHOD SetCaretEnabled(bool aInEnable) override;
  NS_IMETHOD SetCaretReadOnly(bool aReadOnly) override;
  NS_IMETHOD GetCaretEnabled(bool *aOutEnabled) override;
  NS_IMETHOD SetCaretVisibilityDuringSelection(bool aVisibility) override;
  NS_IMETHOD GetCaretVisible(bool *_retval) override;
  virtual void SetCaret(nsCaret *aNewCaret) override;
  virtual void RestoreCaret() override;

  NS_IMETHOD SetSelectionFlags(int16_t aInEnable) override;
  NS_IMETHOD GetSelectionFlags(int16_t *aOutEnable) override;

  // nsISelectionController

  NS_IMETHOD PhysicalMove(int16_t aDirection, int16_t aAmount, bool aExtend) override;
  NS_IMETHOD CharacterMove(bool aForward, bool aExtend) override;
  NS_IMETHOD CharacterExtendForDelete() override;
  NS_IMETHOD CharacterExtendForBackspace() override;
  NS_IMETHOD WordMove(bool aForward, bool aExtend) override;
  NS_IMETHOD WordExtendForDelete(bool aForward) override;
  NS_IMETHOD LineMove(bool aForward, bool aExtend) override;
  NS_IMETHOD IntraLineMove(bool aForward, bool aExtend) override;
  NS_IMETHOD PageMove(bool aForward, bool aExtend) override;
  NS_IMETHOD ScrollPage(bool aForward) override;
  NS_IMETHOD ScrollLine(bool aForward) override;
  NS_IMETHOD ScrollCharacter(bool aRight) override;
  NS_IMETHOD CompleteScroll(bool aForward) override;
  NS_IMETHOD CompleteMove(bool aForward, bool aExtend) override;
  NS_IMETHOD SelectAll() override;
  NS_IMETHOD CheckVisibility(nsIDOMNode *node, int16_t startOffset, int16_t EndOffset, bool *_retval) override;
  virtual nsresult CheckVisibilityContent(nsIContent* aNode, int16_t aStartOffset,
                                          int16_t aEndOffset, bool* aRetval) override;

  NS_IMETHOD GetSelectionCaretsVisibility(bool* aOutVisibility) override;
  NS_IMETHOD SetSelectionCaretsVisibility(bool aVisibility) override;

  // nsIDocumentObserver

  // nsIMutationObserver


  virtual void DumpReflows() override;
  virtual void CountReflows(const char * aName, nsIFrame * aFrame) override;
  virtual void PaintCount(const char * aName,
                                      nsRenderingContext* aRenderingContext,
                                      nsPresContext* aPresContext,
                                      nsIFrame * aFrame,
                                      const nsPoint& aOffset,
                                      uint32_t aColor) override;
  virtual void SetPaintFrameCount(bool aOn) override;
  virtual bool IsPaintingFrameCounts() override;

#ifdef DEBUG
  virtual void ListStyleContexts(nsIFrame *aRootFrame, FILE *out,
                                 int32_t aIndent = 0) override;

  virtual void ListStyleSheets(FILE *out, int32_t aIndent = 0) override;
  virtual void VerifyStyleTree() override;

  static PRLogModuleInfo* gLog;

  virtual void DisableNonTestMouseEvents(bool aDisable) override;

  virtual void UpdateCanvasBackground() override;

  virtual void AddCanvasBackgroundColorItem(nsDisplayListBuilder& aBuilder,
                                            nsDisplayList& aList,
                                            nsIFrame* aFrame,
                                            const nsRect& aBounds,
                                            nscolor aBackstopColor,
                                            uint32_t aFlags) override;

  virtual void AddPrintPreviewBackgroundItem(nsDisplayListBuilder& aBuilder,
                                             nsDisplayList& aList,
                                             nsIFrame* aFrame,
                                             const nsRect& aBounds) override;

  virtual nscolor ComputeBackstopColor(nsView* aDisplayRoot) override;

  virtual nsresult SetIsActive(bool aIsActive) override;

  virtual bool GetIsViewportOverridden() override { return mViewportOverridden; }

  virtual bool IsLayoutFlushObserver() override
    return GetPresContext()->RefreshDriver()->

  virtual void LoadComplete() override;

  void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
                              nsArenaMemoryStats *aArenaObjectsSize,
                              size_t *aPresShellSize,
                              size_t *aStyleSetsSize,
                              size_t *aTextRunsSize,
                              size_t *aPresContextSize) override;
  size_t SizeOfTextRuns(mozilla::MallocSizeOf aMallocSizeOf) const;

  virtual void AddInvalidateHiddenPresShellObserver(nsRefreshDriver *aDriver) override;

  // This data is stored as a content property (nsGkAtoms::scrolling) on
  // mContentToScrollTo when we have a pending ScrollIntoView.
  struct ScrollIntoViewData {
    ScrollAxis mContentScrollVAxis;
    ScrollAxis mContentScrollHAxis;
    uint32_t   mContentToScrollToFlags;

  virtual void ScheduleImageVisibilityUpdate() override;

  virtual void RebuildImageVisibilityDisplayList(const nsDisplayList& aList) override;
  virtual void RebuildImageVisibility(nsRect* aRect = nullptr) override;

  virtual void EnsureImageInVisibleList(nsIImageLoadingContent* aImage) override;

  virtual void RemoveImageFromVisibleList(nsIImageLoadingContent* aImage) override;

  virtual bool AssumeAllImagesVisible() override;

  virtual void RecordShadowStyleChange(mozilla::dom::ShadowRoot* aShadowRoot) override;

  virtual void DispatchAfterKeyboardEvent(nsINode* aTarget,
                                          const mozilla::WidgetKeyboardEvent& aEvent,
                                          bool aEmbeddedCancelled) override;

  void SetNextPaintCompressed() { mNextPaintCompressed = true; }

  virtual ~PresShell();

  void HandlePostedReflowCallbacks(bool aInterruptible);
  void CancelPostedReflowCallbacks();

  void UnsuppressAndInvalidate();

  void WillCauseReflow() {
  nsresult DidCauseReflow();
  friend class nsAutoCauseReflowNotifier;

  nsresult DispatchEventToDOM(mozilla::WidgetEvent* aEvent,
                              nsEventStatus* aStatus,
                              nsPresShellEventCB* aEventCB);
  void DispatchTouchEventToDOM(mozilla::WidgetEvent* aEvent,
                               nsEventStatus* aStatus,
                               nsPresShellEventCB* aEventCB,
                               bool aTouchIsNew);

  void     WillDoReflow();

   * Callback handler for whether reflow happened.
   * @param aInterruptible Whether or not reflow interruption is allowed.
   * @param aWasInterrupted Whether or not the reflow was interrupted earlier.
  void     DidDoReflow(bool aInterruptible, bool aWasInterrupted);
  // ProcessReflowCommands returns whether we processed all our dirty roots
  // without interruptions.
  bool     ProcessReflowCommands(bool aInterruptible);
  // MaybeScheduleReflow checks if posting a reflow is needed, then checks if
  // the last reflow was interrupted. In the interrupted case ScheduleReflow is
  // called off a timer, otherwise it is called directly.
  void     MaybeScheduleReflow();
  // Actually schedules a reflow.  This should only be called by
  // MaybeScheduleReflow and the reflow timer ScheduleReflowOffTimer
  // sets up.
  void     ScheduleReflow();

  // Reflow regardless of whether the override bit has been set.
  nsresult ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight);

  // DoReflow returns whether the reflow finished without interruption
  bool DoReflow(nsIFrame* aFrame, bool aInterruptible);
#ifdef DEBUG
  void DoVerifyReflow();
  void VerifyHasDirtyRootAncestor(nsIFrame* aFrame);

  // Helper for ScrollContentIntoView
  void DoScrollContentIntoView();

   * Initialize cached font inflation preference values and do an initial
   * computation to determine if font inflation is enabled.
   * @see nsLayoutUtils::sFontSizeInflationEmPerLine
   * @see nsLayoutUtils::sFontSizeInflationMinTwips
   * @see nsLayoutUtils::sFontSizeInflationLineThreshold
  void SetupFontInflation();

  friend struct AutoRenderingStateSaveRestore;
  friend struct RenderingState;

  struct RenderingState {
    explicit RenderingState(PresShell* aPresShell)
      : mResolution(aPresShell->mResolution)
      , mRenderFlags(aPresShell->mRenderFlags)
    { }
    float mResolution;
    RenderFlags mRenderFlags;

  struct AutoSaveRestoreRenderingState {
    explicit AutoSaveRestoreRenderingState(PresShell* aPresShell)
      : mPresShell(aPresShell)
      , mOldState(aPresShell)

      mPresShell->mRenderFlags = mOldState.mRenderFlags;
      mPresShell->mResolution = mOldState.mResolution;

    PresShell* mPresShell;
    RenderingState mOldState;
  static RenderFlags ChangeFlag(RenderFlags aFlags, bool aOnOff,
                                eRenderFlag aFlag)
    return aOnOff ? (aFlags | aFlag) : (aFlag & ~aFlag);

  void SetRenderingState(const RenderingState& aState);

  friend class nsPresShellEventCB;

  bool mCaretEnabled;
#ifdef DEBUG
  nsStyleSet* CloneStyleSet(nsStyleSet* aSet);
  bool VerifyIncrementalReflow();
  bool mInVerifyReflow;
  void ShowEventTargetDebug();

  void RecordStyleSheetChange(nsIStyleSheet* aStyleSheet);

  void RemovePreferenceStyles();

  // methods for painting a range to an offscreen buffer

  // given a display list, clip the items within the list to
  // the range
  nsRect ClipListToRange(nsDisplayListBuilder *aBuilder,
                         nsDisplayList* aList,
                         nsRange* aRange);

  // create a RangePaintInfo for the range aRange containing the
  // display list needed to paint the range to a surface
  RangePaintInfo* CreateRangePaintInfo(nsIDOMRange* aRange,
                                       nsRect& aSurfaceRect,
                                       bool aForPrimarySelection);

   * Paint the items to a new surface and return it.
   * aSelection - selection being painted, if any
   * aRegion - clip region, if any
   * aArea - area that the surface occupies, relative to the root frame
   * aPoint - reference point, typically the mouse position
   * aScreenRect - [out] set to the area of the screen the painted area should
   *               be displayed at
  PaintRangePaintInfo(nsTArray<nsAutoPtr<RangePaintInfo> >* aItems,
                      nsISelection* aSelection,
                      nsIntRegion* aRegion,
                      nsRect aArea,
                      nsIntPoint& aPoint,
                      nsIntRect* aScreenRect);

   * Methods to handle changes to user and UA sheet lists that we get
   * notified about.
  void AddUserSheet(nsISupports* aSheet);
  void AddAgentSheet(nsISupports* aSheet);
  void AddAuthorSheet(nsISupports* aSheet);
  void RemoveSheet(nsStyleSet::sheetType aType, nsISupports* aSheet);

  // Hide a view if it is a popup
  void HideViewIfPopup(nsView* aView);

  // Utility method to restore the root scrollframe state
  void RestoreRootScrollPosition();

  void MaybeReleaseCapturingContent();

  nsresult HandleRetargetedEvent(mozilla::WidgetEvent* aEvent,
                                 nsEventStatus* aStatus,
                                 nsIContent* aTarget)
    PushCurrentEventInfo(nullptr, nullptr);
    mCurrentEventContent = aTarget;
    nsresult rv = NS_OK;
    if (GetCurrentEventFrame()) {
      rv = HandleEventInternal(aEvent, aStatus);
    return rv;

  class DelayedEvent
    virtual ~DelayedEvent() { }
    virtual void Dispatch() { }

  class DelayedInputEvent : public DelayedEvent
    virtual void Dispatch() override;

    virtual ~DelayedInputEvent();

    mozilla::WidgetInputEvent* mEvent;

  class DelayedMouseEvent : public DelayedInputEvent
    explicit DelayedMouseEvent(mozilla::WidgetMouseEvent* aEvent);

  class DelayedKeyEvent : public DelayedInputEvent
    explicit DelayedKeyEvent(mozilla::WidgetKeyboardEvent* aEvent);

  // Check if aEvent is a mouse event and record the mouse location for later
  // synth mouse moves.
  void RecordMouseLocation(mozilla::WidgetGUIEvent* aEvent);
  class nsSynthMouseMoveEvent final : public nsARefreshObserver {
    nsSynthMouseMoveEvent(PresShell* aPresShell, bool aFromScroll)
      : mPresShell(aPresShell), mFromScroll(aFromScroll) {
      NS_ASSERTION(mPresShell, "null parameter");

  // Private destructor, to discourage deletion outside of Release():
    ~nsSynthMouseMoveEvent() {

    NS_INLINE_DECL_REFCOUNTING(nsSynthMouseMoveEvent, override)

    void Revoke() {
      if (mPresShell) {
          RemoveRefreshObserver(this, Flush_Display);
        mPresShell = nullptr;
    virtual void WillRefresh(mozilla::TimeStamp aTime) override {
      if (mPresShell) {
        nsRefPtr<PresShell> shell = mPresShell;
    PresShell* mPresShell;
    bool mFromScroll;
  void ProcessSynthMouseMoveEvent(bool aFromScroll);

  void QueryIsActive();
  nsresult UpdateImageLockingState();

#ifdef ANDROID
  nsIDocument* GetTouchEventTargetDocument();
  bool InZombieDocument(nsIContent *aContent);
  already_AddRefed<nsIPresShell> GetParentPresShellForEventHandling();
  nsIContent* GetCurrentEventContent();
  nsIFrame* GetCurrentEventFrame();
  nsresult RetargetEventToParent(mozilla::WidgetGUIEvent* aEvent,
                                 nsEventStatus* aEventStatus);
  void PushCurrentEventInfo(nsIFrame* aFrame, nsIContent* aContent);
  void PopCurrentEventInfo();
  nsresult HandleEventInternal(mozilla::WidgetEvent* aEvent,
                               nsEventStatus* aStatus);
  nsresult HandlePositionedEvent(nsIFrame* aTargetFrame,
                                 mozilla::WidgetGUIEvent* aEvent,
                                 nsEventStatus* aEventStatus);
  // This returns the focused DOM window under our top level window.
  //  I.e., when we are deactive, this returns the *last* focused DOM window.
  already_AddRefed<nsPIDOMWindow> GetFocusedDOMWindowInOurWindow();

   * This and the next two helper methods are used to target and position the
   * context menu when the keyboard shortcut is used to open it.
   * If another menu is open, the context menu is opened relative to the
   * active menuitem within the menu, or the menu itself if no item is active.
   * Otherwise, if the caret is visible, the menu is opened near the caret.
   * Otherwise, if a selectable list such as a listbox is focused, the
   * current item within the menu is opened relative to this item.
   * Otherwise, the context menu is opened at the topleft corner of the
   * view.
   * Returns true if the context menu event should fire and false if it should
   * not.
  bool AdjustContextMenuKeyEvent(mozilla::WidgetMouseEvent* aEvent);

  bool PrepareToUseCaretPosition(nsIWidget* aEventWidget,
                                 mozilla::LayoutDeviceIntPoint& aTargetPt);

  // Get the selected item and coordinates in device pixels relative to root
  // document's root view for element, first ensuring the element is onscreen
  void GetCurrentItemAndPositionForElement(nsIDOMElement *aCurrentEl,
                                           nsIContent **aTargetToUse,
                                           mozilla::LayoutDeviceIntPoint& aTargetPt,
                                           nsIWidget *aRootWidget);

  void FireResizeEvent();
  static void AsyncResizeEventCallback(nsITimer* aTimer, void* aPresShell);

  virtual void SynthesizeMouseMove(bool aFromScroll) override;

  PresShell* GetRootPresShell();

  nscolor GetDefaultBackgroundColorToDraw();

  DOMHighResTimeStamp GetPerformanceNow();

  // The callback for the mPaintSuppressionTimer timer.
  static void sPaintSuppressionCallback(nsITimer* aTimer, void* aPresShell);

  // The callback for the mReflowContinueTimer timer.
  static void sReflowContinueCallback(nsITimer* aTimer, void* aPresShell);
  bool ScheduleReflowOffTimer();

  // Widget notificiations
  virtual void WindowSizeMoveDone() override;
  virtual void SysColorChanged() override { mPresContext->SysColorChanged(); }
  virtual void ThemeChanged() override { mPresContext->ThemeChanged(); }
  virtual void BackingScaleFactorChanged() override { mPresContext->UIResolutionChanged(); }

  virtual void PausePainting() override;
  virtual void ResumePainting() override;

  void UpdateImageVisibility();
  void UpdateActivePointerState(mozilla::WidgetGUIEvent* aEvent);

  nsRevocableEventPtr<nsRunnableMethod<PresShell> > mUpdateImageVisibilityEvent;

  void ClearVisibleImagesList(uint32_t aNonvisibleAction);
  static void ClearImageVisibilityVisited(nsView* aView, bool aClear);
  static void MarkImagesInListVisible(const nsDisplayList& aList);
  void MarkImagesInSubtreeVisible(nsIFrame* aFrame, const nsRect& aRect);

  // Methods for dispatching KeyboardEvent and BeforeAfterKeyboardEvent.
  void HandleKeyboardEvent(nsINode* aTarget,
                           mozilla::WidgetKeyboardEvent& aEvent,
                           bool aEmbeddedCancelled,
                           nsEventStatus* aStatus,
                           mozilla::EventDispatchingCallback* aEventCB);
  void DispatchBeforeKeyboardEventInternal(
         const nsTArray<nsCOMPtr<mozilla::dom::Element> >& aChain,
         const mozilla::WidgetKeyboardEvent& aEvent,
         size_t& aChainIndex,
         bool& aDefaultPrevented);
  void DispatchAfterKeyboardEventInternal(
         const nsTArray<nsCOMPtr<mozilla::dom::Element> >& aChain,
         const mozilla::WidgetKeyboardEvent& aEvent,
         bool aEmbeddedCancelled,
         size_t aChainIndex = 0);
  bool CanDispatchEvent(const mozilla::WidgetGUIEvent* aEvent = nullptr) const;

  // A list of images that are visible or almost visible.
  nsTHashtable< nsRefPtrHashKey<nsIImageLoadingContent> > mVisibleImages;

  nsresult SetResolutionImpl(float aResolution, bool aScaleToResolution);

#ifdef DEBUG
  // The reflow root under which we're currently reflowing.  Null when
  // not in reflow.
  nsIFrame*                 mCurrentReflowRoot;
  uint32_t                  mUpdateCount;

  ReflowCountMgr*           mReflowCountMgr;

  // This is used for synthetic mouse events that are sent when what is under
  // the mouse pointer may have changed without the mouse moving (eg scrolling,
  // change to the document contents).
  // It is set only on a presshell for a root document, this value represents
  // the last observed location of the mouse relative to that root document. It
  // is set to (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if the mouse isn't
  // over our window or there is no last observed mouse location for some
  // reason.
  nsPoint                   mMouseLocation;

  // mStyleSet owns it but we maintain a ref, may be null
  nsRefPtr<mozilla::CSSStyleSheet> mPrefStyleSheet;

  // Set of frames that we should mark with NS_FRAME_HAS_DIRTY_CHILDREN after
  // we finish reflowing mCurrentReflowRoot.
  nsTHashtable<nsPtrHashKey<nsIFrame> > mFramesToDirty;

  // Reflow roots that need to be reflowed.
  nsTArray<nsIFrame*>       mDirtyRoots;

  nsTArray<nsAutoPtr<DelayedEvent> > mDelayedEvents;
  nsRevocableEventPtr<nsRunnableMethod<PresShell> > mResizeEvent;
  nsCOMPtr<nsITimer>        mAsyncResizeEventTimer;
  nsIFrame*                 mCurrentEventFrame;
  nsCOMPtr<nsIContent>      mCurrentEventContent;
  nsTArray<nsIFrame*>       mCurrentEventFrameStack;
  nsCOMArray<nsIContent>    mCurrentEventContentStack;
  nsRevocableEventPtr<nsSynthMouseMoveEvent> mSynthMouseMoveEvent;
  nsCOMPtr<nsIContent>      mLastAnchorScrolledTo;
  nsRefPtr<nsCaret>         mCaret;
  nsRefPtr<nsCaret>         mOriginalCaret;
  nsCallbackEventRequest*   mFirstCallbackEventRequest;
  nsCallbackEventRequest*   mLastCallbackEventRequest;

  // TouchManager
  TouchManager              mTouchManager;

  nsRefPtr<ZoomConstraintsClient> mZoomConstraintsClient;

  // TouchCaret
  nsRefPtr<mozilla::TouchCaret> mTouchCaret;
  nsRefPtr<mozilla::SelectionCarets> mSelectionCarets;
  nsRefPtr<mozilla::AccessibleCaretEventHub> mAccessibleCaretEventHub;

  // This timer controls painting suppression.  Until it fires
  // or all frames are constructed, we won't paint anything but
  // our <body> background and scrollbars.
  nsCOMPtr<nsITimer>        mPaintSuppressionTimer;

  nsCOMPtr<nsITimer>        mDelayedPaintTimer;

  // The `` value when we last started to process reflows.
  DOMHighResTimeStamp       mLastReflowStart;

  mozilla::TimeStamp        mLoadBegin;  // used to time loads

  // Information needed to properly handle scrolling content into view if the
  // pre-scroll reflow flush can be interrupted.  mContentToScrollTo is
  // non-null between the initial scroll attempt and the first time we finish
  // processing all our dirty roots.  mContentToScrollTo has a content property
  // storing the details for the scroll operation, see ScrollIntoViewData above.
  nsCOMPtr<nsIContent>      mContentToScrollTo;

  nscoord                   mLastAnchorScrollPositionY;

  // Information about live content (which still stay in DOM tree).
  // Used in case we need re-dispatch event after sending pointer event,
  // when target of pointer event was deleted during executing user handlers.
  nsCOMPtr<nsIContent>      mPointerEventTarget;

  // This is used to protect ourselves from triggering reflow while in the
  // middle of frame construction and the like... it really shouldn't be
  // needed, one hopes, but it is for now.
  uint16_t                  mChangeNestCount;

  bool                      mDocumentLoading : 1;
  bool                      mIgnoreFrameDestruction : 1;
  bool                      mHaveShutDown : 1;
  bool                      mViewportOverridden : 1;
  bool                      mLastRootReflowHadUnconstrainedBSize : 1;
  bool                      mNoDelayedMouseEvents : 1;
  bool                      mNoDelayedKeyEvents : 1;

  // We've been disconnected from the document.  We will refuse to paint the
  // document until either our timer fires or all frames are constructed.
  bool                      mIsDocumentGone : 1;

  // Indicates that it is safe to unlock painting once all pending reflows
  // have been processed.
  bool                      mShouldUnsuppressPainting : 1;

  bool                      mAsyncResizeTimerIsActive : 1;
  bool                      mInResize : 1;

  bool                      mImageVisibilityVisited : 1;

  bool                      mNextPaintCompressed : 1;

  bool                      mHasCSSBackgroundColor : 1;

  // Whether content should be scaled by the resolution amount. If this is
  // not set, a transform that scales by the inverse of the resolution is
  // applied to rendered layers.
  bool                      mScaleToResolution : 1;

  // Whether the last chrome-only escape key event is consumed.
  bool                      mIsLastChromeOnlyEscapeKeyConsumed : 1;

  // Whether the widget has received a paint message yet.
  bool                      mHasReceivedPaintMessage : 1;

  static bool               sDisableNonTestMouseEvents;

#endif /* !defined(nsPresShell_h_) */