Bug 1423098 - Drop support for SMIL accessKey; r?dholbert draft
authorBrian Birtles <birtles@gmail.com>
Thu, 14 Dec 2017 09:58:32 -0600
changeset 711767 316d353eaa9f6348dfa2d53e2522128793ef922a
parent 711766 e3c90f075eeb9c2e5e68f1b473a2a00104f492d2
child 743866 2d6ac70ac27dc5801d10fb8cee7567afb86f2464
push id93135
push userbbirtles@mozilla.com
push dateThu, 14 Dec 2017 16:52:24 +0000
reviewersdholbert
bugs1423098
milestone59.0a1
Bug 1423098 - Drop support for SMIL accessKey; r?dholbert MozReview-Commit-ID: Evrl4St3QSD
dom/smil/nsSMILParserUtils.cpp
dom/smil/nsSMILTimeValueSpec.cpp
dom/smil/nsSMILTimeValueSpec.h
dom/smil/nsSMILTimeValueSpecParams.h
dom/smil/test/test_smilAccessKey.xhtml
layout/reftests/svg/smil/event/accesskey-entity-1.svg
layout/reftests/svg/smil/event/accesskey-entity-2.svg
layout/reftests/svg/smil/event/event-util.js
layout/reftests/svg/smil/event/reftest.list
--- a/dom/smil/nsSMILParserUtils.cpp
+++ b/dom/smil/nsSMILParserUtils.cpp
@@ -264,65 +264,16 @@ ParseOptionalOffset(RangedPtr<const char
     aResult->SetMillis(0L);
     return true;
   }
 
   return SkipWhitespace(aIter, aEnd) &&
          ParseOffsetValue(aIter, aEnd, aResult);
 }
 
