LCOV - code coverage report
Current view: directory - content/events/src - nsDOMEventTargetHelper.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 154 113 73.4 %
Date: 2012-06-02 Functions: 37 31 83.8 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License
       6                 :  * Version 1.1 (the "License"); you may not use this file except in
       7                 :  * compliance with the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is 
      18                 :  * Mozilla Corporation
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2009
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *  Olli Pettay <Olli.Pettay@helsinki.fi>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "nsDOMEventTargetHelper.h"
      40                 : #include "nsContentUtils.h"
      41                 : #include "nsEventDispatcher.h"
      42                 : #include "nsGUIEvent.h"
      43                 : #include "nsIDocument.h"
      44                 : #include "nsIJSContextStack.h"
      45                 : #include "nsDOMJSUtils.h"
      46                 : #include "prprf.h"
      47                 : #include "nsGlobalWindow.h"
      48                 : 
      49            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMEventListenerWrapper)
      50           23568 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMEventListenerWrapper)
      51            3507 :   NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
      52            3507 : NS_INTERFACE_MAP_END_AGGREGATED(mListener)
      53                 : 
      54           14307 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMEventListenerWrapper)
      55           17814 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMEventListenerWrapper)
      56                 : 
      57             353 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMEventListenerWrapper)
      58             353 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mListener)
      59             353 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
      60                 : 
      61             353 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMEventListenerWrapper)
      62             353 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mListener)
      63             353 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
      64                 : 
      65                 : NS_IMETHODIMP
      66            3433 : nsDOMEventListenerWrapper::HandleEvent(nsIDOMEvent* aEvent)
      67                 : {
      68            3433 :   return mListener->HandleEvent(aEvent);
      69                 : }
      70                 : 
      71            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMEventTargetHelper)
      72                 : 
      73            6262 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMEventTargetHelper)
      74            6262 :   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
      75            6262 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
      76                 : 
      77             641 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDOMEventTargetHelper)
      78             641 :   if (NS_UNLIKELY(cb.WantDebugInfo())) {
      79                 :     char name[512];
      80               0 :     nsAutoString uri;
      81               0 :     if (tmp->mOwner && tmp->mOwner->GetExtantDocument()) {
      82               0 :       tmp->mOwner->GetExtantDocument()->GetDocumentURI(uri);
      83                 :     }
      84                 :     PR_snprintf(name, sizeof(name), "nsDOMEventTargetHelper %s",
      85               0 :                 NS_ConvertUTF16toUTF8(uri).get());
      86                 :     cb.DescribeRefCountedNode(tmp->mRefCnt.get(), sizeof(nsDOMEventTargetHelper),
      87               0 :                               name);
      88                 :   } else {
      89             641 :     NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsDOMEventTargetHelper, tmp->mRefCnt.get())
      90                 :   }
      91                 : 
      92             641 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
      93             641 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mListenerManager,
      94                 :                                                   nsEventListenerManager)
      95             641 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
      96                 : 
      97             623 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMEventTargetHelper)
      98             623 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
      99             623 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mListenerManager)
     100             623 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     101                 : 
     102          143214 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMEventTargetHelper)
     103          117383 :   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
     104          101949 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
     105           98236 :   NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
     106           28470 : NS_INTERFACE_MAP_END
     107                 : 
     108          238329 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMEventTargetHelper)
     109          238329 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMEventTargetHelper)
     110                 : 
     111           34390 : NS_IMPL_DOMTARGET_DEFAULTS(nsDOMEventTargetHelper);
     112                 : 
     113            7354 : nsDOMEventTargetHelper::~nsDOMEventTargetHelper()
     114                 : {
     115            3677 :   if (mOwner) {
     116               0 :     static_cast<nsGlobalWindow*>(mOwner)->RemoveEventTargetObject(this);
     117                 :   }
     118            3677 :   if (mListenerManager) {
     119            2839 :     mListenerManager->Disconnect();
     120                 :   }
     121            3677 :   nsContentUtils::ReleaseWrapper(this, this);
     122            7354 : }
     123                 : 
     124                 : void
     125              77 : nsDOMEventTargetHelper::BindToOwner(nsPIDOMWindow* aOwner)
     126                 : {
     127              77 :   if (mOwner) {
     128               0 :     static_cast<nsGlobalWindow*>(mOwner)->RemoveEventTargetObject(this);
     129               0 :     mOwner = nsnull;
     130               0 :     mHasOrHasHadOwner = false;
     131                 :   }
     132              77 :   if (aOwner) {
     133               0 :     mOwner = aOwner;
     134               0 :     mHasOrHasHadOwner = true;
     135               0 :     static_cast<nsGlobalWindow*>(mOwner)->AddEventTargetObject(this);
     136                 :   }
     137              77 : }
     138                 : 
     139                 : void
     140            3003 : nsDOMEventTargetHelper::BindToOwner(nsDOMEventTargetHelper* aOther)
     141                 : {
     142            3003 :   if (mOwner) {
     143               0 :     static_cast<nsGlobalWindow*>(mOwner)->RemoveEventTargetObject(this);
     144               0 :     mOwner = nsnull;
     145               0 :     mHasOrHasHadOwner = false;
     146                 :   }
     147            3003 :   if (aOther) {
     148            3003 :     mHasOrHasHadOwner = aOther->HasOrHasHadOwner();
     149            3003 :     if (aOther->GetOwner()) {
     150               0 :       mOwner = aOther->GetOwner();
     151               0 :       mHasOrHasHadOwner = true;
     152               0 :       static_cast<nsGlobalWindow*>(mOwner)->AddEventTargetObject(this);
     153                 :     }
     154                 :   }
     155            3003 : }
     156                 : 
     157                 : void
     158               0 : nsDOMEventTargetHelper::DisconnectFromOwner()
     159                 : {
     160               0 :   mOwner = nsnull;
     161                 :   // Event listeners can't be handled anymore, so we can release them here.
     162               0 :   if (mListenerManager) {
     163               0 :     mListenerManager->Disconnect();
     164               0 :     mListenerManager = nsnull;
     165                 :   }
     166               0 : }
     167                 : 
     168                 : NS_IMETHODIMP
     169              29 : nsDOMEventTargetHelper::RemoveEventListener(const nsAString& aType,
     170                 :                                             nsIDOMEventListener* aListener,
     171                 :                                             bool aUseCapture)
     172                 : {
     173              29 :   nsEventListenerManager* elm = GetListenerManager(false);
     174              29 :   if (elm) {
     175              29 :     elm->RemoveEventListener(aType, aListener, aUseCapture);
     176                 :   }
     177                 : 
     178              29 :   return NS_OK;
     179                 : }
     180                 : 
     181               0 : NS_IMPL_REMOVE_SYSTEM_EVENT_LISTENER(nsDOMEventTargetHelper)
     182                 : 
     183                 : NS_IMETHODIMP
     184            4582 : nsDOMEventTargetHelper::AddEventListener(const nsAString& aType,
     185                 :                                          nsIDOMEventListener *aListener,
     186                 :                                          bool aUseCapture,
     187                 :                                          bool aWantsUntrusted,
     188                 :                                          PRUint8 aOptionalArgc)
     189                 : {
     190            4582 :   NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1,
     191                 :                "Won't check if this is chrome, you want to set "
     192                 :                "aWantsUntrusted to false or make the aWantsUntrusted "
     193                 :                "explicit by making aOptionalArgc non-zero.");
     194                 : 
     195            4582 :   if (aOptionalArgc < 2) {
     196                 :     nsresult rv;
     197            4582 :     nsIScriptContext* context = GetContextForEventHandlers(&rv);
     198            4582 :     NS_ENSURE_SUCCESS(rv, rv);
     199                 :     nsCOMPtr<nsIDocument> doc =
     200            9164 :       nsContentUtils::GetDocumentFromScriptContext(context);
     201            4582 :     aWantsUntrusted = doc && !nsContentUtils::IsChromeDoc(doc);
     202                 :   }
     203                 : 
     204            4582 :   nsEventListenerManager* elm = GetListenerManager(true);
     205            4582 :   NS_ENSURE_STATE(elm);
     206            4582 :   elm->AddEventListener(aType, aListener, aUseCapture, aWantsUntrusted);
     207            4582 :   return NS_OK;
     208                 : }
     209                 : 
     210                 : NS_IMETHODIMP
     211               0 : nsDOMEventTargetHelper::AddSystemEventListener(const nsAString& aType,
     212                 :                                                nsIDOMEventListener *aListener,
     213                 :                                                bool aUseCapture,
     214                 :                                                bool aWantsUntrusted,
     215                 :                                                PRUint8 aOptionalArgc)
     216                 : {
     217               0 :   NS_ASSERTION(!aWantsUntrusted || aOptionalArgc > 1,
     218                 :                "Won't check if this is chrome, you want to set "
     219                 :                "aWantsUntrusted to false or make the aWantsUntrusted "
     220                 :                "explicit by making aOptionalArgc non-zero.");
     221                 : 
     222               0 :   if (aOptionalArgc < 2) {
     223                 :     nsresult rv;
     224               0 :     nsIScriptContext* context = GetContextForEventHandlers(&rv);
     225               0 :     NS_ENSURE_SUCCESS(rv, rv);
     226                 :     nsCOMPtr<nsIDocument> doc =
     227               0 :       nsContentUtils::GetDocumentFromScriptContext(context);
     228               0 :     aWantsUntrusted = doc && !nsContentUtils::IsChromeDoc(doc);
     229                 :   }
     230                 : 
     231                 :   return NS_AddSystemEventListener(this, aType, aListener, aUseCapture,
     232               0 :                                    aWantsUntrusted);
     233                 : }
     234                 : 
     235                 : NS_IMETHODIMP
     236            4858 : nsDOMEventTargetHelper::DispatchEvent(nsIDOMEvent* aEvent, bool* aRetVal)
     237                 : {
     238            4858 :   nsEventStatus status = nsEventStatus_eIgnore;
     239                 :   nsresult rv =
     240            4858 :     nsEventDispatcher::DispatchDOMEvent(this, nsnull, aEvent, nsnull, &status);
     241                 : 
     242            4858 :   *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
     243            4858 :   return rv;
     244                 : }
     245                 : 
     246                 : nsresult
     247            3508 : nsDOMEventTargetHelper::RemoveAddEventListener(const nsAString& aType,
     248                 :                                                nsRefPtr<nsDOMEventListenerWrapper>& aCurrent,
     249                 :                                                nsIDOMEventListener* aNew)
     250                 : {
     251            3508 :   if (aCurrent) {
     252              27 :     RemoveEventListener(aType, aCurrent, false);
     253              27 :     aCurrent = nsnull;
     254                 :   }
     255            3508 :   if (aNew) {
     256            3507 :     aCurrent = new nsDOMEventListenerWrapper(aNew);
     257            3507 :     NS_ENSURE_TRUE(aCurrent, NS_ERROR_OUT_OF_MEMORY);
     258            3507 :     nsIDOMEventTarget::AddEventListener(aType, aCurrent, false);
     259                 :   }
     260            3508 :   return NS_OK;
     261                 : }
     262                 : 
     263                 : nsresult
     264               3 : nsDOMEventTargetHelper::GetInnerEventListener(nsRefPtr<nsDOMEventListenerWrapper>& aWrapper,
     265                 :                                               nsIDOMEventListener** aListener)
     266                 : {
     267               3 :   NS_ENSURE_ARG_POINTER(aListener);
     268               3 :   if (aWrapper) {
     269               0 :     NS_IF_ADDREF(*aListener = aWrapper->GetInner());
     270                 :   } else {
     271               3 :     *aListener = nsnull;
     272                 :   }
     273               3 :   return NS_OK;
     274                 : }
     275                 : 
     276                 : 
     277                 : nsresult
     278            9859 : nsDOMEventTargetHelper::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
     279                 : {
     280            9859 :   aVisitor.mCanHandle = true;
     281            9859 :   aVisitor.mParentTarget = nsnull;
     282            9859 :   return NS_OK;
     283                 : }
     284                 : 
     285                 : nsresult
     286            9962 : nsDOMEventTargetHelper::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
     287                 : {
     288            9962 :   return NS_OK;
     289                 : }
     290                 : 
     291                 : nsresult
     292            5078 : nsDOMEventTargetHelper::DispatchDOMEvent(nsEvent* aEvent,
     293                 :                                          nsIDOMEvent* aDOMEvent,
     294                 :                                          nsPresContext* aPresContext,
     295                 :                                          nsEventStatus* aEventStatus)
     296                 : {
     297                 :   return
     298                 :     nsEventDispatcher::DispatchDOMEvent(this, aEvent, aDOMEvent, aPresContext,
     299            5078 :                                         aEventStatus);
     300                 : }
     301                 : 
     302                 : nsEventListenerManager*
     303           32736 : nsDOMEventTargetHelper::GetListenerManager(bool aCreateIfNotFound)
     304                 : {
     305           32736 :   if (!mListenerManager && aCreateIfNotFound) {
     306            3168 :     mListenerManager = new nsEventListenerManager(this);
     307                 :   }
     308                 : 
     309           32736 :   return mListenerManager;
     310                 : }
     311                 : 
     312                 : nsIScriptContext*
     313           10130 : nsDOMEventTargetHelper::GetContextForEventHandlers(nsresult* aRv)
     314                 : {
     315           10130 :   *aRv = CheckInnerWindowCorrectness();
     316           10130 :   if (NS_FAILED(*aRv)) {
     317               0 :     return nsnull;
     318                 :   }
     319               0 :   return mOwner ? static_cast<nsGlobalWindow*>(mOwner)->GetContextInternal()
     320           10130 :                 : nsnull;
     321                 : }
     322                 : 
     323                 : void
     324               2 : nsDOMEventTargetHelper::Init(JSContext* aCx)
     325                 : {
     326               2 :   JSContext* cx = aCx;
     327               2 :   if (!cx) {
     328               2 :     nsIJSContextStack* stack = nsContentUtils::ThreadJSContextStack();
     329                 : 
     330               2 :     if (!stack)
     331               0 :       return;
     332                 : 
     333               2 :     if (NS_FAILED(stack->Peek(&cx)) || !cx)
     334               0 :       return;
     335                 :   }
     336                 : 
     337               2 :   NS_ASSERTION(cx, "Should have returned earlier ...");
     338               2 :   nsIScriptContext* context = GetScriptContextFromJSContext(cx);
     339               2 :   if (context) {
     340                 :     nsCOMPtr<nsPIDOMWindow> window =
     341               0 :       do_QueryInterface(context->GetGlobalObject());
     342               0 :     if (window) {
     343               0 :       BindToOwner(window->GetCurrentInnerWindow());
     344                 :     }
     345                 :   }
     346            4392 : }

Generated by: LCOV version 1.7