summaryrefslogtreecommitdiffstats
path: root/layout/base/nsPresShell.h
diff options
context:
space:
mode:
Diffstat (limited to 'layout/base/nsPresShell.h')
-rw-r--r--layout/base/nsPresShell.h966
1 files changed, 966 insertions, 0 deletions
diff --git a/layout/base/nsPresShell.h b/layout/base/nsPresShell.h
new file mode 100644
index 000000000..ad4ede08b
--- /dev/null
+++ b/layout/base/nsPresShell.h
@@ -0,0 +1,966 @@
+/* -*- 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 http://mozilla.org/MPL/2.0/.
+ *
+ * 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 "nsContentUtils.h" // For AddScriptBlocker().
+#include "nsRefreshDriver.h"
+#include "TouchManager.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/EventForwards.h"
+#include "mozilla/MemoryReporting.h"
+#include "mozilla/StyleSetHandle.h"
+#include "mozilla/UniquePtr.h"
+#include "MobileViewportManager.h"
+#include "ZoomConstraintsClient.h"
+
+class nsIDocShell;
+class nsRange;
+
+struct RangePaintInfo;
+struct nsCallbackEventRequest;
+#ifdef MOZ_REFLOW_PERF
+class ReflowCountMgr;
+#endif
+
+class nsPresShellEventCB;
+class nsAutoCauseReflowNotifier;
+
+namespace mozilla {
+
+class EventDispatchingCallback;
+
+// A set type for tracking visible frames, for use by the visibility code in
+// PresShell. The set contains nsIFrame* pointers.
+typedef nsTHashtable<nsPtrHashKey<nsIFrame>> VisibleFrames;
+
+// A hash table type for tracking visible regions, for use by the visibility
+// code in PresShell. The mapping is from view IDs to regions in the
+// coordinate system of that view's scrolled frame.
+typedef nsClassHashtable<nsUint64HashKey, mozilla::CSSIntRegion> VisibleRegions;
+
+} // namespace mozilla
+
+// 250ms. This is actually pref-controlled, but we use this value if we fail
+// to get the pref for any reason.
+#define PAINTLOCK_EVENT_DELAY 250
+
+class PresShell final : public nsIPresShell,
+ public nsStubDocumentObserver,
+ public nsISelectionController,
+ public nsIObserver,
+ public nsSupportsWeakReference
+{
+ template <typename T> using Maybe = mozilla::Maybe<T>;
+ using Nothing = mozilla::Nothing;
+ using OnNonvisible = mozilla::OnNonvisible;
+ using RawSelectionType = mozilla::RawSelectionType;
+ using SelectionType = mozilla::SelectionType;
+ using VisibleFrames = mozilla::VisibleFrames;
+ using VisibleRegions = mozilla::VisibleRegions;
+
+public:
+ PresShell();
+
+ NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
+
+ // nsISupports
+ NS_DECL_ISUPPORTS
+
+ static bool AccessibleCaretEnabled(nsIDocShell* aDocShell);
+
+ // BeforeAfterKeyboardEvent preference
+ static bool BeforeAfterKeyboardEventEnabled();
+
+ static bool IsTargetIframe(nsINode* aTarget);
+
+ void Init(nsIDocument* aDocument, nsPresContext* aPresContext,
+ nsViewManager* aViewManager, mozilla::StyleSetHandle aStyleSet);
+ virtual void Destroy() override;
+ virtual void MakeZombie() override;
+
+ virtual void UpdatePreferenceStyles() override;
+
+ NS_IMETHOD GetSelection(RawSelectionType aRawSelectionType,
+ nsISelection** aSelection) override;
+ virtual mozilla::dom::Selection*
+ GetCurrentSelection(SelectionType aSelectionType) override;
+ virtual already_AddRefed<nsISelectionController>
+ GetSelectionControllerForFocusedContent(
+ nsIContent** aFocusedContent = nullptr) override;
+
+ NS_IMETHOD SetDisplaySelection(int16_t aToggle) override;
+ NS_IMETHOD GetDisplaySelection(int16_t *aToggle) override;
+ NS_IMETHOD ScrollSelectionIntoView(RawSelectionType aRawSelectionType,
+ SelectionRegion aRegion,
+ int16_t aFlags) override;
+ NS_IMETHOD RepaintSelection(RawSelectionType aRawSelectionType) override;
+
+ virtual void BeginObservingDocument() override;
+ virtual void EndObservingDocument() override;
+ virtual nsresult Initialize(nscoord aWidth, nscoord aHeight) override;
+ virtual nsresult ResizeReflow(nscoord aWidth, nscoord aHeight, nscoord aOldWidth = 0, nscoord aOldHeight = 0) override;
+ virtual nsresult ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight, nscoord aOldWidth, nscoord aOldHeight) override;
+ virtual nsIPageSequenceFrame* GetPageSequenceFrame() const override;
+ virtual nsCanvasFrame* GetCanvasFrame() const override;
+
+ virtual nsIFrame* GetPlaceholderFrameFor(nsIFrame* aFrame) const override;
+ virtual void FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty,
+ nsFrameState aBitToAdd,
+ ReflowRootHandling aRootHandling =
+ eInferFromBitToAdd) 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(
+ nsTArray<RefPtr<mozilla::StyleSheet>>& aSheets) override;
+ virtual nsresult SetAgentStyleSheets(
+ const nsTArray<RefPtr<mozilla::StyleSheet>>& aSheets) override;
+
+ virtual nsresult AddOverrideStyleSheet(mozilla::StyleSheet* aSheet) override;
+ virtual nsresult RemoveOverrideStyleSheet(mozilla::StyleSheet* 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 already_AddRefed<SourceSurface>
+ RenderNode(nsIDOMNode* aNode,
+ nsIntRegion* aRegion,
+ const mozilla::LayoutDeviceIntPoint aPoint,
+ mozilla::LayoutDeviceIntRect* aScreenRect,
+ uint32_t aFlags) override;
+
+ virtual already_AddRefed<SourceSurface>
+ RenderSelection(nsISelection* aSelection,
+ const mozilla::LayoutDeviceIntPoint aPoint,
+ mozilla::LayoutDeviceIntRect* aScreenRect,
+ uint32_t aFlags) override;
+
+ virtual already_AddRefed<nsPIDOMWindowOuter> 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;
+ virtual float GetCumulativeNonRootScaleResolution() override;
+ virtual void SetRestoreResolution(float aResolution,
+ mozilla::LayoutDeviceIntSize aDisplaySize) 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;
+
+ 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;
+
+ // nsIDocumentObserver
+ NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE
+ NS_DECL_NSIDOCUMENTOBSERVER_ENDUPDATE
+ NS_DECL_NSIDOCUMENTOBSERVER_BEGINLOAD
+ NS_DECL_NSIDOCUMENTOBSERVER_ENDLOAD
+ NS_DECL_NSIDOCUMENTOBSERVER_CONTENTSTATECHANGED
+ NS_DECL_NSIDOCUMENTOBSERVER_DOCUMENTSTATESCHANGED
+ NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETADDED
+ NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETREMOVED
+ NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETAPPLICABLESTATECHANGED
+ NS_DECL_NSIDOCUMENTOBSERVER_STYLERULECHANGED
+ NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEADDED
+ NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEREMOVED
+
+ // nsIMutationObserver
+ NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
+ NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE
+ NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
+ NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
+ NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
+ NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
+
+ NS_DECL_NSIOBSERVER
+
+#ifdef MOZ_REFLOW_PERF
+ 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;
+#endif
+
+#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;
+#endif
+
+ static mozilla::LazyLogModule 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 (mMobileViewportManager != nullptr);
+ }
+
+ virtual bool IsLayoutFlushObserver() override
+ {
+ return GetPresContext()->RefreshDriver()->
+ IsLayoutFlushObserver(this);
+ }
+
+ 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;
+ };
+
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Approximate frame visibility tracking public API.
+ //////////////////////////////////////////////////////////////////////////////
+
+ void ScheduleApproximateFrameVisibilityUpdateSoon() override;
+ void ScheduleApproximateFrameVisibilityUpdateNow() override;
+
+ void RebuildApproximateFrameVisibilityDisplayList(const nsDisplayList& aList) override;
+ void RebuildApproximateFrameVisibility(nsRect* aRect = nullptr,
+ bool aRemoveOnly = false) override;
+
+ void EnsureFrameInApproximatelyVisibleList(nsIFrame* aFrame) override;
+ void RemoveFrameFromApproximatelyVisibleList(nsIFrame* aFrame) override;
+
+ bool AssumeAllFramesVisible() override;
+
+
+ virtual void RecordShadowStyleChange(mozilla::dom::ShadowRoot* aShadowRoot) override;
+
+ virtual void DispatchAfterKeyboardEvent(nsINode* aTarget,
+ const mozilla::WidgetKeyboardEvent& aEvent,
+ bool aEmbeddedCancelled) override;
+
+ virtual bool CanDispatchEvent(
+ const mozilla::WidgetGUIEvent* aEvent = nullptr) const override;
+
+ void SetNextPaintCompressed() { mNextPaintCompressed = true; }
+
+protected:
+ virtual ~PresShell();
+
+ void HandlePostedReflowCallbacks(bool aInterruptible);
+ void CancelPostedReflowCallbacks();
+
+ void ScheduleBeforeFirstPaint();
+ void UnsuppressAndInvalidate();
+
+ void WillCauseReflow() {
+ nsContentUtils::AddScriptBlocker();
+ ++mChangeNestCount;
+ }
+ 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.
+ */
+ void DidDoReflow(bool aInterruptible);
+ // 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();
+
+ // DoReflow returns whether the reflow finished without interruption
+ bool DoReflow(nsIFrame* aFrame, bool aInterruptible);
+#ifdef DEBUG
+ void DoVerifyReflow();
+ void VerifyHasDirtyRootAncestor(nsIFrame* aFrame);
+#endif
+
+ // 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)
+ { }
+ Maybe<float> mResolution;
+ RenderFlags mRenderFlags;
+ };
+
+ struct AutoSaveRestoreRenderingState {
+ explicit AutoSaveRestoreRenderingState(PresShell* aPresShell)
+ : mPresShell(aPresShell)
+ , mOldState(aPresShell)
+ {}
+
+ ~AutoSaveRestoreRenderingState()
+ {
+ 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();
+#endif
+
+ void RecordStyleSheetChange(mozilla::StyleSheet* 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
+ mozilla::UniquePtr<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
+ * aFlags - set RENDER_AUTO_SCALE to scale down large images, but it must not
+ * be set if a custom image was specified
+ */
+ already_AddRefed<SourceSurface>
+ PaintRangePaintInfo(const nsTArray<mozilla::UniquePtr<RangePaintInfo>>& aItems,
+ nsISelection* aSelection,
+ nsIntRegion* aRegion,
+ nsRect aArea,
+ const mozilla::LayoutDeviceIntPoint aPoint,
+ mozilla::LayoutDeviceIntRect* aScreenRect,
+ uint32_t aFlags);
+
+ /**
+ * 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(mozilla::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, true);
+ }
+ PopCurrentEventInfo();
+ return rv;
+ }
+
+ class DelayedEvent
+ {
+ public:
+ virtual ~DelayedEvent() { }
+ virtual void Dispatch() { }
+ };
+
+ class DelayedInputEvent : public DelayedEvent
+ {
+ public:
+ virtual void Dispatch() override;
+
+ protected:
+ DelayedInputEvent();
+ virtual ~DelayedInputEvent();
+
+ mozilla::WidgetInputEvent* mEvent;
+ };
+
+ class DelayedMouseEvent : public DelayedInputEvent
+ {
+ public:
+ explicit DelayedMouseEvent(mozilla::WidgetMouseEvent* aEvent);
+ };
+
+ class DelayedKeyEvent : public DelayedInputEvent
+ {
+ public:
+ 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 {
+ public:
+ nsSynthMouseMoveEvent(PresShell* aPresShell, bool aFromScroll)
+ : mPresShell(aPresShell), mFromScroll(aFromScroll) {
+ NS_ASSERTION(mPresShell, "null parameter");
+ }
+
+ private:
+ // Private destructor, to discourage deletion outside of Release():
+ ~nsSynthMouseMoveEvent() {
+ Revoke();
+ }
+
+ public:
+ NS_INLINE_DECL_REFCOUNTING(nsSynthMouseMoveEvent, override)
+
+ void Revoke() {
+ if (mPresShell) {
+ mPresShell->GetPresContext()->RefreshDriver()->
+ RemoveRefreshObserver(this, Flush_Display);
+ mPresShell = nullptr;
+ }
+ }
+ virtual void WillRefresh(mozilla::TimeStamp aTime) override {
+ if (mPresShell) {
+ RefPtr<PresShell> shell = mPresShell;
+ shell->ProcessSynthMouseMoveEvent(mFromScroll);
+ }
+ }
+ private:
+ PresShell* mPresShell;
+ bool mFromScroll;
+ };
+ void ProcessSynthMouseMoveEvent(bool aFromScroll);
+
+ void QueryIsActive();
+ nsresult UpdateImageLockingState();
+
+ 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();
+ /**
+ * @param aIsHandlingNativeEvent true when the caller (perhaps) handles
+ * an event which is caused by native
+ * event. Otherwise, false.
+ */
+ nsresult HandleEventInternal(mozilla::WidgetEvent* aEvent,
+ nsEventStatus* aStatus,
+ bool aIsHandlingNativeEvent);
+ 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<nsPIDOMWindowOuter> 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(); }
+#ifdef ANDROID
+ virtual nsIDocument* GetTouchEventTargetDocument() override;
+#endif
+
+ virtual void PausePainting() override;
+ virtual void ResumePainting() override;
+
+ void UpdateActivePointerState(mozilla::WidgetGUIEvent* aEvent);
+
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Approximate frame visibility tracking implementation.
+ //////////////////////////////////////////////////////////////////////////////
+
+ void UpdateApproximateFrameVisibility();
+ void DoUpdateApproximateFrameVisibility(bool aRemoveOnly);
+
+ void ClearApproximatelyVisibleFramesList(Maybe<mozilla::OnNonvisible> aNonvisibleAction
+ = Nothing());
+ static void ClearApproximateFrameVisibilityVisited(nsView* aView, bool aClear);
+ static void MarkFramesInListApproximatelyVisible(const nsDisplayList& aList,
+ Maybe<VisibleRegions>& aVisibleRegions);
+ void MarkFramesInSubtreeApproximatelyVisible(nsIFrame* aFrame,
+ const nsRect& aRect,
+ Maybe<VisibleRegions>& aVisibleRegions,
+ bool aRemoveOnly = false);
+
+ void DecApproximateVisibleCount(VisibleFrames& aFrames,
+ Maybe<OnNonvisible> aNonvisibleAction = Nothing());
+
+ nsRevocableEventPtr<nsRunnableMethod<PresShell>> mUpdateApproximateFrameVisibilityEvent;
+
+ // A set of frames that were visible or could be visible soon at the time
+ // that we last did an approximate frame visibility update.
+ VisibleFrames mApproximatelyVisibleFrames;
+
+
+ //////////////////////////////////////////////////////////////////////////////
+ // 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);
+
+#ifdef MOZ_B2G
+ // This method is used to forward the keyboard event to the input-method-app
+ // before the event is dispatched to its event target.
+ // Return true if it's successfully forwarded. Otherwise, return false.
+ bool ForwardKeyToInputMethodApp(nsINode* aTarget,
+ mozilla::WidgetKeyboardEvent& aEvent,
+ nsEventStatus* aStatus);
+#endif // MOZ_B2G
+
+ // This method tries forwarding key events to the input-method-editor(IME).
+ // If the event isn't be forwarded, then it will be dispathed to its target.
+ // Return true when event is successfully forwarded to the input-method-editor.
+ // Otherwise, return false.
+ bool ForwardKeyToInputMethodAppOrDispatch(bool aIsTargetRemote,
+ nsINode* aTarget,
+ mozilla::WidgetKeyboardEvent& aEvent,
+ nsEventStatus* aStatus,
+ mozilla::EventDispatchingCallback* aEventCB);
+
+ 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;
+#endif
+
+#ifdef MOZ_REFLOW_PERF
+ ReflowCountMgr* mReflowCountMgr;
+#endif
+
+ // 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;
+ // This is an APZ state variable that tracks the target guid for the last
+ // mouse event that was processed (corresponding to mMouseLocation). This is
+ // needed for the synthetic mouse events.
+ mozilla::layers::ScrollableLayerGuid mMouseEventTargetGuid;
+
+ // mStyleSet owns it but we maintain a ref, may be null
+ RefPtr<mozilla::StyleSheet> 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;
+private:
+ nsIFrame* mCurrentEventFrame;
+ nsCOMPtr<nsIContent> mCurrentEventContent;
+ nsTArray<nsIFrame*> mCurrentEventFrameStack;
+ nsCOMArray<nsIContent> mCurrentEventContentStack;
+protected:
+ nsRevocableEventPtr<nsSynthMouseMoveEvent> mSynthMouseMoveEvent;
+ nsCOMPtr<nsIContent> mLastAnchorScrolledTo;
+ RefPtr<nsCaret> mCaret;
+ RefPtr<nsCaret> mOriginalCaret;
+ nsCallbackEventRequest* mFirstCallbackEventRequest;
+ nsCallbackEventRequest* mLastCallbackEventRequest;
+
+ mozilla::TouchManager mTouchManager;
+
+ RefPtr<ZoomConstraintsClient> mZoomConstraintsClient;
+ RefPtr<MobileViewportManager> mMobileViewportManager;
+
+ RefPtr<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 `performance.now()` 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 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 mApproximateFrameVisibilityVisited : 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_) */