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 /* rendering object that goes directly inside the document's scrollbars */ 8 9 #ifndef nsCanvasFrame_h___ 10 #define nsCanvasFrame_h___ 11 12 #include "mozilla/Attributes.h" 13 #include "mozilla/EventForwards.h" 14 #include "nsContainerFrame.h" 15 #include "nsIScrollPositionListener.h" 16 #include "nsIPopupContainer.h" 17 #include "nsDisplayList.h" 18 #include "nsIAnonymousContentCreator.h" 19 20 class nsPresContext; 21 class gfxContext; 22 class nsPopupSetFrame; 23 24 /** 25 * Root frame class. 26 * 27 * The root frame is the parent frame for the document element's frame. 28 * It only supports having a single child frame which must be an area 29 * frame. 30 * @note nsCanvasFrame keeps overflow container continuations of its child 31 * frame in the main child list. 32 */ 33 class nsCanvasFrame final : public nsContainerFrame, 34 public nsIScrollPositionListener, 35 public nsIAnonymousContentCreator, 36 public nsIPopupContainer { 37 using Element = mozilla::dom::Element; 38 39 public: nsCanvasFrame(ComputedStyle * aStyle,nsPresContext * aPresContext)40 explicit nsCanvasFrame(ComputedStyle* aStyle, nsPresContext* aPresContext) 41 : nsContainerFrame(aStyle, aPresContext, kClassID), 42 mDoPaintFocus(false), 43 mAddedScrollPositionListener(false), 44 mPopupSetFrame(nullptr) {} 45 46 NS_DECL_QUERYFRAME 47 NS_DECL_FRAMEARENA_HELPERS(nsCanvasFrame) 48 49 nsPopupSetFrame* GetPopupSetFrame() override; 50 void SetPopupSetFrame(nsPopupSetFrame* aPopupSet) override; 51 Element* GetDefaultTooltip() override; 52 void SetDefaultTooltip(Element* aTooltip) override; 53 54 virtual void DestroyFrom(nsIFrame* aDestructRoot, 55 PostDestroyData& aPostDestroyData) override; 56 57 virtual void SetInitialChildList(ChildListID aListID, 58 nsFrameList& aChildList) override; 59 virtual void AppendFrames(ChildListID aListID, 60 nsFrameList& aFrameList) override; 61 virtual void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame, 62 const nsLineList::iterator* aPrevFrameLine, 63 nsFrameList& aFrameList) override; 64 #ifdef DEBUG 65 virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override; 66 #endif 67 68 virtual nscoord GetMinISize(gfxContext* aRenderingContext) override; 69 virtual nscoord GetPrefISize(gfxContext* aRenderingContext) override; 70 virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, 71 const ReflowInput& aReflowInput, 72 nsReflowStatus& aStatus) override; IsFrameOfType(uint32_t aFlags)73 virtual bool IsFrameOfType(uint32_t aFlags) const override { 74 return nsContainerFrame::IsFrameOfType( 75 aFlags & ~(nsIFrame::eCanContainOverflowContainers)); 76 } 77 78 // nsIAnonymousContentCreator 79 virtual nsresult CreateAnonymousContent( 80 nsTArray<ContentInfo>& aElements) override; 81 virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, 82 uint32_t aFilter) override; 83 GetCustomContentContainer()84 Element* GetCustomContentContainer() const { return mCustomContentContainer; } 85 86 /** 87 * Unhide the CustomContentContainer. This call only has an effect if 88 * mCustomContentContainer is non-null. 89 */ 90 void ShowCustomContentContainer(); 91 92 /** 93 * Hide the CustomContentContainer. This call only has an effect if 94 * mCustomContentContainer is non-null. 95 */ 96 void HideCustomContentContainer(); 97 98 /** SetHasFocus tells the CanvasFrame to draw with focus ring 99 * @param aHasFocus true to show focus ring, false to hide it 100 */ 101 NS_IMETHOD SetHasFocus(bool aHasFocus); 102 103 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, 104 const nsDisplayListSet& aLists) override; 105 106 void PaintFocus(mozilla::gfx::DrawTarget* aRenderingContext, nsPoint aPt); 107 108 // nsIScrollPositionListener 109 virtual void ScrollPositionWillChange(nscoord aX, nscoord aY) override; ScrollPositionDidChange(nscoord aX,nscoord aY)110 virtual void ScrollPositionDidChange(nscoord aX, nscoord aY) override {} 111 112 #ifdef DEBUG_FRAME_DUMP 113 virtual nsresult GetFrameName(nsAString& aResult) const override; 114 #endif 115 virtual nsresult GetContentForEvent(mozilla::WidgetEvent* aEvent, 116 nsIContent** aContent) override; 117 118 nsRect CanvasArea() const; 119 120 protected: 121 // Data members 122 bool mDoPaintFocus; 123 bool mAddedScrollPositionListener; 124 125 nsCOMPtr<Element> mCustomContentContainer; 126 127 private: 128 nsPopupSetFrame* mPopupSetFrame; 129 nsCOMPtr<Element> mPopupgroupContent; 130 nsCOMPtr<Element> mTooltipContent; 131 }; 132 133 /** 134 * Override nsDisplayBackground methods so that we pass aBGClipRect to 135 * PaintBackground, covering the whole overflow area. 136 * We can also paint an "extra background color" behind the normal 137 * background. 138 */ 139 class nsDisplayCanvasBackgroundColor final : public nsDisplaySolidColorBase { 140 public: nsDisplayCanvasBackgroundColor(nsDisplayListBuilder * aBuilder,nsIFrame * aFrame)141 nsDisplayCanvasBackgroundColor(nsDisplayListBuilder* aBuilder, 142 nsIFrame* aFrame) 143 : nsDisplaySolidColorBase(aBuilder, aFrame, NS_RGBA(0, 0, 0, 0)) {} 144 ComputeVisibility(nsDisplayListBuilder * aBuilder,nsRegion * aVisibleRegion)145 virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, 146 nsRegion* aVisibleRegion) override { 147 return NS_GET_A(mColor) > 0; 148 } GetBounds(nsDisplayListBuilder * aBuilder,bool * aSnap)149 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, 150 bool* aSnap) const override { 151 nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame); 152 *aSnap = true; 153 return frame->CanvasArea() + ToReferenceFrame(); 154 } HitTest(nsDisplayListBuilder * aBuilder,const nsRect & aRect,HitTestState * aState,nsTArray<nsIFrame * > * aOutFrames)155 virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, 156 HitTestState* aState, 157 nsTArray<nsIFrame*>* aOutFrames) override { 158 // We need to override so we don't consider border-radius. 159 aOutFrames->AppendElement(mFrame); 160 } 161 virtual already_AddRefed<Layer> BuildLayer( 162 nsDisplayListBuilder* aBuilder, LayerManager* aManager, 163 const ContainerLayerParameters& aContainerParameters) override; 164 virtual bool CreateWebRenderCommands( 165 mozilla::wr::DisplayListBuilder& aBuilder, 166 mozilla::wr::IpcResourceUpdateQueue& aResources, 167 const StackingContextHelper& aSc, 168 mozilla::layers::RenderRootStateManager* aManager, 169 nsDisplayListBuilder* aDisplayListBuilder) override; GetLayerState(nsDisplayListBuilder * aBuilder,LayerManager * aManager,const ContainerLayerParameters & aParameters)170 virtual LayerState GetLayerState( 171 nsDisplayListBuilder* aBuilder, LayerManager* aManager, 172 const ContainerLayerParameters& aParameters) override { 173 if (ForceActiveLayers()) { 174 return mozilla::LayerState::LAYER_ACTIVE; 175 } 176 return mozilla::LayerState::LAYER_NONE; 177 } 178 virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override; 179 SetExtraBackgroundColor(nscolor aColor)180 void SetExtraBackgroundColor(nscolor aColor) { mColor = aColor; } 181 182 NS_DISPLAY_DECL_NAME("CanvasBackgroundColor", TYPE_CANVAS_BACKGROUND_COLOR) 183 184 virtual void WriteDebugInfo(std::stringstream& aStream) override; 185 }; 186 187 class nsDisplayCanvasBackgroundImage : public nsDisplayBackgroundImage { 188 public: nsDisplayCanvasBackgroundImage(nsDisplayListBuilder * aBuilder,nsIFrame * aFrame,const InitData & aInitData)189 explicit nsDisplayCanvasBackgroundImage(nsDisplayListBuilder* aBuilder, 190 nsIFrame* aFrame, 191 const InitData& aInitData) 192 : nsDisplayBackgroundImage(aBuilder, aFrame, aInitData) {} 193 194 virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override; 195 196 // We still need to paint a background color as well as an image for this 197 // item, so we can't support this yet. SupportsOptimizingToImage()198 virtual bool SupportsOptimizingToImage() const override { return false; } 199 200 bool IsSingleFixedPositionImage(nsDisplayListBuilder* aBuilder, 201 const nsRect& aClipRect, gfxRect* aDestRect); 202 203 NS_DISPLAY_DECL_NAME("CanvasBackgroundImage", TYPE_CANVAS_BACKGROUND_IMAGE) 204 }; 205 206 class nsDisplayCanvasThemedBackground : public nsDisplayThemedBackground { 207 public: nsDisplayCanvasThemedBackground(nsDisplayListBuilder * aBuilder,nsIFrame * aFrame)208 nsDisplayCanvasThemedBackground(nsDisplayListBuilder* aBuilder, 209 nsIFrame* aFrame) 210 : nsDisplayThemedBackground(aBuilder, aFrame, 211 aFrame->GetRectRelativeToSelf() + 212 aBuilder->ToReferenceFrame(aFrame)) { 213 nsDisplayThemedBackground::Init(aBuilder); 214 } 215 216 virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override; 217 218 NS_DISPLAY_DECL_NAME("CanvasThemedBackground", TYPE_CANVAS_THEMED_BACKGROUND) 219 }; 220 221 #endif /* nsCanvasFrame_h___ */ 222