MediaQueryList.h (3554B)
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 /* implements DOM interface for querying and observing media queries */ 8 9 #ifndef mozilla_dom_MediaQueryList_h 10 #define mozilla_dom_MediaQueryList_h 11 12 #include "mozilla/DOMEventTargetHelper.h" 13 #include "mozilla/LinkedList.h" 14 #include "mozilla/dom/MediaQueryListBinding.h" 15 #include "nsCOMPtr.h" 16 #include "nsCycleCollectionParticipant.h" 17 #include "nsISupports.h" 18 #include "nsTArray.h" 19 #include "nsWrapperCache.h" 20 21 namespace mozilla::dom { 22 23 class MediaList; 24 25 class MediaQueryList final : public DOMEventTargetHelper, 26 public LinkedListElement<MediaQueryList> { 27 public: 28 // The caller who constructs is responsible for calling Evaluate 29 // before calling any other methods. 30 MediaQueryList(Document* aDocument, const nsACString& aMediaQueryList, 31 CallerType); 32 33 private: 34 ~MediaQueryList(); 35 36 public: 37 NS_DECL_ISUPPORTS_INHERITED 38 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaQueryList, DOMEventTargetHelper) 39 40 nsISupports* GetParentObject() const; 41 42 void MediaFeatureValuesChanged(); 43 44 // Returns whether we need to notify of the change by dispatching a change 45 // event. 46 [[nodiscard]] bool EvaluateOnRenderingUpdate(); 47 void FireChangeEvent(); 48 49 JSObject* WrapObject(JSContext* aCx, 50 JS::Handle<JSObject*> aGivenProto) override; 51 52 // WebIDL methods 53 void GetMedia(nsACString& aMedia) const; 54 bool Matches(); 55 void AddListener(EventListener* aListener); 56 void RemoveListener(EventListener* aListener); 57 58 IMPL_EVENT_HANDLER(change) 59 60 bool HasListeners() const; 61 62 void Disconnect(); 63 64 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const; 65 66 private: 67 void LastRelease() final { 68 auto* listElement = static_cast<LinkedListElement<MediaQueryList>*>(this); 69 if (listElement->isInList()) { 70 listElement->remove(); 71 } 72 } 73 74 void RecomputeMatches(); 75 76 // We only need a pointer to the document to support lazy 77 // reevaluation following dynamic changes. However, this lazy 78 // reevaluation is perhaps somewhat important, since some usage 79 // patterns may involve the creation of large numbers of 80 // MediaQueryList objects which almost immediately become garbage 81 // (after a single call to the .matches getter). 82 // 83 // This pointer does make us a little more dependent on cycle 84 // collection. 85 // 86 // We have a non-null mDocument for our entire lifetime except 87 // after cycle collection unlinking. Having a non-null mDocument 88 // is equivalent to being in that document's mDOMMediaQueryLists 89 // linked list. 90 RefPtr<Document> mDocument; 91 const RefPtr<const MediaList> mMediaList; 92 // Whether our MediaList depends on our viewport size. Our medialist is 93 // immutable, so we can just compute this once and carry on with our lives. 94 const bool mViewportDependent : 1; 95 // The matches state. 96 // https://drafts.csswg.org/cssom-view/#mediaquerylist-matches-state 97 bool mMatches : 1; 98 // The value of the matches state on creation, or on the last rendering 99 // update, in order to implement: 100 // https://drafts.csswg.org/cssom-view/#evaluate-media-queries-and-report-changes 101 bool mMatchesOnRenderingUpdate : 1; 102 }; 103 104 } // namespace mozilla::dom 105 106 #endif /* !defined(mozilla_dom_MediaQueryList_h) */