Bug 1037990 - AccessLabelKey is now accessible event if the element is detached. r=bzbarsky
authorAkshendra Pratap Singh <akshendra521994@gmail.com>
Wed, 15 Oct 2014 07:42:00 +0200
changeset 210684 2f361ad6e908d79cd8543e6b008445baea6c0b5f
parent 210683 c044fae78ad8d0c83d7bbe5786c466474f8eeb1c
child 210685 5ab9da505d34f640fbe97925859cc01506a619fb
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbzbarsky
bugs1037990
milestone36.0a1
Bug 1037990 - AccessLabelKey is now accessible event if the element is detached. r=bzbarsky
content/html/content/src/nsGenericHTMLElement.cpp
dom/events/EventStateManager.cpp
dom/events/EventStateManager.h
dom/events/test/mochitest.ini
dom/events/test/test_bug1037990.html
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -286,26 +286,21 @@ static const nsAttrValue::EnumTable kDir
   { "rtl", eDir_RTL },
   { "auto", eDir_Auto },
   { 0 }
 };
 
 void
 nsGenericHTMLElement::GetAccessKeyLabel(nsString& aLabel)
 {
-  //XXXsmaug We shouldn't need PresContext for this.
-  nsPresContext *presContext = GetPresContext(eForComposedDoc);
-
-  if (presContext) {
-    nsAutoString suffix;
-    GetAccessKey(suffix);
-    if (!suffix.IsEmpty() && 
-        presContext->EventStateManager()->GetAccessKeyLabelPrefix(aLabel)) {
-      aLabel.Append(suffix);
-    }
+  nsAutoString suffix;
+  GetAccessKey(suffix);
+  if (!suffix.IsEmpty()) {
+    EventStateManager::GetAccessKeyLabelPrefix(this, aLabel);
+    aLabel.Append(suffix);
   }
 }
 
 static bool IS_TABLE_CELL(nsIAtom* frameType) {
   return nsGkAtoms::tableCellFrame == frameType ||
     nsGkAtoms::bcTableCellFrame == frameType;
 }
 
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -939,26 +939,31 @@ EventStateManager::ExecuteAccessKey(nsTA
         }
         return true;
       }
     }
   }
   return false;
 }
 
