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