Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/PresShell.h
Line
Count
Source (jump to first uncovered line)
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 "MobileViewportManager.h"
13
#include "mozilla/Attributes.h"
14
#include "mozilla/EventForwards.h"
15
#include "mozilla/layers/FocusTarget.h"
16
#include "mozilla/MemoryReporting.h"
17
#include "mozilla/ServoStyleSet.h"
18
#include "mozilla/UniquePtr.h"
19
#include "nsAutoPtr.h"
20
#include "nsContentUtils.h" // For AddScriptBlocker().
21
#include "nsCRT.h"
22
#include "nsIObserver.h"
23
#include "nsIPresShell.h"
24
#include "nsISelectionController.h"
25
#include "nsIWidget.h"
26
#include "nsPresContext.h"
27
#include "nsRefreshDriver.h"
28
#include "nsStubDocumentObserver.h"
29
#include "nsThreadUtils.h"
30
#include "nsWeakReference.h"
31
#include "TouchManager.h"
32
#include "ZoomConstraintsClient.h"
33
34
class nsIDocShell;
35
class nsRange;
36
37
struct RangePaintInfo;
38
struct nsCallbackEventRequest;
39
#ifdef MOZ_REFLOW_PERF
40
class ReflowCountMgr;
41
#endif
42
43
class nsPresShellEventCB;
44
class nsAutoCauseReflowNotifier;
45
class AutoPointerEventTargetUpdater;
46
47
namespace mozilla {
48
49
namespace dom {
50
class Element;
51
class Selection;
52
}  // namespace dom
53
54
class EventDispatchingCallback;
55
56
// A set type for tracking visible frames, for use by the visibility code in
57
// PresShell. The set contains nsIFrame* pointers.
58
typedef nsTHashtable<nsPtrHashKey<nsIFrame>> VisibleFrames;
59
60
// This is actually pref-controlled, but we use this value if we fail
61
// to get the pref for any reason.
62
#ifdef MOZ_WIDGET_ANDROID
63
#define PAINTLOCK_EVENT_DELAY 250
64
#else
65
0
#define PAINTLOCK_EVENT_DELAY 5
66
#endif
67
68
class PresShell final : public nsIPresShell,
69
                        public nsISelectionController,
70
                        public nsIObserver,
71
                        public nsSupportsWeakReference
72
{
73
  typedef layers::FocusTarget FocusTarget;
74
75
public:
76
  PresShell();
77
78
  // nsISupports
79
  NS_DECL_ISUPPORTS
80
81
  static bool AccessibleCaretEnabled(nsIDocShell* aDocShell);
82
83
  void Init(nsIDocument* aDocument, nsPresContext* aPresContext,
84
            nsViewManager* aViewManager,
85
            UniquePtr<ServoStyleSet> aStyleSet);
86
  void Destroy() override;
87
88
  void UpdatePreferenceStyles() override;
89
90
  NS_IMETHOD GetSelectionFromScript(RawSelectionType aRawSelectionType,
91
                                    dom::Selection** aSelection) override;
92
  dom::Selection* GetSelection(RawSelectionType aRawSelectionType) override;
93
94
  dom::Selection* GetCurrentSelection(SelectionType aSelectionType) override;
95
96
  already_AddRefed<nsISelectionController>
97
    GetSelectionControllerForFocusedContent(
98
      nsIContent** aFocusedContent = nullptr) override;
99
100
  NS_IMETHOD SetDisplaySelection(int16_t aToggle) override;
101
  NS_IMETHOD GetDisplaySelection(int16_t *aToggle) override;
102
  NS_IMETHOD ScrollSelectionIntoView(RawSelectionType aRawSelectionType,
103
                                     SelectionRegion aRegion,
104
                                     int16_t aFlags) override;
105
  NS_IMETHOD RepaintSelection(RawSelectionType aRawSelectionType) override;
106
107
  nsresult Initialize() override;
108
  nsresult ResizeReflow(nscoord aWidth, nscoord aHeight,
109
                        nscoord aOldWidth = 0, nscoord aOldHeight = 0,
110
                        ResizeReflowOptions aOptions =
111
                        ResizeReflowOptions::eBSizeExact) override;
112
  nsresult ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight,
113
                                      nscoord aOldWidth, nscoord aOldHeight,
114
                                      ResizeReflowOptions aOptions =
115
                                      ResizeReflowOptions::eBSizeExact) override;
116
  nsIPageSequenceFrame* GetPageSequenceFrame() const override;
117
  nsCanvasFrame* GetCanvasFrame() const override;
118
119
  void FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty,
120
                                nsFrameState aBitToAdd,
121
                                ReflowRootHandling aRootHandling =
122
                                  eInferFromBitToAdd) override;
123
  void FrameNeedsToContinueReflow(nsIFrame *aFrame) override;
124
  void CancelAllPendingReflows() override;
125
  void DoFlushPendingNotifications(FlushType aType) override;
126
  void DoFlushPendingNotifications(ChangesToFlush aType) override;
