PresShell.h 123 KB
Newer Older
1
2
3
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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
8

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

9
10
#ifndef mozilla_PresShell_h
#define mozilla_PresShell_h
11

12
13
#include "mozilla/PresShellForwards.h"

14
15
16
17
18
#include <stdio.h>  // for FILE definition
#include "FrameMetrics.h"
#include "GeckoProfiler.h"
#include "TouchManager.h"
#include "Units.h"
19
#include "Visibility.h"
20
21
#include "gfxPoint.h"
#include "mozilla/ArenaObjectID.h"
22
#include "mozilla/Attributes.h"
23
#include "mozilla/EventForwards.h"
24
#include "mozilla/FlushType.h"
25
#include "mozilla/MemoryReporting.h"
26
#include "mozilla/ScrollTypes.h"
27
#include "mozilla/ServoStyleSet.h"
28
#include "mozilla/ServoStyleConsts.h"
29
#include "mozilla/StaticPtr.h"
30
#include "mozilla/StyleSheet.h"
31
#include "mozilla/UniquePtr.h"
32
33
34
#include "mozilla/WeakPtr.h"
#include "mozilla/dom/HTMLDocumentBinding.h"
#include "mozilla/layers/FocusTarget.h"
35
#include "mozilla/layout/LayoutTelemetryTools.h"
36
37
38
39
40
#include "nsChangeHint.h"
#include "nsClassHashtable.h"
#include "nsColor.h"
#include "nsCOMArray.h"
#include "nsCoord.h"
41
#include "nsDOMNavigationTiming.h"
42
43
44
45
#include "nsFrameManager.h"
#include "nsFrameState.h"
#include "nsHashKeys.h"
#include "nsIContent.h"
46
47
48
#include "nsIObserver.h"
#include "nsISelectionController.h"
#include "nsIWidget.h"
49
50
51
#include "nsQueryFrame.h"
#include "nsMargin.h"
#include "nsPresArena.h"
52
#include "nsPresContext.h"
53
54
#include "nsRect.h"
#include "nsRefPtrHashtable.h"
55
#include "nsRefreshDriver.h"
56
57
#include "nsRegionFwd.h"
#include "nsStringFwd.h"
58
#include "nsStubDocumentObserver.h"
59
#include "nsTHashtable.h"
60
61
#include "nsThreadUtils.h"
#include "nsWeakReference.h"
62

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
class AutoPointerEventTargetUpdater;
class AutoWeakFrame;
class gfxContext;
class MobileViewportManager;
#ifdef ACCESSIBILITY
class nsAccessibilityService;
#endif
class nsARefreshObserver;
class nsAutoCauseReflowNotifier;
class nsCanvasFrame;
class nsCaret;
class nsCSSFrameConstructor;
class nsDisplayList;
class nsDisplayListBuilder;
class nsDocShell;
class nsFrameSelection;
79
class nsIDocShell;
80
81
82
class nsIFrame;
class nsILayoutHistoryState;
class nsINode;
83
class nsPageSequenceFrame;
84
85
86
87
88
89
class nsIReflowCallback;
class nsIScrollableFrame;
class nsITimer;
class nsPIDOMWindowOuter;
class nsAPostRefreshObserver;
class nsPresShellEventCB;
90
class nsRange;
91
92
93
94
95
class nsRefreshDriver;
class nsRegion;
class nsView;
class nsViewManager;
class nsWindowSizes;
96
struct RangePaintInfo;
97
98
99
100
#ifdef MOZ_REFLOW_PERF
class ReflowCountMgr;
#endif
class WeakFrame;
101
class ZoomConstraintsClient;
102

103
104
105
106
107
108
template <class E>
class nsCOMArray;

struct nsCallbackEventRequest;
struct nsPoint;
struct nsRect;
109

