Bug 1037990 - AccessLabelKey is now accessible event if the element is detached. r=bzbarsky
--- 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>