127
128
  /**
129
   * Post a callback that should be handled after reflow has finished.
130
   */
131
  nsresult PostReflowCallback(nsIReflowCallback* aCallback) override;
132
  void CancelReflowCallback(nsIReflowCallback* aCallback) override;
133
134
  void ClearFrameRefs(nsIFrame* aFrame) override;
135
  already_AddRefed<gfxContext> CreateReferenceRenderingContext() override;
136
  nsresult GoToAnchor(const nsAString& aAnchorName, bool aScroll,
137
                              uint32_t aAdditionalScrollFlags = 0) override;
138
  nsresult ScrollToAnchor() override;
139
140
  nsresult ScrollContentIntoView(nsIContent* aContent,
141
                                                     ScrollAxis  aVertical,
142
                                                     ScrollAxis  aHorizontal,
143
                                                     uint32_t    aFlags) override;
144
  bool ScrollFrameRectIntoView(nsIFrame*     aFrame,
145
                                       const nsRect& aRect,
146
                                       ScrollAxis    aVertical,
147
                                       ScrollAxis    aHorizontal,
148
                                       uint32_t      aFlags) override;
149
  nsRectVisibility GetRectVisibility(nsIFrame *aFrame,
150
                                             const nsRect &aRect,
151
                                             nscoord aMinTwips) const override;
152
153
  void SetIgnoreFrameDestruction(bool aIgnore) override;
154
  void NotifyDestroyingFrame(nsIFrame* aFrame) override;
155
156
  nsresult CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState) override;
157
158
  void UnsuppressPainting() override;
159
160
  nsresult GetAgentStyleSheets(
161
      nsTArray<RefPtr<StyleSheet>>& aSheets) override;
162
  nsresult SetAgentStyleSheets(
163
      const nsTArray<RefPtr<StyleSheet>>& aSheets) override;
164
165
  nsresult AddOverrideStyleSheet(StyleSheet* aSheet) override;
166
  nsresult RemoveOverrideStyleSheet(StyleSheet* aSheet) override;
167
168
  nsresult HandleEventWithTarget(WidgetEvent* aEvent,
169
                                 nsIFrame* aFrame,
170
                                 nsIContent* aContent,
171
                                 nsEventStatus* aStatus,
172
                                 bool aIsHandlingNativeEvent = false,
173
                                 nsIContent** aTargetContent = nullptr,
174
                                 nsIContent* aOverrideClickTarget = nullptr)
175
                                 override;
176
  already_AddRefed<nsIContent>
177
    GetEventTargetContent(WidgetEvent* aEvent) override;
178
179
  void NotifyCounterStylesAreDirty() override;
180
181
  void ReconstructFrames(void) override;
182
  void Freeze() override;
183
  void Thaw() override;
184
  void FireOrClearDelayedEvents(bool aFireEvents) override;
185
186
  nsresult RenderDocument(const nsRect& aRect,
187
                          uint32_t aFlags,
188
                          nscolor aBackgroundColor,
189
                          gfxContext* aThebesContext) override;
190
191
  already_AddRefed<SourceSurface>
192
  RenderNode(nsINode* aNode,
193
             const Maybe<CSSIntRegion>& aRegion,
194
             const LayoutDeviceIntPoint aPoint,
195
             LayoutDeviceIntRect* aScreenRect,
196
             uint32_t aFlags) override;
197
198
  already_AddRefed<SourceSurface>
199
  RenderSelection(dom::Selection* aSelection,
200
                  const LayoutDeviceIntPoint aPoint,
201
                  LayoutDeviceIntRect* aScreenRect,
202
                  uint32_t aFlags) override;
203
204
  already_AddRefed<nsPIDOMWindowOuter> GetRootWindow() override;
205
206
  already_AddRefed<nsPIDOMWindowOuter> GetFocusedDOMWindowInOurWindow() override;
207
208
  LayerManager* GetLayerManager() override;
209
210
  bool AsyncPanZoomEnabled() override;
211
212
  void SetIgnoreViewportScrolling(bool aIgnore) override;
213
214
0
  nsresult SetResolution(float aResolution) override {
215
0
    return SetResolutionImpl(aResolution, /* aScaleToResolution = */ false);
216
0
  }
217
0
  nsresult SetResolutionAndScaleTo(float aResolution) override {
218
0
    return SetResolutionImpl(aResolution, /* aScaleToResolution = */ true);
219
0
  }
220
  bool ScaleToResolution() const override;
221
  float GetCumulativeResolution() override;
222
  float GetCumulativeNonRootScaleResolution() override;
223
  void SetRestoreResolution(float aResolution,
224
                            LayoutDeviceIntSize aDisplaySize) override;
225
226
  //nsIViewObserver interface
227
228
  void Paint(nsView* aViewToPaint, const nsRegion& aDirtyRegion,
229
             uint32_t aFlags) override;
