layout/style/MediaQueryList.cpp

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

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

mercurial