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