230
  MOZ_CAN_RUN_SCRIPT nsresult HandleEvent(nsIFrame* aFrame,
231
                                          WidgetGUIEvent* aEvent,
232
                                          bool aDontRetargetEvents,
233
                                          nsEventStatus* aEventStatus) override;
234
  nsresult HandleDOMEventWithTarget(nsIContent* aTargetContent,
235
                                    WidgetEvent* aEvent,
236
                                    nsEventStatus* aStatus) override;
237
  nsresult HandleDOMEventWithTarget(nsIContent* aTargetContent,
238
                                    dom::Event* aEvent,
239
                                    nsEventStatus* aStatus) override;
240
  bool ShouldIgnoreInvalidation() override;
241
  void WillPaint() override;
242
  void WillPaintWindow() override;
243
  void DidPaintWindow() override;
244
  void ScheduleViewManagerFlush(PaintType aType = PAINT_DEFAULT) override;
245
  void ClearMouseCaptureOnView(nsView* aView) override;
246
  bool IsVisible() override;
247
  void SuppressDisplayport(bool aEnabled) override;
248
  void RespectDisplayportSuppression(bool aEnabled) override;
249
  bool IsDisplayportSuppressed() override;
250
251
  already_AddRefed<AccessibleCaretEventHub> GetAccessibleCaretEventHub() const override;
252
253
  // caret handling
254
  already_AddRefed<nsCaret> GetCaret() const override;
255
  NS_IMETHOD SetCaretEnabled(bool aInEnable) override;
256
  NS_IMETHOD SetCaretReadOnly(bool aReadOnly) override;
257
  NS_IMETHOD GetCaretEnabled(bool *aOutEnabled) override;
258
  NS_IMETHOD SetCaretVisibilityDuringSelection(bool aVisibility) override;
259
  NS_IMETHOD GetCaretVisible(bool *_retval) override;
260
  void SetCaret(nsCaret *aNewCaret) override;
261
  void RestoreCaret() override;
262
263
  NS_IMETHOD SetSelectionFlags(int16_t aInEnable) override;
264
  NS_IMETHOD GetSelectionFlags(int16_t *aOutEnable) override;
265
266
  // nsISelectionController
267
268
  NS_IMETHOD PhysicalMove(int16_t aDirection, int16_t aAmount, bool aExtend) override;
269
  NS_IMETHOD CharacterMove(bool aForward, bool aExtend) override;
270
  NS_IMETHOD CharacterExtendForDelete() override;
271
  NS_IMETHOD CharacterExtendForBackspace() override;
272
  NS_IMETHOD WordMove(bool aForward, bool aExtend) override;
273
  NS_IMETHOD WordExtendForDelete(bool aForward) override;
274
  NS_IMETHOD LineMove(bool aForward, bool aExtend) override;
275
  NS_IMETHOD IntraLineMove(bool aForward, bool aExtend) override;
276
  NS_IMETHOD PageMove(bool aForward, bool aExtend) override;
277
  NS_IMETHOD ScrollPage(bool aForward) override;
278
  NS_IMETHOD ScrollLine(bool aForward) override;
279
  NS_IMETHOD ScrollCharacter(bool aRight) override;
280
  NS_IMETHOD CompleteScroll(bool aForward) override;
281
  NS_IMETHOD CompleteMove(bool aForward, bool aExtend) override;
282
  NS_IMETHOD SelectAll() override;
283
  NS_IMETHOD CheckVisibility(nsINode *node, int16_t startOffset, int16_t EndOffset, bool *_retval) override;
284
  nsresult CheckVisibilityContent(nsIContent* aNode, int16_t aStartOffset,
285
                                  int16_t aEndOffset, bool* aRetval) override;
286
287
  // nsIDocumentObserver
288
  NS_DECL_NSIDOCUMENTOBSERVER_BEGINLOAD
289
  NS_DECL_NSIDOCUMENTOBSERVER_ENDLOAD
290
  NS_DECL_NSIDOCUMENTOBSERVER_CONTENTSTATECHANGED
291
  NS_DECL_NSIDOCUMENTOBSERVER_DOCUMENTSTATESCHANGED
292
293
  // nsIMutationObserver
294
  NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
295
  NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE
296
  NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
297
  NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
298
  NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
299
  NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
300
301
  NS_DECL_NSIOBSERVER
302
303
#ifdef MOZ_REFLOW_PERF
304
  void DumpReflows() override;
305
  void CountReflows(const char * aName, nsIFrame * aFrame) override;
306
  void PaintCount(const char * aName,
307
                  gfxContext* aRenderingContext,
308
                  nsPresContext* aPresContext,
309
                  nsIFrame * aFrame,
310
                  const nsPoint& aOffset,
311
                  uint32_t aColor) override;
312
  void SetPaintFrameCount(bool aOn) override;
313
  bool IsPaintingFrameCounts() override;
314
#endif
315
316
#ifdef DEBUG
317
  void ListComputedStyles(FILE *out, int32_t aIndent = 0) override;
318
319
  void ListStyleSheets(FILE *out, int32_t aIndent = 0) override;
