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