Diff
Modified: trunk/LayoutTests/ChangeLog (181483 => 181484)
--- trunk/LayoutTests/ChangeLog 2015-03-13 18:58:32 UTC (rev 181483)
+++ trunk/LayoutTests/ChangeLog 2015-03-13 19:24:01 UTC (rev 181484)
@@ -1,3 +1,19 @@
+2015-03-13 Doug Russell <[email protected]>
+
+ AX: Provide API for assistive tech to ignore DOM key event handlers
+ https://bugs.webkit.org/show_bug.cgi?id=142059
+
+ Reviewed by Beth Dakin.
+
+ Assistive technology applications on the desktop are heavily dependent on keyboard navigation being reliable. This is greatly hindered by sites that handle key events without updating keyboard selection and then consume the event. It is important for assistive technology apps to allow users to decide to ignore these handlers that are incorrect for their purposes.
+
+ This can be fixed by exposing, via a new accessibility attribute, a way to decide, for a given WebCore::Frame, to pre-empt DOM dispatch and instead let accessibility caret browsing take place.
+
+ * accessibility/parent-delete-expected.txt:
+ * platform/mac/accessibility/document-attributes-expected.txt:
+ * platform/mac/accessibility/prevent-keyboard-event-dispatch-expected.txt: Added.
+ * platform/mac/accessibility/prevent-keyboard-event-dispatch.html: Added.
+
2015-03-13 Chris Dumez <[email protected]>
XMLHttpRequests should not prevent a page from entering PageCache
Modified: trunk/LayoutTests/accessibility/parent-delete-expected.txt (181483 => 181484)
--- trunk/LayoutTests/accessibility/parent-delete-expected.txt 2015-03-13 18:58:32 UTC (rev 181483)
+++ trunk/LayoutTests/accessibility/parent-delete-expected.txt 2015-03-13 19:24:01 UTC (rev 181484)
@@ -28,5 +28,6 @@
AXLoadingProgress: 1
AXURL: LayoutTests/accessibility/parent-delete.html
AXCaretBrowsingEnabled: 0
+AXPreventKeyboardDOMEventDispatch: 0
AXElementBusy: 0
Modified: trunk/LayoutTests/platform/mac/accessibility/document-attributes-expected.txt (181483 => 181484)
--- trunk/LayoutTests/platform/mac/accessibility/document-attributes-expected.txt 2015-03-13 18:58:32 UTC (rev 181483)
+++ trunk/LayoutTests/platform/mac/accessibility/document-attributes-expected.txt 2015-03-13 19:24:01 UTC (rev 181484)
@@ -27,6 +27,7 @@
AXLoadingProgress: 1
AXURL: LayoutTests/platform/mac/accessibility/document-attributes.html
AXCaretBrowsingEnabled: 0
+AXPreventKeyboardDOMEventDispatch: 0
AXElementBusy: 0
Added: trunk/LayoutTests/platform/mac/accessibility/prevent-keyboard-event-dispatch-expected.txt (0 => 181484)
--- trunk/LayoutTests/platform/mac/accessibility/prevent-keyboard-event-dispatch-expected.txt (rev 0)
+++ trunk/LayoutTests/platform/mac/accessibility/prevent-keyboard-event-dispatch-expected.txt 2015-03-13 19:24:01 UTC (rev 181484)
@@ -0,0 +1,29 @@
+1
+
+2
+
+2
+
+This tests ignoring _javascript_ key handlers that consume key events.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS webArea.role is 'AXRole: AXWebArea'
+PASS caretBrowsingEnabled(webArea) is false
+PASS accessibilityController.enhancedAccessibilityEnabled is false
+PASS preventKeyboardDOMEventDispatch(webArea) is false
+PASS elementAtStartMarkerOfSelectedTextMarkerRange(webArea).stringValue is 'AXValue: 1'
+PASS elementAtStartMarkerOfSelectedTextMarkerRange(webArea).stringValue is 'AXValue: 1'
+PASS elementAtStartMarkerOfSelectedTextMarkerRange(webArea).stringValue is 'AXValue: 1'
+PASS keycount() is '2'
+PASS accessibilityController.enhancedAccessibilityEnabled is true
+PASS preventKeyboardDOMEventDispatch(webArea) is true
+PASS elementAtStartMarkerOfSelectedTextMarkerRange(webArea).stringValue is 'AXValue: 1'
+PASS elementAtStartMarkerOfSelectedTextMarkerRange(webArea).stringValue is 'AXValue: 1'
+PASS elementAtStartMarkerOfSelectedTextMarkerRange(webArea).stringValue is 'AXValue: 2'
+PASS keycount() is '2'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/platform/mac/accessibility/prevent-keyboard-event-dispatch.html (0 => 181484)
--- trunk/LayoutTests/platform/mac/accessibility/prevent-keyboard-event-dispatch.html (rev 0)
+++ trunk/LayoutTests/platform/mac/accessibility/prevent-keyboard-event-dispatch.html 2015-03-13 19:24:01 UTC (rev 181484)
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src=""
+ <script src=""
+</head>
+<body id="body" _onkeydown_="return keydown();">
+ <script>
+ function preventKeyboardDOMEventDispatch(webArea) {
+ return webArea.boolAttributeValue("AXPreventKeyboardDOMEventDispatch");
+ }
+ function setPreventKeyboardDOMEventDispatch(webArea, value) {
+ webArea.setBoolAttributeValue("AXPreventKeyboardDOMEventDispatch", value);
+ }
+ function keydown(event) {
+ var element = document.getElementById("keydowncount");
+ element.innerHTML = parseInt(element.innerHTML) + 1;
+ return false;
+ }
+ function keycount() {
+ return document.getElementById("keydowncount").innerHTML;
+ }
+ </script>
+ <div>
+ <p>1</p>
+ <p>2</p>
+ <p id="keydowncount">0<p>
+ </div>
+ <div id="console"></div>
+ <script>
+ description("This tests ignoring _javascript_ key handlers that consume key events.");
+ if (window.testRunner) {
+
+ testRunner.dumpAsText();
+
+ if (window.accessibilityController && window.eventSender) {
+
+ var webArea = clearSelectionAndFocusOnWebArea();
+ accessibilityController.enableEnhancedAccessibility(false);
+ shouldBe("accessibilityController.enhancedAccessibilityEnabled", "false");
+ setPreventKeyboardDOMEventDispatch(webArea, false);
+ shouldBe("preventKeyboardDOMEventDispatch(webArea)", "false");
+
+ // Arrowing before enabling AX and ignore dom handlers won't move the caret
+ shouldBe("elementAtStartMarkerOfSelectedTextMarkerRange(webArea).stringValue", "'AXValue: 1'");
+ eventSender.keyDown("rightArrow");
+ shouldBe("elementAtStartMarkerOfSelectedTextMarkerRange(webArea).stringValue", "'AXValue: 1'");
+ eventSender.keyDown("rightArrow");
+ shouldBe("elementAtStartMarkerOfSelectedTextMarkerRange(webArea).stringValue", "'AXValue: 1'");
+
+ // Validate that the handler received 2 keys events
+ shouldBe("keycount()", "'2'");
+
+ // Enable enhanced accessibility (necessary for accessibility specific selection handling).
+ accessibilityController.enableEnhancedAccessibility(true);
+ shouldBe("accessibilityController.enhancedAccessibilityEnabled", "true");
+
+ // Enable IgnoreDOMKeyEventHandlers so that the _javascript_ handler will be skipped
+ setPreventKeyboardDOMEventDispatch(webArea, true);
+ shouldBe("preventKeyboardDOMEventDispatch(webArea)", "true");
+
+ shouldBe("elementAtStartMarkerOfSelectedTextMarkerRange(webArea).stringValue", "'AXValue: 1'");
+ eventSender.keyDown("rightArrow");
+ shouldBe("elementAtStartMarkerOfSelectedTextMarkerRange(webArea).stringValue", "'AXValue: 1'");
+ eventSender.keyDown("rightArrow");
+ shouldBe("elementAtStartMarkerOfSelectedTextMarkerRange(webArea).stringValue", "'AXValue: 2'");
+
+ // Validate that the handler didn't receive any more key events
+ shouldBe("keycount()", "'2'");
+
+ setPreventKeyboardDOMEventDispatch(webArea, false);
+ }
+ }
+ </script>
+ <script src=""
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (181483 => 181484)
--- trunk/Source/WebCore/ChangeLog 2015-03-13 18:58:32 UTC (rev 181483)
+++ trunk/Source/WebCore/ChangeLog 2015-03-13 19:24:01 UTC (rev 181484)
@@ -1,3 +1,34 @@
+2015-03-13 Doug Russell <[email protected]>
+
+ AX: Provide API for assistive tech to ignore DOM key event handlers
+ https://bugs.webkit.org/show_bug.cgi?id=142059
+
+ Reviewed by Beth Dakin.
+
+ Assistive technology applications on the desktop are heavily dependent on keyboard navigation being reliable. This is greatly hindered by sites that handle key events without updating keyboard selection and then consume the event. It is important for assistive technology apps to allow users to decide to ignore these handlers that are incorrect for their purposes.
+
+ This can be fixed by exposing, via a new accessibility attribute, a way to decide, for a given WebCore::Frame, to pre-empt DOM dispatch and instead let accessibility caret browsing take place.
+
+ Test: platform/mac/accessibility/prevent-keyboard-event-dispatch.html
+
+ * accessibility/AccessibilityObject.cpp:
+ (WebCore::AccessibilityObject::preventKeyboardDOMEventDispatch):
+ (WebCore::AccessibilityObject::setPreventKeyboardDOMEventDispatch):
+ * accessibility/AccessibilityObject.h:
+ * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+ (-[WebAccessibilityObjectWrapper accessibilityAttributeNames]):
+ (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
+ (-[WebAccessibilityObjectWrapper accessibilityIsAttributeSettable:]):
+ (-[WebAccessibilityObjectWrapper _accessibilitySetValue:forAttribute:]):
+ * dom/Element.cpp:
+ (WebCore::Element::dispatchKeyEvent):
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::keyEvent):
+ (WebCore::handleKeyboardSelectionMovement):
+ (WebCore::EventHandler::handleKeyboardSelectionMovementForAccessibility):
+ * page/EventHandler.h:
+ * page/Settings.in:
+
2015-03-09 Conrad Shultz <[email protected]>
Allow clients to selectively disable plug-ins
Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.cpp (181483 => 181484)
--- trunk/Source/WebCore/accessibility/AccessibilityObject.cpp 2015-03-13 18:58:32 UTC (rev 181483)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.cpp 2015-03-13 19:24:01 UTC (rev 181484)
@@ -2605,4 +2605,20 @@
}
}
+#if PLATFORM(COCOA)
+bool AccessibilityObject::preventKeyboardDOMEventDispatch() const
+{
+ Frame* frame = this->frame();
+ return frame && frame->settings().preventKeyboardDOMEventDispatch();
+}
+
+void AccessibilityObject::setPreventKeyboardDOMEventDispatch(bool on)
+{
+ Frame* frame = this->frame();
+ if (!frame)
+ return;
+ frame->settings().setPreventKeyboardDOMEventDispatch(on);
+}
+#endif
+
} // namespace WebCore
Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.h (181483 => 181484)
--- trunk/Source/WebCore/accessibility/AccessibilityObject.h 2015-03-13 18:58:32 UTC (rev 181483)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.h 2015-03-13 19:24:01 UTC (rev 181484)
@@ -978,6 +978,11 @@
// other operations update type operations
void updateBackingStore();
+#if PLATFORM(COCOA)
+ bool preventKeyboardDOMEventDispatch() const;
+ void setPreventKeyboardDOMEventDispatch(bool);
+#endif
+
#if PLATFORM(COCOA) && !PLATFORM(IOS)
bool caretBrowsingEnabled() const;
void setCaretBrowsingEnabled(bool);
Modified: trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm (181483 => 181484)
--- trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm 2015-03-13 18:58:32 UTC (rev 181483)
+++ trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm 2015-03-13 19:24:01 UTC (rev 181484)
@@ -464,6 +464,10 @@
#define NSAccessibilityMathPrescriptsAttribute @"AXMathPrescripts"
#define NSAccessibilityMathPostscriptsAttribute @"AXMathPostscripts"
+#ifndef NSAccessibilityPreventKeyboardDOMEventDispatchAttribute
+#define NSAccessibilityPreventKeyboardDOMEventDispatchAttribute @"AXPreventKeyboardDOMEventDispatch"
+#endif
+
#ifndef NSAccessibilityCaretBrowsingEnabledAttribute
#define NSAccessibilityCaretBrowsingEnabledAttribute @"AXCaretBrowsingEnabled"
#endif
@@ -1359,6 +1363,7 @@
[tempArray addObject:NSAccessibilityLoadingProgressAttribute];
[tempArray addObject:NSAccessibilityURLAttribute];
[tempArray addObject:NSAccessibilityCaretBrowsingEnabledAttribute];
+ [tempArray addObject:NSAccessibilityPreventKeyboardDOMEventDispatchAttribute];
webAreaAttrs = [[NSArray alloc] initWithArray:tempArray];
[tempArray release];
}
@@ -2958,6 +2963,9 @@
if ([attributeName isEqualToString:@"AXDRTElementIdAttribute"])
return m_object->getAttribute(idAttr);
+ if (m_object->isWebArea() && [attributeName isEqualToString:NSAccessibilityPreventKeyboardDOMEventDispatchAttribute])
+ return [NSNumber numberWithBool:m_object->preventKeyboardDOMEventDispatch()];
+
if (m_object->isWebArea() && [attributeName isEqualToString:NSAccessibilityCaretBrowsingEnabledAttribute])
return [NSNumber numberWithBool:m_object->caretBrowsingEnabled()];
@@ -3033,6 +3041,9 @@
if ([attributeName isEqualToString:NSAccessibilityGrabbedAttribute])
return YES;
+ if (m_object->isWebArea() && [attributeName isEqualToString:NSAccessibilityPreventKeyboardDOMEventDispatchAttribute])
+ return YES;
+
if (m_object->isWebArea() && [attributeName isEqualToString:NSAccessibilityCaretBrowsingEnabledAttribute])
return YES;
@@ -3352,6 +3363,8 @@
m_object->setSelectedRows(selectedRows);
} else if ([attributeName isEqualToString:NSAccessibilityGrabbedAttribute])
m_object->setARIAGrabbed([number boolValue]);
+ else if (m_object->isWebArea() && [attributeName isEqualToString:NSAccessibilityPreventKeyboardDOMEventDispatchAttribute])
+ m_object->setPreventKeyboardDOMEventDispatch([number boolValue]);
else if (m_object->isWebArea() && [attributeName isEqualToString:NSAccessibilityCaretBrowsingEnabledAttribute])
m_object->setCaretBrowsingEnabled([number boolValue]);
}
Modified: trunk/Source/WebCore/dom/Element.cpp (181483 => 181484)
--- trunk/Source/WebCore/dom/Element.cpp 2015-03-13 18:58:32 UTC (rev 181483)
+++ trunk/Source/WebCore/dom/Element.cpp 2015-03-13 19:24:01 UTC (rev 181484)
@@ -39,6 +39,7 @@
#include "ElementIterator.h"
#include "ElementRareData.h"
#include "EventDispatcher.h"
+#include "EventHandler.h"
#include "FlowThreadController.h"
#include "FocusController.h"
#include "FocusEvent.h"
@@ -289,6 +290,10 @@
bool Element::dispatchKeyEvent(const PlatformKeyboardEvent& platformEvent)
{
RefPtr<KeyboardEvent> event = KeyboardEvent::create(platformEvent, document().defaultView());
+ if (Frame* frame = document().frame()) {
+ if (frame->eventHandler().accessibilityPreventsEventPropogation(event.get()))
+ event->stopPropagation();
+ }
return EventDispatcher::dispatchEvent(this, event) && !event->defaultHandled();
}
Modified: trunk/Source/WebCore/page/EventHandler.cpp (181483 => 181484)
--- trunk/Source/WebCore/page/EventHandler.cpp 2015-03-13 18:58:32 UTC (rev 181483)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2015-03-13 19:24:01 UTC (rev 181484)
@@ -3087,6 +3087,9 @@
keydown->setTarget(element);
keydown->setDefaultHandled();
}
+
+ if (accessibilityPreventsEventPropogation(keydown.get()))
+ keydown->stopPropagation();
element->dispatchEvent(keydown, IGNORE_EXCEPTION);
// If frame changed as a result of keydown dispatch, then return early to avoid sending a subsequent keypress message to the new frame.
@@ -3230,6 +3233,27 @@
}
}
+bool EventHandler::accessibilityPreventsEventPropogation(KeyboardEvent* event)
+{
+#if PLATFORM(COCOA)
+ if (!AXObjectCache::accessibilityEnhancedUserInterfaceEnabled())
+ return false;
+
+ if (!m_frame.settings().preventKeyboardDOMEventDispatch())
+ return false;
+
+ // Check for key events that are relevant to accessibility: tab and arrows keys that change focus
+ if (event->keyIdentifier() == "U+0009")
+ return true;
+ FocusDirection direction = focusDirectionForKey(event->keyIdentifier());
+ if (direction != FocusDirectionNone)
+ return true;
+#else
+ UNUSED_PARAM(event);
+#endif
+ return false;
+}
+
void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
{
if (event->type() == eventNames().keydownEvent) {
Modified: trunk/Source/WebCore/page/EventHandler.h (181483 => 181484)
--- trunk/Source/WebCore/page/EventHandler.h 2015-03-13 18:58:32 UTC (rev 181483)
+++ trunk/Source/WebCore/page/EventHandler.h 2015-03-13 19:24:01 UTC (rev 181484)
@@ -239,6 +239,7 @@
WEBCORE_EXPORT bool keyEvent(const PlatformKeyboardEvent&);
void defaultKeyboardEventHandler(KeyboardEvent*);
+ bool accessibilityPreventsEventPropogation(KeyboardEvent*);
WEBCORE_EXPORT void handleKeyboardSelectionMovementForAccessibility(KeyboardEvent*);
bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, TextEventInputType = TextEventInputKeyboard);
Modified: trunk/Source/WebCore/page/Settings.in (181483 => 181484)
--- trunk/Source/WebCore/page/Settings.in 2015-03-13 18:58:32 UTC (rev 181483)
+++ trunk/Source/WebCore/page/Settings.in 2015-03-13 19:24:01 UTC (rev 181484)
@@ -45,6 +45,7 @@
loadsSiteIconsIgnoringImageLoadingSetting initial=false
caretBrowsingEnabled initial=false
+preventKeyboardDOMEventDispatch initial=false
localStorageEnabled initial=false
allowUniversalAccessFromFileURLs initial=true
allowFileAccessFromFileURLs initial=true