320
#endif
321
322
  static LazyLogModule gLog;
323
324
  void DisableNonTestMouseEvents(bool aDisable) override;
325
326
  void UpdateCanvasBackground() override;
327
328
  void AddCanvasBackgroundColorItem(nsDisplayListBuilder& aBuilder,
329
                                    nsDisplayList& aList,
330
                                    nsIFrame* aFrame,
331
                                    const nsRect& aBounds,
332
                                    nscolor aBackstopColor,
333
                                    uint32_t aFlags) override;
334
335
  void AddPrintPreviewBackgroundItem(nsDisplayListBuilder& aBuilder,
336
                                     nsDisplayList& aList,
337
                                     nsIFrame* aFrame,
338
                                     const nsRect& aBounds) override;
339
340
  nscolor ComputeBackstopColor(nsView* aDisplayRoot) override;
341
342
  nsresult SetIsActive(bool aIsActive) override;
343
344
0
  bool GetIsViewportOverridden() override {
345
0
    return (mMobileViewportManager != nullptr);
346
0
  }
347
348
  bool IsLayoutFlushObserver() override
349
0
  {
350
0
    return GetPresContext()->RefreshDriver()->
351
0
      IsLayoutFlushObserver(this);
352
0
  }
353
354
  void LoadComplete() override;
355
356
  void AddSizeOfIncludingThis(nsWindowSizes& aWindowSizes)
357
    const override;
358
  size_t SizeOfTextRuns(MallocSizeOf aMallocSizeOf) const;
359
360
  // This data is stored as a content property (nsGkAtoms::scrolling) on
361
  // mContentToScrollTo when we have a pending ScrollIntoView.
362
  struct ScrollIntoViewData {
363
    ScrollAxis mContentScrollVAxis;
364
    ScrollAxis mContentScrollHAxis;
365
    uint32_t   mContentToScrollToFlags;
366
  };
367
368
369
  //////////////////////////////////////////////////////////////////////////////
370
  // Approximate frame visibility tracking public API.
371
  //////////////////////////////////////////////////////////////////////////////
372
373
  void ScheduleApproximateFrameVisibilityUpdateSoon() override;
374
  void ScheduleApproximateFrameVisibilityUpdateNow() override;
375
376
  void RebuildApproximateFrameVisibilityDisplayList(const nsDisplayList& aList) override;
377
  void RebuildApproximateFrameVisibility(nsRect* aRect = nullptr,
378
                                         bool aRemoveOnly = false) override;
379
380
  void EnsureFrameInApproximatelyVisibleList(nsIFrame* aFrame) override;
381
  void RemoveFrameFromApproximatelyVisibleList(nsIFrame* aFrame) override;
382
383
  bool AssumeAllFramesVisible() override;
384
385
  bool CanDispatchEvent(const WidgetGUIEvent* aEvent = nullptr) const override;
386
387
0
  void SetNextPaintCompressed() { mNextPaintCompressed = true; }
388
389
  void NotifyStyleSheetServiceSheetAdded(StyleSheet* aSheet,
390
                                         uint32_t aSheetType) override;
391
  void NotifyStyleSheetServiceSheetRemoved(StyleSheet* aSheet,
392
                                           uint32_t aSheetType) override;
393
394
0
  bool HasHandledUserInput() const override {
395
0
    return mHasHandledUserInput;
396
0
  }
397
398
  void FireResizeEvent() override;
399
400
  static PresShell* GetShellForEventTarget(nsIFrame* aFrame,
401
                                           nsIContent* aContent);
402
  static PresShell* GetShellForTouchEvent(WidgetGUIEvent* aEvent);
403
404
private:
405
  ~PresShell();
406
407
  void HandlePostedReflowCallbacks(bool aInterruptible);
408
  void CancelPostedReflowCallbacks();
409
410
  void ScheduleBeforeFirstPaint();
411
  void UnsuppressAndInvalidate();
412
413
0
  void WillCauseReflow() {
414
0
    nsContentUtils::AddScriptBlocker();
415
0
    ++mChangeNestCount;
416
0
  }
417
  nsresult DidCauseReflow();
418
  friend class ::nsAutoCauseReflowNotifier;
419
  friend class ::AutoPointerEventTargetUpdater;
420
421
  nsresult DispatchEventToDOM(WidgetEvent* aEvent,
422
                              nsEventStatus* aStatus,
423
                              nsPresShellEventCB* aEventCB);
424
  void DispatchTouchEventToDOM(WidgetEvent* aEvent,
425
                               nsEventStatus* aStatus,
426
                               nsPresShellEventCB* aEventCB,
427
                               bool aTouchIsNew);
428
429
  void     WillDoReflow();
430
431
  /**
432
   * Callback handler for whether reflow happened.
433
   *
434
   * @param aInterruptible Whether or not reflow interruption is allowed.
435
   */
436
  void     DidDoReflow(bool aInterruptible);
437
  // ProcessReflowCommands returns whether we processed all our dirty roots
438
  // without interruptions.
