PopoverData.h (4154B)
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 mozilla_dom_PopoverData_h 8 #define mozilla_dom_PopoverData_h 9 10 #include "Element.h" 11 #include "nsINode.h" 12 #include "nsIRunnable.h" 13 #include "nsIWeakReferenceUtils.h" 14 #include "nsStringFwd.h" 15 #include "nsThreadUtils.h" 16 17 namespace mozilla::dom { 18 19 class CloseWatcher; 20 21 // https://html.spec.whatwg.org/#attr-popover 22 enum class PopoverAttributeState : uint8_t { 23 None, 24 Auto, ///< https://html.spec.whatwg.org/#attr-popover-auto-state 25 Manual, ///< https://html.spec.whatwg.org/#attr-popover-manual-state 26 }; 27 28 enum class PopoverVisibilityState : uint8_t { 29 Hidden, 30 Showing, 31 }; 32 33 class PopoverToggleEventTask : public Runnable { 34 public: 35 explicit PopoverToggleEventTask(nsWeakPtr aElement, nsWeakPtr aSource, 36 PopoverVisibilityState aOldState); 37 38 // MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See 39 // bug 1535398. 40 MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() override; 41 42 PopoverVisibilityState GetOldState() const { return mOldState; } 43 44 Element* GetSource() const; 45 46 private: 47 nsWeakPtr mElement; 48 nsWeakPtr mSource; 49 PopoverVisibilityState mOldState; 50 }; 51 52 class PopoverData { 53 public: 54 PopoverData() = default; 55 ~PopoverData() = default; 56 57 void EnsureCloseWatcher(nsGenericHTMLElement* aElement); 58 CloseWatcher* GetCloseWatcher(); 59 void DestroyCloseWatcher(); 60 61 PopoverAttributeState GetPopoverAttributeState() const { return mState; } 62 void SetPopoverAttributeState(PopoverAttributeState aState) { 63 mState = aState; 64 } 65 66 PopoverAttributeState GetOpenedInMode() const { return mOpenedInMode; } 67 void SetOpenedInMode(PopoverAttributeState aMode) { mOpenedInMode = aMode; } 68 69 PopoverVisibilityState GetPopoverVisibilityState() const { 70 return mVisibilityState; 71 } 72 void SetPopoverVisibilityState(PopoverVisibilityState aVisibilityState) { 73 mVisibilityState = aVisibilityState; 74 } 75 76 nsWeakPtr GetPreviouslyFocusedElement() const { 77 return mPreviouslyFocusedElement; 78 } 79 void SetPreviouslyFocusedElement(nsWeakPtr aPreviouslyFocusedElement) { 80 mPreviouslyFocusedElement = aPreviouslyFocusedElement; 81 } 82 83 RefPtr<Element> GetInvoker() const { 84 return do_QueryReferent(mInvokerElement); 85 } 86 void SetInvoker(Element* aInvokerElement) { 87 mInvokerElement = 88 do_GetWeakReference(static_cast<nsINode*>(aInvokerElement)); 89 } 90 91 PopoverToggleEventTask* GetToggleEventTask() const { return mTask; } 92 void SetToggleEventTask(PopoverToggleEventTask* aTask) { mTask = aTask; } 93 void ClearToggleEventTask() { mTask = nullptr; } 94 95 bool IsShowingOrHiding() const { return mIsShowingOrHiding; } 96 void SetIsShowingOrHiding(bool aIsShowingOrHiding) { 97 mIsShowingOrHiding = aIsShowingOrHiding; 98 } 99 100 private: 101 PopoverVisibilityState mVisibilityState = PopoverVisibilityState::Hidden; 102 PopoverAttributeState mState = PopoverAttributeState::None; 103 PopoverAttributeState mOpenedInMode = PopoverAttributeState::None; 104 // Popover and dialog don't share mPreviouslyFocusedElement for there are 105 // chances to lose the previously focused element. 106 // See, https://github.com/whatwg/html/issues/9063 107 nsWeakPtr mPreviouslyFocusedElement = nullptr; 108 109 // https://html.spec.whatwg.org/#popover-invoker 110 // Since having a popover invoker only makes a difference if the invoker 111 // is in the document (in another open popover to be precise) we can make 112 // this a weak reference, as if the element goes away it's necessarily not 113 // connected to our document. 114 nsWeakPtr mInvokerElement; 115 bool mIsShowingOrHiding = false; 116 RefPtr<PopoverToggleEventTask> mTask; 117 118 // This won't need to be cycle collected as CloseWatcher only has strong 119 // references to event listeners, which themselves have Weak References back 120 // to the Node. 121 RefPtr<CloseWatcher> mCloseWatcher; 122 }; 123 } // namespace mozilla::dom 124 125 #endif