Bug 1440079 - Don't allow repeated access keys in chrome documents. r=smaug
authorJohann Hofmann <jhofmann@mozilla.com>
Wed, 27 Feb 2019 13:53:09 +0000
changeset 519416 9ee0c8bc5a2f2d30d3a5e8170d01d98449bc07e8
parent 519415 c923d2b7817e1ca387fd822bcaeb77b4b5abbf18
child 519417 8f33527974b47fd89c50cc691fa93b91a48d6619
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1440079
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1440079 - Don't allow repeated access keys in chrome documents. r=smaug Differential Revision: https://phabricator.services.mozilla.com/D21355
dom/events/EventStateManager.cpp
dom/events/EventStateManager.h
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -971,17 +971,18 @@ bool EventStateManager::CheckIfEventMatc
   AutoTArray<uint32_t, 10> accessCharCodes;
   aEvent->GetAccessKeyCandidates(accessCharCodes);
   return WalkESMTreeToHandleAccessKey(const_cast<WidgetKeyboardEvent*>(aEvent),
                                       aPresContext, accessCharCodes, nullptr,
                                       eAccessKeyProcessingNormal, false);
 }
 
 bool EventStateManager::LookForAccessKeyAndExecute(
-    nsTArray<uint32_t>& aAccessCharCodes, bool aIsTrustedEvent, bool aExecute) {
+    nsTArray<uint32_t>& aAccessCharCodes, bool aIsTrustedEvent, bool aIsRepeat,
+    bool aExecute) {
   int32_t count, start = -1;
   nsIContent* focusedContent = GetFocusedContent();
   if (focusedContent) {
     start = mAccessKeys.IndexOf(focusedContent);
     if (start == -1 && focusedContent->GetBindingParent())
       start = mAccessKeys.IndexOf(focusedContent->GetBindingParent());
   }
   RefPtr<Element> element;
@@ -995,16 +996,21 @@ bool EventStateManager::LookForAccessKey
       // mAccessKeys always stores Element instances.
       element = mAccessKeys[(start + count) % length]->AsElement();
       frame = element->GetPrimaryFrame();
       if (IsAccessKeyTarget(element, frame, accessKey)) {
         if (!aExecute) {
           return true;
         }
         bool shouldActivate = Prefs::KeyCausesActivation();
+
+        if (aIsRepeat && nsContentUtils::IsChromeDoc(element->OwnerDoc())) {
+          shouldActivate = false;
+        }
+
         while (shouldActivate && ++count <= length) {
           nsIContent* oc = mAccessKeys[(start + count) % length];
           nsIFrame* of = oc->GetPrimaryFrame();
           if (IsAccessKeyTarget(oc, of, accessKey)) shouldActivate = false;
         }
 
         bool focusChanged = false;
         if (shouldActivate) {
@@ -1119,17 +1125,17 @@ bool EventStateManager::WalkESMTreeToHan
   if (accessKeyType == AccessKeyType::eNone) {
     return false;
   }
   // Alt or other accesskey modifier is down, we may need to do an accesskey.
   if (mAccessKeys.Count() > 0 &&
       aEvent->ModifiersMatchWithAccessKey(accessKeyType)) {
     // Someone registered an accesskey.  Find and activate it.
     if (LookForAccessKeyAndExecute(aAccessCharCodes, aEvent->IsTrusted(),
-                                   aExecute)) {
+                                   aEvent->mIsRepeat, aExecute)) {
       return true;
     }
   }
 
   int32_t childCount;
   docShell->GetChildCount(&childCount);
   for (int32_t counter = 0; counter < childCount; counter++) {
     // Not processing the child which bubbles up the handling
--- a/dom/events/EventStateManager.h
+++ b/dom/events/EventStateManager.h
@@ -598,17 +598,18 @@ class EventStateManager : public nsSuppo
    * the instance.
    *
    * @return            true if there is a target which matches with
    *                    aAccessCharCodes and aIsTrustedEvent.  Otherwise,
    *                    false.  I.e., when this returns true and aExecute
    *                    is true, a target is executed or focused.
    */
   bool LookForAccessKeyAndExecute(nsTArray<uint32_t>& aAccessCharCodes,
-                                  bool aIsTrustedEvent, bool aExecute);
+                                  bool aIsTrustedEvent, bool aIsRepeat,
+                                  bool aExecute);
 
   //---------------------------------------------
   // DocShell Focus Traversal Methods
   //---------------------------------------------
 
   nsIContent* GetFocusedContent();
   bool IsShellVisible(nsIDocShell* aShell);