439
  bool     ProcessReflowCommands(bool aInterruptible);
440
  // MaybeScheduleReflow checks if posting a reflow is needed, then checks if
441
  // the last reflow was interrupted. In the interrupted case ScheduleReflow is
442
  // called off a timer, otherwise it is called directly.
443
  void     MaybeScheduleReflow();
444
  // Actually schedules a reflow.  This should only be called by
445
  // MaybeScheduleReflow and the reflow timer ScheduleReflowOffTimer
446
  // sets up.
447
  void     ScheduleReflow();
448
449
  // DoReflow returns whether the reflow finished without interruption
450
  bool DoReflow(nsIFrame* aFrame, bool aInterruptible);
451
#ifdef DEBUG
452
  void DoVerifyReflow();
453
  void VerifyHasDirtyRootAncestor(nsIFrame* aFrame);
454
#endif
455
456
  // Helper for ScrollContentIntoView
457
  void DoScrollContentIntoView();
458
459
  /**
460
   * Initialize cached font inflation preference values and do an initial
461
   * computation to determine if font inflation is enabled.
462
   *
463
   * @see nsLayoutUtils::sFontSizeInflationEmPerLine
464
   * @see nsLayoutUtils::sFontSizeInflationMinTwips
465
   * @see nsLayoutUtils::sFontSizeInflationLineThreshold
466
   */
467
  void SetupFontInflation();
468
469
  struct RenderingState {
470
    explicit RenderingState(PresShell* aPresShell)
471
      : mResolution(aPresShell->mResolution)
472
      , mRenderFlags(aPresShell->mRenderFlags)
473
0
    { }
474
    Maybe<float> mResolution;
475
    RenderFlags mRenderFlags;
476
  };
477
478
  struct AutoSaveRestoreRenderingState {
479
    explicit AutoSaveRestoreRenderingState(PresShell* aPresShell)
480
      : mPresShell(aPresShell)
481
      , mOldState(aPresShell)
482
0
    {}
483
484
    ~AutoSaveRestoreRenderingState()
485
0
    {
486
0
      mPresShell->mRenderFlags = mOldState.mRenderFlags;
487
0
      mPresShell->mResolution = mOldState.mResolution;
488
0
    }
489
490
    PresShell* mPresShell;
491
    RenderingState mOldState;
492
  };
493
  static RenderFlags ChangeFlag(RenderFlags aFlags, bool aOnOff,
494
                                eRenderFlag aFlag)
495
0
  {
496
0
    return aOnOff ? (aFlags | aFlag) : (aFlag & ~aFlag);
497
0
  }
498
499
500
  void SetRenderingState(const RenderingState& aState);
501
502
  friend class ::nsPresShellEventCB;
503
504
  bool mCaretEnabled;
505
506
#ifdef DEBUG
507
  UniquePtr<ServoStyleSet> CloneStyleSet(ServoStyleSet* aSet);
508
  bool VerifyIncrementalReflow();
509
  bool mInVerifyReflow;
510
  void ShowEventTargetDebug();
511
#endif
512
513
  void RemovePreferenceStyles();
514
515
  // methods for painting a range to an offscreen buffer
516
517
  // given a display list, clip the items within the list to
518
  // the range
519
  nsRect ClipListToRange(nsDisplayListBuilder *aBuilder,
520
                         nsDisplayList* aList,
521
                         nsRange* aRange);
522
523
  // create a RangePaintInfo for the range aRange containing the
524
  // display list needed to paint the range to a surface
525
  UniquePtr<RangePaintInfo>
526
  CreateRangePaintInfo(nsRange* aRange,
527
                       nsRect& aSurfaceRect,
528
                       bool aForPrimarySelection);
529
530
  /*
531
   * Paint the items to a new surface and return it.
532
   *
533
   * aSelection - selection being painted, if any
534
   * aRegion - clip region, if any
535
   * aArea - area that the surface occupies, relative to the root frame
536
   * aPoint - reference point, typically the mouse position
537
   * aScreenRect - [out] set to the area of the screen the painted area should
538
   *               be displayed at
539
   * aFlags - set RENDER_AUTO_SCALE to scale down large images, but it must not
540
   *          be set if a custom image was specified
541
   */
542
  already_AddRefed<SourceSurface>
543
  PaintRangePaintInfo(const nsTArray<UniquePtr<RangePaintInfo>>& aItems,
544
                      dom::Selection* aSelection,
545
                      const Maybe<CSSIntRegion>& aRegion,
546
                      nsRect aArea,
547
                      const LayoutDeviceIntPoint aPoint,
548
                      LayoutDeviceIntRect* aScreenRect,
549
                      uint32_t aFlags);
550
551
  /**
552
   * Methods to handle changes to user and UA sheet lists that we get
553
   * notified about.
554
   */
555
  void AddUserSheet(StyleSheet* aSheet);
556
  void AddAgentSheet(StyleSheet* aSheet);
557
  void AddAuthorSheet(StyleSheet* aSheet);