-bool
-EventStateManager::GetAccessKeyLabelPrefix(nsAString& aPrefix)
+// static
+void
+EventStateManager::GetAccessKeyLabelPrefix(Element* aElement, nsAString& aPrefix)
 {
   aPrefix.Truncate();
   nsAutoString separator, modifierText;
   nsContentUtils::GetModifierSeparatorText(separator);
 
-  nsCOMPtr<nsISupports> container = mPresContext->GetContainerWeak();
+  nsCOMPtr<nsISupports> container = aElement->OwnerDoc()->GetDocShell();
   int32_t modifierMask = GetAccessModifierMaskFor(container);
 
+  if (modifierMask == -1) {
+    return;
+  }
+
   if (modifierMask & NS_MODIFIER_CONTROL) {
     nsContentUtils::GetControlText(modifierText);
     aPrefix.Append(modifierText + separator);
   }
   if (modifierMask & NS_MODIFIER_META) {
     nsContentUtils::GetMetaText(modifierText);
     aPrefix.Append(modifierText + separator);
   }
@@ -969,17 +974,16 @@ EventStateManager::GetAccessKeyLabelPref
   if (modifierMask & NS_MODIFIER_ALT) {
     nsContentUtils::GetAltText(modifierText);
     aPrefix.Append(modifierText + separator);
   }
   if (modifierMask & NS_MODIFIER_SHIFT) {
     nsContentUtils::GetShiftText(modifierText);
     aPrefix.Append(modifierText + separator);
   }
-  return !aPrefix.IsEmpty();
 }
 
 void
 EventStateManager::HandleAccessKey(nsPresContext* aPresContext,
                                    WidgetKeyboardEvent* aEvent,
                                    nsEventStatus* aStatus,
                                    nsIDocShellTreeItem* aBubbledFrom,
                                    ProcessingAccessKeyState aAccessKeyState,
--- a/dom/events/EventStateManager.h
+++ b/dom/events/EventStateManager.h
@@ -35,16 +35,17 @@ namespace mozilla {
 class EnterLeaveDispatcher;
 class EventStates;
 class IMEContentObserver;
 class ScrollbarsForWheel;
 class WheelTransaction;
 
 namespace dom {
 class DataTransfer;
+class Element;
 class TabParent;
 } // namespace dom
 
 class OverOutElementsWrapper MOZ_FINAL : public nsISupports
 {
   ~OverOutElementsWrapper();
 
 public:
@@ -164,17 +165,17 @@ public:
   /**
    * Get accesskey registered on the given element or 0 if there is none.
    *
    * @param  aContent  the given element (must not be null)
    * @return           registered accesskey
    */
   uint32_t GetRegisteredAccessKey(nsIContent* aContent);
 
-  bool GetAccessKeyLabelPrefix(nsAString& aPrefix);
+  static void GetAccessKeyLabelPrefix(dom::Element* aElement, nsAString& aPrefix);
 
   nsresult SetCursor(int32_t aCursor, imgIContainer* aContainer,
                      bool aHaveHotspot, float aHotspotX, float aHotspotY,
                      nsIWidget* aWidget, bool aLockCursor); 
 
   static void StartHandlingUserInput()
   {
     ++sUserInputEventDepth;
--- a/dom/events/test/mochitest.ini
+++ b/dom/events/test/mochitest.ini
@@ -17,16 +17,17 @@ support-files =
 [test_addEventListenerExtraArg.html]
 [test_all_synthetic_events.html]
 [test_bug226361.xhtml]
 skip-if = buildapp == 'b2g'
 [test_bug238987.html]
 skip-if = buildapp == 'b2g'
 [test_bug288392.html]
 [test_bug299673-1.html]
+[test_bug1037990.html]
 [test_bug299673-2.html]
 [test_bug322588.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') || e10s #Bug 931116, b2g desktop specific, initial triage
 [test_bug328885.html]
 [test_bug336682.js]
 [test_bug336682_1.html]
 [test_bug367781.html]
 [test_bug368835.html]
new file mode 100644
--- /dev/null
+++ b/dom/events/test/test_bug1037990.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1037990
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 1037990</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1037990">Mozilla Bug 1037990</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+<script type="application/javascript">
+
+  /** Test for Bug 1037990 **/
+
+  var pre, node, detachedAccess, attachedAcess;
+
+  node = document.createElement('a');
+  node.href = 'http://example.org';
+  node.accessKey = 'e';
+  detachedAccess = node.accessKeyLabel;
+  info('[window.document] detached: ' + detachedAccess);
+  document.body.appendChild(node);
+  attachedAcess = node.accessKeyLabel;
+  info('[window.document] attached: ' + attachedAcess);
+  is(detachedAccess, attachedAcess, "Both values are same for the window.document");
+
+  var parser=new DOMParser();
+  var xmlDoc=parser.parseFromString("<root></root>","text/xml");
+  var nn = xmlDoc.createElementNS('http://www.w3.org/1999/xhtml','a');
+  nn.setAttribute('accesskey','t')
+  detachedAccess = nn.accessKeyLabel;
+  info('[xmlDoc] detached: ' + detachedAccess);
+  var root = xmlDoc.getElementsByTagName('root')[0];
+  root.appendChild(nn);
+  attachedAcess = nn.accessKeyLabel;
+  info('[xmlDoc] attached: ' + attachedAcess);
+  is(detachedAccess, attachedAcess, "Both values are same for the xmlDoc");
+
+  var myDoc = new Document();
+  var newnode = myDoc.createElementNS('http://www.w3.org/1999/xhtml','a');
+  newnode.href = 'http://example.org';
+  newnode.accessKey = 'f';
+  detachedAccess = newnode.accessKeyLabel;
+  info('[new document] detached: ' + detachedAccess);
+  myDoc.appendChild(newnode);
+  attachedAcess = newnode.accessKeyLabel;
+  info('[new document] attached: ' + attachedAcess);
+  is(detachedAccess, attachedAcess, "Both values are same for the new Document()");
+
+</script>
+</body>
+</html>