зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
40778f846e
Коммит
7c83560854
|
@ -498,8 +498,6 @@ static const char kEventTypeNames[][40] = {
|
||||||
"text value change", // EVENT_TEXT_VALUE_CHANGE
|
"text value change", // EVENT_TEXT_VALUE_CHANGE
|
||||||
"scrolling", // EVENT_SCROLLING
|
"scrolling", // EVENT_SCROLLING
|
||||||
"announcement", // EVENT_ANNOUNCEMENT
|
"announcement", // EVENT_ANNOUNCEMENT
|
||||||
"live region added", // EVENT_LIVE_REGION_ADDED
|
|
||||||
"live region removed", // EVENT_LIVE_REGION_REMOVED
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -428,20 +428,10 @@ interface nsIAccessibleEvent : nsISupports
|
||||||
*/
|
*/
|
||||||
const unsigned long EVENT_ANNOUNCEMENT = 0x0059;
|
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.
|
* 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
|
* 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
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "DocAccessibleWrap.h"
|
#include "DocAccessible.h"
|
||||||
#include "nsObjCExceptions.h"
|
#include "nsObjCExceptions.h"
|
||||||
#include "nsCocoaUtils.h"
|
#include "nsCocoaUtils.h"
|
||||||
|
|
||||||
|
@ -30,36 +30,7 @@ using namespace mozilla;
|
||||||
using namespace mozilla::a11y;
|
using namespace mozilla::a11y;
|
||||||
|
|
||||||
AccessibleWrap::AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc)
|
AccessibleWrap::AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc)
|
||||||
: Accessible(aContent, aDoc), mNativeObject(nil), mNativeInited(false) {
|
: 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AccessibleWrap::~AccessibleWrap() {}
|
AccessibleWrap::~AccessibleWrap() {}
|
||||||
|
|
||||||
|
@ -149,17 +120,11 @@ nsresult AccessibleWrap::HandleAccEvent(AccEvent* aEvent) {
|
||||||
nsresult rv = Accessible::HandleAccEvent(aEvent);
|
nsresult rv = Accessible::HandleAccEvent(aEvent);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
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()) {
|
if (IPCAccessibilityActive()) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t eventType = aEvent->GetEventType();
|
||||||
Accessible* eventTarget = nullptr;
|
Accessible* eventTarget = nullptr;
|
||||||
|
|
||||||
switch (eventType) {
|
switch (eventType) {
|
||||||
|
@ -257,9 +222,6 @@ nsresult AccessibleWrap::HandleAccEvent(AccEvent* aEvent) {
|
||||||
case nsIAccessibleEvent::EVENT_SELECTION:
|
case nsIAccessibleEvent::EVENT_SELECTION:
|
||||||
case nsIAccessibleEvent::EVENT_SELECTION_ADD:
|
case nsIAccessibleEvent::EVENT_SELECTION_ADD:
|
||||||
case nsIAccessibleEvent::EVENT_SELECTION_REMOVE:
|
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];
|
[nativeAcc handleAccessibleEvent:eventType];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -23,20 +23,6 @@ class DocAccessibleWrap : public DocAccessible {
|
||||||
virtual void Shutdown() override;
|
virtual void Shutdown() override;
|
||||||
|
|
||||||
virtual ~DocAccessibleWrap();
|
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
|
} // namespace a11y
|
||||||
|
|
|
@ -23,77 +23,3 @@ void DocAccessibleWrap::Shutdown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
DocAccessibleWrap::~DocAccessibleWrap() {}
|
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
|
// override
|
||||||
- (id<MOXTextMarkerSupport>)moxTextMarkerDelegate;
|
- (id<MOXTextMarkerSupport>)moxTextMarkerDelegate;
|
||||||
|
|
||||||
- (BOOL)moxIsLiveRegion;
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
|
||||||
- (NSString*)description;
|
- (NSString*)description;
|
||||||
|
|
|
@ -511,10 +511,6 @@ mozilla::LogModule* GetMacAccessibilityLog() {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)moxIsLiveRegion {
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
|
||||||
// objc-style description (from NSObject); not to be confused with the
|
// objc-style description (from NSObject); not to be confused with the
|
||||||
|
|
|
@ -57,9 +57,6 @@
|
||||||
// Return text delegate if it exists.
|
// Return text delegate if it exists.
|
||||||
- (id<MOXTextMarkerSupport> _Nullable)moxTextMarkerDelegate;
|
- (id<MOXTextMarkerSupport> _Nullable)moxTextMarkerDelegate;
|
||||||
|
|
||||||
// Return true if this accessible is a live region
|
|
||||||
- (BOOL)moxIsLiveRegion;
|
|
||||||
|
|
||||||
@optional
|
@optional
|
||||||
|
|
||||||
#pragma mark - AttributeGetters
|
#pragma mark - AttributeGetters
|
||||||
|
@ -267,15 +264,6 @@
|
||||||
// AXEditableAncestor
|
// AXEditableAncestor
|
||||||
- (id _Nullable)moxEditableAncestor;
|
- (id _Nullable)moxEditableAncestor;
|
||||||
|
|
||||||
// AXARIAAtomic
|
|
||||||
- (NSNumber* _Nullable)moxARIAAtomic;
|
|
||||||
|
|
||||||
// AXARIALive
|
|
||||||
- (NSString* _Nullable)moxARIALive;
|
|
||||||
|
|
||||||
// AXARIARelevant
|
|
||||||
- (NSString* _Nullable)moxARIARelevant;
|
|
||||||
|
|
||||||
// AXMozDebugDescription
|
// AXMozDebugDescription
|
||||||
- (NSString* _Nullable)moxMozDebugDescription;
|
- (NSString* _Nullable)moxMozDebugDescription;
|
||||||
|
|
||||||
|
|
|
@ -329,13 +329,6 @@ using namespace mozilla::a11y;
|
||||||
: RotorMacRoleRule(@"AXTextField");
|
: RotorMacRoleRule(@"AXTextField");
|
||||||
[matches addObjectsFromArray:[self getMatchesForRule:rule]];
|
[matches addObjectsFromArray:[self getMatchesForRule:rule]];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([key isEqualToString:@"AXLiveRegionSearchKey"]) {
|
|
||||||
RotorLiveRegionRule rule = mImmediateDescendantsOnly
|
|
||||||
? RotorLiveRegionRule(geckoRootAcc)
|
|
||||||
: RotorLiveRegionRule();
|
|
||||||
[matches addObjectsFromArray:[self getMatchesForRule:rule]];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return matches;
|
return matches;
|
||||||
|
|
|
@ -77,16 +77,14 @@ void ProxyDestroyed(ProxyAccessible* aProxy) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyEvent(ProxyAccessible* aProxy, uint32_t aEventType) {
|
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 &&
|
if (aEventType != nsIAccessibleEvent::EVENT_FOCUS &&
|
||||||
aEventType != nsIAccessibleEvent::EVENT_VALUE_CHANGE &&
|
aEventType != nsIAccessibleEvent::EVENT_VALUE_CHANGE &&
|
||||||
aEventType != nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE &&
|
aEventType != nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE &&
|
||||||
aEventType != nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED &&
|
aEventType != nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED &&
|
||||||
aEventType != nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE &&
|
aEventType != nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE &&
|
||||||
aEventType != nsIAccessibleEvent::EVENT_REORDER &&
|
aEventType != nsIAccessibleEvent::EVENT_REORDER)
|
||||||
aEventType != nsIAccessibleEvent::EVENT_LIVE_REGION_ADDED &&
|
|
||||||
aEventType != nsIAccessibleEvent::EVENT_LIVE_REGION_REMOVED &&
|
|
||||||
aEventType != nsIAccessibleEvent::EVENT_NAME_CHANGE)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mozAccessible* wrapper = GetNativeFromGeckoAccessible(aProxy);
|
mozAccessible* wrapper = GetNativeFromGeckoAccessible(aProxy);
|
||||||
|
|
|
@ -112,12 +112,3 @@ class RotorHeadingLevelRule : public RotorRoleRule {
|
||||||
private:
|
private:
|
||||||
int32_t mLevel;
|
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;
|
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;
|
uint64_t mCachedState;
|
||||||
|
|
||||||
nsStaticAtom* mARIARole;
|
nsStaticAtom* mARIARole;
|
||||||
|
|
||||||
bool mIsLiveRegion;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// inits with the given wrap or proxy accessible
|
// inits with the given wrap or proxy accessible
|
||||||
|
@ -135,8 +133,6 @@ inline mozAccessible* GetNativeFromGeckoAccessible(
|
||||||
|
|
||||||
- (id<MOXTextMarkerSupport>)moxTextMarkerDelegate;
|
- (id<MOXTextMarkerSupport>)moxTextMarkerDelegate;
|
||||||
|
|
||||||
- (BOOL)moxIsLiveRegion;
|
|
||||||
|
|
||||||
// Attribute getters
|
// Attribute getters
|
||||||
|
|
||||||
// override
|
// override
|
||||||
|
@ -187,15 +183,6 @@ inline mozAccessible* GetNativeFromGeckoAccessible(
|
||||||
// override
|
// override
|
||||||
- (NSString*)moxARIACurrent;
|
- (NSString*)moxARIACurrent;
|
||||||
|
|
||||||
// override
|
|
||||||
- (NSNumber*)moxARIAAtomic;
|
|
||||||
|
|
||||||
// override
|
|
||||||
- (NSString*)moxARIALive;
|
|
||||||
|
|
||||||
// override
|
|
||||||
- (NSString*)moxARIARelevant;
|
|
||||||
|
|
||||||
// override
|
// override
|
||||||
- (id)moxTitleUIElement;
|
- (id)moxTitleUIElement;
|
||||||
|
|
||||||
|
|
|
@ -41,8 +41,6 @@ using namespace mozilla::a11y;
|
||||||
- (BOOL)providesLabelNotTitle;
|
- (BOOL)providesLabelNotTitle;
|
||||||
|
|
||||||
- (nsStaticAtom*)ARIARole;
|
- (nsStaticAtom*)ARIARole;
|
||||||
|
|
||||||
- (void)maybePostLiveRegionChanged;
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation mozAccessible
|
@implementation mozAccessible
|
||||||
|
@ -209,12 +207,6 @@ static const uint64_t kCacheInitialized = ((uint64_t)0x1) << 63;
|
||||||
return [self stateWithMask:states::FOCUSABLE] == 0;
|
return [self stateWithMask:states::FOCUSABLE] == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selector == @selector(moxARIALive) ||
|
|
||||||
selector == @selector(moxARIAAtomic) ||
|
|
||||||
selector == @selector(moxARIARelevant)) {
|
|
||||||
return ![self moxIsLiveRegion];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [super moxBlockSelector:selector];
|
return [super moxBlockSelector:selector];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,10 +260,6 @@ static const uint64_t kCacheInitialized = ((uint64_t)0x1) << 63;
|
||||||
getOrCreateForDoc:mGeckoAccessible.AsProxy()->Document()];
|
getOrCreateForDoc:mGeckoAccessible.AsProxy()->Document()];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)moxIsLiveRegion {
|
|
||||||
return mIsLiveRegion;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)moxHitTest:(NSPoint)point {
|
- (id)moxHitTest:(NSPoint)point {
|
||||||
MOZ_ASSERT(!mGeckoAccessible.IsNull());
|
MOZ_ASSERT(!mGeckoAccessible.IsNull());
|
||||||
|
|
||||||
|
@ -721,23 +709,6 @@ struct RoleDescrComparator {
|
||||||
return utils::GetAccAttr(self, "current");
|
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 {
|
- (id)moxTitleUIElement {
|
||||||
MOZ_ASSERT(!mGeckoAccessible.IsNull());
|
MOZ_ASSERT(!mGeckoAccessible.IsNull());
|
||||||
|
|
||||||
|
@ -940,20 +911,11 @@ struct RoleDescrComparator {
|
||||||
return NO;
|
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
|
- (void)handleAccessibleTextChangeEvent:(NSString*)change
|
||||||
inserted:(BOOL)isInserted
|
inserted:(BOOL)isInserted
|
||||||
inContainer:(const AccessibleOrProxy&)container
|
inContainer:(const AccessibleOrProxy&)container
|
||||||
at:(int32_t)start {
|
at:(int32_t)start {
|
||||||
|
// XXX: Eventually live region handling will go here.
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)handleAccessibleEvent:(uint32_t)eventType {
|
- (void)handleAccessibleEvent:(uint32_t)eventType {
|
||||||
|
@ -1001,17 +963,6 @@ struct RoleDescrComparator {
|
||||||
withUserInfo:userInfo];
|
withUserInfo:userInfo];
|
||||||
break;
|
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_text_selection.js]
|
||||||
[browser_navigate.js]
|
[browser_navigate.js]
|
||||||
[browser_hierarchy.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) {
|
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 => {
|
return new Promise(resolve => {
|
||||||
let eventObserver = {
|
let eventObserver = {
|
||||||
observe(subject, topic, data) {
|
observe(subject, topic, data) {
|
||||||
let macEvent = subject.QueryInterface(Ci.nsIAccessibleMacEvent);
|
let macEvent = subject.QueryInterface(Ci.nsIAccessibleMacEvent);
|
||||||
if (
|
if (
|
||||||
data === notificationType &&
|
data === notificationType &&
|
||||||
filterFunc(macEvent.macIface, macEvent.data)
|
(!filter || filter(macEvent.macIface, macEvent.data))
|
||||||
) {
|
) {
|
||||||
Services.obs.removeObserver(this, "accessible-mac-event");
|
Services.obs.removeObserver(this, "accessible-mac-event");
|
||||||
resolve(macEvent);
|
resolve(macEvent);
|
||||||
|
|
|
@ -42,8 +42,6 @@ const EVENT_VIRTUALCURSOR_CHANGED =
|
||||||
const EVENT_ALERT = nsIAccessibleEvent.EVENT_ALERT;
|
const EVENT_ALERT = nsIAccessibleEvent.EVENT_ALERT;
|
||||||
const EVENT_TEXT_SELECTION_CHANGED =
|
const EVENT_TEXT_SELECTION_CHANGED =
|
||||||
nsIAccessibleEvent.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 = {
|
const EventsLogger = {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
|
|
@ -2294,7 +2294,6 @@ STATIC_ATOMS = [
|
||||||
Atom("aria_rowindextext", "aria-rowindextext"),
|
Atom("aria_rowindextext", "aria-rowindextext"),
|
||||||
Atom("aria_rowspan", "aria-rowspan"),
|
Atom("aria_rowspan", "aria-rowspan"),
|
||||||
Atom("aria_valuetext", "aria-valuetext"),
|
Atom("aria_valuetext", "aria-valuetext"),
|
||||||
Atom("assertive", "assertive"),
|
|
||||||
Atom("auto_generated", "auto-generated"),
|
Atom("auto_generated", "auto-generated"),
|
||||||
Atom("banner", "banner"),
|
Atom("banner", "banner"),
|
||||||
Atom("checkable", "checkable"),
|
Atom("checkable", "checkable"),
|
||||||
|
|
Загрузка…
Ссылка в новой задаче