558
  void RemoveSheet(SheetType aType, StyleSheet* aSheet);
559
560
  // Hide a view if it is a popup
561
  void HideViewIfPopup(nsView* aView);
562
563
  // Utility method to restore the root scrollframe state
564
  void RestoreRootScrollPosition();
565
566
  void MaybeReleaseCapturingContent();
567
568
  nsresult HandleRetargetedEvent(WidgetEvent* aEvent,
569
                                 nsEventStatus* aStatus,
570
                                 nsIContent* aTarget)
571
0
  {
572
0
    PushCurrentEventInfo(nullptr, nullptr);
573
0
    mCurrentEventContent = aTarget;
574
0
    nsresult rv = NS_OK;
575
0
    if (GetCurrentEventFrame()) {
576
0
      rv = HandleEventInternal(aEvent, aStatus, true);
577
0
    }
578
0
    PopCurrentEventInfo();
579
0
    return rv;
580
0
  }
581
582
  class DelayedEvent
583
  {
584
  public:
585
0
    virtual ~DelayedEvent() { }
586
0
    virtual void Dispatch() { }
587
0
    virtual bool IsKeyPressEvent() { return false; }
588
  };
589
590
  class DelayedInputEvent : public DelayedEvent
591
  {
592
  public:
593
    void Dispatch() override;
594
595
  protected:
596
    DelayedInputEvent();
597
    ~DelayedInputEvent() override;
598
599
    WidgetInputEvent* mEvent;
600
  };
601
602
  class DelayedMouseEvent : public DelayedInputEvent
603
  {
604
  public:
605
    explicit DelayedMouseEvent(WidgetMouseEvent* aEvent);
606
  };
607
608
  class DelayedKeyEvent : public DelayedInputEvent
609
  {
610
  public:
611
    explicit DelayedKeyEvent(WidgetKeyboardEvent* aEvent);
612
    bool IsKeyPressEvent() override;
613
  };
614
615
  // Check if aEvent is a mouse event and record the mouse location for later
616
  // synth mouse moves.
617
  void RecordMouseLocation(WidgetGUIEvent* aEvent);
618
  class nsSynthMouseMoveEvent final : public nsARefreshObserver {
619
  public:
620
    nsSynthMouseMoveEvent(PresShell* aPresShell, bool aFromScroll)
621
0
      : mPresShell(aPresShell), mFromScroll(aFromScroll) {
622
0
      NS_ASSERTION(mPresShell, "null parameter");
623
0
    }
624
625
  private:
626
  // Private destructor, to discourage deletion outside of Release():
627
0
    ~nsSynthMouseMoveEvent() {
628
0
      Revoke();
629
0
    }
630
631
  public:
632
    NS_INLINE_DECL_REFCOUNTING(nsSynthMouseMoveEvent, override)
633
634
0
    void Revoke() {
635
0
      if (mPresShell) {
636
0
        mPresShell->GetPresContext()->RefreshDriver()->
637
0
          RemoveRefreshObserver(this, FlushType::Display);
638
0
        mPresShell = nullptr;
639
0
      }
640
0
    }
641
0
    void WillRefresh(TimeStamp aTime) override {
642
0
      if (mPresShell) {
643
0
        RefPtr<PresShell> shell = mPresShell;
644
0
        shell->ProcessSynthMouseMoveEvent(mFromScroll);
645
0
      }
646
0
    }
647
  private:
648
    PresShell* mPresShell;
649
    bool mFromScroll;
650
  };
651
  void ProcessSynthMouseMoveEvent(bool aFromScroll);
652
653
  void QueryIsActive();
654
  nsresult UpdateImageLockingState();
655
656
  bool InZombieDocument(nsIContent *aContent);
657
  already_AddRefed<nsIPresShell> GetParentPresShellForEventHandling();
658
  nsIContent* GetCurrentEventContent();
659
  nsIFrame* GetCurrentEventFrame() override;
660
  MOZ_CAN_RUN_SCRIPT nsresult
661
  RetargetEventToParent(WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus);
662
  void PushCurrentEventInfo(nsIFrame* aFrame, nsIContent* aContent);
663
  void PopCurrentEventInfo();
664
  /**
665
   * @param aIsHandlingNativeEvent      true when the caller (perhaps) handles
666
   *                                    an event which is caused by native
667
   *                                    event.  Otherwise, false.
668
   */
669
  nsresult HandleEventInternal(WidgetEvent* aEvent,
670
                               nsEventStatus* aStatus,
671
                               bool aIsHandlingNativeEvent,
672
                               nsIContent* aOverrideClickTarget = nullptr);
673
674
  /*
675
   * This and the next two helper methods are used to target and position the
676
   * context menu when the keyboard shortcut is used to open it.
677
   *
678
   * If another menu is open, the context menu is opened relative to the
679
   * active menuitem within the menu, or the menu itself if no item is active.
680
   * Otherwise, if the caret is visible, the menu is opened near the caret.
681
   * Otherwise, if a selectable list such as a listbox is focused, the
682
   * current item within the menu is opened relative to this item.
683
   * Otherwise, the context menu is opened at the topleft corner of the
684
   * view.
685
   *
686
   * Returns true if the context menu event should fire and false if it should
687
   * not.
688
   */