110
namespace mozilla {
111
112
113
114
115
116
117
118
119
120
121
class AccessibleCaretEventHub;
class EventStates;
class GeckoMVMContext;
class OverflowChangedTracker;
class StyleSheet;

#ifdef ACCESSIBILITY
namespace a11y {
class DocAccessible;
}  // namespace a11y
#endif
122

123
namespace dom {
124
class Document;
125
class Element;
126
127
class Event;
class HTMLSlotElement;
128
class Selection;
129
130
}  // namespace dom

131
132
133
134
135
136
137
138
139
140
141
namespace gfx {
class SourceSurface;
}  // namespace gfx

namespace layers {
class LayerManager;
}  // namespace layers

namespace layout {
class ScrollAnchorContainer;
}  // namespace layout
142

143
144
145
146
147
148
149
150
// 039d8ffc-fa55-42d7-a53a-388cb129b052
#define NS_PRESSHELL_IID                             \
  {                                                  \
    0x039d8ffc, 0xfa55, 0x42d7, {                    \
      0xa5, 0x3a, 0x38, 0x8c, 0xb1, 0x29, 0xb0, 0x52 \
    }                                                \
  }

151
152
153
154
155
156
157
158
159
160
161
162
163
#undef NOISY_INTERRUPTIBLE_REFLOW

/**
 * Presentation shell. Presentation shells are the controlling point for
 * managing the presentation of a document.  The presentation shell holds a
 * live reference to the document, the presentation context, the style
 * manager, the style set and the root frame.
 *
 * When this object is Release'd, it will release the document, the
 * presentation context, the style manager, the style set and the root frame.
 */

class PresShell final : public nsStubDocumentObserver,
164
165
                        public nsISelectionController,
                        public nsIObserver,
166
                        public nsSupportsWeakReference {
167
  typedef dom::Document Document;
168
  typedef dom::Element Element;
169
170
171
172
  typedef gfx::SourceSurface SourceSurface;
  typedef layers::FocusTarget FocusTarget;
  typedef layers::FrameMetrics FrameMetrics;
  typedef layers::LayerManager LayerManager;
173

174
175
176
177
  // 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;

178
 public:
179
  explicit PresShell(Document* aDocument);
180
181
182
183

  // nsISupports
  NS_DECL_ISUPPORTS

184
185
  NS_DECLARE_STATIC_IID_ACCESSOR(NS_PRESSHELL_IID)

186
  static bool AccessibleCaretEnabled(nsIDocShell* aDocShell);
187

188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
  /**
   * Return the active content currently capturing the mouse if any.
   */
  static nsIContent* GetCapturingContent() {
    return sCapturingContentInfo.mContent;
  }

  /**
   * Allow or disallow mouse capturing.
   */
  static void AllowMouseCapture(bool aAllowed) {
    sCapturingContentInfo.mAllowed = aAllowed;
  }

  /**
   * Returns true if there is an active mouse capture that wants to prevent
   * drags.
   */
  static bool IsMouseCapturePreventingDrag() {
    return sCapturingContentInfo.mPreventDrag && sCapturingContentInfo.mContent;
  }

  static void ClearMouseCaptureOnView(nsView* aView);

  // If a frame in the subtree rooted at aFrame is capturing the mouse then
  // clears that capture.
  static void ClearMouseCapture(nsIFrame* aFrame);

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#ifdef ACCESSIBILITY
  /**
   * Return the document accessible for this PresShell if there is one.
   */
  a11y::DocAccessible* GetDocAccessible() const { return mDocAccessible; }

  /**
   * Set the document accessible for this PresShell.
   */
  void SetDocAccessible(a11y::DocAccessible* aDocAccessible) {
    mDocAccessible = aDocAccessible;
  }

  /**
   * Return true if accessibility is active.
   */
  static bool IsAccessibilityActive();

  /**
   * Return accessibility service if accessibility is active.
   */
  static nsAccessibilityService* GetAccessibilityService();
#endif  // #ifdef ACCESSIBILITY

240
  void Init(nsPresContext*, nsViewManager*);
241

242
243
244
245
246
247
248
249
  /**
   * All callers are responsible for calling |Destroy| after calling
   * |EndObservingDocument|.  It needs to be separate only because form
   * controls incorrectly store their data in the frames rather than the
   * content model and printing calls |EndObservingDocument| multiple
   * times to make form controls behave nicely when printed.
   */
  void Destroy();
250

251
  bool IsDestroying() { return mIsDestroying; }
252

253
254
255
256
257
258
259
260
  /**
   * All frames owned by the shell are allocated from an arena.  They
   * are also recycled using free lists.  Separate free lists are
   * maintained for each frame type (aID), which must always correspond
   * to the same aSize value.  AllocateFrame is infallible and will abort
   * on out-of-memory.
   */
  void* AllocateFrame(nsQueryFrame::FrameIID aID, size_t aSize) {
261
262
263
264
265
266
267
268
269
270
271
272
#define FRAME_ID(classname, ...)                                  \
  static_assert(size_t(nsQueryFrame::FrameIID::classname##_id) == \
                    size_t(eArenaObjectID_##classname),           \
                "");
#define ABSTRACT_FRAME_ID(classname)                              \
  static_assert(size_t(nsQueryFrame::FrameIID::classname##_id) == \
                    size_t(eArenaObjectID_##classname),           \
                "");
#include "mozilla/FrameIdList.h"
#undef FRAME_ID
#undef ABSTRACT_FRAME_ID
    return AllocateByObjectID(ArenaObjectID(size_t(aID)), aSize);
273
  }
274

275
  void FreeFrame(nsQueryFrame::FrameIID aID, void* aPtr) {
276
    return FreeByObjectID(ArenaObjectID(size_t(aID)), aPtr);
277
278
279
  }

  void* AllocateByObjectID(ArenaObjectID aID, size_t aSize) {
280
    void* result = mFrameArena.Allocate(aID, aSize);
281
282
283
284
285
286
287
    RecordAlloc(result);
    return result;
  }

  void FreeByObjectID(ArenaObjectID aID, void* aPtr) {
    RecordFree(aPtr);
    if (!mIsDestroying) {
288
      mFrameArena.Free(aID, aPtr);
289
290
291
292
293
294
295
296
297
298
299
300
301
302
    }
  }

  Document* GetDocument() const { return mDocument; }

  nsPresContext* GetPresContext() const { return mPresContext; }

  nsViewManager* GetViewManager() const { return mViewManager; }

  nsRefreshDriver* GetRefreshDriver() const;

  nsCSSFrameConstructor* FrameConstructor() const {
    return mFrameConstructor.get();
  }
303

304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
  /**
   * FrameSelection will return the Frame based selection API.
   * You cannot go back and forth anymore with QI between nsIDOM sel and
   * nsIFrame sel.
   */
  already_AddRefed<nsFrameSelection> FrameSelection();

  /**
   * ConstFrameSelection returns an object which methods are safe to use for
   * example in nsIFrame code.
   */
  const nsFrameSelection* ConstFrameSelection() const { return mSelection; }

  // Start receiving notifications from our document. If called after Destroy,
  // this will be ignored.
  void BeginObservingDocument();

  // Stop receiving notifications from our document. If called after Destroy,
  // this will be ignored.
  void EndObservingDocument();

  bool IsObservingDocument() const { return mIsObservingDocument; }

  /**
   * Return whether Initialize() was previously called.
   */
  bool DidInitialize() const { return mDidInitialize; }

  /**
   * Perform initialization. Constructs the frame for the root content
   * object and then enqueues a reflow of the frame model.
   *
   * Callers of this method must hold a reference to this shell that
   * is guaranteed to survive through arbitrary script execution.
   * Calling Initialize can execute arbitrary script.
   */
340
  MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult Initialize();
341
342
343
344
345
346

  /**
   * Reflow the frame model into a new width and height.  The
   * coordinates for aWidth and aHeight must be in standard nscoord's.
   */
  MOZ_CAN_RUN_SCRIPT nsresult
347
348
  ResizeReflow(nscoord aWidth, nscoord aHeight,
               ResizeReflowOptions = ResizeReflowOptions::NoOption);
349
350
351
  MOZ_CAN_RUN_SCRIPT nsresult ResizeReflowIgnoreOverride(nscoord aWidth,
                                                         nscoord aHeight,
                                                         ResizeReflowOptions);
352

353
354
355
356
357
358
  /**
   * Add this pres shell to the refresh driver to be observed for resize
   * event if applicable.
   */
  void AddResizeEventFlushObserverIfNeeded();

359
360
361
362
363
 private:
  /**
   * This is what ResizeReflowIgnoreOverride does when not shrink-wrapping (that
   * is, when ResizeReflowOptions::BSizeLimit is not specified).
   */
364
  void SimpleResizeReflow(nscoord aWidth, nscoord aHeight, ResizeReflowOptions);
365
366

 public:
367
  /**
368
369
   * Returns true if this document has a potentially zoomable viewport,
   * allowing for its layout and visual viewports to diverge.
370
   */
371
372
373
  bool GetIsViewportOverridden() const {
    return (mMobileViewportManager != nullptr);
  }
374
375

  /**
376
377
   * Note that the assumptions that determine whether we have a potentially
   * zoomable viewport may have changed.
378
379
380
   */
  void UpdateViewportOverridden(bool aAfterInitialization);

381
382
383
384
385
386
387
388
389
390
391
392
  /**
   * Returns true if this document uses mobile viewport sizing (including
   * processing of <meta name="viewport"> tags).
   *
   * Note that having a MobileViewportManager does not necessarily mean using
   * mobile viewport sizing, as with desktop zooming we can have a
   * MobileViewportManager on desktop, but we only want to do mobile viewport
   * sizing on mobile. (TODO: Rename MobileViewportManager to reflect its more
   * general role.)
   */
  bool UsesMobileViewportSizing() const;

393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
  /**
   * Get the MobileViewportManager used to manage the document's mobile
   * viewport. Will return null in situations where we don't have a mobile
   * viewport, and for documents that are not the root content document.
   */
  RefPtr<MobileViewportManager> GetMobileViewportManager() const;

  /**
   * Return true if the presshell expects layout flush.
   */
  bool IsLayoutFlushObserver() {
    return GetPresContext()->RefreshDriver()->IsLayoutFlushObserver(this);
  }

  /**
   * Called when document load completes.
   */
  void LoadComplete();
  /**
   * This calls through to the frame manager to get the root frame.
   */
  nsIFrame* GetRootFrame() const { return mFrameManager->GetRootFrame(); }

  /*
   * Get root scroll frame from FrameManager()->GetRootFrame().
   */
  nsIFrame* GetRootScrollFrame() const;

  /*
   * The same as GetRootScrollFrame, but returns an nsIScrollableFrame
   */
  nsIScrollableFrame* GetRootScrollFrameAsScrollable() const;

  /**
   * Get the current focused content or DOM selection that should be the
   * target for scrolling.
   */
  already_AddRefed<nsIContent> GetContentForScrolling() const;

  /**
   * Get the DOM selection that should be the target for scrolling, if there
   * is no focused content.
   */
  already_AddRefed<nsIContent> GetSelectedContentForScrolling() const;

  /**
   * Gets nearest scrollable frame from the specified content node. The frame
   * is scrollable with overflow:scroll or overflow:auto in some direction when
   * aDirection is eEither.  Otherwise, this returns a nearest frame that is
   * scrollable in the specified direction.
   */
  nsIScrollableFrame* GetScrollableFrameToScrollForContent(
      nsIContent* aContent, ScrollableDirection aDirection);

  /**
   * Gets nearest scrollable frame from current focused content or DOM
   * selection if there is no focused content. The frame is scrollable with
   * overflow:scroll or overflow:auto in some direction when aDirection is
   * eEither.  Otherwise, this returns a nearest frame that is scrollable in
   * the specified direction.
   */
  nsIScrollableFrame* GetScrollableFrameToScroll(
      ScrollableDirection aDirection);

  /**
   * Gets nearest ancestor scrollable frame from aFrame.  The frame is
   * scrollable with overflow:scroll or overflow:auto in some direction when
   * aDirection is eEither.  Otherwise, this returns a nearest frame that is
   * scrollable in the specified direction.
   */
  nsIScrollableFrame* GetNearestScrollableFrame(nsIFrame* aFrame,
                                                ScrollableDirection aDirection);

  /**
   * Returns the page sequence frame associated with the frame hierarchy.
   * Returns nullptr if not a paginated view.
   */
470
  nsPageSequenceFrame* GetPageSequenceFrame() const;
471

472
473
474
475
476
477
478
479
480
481
482
483
484
485
  /**
   * Returns the canvas frame associated with the frame hierarchy.
   * Returns nullptr if is XUL document.
   */
  nsCanvasFrame* GetCanvasFrame() const;

  void PostPendingScrollAnchorSelection(
      layout::ScrollAnchorContainer* aContainer);
  void FlushPendingScrollAnchorSelections();
  void PostPendingScrollAnchorAdjustment(
      layout::ScrollAnchorContainer* aContainer);

  void CancelAllPendingReflows();

486
  MOZ_CAN_RUN_SCRIPT_BOUNDARY void NotifyCounterStylesAreDirty();
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560

  bool FrameIsAncestorOfDirtyRoot(nsIFrame* aFrame) const;

  /**
   * Destroy the frames for aElement, and reconstruct them asynchronously if
   * needed.
   *
   * Note that this may destroy frames for an ancestor instead.
   */
  void DestroyFramesForAndRestyle(Element* aElement);

  /**
   * Handles all the layout stuff needed when the slot assignment for an element
   * is about to change.
   *
   * Only called when the slot attribute of the element changes, the rest of
   * the changes should be handled in ShadowRoot.
   */
  void SlotAssignmentWillChange(Element& aElement,
                                dom::HTMLSlotElement* aOldSlot,
                                dom::HTMLSlotElement* aNewSlot);

  void PostRecreateFramesFor(Element*);
  void RestyleForAnimation(Element*, RestyleHint);

  /**
   * Determine if it is safe to flush all pending notifications.
   */
  bool IsSafeToFlush() const;

  /**
   * Informs the document's FontFaceSet that the refresh driver ticked,
   * flushing style and layout.
   */
  void NotifyFontFaceSetOnRefresh();

  // Removes ourself from the list of layout / style / and resize refresh driver
  // observers.
  //
  // Right now this is only used for documents in the BFCache, so if you want to
  // use this for anything else you need to ensure we don't end up in those
  // lists after calling this, but before calling StartObservingRefreshDriver
  // again.
  //
  // That is handled by the mDocument->GetBFCacheEntry checks in
  // DoObserve*Flushes functions, though that could conceivably become a boolean
  // member in the shell if needed.
  //
  // Callers are responsible of manually calling StartObservingRefreshDriver
  // again.
  void StopObservingRefreshDriver();
  void StartObservingRefreshDriver();

  bool ObservingStyleFlushes() const { return mObservingStyleFlushes; }
  bool ObservingLayoutFlushes() const { return mObservingLayoutFlushes; }

  void ObserveStyleFlushes() {
    if (!ObservingStyleFlushes()) {
      DoObserveStyleFlushes();
    }
  }

  /**
   * Callbacks will be called even if reflow itself fails for
   * some reason.
   */
  nsresult PostReflowCallback(nsIReflowCallback* aCallback);
  void CancelReflowCallback(nsIReflowCallback* aCallback);

  void ScheduleBeforeFirstPaint();
  void UnsuppressAndInvalidate();

  void ClearFrameRefs(nsIFrame* aFrame);

561
562
563
564
565
566
  // Clears the selection of the older focused frame selection if any.
  void FrameSelectionWillTakeFocus(nsFrameSelection&);

  // Clears and repaint mFocusedFrameSelection if it matches the argument.
  void FrameSelectionWillLoseFocus(nsFrameSelection&);

567
568
569
570
571
572
573
574
575
576
577
  /**
   * Get a reference rendering context. This is a context that should not
   * be rendered to, but is suitable for measuring text and performing
   * other non-rendering operations. Guaranteed to return non-null.
   */
  already_AddRefed<gfxContext> CreateReferenceRenderingContext();

  /**
   * Scrolls the view of the document so that the given area of a frame
   * is visible, if possible. Layout is not flushed before scrolling.
   *
578
579
   * @param aRect Relative to aFrame. The rect edges will be respected even if
   * the rect is empty.
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
   * @param aVertical see ScrollContentIntoView and ScrollAxis
   * @param aHorizontal see ScrollContentIntoView and ScrollAxis
   * @param aScrollFlags if SCROLL_FIRST_ANCESTOR_ONLY is set, only the
   * nearest scrollable ancestor is scrolled, otherwise all
   * scrollable ancestors may be scrolled if necessary
   * if SCROLL_OVERFLOW_HIDDEN is set then we may scroll in a direction
   * even if overflow:hidden is specified in that direction; otherwise
   * we will not scroll in that direction when overflow:hidden is
   * set for that direction
   * If SCROLL_NO_PARENT_FRAMES is set then we only scroll
   * nodes in this document, not in any parent documents which
   * contain this document in a iframe or the like.
   * If SCROLL_IGNORE_SCROLL_MARGIN_AND_PADDING is set we ignore scroll-margin
   * value specified for |aFrame| and scroll-padding value for the scroll
   * container. This option is typically used to locate poped-up frames into
   * view.
   * @return true if any scrolling happened, false if no scrolling happened
   */
598
  MOZ_CAN_RUN_SCRIPT
599
600
601
602
603
604
605
606
607
  bool ScrollFrameRectIntoView(nsIFrame* aFrame, const nsRect& aRect,
                               ScrollAxis aVertical, ScrollAxis aHorizontal,
                               ScrollFlags aScrollFlags);

  /**
   * Suppress notification of the frame manager that frames are
   * being destroyed.
   */
  void SetIgnoreFrameDestruction(bool aIgnore);
608

609
610
611
612
  /**
   * Get the AccessibleCaretEventHub, if it exists. AddRefs it.
   */
  already_AddRefed<AccessibleCaretEventHub> GetAccessibleCaretEventHub() const;
613

614
615
616
617
  /**
   * Get the caret, if it exists. AddRefs it.
   */
  already_AddRefed<nsCaret> GetCaret() const;
618

619
620
621
622
623
624
625
626
627
628
629
630
631
632
  /**
   * Set the current caret to a new caret. To undo this, call RestoreCaret.
   */
  void SetCaret(nsCaret* aNewCaret);

  /**
   * Restore the caret to the original caret that this pres shell was created
   * with.
   */
  void RestoreCaret();

  dom::Selection* GetCurrentSelection(SelectionType aSelectionType);

  /**
633
634
   * Gets the last selection that took focus in this document. This is basically
   * the frame selection that's visible to the user.
635
   */
636
  nsFrameSelection* GetLastFocusedFrameSelection();
637
638
639
640
641

  /**
   * Interface to dispatch events via the presshell
   * @note The caller must have a strong reference to the PresShell.
   */
642
  MOZ_CAN_RUN_SCRIPT
643
644
645
646
647
648
  nsresult HandleEventWithTarget(WidgetEvent* aEvent, nsIFrame* aFrame,
                                 nsIContent* aContent,
                                 nsEventStatus* aEventStatus,
                                 bool aIsHandlingNativeEvent = false,
                                 nsIContent** aTargetContent = nullptr,
                                 nsIContent* aOverrideClickTarget = nullptr) {
649
650
651
652
653
654
    MOZ_ASSERT(aEvent);
    EventHandler eventHandler(*this);
    return eventHandler.HandleEventWithTarget(
        aEvent, aFrame, aContent, aEventStatus, aIsHandlingNativeEvent,
        aTargetContent, aOverrideClickTarget);
  }
655

656
657
658
  /**
   * Dispatch event to content only (NOT full processing)
   */
659
  MOZ_CAN_RUN_SCRIPT
660
661
662
663
664
665
666
  nsresult HandleDOMEventWithTarget(nsIContent* aTargetContent,
                                    WidgetEvent* aEvent,
                                    nsEventStatus* aStatus);

  /**
   * Dispatch event to content only (NOT full processing)
   */
667
  MOZ_CAN_RUN_SCRIPT
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
  nsresult HandleDOMEventWithTarget(nsIContent* aTargetContent,
                                    dom::Event* aEvent, nsEventStatus* aStatus);

  /**
   * Return whether or not the event is valid to be dispatched
   */
  bool CanDispatchEvent(const WidgetGUIEvent* aEvent = nullptr) const;

  /**
   * Gets the current target event frame from the PresShell
   */
  nsIFrame* GetCurrentEventFrame();

  /**
   * Gets the current target event frame from the PresShell
   */
  already_AddRefed<nsIContent> GetEventTargetContent(WidgetEvent* aEvent);

  /**
   * Get and set the history state for the current document
   */
  nsresult CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState);
690

691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
  /**
   * Determine if reflow is currently locked
   * returns true if reflow is locked, false otherwise
   */
  bool IsReflowLocked() const { return mIsReflowing; }

  /**
   * Called to find out if painting is suppressed for this presshell.  If it is
   * suppressd, we don't allow the painting of any layer but the background, and
   * we don't recur into our children.
   */
  bool IsPaintingSuppressed() const { return mPaintingSuppressed; }

  /**
   * Pause painting by freezing the refresh driver of this and all parent
   * presentations. This may not have the desired effect if this pres shell
   * has its own refresh driver.
   */
  void PausePainting();

  /**
   * Resume painting by thawing the refresh driver of this and all parent
   * presentations. This may not have the desired effect if this pres shell
   * has its own refresh driver.
   */
  void ResumePainting();

  /**
   * Unsuppress painting.
   */
  void UnsuppressPainting();

  /**
   * Reconstruct frames for all elements in the document
   */
726
  MOZ_CAN_RUN_SCRIPT void ReconstructFrames();
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752

  /**
   * See if reflow verification is enabled. To enable reflow verification add
   * "verifyreflow:1" to your MOZ_LOG environment variable (any non-zero
   * debug level will work). Or, call SetVerifyReflowEnable with true.
   */
  static bool GetVerifyReflowEnable();

  /**
   * Set the verify-reflow enable flag.
   */
  static void SetVerifyReflowEnable(bool aEnabled);

  nsIFrame* GetAbsoluteContainingBlock(nsIFrame* aFrame);

#ifdef MOZ_REFLOW_PERF
  void DumpReflows();
  void CountReflows(const char* aName, nsIFrame* aFrame);
  void PaintCount(const char* aName, gfxContext* aRenderingContext,
                  nsPresContext* aPresContext, nsIFrame* aFrame,
                  const nsPoint& aOffset, uint32_t aColor);
  void SetPaintFrameCount(bool aOn);
  bool IsPaintingFrameCounts();
#endif  // #ifdef MOZ_REFLOW_PERF

  // Debugging hooks
753
#ifdef DEBUG
754
  void ListComputedStyles(FILE* out, int32_t aIndent = 0);
755
756
#endif
#if defined(DEBUG) || defined(MOZ_LAYOUT_DEBUGGER)
757
  void ListStyleSheets(FILE* out, int32_t aIndent = 0);
758
#endif
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824

  /**
   * Stop all active elements (plugins and the caret) in this presentation and
   * in the presentations of subdocuments.  Resets painting to a suppressed
   * state.
   * XXX this should include image animations
   */
  void Freeze();
  bool IsFrozen() { return mFrozen; }

  /**
   * Restarts active elements (plugins) in this presentation and in the
   * presentations of subdocuments, then do a full invalidate of the content
   * area.
   */
  void Thaw();

  void FireOrClearDelayedEvents(bool aFireEvents);

  /**
   * When this shell is disconnected from its containing docshell, we
   * lose our container pointer.  However, we'd still like to be able to target
   * user events at the docshell's parent.  This pointer allows us to do that.
   * It should not be used for any other purpose.
   */
  void SetForwardingContainer(const WeakPtr<nsDocShell>& aContainer);

  /**
   * Render the document into an arbitrary gfxContext
   * Designed for getting a picture of a document or a piece of a document
   * Note that callers will generally want to call FlushPendingNotifications
   * to get an up-to-date view of the document
   * @param aRect is the region to capture into the offscreen buffer, in the
   * root frame's coordinate system (if aIgnoreViewportScrolling is false)
   * or in the root scrolled frame's coordinate system
   * (if aIgnoreViewportScrolling is true). The coordinates are in appunits.
   * @param aFlags see below;
   *   set RenderDocumentFlags::IsUntrusted if the contents may be passed to
   * malicious agents. E.g. we might choose not to paint the contents of
   * sensitive widgets such as the file name in a file upload widget, and we
   * might choose not to paint themes.
   *   set RenderDocumentFlags::IgnoreViewportScrolling to ignore clipping and
   *  scrollbar painting due to scrolling in the viewport
   *   set RenderDocumentFlags::DrawCaret to draw the caret if one would be
   *  visible (by default the caret is never drawn)
   *   set RenderDocumentFlags::UseWidgetLayers to force rendering to go
   *  through the layer manager for the window. This may be unexpectedly slow
   * (if the layer manager must read back data from the GPU) or low-quality
   * (if the layer manager reads back pixel data and scales it
   * instead of rendering using the appropriate scaling). It may also
   * slow everything down if the area rendered does not correspond to the
   * normal visible area of the window.
   *   set RenderDocumentFlags::AsyncDecodeImages to avoid having images
   * synchronously decoded during rendering.
   * (by default images decode synchronously with RenderDocument)
   *   set RenderDocumentFlags::DocumentRelative to render the document as if
   * there has been no scrolling and interpret |aRect| relative to the document
   * instead of the CSS viewport. Only considered if
   * RenderDocumentFlags::IgnoreViewportScrolling is set or the document is in
   * ignore viewport scrolling mode
   * (PresShell::SetIgnoreViewportScrolling/IgnoringViewportScrolling).
   * @param aBackgroundColor a background color to render onto
   * @param aRenderedContext the gfxContext to render to. We render so that
   * one CSS pixel in the source document is rendered to one unit in the current
   * transform.
   */
825
  nsresult RenderDocument(const nsRect& aRect, RenderDocumentFlags aFlags,
826
                          nscolor aBackgroundColor,
827
                          gfxContext* aRenderedContext);
828

829
830
831
832
833
834
  /**
   * Renders a node aNode to a surface and returns it. The aRegion may be used
   * to clip the rendering. This region is measured in CSS pixels from the
   * edge of the presshell area. The aPoint, aScreenRect and aFlags arguments
   * function in a similar manner as RenderSelection.
   */
835
836
837
838
839
  already_AddRefed<SourceSurface> RenderNode(nsINode* aNode,
                                             const Maybe<CSSIntRegion>& aRegion,
                                             const LayoutDeviceIntPoint aPoint,
                                             LayoutDeviceIntRect* aScreenRect,
                                             RenderImageFlags aFlags);
840

841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
  /**
   * Renders a selection to a surface and returns it. This method is primarily
   * intended to create the drag feedback when dragging a selection.
   *
   * aScreenRect will be filled in with the bounding rectangle of the
   * selection area on screen.
   *
   * If the area of the selection is large and the RenderImageFlags::AutoScale
   * is set, the image will be scaled down. The argument aPoint is used in this
   * case as a reference point when determining the new screen rectangle after
   * scaling. Typically, this will be the mouse position, so that the screen
   * rectangle is positioned such that the mouse is over the same point in the
   * scaled image as in the original. When scaling does not occur, the mouse
   * point isn't used because the position can be determined from the displayed
   * frames.
   */
857
  already_AddRefed<SourceSurface> RenderSelection(
858
      dom::Selection* aSelection, const LayoutDeviceIntPoint aPoint,
859
      LayoutDeviceIntRect* aScreenRect, RenderImageFlags aFlags);
860

861
862
  void AddAutoWeakFrame(AutoWeakFrame* aWeakFrame);
  void AddWeakFrame(WeakFrame* aWeakFrame);
863

864
865
  void RemoveAutoWeakFrame(AutoWeakFrame* aWeakFrame);
  void RemoveWeakFrame(WeakFrame* aWeakFrame);
866

867
868
869
870
871
872
873
874
  /**
   * Stop or restart non synthetic test mouse event handling on *all*
   * presShells.
   *
   * @param aDisable If true, disable all non synthetic test mouse
   * events on all presShells.  Otherwise, enable them.
   */
  void DisableNonTestMouseEvents(bool aDisable);
875

876
877
878
879
880
881
882
883
884
  /**
   * Record the background color of the most recently drawn canvas. This color
   * is composited on top of the user's default background color and then used
   * to draw the background color of the canvas. See PresShell::Paint,
   * PresShell::PaintDefaultBackground, and nsDocShell::SetupNewViewer;
   * bug 488242, bug 476557 and other bugs mentioned there.
   */
  void SetCanvasBackground(nscolor aColor) { mCanvasBackgroundColor = aColor; }
  nscolor GetCanvasBackground() { return mCanvasBackgroundColor; }
885

886
887
888
889
890
891
892
893
894
895
896
  /**
   * Use the current frame tree (if it exists) to update the background
   * color of the most recently drawn canvas.
   */
  void UpdateCanvasBackground();

  /**
   * Add a solid color item to the bottom of aList with frame aFrame and
   * bounds aBounds representing the dark grey background behind the page of a
   * print preview presentation.
   */
897
898
  void AddPrintPreviewBackgroundItem(nsDisplayListBuilder* aBuilder,
                                     nsDisplayList* aList, nsIFrame* aFrame,
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
                                     const nsRect& aBounds);

  /**
   * Computes the backstop color for the view: transparent if in a transparent
   * widget, otherwise the PresContext default background color. This color is
   * only visible if the contents of the view as a whole are translucent.
   */
  nscolor ComputeBackstopColor(nsView* aDisplayRoot);

  void ObserveNativeAnonMutationsForPrint(bool aObserve) {
    mObservesMutationsForPrint = aObserve;
  }
  bool ObservesNativeAnonMutationsForPrint() {
    return mObservesMutationsForPrint;
  }

  nsresult SetIsActive(bool aIsActive);

  bool IsActive() { return mIsActive; }

  /**
   * Keep track of how many times this presshell has been rendered to
   * a window.
   */
  uint64_t GetPaintCount() { return mPaintCount; }
  void IncrementPaintCount() { ++mPaintCount; }

  /**
   * Get the root DOM window of this presShell.
   */
  already_AddRefed<nsPIDOMWindowOuter> GetRootWindow();

  /**
   * 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();

  /**
   * Get the focused content under this window.
   */
  already_AddRefed<nsIContent> GetFocusedContentInOurWindow() const;

  /**
   * Get the layer manager for the widget of the root view, if it has
   * one.
   */
  LayerManager* GetLayerManager();

  /**
   * Return true iff there is a widget rendering this presShell and that
   * widget is APZ-enabled.
   */
  bool AsyncPanZoomEnabled();

  /**
   * Track whether we're ignoring viewport scrolling for the purposes
   * of painting.  If we are ignoring, then layers aren't clipped to
   * the CSS viewport and scrollbars aren't drawn.
   */
  bool IgnoringViewportScrolling() const {
960
961
    return !!(mRenderingStateFlags &
              RenderingStateFlags::IgnoringViewportScrolling);
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
  }

  float GetResolution() const { return mResolution.valueOr(1.0); }
  float GetCumulativeResolution();

  /**
   * Accessors for a flag that tracks whether the most recent change to
   * the pres shell's resolution was originated by the main thread.
   */
  bool IsResolutionUpdated() const { return mResolutionUpdated; }
  void SetResolutionUpdated(bool aUpdated) { mResolutionUpdated = aUpdated; }

  /**
   * Returns true if the resolution has ever been changed by APZ.
   */
  bool IsResolutionUpdatedByApz() const { return mResolutionUpdatedByApz; }

  /**
   * Used by session restore code to restore a resolution before the first
   * paint.
   */
  void SetRestoreResolution(float aResolution,
                            LayoutDeviceIntSize aDisplaySize);

  /**
   * Returns whether we are in a DrawWindow() call that used the
   * DRAWWINDOW_DO_NOT_FLUSH flag.
   */
  bool InDrawWindowNotFlushing() const {
991
992
    return !!(mRenderingStateFlags &
              RenderingStateFlags::DrawWindowNotFlushing);
993
994
995
996
997
998
999
1000
  }

  /**
   * Set the isFirstPaint flag.
   */
  void SetIsFirstPaint(bool aIsFirstPaint) { mIsFirstPaint = aIsFirstPaint; }

  /**