tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

MediaQueryList.cpp (4724B)


      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 #include "mozilla/dom/MediaQueryList.h"
     10 
     11 #include "mozilla/dom/Document.h"
     12 #include "mozilla/dom/EventTarget.h"
     13 #include "mozilla/dom/EventTargetBinding.h"
     14 #include "mozilla/dom/MediaList.h"
     15 #include "mozilla/dom/MediaQueryListEvent.h"
     16 #include "nsPresContext.h"
     17 
     18 namespace mozilla::dom {
     19 
     20 MediaQueryList::MediaQueryList(Document* aDocument,
     21                               const nsACString& aMediaQueryList,
     22                               CallerType aCallerType)
     23    : DOMEventTargetHelper(aDocument->GetInnerWindow()),
     24      mDocument(aDocument),
     25      mMediaList(MediaList::Create(aMediaQueryList, aCallerType)),
     26      mViewportDependent(mMediaList->IsViewportDependent()),
     27      mMatches(mMediaList->Matches(*aDocument)),
     28      mMatchesOnRenderingUpdate(mMatches) {
     29  KeepAliveIfHasListenersFor(nsGkAtoms::onchange);
     30 }
     31 
     32 MediaQueryList::~MediaQueryList() = default;
     33 
     34 NS_IMPL_CYCLE_COLLECTION_CLASS(MediaQueryList)
     35 
     36 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaQueryList,
     37                                                  DOMEventTargetHelper)
     38  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
     39 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     40 
     41 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaQueryList,
     42                                                DOMEventTargetHelper)
     43  if (tmp->mDocument) {
     44    static_cast<LinkedListElement<MediaQueryList>*>(tmp)->remove();
     45    NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
     46  }
     47  tmp->Disconnect();
     48  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
     49 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     50 
     51 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaQueryList)
     52 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
     53 
     54 NS_IMPL_ADDREF_INHERITED(MediaQueryList, DOMEventTargetHelper)
     55 NS_IMPL_RELEASE_INHERITED(MediaQueryList, DOMEventTargetHelper)
     56 
     57 void MediaQueryList::GetMedia(nsACString& aMedia) const {
     58  mMediaList->GetText(aMedia);
     59 }
     60 
     61 bool MediaQueryList::Matches() {
     62  if (mViewportDependent &&
     63      mDocument->StyleOrLayoutObservablyDependsOnParentDocumentLayout()) {
     64    RefPtr<Document> doc = mDocument;
     65    // This is enough to trigger media query updates in the current doc, and
     66    // will flush the parent document layout if appropriate.
     67    doc->FlushPendingNotifications(FlushType::Layout);
     68  }
     69  return mMatches;
     70 }
     71 
     72 void MediaQueryList::AddListener(EventListener* aListener) {
     73  if (!aListener) {
     74    return;
     75  }
     76 
     77  AddEventListenerOptionsOrBoolean options;
     78  options.SetAsBoolean() = false;
     79 
     80  AddEventListener(u"change"_ns, aListener, options, Nullable<bool>());
     81 }
     82 
     83 void MediaQueryList::RemoveListener(EventListener* aListener) {
     84  if (!aListener) {
     85    return;
     86  }
     87 
     88  EventListenerOptionsOrBoolean options;
     89  options.SetAsBoolean() = false;
     90 
     91  RemoveEventListener(u"change"_ns, aListener, options);
     92 }
     93 
     94 bool MediaQueryList::HasListeners() const {
     95  return HasListenersFor(nsGkAtoms::onchange);
     96 }
     97 
     98 void MediaQueryList::Disconnect() {
     99  DisconnectFromOwner();
    100  IgnoreKeepAliveIfHasListenersFor(nsGkAtoms::onchange);
    101 }
    102 
    103 nsISupports* MediaQueryList::GetParentObject() const {
    104  return ToSupports(mDocument);
    105 }
    106 
    107 JSObject* MediaQueryList::WrapObject(JSContext* aCx,
    108                                     JS::Handle<JSObject*> aGivenProto) {
    109  return MediaQueryList_Binding::Wrap(aCx, this, aGivenProto);
    110 }
    111 
    112 void MediaQueryList::MediaFeatureValuesChanged() {
    113  mMatches = mDocument && mMediaList->Matches(*mDocument);
    114  // Note that mMatchesOnRenderingUpdate remains with the old value here.
    115  // That gets updated in EvaluateOnRenderingUpdate().
    116 }
    117 
    118 bool MediaQueryList::EvaluateOnRenderingUpdate() {
    119  if (mMatches == mMatchesOnRenderingUpdate) {
    120    return false;
    121  }
    122  mMatchesOnRenderingUpdate = mMatches;
    123  return HasListeners();
    124 }
    125 
    126 void MediaQueryList::FireChangeEvent() {
    127  MediaQueryListEventInit init;
    128  init.mBubbles = false;
    129  init.mCancelable = false;
    130  init.mMatches = mMatches;
    131  mMediaList->GetText(init.mMedia);
    132 
    133  RefPtr<MediaQueryListEvent> event =
    134      MediaQueryListEvent::Constructor(this, u"change"_ns, init);
    135  event->SetTrusted(true);
    136  DispatchEvent(*event);
    137 }
    138 
    139 size_t MediaQueryList::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
    140  size_t n = 0;
    141  // mMediaList is reference counted, but it's created and primarily owned
    142  // by this MediaQueryList object.
    143  n += mMediaList->SizeOfIncludingThis(aMallocSizeOf);
    144  return n;
    145 }
    146 
    147 }  // namespace mozilla::dom