689
  bool AdjustContextMenuKeyEvent(WidgetMouseEvent* aEvent);
690
691
  //
692
  bool PrepareToUseCaretPosition(nsIWidget* aEventWidget,
693
                                 LayoutDeviceIntPoint& aTargetPt);
694
695
  // Get the selected item and coordinates in device pixels relative to root
696
  // document's root view for element, first ensuring the element is onscreen
697
  void GetCurrentItemAndPositionForElement(dom::Element* aFocusedElement,
698
                                           nsIContent **aTargetToUse,
699
                                           LayoutDeviceIntPoint& aTargetPt,
700
                                           nsIWidget *aRootWidget);
701
702
  void SynthesizeMouseMove(bool aFromScroll) override;
703
704
  PresShell* GetRootPresShell();
705
706
  nscolor GetDefaultBackgroundColorToDraw();
707
708
  DOMHighResTimeStamp GetPerformanceNowUnclamped();
709
710
  // The callback for the mPaintSuppressionTimer timer.
711
  static void sPaintSuppressionCallback(nsITimer* aTimer, void* aPresShell);
712
713
  // The callback for the mReflowContinueTimer timer.
714
  static void sReflowContinueCallback(nsITimer* aTimer, void* aPresShell);
715
  bool ScheduleReflowOffTimer();
716
717
  // Widget notificiations
718
  void WindowSizeMoveDone() override;
719
0
  void SysColorChanged() override { mPresContext->SysColorChanged(); }
720
0
  void ThemeChanged() override { mPresContext->ThemeChanged(); }
721
0
  void BackingScaleFactorChanged() override { mPresContext->UIResolutionChangedSync(); }
722
  nsIDocument* GetPrimaryContentDocument() override;
723
724
  void PausePainting() override;
725
  void ResumePainting() override;
726
727
  //////////////////////////////////////////////////////////////////////////////
728
  // Approximate frame visibility tracking implementation.
729
  //////////////////////////////////////////////////////////////////////////////
730
731
  void UpdateApproximateFrameVisibility();
732
  void DoUpdateApproximateFrameVisibility(bool aRemoveOnly);
733
734
  void ClearApproximatelyVisibleFramesList(const Maybe<OnNonvisible>& aNonvisibleAction
735
                                             = Nothing());
736
  static void ClearApproximateFrameVisibilityVisited(nsView* aView, bool aClear);
737
  static void MarkFramesInListApproximatelyVisible(const nsDisplayList& aList);
738
  void MarkFramesInSubtreeApproximatelyVisible(nsIFrame* aFrame,
739
                                               const nsRect& aRect,
740
                                               bool aRemoveOnly = false);
741
742
  void DecApproximateVisibleCount(VisibleFrames& aFrames,
743
                                  const Maybe<OnNonvisible>& aNonvisibleAction = Nothing());
744
745
  nsRevocableEventPtr<nsRunnableMethod<PresShell>> mUpdateApproximateFrameVisibilityEvent;
746
747
  // A set of frames that were visible or could be visible soon at the time
748
  // that we last did an approximate frame visibility update.
749
  VisibleFrames mApproximatelyVisibleFrames;
750
751
  nsresult SetResolutionImpl(float aResolution, bool aScaleToResolution);
752
753
  nsIContent* GetOverrideClickTarget(WidgetGUIEvent* aEvent,
754
                                     nsIFrame* aFrame);
755
#ifdef DEBUG
756
  // The reflow root under which we're currently reflowing.  Null when
757
  // not in reflow.
758
  nsIFrame* mCurrentReflowRoot;
759
#endif
760
761
#ifdef MOZ_REFLOW_PERF
762
  ReflowCountMgr* mReflowCountMgr;
763
#endif
764
765
  // This is used for synthetic mouse events that are sent when what is under
766
  // the mouse pointer may have changed without the mouse moving (eg scrolling,
767
  // change to the document contents).
768
  // It is set only on a presshell for a root document, this value represents
769
  // the last observed location of the mouse relative to that root document. It
770
  // is set to (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if the mouse isn't
771
  // over our window or there is no last observed mouse location for some
772
  // reason.
773
  nsPoint mMouseLocation;
774
  // This is an APZ state variable that tracks the target guid for the last
775
  // mouse event that was processed (corresponding to mMouseLocation). This is
776
  // needed for the synthetic mouse events.
777
  layers::ScrollableLayerGuid mMouseEventTargetGuid;
778
779
  // mStyleSet owns it but we maintain a ref, may be null
780
  RefPtr<StyleSheet> mPrefStyleSheet;
781
782
  // Set of frames that we should mark with NS_FRAME_HAS_DIRTY_CHILDREN after
783
  // we finish reflowing mCurrentReflowRoot.
