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 nsFileControlFrame_h___ 8 #define nsFileControlFrame_h___ 9 10 #include "mozilla/Attributes.h" 11 #include "nsBlockFrame.h" 12 #include "nsIFormControlFrame.h" 13 #include "nsIDOMEventListener.h" 14 #include "nsIAnonymousContentCreator.h" 15 #include "nsCOMPtr.h" 16 17 namespace mozilla { 18 namespace dom { 19 class FileList; 20 class BlobImpl; 21 class DataTransfer; 22 } // namespace dom 23 } // namespace mozilla 24 25 class nsFileControlFrame final : public nsBlockFrame, 26 public nsIFormControlFrame, 27 public nsIAnonymousContentCreator { 28 using Element = mozilla::dom::Element; 29 30 public: 31 NS_DECL_QUERYFRAME 32 NS_DECL_FRAMEARENA_HELPERS(nsFileControlFrame) 33 34 explicit nsFileControlFrame(ComputedStyle* aStyle, 35 nsPresContext* aPresContext); 36 37 virtual void Init(nsIContent* aContent, nsContainerFrame* aParent, 38 nsIFrame* aPrevInFlow) override; 39 40 void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, 41 const ReflowInput& aReflowInput, 42 nsReflowStatus& aStatus) override; 43 44 virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, 45 const nsDisplayListSet& aLists) override; 46 47 // nsIFormControlFrame 48 virtual nsresult SetFormProperty(nsAtom* aName, 49 const nsAString& aValue) override; 50 virtual void SetFocus(bool aOn, bool aRepaint) override; 51 52 nscoord GetMinISize(gfxContext* aRenderingContext) override; 53 nscoord GetPrefISize(gfxContext* aRenderingContext) override; 54 55 virtual void DestroyFrom(nsIFrame* aDestructRoot, 56 PostDestroyData& aPostDestroyData) override; 57 58 #ifdef DEBUG_FRAME_DUMP 59 virtual nsresult GetFrameName(nsAString& aResult) const override; 60 #endif 61 62 virtual void ContentStatesChanged(mozilla::EventStates aStates) override; 63 64 // nsIAnonymousContentCreator 65 virtual nsresult CreateAnonymousContent( 66 nsTArray<ContentInfo>& aElements) override; 67 virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, 68 uint32_t aFilter) override; 69 70 #ifdef ACCESSIBILITY 71 virtual mozilla::a11y::AccType AccessibleType() override; 72 #endif 73 74 typedef bool (*AcceptAttrCallback)(const nsAString&, void*); 75 76 protected: 77 class MouseListener; 78 friend class MouseListener; 79 class MouseListener : public nsIDOMEventListener { 80 public: 81 NS_DECL_ISUPPORTS 82 MouseListener(nsFileControlFrame * aFrame)83 explicit MouseListener(nsFileControlFrame* aFrame) : mFrame(aFrame) {} 84 ForgetFrame()85 void ForgetFrame() { mFrame = nullptr; } 86 87 protected: 88 virtual ~MouseListener() = default; 89 90 nsFileControlFrame* mFrame; 91 }; 92 93 class SyncDisabledStateEvent; 94 friend class SyncDisabledStateEvent; 95 class SyncDisabledStateEvent : public mozilla::Runnable { 96 public: SyncDisabledStateEvent(nsFileControlFrame * aFrame)97 explicit SyncDisabledStateEvent(nsFileControlFrame* aFrame) 98 : mozilla::Runnable("nsFileControlFrame::SyncDisabledStateEvent"), 99 mFrame(aFrame) {} 100 Run()101 NS_IMETHOD Run() override { 102 nsFileControlFrame* frame = 103 static_cast<nsFileControlFrame*>(mFrame.GetFrame()); 104 NS_ENSURE_STATE(frame); 105 106 frame->SyncDisabledState(); 107 return NS_OK; 108 } 109 110 private: 111 WeakFrame mFrame; 112 }; 113 114 class DnDListener : public MouseListener { 115 public: DnDListener(nsFileControlFrame * aFrame)116 explicit DnDListener(nsFileControlFrame* aFrame) : MouseListener(aFrame) {} 117 118 // nsIDOMEventListener 119 MOZ_CAN_RUN_SCRIPT_BOUNDARY 120 NS_IMETHOD HandleEvent(mozilla::dom::Event* aEvent) override; 121 122 nsresult GetBlobImplForWebkitDirectory(mozilla::dom::FileList* aFileList, 123 mozilla::dom::BlobImpl** aBlobImpl); 124 125 bool IsValidDropData(mozilla::dom::DataTransfer* aDataTransfer); 126 bool CanDropTheseFiles(mozilla::dom::DataTransfer* aDataTransfer, 127 bool aSupportsMultiple); 128 }; 129 IsFrameOfType(uint32_t aFlags)130 virtual bool IsFrameOfType(uint32_t aFlags) const override { 131 return nsBlockFrame::IsFrameOfType( 132 aFlags & ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock)); 133 } 134 135 /** 136 * The text box input. 137 * @see nsFileControlFrame::CreateAnonymousContent 138 */ 139 RefPtr<Element> mTextContent; 140 /** 141 * The button to open a file or directory picker. 142 * @see nsFileControlFrame::CreateAnonymousContent 143 */ 144 RefPtr<Element> mBrowseFilesOrDirs; 145 146 /** 147 * Drag and drop mouse listener. 148 * This makes sure we don't get used after destruction. 149 */ 150 RefPtr<DnDListener> mMouseListener; 151 152 protected: 153 /** 154 * Crop aText to fit inside aWidth using the styles of aFrame. 155 * @return true if aText was modified 156 */ 157 static bool CropTextToWidth(gfxContext& aRenderingContext, 158 const nsIFrame* aFrame, nscoord aWidth, 159 nsString& aText); 160 161 /** 162 * Sync the disabled state of the content with anonymous children. 163 */ 164 void SyncDisabledState(); 165 166 /** 167 * Updates the displayed value by using aValue. 168 */ 169 void UpdateDisplayedValue(const nsAString& aValue, bool aNotify); 170 }; 171 172 #endif // nsFileControlFrame_h___ 173