LCOV - code coverage report
Current view: top level - layout/style - MediaQueryList.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 53 90 58.9 %
Date: 2017-07-14 16:53:18 Functions: 13 19 68.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
       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             : #include "mozilla/dom/MediaQueryListEvent.h"
      11             : #include "mozilla/dom/MediaList.h"
      12             : #include "mozilla/dom/EventTarget.h"
      13             : #include "mozilla/dom/EventTargetBinding.h"
      14             : #include "nsPresContext.h"
      15             : #include "nsCSSParser.h"
      16             : #include "nsIDocument.h"
      17             : 
      18             : #define ONCHANGE_STRING NS_LITERAL_STRING("change")
      19             : 
      20             : namespace mozilla {
      21             : namespace dom {
      22             : 
      23           3 : MediaQueryList::MediaQueryList(nsIDocument* aDocument,
      24           3 :                                const nsAString& aMediaQueryList)
      25             :   : mDocument(aDocument)
      26           3 :   , mMatchesValid(false)
      27             : {
      28             :   mMediaList =
      29           3 :     MediaList::Create(aDocument->GetStyleBackendType(), aMediaQueryList);
      30             : 
      31           3 :   KeepAliveIfHasListenersFor(ONCHANGE_STRING);
      32           3 : }
      33             : 
      34           0 : MediaQueryList::~MediaQueryList()
      35           0 : {}
      36             : 
      37             : NS_IMPL_CYCLE_COLLECTION_CLASS(MediaQueryList)
      38             : 
      39           3 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaQueryList,
      40             :                                                   DOMEventTargetHelper)
      41           3 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
      42           3 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
      43             : 
      44           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaQueryList,
      45             :                                                 DOMEventTargetHelper)
      46           0 :   if (tmp->mDocument) {
      47           0 :     tmp->remove();
      48           0 :     NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
      49             :   }
      50           0 :   tmp->Disconnect();
      51           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
      52           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
      53             : 
      54          36 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaQueryList)
      55          18 : NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
      56             : 
      57           7 : NS_IMPL_ADDREF_INHERITED(MediaQueryList, DOMEventTargetHelper)
      58           3 : NS_IMPL_RELEASE_INHERITED(MediaQueryList, DOMEventTargetHelper)
      59             : 
      60             : void
      61           0 : MediaQueryList::GetMedia(nsAString &aMedia)
      62             : {
      63           0 :   mMediaList->GetText(aMedia);
      64           0 : }
      65             : 
      66             : bool
      67           2 : MediaQueryList::Matches()
      68             : {
      69           2 :   if (!mMatchesValid) {
      70           2 :     MOZ_ASSERT(!HasListeners(),
      71             :                "when listeners present, must keep mMatches current");
      72           2 :     RecomputeMatches();
      73             :   }
      74             : 
      75           2 :   return mMatches;
      76             : }
      77             : 
      78             : void
      79           1 : MediaQueryList::AddListener(EventListener* aListener, ErrorResult& aRv)
      80             : {
      81           1 :   if (!aListener) {
      82           0 :     return;
      83             :   }
      84             : 
      85           2 :   AddEventListenerOptionsOrBoolean options;
      86           1 :   options.SetAsBoolean() = false;
      87             : 
      88           1 :   AddEventListener(ONCHANGE_STRING, aListener, options, false, aRv);
      89             : }
      90             : 
      91             : void
      92           1 : MediaQueryList::AddEventListener(const nsAString& aType,
      93             :                                  EventListener* aCallback,
      94             :                                  const AddEventListenerOptionsOrBoolean& aOptions,
      95             :                                  const dom::Nullable<bool>& aWantsUntrusted,
      96             :                                  ErrorResult& aRv)
      97             : {
      98           1 :   if (!mMatchesValid) {
      99           1 :     MOZ_ASSERT(!HasListeners(),
     100             :                "when listeners present, must keep mMatches current");
     101           1 :     RecomputeMatches();
     102             :   }
     103             : 
     104           1 :   DOMEventTargetHelper::AddEventListener(aType, aCallback, aOptions,
     105           1 :                                          aWantsUntrusted, aRv);
     106           1 : }
     107             : 
     108             : void
     109           0 : MediaQueryList::RemoveListener(EventListener* aListener, ErrorResult& aRv)
     110             : {
     111           0 :   if (!aListener) {
     112           0 :     return;
     113             :   }
     114             : 
     115           0 :   EventListenerOptionsOrBoolean options;
     116           0 :   options.SetAsBoolean() = false;
     117             : 
     118           0 :   RemoveEventListener(ONCHANGE_STRING, aListener, options, aRv);
     119             : }
     120             : 
     121             : bool
     122          10 : MediaQueryList::HasListeners()
     123             : {
     124          10 :   return HasListenersFor(ONCHANGE_STRING);
     125             : }
     126             : 
     127             : void
     128           0 : MediaQueryList::Disconnect()
     129             : {
     130           0 :   DisconnectFromOwner();
     131             : 
     132           0 :   IgnoreKeepAliveIfHasListenersFor(ONCHANGE_STRING);
     133           0 : }
     134             : 
     135             : void
     136           4 : MediaQueryList::RecomputeMatches()
     137             : {
     138           4 :   if (!mDocument) {
     139           0 :     return;
     140             :   }
     141             : 
     142           4 :   if (mDocument->GetParentDocument()) {
     143             :     // Flush frames on the parent so our prescontext will get
     144             :     // recreated as needed.
     145           0 :     mDocument->GetParentDocument()->FlushPendingNotifications(FlushType::Frames);
     146             :     // That might have killed our document, so recheck that.
     147           0 :     if (!mDocument) {
     148           0 :       return;
     149             :     }
     150             :   }
     151             : 
     152           4 :   nsIPresShell* shell = mDocument->GetShell();
     153           4 :   if (!shell) {
     154             :     // XXXbz What's the right behavior here?  Spec doesn't say.
     155           0 :     return;
     156             :   }
     157             : 
     158           4 :   nsPresContext* presContext = shell->GetPresContext();
     159           4 :   if (!presContext) {
     160             :     // XXXbz What's the right behavior here?  Spec doesn't say.
     161           0 :     return;
     162             :   }
     163             : 
     164           4 :   mMatches = mMediaList->Matches(presContext);
     165           4 :   mMatchesValid = true;
     166             : }
     167             : 
     168             : nsISupports*
     169           3 : MediaQueryList::GetParentObject() const
     170             : {
     171           3 :   return mDocument;
     172             : }
     173             : 
     174             : JSObject*
     175           3 : MediaQueryList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
     176             : {
     177           3 :   return MediaQueryListBinding::Wrap(aCx, this, aGivenProto);
     178             : }
     179             : 
     180             : void
     181           7 : MediaQueryList::MaybeNotify()
     182             : {
     183           7 :   mMatchesValid = false;
     184             : 
     185           7 :   if (!HasListeners()) {
     186          13 :     return;
     187             :   }
     188             : 
     189           1 :   bool oldMatches = mMatches;
     190           1 :   RecomputeMatches();
     191             : 
     192             :   // No need to notify the change.
     193           1 :   if (mMatches == oldMatches) {
     194           1 :     return;
     195             :   }
     196             : 
     197           0 :   MediaQueryListEventInit init;
     198           0 :   init.mBubbles = false;
     199           0 :   init.mCancelable = false;
     200           0 :   init.mMatches = mMatches;
     201           0 :   mMediaList->GetText(init.mMedia);
     202             : 
     203             :   RefPtr<MediaQueryListEvent> event =
     204           0 :     MediaQueryListEvent::Constructor(this, ONCHANGE_STRING, init);
     205           0 :   event->SetTrusted(true);
     206             : 
     207             :   bool dummy;
     208           0 :   DispatchEvent(event, &dummy);
     209             : }
     210             : 
     211             : } // namespace dom
     212             : } // namespace mozilla

Generated by: LCOV version 1.13