Diff
Modified: trunk/LayoutTests/ChangeLog (228826 => 228827)
--- trunk/LayoutTests/ChangeLog 2018-02-20 18:46:10 UTC (rev 228826)
+++ trunk/LayoutTests/ChangeLog 2018-02-20 19:02:25 UTC (rev 228827)
@@ -1,3 +1,16 @@
+2018-02-20 Nan Wang <n_w...@apple.com>
+
+ AX: AOM: Dispatch accessibleclick event
+ https://bugs.webkit.org/show_bug.cgi?id=180898
+ <rdar://problem/36086710>
+
+ Reviewed by Ryosuke Niwa.
+
+ * accessibility/mac/AOM-events-expected.txt: Added.
+ * accessibility/mac/AOM-events.html: Added.
+ * js/dom/dom-static-property-for-in-iteration-expected.txt:
+ * platform/mac-wk1/TestExpectations:
+
2018-02-19 Dean Jackson <d...@apple.com>
Handle all writing-modes in downcast
Added: trunk/LayoutTests/accessibility/mac/AOM-events-expected.txt (0 => 228827)
--- trunk/LayoutTests/accessibility/mac/AOM-events-expected.txt (rev 0)
+++ trunk/LayoutTests/accessibility/mac/AOM-events-expected.txt 2018-02-20 19:02:25 UTC (rev 228827)
@@ -0,0 +1,28 @@
+Click Click
+Click
+
+Click
+This tests accessibility-specific events.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+onaccessibleclick support
+PASS receivedAXEvent is true
+PASS receivedFallbackEvent is true
+
+Test preventDefault
+PASS receivedAXEvent is true
+PASS receivedFallbackEvent is false
+
+Test event bubbling
+PASS receivedAXEvent is true
+
+Test event capturing and bubbling
+AX capture UL
+AX capture LI
+AX main event listener BUTTON
+AX bubble LI
+AX bubble UL
+
Added: trunk/LayoutTests/accessibility/mac/AOM-events.html (0 => 228827)
--- trunk/LayoutTests/accessibility/mac/AOM-events.html (rev 0)
+++ trunk/LayoutTests/accessibility/mac/AOM-events.html 2018-02-20 19:02:25 UTC (rev 228827)
@@ -0,0 +1,122 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+
+<button id="button1">Click</button>
+<button id="button2">Click</button>
+<p id="p1">
+<button id="button3">Click</button>
+</p>
+
+<ul id="ul">
+<li id="li">
+<button id="button4">Click</button>
+</li>
+</ul>
+
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+ description("This tests accessibility-specific events.");
+ if (window.accessibilityController) {
+ var node;
+ var axNode;
+ var receivedAXEvent;
+ var receivedFallbackEvent;
+
+ testAccessibleClick();
+ testPreventDefault();
+ testEventBubbling();
+ testEventCapturingAndBubbling();
+ }
+
+ function testAccessibleClick() {
+ debug("\nonaccessibleclick support");
+ node = document.getElementById("button1");
+ axNode = accessibilityController.accessibleElementById("button1");
+
+ receivedAXEvent = false;
+ receivedFallbackEvent = false;
+ node._onaccessibleclick_ = function() {
+ receivedAXEvent = true;
+ };
+ node._onclick_ = function() {
+ receivedFallbackEvent = true;
+ };
+ axNode.syncPress();
+ shouldBeTrue("receivedAXEvent");
+ shouldBeTrue("receivedFallbackEvent");
+ }
+
+ function testPreventDefault() {
+ debug("\nTest preventDefault");
+ node = document.getElementById("button2");
+ axNode = accessibilityController.accessibleElementById("button2");
+
+ receivedAXEvent = false;
+ receivedFallbackEvent = false;
+ node._onaccessibleclick_ = function(evt) {
+ receivedAXEvent = true;
+ evt.preventDefault();
+ };
+ node._onclick_ = function() {
+ receivedFallbackEvent = true;
+ };
+ axNode.syncPress();
+ shouldBeTrue("receivedAXEvent");
+ shouldBeFalse("receivedFallbackEvent");
+ }
+
+ function testEventBubbling() {
+ debug("\nTest event bubbling");
+ node = document.getElementById("p1");
+ axNode = accessibilityController.accessibleElementById("button3");
+
+ node._onaccessibleclick_ = function() {
+ receivedAXEvent = true;
+ };
+ axNode.syncPress();
+ shouldBeTrue("receivedAXEvent");
+ }
+
+ function testEventCapturingAndBubbling() {
+ debug("\nTest event capturing and bubbling");
+ var ul = document.getElementById("ul");
+ var li = document.getElementById("li");
+ var button = document.getElementById("button4");
+ axNode = accessibilityController.accessibleElementById("button4");
+
+ var seq = [];
+
+ // Add event listeners to each layer
+ ul.addEventListener("accessibleclick", function() {
+ seq.push("AX capture UL");
+ }, true);
+ ul.addEventListener("accessibleclick", function() {
+ seq.push("AX bubble UL");
+ }, false);
+ li.addEventListener("accessibleclick", function() {
+ seq.push("AX capture LI");
+ }, true);
+ li.addEventListener("accessibleclick", function() {
+ seq.push("AX bubble LI");
+ }, false);
+ button.addEventListener("accessibleclick", function() {
+ seq.push("AX main event listener BUTTON");
+ }, false);
+
+ axNode.syncPress();
+ seq.forEach(function (entry) {
+ debug(entry);
+ });
+ }
+
+</script>
+<script src=""
+</body>
+</html>
Modified: trunk/LayoutTests/js/dom/dom-static-property-for-in-iteration-expected.txt (228826 => 228827)
--- trunk/LayoutTests/js/dom/dom-static-property-for-in-iteration-expected.txt 2018-02-20 18:46:10 UTC (rev 228826)
+++ trunk/LayoutTests/js/dom/dom-static-property-for-in-iteration-expected.txt 2018-02-20 19:02:25 UTC (rev 228827)
@@ -134,6 +134,7 @@
PASS a["clientHeight"] is 0
PASS a["innerHTML"] is nerget
PASS a["outerHTML"] is <a id="foo" href=""
+PASS a["onaccessibleclick"] is null
PASS a["oncopy"] is null
PASS a["oncut"] is null
PASS a["onpaste"] is null
Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (228826 => 228827)
--- trunk/LayoutTests/platform/mac-wk1/TestExpectations 2018-02-20 18:46:10 UTC (rev 228826)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations 2018-02-20 19:02:25 UTC (rev 228827)
@@ -486,6 +486,8 @@
webkit.org/b/172044 [ Debug ] imported/w3c/web-platform-tests/IndexedDB/open-request-queue.html [ Pass Timeout ]
+webkit.org/b/180898 accessibility/mac/AOM-events.html [ Skip ]
+
# User-installed fonts test infrastructure is not present in WK1
webkit.org/b/180062 fast/text/user-installed-fonts [ ImageOnlyFailure ]
Modified: trunk/Source/WebCore/ChangeLog (228826 => 228827)
--- trunk/Source/WebCore/ChangeLog 2018-02-20 18:46:10 UTC (rev 228826)
+++ trunk/Source/WebCore/ChangeLog 2018-02-20 19:02:25 UTC (rev 228827)
@@ -1,3 +1,40 @@
+2018-02-20 Nan Wang <n_w...@apple.com>
+
+ AX: AOM: Dispatch accessibleclick event
+ https://bugs.webkit.org/show_bug.cgi?id=180898
+ <rdar://problem/36086710>
+
+ Reviewed by Ryosuke Niwa.
+
+ Accessibility events.
+ Spec: https://wicg.github.io/aom/spec/phase2.html
+
+ This patch allows developers to register event handlers on Elements
+ for custom accessibility events.
+
+ Accessibility events go through a capturing and bubbling phase just
+ like DOM events, but in the accessibility tree.
+
+ Implemented "accessibleclick" event.
+
+ Test: accessibility/mac/AOM-events.html
+
+ * accessibility/AccessibilityObject.cpp:
+ (WebCore::AccessibilityObject::press):
+ (WebCore::AccessibilityObject::dispatchAccessibilityEvent):
+ * accessibility/AccessibilityObject.h:
+ * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+ (-[WebAccessibilityObjectWrapper accessibilityPerformAction:]):
+ * dom/Element.idl:
+ * dom/EventDispatcher.cpp:
+ (WebCore::dispatchEventWithType):
+ (WebCore::EventDispatcher::dispatchEvent):
+ * dom/EventDispatcher.h:
+ * dom/EventNames.h:
+ * dom/EventPath.cpp:
+ (WebCore::EventPath::EventPath):
+ * dom/EventPath.h:
+
2018-02-20 Wenson Hsieh <wenson_hs...@apple.com>
[iOS 11.3 Beta] Can't copy a URL from Safari and paste it into the Gmail app
Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.cpp (228826 => 228827)
--- trunk/Source/WebCore/accessibility/AccessibilityObject.cpp 2018-02-20 18:46:10 UTC (rev 228826)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.cpp 2018-02-20 19:02:25 UTC (rev 228827)
@@ -37,6 +37,8 @@
#include "Editing.h"
#include "Editor.h"
#include "ElementIterator.h"
+#include "Event.h"
+#include "EventDispatcher.h"
#include "EventHandler.h"
#include "FloatRect.h"
#include "FocusController.h"
@@ -991,6 +993,16 @@
if (hitTestElement && hitTestElement->isDescendantOf(*pressElement))
pressElement = hitTestElement;
+ // dispatch accessibleclick event
+ if (auto* cache = axObjectCache()) {
+ if (auto* pressObject = cache->getOrCreate(pressElement)) {
+ auto event = Event::create(eventNames().accessibleclickEvent, true, true);
+ pressObject->dispatchAccessibilityEvent(event);
+ if (event->defaultPrevented())
+ return true;
+ }
+ }
+
UserGestureIndicator gestureIndicator(ProcessingUserGesture, document);
bool dispatchedTouchEvent = false;
@@ -2141,6 +2153,17 @@
return nullAtom();
}
+void AccessibilityObject::dispatchAccessibilityEvent(Event& event)
+{
+ Vector<Element*> eventPath;
+ for (auto* parentObject = this; parentObject; parentObject = parentObject->parentObject()) {
+ if (auto* parentElement = parentObject->element())
+ eventPath.append(parentElement);
+ }
+
+ EventDispatcher::dispatchEvent(eventPath, event);
+}
+
// Lacking concrete evidence of orientation, horizontal means width > height. vertical is height > width;
AccessibilityOrientation AccessibilityObject::orientation() const
{
Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.h (228826 => 228827)
--- trunk/Source/WebCore/accessibility/AccessibilityObject.h 2018-02-20 18:46:10 UTC (rev 228826)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.h 2018-02-20 19:02:25 UTC (rev 228827)
@@ -90,8 +90,6 @@
class ScrollView;
class Widget;
-enum class AXPropertyName;
-
typedef unsigned AXID;
enum class AccessibilityRole {
@@ -896,15 +894,9 @@
bool hasAttribute(const QualifiedName&) const;
const AtomicString& getAttribute(const QualifiedName&) const;
bool hasTagName(const QualifiedName&) const;
+
+ void dispatchAccessibilityEvent(Event&);
- bool hasProperty(AXPropertyName) const;
- const String stringValueForProperty(AXPropertyName) const;
- std::optional<bool> boolValueForProperty(AXPropertyName) const;
- int intValueForProperty(AXPropertyName) const;
- unsigned unsignedValueForProperty(AXPropertyName) const;
- double doubleValueForProperty(AXPropertyName) const;
- Element* elementValueForProperty(AXPropertyName) const;
-
virtual VisiblePositionRange visiblePositionRange() const { return VisiblePositionRange(); }
virtual VisiblePositionRange visiblePositionRangeForLine(unsigned) const { return VisiblePositionRange(); }
Modified: trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm (228826 => 228827)
--- trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm 2018-02-20 18:46:10 UTC (rev 228826)
+++ trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm 2018-02-20 19:02:25 UTC (rev 228827)
@@ -3577,6 +3577,10 @@
if ([action isEqualToString:NSAccessibilityPressAction])
[self accessibilityPerformPressAction];
+ // Used in layout tests, so that we don't have to wait for the async press action.
+ else if ([action isEqualToString:@"AXSyncPressAction"])
+ [self _accessibilityPerformPressAction];
+
else if ([action isEqualToString:NSAccessibilityShowMenuAction])
[self accessibilityPerformShowMenuAction];
Modified: trunk/Source/WebCore/dom/Element.idl (228826 => 228827)
--- trunk/Source/WebCore/dom/Element.idl 2018-02-20 18:46:10 UTC (rev 228826)
+++ trunk/Source/WebCore/dom/Element.idl 2018-02-20 19:02:25 UTC (rev 228827)
@@ -140,6 +140,9 @@
// Non standard event handler (https://developer.apple.com/reference/webkitjs/element/1629580-onwebkitplaybacktargetavailabili).
[NotEnumerable, Conditional=WIRELESS_PLAYBACK_TARGET] attribute EventHandler onwebkitplaybacktargetavailabilitychanged;
+
+ // Accessibility events.
+ [EnabledAtRuntime=AccessibilityObjectModel] attribute EventHandler onaccessibleclick;
};
dictionary ShadowRootInit {
Modified: trunk/Source/WebCore/dom/EventDispatcher.cpp (228826 => 228827)
--- trunk/Source/WebCore/dom/EventDispatcher.cpp 2018-02-20 18:46:10 UTC (rev 228826)
+++ trunk/Source/WebCore/dom/EventDispatcher.cpp 2018-02-20 19:02:25 UTC (rev 228827)
@@ -177,7 +177,8 @@
}
}
-void EventDispatcher::dispatchEvent(const Vector<EventTarget*>& targets, Event& event)
+template<typename T>
+static void dispatchEventWithType(const Vector<T*>& targets, Event& event)
{
ASSERT(targets.size() >= 1);
ASSERT(*targets.begin());
@@ -190,4 +191,14 @@
event.resetAfterDispatch();
}
+void EventDispatcher::dispatchEvent(const Vector<EventTarget*>& targets, Event& event)
+{
+ dispatchEventWithType<EventTarget>(targets, event);
}
+
+void EventDispatcher::dispatchEvent(const Vector<Element*>& targets, Event& event)
+{
+ dispatchEventWithType<Element>(targets, event);
+}
+
+}
Modified: trunk/Source/WebCore/dom/EventDispatcher.h (228826 => 228827)
--- trunk/Source/WebCore/dom/EventDispatcher.h 2018-02-20 18:46:10 UTC (rev 228826)
+++ trunk/Source/WebCore/dom/EventDispatcher.h 2018-02-20 19:02:25 UTC (rev 228827)
@@ -24,6 +24,7 @@
namespace WebCore {
+class Element;
class Event;
class EventTarget;
class Node;
@@ -32,6 +33,7 @@
void dispatchEvent(Node&, Event&);
void dispatchEvent(const Vector<EventTarget*>&, Event&);
+void dispatchEvent(const Vector<Element*>&, Event&);
void dispatchScopedEvent(Node&, Event&);
Modified: trunk/Source/WebCore/dom/EventNames.h (228826 => 228827)
--- trunk/Source/WebCore/dom/EventNames.h 2018-02-20 18:46:10 UTC (rev 228826)
+++ trunk/Source/WebCore/dom/EventNames.h 2018-02-20 19:02:25 UTC (rev 228827)
@@ -45,6 +45,7 @@
macro(DOMNodeRemovedFromDocument) \
macro(DOMSubtreeModified) \
macro(abort) \
+ macro(accessibleclick) \
macro(activate) \
macro(active) \
macro(addsourcebuffer) \
Modified: trunk/Source/WebCore/dom/EventPath.cpp (228826 => 228827)
--- trunk/Source/WebCore/dom/EventPath.cpp 2018-02-20 18:46:10 UTC (rev 228826)
+++ trunk/Source/WebCore/dom/EventPath.cpp 2018-02-20 19:02:25 UTC (rev 228827)
@@ -270,6 +270,16 @@
return path;
}
+EventPath::EventPath(const Vector<Element*>& targets)
+{
+ for (auto* target : targets) {
+ ASSERT(target);
+ Node* origin = *targets.begin();
+ if (!target->isClosedShadowHidden(*origin))
+ m_path.append(std::make_unique<EventContext>(target, target, origin));
+ }
+}
+
EventPath::EventPath(const Vector<EventTarget*>& targets)
{
for (auto* target : targets) {
Modified: trunk/Source/WebCore/dom/EventPath.h (228826 => 228827)
--- trunk/Source/WebCore/dom/EventPath.h 2018-02-20 18:46:10 UTC (rev 228826)
+++ trunk/Source/WebCore/dom/EventPath.h 2018-02-20 19:02:25 UTC (rev 228827)
@@ -33,6 +33,7 @@
public:
EventPath(Node& origin, Event&);
explicit EventPath(const Vector<EventTarget*>&);
+ explicit EventPath(const Vector<Element*>&);
bool isEmpty() const { return m_path.isEmpty(); }
size_t size() const { return m_path.size(); }
Modified: trunk/Tools/ChangeLog (228826 => 228827)
--- trunk/Tools/ChangeLog 2018-02-20 18:46:10 UTC (rev 228826)
+++ trunk/Tools/ChangeLog 2018-02-20 19:02:25 UTC (rev 228827)
@@ -1,3 +1,17 @@
+2018-02-20 Nan Wang <n_w...@apple.com>
+
+ AX: AOM: Dispatch accessibleclick event
+ https://bugs.webkit.org/show_bug.cgi?id=180898
+ <rdar://problem/36086710>
+
+ Reviewed by Ryosuke Niwa.
+
+ * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
+ (WTR::AccessibilityUIElement::syncPress):
+ * WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl:
+ * WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
+ (WTR::AccessibilityUIElement::syncPress):
+
2018-02-20 Wenson Hsieh <wenson_hs...@apple.com>
[iOS 11.3 Beta] Can't copy a URL from Safari and paste it into the Gmail app
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h (228826 => 228827)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h 2018-02-20 18:46:10 UTC (rev 228826)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h 2018-02-20 19:02:25 UTC (rev 228827)
@@ -97,6 +97,11 @@
void decrement();
void showMenu();
void press();
+#if PLATFORM(MAC)
+ void syncPress();
+#else
+ void syncPress() { press(); }
+#endif
// Attributes - platform-independent implementations
JSRetainPtr<JSStringRef> stringAttributeValue(JSStringRef attribute);
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl (228826 => 228827)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl 2018-02-20 18:46:10 UTC (rev 228826)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl 2018-02-20 19:02:25 UTC (rev 228827)
@@ -116,6 +116,7 @@
void increment();
void decrement();
void press();
+ void syncPress();
void showMenu();
// Attribute info.
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm (228826 => 228827)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm 2018-02-20 18:46:10 UTC (rev 228826)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm 2018-02-20 19:02:25 UTC (rev 228827)
@@ -1432,6 +1432,13 @@
END_AX_OBJC_EXCEPTIONS
}
+void AccessibilityUIElement::syncPress()
+{
+ BEGIN_AX_OBJC_EXCEPTIONS
+ [m_element accessibilityPerformAction:@"AXSyncPressAction"];
+ END_AX_OBJC_EXCEPTIONS
+}
+
void AccessibilityUIElement::setSelectedChild(AccessibilityUIElement* element) const
{
BEGIN_AX_OBJC_EXCEPTIONS