784
  nsTHashtable<nsPtrHashKey<nsIFrame> > mFramesToDirty;
785
786
  nsTArray<nsAutoPtr<DelayedEvent> > mDelayedEvents;
787
private:
788
  nsIFrame* mCurrentEventFrame;
789
  nsCOMPtr<nsIContent> mCurrentEventContent;
790
  nsTArray<nsIFrame*> mCurrentEventFrameStack;
791
  nsCOMArray<nsIContent> mCurrentEventContentStack;
792
  nsRevocableEventPtr<nsSynthMouseMoveEvent> mSynthMouseMoveEvent;
793
  nsCOMPtr<nsIContent> mLastAnchorScrolledTo;
794
  RefPtr<nsCaret> mCaret;
795
  RefPtr<nsCaret> mOriginalCaret;
796
  nsCallbackEventRequest* mFirstCallbackEventRequest;
797
  nsCallbackEventRequest* mLastCallbackEventRequest;
798
799
  TouchManager mTouchManager;
800
801
  RefPtr<ZoomConstraintsClient> mZoomConstraintsClient;
802
  RefPtr<MobileViewportManager> mMobileViewportManager;
803
804
  RefPtr<AccessibleCaretEventHub> mAccessibleCaretEventHub;
805
806
  // This timer controls painting suppression.  Until it fires
807
  // or all frames are constructed, we won't paint anything but
808
  // our <body> background and scrollbars.
809
  nsCOMPtr<nsITimer> mPaintSuppressionTimer;
810
811
  nsCOMPtr<nsITimer> mDelayedPaintTimer;
812
813
  // The `performance.now()` value when we last started to process reflows.
814
  DOMHighResTimeStamp mLastReflowStart;
815
816
  TimeStamp mLoadBegin;  // used to time loads
817
818
  // Information needed to properly handle scrolling content into view if the
819
  // pre-scroll reflow flush can be interrupted.  mContentToScrollTo is
820
  // non-null between the initial scroll attempt and the first time we finish
821
  // processing all our dirty roots.  mContentToScrollTo has a content property
822
  // storing the details for the scroll operation, see ScrollIntoViewData above.
823
  nsCOMPtr<nsIContent> mContentToScrollTo;
824
825
  nscoord mLastAnchorScrollPositionY;
826
827
  // Information about live content (which still stay in DOM tree).
828
  // Used in case we need re-dispatch event after sending pointer event,
829
  // when target of pointer event was deleted during executing user handlers.
830
  nsCOMPtr<nsIContent> mPointerEventTarget;
831
832
  int32_t mActiveSuppressDisplayport;
833
834
  // The focus sequence number of the last processed input event
835
  uint64_t mAPZFocusSequenceNumber;
836
  // The focus information needed for async keyboard scrolling
837
  FocusTarget mAPZFocusTarget;
838
839
  bool mDocumentLoading : 1;
840
  bool mIgnoreFrameDestruction : 1;
841
  bool mHaveShutDown : 1;
842
  bool mLastRootReflowHadUnconstrainedBSize : 1;
843
  bool mNoDelayedMouseEvents : 1;
844
  bool mNoDelayedKeyEvents : 1;
845
846
  // Indicates that it is safe to unlock painting once all pending reflows
847
  // have been processed.
848
  bool mShouldUnsuppressPainting : 1;
849
850
  bool mApproximateFrameVisibilityVisited : 1;
851
852
  bool mNextPaintCompressed : 1;
853
854
  bool mHasCSSBackgroundColor : 1;
855
856
  // Whether content should be scaled by the resolution amount. If this is
857
  // not set, a transform that scales by the inverse of the resolution is
858
  // applied to rendered layers.
859
  bool mScaleToResolution : 1;
860
861
  // Whether the last chrome-only escape key event is consumed.
862
  bool mIsLastChromeOnlyEscapeKeyConsumed : 1;
863
864
  // Whether the widget has received a paint message yet.
865
  bool mHasReceivedPaintMessage : 1;
866
867
  bool mIsLastKeyDownCanceled : 1;
868
869
  // Whether we have ever handled a user input event
870
  bool mHasHandledUserInput : 1;
871
872
#ifdef NIGHTLY_BUILD
873
  // Whether we should dispatch keypress events even for non-printable keys
874
  // for keeping backward compatibility.
875
  bool mForceDispatchKeyPressEventsForNonPrintableKeys : 1;
876
  // Whether mForceDispatchKeyPressEventsForNonPrintableKeys is initialized.
877
  bool mInitializedForceDispatchKeyPressEventsForNonPrintableKeys : 1;
878
#endif // #ifdef NIGHTLY_BUILD
879
880
  static bool sDisableNonTestMouseEvents;
881
882
  TimeStamp mLastOSWake;
883
884
  static TimeStamp sLastInputCreated;
885
  static TimeStamp sLastInputProcessed;
886
887
  static bool sProcessInteractable;
888
};
889
890
} // namespace mozilla
891
892
#endif // mozilla_PresShell_h