mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 23:02:20 +00:00
Backed out 4 changesets (bug 1198336) for bustages on rules.mk. CLOSED TREE
Backed out changeset 8399406e5f2e (bug 1198336) Backed out changeset 7a2dbe67b6a6 (bug 1198336) Backed out changeset fd45661dd659 (bug 1198336) Backed out changeset 68cf7e4b16f2 (bug 1198336)
This commit is contained in:
parent
40778f846e
commit
7c83560854
@ -498,8 +498,6 @@ static const char kEventTypeNames[][40] = {
|
||||
"text value change", // EVENT_TEXT_VALUE_CHANGE
|
||||
"scrolling", // EVENT_SCROLLING
|
||||
"announcement", // EVENT_ANNOUNCEMENT
|
||||
"live region added", // EVENT_LIVE_REGION_ADDED
|
||||
"live region removed", // EVENT_LIVE_REGION_REMOVED
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -428,20 +428,10 @@ interface nsIAccessibleEvent : nsISupports
|
||||
*/
|
||||
const unsigned long EVENT_ANNOUNCEMENT = 0x0059;
|
||||
|
||||
/**
|
||||
* A live region has been introduced. Mac only.
|
||||
*/
|
||||
const unsigned long EVENT_LIVE_REGION_ADDED = 0x005A;
|
||||
|
||||
/**
|
||||
* A live region has been removed (aria-live attribute changed). Mac Only.
|
||||
*/
|
||||
const unsigned long EVENT_LIVE_REGION_REMOVED = 0x005B;
|
||||
|
||||
/**
|
||||
* Help make sure event map does not get out-of-line.
|
||||
*/
|
||||
const unsigned long EVENT_LAST_ENTRY = 0x005C;
|
||||
const unsigned long EVENT_LAST_ENTRY = 0x005A;
|
||||
|
||||
/**
|
||||
* The type of event, based on the enumerated event values
|
||||
|
@ -5,7 +5,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "DocAccessibleWrap.h"
|
||||
#include "DocAccessible.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "nsCocoaUtils.h"
|
||||
|
||||
@ -30,36 +30,7 @@ using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
AccessibleWrap::AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc)
|
||||
: Accessible(aContent, aDoc), mNativeObject(nil), mNativeInited(false) {
|
||||
if (aContent && aContent->IsElement() && aDoc) {
|
||||
// Check if this accessible is a live region and queue it
|
||||
// it for dispatching an event after it has been inserted.
|
||||
DocAccessibleWrap* doc = static_cast<DocAccessibleWrap*>(aDoc);
|
||||
static const dom::Element::AttrValuesArray sLiveRegionValues[] = {
|
||||
nsGkAtoms::OFF, nsGkAtoms::polite, nsGkAtoms::assertive, nullptr};
|
||||
int32_t attrValue = aContent->AsElement()->FindAttrValueIn(
|
||||
kNameSpaceID_None, nsGkAtoms::aria_live, sLiveRegionValues,
|
||||
eIgnoreCase);
|
||||
if (attrValue == 0) {
|
||||
// aria-live is "off", do nothing.
|
||||
} else if (attrValue > 0) {
|
||||
// aria-live attribute is polite or assertive. It's live!
|
||||
doc->QueueNewLiveRegion(this);
|
||||
} else if (const nsRoleMapEntry* roleMap =
|
||||
aria::GetRoleMap(aContent->AsElement())) {
|
||||
// aria role defines it as a live region. It's live!
|
||||
if (roleMap->liveAttRule == ePoliteLiveAttr) {
|
||||
doc->QueueNewLiveRegion(this);
|
||||
}
|
||||
} else if (nsStaticAtom* value = GetAccService()->MarkupAttribute(
|
||||
aContent, nsGkAtoms::live)) {
|
||||
// HTML element defines it as a live region. It's live!
|
||||
if (value == nsGkAtoms::polite || value == nsGkAtoms::assertive) {
|
||||
doc->QueueNewLiveRegion(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
: Accessible(aContent, aDoc), mNativeObject(nil), mNativeInited(false) {}
|
||||
|
||||
AccessibleWrap::~AccessibleWrap() {}
|
||||
|
||||
@ -149,17 +120,11 @@ nsresult AccessibleWrap::HandleAccEvent(AccEvent* aEvent) {
|
||||
nsresult rv = Accessible::HandleAccEvent(aEvent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uint32_t eventType = aEvent->GetEventType();
|
||||
|
||||
if (eventType == nsIAccessibleEvent::EVENT_SHOW) {
|
||||
DocAccessibleWrap* doc = static_cast<DocAccessibleWrap*>(Document());
|
||||
doc->ProcessNewLiveRegions();
|
||||
}
|
||||
|
||||
if (IPCAccessibilityActive()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint32_t eventType = aEvent->GetEventType();
|
||||
Accessible* eventTarget = nullptr;
|
||||
|
||||
switch (eventType) {
|
||||
@ -257,9 +222,6 @@ nsresult AccessibleWrap::HandleAccEvent(AccEvent* aEvent) {
|
||||
case nsIAccessibleEvent::EVENT_SELECTION:
|
||||
case nsIAccessibleEvent::EVENT_SELECTION_ADD:
|
||||
case nsIAccessibleEvent::EVENT_SELECTION_REMOVE:
|
||||
case nsIAccessibleEvent::EVENT_LIVE_REGION_ADDED:
|
||||
case nsIAccessibleEvent::EVENT_LIVE_REGION_REMOVED:
|
||||
case nsIAccessibleEvent::EVENT_NAME_CHANGE:
|
||||
[nativeAcc handleAccessibleEvent:eventType];
|
||||
break;
|
||||
|
||||
|
@ -23,20 +23,6 @@ class DocAccessibleWrap : public DocAccessible {
|
||||
virtual void Shutdown() override;
|
||||
|
||||
virtual ~DocAccessibleWrap();
|
||||
|
||||
virtual void AttributeChanged(dom::Element* aElement, int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute, int32_t aModType,
|
||||
const nsAttrValue* aOldValue) override;
|
||||
|
||||
void QueueNewLiveRegion(Accessible* aAccessible);
|
||||
|
||||
void ProcessNewLiveRegions();
|
||||
|
||||
protected:
|
||||
virtual void DoInitialUpdate() override;
|
||||
|
||||
private:
|
||||
AccessibleHashtable mNewLiveRegions;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
|
@ -23,77 +23,3 @@ void DocAccessibleWrap::Shutdown() {
|
||||
}
|
||||
|
||||
DocAccessibleWrap::~DocAccessibleWrap() {}
|
||||
|
||||
void DocAccessibleWrap::AttributeChanged(dom::Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsAtom* aAttribute, int32_t aModType,
|
||||
const nsAttrValue* aOldValue) {
|
||||
DocAccessible::AttributeChanged(aElement, aNameSpaceID, aAttribute, aModType,
|
||||
aOldValue);
|
||||
if (aAttribute == nsGkAtoms::aria_live) {
|
||||
Accessible* accessible =
|
||||
mContent != aElement ? GetAccessible(aElement) : this;
|
||||
if (!accessible) {
|
||||
return;
|
||||
}
|
||||
|
||||
static const dom::Element::AttrValuesArray sLiveRegionValues[] = {
|
||||
nsGkAtoms::OFF, nsGkAtoms::polite, nsGkAtoms::assertive, nullptr};
|
||||
int32_t attrValue =
|
||||
aElement->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::aria_live,
|
||||
sLiveRegionValues, eIgnoreCase);
|
||||
if (attrValue > 0) {
|
||||
if (!aOldValue || aOldValue->IsEmptyString() ||
|
||||
aOldValue->Equals(nsGkAtoms::OFF, eIgnoreCase)) {
|
||||
// This element just got an active aria-live attribute value
|
||||
FireDelayedEvent(nsIAccessibleEvent::EVENT_LIVE_REGION_ADDED,
|
||||
accessible);
|
||||
}
|
||||
} else {
|
||||
if (aOldValue && (aOldValue->Equals(nsGkAtoms::polite, eIgnoreCase) ||
|
||||
aOldValue->Equals(nsGkAtoms::assertive, eIgnoreCase))) {
|
||||
// This element lost an active live region
|
||||
FireDelayedEvent(nsIAccessibleEvent::EVENT_LIVE_REGION_REMOVED,
|
||||
accessible);
|
||||
} else if (attrValue == 0) {
|
||||
// aria-live="off", check if its a role-based live region that
|
||||
// needs to be removed.
|
||||
if (const nsRoleMapEntry* roleMap = accessible->ARIARoleMap()) {
|
||||
// aria role defines it as a live region. It's live!
|
||||
if (roleMap->liveAttRule == ePoliteLiveAttr) {
|
||||
FireDelayedEvent(nsIAccessibleEvent::EVENT_LIVE_REGION_REMOVED,
|
||||
accessible);
|
||||
}
|
||||
} else if (nsStaticAtom* value = GetAccService()->MarkupAttribute(
|
||||
aElement, nsGkAtoms::live)) {
|
||||
// HTML element defines it as a live region. It's live!
|
||||
if (value == nsGkAtoms::polite || value == nsGkAtoms::assertive) {
|
||||
FireDelayedEvent(nsIAccessibleEvent::EVENT_LIVE_REGION_REMOVED,
|
||||
accessible);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DocAccessibleWrap::QueueNewLiveRegion(Accessible* aAccessible) {
|
||||
if (!aAccessible) {
|
||||
return;
|
||||
}
|
||||
|
||||
mNewLiveRegions.Put(aAccessible->UniqueID(), RefPtr{aAccessible});
|
||||
}
|
||||
|
||||
void DocAccessibleWrap::ProcessNewLiveRegions() {
|
||||
for (auto iter = mNewLiveRegions.Iter(); !iter.Done(); iter.Next()) {
|
||||
FireDelayedEvent(nsIAccessibleEvent::EVENT_LIVE_REGION_ADDED, iter.Data());
|
||||
}
|
||||
|
||||
mNewLiveRegions.Clear();
|
||||
}
|
||||
|
||||
void DocAccessibleWrap::DoInitialUpdate() {
|
||||
DocAccessible::DoInitialUpdate();
|
||||
ProcessNewLiveRegions();
|
||||
}
|
||||
|
@ -123,8 +123,6 @@ inline id<mozAccessible> GetObjectOrRepresentedView(id<mozAccessible> aObject) {
|
||||
// override
|
||||
- (id<MOXTextMarkerSupport>)moxTextMarkerDelegate;
|
||||
|
||||
- (BOOL)moxIsLiveRegion;
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSString*)description;
|
||||
|
@ -511,10 +511,6 @@ mozilla::LogModule* GetMacAccessibilityLog() {
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)moxIsLiveRegion {
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// objc-style description (from NSObject); not to be confused with the
|
||||
|
@ -57,9 +57,6 @@
|
||||
// Return text delegate if it exists.
|
||||
- (id<MOXTextMarkerSupport> _Nullable)moxTextMarkerDelegate;
|
||||
|
||||
// Return true if this accessible is a live region
|
||||
- (BOOL)moxIsLiveRegion;
|
||||
|
||||
@optional
|
||||
|
||||
#pragma mark - AttributeGetters
|
||||
@ -267,15 +264,6 @@
|
||||
// AXEditableAncestor
|
||||
- (id _Nullable)moxEditableAncestor;
|
||||
|
||||
// AXARIAAtomic
|
||||
- (NSNumber* _Nullable)moxARIAAtomic;
|
||||
|
||||
// AXARIALive
|
||||
- (NSString* _Nullable)moxARIALive;
|
||||
|
||||
// AXARIARelevant
|
||||
- (NSString* _Nullable)moxARIARelevant;
|
||||
|
||||
// AXMozDebugDescription
|
||||
- (NSString* _Nullable)moxMozDebugDescription;
|
||||
|
||||
|
@ -329,13 +329,6 @@ using namespace mozilla::a11y;
|
||||
: RotorMacRoleRule(@"AXTextField");
|
||||
[matches addObjectsFromArray:[self getMatchesForRule:rule]];
|
||||
}
|
||||
|
||||
if ([key isEqualToString:@"AXLiveRegionSearchKey"]) {
|
||||
RotorLiveRegionRule rule = mImmediateDescendantsOnly
|
||||
? RotorLiveRegionRule(geckoRootAcc)
|
||||
: RotorLiveRegionRule();
|
||||
[matches addObjectsFromArray:[self getMatchesForRule:rule]];
|
||||
}
|
||||
}
|
||||
|
||||
return matches;
|
||||
|
@ -77,16 +77,14 @@ void ProxyDestroyed(ProxyAccessible* aProxy) {
|
||||
}
|
||||
|
||||
void ProxyEvent(ProxyAccessible* aProxy, uint32_t aEventType) {
|
||||
// Ignore event that we don't escape below, they aren't yet supported.
|
||||
// ignore everything but focus-changed, value-changed, caret,
|
||||
// selection, and document load complete events for now.
|
||||
if (aEventType != nsIAccessibleEvent::EVENT_FOCUS &&
|
||||
aEventType != nsIAccessibleEvent::EVENT_VALUE_CHANGE &&
|
||||
aEventType != nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE &&
|
||||
aEventType != nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED &&
|
||||
aEventType != nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE &&
|
||||
aEventType != nsIAccessibleEvent::EVENT_REORDER &&
|
||||
aEventType != nsIAccessibleEvent::EVENT_LIVE_REGION_ADDED &&
|
||||
aEventType != nsIAccessibleEvent::EVENT_LIVE_REGION_REMOVED &&
|
||||
aEventType != nsIAccessibleEvent::EVENT_NAME_CHANGE)
|
||||
aEventType != nsIAccessibleEvent::EVENT_REORDER)
|
||||
return;
|
||||
|
||||
mozAccessible* wrapper = GetNativeFromGeckoAccessible(aProxy);
|
||||
|
@ -112,12 +112,3 @@ class RotorHeadingLevelRule : public RotorRoleRule {
|
||||
private:
|
||||
int32_t mLevel;
|
||||
};
|
||||
|
||||
class RotorLiveRegionRule : public RotorRule {
|
||||
public:
|
||||
explicit RotorLiveRegionRule(AccessibleOrProxy& aDirectDescendantsFrom)
|
||||
: RotorRule(aDirectDescendantsFrom) {}
|
||||
explicit RotorLiveRegionRule() : RotorRule() {}
|
||||
|
||||
uint16_t Match(const AccessibleOrProxy& aAccOrProxy) override;
|
||||
};
|
||||
|
@ -307,15 +307,3 @@ uint16_t RotorHeadingLevelRule::Match(const AccessibleOrProxy& aAccOrProxy) {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint16_t RotorLiveRegionRule::Match(const AccessibleOrProxy& aAccOrProxy) {
|
||||
uint16_t result = RotorRule::Match(aAccOrProxy);
|
||||
|
||||
if ((result & nsIAccessibleTraversalRule::FILTER_MATCH)) {
|
||||
mozAccessible* nativeMatch = GetNativeFromGeckoAccessible(aAccOrProxy);
|
||||
if (![nativeMatch moxIsLiveRegion]) {
|
||||
result &= ~nsIAccessibleTraversalRule::FILTER_MATCH;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -59,8 +59,6 @@ inline mozAccessible* GetNativeFromGeckoAccessible(
|
||||
uint64_t mCachedState;
|
||||
|
||||
nsStaticAtom* mARIARole;
|
||||
|
||||
bool mIsLiveRegion;
|
||||
}
|
||||
|
||||
// inits with the given wrap or proxy accessible
|
||||
@ -135,8 +133,6 @@ inline mozAccessible* GetNativeFromGeckoAccessible(
|
||||
|
||||
- (id<MOXTextMarkerSupport>)moxTextMarkerDelegate;
|
||||
|
||||
- (BOOL)moxIsLiveRegion;
|
||||
|
||||
// Attribute getters
|
||||
|
||||
// override
|
||||
@ -187,15 +183,6 @@ inline mozAccessible* GetNativeFromGeckoAccessible(
|
||||
// override
|
||||
- (NSString*)moxARIACurrent;
|
||||
|
||||
// override
|
||||
- (NSNumber*)moxARIAAtomic;
|
||||
|
||||
// override
|
||||
- (NSString*)moxARIALive;
|
||||
|
||||
// override
|
||||
- (NSString*)moxARIARelevant;
|
||||
|
||||
// override
|
||||
- (id)moxTitleUIElement;
|
||||
|
||||
|
@ -41,8 +41,6 @@ using namespace mozilla::a11y;
|
||||
- (BOOL)providesLabelNotTitle;
|
||||
|
||||
- (nsStaticAtom*)ARIARole;
|
||||
|
||||
- (void)maybePostLiveRegionChanged;
|
||||
@end
|
||||
|
||||
@implementation mozAccessible
|
||||
@ -209,12 +207,6 @@ static const uint64_t kCacheInitialized = ((uint64_t)0x1) << 63;
|
||||
return [self stateWithMask:states::FOCUSABLE] == 0;
|
||||
}
|
||||
|
||||
if (selector == @selector(moxARIALive) ||
|
||||
selector == @selector(moxARIAAtomic) ||
|
||||
selector == @selector(moxARIARelevant)) {
|
||||
return ![self moxIsLiveRegion];
|
||||
}
|
||||
|
||||
return [super moxBlockSelector:selector];
|
||||
}
|
||||
|
||||
@ -268,10 +260,6 @@ static const uint64_t kCacheInitialized = ((uint64_t)0x1) << 63;
|
||||
getOrCreateForDoc:mGeckoAccessible.AsProxy()->Document()];
|
||||
}
|
||||
|
||||
- (BOOL)moxIsLiveRegion {
|
||||
return mIsLiveRegion;
|
||||
}
|
||||
|
||||
- (id)moxHitTest:(NSPoint)point {
|
||||
MOZ_ASSERT(!mGeckoAccessible.IsNull());
|
||||
|
||||
@ -721,23 +709,6 @@ struct RoleDescrComparator {
|
||||
return utils::GetAccAttr(self, "current");
|
||||
}
|
||||
|
||||
- (NSNumber*)moxARIAAtomic {
|
||||
return @(utils::GetAccAttr(self, "atomic") != nil);
|
||||
}
|
||||
|
||||
- (NSString*)moxARIALive {
|
||||
return utils::GetAccAttr(self, "live");
|
||||
}
|
||||
|
||||
- (NSString*)moxARIARelevant {
|
||||
if (NSString* relevant = utils::GetAccAttr(self, "container-relevant")) {
|
||||
return relevant;
|
||||
}
|
||||
|
||||
// Default aria-relevant value
|
||||
return @"additions text";
|
||||
}
|
||||
|
||||
- (id)moxTitleUIElement {
|
||||
MOZ_ASSERT(!mGeckoAccessible.IsNull());
|
||||
|
||||
@ -940,20 +911,11 @@ struct RoleDescrComparator {
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)maybePostLiveRegionChanged {
|
||||
for (id element = self; [element conformsToProtocol:@protocol(MOXAccessible)];
|
||||
element = [element moxUnignoredParent]) {
|
||||
if ([element moxIsLiveRegion]) {
|
||||
[element moxPostNotification:@"AXLiveRegionChanged"];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleAccessibleTextChangeEvent:(NSString*)change
|
||||
inserted:(BOOL)isInserted
|
||||
inContainer:(const AccessibleOrProxy&)container
|
||||
at:(int32_t)start {
|
||||
// XXX: Eventually live region handling will go here.
|
||||
}
|
||||
|
||||
- (void)handleAccessibleEvent:(uint32_t)eventType {
|
||||
@ -1001,17 +963,6 @@ struct RoleDescrComparator {
|
||||
withUserInfo:userInfo];
|
||||
break;
|
||||
}
|
||||
case nsIAccessibleEvent::EVENT_LIVE_REGION_ADDED:
|
||||
mIsLiveRegion = true;
|
||||
[self moxPostNotification:@"AXLiveRegionCreated"];
|
||||
break;
|
||||
case nsIAccessibleEvent::EVENT_LIVE_REGION_REMOVED:
|
||||
mIsLiveRegion = false;
|
||||
break;
|
||||
case nsIAccessibleEvent::EVENT_REORDER:
|
||||
case nsIAccessibleEvent::EVENT_NAME_CHANGE:
|
||||
[self maybePostLiveRegionChanged];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,4 +38,3 @@ skip-if = os == 'mac' && debug # Bug 1664577
|
||||
[browser_text_selection.js]
|
||||
[browser_navigate.js]
|
||||
[browser_hierarchy.js]
|
||||
[browser_live_regions.js]
|
||||
|
@ -1,164 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Test live region creation and removal.
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`
|
||||
<div id="polite" aria-relevant="removals">Polite region</div>
|
||||
<div id="assertive" aria-live="assertive">Assertive region</div>
|
||||
`,
|
||||
async (browser, accDoc) => {
|
||||
let politeRegion = getNativeInterface(accDoc, "polite");
|
||||
ok(
|
||||
!politeRegion.attributeNames.includes("AXARIALive"),
|
||||
"region is not live"
|
||||
);
|
||||
|
||||
let liveRegionAdded = waitForMacEvent("AXLiveRegionCreated", "polite");
|
||||
await SpecialPowers.spawn(browser, [], () => {
|
||||
content.document
|
||||
.getElementById("polite")
|
||||
.setAttribute("aria-atomic", "true");
|
||||
content.document
|
||||
.getElementById("polite")
|
||||
.setAttribute("aria-live", "polite");
|
||||
});
|
||||
await liveRegionAdded;
|
||||
is(
|
||||
politeRegion.getAttributeValue("AXARIALive"),
|
||||
"polite",
|
||||
"region is now live"
|
||||
);
|
||||
ok(politeRegion.getAttributeValue("AXARIAAtomic"), "region is atomic");
|
||||
is(
|
||||
politeRegion.getAttributeValue("AXARIARelevant"),
|
||||
"removals",
|
||||
"region has defined aria-relevant"
|
||||
);
|
||||
|
||||
let assertiveRegion = getNativeInterface(accDoc, "assertive");
|
||||
is(
|
||||
assertiveRegion.getAttributeValue("AXARIALive"),
|
||||
"assertive",
|
||||
"region is assertive"
|
||||
);
|
||||
ok(
|
||||
!assertiveRegion.getAttributeValue("AXARIAAtomic"),
|
||||
"region is not atomic"
|
||||
);
|
||||
is(
|
||||
assertiveRegion.getAttributeValue("AXARIARelevant"),
|
||||
"additions text",
|
||||
"region has default aria-relevant"
|
||||
);
|
||||
|
||||
let liveRegionRemoved = waitForEvent(
|
||||
EVENT_LIVE_REGION_REMOVED,
|
||||
"assertive"
|
||||
);
|
||||
await SpecialPowers.spawn(browser, [], () => {
|
||||
content.document.getElementById("assertive").removeAttribute("aria-live");
|
||||
});
|
||||
await liveRegionRemoved;
|
||||
ok(!assertiveRegion.getAttributeValue("AXARIALive"), "region is not live");
|
||||
|
||||
liveRegionAdded = waitForMacEvent("AXLiveRegionCreated", "new-region");
|
||||
await SpecialPowers.spawn(browser, [], () => {
|
||||
let newRegionElm = content.document.createElement("div");
|
||||
newRegionElm.id = "new-region";
|
||||
newRegionElm.setAttribute("aria-live", "assertive");
|
||||
content.document.body.appendChild(newRegionElm);
|
||||
});
|
||||
await liveRegionAdded;
|
||||
|
||||
let newRegion = getNativeInterface(accDoc, "new-region");
|
||||
is(
|
||||
newRegion.getAttributeValue("AXARIALive"),
|
||||
"assertive",
|
||||
"region is assertive"
|
||||
);
|
||||
|
||||
let loadComplete = Promise.all([
|
||||
waitForMacEvent("AXLoadComplete"),
|
||||
waitForMacEvent("AXLiveRegionCreated", "region-1"),
|
||||
waitForMacEvent("AXLiveRegionCreated", "region-2"),
|
||||
waitForMacEvent("AXLiveRegionCreated", "status"),
|
||||
waitForMacEvent("AXLiveRegionCreated", "output"),
|
||||
]);
|
||||
|
||||
await SpecialPowers.spawn(browser, [], () => {
|
||||
content.location = `data:text/html;charset=utf-8,
|
||||
<div id="region-1" aria-live="polite"></div>
|
||||
<div id="region-2" aria-live="assertive"></div>
|
||||
<div id="region-3" aria-live="off"></div>
|
||||
<div id="status" role="status"></div>
|
||||
<output id="output"></output>`;
|
||||
});
|
||||
let webArea = (await loadComplete)[0];
|
||||
|
||||
is(webArea.getAttributeValue("AXRole"), "AXWebArea", "web area yeah");
|
||||
const searchPred = {
|
||||
AXSearchKey: "AXLiveRegionSearchKey",
|
||||
AXResultsLimit: -1,
|
||||
AXDirection: "AXDirectionNext",
|
||||
};
|
||||
const liveRegions = webArea.getParameterizedAttributeValue(
|
||||
"AXUIElementsForSearchPredicate",
|
||||
NSDictionary(searchPred)
|
||||
);
|
||||
Assert.deepEqual(
|
||||
liveRegions.map(r => r.getAttributeValue("AXDOMIdentifier")),
|
||||
["region-1", "region-2", "status", "output"],
|
||||
"SearchPredicate returned all live regions"
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Test live region changes
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`
|
||||
<div id="live" aria-live="polite">
|
||||
The time is <span id="time">4:55pm</span>
|
||||
<p id="p" style="display: none">Georgia on my mind</p>
|
||||
<button id="button" aria-label="Start"></button>
|
||||
</div>
|
||||
`,
|
||||
async (browser, accDoc) => {
|
||||
let liveRegionChanged = waitForMacEvent("AXLiveRegionChanged", "live");
|
||||
await SpecialPowers.spawn(browser, [], () => {
|
||||
content.document.getElementById("time").textContent = "4:56pm";
|
||||
});
|
||||
await liveRegionChanged;
|
||||
ok(true, "changed textContent");
|
||||
|
||||
liveRegionChanged = waitForMacEvent("AXLiveRegionChanged", "live");
|
||||
await SpecialPowers.spawn(browser, [], () => {
|
||||
content.document.getElementById("p").style.display = "block";
|
||||
});
|
||||
await liveRegionChanged;
|
||||
ok(true, "changed display style to block");
|
||||
|
||||
liveRegionChanged = waitForMacEvent("AXLiveRegionChanged", "live");
|
||||
await SpecialPowers.spawn(browser, [], () => {
|
||||
content.document.getElementById("p").style.display = "none";
|
||||
});
|
||||
await liveRegionChanged;
|
||||
ok(true, "changed display style to none");
|
||||
|
||||
liveRegionChanged = waitForMacEvent("AXLiveRegionChanged", "live");
|
||||
await SpecialPowers.spawn(browser, [], () => {
|
||||
content.document
|
||||
.getElementById("button")
|
||||
.setAttribute("aria-label", "Stop");
|
||||
});
|
||||
await liveRegionChanged;
|
||||
ok(true, "changed aria-label");
|
||||
}
|
||||
);
|
@ -28,25 +28,13 @@ function getNativeInterface(accDoc, id) {
|
||||
}
|
||||
|
||||
function waitForMacEventWithInfo(notificationType, filter) {
|
||||
let filterFunc = (macIface, data) => {
|
||||
if (!filter) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof filter == "function") {
|
||||
return filter(macIface, data);
|
||||
}
|
||||
|
||||
return macIface.getAttributeValue("AXDOMIdentifier") == filter;
|
||||
};
|
||||
|
||||
return new Promise(resolve => {
|
||||
let eventObserver = {
|
||||
observe(subject, topic, data) {
|
||||
let macEvent = subject.QueryInterface(Ci.nsIAccessibleMacEvent);
|
||||
if (
|
||||
data === notificationType &&
|
||||
filterFunc(macEvent.macIface, macEvent.data)
|
||||
(!filter || filter(macEvent.macIface, macEvent.data))
|
||||
) {
|
||||
Services.obs.removeObserver(this, "accessible-mac-event");
|
||||
resolve(macEvent);
|
||||
|
@ -42,8 +42,6 @@ const EVENT_VIRTUALCURSOR_CHANGED =
|
||||
const EVENT_ALERT = nsIAccessibleEvent.EVENT_ALERT;
|
||||
const EVENT_TEXT_SELECTION_CHANGED =
|
||||
nsIAccessibleEvent.EVENT_TEXT_SELECTION_CHANGED;
|
||||
const EVENT_LIVE_REGION_ADDED = nsIAccessibleEvent.EVENT_LIVE_REGION_ADDED;
|
||||
const EVENT_LIVE_REGION_REMOVED = nsIAccessibleEvent.EVENT_LIVE_REGION_REMOVED;
|
||||
|
||||
const EventsLogger = {
|
||||
enabled: false,
|
||||
|
@ -2294,7 +2294,6 @@ STATIC_ATOMS = [
|
||||
Atom("aria_rowindextext", "aria-rowindextext"),
|
||||
Atom("aria_rowspan", "aria-rowspan"),
|
||||
Atom("aria_valuetext", "aria-valuetext"),
|
||||
Atom("assertive", "assertive"),
|
||||
Atom("auto_generated", "auto-generated"),
|
||||
Atom("banner", "banner"),
|
||||
Atom("checkable", "checkable"),
|
||||
|
Loading…
Reference in New Issue
Block a user