-bool
-ParseAccessKey(const nsAString& aSpec, nsSMILTimeValueSpecParams& aResult)
-{
-  MOZ_ASSERT(StringBeginsWith(aSpec, ACCESSKEY_PREFIX_CC) ||
-             StringBeginsWith(aSpec, ACCESSKEY_PREFIX_LC),
-             "Calling ParseAccessKey on non-accesskey-type spec");
-
-  nsSMILTimeValueSpecParams result;
-  result.mType = nsSMILTimeValueSpecParams::ACCESSKEY;
-
-  MOZ_ASSERT(ACCESSKEY_PREFIX_LC.Length() == ACCESSKEY_PREFIX_CC.Length(),
-             "Case variations for accesskey prefix differ in length");
-
-  RangedPtr<const char16_t> iter(SVGContentUtils::GetStartRangedPtr(aSpec));
-  RangedPtr<const char16_t> end(SVGContentUtils::GetEndRangedPtr(aSpec));
-
-  iter += ACCESSKEY_PREFIX_LC.Length();
-
-  // Expecting at least <accesskey> + ')'
-  if (end - iter < 2)
-    return false;
-
-  uint32_t c = *iter++;
-
-  // Process 32-bit codepoints
-  if (NS_IS_HIGH_SURROGATE(c)) {
-    if (end - iter < 2) // Expecting at least low-surrogate + ')'
-      return false;
-    uint32_t lo = *iter++;
-    if (!NS_IS_LOW_SURROGATE(lo))
-      return false;
-    c = SURROGATE_TO_UCS4(c, lo);
-  // XML 1.1 says that 0xFFFE and 0xFFFF are not valid characters
-  } else if (NS_IS_LOW_SURROGATE(c) || c == 0xFFFE || c == 0xFFFF) {
-    return false;
-  }
-
-  result.mRepeatIterationOrAccessKey = c;
-
-  if (*iter++ != ')')
-    return false;
-
-  if (!ParseOptionalOffset(iter, end, &result.mOffset) || iter != end) {
-    return false;
-  }
-  aResult = result;
-  return true;
-}
-
 void
 MoveToNextToken(RangedPtr<const char16_t>& aIter,
                 const RangedPtr<const char16_t>& aEnd,
                 bool aBreakOnDot,
                 bool& aIsAnyCharEscaped)
 {
   aIsAnyCharEscaped = false;
 
@@ -448,17 +399,17 @@ ParseElementBaseTimeValueSpec(const nsAS
       if (start == tokenEnd || *start == '+' || *start == '-' ||
           !SVGContentUtils::ParseInteger(start, tokenEnd, repeatValue)) {
         return false;
       }
       if (start == tokenEnd || *start != ')') {
         return false;
       }
       result.mType = nsSMILTimeValueSpecParams::REPEAT;
-      result.mRepeatIterationOrAccessKey = repeatValue;
+      result.mRepeatIteration = repeatValue;
     // element-name.event-symbol
     } else {
       atom = ConvertTokenToAtom(token2, requiresUnescaping);
       if (atom == nullptr) {
         return false;
       }
       result.mType = nsSMILTimeValueSpecParams::EVENT;
       result.mEventSymbol = atom;
@@ -682,17 +633,17 @@ nsSMILParserUtils::ParseTimeValueSpecPar
   // wallclock type
   if (StringBeginsWith(spec, WALLCLOCK_PREFIX)) {
     return false; // Wallclock times not implemented
   }
 
   // accesskey type
   if (StringBeginsWith(spec, ACCESSKEY_PREFIX_LC) ||
       StringBeginsWith(spec, ACCESSKEY_PREFIX_CC)) {
-    return ParseAccessKey(spec, aResult);
+    return false; // accesskey is not supported
   }
 
   // event, syncbase, or repeat
   return ParseElementBaseTimeValueSpec(spec, aResult);
 }
 
 bool
 nsSMILParserUtils::ParseClockValue(const nsAString& aSpec,
--- a/dom/smil/nsSMILTimeValueSpec.cpp
+++ b/dom/smil/nsSMILTimeValueSpec.cpp
@@ -73,18 +73,16 @@ nsSMILTimeValueSpec::SetSpec(const nsASt
   if (mParams.mType == nsSMILTimeValueSpecParams::OFFSET ||
       (!mIsBegin && mParams.mType == nsSMILTimeValueSpecParams::INDEFINITE)) {
     mOwner->AddInstanceTime(new nsSMILInstanceTime(mParams.mOffset), mIsBegin);
   }
 
   // Fill in the event symbol to simplify handling later
   if (mParams.mType == nsSMILTimeValueSpecParams::REPEAT) {
     mParams.mEventSymbol = nsGkAtoms::repeatEvent;
-  } else if (mParams.mType == nsSMILTimeValueSpecParams::ACCESSKEY) {
-    mParams.mEventSymbol = nsGkAtoms::keypress;
   }
 
   ResolveReferences(aContextNode);
 
   return NS_OK;
 }
 
 void
@@ -107,32 +105,27 @@ nsSMILTimeValueSpec::ResolveReferences(n
   RefPtr<Element> oldReferencedElement = mReferencedElement.get();
 
   if (mParams.mDependentElemID) {
     mReferencedElement.ResetWithID(aContextNode,
         nsDependentAtomString(mParams.mDependentElemID));
   } else if (mParams.mType == nsSMILTimeValueSpecParams::EVENT) {
     Element* target = mOwner->GetTargetElement();
     mReferencedElement.ResetWithElement(target);
-  } else if (mParams.mType == nsSMILTimeValueSpecParams::ACCESSKEY) {
-    nsIDocument* doc = aContextNode->GetUncomposedDoc();
-    MOZ_ASSERT(doc, "We are in the document but current doc is null");
-    mReferencedElement.ResetWithElement(doc->GetRootElement());
   } else {
     MOZ_ASSERT(false, "Syncbase or repeat spec without ID");
   }
   UpdateReferencedElement(oldReferencedElement, mReferencedElement.get());
 }
 
 bool
 nsSMILTimeValueSpec::IsEventBased() const
 {
   return mParams.mType == nsSMILTimeValueSpecParams::EVENT ||
-         mParams.mType == nsSMILTimeValueSpecParams::REPEAT ||
-         mParams.mType == nsSMILTimeValueSpecParams::ACCESSKEY;
+         mParams.mType == nsSMILTimeValueSpecParams::REPEAT;
 }
 
 void
 nsSMILTimeValueSpec::HandleNewInterval(nsSMILInterval& aInterval,
                                        const nsSMILTimeContainer* aSrcContainer)
 {
   const nsSMILInstanceTime& baseInstance = mParams.mSyncBegin
     ? *aInterval.Begin() : *aInterval.End();
@@ -234,17 +227,16 @@ nsSMILTimeValueSpec::UpdateReferencedEle
       if (to) {
         to->AddDependent(*this);
       }
     }
     break;
 
   case nsSMILTimeValueSpecParams::EVENT:
   case nsSMILTimeValueSpecParams::REPEAT:
-  case nsSMILTimeValueSpecParams::ACCESSKEY:
     RegisterEventListener(aTo);
     break;
 
   default:
     // not a referencing-type
     break;
   }
 }
@@ -313,179 +305,87 @@ nsSMILTimeValueSpec::RegisterEventListen
       !IsWhitelistedEvent()) {
     return;
   }
 
   if (!mEventListener) {
     mEventListener = new EventListener(this);
   }
 
