layout/style/MediaQueryList.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 /* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /* implements DOM interface for querying and observing media queries */
     8 #include "mozilla/dom/MediaQueryList.h"
     9 #include "nsPresContext.h"
    10 #include "nsIMediaList.h"
    11 #include "nsCSSParser.h"
    12 #include "nsIDocument.h"
    14 namespace mozilla {
    15 namespace dom {
    17 MediaQueryList::MediaQueryList(nsPresContext *aPresContext,
    18                                const nsAString &aMediaQueryList)
    19   : mPresContext(aPresContext),
    20     mMediaList(new nsMediaList),
    21     mMatchesValid(false)
    22 {
    23   PR_INIT_CLIST(this);
    25   SetIsDOMBinding();
    27   nsCSSParser parser;
    28   parser.ParseMediaList(aMediaQueryList, nullptr, 0, mMediaList, false);
    29 }
    31 MediaQueryList::~MediaQueryList()
    32 {
    33   if (mPresContext) {
    34     PR_REMOVE_LINK(this);
    35   }
    36 }
    38 NS_IMPL_CYCLE_COLLECTION_CLASS(MediaQueryList)
    40 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(MediaQueryList)
    41   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresContext)
    42   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallbacks)
    43   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
    44 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
    46 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(MediaQueryList)
    47   if (tmp->mPresContext) {
    48     PR_REMOVE_LINK(tmp);
    49     NS_IMPL_CYCLE_COLLECTION_UNLINK(mPresContext)
    50   }
    51   tmp->RemoveAllListeners();
    52   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
    53 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
    55 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(MediaQueryList)
    57 NS_INTERFACE_MAP_BEGIN(MediaQueryList)
    58   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
    59   NS_INTERFACE_MAP_ENTRY(nsISupports)
    60   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(MediaQueryList)
    61 NS_INTERFACE_MAP_END
    63 NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaQueryList)
    64 NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaQueryList)
    66 void
    67 MediaQueryList::GetMedia(nsAString &aMedia)
    68 {
    69   mMediaList->GetText(aMedia);
    70 }
    72 bool
    73 MediaQueryList::Matches()
    74 {
    75   if (!mMatchesValid) {
    76     NS_ABORT_IF_FALSE(!HasListeners(),
    77                       "when listeners present, must keep mMatches current");
    78     RecomputeMatches();
    79   }
    81   return mMatches;
    82 }
    84 void
    85 MediaQueryList::AddListener(MediaQueryListListener& aListener)
    86 {
    87   if (!HasListeners()) {
    88     // When we have listeners, the pres context owns a reference to
    89     // this.  This is a cyclic reference that can only be broken by
    90     // cycle collection.
    91     NS_ADDREF_THIS();
    92   }
    94   if (!mMatchesValid) {
    95     NS_ABORT_IF_FALSE(!HasListeners(),
    96                       "when listeners present, must keep mMatches current");
    97     RecomputeMatches();
    98   }
   100   for (uint32_t i = 0; i < mCallbacks.Length(); ++i) {
   101     if (aListener == *mCallbacks[i]) {
   102       // Already registered
   103       return;
   104     }
   105   }
   107   mCallbacks.AppendElement(&aListener);
   108   if (!HasListeners()) {
   109     // Append failed; undo the AddRef above.
   110     NS_RELEASE_THIS();
   111   }
   112 }
   114 void
   115 MediaQueryList::RemoveListener(MediaQueryListListener& aListener)
   116 {
   117   for (uint32_t i = 0; i < mCallbacks.Length(); ++i) {
   118     if (aListener == *mCallbacks[i]) {
   119       mCallbacks.RemoveElementAt(i);
   120       if (!HasListeners()) {
   121         // See NS_ADDREF_THIS() in AddListener.
   122         NS_RELEASE_THIS();
   123       }
   124       break;
   125     }
   126   }
   127 }
   129 void
   130 MediaQueryList::RemoveAllListeners()
   131 {
   132   bool hadListeners = HasListeners();
   133   mCallbacks.Clear();
   134   if (hadListeners) {
   135     // See NS_ADDREF_THIS() in AddListener.
   136     NS_RELEASE_THIS();
   137   }
   138 }
   140 void
   141 MediaQueryList::RecomputeMatches()
   142 {
   143   if (!mPresContext) {
   144     return;
   145   }
   147   mMatches = mMediaList->Matches(mPresContext, nullptr);
   148   mMatchesValid = true;
   149 }
   151 void
   152 MediaQueryList::MediumFeaturesChanged(NotifyList &aListenersToNotify)
   153 {
   154   mMatchesValid = false;
   156   if (HasListeners()) {
   157     bool oldMatches = mMatches;
   158     RecomputeMatches();
   159     if (mMatches != oldMatches) {
   160       for (uint32_t i = 0, i_end = mCallbacks.Length(); i != i_end; ++i) {
   161         HandleChangeData *d = aListenersToNotify.AppendElement();
   162         if (d) {
   163           d->mql = this;
   164           d->callback = mCallbacks[i];
   165         }
   166       }
   167     }
   168   }
   169 }
   171 nsISupports*
   172 MediaQueryList::GetParentObject() const
   173 {
   174   if (!mPresContext) {
   175     return nullptr;
   176   }
   177   return mPresContext->Document();
   178 }
   180 JSObject*
   181 MediaQueryList::WrapObject(JSContext* aCx)
   182 {
   183   return MediaQueryListBinding::Wrap(aCx, this);
   184 }
   186 } // namespace dom
   187 } // namespace mozilla

mercurial