Title: [181484] trunk
Revision
181484
Author
[email protected]
Date
2015-03-13 12:24:01 -0700 (Fri, 13 Mar 2015)

Log Message

AX: Provide API for assistive tech to ignore DOM key event handlers
https://bugs.webkit.org/show_bug.cgi?id=142059

Patch by Doug Russell <[email protected]> on 2015-03-13
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.

Source/WebCore:

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:

LayoutTests:

* 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.

Modified Paths

Added Paths

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
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to