-  EventListenerManager* elm = GetEventListenerManager(aTarget);
-  if (!elm)
+  EventListenerManager* elm = aTarget->GetOrCreateListenerManager();
+  if (!elm) {
     return;
+  }
 
   elm->AddEventListenerByType(mEventListener,
                               nsDependentAtomString(mParams.mEventSymbol),
                               AllEventsAtSystemGroupBubble());
 }
 
 void
 nsSMILTimeValueSpec::UnregisterEventListener(Element* aTarget)
 {
-  if (!aTarget || !mEventListener)
+  if (!aTarget || !mEventListener) {
     return;
+  }
 
-  EventListenerManager* elm = GetEventListenerManager(aTarget);
-  if (!elm)
+  EventListenerManager* elm = aTarget->GetOrCreateListenerManager();
+  if (!elm) {
     return;
+  }
 
   elm->RemoveEventListenerByType(mEventListener,
                                  nsDependentAtomString(mParams.mEventSymbol),
                                  AllEventsAtSystemGroupBubble());
 }
 
-EventListenerManager*
-nsSMILTimeValueSpec::GetEventListenerManager(Element* aTarget)
-{
-  MOZ_ASSERT(aTarget, "null target; can't get EventListenerManager");
-
-  nsCOMPtr<EventTarget> target;
-
-  if (mParams.mType == nsSMILTimeValueSpecParams::ACCESSKEY) {
-    nsIDocument* doc = aTarget->GetUncomposedDoc();
-    if (!doc)
-      return nullptr;
-    nsPIDOMWindowOuter* win = doc->GetWindow();
-    if (!win)
-      return nullptr;
-    target = do_QueryInterface(win);
-  } else {
-    target = aTarget;
-  }
-  if (!target)
-    return nullptr;
-
-  return target->GetOrCreateListenerManager();
-}
-
 void
 nsSMILTimeValueSpec::HandleEvent(nsIDOMEvent* aEvent)
 {
   MOZ_ASSERT(mEventListener, "Got event without an event listener");
   MOZ_ASSERT(IsEventBased(),
              "Got event for non-event nsSMILTimeValueSpec");
   MOZ_ASSERT(aEvent, "No event supplied");
 
   // XXX In the long run we should get the time from the event itself which will
   // store the time in global document time which we'll need to convert to our
   // time container
   nsSMILTimeContainer* container = mOwner->GetTimeContainer();
   if (!container)
     return;
 
-  if (!CheckEventDetail(aEvent))
+  if (mParams.mType == nsSMILTimeValueSpecParams::REPEAT &&
+      !CheckRepeatEventDetail(aEvent)) {
     return;
+  }
 
   nsSMILTime currentTime = container->GetCurrentTime();
   nsSMILTimeValue newTime(currentTime);
   if (!ApplyOffset(newTime)) {
     NS_WARNING("New time generated from event overflows nsSMILTime, ignoring");
     return;
   }
 
   RefPtr<nsSMILInstanceTime> newInstance =
     new nsSMILInstanceTime(newTime, nsSMILInstanceTime::SOURCE_EVENT);
   mOwner->AddInstanceTime(newInstance, mIsBegin);
 }
 
 bool
