LCOV - code coverage report
Current view: directory - content/smil - nsSMILTimeValueSpec.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 232 0 0.0 %
Date: 2012-06-02 Functions: 29 0 0.0 %

       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 Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * 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 the Mozilla SMIL module.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is Brian Birtles.
      18                 :  * Portions created by the Initial Developer are Copyright (C) 2005
      19                 :  * the Initial Developer. All Rights Reserved.
      20                 :  *
      21                 :  * Contributor(s):
      22                 :  *   Brian Birtles <birtles@gmail.com>
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      26                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : #include "nsSMILTimeValueSpec.h"
      39                 : #include "nsSMILInterval.h"
      40                 : #include "nsSMILTimeContainer.h"
      41                 : #include "nsSMILTimeValue.h"
      42                 : #include "nsSMILTimedElement.h"
      43                 : #include "nsSMILInstanceTime.h"
      44                 : #include "nsSMILParserUtils.h"
      45                 : #include "nsISMILAnimationElement.h"
      46                 : #include "nsContentUtils.h"
      47                 : #include "nsEventListenerManager.h"
      48                 : #include "nsGUIEvent.h"
      49                 : #include "nsIDOMTimeEvent.h"
      50                 : #include "nsString.h"
      51                 : #include <limits>
      52                 : 
      53                 : using namespace mozilla::dom;
      54                 : 
      55                 : //----------------------------------------------------------------------
      56                 : // Nested class: EventListener
      57                 : 
      58               0 : NS_IMPL_ISUPPORTS1(nsSMILTimeValueSpec::EventListener, nsIDOMEventListener)
      59                 : 
      60                 : NS_IMETHODIMP
      61               0 : nsSMILTimeValueSpec::EventListener::HandleEvent(nsIDOMEvent* aEvent)
      62                 : {
      63               0 :   if (mSpec) {
      64               0 :     mSpec->HandleEvent(aEvent);
      65                 :   }
      66               0 :   return NS_OK;
      67                 : }
      68                 : 
      69                 : //----------------------------------------------------------------------
      70                 : // Implementation
      71                 : 
      72                 : #ifdef _MSC_VER
      73                 : // Disable "warning C4355: 'this' : used in base member initializer list".
      74                 : // We can ignore that warning because we know that mReferencedElement's
      75                 : // constructor doesn't dereference the pointer passed to it.
      76                 : #pragma warning(push)
      77                 : #pragma warning(disable:4355)
      78                 : #endif
      79               0 : nsSMILTimeValueSpec::nsSMILTimeValueSpec(nsSMILTimedElement& aOwner,
      80                 :                                          bool aIsBegin)
      81                 :   : mOwner(&aOwner),
      82                 :     mIsBegin(aIsBegin),
      83               0 :     mReferencedElement(this)
      84                 : #ifdef _MSC_VER
      85                 : #pragma warning(pop)
      86                 : #endif
      87                 : {
      88               0 : }
      89                 : 
      90               0 : nsSMILTimeValueSpec::~nsSMILTimeValueSpec()
      91                 : {
      92               0 :   UnregisterFromReferencedElement(mReferencedElement.get());
      93               0 :   if (mEventListener) {
      94               0 :     mEventListener->Disconnect();
      95               0 :     mEventListener = nsnull;
      96                 :   }
      97               0 : }
      98                 : 
      99                 : nsresult
     100               0 : nsSMILTimeValueSpec::SetSpec(const nsAString& aStringSpec,
     101                 :                              Element* aContextNode)
     102                 : {
     103               0 :   nsSMILTimeValueSpecParams params;
     104                 :   nsresult rv =
     105               0 :     nsSMILParserUtils::ParseTimeValueSpecParams(aStringSpec, params);
     106                 : 
     107               0 :   if (NS_FAILED(rv))
     108               0 :     return rv;
     109                 : 
     110               0 :   mParams = params;
     111                 : 
     112                 :   // According to SMIL 3.0:
     113                 :   //   The special value "indefinite" does not yield an instance time in the
     114                 :   //   begin list. It will, however yield a single instance with the value
     115                 :   //   "indefinite" in an end list. This value is not removed by a reset.
     116               0 :   if (mParams.mType == nsSMILTimeValueSpecParams::OFFSET ||
     117               0 :       (!mIsBegin && mParams.mType == nsSMILTimeValueSpecParams::INDEFINITE)) {
     118               0 :     mOwner->AddInstanceTime(new nsSMILInstanceTime(mParams.mOffset), mIsBegin);
     119                 :   }
     120                 : 
     121                 :   // Fill in the event symbol to simplify handling later
     122               0 :   if (mParams.mType == nsSMILTimeValueSpecParams::REPEAT) {
     123               0 :     mParams.mEventSymbol = nsGkAtoms::repeatEvent;
     124               0 :   } else if (mParams.mType == nsSMILTimeValueSpecParams::ACCESSKEY) {
     125               0 :     mParams.mEventSymbol = nsGkAtoms::keypress;
     126                 :   }
     127                 : 
     128               0 :   ResolveReferences(aContextNode);
     129                 : 
     130               0 :   return rv;
     131                 : }
     132                 : 
     133                 : void
     134               0 : nsSMILTimeValueSpec::ResolveReferences(nsIContent* aContextNode)
     135                 : {
     136               0 :   if (mParams.mType != nsSMILTimeValueSpecParams::SYNCBASE && !IsEventBased())
     137               0 :     return;
     138                 : 
     139               0 :   NS_ABORT_IF_FALSE(aContextNode,
     140                 :       "null context node for resolving timing references against");
     141                 : 
     142                 :   // If we're not bound to the document yet, don't worry, we'll get called again
     143                 :   // when that happens
     144               0 :   if (!aContextNode->IsInDoc())
     145               0 :     return;
     146                 : 
     147                 :   // Hold ref to the old element so that it isn't destroyed in between resetting
     148                 :   // the referenced element and using the pointer to update the referenced
     149                 :   // element.
     150               0 :   nsRefPtr<Element> oldReferencedElement = mReferencedElement.get();
     151                 : 
     152               0 :   if (mParams.mDependentElemID) {
     153                 :     mReferencedElement.ResetWithID(aContextNode,
     154               0 :         nsDependentAtomString(mParams.mDependentElemID));
     155               0 :   } else if (mParams.mType == nsSMILTimeValueSpecParams::EVENT) {
     156               0 :     Element* target = mOwner->GetTargetElement();
     157               0 :     mReferencedElement.ResetWithElement(target);
     158               0 :   } else if (mParams.mType == nsSMILTimeValueSpecParams::ACCESSKEY) {
     159               0 :     nsIDocument* doc = aContextNode->GetCurrentDoc();
     160               0 :     NS_ABORT_IF_FALSE(doc, "We are in the document but current doc is null");
     161               0 :     mReferencedElement.ResetWithElement(doc->GetRootElement());
     162                 :   } else {
     163               0 :     NS_ABORT_IF_FALSE(false, "Syncbase or repeat spec without ID");
     164                 :   }
     165               0 :   UpdateReferencedElement(oldReferencedElement, mReferencedElement.get());
     166                 : }
     167                 : 
     168                 : bool
     169               0 : nsSMILTimeValueSpec::IsEventBased() const
     170                 : {
     171                 :   return mParams.mType == nsSMILTimeValueSpecParams::EVENT ||
     172                 :          mParams.mType == nsSMILTimeValueSpecParams::REPEAT ||
     173               0 :          mParams.mType == nsSMILTimeValueSpecParams::ACCESSKEY;
     174                 : }
     175                 : 
     176                 : void
     177               0 : nsSMILTimeValueSpec::HandleNewInterval(nsSMILInterval& aInterval,
     178                 :                                        const nsSMILTimeContainer* aSrcContainer)
     179                 : {
     180                 :   const nsSMILInstanceTime& baseInstance = mParams.mSyncBegin
     181               0 :     ? *aInterval.Begin() : *aInterval.End();
     182                 :   nsSMILTimeValue newTime =
     183               0 :     ConvertBetweenTimeContainers(baseInstance.Time(), aSrcContainer);
     184                 : 
     185                 :   // Apply offset
     186               0 :   if (!ApplyOffset(newTime)) {
     187               0 :     NS_WARNING("New time overflows nsSMILTime, ignoring");
     188               0 :     return;
     189                 :   }
     190                 : 
     191                 :   // Create the instance time and register it with the interval
     192                 :   nsRefPtr<nsSMILInstanceTime> newInstance =
     193                 :     new nsSMILInstanceTime(newTime, nsSMILInstanceTime::SOURCE_SYNCBASE, this,
     194               0 :                            &aInterval);
     195               0 :   mOwner->AddInstanceTime(newInstance, mIsBegin);
     196                 : }
     197                 : 
     198                 : void
     199               0 : nsSMILTimeValueSpec::HandleTargetElementChange(Element* aNewTarget)
     200                 : {
     201               0 :   if (!IsEventBased() || mParams.mDependentElemID)
     202               0 :     return;
     203                 : 
     204               0 :   mReferencedElement.ResetWithElement(aNewTarget);
     205                 : }
     206                 : 
     207                 : void
     208               0 : nsSMILTimeValueSpec::HandleChangedInstanceTime(
     209                 :     const nsSMILInstanceTime& aBaseTime,
     210                 :     const nsSMILTimeContainer* aSrcContainer,
     211                 :     nsSMILInstanceTime& aInstanceTimeToUpdate,
     212                 :     bool aObjectChanged)
     213                 : {
     214                 :   // If the instance time is fixed (e.g. because it's being used as the begin
     215                 :   // time of an active or postactive interval) we just ignore the change.
     216               0 :   if (aInstanceTimeToUpdate.IsFixedTime())
     217               0 :     return;
     218                 : 
     219                 :   nsSMILTimeValue updatedTime =
     220               0 :     ConvertBetweenTimeContainers(aBaseTime.Time(), aSrcContainer);
     221                 : 
     222                 :   // Apply offset
     223               0 :   if (!ApplyOffset(updatedTime)) {
     224               0 :     NS_WARNING("Updated time overflows nsSMILTime, ignoring");
     225               0 :     return;
     226                 :   }
     227                 : 
     228                 :   // The timed element that owns the instance time does the updating so it can
     229                 :   // re-sort its array of instance times more efficiently
     230               0 :   if (aInstanceTimeToUpdate.Time() != updatedTime || aObjectChanged) {
     231               0 :     mOwner->UpdateInstanceTime(&aInstanceTimeToUpdate, updatedTime, mIsBegin);
     232                 :   }
     233                 : }
     234                 : 
     235                 : void
     236               0 : nsSMILTimeValueSpec::HandleDeletedInstanceTime(
     237                 :     nsSMILInstanceTime &aInstanceTime)
     238                 : {
     239               0 :   mOwner->RemoveInstanceTime(&aInstanceTime, mIsBegin);
     240               0 : }
     241                 : 
     242                 : bool
     243               0 : nsSMILTimeValueSpec::DependsOnBegin() const
     244                 : {
     245               0 :   return mParams.mSyncBegin;
     246                 : }
     247                 : 
     248                 : void
     249               0 : nsSMILTimeValueSpec::Traverse(nsCycleCollectionTraversalCallback* aCallback)
     250                 : {
     251               0 :   mReferencedElement.Traverse(aCallback);
     252               0 : }
     253                 : 
     254                 : void
     255               0 : nsSMILTimeValueSpec::Unlink()
     256                 : {
     257               0 :   UnregisterFromReferencedElement(mReferencedElement.get());
     258               0 :   mReferencedElement.Unlink();
     259               0 : }
     260                 : 
     261                 : //----------------------------------------------------------------------
     262                 : // Implementation helpers
     263                 : 
     264                 : void
     265               0 : nsSMILTimeValueSpec::UpdateReferencedElement(Element* aFrom, Element* aTo)
     266                 : {
     267               0 :   if (aFrom == aTo)
     268               0 :     return;
     269                 : 
     270               0 :   UnregisterFromReferencedElement(aFrom);
     271                 : 
     272               0 :   switch (mParams.mType)
     273                 :   {
     274                 :   case nsSMILTimeValueSpecParams::SYNCBASE:
     275                 :     {
     276               0 :       nsSMILTimedElement* to = GetTimedElement(aTo);
     277               0 :       if (to) {
     278               0 :         to->AddDependent(*this);
     279                 :       }
     280                 :     }
     281               0 :     break;
     282                 : 
     283                 :   case nsSMILTimeValueSpecParams::EVENT:
     284                 :   case nsSMILTimeValueSpecParams::REPEAT:
     285                 :   case nsSMILTimeValueSpecParams::ACCESSKEY:
     286               0 :     RegisterEventListener(aTo);
     287               0 :     break;
     288                 : 
     289                 :   default:
     290                 :     // not a referencing-type
     291               0 :     break;
     292                 :   }
     293                 : }
     294                 : 
     295                 : void
     296               0 : nsSMILTimeValueSpec::UnregisterFromReferencedElement(Element* aElement)
     297                 : {
     298               0 :   if (!aElement)
     299               0 :     return;
     300                 : 
     301               0 :   if (mParams.mType == nsSMILTimeValueSpecParams::SYNCBASE) {
     302               0 :     nsSMILTimedElement* timedElement = GetTimedElement(aElement);
     303               0 :     if (timedElement) {
     304               0 :       timedElement->RemoveDependent(*this);
     305                 :     }
     306               0 :     mOwner->RemoveInstanceTimesForCreator(this, mIsBegin);
     307               0 :   } else if (IsEventBased()) {
     308               0 :     UnregisterEventListener(aElement);
     309                 :   }
     310                 : }
     311                 : 
     312                 : nsSMILTimedElement*
     313               0 : nsSMILTimeValueSpec::GetTimedElement(Element* aElement)
     314                 : {
     315               0 :   if (!aElement)
     316               0 :     return nsnull;
     317                 : 
     318               0 :   nsCOMPtr<nsISMILAnimationElement> animElement = do_QueryInterface(aElement);
     319               0 :   if (!animElement)
     320               0 :     return nsnull;
     321                 : 
     322               0 :   return &animElement->TimedElement();
     323                 : }
     324                 : 
     325                 : // Indicates whether we're allowed to register an event-listener
     326                 : // when scripting is disabled.
     327                 : bool
     328               0 : nsSMILTimeValueSpec::IsWhitelistedEvent()
     329                 : {
     330                 :   // The category of (SMIL-specific) "repeat(n)" events are allowed.
     331               0 :   if (mParams.mType == nsSMILTimeValueSpecParams::REPEAT) {
     332               0 :     return true;
     333                 :   }
     334                 : 
     335                 :   // A specific list of other SMIL-related events are allowed, too.
     336               0 :   if (mParams.mType == nsSMILTimeValueSpecParams::EVENT &&
     337               0 :       (mParams.mEventSymbol == nsGkAtoms::repeat ||
     338               0 :        mParams.mEventSymbol == nsGkAtoms::repeatEvent ||
     339               0 :        mParams.mEventSymbol == nsGkAtoms::beginEvent ||
     340               0 :        mParams.mEventSymbol == nsGkAtoms::endEvent)) {
     341               0 :     return true;
     342                 :   }
     343                 : 
     344               0 :   return false;
     345                 : }
     346                 : 
     347                 : void
     348               0 : nsSMILTimeValueSpec::RegisterEventListener(Element* aTarget)
     349                 : {
     350               0 :   NS_ABORT_IF_FALSE(IsEventBased(),
     351                 :     "Attempting to register event-listener for unexpected nsSMILTimeValueSpec"
     352                 :     " type");
     353               0 :   NS_ABORT_IF_FALSE(mParams.mEventSymbol,
     354                 :     "Attempting to register event-listener but there is no event name");
     355                 : 
     356               0 :   if (!aTarget)
     357               0 :     return;
     358                 : 
     359                 :   // When script is disabled, only allow registration for whitelisted events.
     360               0 :   if (!aTarget->GetOwnerDocument()->IsScriptEnabled() &&
     361               0 :       !IsWhitelistedEvent()) {
     362               0 :     return;
     363                 :   }
     364                 : 
     365               0 :   if (!mEventListener) {
     366               0 :     mEventListener = new EventListener(this);
     367                 :   }
     368                 : 
     369               0 :   nsEventListenerManager* elm = GetEventListenerManager(aTarget);
     370               0 :   if (!elm)
     371               0 :     return;
     372                 : 
     373                 :   elm->AddEventListenerByType(mEventListener,
     374               0 :                               nsDependentAtomString(mParams.mEventSymbol),
     375                 :                               NS_EVENT_FLAG_BUBBLE |
     376                 :                               NS_PRIV_EVENT_UNTRUSTED_PERMITTED |
     377               0 :                               NS_EVENT_FLAG_SYSTEM_EVENT);
     378                 : }
     379                 : 
     380                 : void
     381               0 : nsSMILTimeValueSpec::UnregisterEventListener(Element* aTarget)
     382                 : {
     383               0 :   if (!aTarget || !mEventListener)
     384               0 :     return;
     385                 : 
     386               0 :   nsEventListenerManager* elm = GetEventListenerManager(aTarget);
     387               0 :   if (!elm)
     388               0 :     return;
     389                 : 
     390                 :   elm->RemoveEventListenerByType(mEventListener,
     391               0 :                                  nsDependentAtomString(mParams.mEventSymbol),
     392                 :                                  NS_EVENT_FLAG_BUBBLE |
     393                 :                                  NS_PRIV_EVENT_UNTRUSTED_PERMITTED |
     394               0 :                                  NS_EVENT_FLAG_SYSTEM_EVENT);
     395                 : }
     396                 : 
     397                 : nsEventListenerManager*
     398               0 : nsSMILTimeValueSpec::GetEventListenerManager(Element* aTarget)
     399                 : {
     400               0 :   NS_ABORT_IF_FALSE(aTarget, "null target; can't get EventListenerManager");
     401                 : 
     402               0 :   nsCOMPtr<nsIDOMEventTarget> target;
     403                 : 
     404               0 :   if (mParams.mType == nsSMILTimeValueSpecParams::ACCESSKEY) {
     405               0 :     nsIDocument* doc = aTarget->GetCurrentDoc();
     406               0 :     if (!doc)
     407               0 :       return nsnull;
     408               0 :     nsPIDOMWindow* win = doc->GetWindow();
     409               0 :     if (!win)
     410               0 :       return nsnull;
     411               0 :     target = do_QueryInterface(win);
     412                 :   } else {
     413               0 :     target = aTarget;
     414                 :   }
     415               0 :   if (!target)
     416               0 :     return nsnull;
     417                 : 
     418               0 :   return target->GetListenerManager(true);
     419                 : }
     420                 : 
     421                 : void
     422               0 : nsSMILTimeValueSpec::HandleEvent(nsIDOMEvent* aEvent)
     423                 : {
     424               0 :   NS_ABORT_IF_FALSE(mEventListener, "Got event without an event listener");
     425               0 :   NS_ABORT_IF_FALSE(IsEventBased(),
     426                 :                     "Got event for non-event nsSMILTimeValueSpec");
     427               0 :   NS_ABORT_IF_FALSE(aEvent, "No event supplied");
     428                 : 
     429                 :   // XXX In the long run we should get the time from the event itself which will
     430                 :   // store the time in global document time which we'll need to convert to our
     431                 :   // time container
     432               0 :   nsSMILTimeContainer* container = mOwner->GetTimeContainer();
     433               0 :   if (!container)
     434               0 :     return;
     435                 : 
     436               0 :   if (!CheckEventDetail(aEvent))
     437               0 :     return;
     438                 : 
     439               0 :   nsSMILTime currentTime = container->GetCurrentTime();
     440               0 :   nsSMILTimeValue newTime(currentTime);
     441               0 :   if (!ApplyOffset(newTime)) {
     442               0 :     NS_WARNING("New time generated from event overflows nsSMILTime, ignoring");
     443               0 :     return;
     444                 :   }
     445                 : 
     446                 :   nsRefPtr<nsSMILInstanceTime> newInstance =
     447               0 :     new nsSMILInstanceTime(newTime, nsSMILInstanceTime::SOURCE_EVENT);
     448               0 :   mOwner->AddInstanceTime(newInstance, mIsBegin);
     449                 : }
     450                 : 
     451                 : bool
     452               0 : nsSMILTimeValueSpec::CheckEventDetail(nsIDOMEvent *aEvent)
     453                 : {
     454               0 :   switch (mParams.mType)
     455                 :   {
     456                 :   case nsSMILTimeValueSpecParams::REPEAT:
     457               0 :     return CheckRepeatEventDetail(aEvent);
     458                 : 
     459                 :   case nsSMILTimeValueSpecParams::ACCESSKEY:
     460               0 :     return CheckAccessKeyEventDetail(aEvent);
     461                 : 
     462                 :   default:
     463                 :     // nothing to check
     464               0 :     return true;
     465                 :   }
     466                 : }
     467                 : 
     468                 : bool
     469               0 : nsSMILTimeValueSpec::CheckRepeatEventDetail(nsIDOMEvent *aEvent)
     470                 : {
     471               0 :   nsCOMPtr<nsIDOMTimeEvent> timeEvent = do_QueryInterface(aEvent);
     472               0 :   if (!timeEvent) {
     473               0 :     NS_WARNING("Received a repeat event that was not a DOMTimeEvent");
     474               0 :     return false;
     475                 :   }
     476                 : 
     477                 :   PRInt32 detail;
     478               0 :   timeEvent->GetDetail(&detail);
     479               0 :   return detail > 0 && (PRUint32)detail == mParams.mRepeatIterationOrAccessKey;
     480                 : }
     481                 : 
     482                 : bool
     483               0 : nsSMILTimeValueSpec::CheckAccessKeyEventDetail(nsIDOMEvent *aEvent)
     484                 : {
     485               0 :   nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aEvent);
     486               0 :   if (!keyEvent) {
     487               0 :     NS_WARNING("Received an accesskey event that was not a DOMKeyEvent");
     488               0 :     return false;
     489                 :   }
     490                 : 
     491                 :   // Ignore the key event if any modifier keys are pressed UNLESS we're matching
     492                 :   // on the charCode in which case we ignore the state of the shift and alt keys
     493                 :   // since they might be needed to generate the character in question.
     494                 :   bool isCtrl;
     495                 :   bool isMeta;
     496               0 :   keyEvent->GetCtrlKey(&isCtrl);
     497               0 :   keyEvent->GetMetaKey(&isMeta);
     498               0 :   if (isCtrl || isMeta)
     499               0 :     return false;
     500                 : 
     501                 :   PRUint32 code;
     502               0 :   keyEvent->GetCharCode(&code);
     503               0 :   if (code)
     504               0 :     return code == mParams.mRepeatIterationOrAccessKey;
     505                 : 
     506                 :   // Only match on the keyCode if it corresponds to some ASCII character that
     507                 :   // does not produce a charCode.
     508                 :   // In this case we can safely bail out if either alt or shift is pressed since
     509                 :   // they won't already be incorporated into the keyCode unlike the charCode.
     510                 :   bool isAlt;
     511                 :   bool isShift;
     512               0 :   keyEvent->GetAltKey(&isAlt);
     513               0 :   keyEvent->GetShiftKey(&isShift);
     514               0 :   if (isAlt || isShift)
     515               0 :     return false;
     516                 : 
     517               0 :   keyEvent->GetKeyCode(&code);
     518               0 :   switch (code)
     519                 :   {
     520                 :   case nsIDOMKeyEvent::DOM_VK_BACK_SPACE:
     521               0 :     return mParams.mRepeatIterationOrAccessKey == 0x08;
     522                 : 
     523                 :   case nsIDOMKeyEvent::DOM_VK_RETURN:
     524                 :   case nsIDOMKeyEvent::DOM_VK_ENTER:
     525                 :     return mParams.mRepeatIterationOrAccessKey == 0x0A ||
     526               0 :            mParams.mRepeatIterationOrAccessKey == 0x0D;
     527                 : 
     528                 :   case nsIDOMKeyEvent::DOM_VK_ESCAPE:
     529               0 :     return mParams.mRepeatIterationOrAccessKey == 0x1B;
     530                 : 
     531                 :   case nsIDOMKeyEvent::DOM_VK_DELETE:
     532               0 :     return mParams.mRepeatIterationOrAccessKey == 0x7F;
     533                 : 
     534                 :   default:
     535               0 :     return false;
     536                 :   }
     537                 : }
     538                 : 
     539                 : nsSMILTimeValue
     540               0 : nsSMILTimeValueSpec::ConvertBetweenTimeContainers(
     541                 :     const nsSMILTimeValue& aSrcTime,
     542                 :     const nsSMILTimeContainer* aSrcContainer)
     543                 : {
     544                 :   // If the source time is either indefinite or unresolved the result is going
     545                 :   // to be the same
     546               0 :   if (!aSrcTime.IsDefinite())
     547               0 :     return aSrcTime;
     548                 : 
     549                 :   // Convert from source time container to our parent time container
     550               0 :   const nsSMILTimeContainer* dstContainer = mOwner->GetTimeContainer();
     551               0 :   if (dstContainer == aSrcContainer)
     552               0 :     return aSrcTime;
     553                 : 
     554                 :   // If one of the elements is not attached to a time container then we can't do
     555                 :   // any meaningful conversion
     556               0 :   if (!aSrcContainer || !dstContainer)
     557               0 :     return nsSMILTimeValue(); // unresolved
     558                 : 
     559                 :   nsSMILTimeValue docTime =
     560               0 :     aSrcContainer->ContainerToParentTime(aSrcTime.GetMillis());
     561                 : 
     562               0 :   if (docTime.IsIndefinite())
     563                 :     // This will happen if the source container is paused and we have a future
     564                 :     // time. Just return the indefinite time.
     565               0 :     return docTime;
     566                 : 
     567               0 :   NS_ABORT_IF_FALSE(docTime.IsDefinite(),
     568                 :     "ContainerToParentTime gave us an unresolved or indefinite time");
     569                 : 
     570               0 :   return dstContainer->ParentToContainerTime(docTime.GetMillis());
     571                 : }
     572                 : 
     573                 : bool
     574               0 : nsSMILTimeValueSpec::ApplyOffset(nsSMILTimeValue& aTime) const
     575                 : {
     576                 :   // indefinite + offset = indefinite. Likewise for unresolved times.
     577               0 :   if (!aTime.IsDefinite()) {
     578               0 :     return true;
     579                 :   }
     580                 : 
     581                 :   double resultAsDouble =
     582               0 :     (double)aTime.GetMillis() + mParams.mOffset.GetMillis();
     583               0 :   if (resultAsDouble > std::numeric_limits<nsSMILTime>::max() ||
     584               0 :       resultAsDouble < std::numeric_limits<nsSMILTime>::min()) {
     585               0 :     return false;
     586                 :   }
     587               0 :   aTime.SetMillis(aTime.GetMillis() + mParams.mOffset.GetMillis());
     588               0 :   return true;
     589                 : }

Generated by: LCOV version 1.7