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 #ifndef NSSUBDOCUMENTFRAME_H_
8 #define NSSUBDOCUMENTFRAME_H_
9 
10 #include "LayerState.h"
11 #include "mozilla/Attributes.h"
12 #include "nsDisplayList.h"
13 #include "nsAtomicContainerFrame.h"
14 #include "nsIReflowCallback.h"
15 #include "nsFrameLoader.h"
16 #include "Units.h"
17 
18 namespace mozilla {
19 class PresShell;
20 }  // namespace mozilla
21 
22 namespace mozilla::layers {
23 class Layer;
24 class RenderRootStateManager;
25 class WebRenderLayerScrollData;
26 class WebRenderScrollData;
27 }  // namespace mozilla::layers
28 
29 /******************************************************************************
30  * nsSubDocumentFrame
31  *****************************************************************************/
32 class nsSubDocumentFrame final : public nsAtomicContainerFrame,
33                                  public nsIReflowCallback {
34  public:
35   NS_DECL_FRAMEARENA_HELPERS(nsSubDocumentFrame)
36 
37   explicit nsSubDocumentFrame(ComputedStyle* aStyle,
38                               nsPresContext* aPresContext);
39 
40 #ifdef DEBUG_FRAME_DUMP
41   void List(FILE* out = stderr, const char* aPrefix = "",
42             ListFlags aFlags = ListFlags()) const override;
43   nsresult GetFrameName(nsAString& aResult) const override;
44 #endif
45 
46   NS_DECL_QUERYFRAME
47 
IsFrameOfType(uint32_t aFlags)48   bool IsFrameOfType(uint32_t aFlags) const override {
49     return nsAtomicContainerFrame::IsFrameOfType(
50         aFlags & ~(nsIFrame::eReplaced | nsIFrame::eReplacedSizing |
51                    nsIFrame::eReplacedContainsBlock));
52   }
53 
54   void Init(nsIContent* aContent, nsContainerFrame* aParent,
55             nsIFrame* aPrevInFlow) override;
56 
57   void DestroyFrom(nsIFrame* aDestructRoot,
58                    PostDestroyData& aPostDestroyData) override;
59 
60   nscoord GetMinISize(gfxContext* aRenderingContext) override;
61   nscoord GetPrefISize(gfxContext* aRenderingContext) override;
62 
63   mozilla::IntrinsicSize GetIntrinsicSize() override;
64   mozilla::AspectRatio GetIntrinsicRatio() const override;
65 
66   mozilla::LogicalSize ComputeAutoSize(
67       gfxContext* aRenderingContext, mozilla::WritingMode aWritingMode,
68       const mozilla::LogicalSize& aCBSize, nscoord aAvailableISize,
69       const mozilla::LogicalSize& aMargin,
70       const mozilla::LogicalSize& aBorderPadding,
71       const mozilla::StyleSizeOverrides& aSizeOverrides,
72       mozilla::ComputeSizeFlags aFlags) override;
73 
74   SizeComputationResult ComputeSize(
75       gfxContext* aRenderingContext, mozilla::WritingMode aWM,
76       const mozilla::LogicalSize& aCBSize, nscoord aAvailableISize,
77       const mozilla::LogicalSize& aMargin,
78       const mozilla::LogicalSize& aBorderPadding,
79       const mozilla::StyleSizeOverrides& aSizeOverrides,
80       mozilla::ComputeSizeFlags aFlags) override;
81 
82   void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
83               const ReflowInput& aReflowInput,
84               nsReflowStatus& aStatus) override;
85 
86   void BuildDisplayList(nsDisplayListBuilder* aBuilder,
87                         const nsDisplayListSet& aLists) override;
88 
89   nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
90                             int32_t aModType) override;
91 
92   void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;
93 
94   // if the content is "visibility:hidden", then just hide the view
95   // and all our contents. We don't extend "visibility:hidden" to
96   // the child content ourselves, since it belongs to a different
97   // document and CSS doesn't inherit in there.
SupportsVisibilityHidden()98   bool SupportsVisibilityHidden() override { return false; }
99 
100 #ifdef ACCESSIBILITY
101   mozilla::a11y::AccType AccessibleType() override;
102 #endif
103 
104   nsIDocShell* GetDocShell() const;
105   nsresult BeginSwapDocShells(nsIFrame* aOther);
106   void EndSwapDocShells(nsIFrame* aOther);
107   nsView* EnsureInnerView();
108   nsPoint GetExtraOffset() const;
109   nsIFrame* GetSubdocumentRootFrame();
110   enum { IGNORE_PAINT_SUPPRESSION = 0x1 };
111   mozilla::PresShell* GetSubdocumentPresShellForPainting(uint32_t aFlags);
112   mozilla::ScreenIntSize GetSubdocumentSize();
113 
114   // nsIReflowCallback
115   bool ReflowFinished() override;
116   void ReflowCallbackCanceled() override;
117 
118   /**
119    * Return true if pointer event hit-testing should be allowed to target
120    * content in the subdocument.
121    */
122   bool PassPointerEventsToChildren();
123 
MaybeShowViewer()124   void MaybeShowViewer() {
125     if (!mDidCreateDoc && !mCallingShow) {
126       ShowViewer();
127     }
128   }
129 
130   nsFrameLoader* FrameLoader() const;
131 
132   enum class RetainPaintData : bool { No, Yes };
133   void ResetFrameLoader(RetainPaintData);
134   void ClearRetainedPaintData();
135 
136   void PropagateIsUnderHiddenEmbedderElementToSubView(
137       bool aIsUnderHiddenEmbedderElement);
138 
139   void ClearDisplayItems();
140 
141   void SubdocumentIntrinsicSizeOrRatioChanged();
142 
143   struct RemoteFramePaintData {
144     mozilla::layers::LayersId mLayersId;
145     mozilla::dom::TabId mTabId{0};
146   };
147 
148   RemoteFramePaintData GetRemotePaintData() const;
HasRetainedPaintData()149   bool HasRetainedPaintData() const { return mRetainedRemoteFrame.isSome(); }
150 
151  protected:
152   friend class AsyncFrameInit;
153 
IsInline()154   bool IsInline() { return mIsInline; }
155 
GetIntrinsicBSize()156   nscoord GetIntrinsicBSize() {
157     auto size = GetIntrinsicSize();
158     Maybe<nscoord> bSize =
159         GetWritingMode().IsVertical() ? size.width : size.height;
160     return bSize.valueOr(0);
161   }
162 
GetIntrinsicISize()163   nscoord GetIntrinsicISize() {
164     auto size = GetIntrinsicSize();
165     Maybe<nscoord> iSize =
166         GetWritingMode().IsVertical() ? size.height : size.width;
167     return iSize.valueOr(0);
168   }
169 
170   // Show our document viewer. The document viewer is hidden via a script
171   // runner, so that we can save and restore the presentation if we're
172   // being reframed.
173   void ShowViewer();
174 
GetViewInternal()175   nsView* GetViewInternal() const override { return mOuterView; }
SetViewInternal(nsView * aView)176   void SetViewInternal(nsView* aView) override { mOuterView = aView; }
177 
178   mutable RefPtr<nsFrameLoader> mFrameLoader;
179 
180   nsView* mOuterView;
181   nsView* mInnerView;
182 
183   // When process-switching a remote tab, we might temporarily paint the old
184   // one.
185   Maybe<RemoteFramePaintData> mRetainedRemoteFrame;
186 
187   bool mIsInline : 1;
188   bool mPostedReflowCallback : 1;
189   bool mDidCreateDoc : 1;
190   bool mCallingShow : 1;
191 };
192 
193 namespace mozilla {
194 
195 /**
196  * A nsDisplayRemote will graft a remote frame's shadow layer tree (for a given
197  * nsFrameLoader) into its parent frame's layer tree.
198  */
199 class nsDisplayRemote final : public nsPaintedDisplayItem {
200   typedef mozilla::dom::TabId TabId;
201   typedef mozilla::gfx::Matrix4x4 Matrix4x4;
202   typedef mozilla::layers::EventRegionsOverride EventRegionsOverride;
203   typedef mozilla::layers::Layer Layer;
204   typedef mozilla::layers::LayersId LayersId;
205   typedef mozilla::layers::StackingContextHelper StackingContextHelper;
206   typedef mozilla::LayerState LayerState;
207   typedef mozilla::LayoutDeviceRect LayoutDeviceRect;
208   typedef mozilla::LayoutDevicePoint LayoutDevicePoint;
209 
210  public:
211   nsDisplayRemote(nsDisplayListBuilder* aBuilder, nsSubDocumentFrame* aFrame);
212 
213   void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
214 
215   bool CreateWebRenderCommands(
216       mozilla::wr::DisplayListBuilder& aBuilder,
217       mozilla::wr::IpcResourceUpdateQueue& aResources,
218       const StackingContextHelper& aSc,
219       mozilla::layers::RenderRootStateManager* aManager,
220       nsDisplayListBuilder* aDisplayListBuilder) override;
221   bool UpdateScrollData(
222       mozilla::layers::WebRenderScrollData* aData,
223       mozilla::layers::WebRenderLayerScrollData* aLayerData) override;
224 
225   NS_DISPLAY_DECL_NAME("Remote", TYPE_REMOTE)
226 
227  private:
228   friend class nsDisplayItem;
229   using RemoteFramePaintData = nsSubDocumentFrame::RemoteFramePaintData;
230 
231   nsFrameLoader* GetFrameLoader() const;
232 
233   RemoteFramePaintData mPaintData;
234   LayoutDevicePoint mOffset;
235   EventRegionsOverride mEventRegionsOverride;
236 };
237 
238 }  // namespace mozilla
239 
240 #endif /* NSSUBDOCUMENTFRAME_H_ */
241