-nsSMILTimeValueSpec::CheckEventDetail(nsIDOMEvent *aEvent)
-{
-  switch (mParams.mType)
-  {
-  case nsSMILTimeValueSpecParams::REPEAT:
-    return CheckRepeatEventDetail(aEvent);
-
-  case nsSMILTimeValueSpecParams::ACCESSKEY:
-    return CheckAccessKeyEventDetail(aEvent);
-
-  default:
-    // nothing to check
-    return true;
-  }
-}
-
-bool
 nsSMILTimeValueSpec::CheckRepeatEventDetail(nsIDOMEvent *aEvent)
 {
   nsCOMPtr<nsIDOMTimeEvent> timeEvent = do_QueryInterface(aEvent);
   if (!timeEvent) {
     NS_WARNING("Received a repeat event that was not a DOMTimeEvent");
     return false;
   }
 
   int32_t detail;
   timeEvent->GetDetail(&detail);
-  return detail > 0 && (uint32_t)detail == mParams.mRepeatIterationOrAccessKey;
-}
-
-bool
-nsSMILTimeValueSpec::CheckAccessKeyEventDetail(nsIDOMEvent *aEvent)
-{
-  nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aEvent);
-  if (!keyEvent) {
-    NS_WARNING("Received an accesskey event that was not a DOMKeyEvent");
-    return false;
-  }
-
-  // Ignore the key event if any modifier keys are pressed UNLESS we're matching
-  // on the charCode in which case we ignore the state of the shift and alt keys
-  // since they might be needed to generate the character in question.
-  bool isCtrl;
-  bool isMeta;
-  keyEvent->GetCtrlKey(&isCtrl);
-  keyEvent->GetMetaKey(&isMeta);
-  if (isCtrl || isMeta)
-    return false;
-
-  uint32_t code;
-  keyEvent->GetCharCode(&code);
-  if (code)
-    return code == mParams.mRepeatIterationOrAccessKey;
-
-  // Only match on the keyCode if it corresponds to some ASCII character that
-  // does not produce a charCode.
-  // In this case we can safely bail out if either alt or shift is pressed since
-  // they won't already be incorporated into the keyCode unlike the charCode.
-  bool isAlt;
-  bool isShift;
-  keyEvent->GetAltKey(&isAlt);
-  keyEvent->GetShiftKey(&isShift);
-  if (isAlt || isShift)
-    return false;
-
-  keyEvent->GetKeyCode(&code);
-  switch (code)
-  {
-  case nsIDOMKeyEvent::DOM_VK_BACK_SPACE:
-    return mParams.mRepeatIterationOrAccessKey == 0x08;
-
-  case nsIDOMKeyEvent::DOM_VK_RETURN:
-    return mParams.mRepeatIterationOrAccessKey == 0x0A ||
-           mParams.mRepeatIterationOrAccessKey == 0x0D;
-
-  case nsIDOMKeyEvent::DOM_VK_ESCAPE:
-    return mParams.mRepeatIterationOrAccessKey == 0x1B;
-
-  case nsIDOMKeyEvent::DOM_VK_DELETE:
-    return mParams.mRepeatIterationOrAccessKey == 0x7F;
-
-  default:
-    return false;
-  }
+  return detail > 0 && (uint32_t)detail == mParams.mRepeatIteration;
 }
 
 nsSMILTimeValue
 nsSMILTimeValueSpec::ConvertBetweenTimeContainers(
     const nsSMILTimeValue& aSrcTime,
     const nsSMILTimeContainer* aSrcContainer)
 {
   // If the source time is either indefinite or unresolved the result is going
--- a/dom/smil/nsSMILTimeValueSpec.h
+++ b/dom/smil/nsSMILTimeValueSpec.h
@@ -23,17 +23,17 @@ namespace mozilla {
 class EventListenerManager;
 } // namespace mozilla
 
 //----------------------------------------------------------------------
 // nsSMILTimeValueSpec class
 //
 // An individual element of a 'begin' or 'end' attribute, e.g. '5s', 'a.end'.
 // This class handles the parsing of such specifications and performs the
-// necessary event handling (for event, repeat, and accesskey specifications)
+// necessary event handling (for event and repeat specifications)
 // and synchronisation (for syncbase specifications).
 //
 // For an overview of how this class is related to other SMIL time classes see
 // the documentation in nsSMILTimeValue.h
 
 class nsSMILTimeValueSpec
 {
 public:
@@ -65,21 +65,18 @@ public:
 
 protected:
   void UpdateReferencedElement(Element* aFrom, Element* aTo);
   void UnregisterFromReferencedElement(Element* aElement);
   nsSMILTimedElement* GetTimedElement(Element* aElement);
   bool IsWhitelistedEvent();
   void RegisterEventListener(Element* aElement);
   void UnregisterEventListener(Element* aElement);
-  mozilla::EventListenerManager* GetEventListenerManager(Element* aElement);
   void HandleEvent(nsIDOMEvent* aEvent);
-  bool CheckEventDetail(nsIDOMEvent* aEvent);
   bool CheckRepeatEventDetail(nsIDOMEvent* aEvent);
-  bool CheckAccessKeyEventDetail(nsIDOMEvent* aEvent);
   nsSMILTimeValue ConvertBetweenTimeContainers(const nsSMILTimeValue& aSrcTime,
                                       const nsSMILTimeContainer* aSrcContainer);
   bool ApplyOffset(nsSMILTimeValue& aTime) const;
 
   nsSMILTimedElement*           mOwner;
   bool                          mIsBegin; // Indicates if *we* are a begin spec,
                                           // not to be confused with
                                           // mParams.mSyncBegin which indicates
--- a/dom/smil/nsSMILTimeValueSpecParams.h
+++ b/dom/smil/nsSMILTimeValueSpecParams.h
@@ -15,39 +15,36 @@
 //
 // A simple data type for storing the result of parsing a single begin or end
 // value (e.g. the '5s' in begin="5s; indefinite; a.begin+2s").
 
 class nsSMILTimeValueSpecParams
 {
 public:
   nsSMILTimeValueSpecParams()
-  :
-    mType(INDEFINITE),
-    mSyncBegin(false),
-    mRepeatIterationOrAccessKey(0)
+    : mType(INDEFINITE)
+    , mSyncBegin(false)
+    , mRepeatIteration(0)
   { }
 
   // The type of value this specification describes
   enum {
     OFFSET,
     SYNCBASE,
     EVENT,
     REPEAT,
-    ACCESSKEY,
     WALLCLOCK,
     INDEFINITE
   } mType;
 
   // A clock value that is added to:
   // - type OFFSET: the document begin
   // - type SYNCBASE: the timebase's begin or end time
   // - type EVENT: the event time
   // - type REPEAT: the repeat time
-  // - type ACCESSKEY: the keypress time
   // It is not used for WALLCLOCK or INDEFINITE times
   nsSMILTimeValue   mOffset;
 
   // The base element that this specification refers to.
   // For SYNCBASE types, this is the timebase
   // For EVENT and REPEAT types, this is the eventbase
   RefPtr<nsAtom> mDependentElemID;
 
@@ -55,14 +52,14 @@ public:
   // Only used for EVENT types.
   RefPtr<nsAtom> mEventSymbol;
 
   // Indicates if this specification refers to the begin or end of the dependent
   // element.
   // Only used for SYNCBASE types.
   bool              mSyncBegin;
 
-  // The repeat iteration (type=REPEAT) or access key (type=ACCESSKEY) to
-  // respond to.
-  uint32_t          mRepeatIterationOrAccessKey;
+  // The repeat iteration to respond to.
+  // Only used for mType=REPEAT.
+  uint32_t mRepeatIteration;
 };
 
 #endif // NS_SMILTIMEVALUESPECPARAMS_H_
--- a/dom/smil/test/test_smilAccessKey.xhtml
+++ b/dom/smil/test/test_smilAccessKey.xhtml
@@ -12,351 +12,68 @@
 <div id="content" style="display: none">
 <svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
   <circle cx="20" cy="20" r="15" fill="blue" id="circle"/>
 </svg>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 <![CDATA[
-/** Test for SMIL accessKey support **/
+/** Test for lack of SMIL accessKey support **/
 
-const gSvgns = "http://www.w3.org/2000/svg";
-var gSvg = document.getElementById("svg");
+const gSvgns = 'http://www.w3.org/2000/svg';
 SimpleTest.waitForExplicitFinish();
 
 function main()
 {
-  gSvg.pauseAnimations();
-
-  // Basic syntax
-  testOk('accessKey(a)', 'a');
-  testOk(' accessKey(a)  ', 'a');
-  testNotOk('accessKey (a)', 'a');
-  testNotOk('accessKey( a)', 'a');
-  testNotOk('accessKey(a )', 'a');
-  testNotOk('accessKey(a)', 'b');
-  testNotOk('accessKey()', ' ');
-
-  // Test the test framework itself
-  testOk('accessKey(a)', 97);
-
-  // Allow for either accessKey (SVG / SMIL Animation) or accesskey (SMIL2+)
-  testOk('accesskey(a)', 'a');
-
-  // Offset
-  testOk('accessKey(a)+0s', 'a');
-  testOk('accessKey(a) + 0min', 'a');
-  testOk('accessKey(a) -0h', 'a');
-  testOk('accessKey(a)+100ms', 'a', 0, 0.1);
-  testOk('accessKey(a)-0.1s', 'a', 0, -0.1);
-
-  // Id references are not allowed
-  testNotOk('svg.accessKey(a)', 'a');
-  testNotOk('window.accessKey(a)', 'a');
-
-  // Case sensitivity
-  testOk('accessKey(A)', 'A');
-  testNotOk('accessKey(a)', 'A');
-  testNotOk('accessKey(A)', 'a');
+  testBeginValueIsNotSupported('accessKey(a)');
+  testBeginValueIsNotSupported('accesskey(a)');
 
-  // Test unusual characters
-  testOk('accessKey(-)', '-');
-  testOk('accessKey(\\)', '\\');
-  testOk('accessKey( )', ' ');
-  testOk('accessKey(\x0D)', 0, KeyboardEvent.DOM_VK_RETURN);
-  testOk('accessKey(\n)', 0, KeyboardEvent.DOM_VK_RETURN); // New line
-  testOk('accessKey(\r)', 0, KeyboardEvent.DOM_VK_RETURN); // Carriage return
-  testOk('accessKey(\x08)', 0, KeyboardEvent.DOM_VK_BACK_SPACE);
-  testOk('accessKey(\x1B)', 0, KeyboardEvent.DOM_VK_ESCAPE);
-  testOk('accessKey(\x7F)', 0, KeyboardEvent.DOM_VK_DELETE);
-
-  // Check some disallowed keys
-  // -- For now we don't allow tab since the interaction with focus causes
-  //    confusing results
-  testNotOk('accessKey(\x09)', 0, 9);  // Tab
-
-  // Test setting the keyCode field
-  testNotOk('accessKey(a)', 0, 97);
-  testOk('accessKey(a)', 97, 66); // Give priority to charCode field
-  testNotOk('accessKey(a)', 98, 97); // Give priority to charCode field
-
-  // Test unicode
-  testOk("accessKey(\u20AC)", 8364); // euro-symbol
-
-  // Test an astral character just to make sure we don't crash
-  testOk("accessKey(\uD835\uDC00)", 119808); // mathematical bold capital A
-                                             // 0x1D400
-  // Test bad surrogate pairs don't confuse us either
-  testNotOk("accessKey(\uD800\uD800)", 97);
-  testNotOk("accessKey(\uD80020)", 97);
-  testNotOk("accessKey(\uD800)", 97);
-
-  // Test modifiers
-  // -- When matching on charCode ignore shift and alt
-  testNotOk('accessKey(a)', 'a', 0, 0, { ctrl: true });
-  testNotOk('accessKey(a)', 'a', 0, 0, { meta: true });
-  testOk('accessKey(a)', 'a', 0, 0, { alt: true });
-  testOk('accessKey(a)', 'a', 0, 0, { shift: true });
-  testNotOk('accessKey(a)', 'a', 0, 0, { shift: true, ctrl: true });
-  testNotOk('accessKey(a)', 'a', 0, 0, { alt: true, meta: true });
-  // -- When matching on keyCode ignore all
-  testNotOk('accessKey(\x0D)', 0, 13, 0, { ctrl: true });
-  testNotOk('accessKey(\x0D)', 0, 13, 0, { meta: true });
-  testNotOk('accessKey(\x0D)', 0, 13, 0, { alt: true });
-  testNotOk('accessKey(\x0D)', 0, 13, 0, { shift: true });
-  testNotOk('accessKey(\x0D)', 0, 13, 0, { shift: true, ctrl: true });
-
-  testOpenEnd();
-  testPreventDefault();
-  testDispatchToWindow();
-  testAdoptNode();
-  testFauxEvent();
+  is(getStartTime('accesskey(a); 1s'), 1,
+     'Start time for accesskey(a) followed by a literal time');
+  is(getStartTime('3s; accessKey(a)'), 3,
+     'Start time for accesskey(a) preceded by a literal time');
 
   SimpleTest.finish();
 }
 
-function testOk(spec, charCode, keyCode, offset, modifiers)
-{
-  if (typeof offset == 'undefined') offset = 0;
-  var msg = "No interval created for '" + spec +
-    "' with input [charCode: " + charCode + "; keyCode: " + keyCode + "]" +
-    getModifiersDescr(modifiers);
-  ok(test(spec, charCode, keyCode, offset, modifiers), msg);
-}
-
-function testNotOk(spec, charCode, keyCode, offset, modifiers)
-{
-  if (typeof offset == 'undefined') offset = 0;
-  var msg = "Interval unexpectedly created for '" + spec +
-    "' with input [charCode: " + charCode + "; keyCode: " + keyCode + "]" +
-    getModifiersDescr(modifiers);
-  ok(!test(spec, charCode, keyCode, offset, modifiers), msg);
-}
-
-function getModifiersDescr(modifiers)
-{
-  if (typeof modifiers != 'object')
-    return '';
-  var str = ' modifiers set:';
-  for (var key in modifiers) {
-    if (modifiers[key]) str += ' ' + key;
-  }
-  return str;
-}
-
-function test(spec, charCode, keyCode, offset, modifiers)
-{
-  gSvg.setCurrentTime(1);
-  ok(gSvg.animationsPaused(), "Expected animations to be paused");
-
-  var anim = createAnim(spec);
-  var evt = createEvent(charCode, keyCode, modifiers);
-
-  document.getElementById('circle').dispatchEvent(evt);
-
-  var gotStartTimeOk = true;
-  try {
-    var start = anim.getStartTime();
-    if (offset) {
-      var expected = gSvg.getCurrentTime() + offset;
-      ok(Math.abs(expected - start) <= 0.00001,
-        "Unexpected start time for animation with begin: " + spec +
-          " got " + start + ", expected " + expected);
-    } else {
-      is(start, gSvg.getCurrentTime() + offset,
-         "Unexpected start time for animation with begin: " + spec);
-    }
-  } catch(e) {
-    is(e.name, "InvalidStateError",
-       "Unexpected exception: " + e.name);
-    is(e.code, DOMException.INVALID_STATE_ERR,
-       "Unexpected exception code: " + e.code);
-    gotStartTimeOk = false;
-  }
-
-  anim.remove();
-
-  return gotStartTimeOk;
-}
-
-function createAnim(beginSpec)
-{
-  var anim = document.createElementNS(gSvgns, 'animate');
+function createAnim(beginSpec) {
+  const anim = document.createElementNS(gSvgns, 'animate');
   anim.setAttribute('attributeName', 'cx');
   anim.setAttribute('values', '0; 100');
   anim.setAttribute('dur', '10s');
   anim.setAttribute('begin', beginSpec);
   return document.getElementById('circle').appendChild(anim);
 }
 
-function createEvent(charCode, keyCode, modifiers)
-{
-  if (typeof charCode == 'string') {
-    is(charCode.length, 1,
-       "If charCode is a string it should be 1 character long");
-    charCode = charCode.charCodeAt(0);
-  } else if (typeof charCode == 'undefined') {
-    charCode = 0;
-  }
-  args = { ctrl: false, alt: false, shift: false, meta: false };
-  if (typeof modifiers == 'object') {
-    for (var key in modifiers)
-      args[key] = modifiers[key];
-  }
-  if (typeof keyCode == 'undefined') keyCode = 0;
-  var evt = document.createEvent("KeyboardEvent");
-  evt.initKeyEvent("keypress", true, true, window,
-                   args['ctrl'],
-                   args['alt'],
-                   args['shift'],
-                   args['meta'],
-                   keyCode,
-                   charCode);
-  return evt;
-}
-
-function testOpenEnd()
-{
-  // Test that an end specification with an accesskey value is treated as open
-  // ended
-  gSvg.setCurrentTime(0);
-  ok(gSvg.animationsPaused(), "Expected animations to be paused");
-
-  var anim = createAnim('0s; 2s');
-  anim.setAttribute('end', '1s; accessKey(a)');
-
-  gSvg.setCurrentTime(2);
+function testBeginValueIsNotSupported(beginSpec) {
+  const anim = createAnim(beginSpec);
 
   try {
-    is(anim.getStartTime(), 2,
-       "Unexpected start time for second interval of open-ended animation");
+    anim.getStartTime();
+    ok(false,
+       `Should have failed to get start time for begin value: ${beginSpec}`);
   } catch(e) {
-    is(e.name, "InvalidStateError",
-       "Unexpected exception:" + e.name);
+    is(e.name, 'InvalidStateError', `Unexpected exception: ${e.name}`);
     is(e.code, DOMException.INVALID_STATE_ERR,
-       "Unexpected exception code:" + e.code);
-    ok(false, "Failed to recognise accessKey as qualifying for creating an " +
-              "open-ended interval");
+       `Unexpected exception code: ${e.code}`);
   }
 
   anim.remove();
 }
 
-function testPreventDefault()
-{
-  // SVG/SMIL don't specify what should happen if preventDefault is called on
-  // the keypress event. For now, for consistency with event timing we ignore
-  // it.
-  gSvg.setCurrentTime(1);
-  ok(gSvg.animationsPaused(), "Expected animations to be paused");
-
-  var anim = createAnim('accessKey(a)');
-  var evt = createEvent('a');
-
-  var circle = document.getElementById('circle');
-  var func = function(evt) { evt.preventDefault(); }
-  circle.addEventListener('keypress', func);
-  circle.dispatchEvent(evt);
-
+function getStartTime(beginSpec) {
+  const anim = createAnim(beginSpec);
+  let startTime;
   try {
-    var start = anim.getStartTime();
-  } catch(e) {
-    ok(false, "preventDefault() cancelled accessKey handling");
-  }
+    startTime = anim.getStartTime();
+  } catch (e) { }
+  anim.remove();
 
-  circle.removeEventListener('keypress', func);
-  anim.remove();
-}
-
-function testDispatchToWindow()
-{
-  gSvg.setCurrentTime(1);
-  ok(gSvg.animationsPaused(), "Expected animations to be paused");
-
-  var anim = createAnim('accessKey(a)');
-  var evt = createEvent('a');
-
-  window.dispatchEvent(evt);
-
-  try {
-    var start = anim.getStartTime();
-  } catch(e) {
-    ok(false, "Key event dispatched to the window failed to trigger " +
-              "accesskey handling");
-  }
-
-  anim.remove();
+  return startTime;
 }
 
-function testAdoptNode()
-{
-  gSvg.setCurrentTime(1);
-  ok(gSvg.animationsPaused(), "Expected animations to be paused");
-
-  // Create a new document with an animation element
-  var newdoc = document.implementation.createDocument(gSvgns, 'svg', null);
-  var anim = newdoc.createElementNS(gSvgns, 'animate');
-  anim.setAttribute('attributeName', 'cx');
-  anim.setAttribute('values', '0; 100');
-  anim.setAttribute('dur', '10s');
-  anim.setAttribute('begin', 'accesskey(a)');
-  newdoc.documentElement.appendChild(anim);
-
-  // Adopt
-  ok(anim.ownerDocument !== document,
-     "Expected newly created animation to belong to a different doc");
-  document.adoptNode(anim);
-  document.getElementById('circle').appendChild(anim);
-  ok(anim.ownerDocument === document,
-     "Expected newly created animation to belong to the same doc");
-
-  var evt = createEvent('a');
-
-  // Now fire an event at the original window and check nothing happens
-  newdoc.dispatchEvent(evt);
-  try {
-    var start = anim.getStartTime();
-    ok(false, "Adopted node still receiving accesskey events from old doc");
-  } catch(e) {
-    // Ok
-  }
-
-  // And then fire at our window
-  document.dispatchEvent(evt);
-  try {
-    var start = anim.getStartTime();
-  } catch(e) {
-    ok(false, "Adopted node failed to catch accesskey event");
-  }
-
-  anim.remove();
-}
-
-function testFauxEvent()
-{
-  // Test a non-KeyEvent labelled as a key event
-  gSvg.setCurrentTime(0);
-  ok(gSvg.animationsPaused(), "Expected animations to be paused");
-
-  var anim = createAnim('accessKey(a)');
-  var evt = document.createEvent("SVGEvents");
-  evt.initEvent("keypress", true, true);
-  document.getElementById('circle').dispatchEvent(evt);
-
-  // We're really just testing that the above didn't crash us, but while we're
-  // at it, just do a sanity check that we didn't also create an interval
-  try {
-    var start = anim.getStartTime();
-    ok(false, "Faux event generated interval");
-  } catch(e) {
-    // All is well
-  }
-
-  anim.remove();
-}
-
-window.addEventListener("load", main);
+window.addEventListener('load', main);
 ]]>
 </script>
 </pre>
 </body>
 </html>
deleted file mode 100644
--- a/layout/reftests/svg/smil/event/accesskey-entity-1.svg
+++ /dev/null
@@ -1,17 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg"
-     xmlns:xlink="http://www.w3.org/1999/xlink"
-     class="reftest-wait"
-     onload="
-        document.documentElement.pauseAnimations();
-        document.documentElement.setCurrentTime(0);
-        keypress(0x20);
-        delayedSnapshot(2)">
-  <script xlink:href="event-util.js" type="text/javascript"/>
-  <circle id="circle" r="10"/>
-  <rect width="100" height="100" fill="red">
-    <set attributeName="fill" attributeType="CSS"
-      to="green" begin="accesskey(&#x20;)" dur="4s"/>
-    <set attributeName="width" attributeType="XML"
-      to="200" begin="accesskey(&#x21;)" dur="4s"/>
-  </rect>
-</svg>
deleted file mode 100644
--- a/layout/reftests/svg/smil/event/accesskey-entity-2.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg"
-     xmlns:xlink="http://www.w3.org/1999/xlink"
-     class="reftest-wait"
-     onload="
-        document.documentElement.pauseAnimations();
-        document.documentElement.setCurrentTime(0);
-        keypress(0x0D);
-        delayedSnapshot(2)">
-  <script xlink:href="event-util.js" type="text/javascript"/>
-  <circle id="circle" r="10"/>
-  <rect width="100" height="100" fill="red">
-    <set attributeName="fill" attributeType="CSS"
-      to="green" begin="accesskey(&#x0D;)" dur="4s"/>
-  </rect>
-</svg>
--- a/layout/reftests/svg/smil/event/event-util.js
+++ b/layout/reftests/svg/smil/event/event-util.js
@@ -17,21 +17,8 @@ function finish(seekTimeInSeconds)
 function click(targetId)
 {
   var evt = document.createEvent("MouseEvents");
   evt.initMouseEvent("click", true, true, window,
     0, 0, 0, 0, 0, false, false, false, false, 0, null);
   var target = document.getElementById(targetId);
   target.dispatchEvent(evt);
 }
-
-function keypress(charCode)
-{
-  var evt = document.createEvent("KeyboardEvent");
-  evt.initKeyEvent("keypress", true, true, window,
-                   false, // ctrlKeyArg
-                   false, // altKeyArg
-                   false, // shiftKeyArg
-                   false, // metaKeyArg
-                   0,     // keyCode
-                   charCode);
-  document.documentElement.dispatchEvent(evt);
-}
--- a/layout/reftests/svg/smil/event/reftest.list
+++ b/layout/reftests/svg/smil/event/reftest.list
@@ -23,10 +23,8 @@ random-if(Android) == event-begin-timeev
 == event-target-xlink-change-1.svg green-box-ref.svg
 == event-target-xlink-change-2.svg green-box-ref.svg
 == event-target-xlink-change-3.svg green-box-ref.svg
 == event-target-xlink-change-4.svg green-box-ref.svg
 == event-target-surgery-1.svg green-box-ref.svg
 == event-target-surgery-2.svg green-box-ref.svg
 == event-target-surgery-3.svg green-box-ref.svg
 == event-target-non-svg-1.xhtml green-box-ref.xhtml
-== accesskey-entity-1.svg green-box-ref.svg
-== accesskey-entity-2.svg green-box-ref.svg