--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
#
# Modifying this file will now automatically clobber the buildbot machines \o/
#
# Are you updating CLOBBER because you think it's needed for your WebIDL
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
-Merge day clobber
\ No newline at end of file
+Bug 1166031 - NSS update hit needs-clobber bustage.
--- a/Makefile.in
+++ b/Makefile.in
@@ -16,17 +16,17 @@ export TOPLEVEL_BUILD := 1
default::
ifdef MOZ_BUILD_APP
include $(topsrcdir)/$(MOZ_BUILD_APP)/build.mk
endif
include $(topsrcdir)/config/config.mk
-GARBAGE_DIRS += dist _javagen _profile staticlib
+GARBAGE_DIRS += _javagen _profile staticlib
DIST_GARBAGE = config.cache config.log config.status* config-defs.h \
config/autoconf.mk \
mozilla-config.h \
netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \
.mozconfig.mk
ifdef JS_STANDALONE
configure_dir = $(topsrcdir)/js/src
@@ -136,20 +136,20 @@ install-_tests: $(install_manifest_depen
$(call py_action,process_install_manifest,$(if $(NO_REMOVE),--no-remove )_tests _build_manifests/install/tests)
# For compatibility
.PHONY: install-tests
install-tests: install-_tests
include $(topsrcdir)/build/moz-automation.mk
-# _tests should be purged during cleaning. However, we don't want it purged
-# during PGO builds because it contains some auto-generated files.
+# dist and _tests should be purged during cleaning. However, we don't want them
+# purged during PGO builds because they contain some auto-generated files.
ifneq ($(filter-out maybe_clobber_profiledbuild,$(MAKECMDGOALS)),)
-GARBAGE_DIRS += _tests
+GARBAGE_DIRS += dist _tests
endif
# Windows PGO builds don't perform a clean before the 2nd pass. So, we want
# to preserve content for the 2nd pass on Windows. Everywhere else, we always
# process the install manifests as part of export.
# For the binaries rule, not all the install manifests matter, so force only
# the interesting ones to be done.
ifdef MOZ_PROFILE_USE
@@ -249,17 +249,17 @@ ifdef MOZ_CRASHREPORTER
mv $(SYMBOL_INDEX_NAME).tmp $(SYMBOL_INDEX_NAME)
cd $(DIST)/crashreporter-symbols && \
zip -r9D '../$(PKG_PATH)$(SYMBOL_ARCHIVE_BASENAME).zip' . -i '*.sym' -i '*.txt' -x '*test*' -x '*Test*'
endif # MOZ_CRASHREPORTER
uploadsymbols:
ifdef MOZ_CRASHREPORTER
ifdef SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE
- $(PYTHON) $(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.py '$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip'
+ $(PYTHON) -u $(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.py '$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip'
else
$(SHELL) $(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.sh $(SYMBOL_INDEX_NAME) '$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip'
endif
endif
# MOZ_SOURCE_STAMP is defined in package-name.mk with a deferred assignment.
# exporting it makes make run its $(shell) command for each invoked submake,
# so transform it to an immediate assignment.
--- a/accessible/atk/AccessibleWrap.cpp
+++ b/accessible/atk/AccessibleWrap.cpp
@@ -795,17 +795,21 @@ getParentCB(AtkObject *aAtkObj)
return aAtkObj->accessible_parent;
AtkObject* atkParent = nullptr;
if (AccessibleWrap* wrapper = GetAccessibleWrap(aAtkObj)) {
Accessible* parent = wrapper->Parent();
atkParent = parent ? AccessibleWrap::GetAtkObject(parent) : nullptr;
} else if (ProxyAccessible* proxy = GetProxy(aAtkObj)) {
ProxyAccessible* parent = proxy->Parent();
- atkParent = parent ? GetWrapperFor(parent) : nullptr;
+ if (parent)
+ atkParent = GetWrapperFor(parent);
+
+ // Otherwise this should be the proxy for the tab's top level document.
+ atkParent = AccessibleWrap::GetAtkObject(proxy->OuterDocOfRemoteBrowser());
}
if (atkParent)
atk_object_set_parent(aAtkObj, atkParent);
return aAtkObj->accessible_parent;
}
@@ -854,16 +858,19 @@ gint
getIndexInParentCB(AtkObject* aAtkObj)
{
// We don't use Accessible::IndexInParent() because we don't include text
// leaf nodes as children in ATK.
if (ProxyAccessible* proxy = GetProxy(aAtkObj)) {
if (ProxyAccessible* parent = proxy->Parent())
return parent->IndexOfEmbeddedChild(proxy);
+ if (proxy->OuterDocOfRemoteBrowser())
+ return 0;
+
return -1;
}
AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
if (!accWrap) {
return -1;
}
@@ -1123,17 +1130,22 @@ AccessibleWrap::HandleAccEvent(AccEvent*
AccessibleWrap* accWrap = GetAccessibleWrap(atkObj);
if (!accWrap) {
return NS_OK; // Node is shut down
}
switch (type) {
case nsIAccessibleEvent::EVENT_STATE_CHANGE:
- return FireAtkStateChangeEvent(aEvent, atkObj);
+ {
+ AccStateChangeEvent* event = downcast_accEvent(aEvent);
+ MAI_ATK_OBJECT(atkObj)->FireStateChangeEvent(event->GetState(),
+ event->IsStateEnabled());
+ break;
+ }
case nsIAccessibleEvent::EVENT_TEXT_REMOVED:
case nsIAccessibleEvent::EVENT_TEXT_INSERTED:
return FireAtkTextChangedEvent(aEvent, atkObj);
case nsIAccessibleEvent::EVENT_FOCUS:
{
a11y::RootAccessible* rootAccWrap = accWrap->RootAccessible();
@@ -1348,50 +1360,79 @@ AccessibleWrap::HandleAccEvent(AccEvent*
return NS_OK;
}
void
a11y::ProxyEvent(ProxyAccessible* aTarget, uint32_t aEventType)
{
AtkObject* wrapper = GetWrapperFor(aTarget);
- if (aEventType == nsIAccessibleEvent::EVENT_FOCUS) {
+
+ switch (aEventType) {
+ case nsIAccessibleEvent::EVENT_FOCUS:
atk_focus_tracker_notify(wrapper);
atk_object_notify_state_change(wrapper, ATK_STATE_FOCUSED, true);
+ break;
+ case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE:
+ g_signal_emit_by_name(wrapper, "load_complete");
+ break;
+ case nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD:
+ g_signal_emit_by_name(wrapper, "reload");
+ break;
+ case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED:
+ g_signal_emit_by_name(wrapper, "load_stopped");
+ break;
+ case nsIAccessibleEvent::EVENT_MENUPOPUP_START:
+ atk_focus_tracker_notify(wrapper); // fire extra focus event
+ atk_object_notify_state_change(wrapper, ATK_STATE_VISIBLE, true);
+ atk_object_notify_state_change(wrapper, ATK_STATE_SHOWING, true);
+ break;
+ case nsIAccessibleEvent::EVENT_MENUPOPUP_END:
+ atk_object_notify_state_change(wrapper, ATK_STATE_VISIBLE, false);
+ atk_object_notify_state_change(wrapper, ATK_STATE_SHOWING, false);
+ break;
}
}
-nsresult
-AccessibleWrap::FireAtkStateChangeEvent(AccEvent* aEvent,
- AtkObject* aObject)
+void
+a11y::ProxyStateChangeEvent(ProxyAccessible* aTarget, uint64_t aState,
+ bool aEnabled)
{
- AccStateChangeEvent* event = downcast_accEvent(aEvent);
- NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
+ MaiAtkObject* atkObj = MAI_ATK_OBJECT(GetWrapperFor(aTarget));
+ atkObj->FireStateChangeEvent(aState, aEnabled);
+}
- bool isEnabled = event->IsStateEnabled();
- int32_t stateIndex = AtkStateMap::GetStateIndexFor(event->GetState());
+void
+a11y::ProxyCaretMoveEvent(ProxyAccessible* aTarget, int32_t aOffset)
+{
+ AtkObject* wrapper = GetWrapperFor(aTarget);
+ g_signal_emit_by_name(wrapper, "text_caret_moved", aOffset);
+}
+
+void
+MaiAtkObject::FireStateChangeEvent(uint64_t aState, bool aEnabled)
+{
+ int32_t stateIndex = AtkStateMap::GetStateIndexFor(aState);
if (stateIndex >= 0) {
NS_ASSERTION(gAtkStateMap[stateIndex].stateMapEntryType != kNoSuchState,
"No such state");
if (gAtkStateMap[stateIndex].atkState != kNone) {
NS_ASSERTION(gAtkStateMap[stateIndex].stateMapEntryType != kNoStateChange,
"State changes should not fired for this state");
if (gAtkStateMap[stateIndex].stateMapEntryType == kMapOpposite)
- isEnabled = !isEnabled;
+ aEnabled = !aEnabled;
// Fire state change for first state if there is one to map
- atk_object_notify_state_change(aObject,
+ atk_object_notify_state_change(&parent,
gAtkStateMap[stateIndex].atkState,
- isEnabled);
+ aEnabled);
}
}
-
- return NS_OK;
}
nsresult
AccessibleWrap::FireAtkTextChangedEvent(AccEvent* aEvent,
AtkObject* aObject)
{
AccTextChangeEvent* event = downcast_accEvent(aEvent);
NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
--- a/accessible/atk/Platform.cpp
+++ b/accessible/atk/Platform.cpp
@@ -356,18 +356,17 @@ dbus_done:
if (reply)
dbus_message_unref(reply);
if (dbusSuccess)
return sShouldEnable;
#endif
//check gconf-2 setting
-static const char sGconfAccessibilityKey[] =
- "/desktop/gnome/interface/accessibility";
+#define GCONF_A11Y_KEY "/desktop/gnome/interface/accessibility"
nsresult rv = NS_OK;
nsCOMPtr<nsIGConfService> gconf =
do_GetService(NS_GCONFSERVICE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv) && gconf)
- gconf->GetBool(NS_LITERAL_CSTRING(sGconfAccessibilityKey), &sShouldEnable);
+ gconf->GetBool(NS_LITERAL_CSTRING(GCONF_A11Y_KEY), &sShouldEnable);
return sShouldEnable;
}
--- a/accessible/atk/nsMai.h
+++ b/accessible/atk/nsMai.h
@@ -71,11 +71,16 @@ struct MaiAtkObject
* Get the AtkHyperlink for this atk object.
*/
AtkHyperlink* GetAtkHyperlink();
/*
* Shutdown this AtkObject.
*/
void Shutdown();
+
+ /*
+ * Notify atk of a state change on this AtkObject.
+ */
+ void FireStateChangeEvent(uint64_t aState, bool aEnabled);
};
#endif /* __NS_MAI_H__ */
--- a/accessible/atk/nsMaiHyperlink.cpp
+++ b/accessible/atk/nsMaiHyperlink.cpp
@@ -216,17 +216,17 @@ getEndIndexCB(AtkHyperlink *aLink)
uint32_t endIdx = maiLink->Proxy()->EndOffset(&valid);
return valid ? static_cast<gint>(endIdx) : -1;
}
gint
getStartIndexCB(AtkHyperlink *aLink)
{
MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
- if (maiLink)
+ if (!maiLink)
return -1;
if (Accessible* hyperlink = maiLink->GetAccHyperlink())
return static_cast<gint>(hyperlink->StartOffset());
bool valid = false;
uint32_t startIdx = maiLink->Proxy()->StartOffset(&valid);
return valid ? static_cast<gint>(startIdx) : -1;
--- a/accessible/base/DocManager.cpp
+++ b/accessible/base/DocManager.cpp
@@ -27,17 +27,17 @@
#include "nsIDOMDocument.h"
#include "nsIDOMWindow.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIWebNavigation.h"
#include "nsServiceManagerUtils.h"
#include "nsIWebProgress.h"
#include "nsCoreUtils.h"
#include "nsXULAppAPI.h"
-#include "mozilla/dom/ContentChild.h"
+#include "mozilla/dom/TabChild.h"
using namespace mozilla;
using namespace mozilla::a11y;
using namespace mozilla::dom;
StaticAutoPtr<nsTArray<DocAccessibleParent*>> DocManager::sRemoteDocuments;
////////////////////////////////////////////////////////////////////////////////
@@ -452,18 +452,20 @@ DocManager::CreateDocOrRootAccessible(ns
// Note: don't use AccReorderEvent to avoid coalsecense and special reorder
// events processing.
docAcc->FireDelayedEvent(nsIAccessibleEvent::EVENT_REORDER,
ApplicationAcc());
if (IPCAccessibilityActive()) {
DocAccessibleChild* ipcDoc = new DocAccessibleChild(docAcc);
docAcc->SetIPCDoc(ipcDoc);
- auto contentChild = dom::ContentChild::GetSingleton();
- contentChild->SendPDocAccessibleConstructor(ipcDoc, nullptr, 0);
+ nsCOMPtr<nsITabChild> tabChild =
+ do_GetInterface(aDocument->GetDocShell());
+ static_cast<TabChild*>(tabChild.get())->
+ SendPDocAccessibleConstructor(ipcDoc, nullptr, 0);
}
} else {
parentDocAcc->BindChildDocument(docAcc);
}
#ifdef A11Y_LOG
if (logging::IsEnabled(logging::eDocCreate)) {
logging::DocCreate("document creation finished", aDocument);
--- a/accessible/base/EventQueue.cpp
+++ b/accessible/base/EventQueue.cpp
@@ -497,16 +497,27 @@ EventQueue::SendIPCEvent(AccEvent* aEven
break;
case nsIAccessibleEvent::EVENT_REORDER:
// reorder events on the application acc aren't necessary to tell the parent
// about new top level documents.
if (!aEvent->GetAccessible()->IsApplication())
ipcDoc->SendEvent(id, aEvent->GetEventType());
break;
+ case nsIAccessibleEvent::EVENT_STATE_CHANGE: {
+ AccStateChangeEvent* event = downcast_accEvent(aEvent);
+ ipcDoc->SendStateChangeEvent(id, event->GetState(),
+ event->IsStateEnabled());
+ break;
+ }
+ case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED: {
+ AccCaretMoveEvent* event = downcast_accEvent(aEvent);
+ ipcDoc->SendEvent(id, event->GetCaretOffset());
+ break;
+ }
default:
ipcDoc->SendEvent(id, aEvent->GetEventType());
}
}
////////////////////////////////////////////////////////////////////////////////
// EventQueue: event queue
--- a/accessible/base/MarkupMap.h
+++ b/accessible/base/MarkupMap.h
@@ -98,16 +98,20 @@ MARKUPMAP(label,
MARKUPMAP(legend,
New_HTMLLegend,
roles::LABEL)
MARKUPMAP(li,
New_HTMLListitem,
0)
+MARKUPMAP(map,
+ nullptr,
+ roles::TEXT_CONTAINER)
+
MARKUPMAP(math,
New_HyperText,
roles::MATHML_MATH)
MARKUPMAP(mi_,
New_HyperText,
roles::MATHML_IDENTIFIER)
@@ -299,16 +303,20 @@ MARKUPMAP(optgroup,
New_HTMLOptgroup,
0)
MARKUPMAP(output,
New_HTMLOutput,
roles::SECTION,
Attr(live, polite))
+MARKUPMAP(p,
+ nullptr,
+ roles::PARAGRAPH)
+
MARKUPMAP(progress,
New_HTMLProgress,
0)
MARKUPMAP(q,
New_HyperText,
0)
--- a/accessible/base/NotificationController.cpp
+++ b/accessible/base/NotificationController.cpp
@@ -5,17 +5,17 @@
#include "NotificationController.h"
#include "DocAccessible-inl.h"
#include "DocAccessibleChild.h"
#include "TextLeafAccessible.h"
#include "TextUpdater.h"
-#include "mozilla/dom/ContentChild.h"
+#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/Element.h"
#include "mozilla/Telemetry.h"
using namespace mozilla;
using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////
// NotificationCollector
@@ -287,18 +287,20 @@ NotificationController::WillRefresh(mozi
DocAccessibleChild* ipcDoc = childDoc->IPCDoc();
if (ipcDoc) {
parentIPCDoc->SendBindChildDoc(ipcDoc, id);
continue;
}
ipcDoc = new DocAccessibleChild(childDoc);
childDoc->SetIPCDoc(ipcDoc);
- auto contentChild = dom::ContentChild::GetSingleton();
- contentChild->SendPDocAccessibleConstructor(ipcDoc, parentIPCDoc, id);
+ nsCOMPtr<nsITabChild> tabChild =
+ do_GetInterface(mDocument->DocumentNode()->GetDocShell());
+ static_cast<TabChild*>(tabChild.get())->
+ SendPDocAccessibleConstructor(ipcDoc, parentIPCDoc, id);
}
}
mObservingState = eRefreshObserving;
if (!mDocument)
return;
// Stop further processing if there are no new notifications of any kind or
--- a/accessible/base/Platform.h
+++ b/accessible/base/Platform.h
@@ -62,11 +62,14 @@ void ProxyCreated(ProxyAccessible* aProx
* disposed of and other action taken.
*/
void ProxyDestroyed(ProxyAccessible*);
/**
* Callied when an event is fired on a proxied accessible.
*/
void ProxyEvent(ProxyAccessible* aTarget, uint32_t aEventType);
+void ProxyStateChangeEvent(ProxyAccessible* aTarget, uint64_t aState,
+ bool aEnabled);
+void ProxyCaretMoveEvent(ProxyAccessible* aTarget, int32_t aOffset);
} // namespace a11y
} // namespace mozilla
--- a/accessible/base/Role.h
+++ b/accessible/base/Role.h
@@ -976,17 +976,23 @@ enum Role {
*/
MATHML_STACK_LINE = 167,
/**
* A group containing radio buttons
*/
RADIO_GROUP = 168,
- LAST_ROLE = RADIO_GROUP
+ /**
+ * A text container exposing brief amount of information. See related
+ * TEXT_CONTAINER role.
+ */
+ TEXT = 169,
+
+ LAST_ROLE = TEXT
};
} // namespace role
typedef enum mozilla::a11y::roles::Role role;
} // namespace a11y
} // namespace mozilla
--- a/accessible/base/RoleMap.h
+++ b/accessible/base/RoleMap.h
@@ -749,17 +749,17 @@ ROLE(TERMINAL,
ATK_ROLE_TERMINAL,
NSAccessibilityUnknownRole,
USE_ROLE_STRING,
IA2_ROLE_TERMINAL,
eNoNameRule)
ROLE(TEXT_CONTAINER,
"text container",
- ATK_ROLE_TEXT,
+ ATK_ROLE_SECTION,
NSAccessibilityGroupRole,
USE_ROLE_STRING,
IA2_ROLE_TEXT_FRAME,
eNameFromSubtreeIfReqRule)
ROLE(TOGGLE_BUTTON,
"toggle button",
ATK_ROLE_TOGGLE_BUTTON,
@@ -1362,8 +1362,17 @@ ROLE(MATHML_STACK_LINE,
ROLE(RADIO_GROUP,
"grouping",
ATK_ROLE_PANEL,
NSAccessibilityRadioGroupRole,
ROLE_SYSTEM_GROUPING,
ROLE_SYSTEM_GROUPING,
eNoNameRule)
+
+ROLE(TEXT,
+ "text",
+ ATK_ROLE_STATIC,
+ NSAccessibilityGroupRole,
+ USE_ROLE_STRING,
+ IA2_ROLE_TEXT_FRAME,
+ eNameFromSubtreeIfReqRule)
+
--- a/accessible/base/TextAttrs.cpp
+++ b/accessible/base/TextAttrs.cpp
@@ -13,16 +13,20 @@
#include "gfxFont.h"
#include "nsFontMetrics.h"
#include "nsLayoutUtils.h"
#include "nsContainerFrame.h"
#include "HyperTextAccessible.h"
#include "mozilla/AppUnits.h"
#include "mozilla/gfx/2D.h"
+#if defined(MOZ_WIDGET_GTK)
+#include "gfxPlatformGtk.h" // xxx - for UseFcFontList
+#endif
+
using namespace mozilla;
using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////
// TextAttrsMgr
////////////////////////////////////////////////////////////////////////////////
void
@@ -623,31 +627,40 @@ TextAttrsMgr::FontWeightTextAttr::
// When there doesn't exist a bold font in the family and so the rendering of
// a non-bold font face is changed so that the user sees what looks like a
// bold font, i.e. synthetic bolding is used. IsSyntheticBold method is only
// needed on Mac, but it is "safe" to use on all platforms. (For non-Mac
// platforms it always return false.)
if (font->IsSyntheticBold())
return 700;
-#if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
- // On Linux, font->GetStyle()->weight will give the absolute weight requested
- // of the font face. The Linux code uses the gfxFontEntry constructor which
- // doesn't initialize the weight field.
- return font->GetStyle()->weight;
-#else
- // On Windows, font->GetStyle()->weight will give the same weight as
- // fontEntry->Weight(), the weight of the first font in the font group, which
- // may not be the weight of the font face used to render the characters.
- // On Mac, font->GetStyle()->weight will just give the same number as
- // getComputedStyle(). fontEntry->Weight() will give the weight of the font
- // face used.
- gfxFontEntry *fontEntry = font->GetFontEntry();
- return fontEntry->Weight();
+ bool useFontEntryWeight = true;
+
+ // Under Linux, when gfxPangoFontGroup code is used,
+ // font->GetStyle()->weight will give the absolute weight requested of the
+ // font face. The gfxPangoFontGroup code uses the gfxFontEntry constructor
+ // which doesn't initialize the weight field.
+#if defined(MOZ_WIDGET_QT)
+ useFontEntryWeight = false;
+#elif defined(MOZ_WIDGET_GTK)
+ useFontEntryWeight = gfxPlatformGtk::UseFcFontList();
#endif
+
+ if (useFontEntryWeight) {
+ // On Windows, font->GetStyle()->weight will give the same weight as
+ // fontEntry->Weight(), the weight of the first font in the font group,
+ // which may not be the weight of the font face used to render the
+ // characters. On Mac, font->GetStyle()->weight will just give the same
+ // number as getComputedStyle(). fontEntry->Weight() will give the weight
+ // of the font face used.
+ gfxFontEntry *fontEntry = font->GetFontEntry();
+ return fontEntry->Weight();
+ } else {
+ return font->GetStyle()->weight;
+ }
}
////////////////////////////////////////////////////////////////////////////////
// AutoGeneratedTextAttr
////////////////////////////////////////////////////////////////////////////////
TextAttrsMgr::AutoGeneratedTextAttr::
AutoGeneratedTextAttr(HyperTextAccessible* aHyperTextAcc,
Accessible* aAccessible) :
--- a/accessible/generic/HyperTextAccessible.cpp
+++ b/accessible/generic/HyperTextAccessible.cpp
@@ -58,22 +58,21 @@ NS_IMPL_ISUPPORTS_INHERITED0(HyperTextAc
role
HyperTextAccessible::NativeRole()
{
a11y::role r = GetAccService()->MarkupRole(mContent);
if (r != roles::NOTHING)
return r;
- // Treat block frames as paragraphs
- nsIFrame *frame = GetFrame();
- if (frame && frame->GetType() == nsGkAtoms::blockFrame)
- return roles::PARAGRAPH;
+ nsIFrame* frame = GetFrame();
+ if (frame && frame->GetType() == nsGkAtoms::inlineFrame)
+ return roles::TEXT;
- return roles::TEXT_CONTAINER; // In ATK this works
+ return roles::TEXT_CONTAINER;
}
uint64_t
HyperTextAccessible::NativeState()
{
uint64_t states = AccessibleWrap::NativeState();
if (mContent->AsElement()->State().HasState(NS_EVENT_STATE_MOZ_READWRITE)) {
--- a/accessible/interfaces/msaa/moz.build
+++ b/accessible/interfaces/msaa/moz.build
@@ -1,24 +1,24 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
GeckoSharedLibrary('AccessibleMarshal', linkage=None)
-GENERATED_SOURCES += [
- 'dlldata.c',
- 'ISimpleDOMDocument_i.c',
- 'ISimpleDOMDocument_p.c',
- 'ISimpleDOMNode_i.c',
- 'ISimpleDOMNode_p.c',
- 'ISimpleDOMText_i.c',
- 'ISimpleDOMText_p.c',
+SOURCES += [
+ '!dlldata.c',
+ '!ISimpleDOMDocument_i.c',
+ '!ISimpleDOMDocument_p.c',
+ '!ISimpleDOMNode_i.c',
+ '!ISimpleDOMNode_p.c',
+ '!ISimpleDOMText_i.c',
+ '!ISimpleDOMText_p.c',
]
DEFINES['REGISTER_PROXY_DLL'] = True
DEFFILE = SRCDIR + '/AccessibleMarshal.def'
OS_LIBS += [
'kernel32',
--- a/accessible/interfaces/nsIAccessibleRole.idl
+++ b/accessible/interfaces/nsIAccessibleRole.idl
@@ -3,17 +3,17 @@
* 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 "nsISupports.idl"
/**
* Defines cross platform (Gecko) roles.
*/
-[scriptable, uuid(00f9e831-3198-40b7-9186-5251474d4d7a)]
+[scriptable, uuid(94add87a-190c-443e-9549-d11131affb2a)]
interface nsIAccessibleRole : nsISupports
{
/**
* Used when accessible hans't strong defined role.
*/
const unsigned long ROLE_NOTHING = 0;
/**
@@ -969,9 +969,15 @@ interface nsIAccessibleRole : nsISupport
* A MathML line in a stack (msline in MathML).
*/
const unsigned long ROLE_MATHML_STACK_LINE = 167;
/**
* A group containing radio buttons
*/
const unsigned long ROLE_RADIO_GROUP = 168;
+
+ /**
+ * A text container exposing brief amount of information. See related
+ * TEXT_CONTAINER role.
+ */
+ const unsigned long ROLE_TEXT = 169;
};
--- a/accessible/ipc/DocAccessibleParent.cpp
+++ b/accessible/ipc/DocAccessibleParent.cpp
@@ -18,24 +18,17 @@ DocAccessibleParent::RecvShowEvent(const
if (mShutdown)
return true;
if (aData.NewTree().IsEmpty()) {
NS_ERROR("no children being added");
return false;
}
- ProxyAccessible* parent = nullptr;
- if (aData.ID()) {
- ProxyEntry* e = mAccessibles.GetEntry(aData.ID());
- if (e)
- parent = e->mProxy;
- } else {
- parent = this;
- }
+ ProxyAccessible* parent = GetAccessible(aData.ID());
// XXX This should really never happen, but sometimes we fail to fire the
// required show events.
if (!parent) {
NS_ERROR("adding child to unknown accessible");
return false;
}
@@ -118,28 +111,47 @@ DocAccessibleParent::RecvHideEvent(const
root->Shutdown();
return true;
}
bool
DocAccessibleParent::RecvEvent(const uint64_t& aID, const uint32_t& aEventType)
{
- if (!aID) {
- ProxyEvent(this, aEventType);
- return true;
- }
-
- ProxyEntry* e = mAccessibles.GetEntry(aID);
- if (!e) {
+ ProxyAccessible* proxy = GetAccessible(aID);
+ if (!proxy) {
NS_ERROR("no proxy for event!");
return true;
}
- ProxyEvent(e->mProxy, aEventType);
+ ProxyEvent(proxy, aEventType);
+ return true;
+}
+
+bool
+DocAccessibleParent::RecvStateChangeEvent(const uint64_t& aID,
+ const uint64_t& aState,
+ const bool& aEnabled)
+{
+ ProxyAccessible* target = GetAccessible(aID);
+ if (!target)
+ return false;
+
+ ProxyStateChangeEvent(target, aState, aEnabled);
+ return true;
+}
+
+bool
+DocAccessibleParent::RecvCaretMoveEvent(const uint64_t& aID, const int32_t& aOffset)
+{
+ ProxyAccessible* proxy = GetAccessible(aID);
+ if (!proxy)
+ return false;
+
+ ProxyCaretMoveEvent(proxy, aOffset);
return true;
}
bool
DocAccessibleParent::RecvBindChildDoc(PDocAccessibleParent* aChildDoc, const uint64_t& aID)
{
auto childDoc = static_cast<DocAccessibleParent*>(aChildDoc);
DebugOnly<bool> result = AddChildDoc(childDoc, aID, false);
--- a/accessible/ipc/DocAccessibleParent.h
+++ b/accessible/ipc/DocAccessibleParent.h
@@ -27,84 +27,96 @@ class DocAccessibleParent : public Proxy
public:
DocAccessibleParent() :
ProxyAccessible(this), mParentDoc(nullptr), mShutdown(false)
{ MOZ_COUNT_CTOR_INHERITED(DocAccessibleParent, ProxyAccessible); }
~DocAccessibleParent()
{
MOZ_COUNT_DTOR_INHERITED(DocAccessibleParent, ProxyAccessible);
MOZ_ASSERT(mChildDocs.Length() == 0);
- MOZ_ASSERT(!mParentDoc);
+ MOZ_ASSERT(!ParentDoc());
}
/*
* Called when a message from a document in a child process notifies the main
* process it is firing an event.
*/
virtual bool RecvEvent(const uint64_t& aID, const uint32_t& aType)
override;
virtual bool RecvShowEvent(const ShowEventData& aData) override;
virtual bool RecvHideEvent(const uint64_t& aRootID) override;
+ virtual bool RecvStateChangeEvent(const uint64_t& aID,
+ const uint64_t& aState,
+ const bool& aEnabled) override final;
+
+ virtual bool RecvCaretMoveEvent(const uint64_t& aID, const int32_t& aOffset)
+ override final;
virtual bool RecvBindChildDoc(PDocAccessibleParent* aChildDoc, const uint64_t& aID) override;
void Unbind()
{
mParent = nullptr;
- mParentDoc->mChildDocs.RemoveElement(this);
+ ParentDoc()->mChildDocs.RemoveElement(this);
mParentDoc = nullptr;
}
void Destroy();
virtual void ActorDestroy(ActorDestroyReason aWhy) override
{
if (!mShutdown)
Destroy();
}
/*
* Return the main processes representation of the parent document (if any)
* of the document this object represents.
*/
- DocAccessibleParent* Parent() const { return mParentDoc; }
+ DocAccessibleParent* ParentDoc() const { return mParentDoc; }
/*
* Called when a document in a content process notifies the main process of a
* new child document.
*/
bool AddChildDoc(DocAccessibleParent* aChildDoc, uint64_t aParentID,
bool aCreating = true);
/*
* Called when the document in the content process this object represents
* notifies the main process a child document has been removed.
*/
void RemoveChildDoc(DocAccessibleParent* aChildDoc)
{
- aChildDoc->mParent->SetChildDoc(nullptr);
+ aChildDoc->Parent()->SetChildDoc(nullptr);
mChildDocs.RemoveElement(aChildDoc);
aChildDoc->mParentDoc = nullptr;
MOZ_ASSERT(aChildDoc->mChildDocs.Length() == 0);
}
void RemoveAccessible(ProxyAccessible* aAccessible)
{
MOZ_ASSERT(mAccessibles.GetEntry(aAccessible->ID()));
mAccessibles.RemoveEntry(aAccessible->ID());
}
/**
* Return the accessible for given id.
*/
- ProxyAccessible* GetAccessible(uintptr_t aID) const
+ ProxyAccessible* GetAccessible(uintptr_t aID)
{
+ if (!aID)
+ return this;
+
ProxyEntry* e = mAccessibles.GetEntry(aID);
return e ? e->mProxy : nullptr;
}
+ const ProxyAccessible* GetAccessible(uintptr_t aID) const
+ { return const_cast<DocAccessibleParent*>(this)->GetAccessible(aID); }
+
private:
class ProxyEntry : public PLDHashEntryHdr
{
public:
explicit ProxyEntry(const void*) : mProxy(nullptr) {}
ProxyEntry(ProxyEntry&& aOther) :
mProxy(aOther.mProxy) { aOther.mProxy = nullptr; }
--- a/accessible/ipc/PDocAccessible.ipdl
+++ b/accessible/ipc/PDocAccessible.ipdl
@@ -1,15 +1,16 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
-include protocol PContent;
+include protocol PFileDescriptorSet;
+include protocol PBrowser;
include "mozilla/GfxMessageUtils.h";
using nsIntRect from "nsRect.h";
using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
using mozilla::gfx::IntPoint from "mozilla/gfx/Point.h";
namespace mozilla {
@@ -39,28 +40,30 @@ struct Attribute
struct RelationTargets
{
uint32_t Type;
uint64_t[] Targets;
};
prio(normal upto high) sync protocol PDocAccessible
{
- manager PContent;
+ manager PBrowser;
parent:
__delete__();
/*
* Notify the parent process the document in the child process is firing an
* event.
*/
Event(uint64_t aID, uint32_t type);
ShowEvent(ShowEventData data);
HideEvent(uint64_t aRootID);
+ StateChangeEvent(uint64_t aID, uint64_t aState, bool aEnabled);
+ CaretMoveEvent(uint64_t aID, int32_t aOffset);
/*
* Tell the parent document to bind the existing document as a new child
* document.
*/
BindChildDoc(PDocAccessible aChildDoc, uint64_t aID);
child:
--- a/accessible/ipc/ProxyAccessible.cpp
+++ b/accessible/ipc/ProxyAccessible.cpp
@@ -1,16 +1,20 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
#include "ProxyAccessible.h"
#include "DocAccessibleParent.h"
+#include "DocAccessible.h"
+#include "mozilla/a11y/DocManager.h"
+#include "mozilla/dom/Element.h"
+#include "mozilla/dom/TabParent.h"
#include "mozilla/unused.h"
#include "mozilla/a11y/Platform.h"
#include "RelationType.h"
#include "mozilla/a11y/Role.h"
namespace mozilla {
namespace a11y {
@@ -958,10 +962,24 @@ ProxyAccessible::MimeType(nsString aMime
void
ProxyAccessible::URLDocTypeMimeType(nsString& aURL, nsString& aDocType,
nsString& aMimeType)
{
unused << mDoc->SendURLDocTypeMimeType(mID, &aURL, &aDocType, &aMimeType);
}
+Accessible*
+ProxyAccessible::OuterDocOfRemoteBrowser() const
+{
+ auto tab = static_cast<dom::TabParent*>(mDoc->Manager());
+ dom::Element* frame = tab->GetOwnerElement();
+ NS_ASSERTION(frame, "why isn't the tab in a frame!");
+ if (!frame)
+ return nullptr;
+
+ DocAccessible* chromeDoc = GetExistingDocAccessible(frame->OwnerDoc());
+ NS_ASSERTION(chromeDoc, "accessible tab in not accessible chromeDocument");
+
+ return chromeDoc ? chromeDoc->GetAccessible(frame) : nullptr;
}
}
+}
--- a/accessible/ipc/ProxyAccessible.h
+++ b/accessible/ipc/ProxyAccessible.h
@@ -13,16 +13,17 @@
#include "nsString.h"
#include "nsTArray.h"
#include "nsRect.h"
#include "Accessible.h"
namespace mozilla {
namespace a11y {
+class Accessible;
class Attribute;
class DocAccessibleParent;
enum class RelationType;
class ProxyAccessible
{
public:
@@ -41,17 +42,17 @@ public:
void AddChildAt(uint32_t aIdx, ProxyAccessible* aChild)
{ mChildren.InsertElementAt(aIdx, aChild); }
uint32_t ChildrenCount() const { return mChildren.Length(); }
ProxyAccessible* ChildAt(uint32_t aIdx) const { return mChildren[aIdx]; }
// XXX evaluate if this is fast enough.
- size_t IndexInParent() const { return mParent->mChildren.IndexOf(this); }
+ size_t IndexInParent() const { return Parent()->mChildren.IndexOf(this); }
int32_t IndexOfEmbeddedChild(const ProxyAccessible*);
bool MustPruneChildren() const;
void Shutdown();
void SetChildDoc(DocAccessibleParent*);
/**
@@ -60,16 +61,18 @@ public:
void RemoveChild(ProxyAccessible* aChild)
{ mChildren.RemoveElement(aChild); }
/**
* Return the proxy for the parent of the wrapped accessible.
*/
ProxyAccessible* Parent() const { return mParent; }
+ Accessible* OuterDocOfRemoteBrowser() const;
+
/**
* Get the role of the accessible we're proxying.
*/
role Role() const { return mRole; }
/*
* Return the states for the proxied accessible.
*/
--- a/accessible/jsat/AccessFu.jsm
+++ b/accessible/jsat/AccessFu.jsm
@@ -412,24 +412,16 @@ this.AccessFu = { // jshint ignore:line
function(aJsonBounds, aBrowser, aToCSSPixels) {
let bounds = new Rect(aJsonBounds.left, aJsonBounds.top,
aJsonBounds.right - aJsonBounds.left,
aJsonBounds.bottom - aJsonBounds.top);
let win = Utils.win;
let dpr = win.devicePixelRatio;
let offset = { left: -win.mozInnerScreenX, top: -win.mozInnerScreenY };
- if (!aBrowser.contentWindow) {
- // OOP browser, add offset of browser.
- // The offset of the browser element in relation to its parent window.
- let clientRect = aBrowser.getBoundingClientRect();
- let win = aBrowser.ownerDocument.defaultView;
- offset.left += clientRect.left + win.mozInnerScreenX;
- offset.top += clientRect.top + win.mozInnerScreenY;
- }
// Add the offset; the offset is in CSS pixels, so multiply the
// devicePixelRatio back in before adding to preserve unit consistency.
bounds = bounds.translate(offset.left * dpr, offset.top * dpr);
// If we want to get to CSS pixels from device pixels, this needs to be
// further divided by the devicePixelRatio due to widget scaling.
if (aToCSSPixels) {
bounds = bounds.scale(1 / dpr, 1 / dpr);
--- a/accessible/jsat/EventManager.jsm
+++ b/accessible/jsat/EventManager.jsm
@@ -169,20 +169,27 @@ this.EventManager.prototype = {
break;
}
case Events.STATE_CHANGE:
{
let event = aEvent.QueryInterface(Ci.nsIAccessibleStateChangeEvent);
let state = Utils.getState(event);
if (state.contains(States.CHECKED)) {
- this.present(
- Presentation.
- actionInvoked(aEvent.accessible,
- event.isEnabled ? 'check' : 'uncheck'));
+ if (aEvent.accessible.role === Roles.SWITCH) {
+ this.present(
+ Presentation.
+ actionInvoked(aEvent.accessible,
+ event.isEnabled ? 'on' : 'off'));
+ } else {
+ this.present(
+ Presentation.
+ actionInvoked(aEvent.accessible,
+ event.isEnabled ? 'check' : 'uncheck'));
+ }
} else if (state.contains(States.SELECTED)) {
this.present(
Presentation.
actionInvoked(aEvent.accessible,
event.isEnabled ? 'select' : 'unselect'));
}
break;
}
--- a/accessible/jsat/OutputGenerator.jsm
+++ b/accessible/jsat/OutputGenerator.jsm
@@ -205,17 +205,17 @@ let OutputGenerator = {
let typeName = Utils.getAttributes(aAccessible)['text-input-type'];
// Ignore the the input type="text" case.
if (!typeName || typeName === 'text') {
return;
}
aOutput.push({string: 'textInputType_' + typeName});
},
- _addState: function _addState(aOutput, aState) {}, // jshint ignore:line
+ _addState: function _addState(aOutput, aState, aRoleStr) {}, // jshint ignore:line
_addRole: function _addRole(aOutput, aRoleStr) {}, // jshint ignore:line
get outputOrder() {
if (!this._utteranceOrder) {
this._utteranceOrder = new PrefCache('accessibility.accessfu.utterance');
}
return typeof this._utteranceOrder.value === 'number' ?
@@ -247,16 +247,17 @@ let OutputGenerator = {
'link': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
'helpballoon': NAME_FROM_SUBTREE_RULE,
'list': INCLUDE_DESC | INCLUDE_NAME,
'listitem': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
'outline': INCLUDE_DESC,
'outlineitem': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
'pagetab': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
'graphic': INCLUDE_DESC,
+ 'switch': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
'pushbutton': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
'checkbutton': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
'radiobutton': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
'buttondropdown': NAME_FROM_SUBTREE_RULE,
'combobox': INCLUDE_DESC | INCLUDE_VALUE,
'droplist': INCLUDE_DESC,
'progressbar': INCLUDE_DESC | INCLUDE_VALUE,
'slider': INCLUDE_DESC | INCLUDE_VALUE,
@@ -302,17 +303,17 @@ let OutputGenerator = {
'app root': IGNORE_EXPLICIT_NAME },
objectOutputFunctions: {
_generateBaseOutput:
function _generateBaseOutput(aAccessible, aRoleStr, aState, aFlags) {
let output = [];
if (aFlags & INCLUDE_DESC) {
- this._addState(output, aState);
+ this._addState(output, aState, aRoleStr);
this._addType(output, aAccessible, aRoleStr);
this._addRole(output, aRoleStr);
}
if (aFlags & INCLUDE_VALUE && aAccessible.value.trim()) {
output[this.outputOrder === OUTPUT_DESC_FIRST ? 'push' : 'unshift'](
aAccessible.value);
}
@@ -408,23 +409,25 @@ let OutputGenerator = {
*
* An utterance is ordered from the least to the most important. Speaking the
* last string usually makes sense, but speaking the first often won't.
* For example {@link genForAction} might return ['button', 'clicked'] for a
* clicked event. Speaking only 'clicked' makes sense. Speaking 'button' does
* not.
*/
this.UtteranceGenerator = { // jshint ignore:line
- __proto__: OutputGenerator,
+ __proto__: OutputGenerator, // jshint ignore:line
gActionMap: {
jump: 'jumpAction',
press: 'pressAction',
check: 'checkAction',
uncheck: 'uncheckAction',
+ on: 'onAction',
+ off: 'offAction',
select: 'selectAction',
unselect: 'unselectAction',
open: 'openAction',
close: 'closeAction',
switch: 'switchAction',
click: 'clickAction',
collapse: 'collapseAction',
expand: 'expandAction',
@@ -470,17 +473,17 @@ this.UtteranceGenerator = { // jshint i
},
genForEditingMode: function genForEditingMode(aIsEditing) {
return [{string: aIsEditing ? 'editingMode' : 'navigationMode'}];
},
objectOutputFunctions: {
- __proto__: OutputGenerator.objectOutputFunctions,
+ __proto__: OutputGenerator.objectOutputFunctions, // jshint ignore:line
defaultFunc: function defaultFunc() {
return this.objectOutputFunctions._generateBaseOutput.apply(
this, arguments);
},
heading: function heading(aAccessible, aRoleStr, aState, aFlags) {
let level = {};
@@ -592,34 +595,39 @@ this.UtteranceGenerator = { // jshint i
_getContextStart: function _getContextStart(aContext) {
return aContext.newAncestry;
},
_addRole: function _addRole(aOutput, aRoleStr) {
aOutput.push({string: this._getOutputName(aRoleStr)});
},
- _addState: function _addState(aOutput, aState) {
+ _addState: function _addState(aOutput, aState, aRoleStr) {
if (aState.contains(States.UNAVAILABLE)) {
aOutput.push({string: 'stateUnavailable'});
}
if (aState.contains(States.READONLY)) {
aOutput.push({string: 'stateReadonly'});
}
// Don't utter this in Jelly Bean, we let TalkBack do it for us there.
// This is because we expose the checked information on the node itself.
// XXX: this means the checked state is always appended to the end,
// regardless of the utterance ordering preference.
if ((Utils.AndroidSdkVersion < 16 || Utils.MozBuildApp === 'browser') &&
aState.contains(States.CHECKABLE)) {
- let statetr = aState.contains(States.CHECKED) ?
- 'stateChecked' : 'stateNotChecked';
+ let checked = aState.contains(States.CHECKED);
+ let statetr;
+ if (aRoleStr === 'switch') {
+ statetr = checked ? 'stateOn' : 'stateOff';
+ } else {
+ statetr = checked ? 'stateChecked' : 'stateNotChecked';
+ }
aOutput.push({string: statetr});
}
if (aState.contains(States.PRESSED)) {
aOutput.push({string: 'statePressed'});
}
if (aState.contains(States.EXPANDABLE)) {
@@ -657,17 +665,17 @@ this.UtteranceGenerator = { // jshint i
this._addName(utterance, aAccessible, aFlags);
this._addLandmark(utterance, aAccessible);
return utterance;
}
};
this.BrailleGenerator = { // jshint ignore:line
- __proto__: OutputGenerator,
+ __proto__: OutputGenerator, // jshint ignore:line
genForContext: function genForContext(aContext) {
let output = OutputGenerator.genForContext.apply(this, arguments);
let acc = aContext.accessible;
// add the static text indicating a list item; do this for both listitems or
// direct first children of listitems, because these are both common
@@ -694,17 +702,17 @@ this.BrailleGenerator = { // jshint ign
}
}
return output;
},
objectOutputFunctions: {
- __proto__: OutputGenerator.objectOutputFunctions,
+ __proto__: OutputGenerator.objectOutputFunctions, // jshint ignore:line
defaultFunc: function defaultFunc() {
return this.objectOutputFunctions._generateBaseOutput.apply(
this, arguments);
},
listitem: function listitem(aAccessible, aRoleStr, aState, aFlags) {
let braille = [];
@@ -755,23 +763,27 @@ this.BrailleGenerator = { // jshint ign
}
return this.objectOutputFunctions._useStateNotRole.apply(this, arguments);
},
_useStateNotRole:
function _useStateNotRole(aAccessible, aRoleStr, aState, aFlags) {
let braille = [];
- this._addState(braille, aState, aAccessible.role);
+ this._addState(braille, aState, aRoleStr);
this._addName(braille, aAccessible, aFlags);
this._addLandmark(braille, aAccessible);
return braille;
},
+ switch: function braille_generator_object_output_functions_switch() {
+ return this.objectOutputFunctions._useStateNotRole.apply(this, arguments);
+ },
+
checkbutton: function checkbutton() {
return this.objectOutputFunctions._useStateNotRole.apply(this, arguments);
},
radiobutton: function radiobutton() {
return this.objectOutputFunctions._useStateNotRole.apply(this, arguments);
},
@@ -791,25 +803,25 @@ this.BrailleGenerator = { // jshint ign
_getOutputName: function _getOutputName(aName) {
return OutputGenerator._getOutputName(aName) + 'Abbr';
},
_addRole: function _addRole(aBraille, aRoleStr) {
aBraille.push({string: this._getOutputName(aRoleStr)});
},
- _addState: function _addState(aBraille, aState, aRole) {
+ _addState: function _addState(aBraille, aState, aRoleStr) {
if (aState.contains(States.CHECKABLE)) {
aBraille.push({
string: aState.contains(States.CHECKED) ?
this._getOutputName('stateChecked') :
this._getOutputName('stateUnchecked')
});
}
- if (aRole === Roles.TOGGLE_BUTTON) {
+ if (aRoleStr === 'toggle button') {
aBraille.push({
string: aState.contains(States.PRESSED) ?
this._getOutputName('statePressed') :
this._getOutputName('stateUnpressed')
});
}
}
};
--- a/accessible/jsat/TraversalRules.jsm
+++ b/accessible/jsat/TraversalRules.jsm
@@ -1,22 +1,20 @@
/* 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/. */
/* global PrefCache, Roles, Prefilters, States, Filters, Utils,
- TraversalRules */
+ TraversalRules, Components, XPCOMUtils */
/* exported TraversalRules */
'use strict';
-const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
-const Cr = Components.results;
this.EXPORTED_SYMBOLS = ['TraversalRules']; // jshint ignore:line
Cu.import('resource://gre/modules/accessibility/Utils.jsm');
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'Roles', // jshint ignore:line
'resource://gre/modules/accessibility/Constants.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'Filters', // jshint ignore:line
@@ -98,17 +96,18 @@ var gSimpleTraversalRoles =
Roles.HEADING,
Roles.SLIDER,
Roles.SPINBUTTON,
Roles.OPTION,
Roles.LISTITEM,
Roles.GRID_CELL,
Roles.COLUMNHEADER,
Roles.ROWHEADER,
- Roles.STATUSBAR];
+ Roles.STATUSBAR,
+ Roles.SWITCH];
var gSimpleMatchFunc = function gSimpleMatchFunc(aAccessible) {
// An object is simple, if it either has a single child lineage,
// or has a flat subtree.
function isSingleLineage(acc) {
for (let child = acc; child; child = child.firstChild) {
if (Utils.visibleChildCount(child) > 1) {
return false;
@@ -235,17 +234,18 @@ this.TraversalRules = { // jshint ignore
Roles.LISTBOX,
Roles.ENTRY,
Roles.PASSWORD_TEXT,
Roles.PAGETAB,
Roles.RADIOBUTTON,
Roles.RADIO_MENU_ITEM,
Roles.SLIDER,
Roles.CHECKBUTTON,
- Roles.CHECK_MENU_ITEM]),
+ Roles.CHECK_MENU_ITEM,
+ Roles.SWITCH]),
Graphic: new BaseTraversalRule(
[Roles.GRAPHIC],
function Graphic_match(aAccessible) {
return TraversalRules._shouldSkipImage(aAccessible);
}),
Heading: new BaseTraversalRule(
@@ -297,17 +297,18 @@ this.TraversalRules = { // jshint ignore
Separator: new BaseTraversalRule(
[Roles.SEPARATOR]),
Table: new BaseTraversalRule(
[Roles.TABLE]),
Checkbox: new BaseTraversalRule(
[Roles.CHECKBUTTON,
- Roles.CHECK_MENU_ITEM]),
+ Roles.CHECK_MENU_ITEM,
+ Roles.SWITCH /* A type of checkbox that represents on/off values */]),
_shouldSkipImage: function _shouldSkipImage(aAccessible) {
if (gSkipEmptyImages.value && aAccessible.name === '') {
return Filters.IGNORE;
}
return Filters.MATCH;
}
};
--- a/accessible/mac/AccessibleWrap.h
+++ b/accessible/mac/AccessibleWrap.h
@@ -54,20 +54,17 @@ public: // construction, destruction
virtual nsresult HandleAccEvent(AccEvent* aEvent) override;
/**
* Ignored means that the accessible might still have children, but is not
* displayed to the user. it also has no native accessible object represented
* for it.
*/
bool IsIgnored();
-
- inline bool HasPopup ()
- { return (NativeState() & mozilla::a11y::states::HASPOPUP); }
-
+
/**
* Returns this accessible's all children, adhering to "flat" accessibles by
* not returning their children.
*/
void GetUnignoredChildren(nsTArray<Accessible*>* aChildrenArray);
Accessible* GetUnignoredParent() const;
protected:
@@ -103,12 +100,14 @@ private:
/**
* We have created our native. This does not mean there is one.
* This can never go back to false.
* We need it because checking whether we need a native object cost time.
*/
bool mNativeInited;
};
+Class GetTypeFromRole(roles::Role aRole);
+
} // namespace a11y
} // namespace mozilla
#endif
--- a/accessible/mac/AccessibleWrap.mm
+++ b/accessible/mac/AccessibleWrap.mm
@@ -10,16 +10,17 @@
#include "nsAccUtils.h"
#include "Role.h"
#import "mozAccessible.h"
#import "mozActionElements.h"
#import "mozHTMLAccessible.h"
#import "mozTextAccessible.h"
+using namespace mozilla;
using namespace mozilla::a11y;
AccessibleWrap::
AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc) :
Accessible(aContent, aDoc), mNativeObject(nil),
mNativeInited(false)
{
}
@@ -28,18 +29,20 @@ AccessibleWrap::~AccessibleWrap()
{
}
mozAccessible*
AccessibleWrap::GetNativeObject()
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
- if (!mNativeInited && !mNativeObject && !IsDefunct() && !AncestorIsFlat())
- mNativeObject = [[GetNativeType() alloc] initWithAccessible:this];
+ if (!mNativeInited && !mNativeObject && !IsDefunct() && !AncestorIsFlat()) {
+ uintptr_t accWrap = reinterpret_cast<uintptr_t>(this);
+ mNativeObject = [[GetNativeType() alloc] initWithAccessible:accWrap];
+ }
mNativeInited = true;
return mNativeObject;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
@@ -54,61 +57,17 @@ AccessibleWrap::GetNativeInterface(void*
Class
AccessibleWrap::GetNativeType ()
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if (IsXULTabpanels())
return [mozPaneAccessible class];
- roles::Role role = Role();
- switch (role) {
- case roles::PUSHBUTTON:
- case roles::SPLITBUTTON:
- case roles::TOGGLE_BUTTON:
- {
- // if this button may show a popup, let's make it of the popupbutton type.
- return HasPopup() ? [mozPopupButtonAccessible class] :
- [mozButtonAccessible class];
- }
-
- case roles::PAGETAB:
- return [mozButtonAccessible class];
-
- case roles::CHECKBUTTON:
- return [mozCheckboxAccessible class];
-
- case roles::HEADING:
- return [mozHeadingAccessible class];
-
- case roles::PAGETABLIST:
- return [mozTabsAccessible class];
-
- case roles::ENTRY:
- case roles::STATICTEXT:
- case roles::CAPTION:
- case roles::ACCEL_LABEL:
- case roles::PASSWORD_TEXT:
- // normal textfield (static or editable)
- return [mozTextAccessible class];
-
- case roles::TEXT_LEAF:
- return [mozTextLeafAccessible class];
-
- case roles::LINK:
- return [mozLinkAccessible class];
-
- case roles::COMBOBOX:
- return [mozPopupButtonAccessible class];
-
- default:
- return [mozAccessible class];
- }
-
- return nil;
+ return GetTypeFromRole(Role());
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
// this method is very important. it is fired when an accessible object "dies". after this point
// the object might still be around (because some 3rd party still has a ref to it), but it is
// in fact 'dead'.
void
@@ -269,8 +228,57 @@ AccessibleWrap::AncestorIsFlat()
if (nsAccUtils::MustPrune(parent))
return true;
parent = parent->Parent();
}
// no parent was flat
return false;
}
+
+Class
+a11y::GetTypeFromRole(roles::Role aRole)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
+
+ switch (aRole) {
+ case roles::COMBOBOX:
+ case roles::PUSHBUTTON:
+ case roles::SPLITBUTTON:
+ case roles::TOGGLE_BUTTON:
+ {
+ return [mozButtonAccessible class];
+ }
+
+ case roles::PAGETAB:
+ return [mozButtonAccessible class];
+
+ case roles::CHECKBUTTON:
+ return [mozCheckboxAccessible class];
+
+ case roles::HEADING:
+ return [mozHeadingAccessible class];
+
+ case roles::PAGETABLIST:
+ return [mozTabsAccessible class];
+
+ case roles::ENTRY:
+ case roles::STATICTEXT:
+ case roles::CAPTION:
+ case roles::ACCEL_LABEL:
+ case roles::PASSWORD_TEXT:
+ // normal textfield (static or editable)
+ return [mozTextAccessible class];
+
+ case roles::TEXT_LEAF:
+ return [mozTextLeafAccessible class];
+
+ case roles::LINK:
+ return [mozLinkAccessible class];
+
+ default:
+ return [mozAccessible class];
+ }
+
+ return nil;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
+}
--- a/accessible/mac/Platform.mm
+++ b/accessible/mac/Platform.mm
@@ -2,16 +2,17 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
#import <Cocoa/Cocoa.h>
#include "Platform.h"
+#include "ProxyAccessible.h"
#include "nsAppShell.h"
namespace mozilla {
namespace a11y {
// Mac a11y whitelisting
static bool sA11yShouldBeEnabled = false;
@@ -29,27 +30,47 @@ PlatformInit()
}
void
PlatformShutdown()
{
}
void
-ProxyCreated(ProxyAccessible*, uint32_t)
+ProxyCreated(ProxyAccessible* aProxy, uint32_t)
+{
+ // Pass in dummy state for now as retrieving proxy state requires IPC.
+ Class type = GetTypeFromRole(aProxy->Role());
+ uintptr_t accWrap = reinterpret_cast<uintptr_t>(aProxy) | IS_PROXY;
+ mozAccessible* mozWrapper = [[type alloc] initWithAccessible:accWrap];
+ aProxy->SetWrapper(reinterpret_cast<uintptr_t>(mozWrapper));
+}
+
+void
+ProxyDestroyed(ProxyAccessible* aProxy)
+{
+ mozAccessible* wrapper =
+ reinterpret_cast<mozAccessible*>(aProxy->GetWrapper());
+ [wrapper expire];
+ [wrapper release];
+ aProxy->SetWrapper(0);
+}
+
+void
+ProxyEvent(ProxyAccessible*, uint32_t)
{
}
void
-ProxyDestroyed(ProxyAccessible*)
+ProxyStateChangeEvent(ProxyAccessible*, uint64_t, bool)
{
}
void
-ProxyEvent(ProxyAccessible*, uint32_t)
+ProxyCaretMoveEvent(ProxyAccessible* aTarget, int32_t aOffset)
{
}
}
}
@interface GeckoNSApplication(a11y)
-(void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute;
@end
--- a/accessible/mac/moz.build
+++ b/accessible/mac/moz.build
@@ -25,16 +25,17 @@ UNIFIED_SOURCES += [
'Platform.mm',
'RootAccessibleWrap.mm',
]
LOCAL_INCLUDES += [
'/accessible/base',
'/accessible/generic',
'/accessible/html',
+ '/accessible/ipc',
'/accessible/xul',
'/layout/generic',
'/layout/xul',
'/widget',
'/widget/cocoa',
]
FINAL_LIBRARY = 'xul'
--- a/accessible/mac/mozAccessible.h
+++ b/accessible/mac/mozAccessible.h
@@ -26,22 +26,25 @@ GetObjectOrRepresentedView(id <mozAccess
inline mozAccessible*
GetNativeFromGeckoAccessible(mozilla::a11y::Accessible* aAccessible)
{
mozAccessible* native = nil;
aAccessible->GetNativeInterface((void**)&native);
return native;
}
+// This is OR'd with the Accessible owner to indicate the wrap-ee is a proxy.
+static const uintptr_t IS_PROXY = 1;
+
@interface mozAccessible : NSObject <mozAccessible>
{
/**
* Weak reference; it owns us.
*/
- mozilla::a11y::AccessibleWrap* mGeckoAccessible;
+ uintptr_t mGeckoAccessible;
/**
* Strong ref to array of children
*/
NSMutableArray* mChildren;
/**
* Weak reference to the parent
@@ -49,18 +52,24 @@ GetNativeFromGeckoAccessible(mozilla::a1
mozAccessible* mParent;
/**
* The role of our gecko accessible.
*/
mozilla::a11y::role mRole;
}
+// return the Accessible for this mozAccessible if it exists.
+- (mozilla::a11y::AccessibleWrap*)getGeckoAccessible;
+
+// return the ProxyAccessible for this mozAccessible if it exists.
+- (mozilla::a11y::ProxyAccessible*)getProxyAccessible;
+
// inits with the gecko owner.
-- (id)initWithAccessible:(mozilla::a11y::AccessibleWrap*)geckoParent;
+- (id)initWithAccessible:(uintptr_t)aGeckoObj;
// our accessible parent (AXParent)
- (id <mozAccessible>)parent;
// a lazy cache of our accessible children (AXChildren). updated
- (NSArray*)children;
// returns the size of this accessible.
--- a/accessible/mac/mozAccessible.mm
+++ b/accessible/mac/mozAccessible.mm
@@ -55,60 +55,83 @@ GetClosestInterestingAccessible(id anObj
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
#pragma mark -
@implementation mozAccessible
-- (id)initWithAccessible:(AccessibleWrap*)geckoAccessible
+- (id)initWithAccessible:(uintptr_t)aGeckoAccessible
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if ((self = [super init])) {
- mGeckoAccessible = geckoAccessible;
- mRole = geckoAccessible->Role();
+ mGeckoAccessible = aGeckoAccessible;
+ if (aGeckoAccessible & IS_PROXY)
+ mRole = [self getProxyAccessible]->Role();
+ else
+ mRole = [self getGeckoAccessible]->Role();
}
-
+
return self;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (void)dealloc
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
[mChildren release];
[super dealloc];
NS_OBJC_END_TRY_ABORT_BLOCK;
}
+
+- (mozilla::a11y::AccessibleWrap*)getGeckoAccessible
+{
+ // Check if mGeckoAccessible points at a proxy
+ if (mGeckoAccessible & IS_PROXY)
+ return nil;
+
+ return reinterpret_cast<AccessibleWrap*>(mGeckoAccessible);
+}
+
+- (mozilla::a11y::ProxyAccessible*)getProxyAccessible
+{
+ // Check if mGeckoAccessible points at a proxy
+ if (!(mGeckoAccessible & IS_PROXY))
+ return nil;
+
+ return reinterpret_cast<ProxyAccessible*>(mGeckoAccessible & ~IS_PROXY);
+}
#pragma mark -
- (BOOL)accessibilityIsIgnored
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
// unknown (either unimplemented, or irrelevant) elements are marked as ignored
// as well as expired elements.
- return !mGeckoAccessible || ([[self role] isEqualToString:NSAccessibilityUnknownRole] &&
- !(mGeckoAccessible->InteractiveState() & states::FOCUSABLE));
+
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ return !accWrap || ([[self role] isEqualToString:NSAccessibilityUnknownRole] &&
+ !(accWrap->InteractiveState() & states::FOCUSABLE));
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
}
- (NSArray*)accessibilityAttributeNames
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
// if we're expired, we don't support any attributes.
- if (!mGeckoAccessible)
+ if (![self getGeckoAccessible])
return [NSArray array];
static NSArray *generalAttributes = nil;
if (!generalAttributes) {
// standard attributes that are shared and supported by all generic elements.
generalAttributes = [[NSArray alloc] initWithObjects: NSAccessibilityChildrenAttribute,
NSAccessibilityParentAttribute,
@@ -136,17 +159,17 @@ GetClosestInterestingAccessible(id anObj
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (id)accessibilityAttributeValue:(NSString*)attribute
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
- if (!mGeckoAccessible)
+ if (![self getGeckoAccessible])
return nil;
#if DEBUG
if ([attribute isEqualToString:@"AXMozDescription"])
return [NSString stringWithFormat:@"role = %u native = %@", mRole, [self class]];
#endif
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
@@ -178,17 +201,18 @@ GetClosestInterestingAccessible(id anObj
return [self size];
if ([attribute isEqualToString:NSAccessibilityWindowAttribute])
return [self window];
if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute])
return [self window];
if ([attribute isEqualToString:NSAccessibilityTitleAttribute])
return [self title];
if ([attribute isEqualToString:NSAccessibilityTitleUIElementAttribute]) {
- Relation rel = mGeckoAccessible->RelationByType(RelationType::LABELLED_BY);
+ Relation rel =
+ [self getGeckoAccessible]->RelationByType(RelationType::LABELLED_BY);
Accessible* tempAcc = rel.Next();
return tempAcc ? GetNativeFromGeckoAccessible(tempAcc) : nil;
}
if ([attribute isEqualToString:NSAccessibilityHelpAttribute])
return [self help];
#ifdef DEBUG
NSLog (@"!!! %@ can't respond to attribute %@", self, attribute);
@@ -222,30 +246,32 @@ GetClosestInterestingAccessible(id anObj
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute] && [value boolValue])
[self focus];
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (id)accessibilityHitTest:(NSPoint)point
{
- if (!mGeckoAccessible)
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ if (!accWrap)
return nil;
// Convert the given screen-global point in the cocoa coordinate system (with
// origin in the bottom-left corner of the screen) into point in the Gecko
// coordinate system (with origin in a top-left screen point).
NSScreen* mainView = [[NSScreen screens] objectAtIndex:0];
NSPoint tmpPoint = NSMakePoint(point.x,
[mainView frame].size.height - point.y);
nsIntPoint geckoPoint = nsCocoaUtils::
CocoaPointsToDevPixels(tmpPoint, nsCocoaUtils::GetBackingScaleFactor(mainView));
- Accessible* child = mGeckoAccessible->ChildAtPoint(geckoPoint.x, geckoPoint.y,
- Accessible::eDeepestChild);
+ Accessible* child =
+ accWrap->ChildAtPoint(geckoPoint.x, geckoPoint.y,
+ Accessible::eDeepestChild);
if (child) {
mozAccessible* nativeChild = GetNativeFromGeckoAccessible(child);
if (nativeChild)
return GetClosestInterestingAccessible(nativeChild);
}
// if we didn't find anything, return ourself (or the first unignored ancestor).
@@ -265,50 +291,52 @@ GetClosestInterestingAccessible(id anObj
}
- (void)accessibilityPerformAction:(NSString*)action
{
}
- (id)accessibilityFocusedUIElement
{
- if (!mGeckoAccessible)
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ if (!accWrap)
return nil;
- Accessible* focusedGeckoChild = mGeckoAccessible->FocusedChild();
+ Accessible* focusedGeckoChild = accWrap->FocusedChild();
if (focusedGeckoChild) {
mozAccessible *focusedChild = GetNativeFromGeckoAccessible(focusedGeckoChild);
if (focusedChild)
return GetClosestInterestingAccessible(focusedChild);
}
// return ourself if we can't get a native focused child.
return GetClosestInterestingAccessible(self);
}
#pragma mark -
- (id <mozAccessible>)parent
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
- Accessible* accessibleParent = mGeckoAccessible->GetUnignoredParent();
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ Accessible* accessibleParent = accWrap->GetUnignoredParent();
if (accessibleParent) {
id nativeParent = GetNativeFromGeckoAccessible(accessibleParent);
if (nativeParent)
return GetClosestInterestingAccessible(nativeParent);
}
// GetUnignoredParent() returns null when there is no unignored accessible all the way up to
// the root accessible. so we'll have to return whatever native accessible is above our root accessible
// (which might be the owning NSWindow in the application, for example).
//
// get the native root accessible, and tell it to return its first parent unignored accessible.
id nativeParent =
- GetNativeFromGeckoAccessible(mGeckoAccessible->RootAccessible());
+ GetNativeFromGeckoAccessible(accWrap->RootAccessible());
NSAssert1 (nativeParent, @"!!! we can't find a parent for %@", self);
return GetClosestInterestingAccessible(nativeParent);
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (BOOL)hasRepresentedView
@@ -327,24 +355,25 @@ GetClosestInterestingAccessible(id anObj
}
// gets our native children lazily.
// returns nil when there are no children.
- (NSArray*)children
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
- if (mChildren || !mGeckoAccessible->AreChildrenCached())
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ if (mChildren || !accWrap->AreChildrenCached())
return mChildren;
mChildren = [[NSMutableArray alloc] init];
// get the array of children.
nsAutoTArray<Accessible*, 10> childrenArray;
- mGeckoAccessible->GetUnignoredChildren(&childrenArray);
+ accWrap->GetUnignoredChildren(&childrenArray);
// now iterate through the children array, and get each native accessible.
uint32_t totalCount = childrenArray.Length();
for (uint32_t idx = 0; idx < totalCount; idx++) {
Accessible* curAccessible = childrenArray.ElementAt(idx);
if (curAccessible) {
mozAccessible *curNative = GetNativeFromGeckoAccessible(curAccessible);
if (curNative)
@@ -365,54 +394,57 @@ GetClosestInterestingAccessible(id anObj
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (NSValue*)position
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
- if (!mGeckoAccessible)
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ if (!accWrap)
return nil;
- nsIntRect rect = mGeckoAccessible->Bounds();
+ nsIntRect rect = accWrap->Bounds();
NSScreen* mainView = [[NSScreen screens] objectAtIndex:0];
CGFloat scaleFactor = nsCocoaUtils::GetBackingScaleFactor(mainView);
NSPoint p = NSMakePoint(static_cast<CGFloat>(rect.x) / scaleFactor,
[mainView frame].size.height - static_cast<CGFloat>(rect.y + rect.height) / scaleFactor);
return [NSValue valueWithPoint:p];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (NSValue*)size
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
- if (!mGeckoAccessible)
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ if (!accWrap)
return nil;
- nsIntRect rect = mGeckoAccessible->Bounds();
+ nsIntRect rect = accWrap->Bounds();
CGFloat scaleFactor =
nsCocoaUtils::GetBackingScaleFactor([[NSScreen screens] objectAtIndex:0]);
return [NSValue valueWithSize:NSMakeSize(static_cast<CGFloat>(rect.width) / scaleFactor,
static_cast<CGFloat>(rect.height) / scaleFactor)];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (NSString*)role
{
- if (!mGeckoAccessible)
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ if (!accWrap)
return nil;
#ifdef DEBUG_A11Y
- NS_ASSERTION(nsAccUtils::IsTextInterfaceSupportCorrect(mGeckoAccessible),
+ NS_ASSERTION(nsAccUtils::IsTextInterfaceSupportCorrect(accWrap),
"Does not support Text when it should");
#endif
#define ROLE(geckoRole, stringRole, atkRole, macRole, msaaRole, ia2Role, nameRule) \
case roles::geckoRole: \
return macRole;
switch (mRole) {
@@ -422,20 +454,21 @@ GetClosestInterestingAccessible(id anObj
return NSAccessibilityUnknownRole;
}
#undef ROLE
}
- (NSString*)subrole
{
- if (!mGeckoAccessible)
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ if (!accWrap)
return nil;
- nsIAtom* landmark = mGeckoAccessible->LandmarkRole();
+ nsIAtom* landmark = accWrap->LandmarkRole();
if (landmark) {
if (landmark == nsGkAtoms::application)
return @"AXLandmarkApplication";
if (landmark == nsGkAtoms::banner)
return @"AXLandmarkBanner";
if (landmark == nsGkAtoms::complementary)
return @"AXLandmarkComplementary";
if (landmark == nsGkAtoms::contentinfo)
@@ -452,17 +485,17 @@ GetClosestInterestingAccessible(id anObj
return @"AXSearchField";
}
switch (mRole) {
case roles::LIST:
return @"AXContentList"; // 10.6+ NSAccessibilityContentListSubrole;
case roles::ENTRY:
- if (mGeckoAccessible->IsSearchbox())
+ if (accWrap->IsSearchbox())
return @"AXSearchField";
break;
case roles::DEFINITION_LIST:
return @"AXDefinitionList"; // 10.6+ NSAccessibilityDefinitionListSubrole;
case roles::TERM:
return @"AXTerm";
@@ -523,28 +556,28 @@ struct RoleDescrComparator
return NSAccessibilityRoleDescription([self role], subrole);
}
- (NSString*)title
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
nsAutoString title;
- mGeckoAccessible->Name(title);
+ [self getGeckoAccessible]->Name(title);
return nsCocoaUtils::ToNSString(title);
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (id)value
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
nsAutoString value;
- mGeckoAccessible->Value(value);
+ [self getGeckoAccessible]->Value(value);
return nsCocoaUtils::ToNSString(value);
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (void)valueDidChange
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
@@ -562,33 +595,34 @@ struct RoleDescrComparator
{
// Do nothing. mozTextAccessible will.
}
- (NSString*)customDescription
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
- if (mGeckoAccessible->IsDefunct())
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ if (accWrap->IsDefunct())
return nil;
nsAutoString desc;
- mGeckoAccessible->Description(desc);
+ accWrap->Description(desc);
return nsCocoaUtils::ToNSString(desc);
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (NSString*)help
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
nsAutoString helpText;
- mGeckoAccessible->Help(helpText);
+ [self getGeckoAccessible]->Help(helpText);
return nsCocoaUtils::ToNSString(helpText);
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
// objc-style description (from NSObject); not to be confused with the accessible description above.
- (NSString*)description
{
@@ -596,36 +630,39 @@ struct RoleDescrComparator
return [NSString stringWithFormat:@"(%p) %@", self, [self role]];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (BOOL)isFocused
{
- return FocusMgr()->IsFocused(mGeckoAccessible);
+ return FocusMgr()->IsFocused([self getGeckoAccessible]);
}
- (BOOL)canBeFocused
{
- return mGeckoAccessible && (mGeckoAccessible->InteractiveState() & states::FOCUSABLE);
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ return accWrap && (accWrap->InteractiveState() & states::FOCUSABLE);
}
- (BOOL)focus
{
- if (!mGeckoAccessible)
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ if (!accWrap)
return NO;
- mGeckoAccessible->TakeFocus();
+ accWrap->TakeFocus();
return YES;
}
- (BOOL)isEnabled
{
- return mGeckoAccessible && ((mGeckoAccessible->InteractiveState() & states::UNAVAILABLE) == 0);
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ return accWrap && ((accWrap->InteractiveState() & states::UNAVAILABLE) == 0);
}
// The root accessible calls this when the focused node was
// changed to us.
- (void)didReceiveFocus
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
@@ -638,17 +675,17 @@ struct RoleDescrComparator
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (NSWindow*)window
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
- AccessibleWrap* accWrap = static_cast<AccessibleWrap*>(mGeckoAccessible);
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
// Get a pointer to the native window (NSWindow) we reside in.
NSWindow *nativeWindow = nil;
DocAccessible* docAcc = accWrap->Document();
if (docAcc)
nativeWindow = static_cast<NSWindow*>(docAcc->GetNativeWindow());
NSAssert1(nativeWindow, @"Could not get native window for %@", self);
@@ -680,24 +717,24 @@ struct RoleDescrComparator
}
- (void)expire
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
[self invalidateChildren];
- mGeckoAccessible = nullptr;
+ mGeckoAccessible = 0;
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (BOOL)isExpired
{
- return !mGeckoAccessible;
+ return ![self getGeckoAccessible];
}
#pragma mark -
#pragma mark Debug methods
#pragma mark -
#ifdef DEBUG
--- a/accessible/mac/mozActionElements.h
+++ b/accessible/mac/mozActionElements.h
@@ -4,29 +4,28 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#import <Cocoa/Cocoa.h>
#import "mozAccessible.h"
/* Simple subclasses for things like checkboxes, buttons, etc. */
@interface mozButtonAccessible : mozAccessible
+ {
+ }
+- (BOOL)hasPopup;
- (void)click;
- (BOOL)isTab;
@end
@interface mozCheckboxAccessible : mozButtonAccessible
// returns one of the constants defined in CheckboxValue
- (int)isChecked;
@end
-/* Used for buttons that may pop up a menu. */
-@interface mozPopupButtonAccessible : mozButtonAccessible
-@end
-
/* Class for tabs - not individual tabs */
@interface mozTabsAccessible : mozAccessible
{
NSMutableArray* mTabs;
}
-(id)tabs;
@end
--- a/accessible/mac/mozActionElements.mm
+++ b/accessible/mac/mozActionElements.mm
@@ -37,98 +37,123 @@ enum CheckboxValue {
NSAccessibilitySizeAttribute, // required
NSAccessibilityWindowAttribute, // required
NSAccessibilityPositionAttribute, // required
NSAccessibilityTopLevelUIElementAttribute, // required
NSAccessibilityHelpAttribute,
NSAccessibilityEnabledAttribute, // required
NSAccessibilityFocusedAttribute, // required
NSAccessibilityTitleAttribute, // required
+ NSAccessibilityChildrenAttribute,
NSAccessibilityDescriptionAttribute,
#if DEBUG
@"AXMozDescription",
#endif
nil];
}
return attributes;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (id)accessibilityAttributeValue:(NSString *)attribute
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
- if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
+ if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
+ if ([self hasPopup])
+ return [self children];
return nil;
+ }
+
if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
if ([self isTab])
return utils::LocalizedString(NS_LITERAL_STRING("tab"));
-
+
return NSAccessibilityRoleDescription([self role], nil);
}
-
+
return [super accessibilityAttributeValue:attribute];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (BOOL)accessibilityIsIgnored
{
- return !mGeckoAccessible;
+ return ![self getGeckoAccessible];
}
- (NSArray*)accessibilityActionNames
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
- if ([self isEnabled])
+ if ([self isEnabled]) {
+ if ([self hasPopup])
+ return [NSArray arrayWithObjects:NSAccessibilityPressAction,
+ NSAccessibilityShowMenuAction,
+ nil];
return [NSArray arrayWithObject:NSAccessibilityPressAction];
-
+ }
return nil;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
-- (NSString*)accessibilityActionDescription:(NSString*)action
+- (NSString*)accessibilityActionDescription:(NSString*)action
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if ([action isEqualToString:NSAccessibilityPressAction]) {
if ([self isTab])
return utils::LocalizedString(NS_LITERAL_STRING("switch"));
-
+
return @"press button"; // XXX: localize this later?
}
-
+
+ if ([self hasPopup]) {
+ if ([action isEqualToString:NSAccessibilityShowMenuAction])
+ return @"show menu";
+ }
+
return nil;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
-- (void)accessibilityPerformAction:(NSString*)action
+- (void)accessibilityPerformAction:(NSString*)action
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
- if ([action isEqualToString:NSAccessibilityPressAction])
+ if ([self isEnabled] && [action isEqualToString:NSAccessibilityPressAction]) {
+ // TODO: this should bring up the menu, but currently doesn't.
+ // once msaa and atk have merged better, they will implement
+ // the action needed to show the menu.
[self click];
+ }
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (void)click
{
// both buttons and checkboxes have only one action. we should really stop using arbitrary
// arrays with actions, and define constants for these actions.
- mGeckoAccessible->DoAction(0);
+ [self getGeckoAccessible]->DoAction(0);
}
- (BOOL)isTab
{
- return (mGeckoAccessible && (mGeckoAccessible->Role() == roles::PAGETAB));
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ return (accWrap && (accWrap->Role() == roles::PAGETAB));
+}
+
+- (BOOL)hasPopup
+{
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ return accWrap && (accWrap->NativeState() & mozilla::a11y::states::HASPOPUP);
}
@end
@implementation mozCheckboxAccessible
- (NSString*)accessibilityActionDescription:(NSString*)action
{
@@ -143,17 +168,17 @@ enum CheckboxValue {
return nil;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (int)isChecked
{
- uint64_t state = mGeckoAccessible->NativeState();
+ uint64_t state = [self getGeckoAccessible]->NativeState();
// check if we're checked or in a mixed state
if (state & states::CHECKED) {
return (state & states::MIXED) ? kMixed : kChecked;
}
return kUnchecked;
}
@@ -164,101 +189,16 @@ enum CheckboxValue {
return [NSNumber numberWithInt:[self isChecked]];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
@end
-@implementation mozPopupButtonAccessible
-
-- (NSArray *)accessibilityAttributeNames
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- static NSArray *attributes = nil;
-
- if (!attributes) {
- attributes = [[NSArray alloc] initWithObjects:NSAccessibilityParentAttribute, // required
- NSAccessibilityPositionAttribute, // required
- NSAccessibilityRoleAttribute, // required
- NSAccessibilitySizeAttribute, // required
- NSAccessibilityWindowAttribute, // required
- NSAccessibilityTopLevelUIElementAttribute, // required
- NSAccessibilityHelpAttribute,
- NSAccessibilityEnabledAttribute, // required
- NSAccessibilityFocusedAttribute, // required
- NSAccessibilityTitleAttribute, // required for popupmenus, and for menubuttons with a title
- NSAccessibilityChildrenAttribute, // required
- NSAccessibilityDescriptionAttribute, // required if it has no title attr
-#if DEBUG
- @"AXMozDescription",
-#endif
- nil];
- }
- return attributes;
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (id)accessibilityAttributeValue:(NSString *)attribute
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
- return [super children];
- }
- return [super accessibilityAttributeValue:attribute];
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (NSArray *)accessibilityActionNames
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- if ([self isEnabled]) {
- return [NSArray arrayWithObjects:NSAccessibilityPressAction,
- NSAccessibilityShowMenuAction,
- nil];
- }
- return nil;
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (NSString *)accessibilityActionDescription:(NSString *)action
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- if ([action isEqualToString:NSAccessibilityShowMenuAction])
- return @"show menu";
- return [super accessibilityActionDescription:action];
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
-- (void)accessibilityPerformAction:(NSString *)action
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
- // both the ShowMenu and Click action do the same thing.
- if ([self isEnabled]) {
- // TODO: this should bring up the menu, but currently doesn't.
- // once msaa and atk have merged better, they will implement
- // the action needed to show the menu.
- [super click];
- }
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
-@end
-
@implementation mozTabsAccessible
- (void)dealloc
{
[mTabs release];
[super dealloc];
}
@@ -287,20 +227,20 @@ enum CheckboxValue {
return [super accessibilityAttributeValue:attribute];
}
/**
* Returns the selected tab (the mozAccessible)
*/
- (id)value
{
- if (!mGeckoAccessible)
+ if (![self getGeckoAccessible])
return nil;
- Accessible* accessible = mGeckoAccessible->GetSelectedItem(0);
+ Accessible* accessible = [self getGeckoAccessible]->GetSelectedItem(0);
if (!accessible)
return nil;
mozAccessible* nativeAcc = nil;
accessible->GetNativeInterface((void**)&nativeAcc);
return nativeAcc;
}
@@ -334,39 +274,39 @@ enum CheckboxValue {
}
@end
@implementation mozPaneAccessible
- (NSUInteger)accessibilityArrayAttributeCount:(NSString*)attribute
{
- if (!mGeckoAccessible)
+ if (![self getGeckoAccessible])
return 0;
// By default this calls -[[mozAccessible children] count].
// Since we don't cache mChildren. This is faster.
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
- return mGeckoAccessible->ChildCount() ? 1 : 0;
+ return [self getGeckoAccessible]->ChildCount() ? 1 : 0;
return [super accessibilityArrayAttributeCount:attribute];
}
- (NSArray*)children
{
- if (!mGeckoAccessible)
+ if (![self getGeckoAccessible])
return nil;
- nsDeckFrame* deckFrame = do_QueryFrame(mGeckoAccessible->GetFrame());
+ nsDeckFrame* deckFrame = do_QueryFrame([self getGeckoAccessible]->GetFrame());
nsIFrame* selectedFrame = deckFrame ? deckFrame->GetSelectedBox() : nullptr;
Accessible* selectedAcc = nullptr;
if (selectedFrame) {
nsINode* node = selectedFrame->GetContent();
- selectedAcc = mGeckoAccessible->Document()->GetAccessible(node);
+ selectedAcc = [self getGeckoAccessible]->Document()->GetAccessible(node);
}
if (selectedAcc) {
mozAccessible *curNative = GetNativeFromGeckoAccessible(selectedAcc);
if (curNative)
return [NSArray arrayWithObjects:GetObjectOrRepresentedView(curNative), nil];
}
--- a/accessible/mac/mozDocAccessible.mm
+++ b/accessible/mac/mozDocAccessible.mm
@@ -28,17 +28,17 @@ getNativeViewFromRootAccessible(Accessib
@implementation mozRootAccessible
- (NSArray*)accessibilityAttributeNames
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
// if we're expired, we don't support any attributes.
- if (!mGeckoAccessible)
+ if (![self getGeckoAccessible])
return [NSArray array];
// standard attributes that are shared and supported by root accessible (AXMain) elements.
static NSMutableArray* attributes = nil;
if (!attributes) {
attributes = [[super accessibilityAttributeNames] mutableCopy];
[attributes addObject:NSAccessibilityMainAttribute];
@@ -90,17 +90,17 @@ getNativeViewFromRootAccessible(Accessib
// this will return our parallell NSView. see mozDocAccessible.h
- (id)representedView
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if (mParallelView)
return (id)mParallelView;
- mParallelView = getNativeViewFromRootAccessible (mGeckoAccessible);
+ mParallelView = getNativeViewFromRootAccessible ([self getGeckoAccessible]);
NSAssert(mParallelView, @"can't return root accessible's native parallel view.");
return mParallelView;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (BOOL)isRoot
--- a/accessible/mac/mozHTMLAccessible.mm
+++ b/accessible/mac/mozHTMLAccessible.mm
@@ -15,42 +15,44 @@
@implementation mozHeadingAccessible
- (NSString*)title
{
nsAutoString title;
mozilla::ErrorResult rv;
// XXX use the flattening API when there are available
// see bug 768298
- mGeckoAccessible->GetContent()->GetTextContent(title, rv);
+ [self getGeckoAccessible]->GetContent()->GetTextContent(title, rv);
return nsCocoaUtils::ToNSString(title);
}
- (id)value
{
- if (!mGeckoAccessible || !mGeckoAccessible->IsHyperText())
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+
+ if (!accWrap || !accWrap->IsHyperText())
return nil;
- uint32_t level = mGeckoAccessible->AsHyperText()->GetLevelInternal();
+ uint32_t level = accWrap->AsHyperText()->GetLevelInternal();
return [NSNumber numberWithInt:level];
}
@end
@interface mozLinkAccessible ()
-(NSURL*)url;
@end
@implementation mozLinkAccessible
- (NSArray*)accessibilityAttributeNames
{
// if we're expired, we don't support any attributes.
- if (!mGeckoAccessible)
+ if (![self getGeckoAccessible])
return [NSArray array];
static NSMutableArray* attributes = nil;
if (!attributes) {
attributes = [[super accessibilityAttributeNames] mutableCopy];
[attributes addObject:NSAccessibilityURLAttribute];
}
@@ -64,57 +66,59 @@
return [self url];
return [super accessibilityAttributeValue:attribute];
}
- (NSArray*)accessibilityActionNames
{
// if we're expired, we don't support any attributes.
- if (!mGeckoAccessible)
+ if (![self getGeckoAccessible])
return [NSArray array];
static NSArray* actionNames = nil;
if (!actionNames) {
actionNames = [[NSArray alloc] initWithObjects:NSAccessibilityPressAction,
nil];
}
return actionNames;
}
- (void)accessibilityPerformAction:(NSString*)action
{
- if (!mGeckoAccessible)
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+
+ if (!accWrap)
return;
if ([action isEqualToString:NSAccessibilityPressAction])
- mGeckoAccessible->DoAction(0);
+ accWrap->DoAction(0);
else
[super accessibilityPerformAction:action];
}
- (NSString*)customDescription
{
return @"";
}
- (NSString*)value
{
return @"";
}
- (NSURL*)url
{
- if (!mGeckoAccessible || mGeckoAccessible->IsDefunct())
+ if (![self getGeckoAccessible] || [self getGeckoAccessible]->IsDefunct())
return nil;
nsAutoString value;
- mGeckoAccessible->Value(value);
+ [self getGeckoAccessible]->Value(value);
NSString* urlString = value.IsEmpty() ? nil : nsCocoaUtils::ToNSString(value);
if (!urlString)
return nil;
return [NSURL URLWithString:urlString];
}
--- a/accessible/mac/mozTextAccessible.h
+++ b/accessible/mac/mozTextAccessible.h
@@ -3,18 +3,15 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#import "mozAccessible.h"
#import "HyperTextAccessible.h"
@interface mozTextAccessible : mozAccessible
{
- // both of these are the same old mGeckoAccessible, but already
- // QI'd for us, to the right type, for convenience.
- mozilla::a11y::HyperTextAccessible* mGeckoTextAccessible; // strong
}
@end
@interface mozTextLeafAccessible : mozAccessible
{
}
@end
--- a/accessible/mac/mozTextAccessible.mm
+++ b/accessible/mac/mozTextAccessible.mm
@@ -48,31 +48,19 @@ ToNSString(id aValue)
- (NSNumber*)caretLineNumber;
- (void)setText:(NSString*)newText;
- (NSString*)text;
- (NSString*)stringFromRange:(NSRange*)range;
@end
@implementation mozTextAccessible
-- (id)initWithAccessible:(AccessibleWrap*)accessible
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- if ((self = [super initWithAccessible:accessible])) {
- mGeckoTextAccessible = accessible->AsHyperText();
- }
- return self;
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
-}
-
- (BOOL)accessibilityIsIgnored
{
- return !mGeckoAccessible;
+ return ![self getGeckoAccessible];
}
- (NSArray*)accessibilityAttributeNames
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
static NSMutableArray* supportedAttributes = nil;
if (!supportedAttributes) {
@@ -121,21 +109,23 @@ ToNSString(id aValue)
if ([[self role] isEqualToString:NSAccessibilityStaticTextRole]) {
NSString* selectedText = [self selectedText];
return (selectedText && [selectedText length]) ? selectedText : [self text];
}
return [self text];
}
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+
if ([attribute isEqualToString:@"AXRequired"])
- return [NSNumber numberWithBool:!!(mGeckoAccessible->State() & states::REQUIRED)];
+ return [NSNumber numberWithBool:!!(accWrap->State() & states::REQUIRED)];
if ([attribute isEqualToString:@"AXInvalid"])
- return [NSNumber numberWithBool:!!(mGeckoAccessible->State() & states::INVALID)];
+ return [NSNumber numberWithBool:!!(accWrap->State() & states::INVALID)];
if ([attribute isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute])
return [self visibleCharacterRange];
// let mozAccessible handle all other attributes
return [super accessibilityAttributeValue:attribute];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
@@ -161,17 +151,19 @@ ToNSString(id aValue)
nil
];
}
return supportedParametrizedAttributes;
}
- (id)accessibilityAttributeValue:(NSString*)attribute forParameter:(id)parameter
{
- if (!mGeckoTextAccessible)
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
+ if (!textAcc)
return nil;
if ([attribute isEqualToString:NSAccessibilityStringForRangeParameterizedAttribute]) {
NSRange range;
if (!ToNSRange(parameter, &range)) {
#if DEBUG
NSLog(@"%@: range not set", attribute);
#endif
@@ -209,17 +201,17 @@ ToNSString(id aValue)
#if DEBUG
NSLog(@"%@:no range", attribute);
#endif
return nil;
}
int32_t start = range.location;
int32_t end = start + range.length;
- nsIntRect bounds = mGeckoTextAccessible->TextBounds(start, end);
+ nsIntRect bounds = textAcc->TextBounds(start, end);
return [NSValue valueWithRect:nsCocoaUtils::GeckoRectToCocoaRect(bounds)];
}
#if DEBUG
NSLog(@"unhandled attribute:%@ forParameter:%@", attribute, parameter);
#endif
@@ -242,209 +234,217 @@ ToNSString(id aValue)
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
}
- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
- if (!mGeckoTextAccessible)
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
+ if (!textAcc)
return;
if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
[self setText:ToNSString(value)];
return;
}
if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) {
NSString* stringValue = ToNSString(value);
if (!stringValue)
return;
int32_t start = 0, end = 0;
- mGeckoTextAccessible->SelectionBoundsAt(0, &start, &end);
- mGeckoTextAccessible->DeleteText(start, end - start);
+ textAcc->SelectionBoundsAt(0, &start, &end);
+ textAcc->DeleteText(start, end - start);
nsString text;
nsCocoaUtils::GetStringForNSString(stringValue, text);
- mGeckoTextAccessible->InsertText(text, start);
+ textAcc->InsertText(text, start);
}
if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
NSRange range;
if (!ToNSRange(value, &range))
return;
- mGeckoTextAccessible->SetSelectionBoundsAt(0, range.location,
- range.location + range.length);
+ textAcc->SetSelectionBoundsAt(0, range.location,
+ range.location + range.length);
return;
}
if ([attribute isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute]) {
NSRange range;
if (!ToNSRange(value, &range))
return;
- mGeckoTextAccessible->ScrollSubstringTo(range.location, range.location + range.length,
- nsIAccessibleScrollType::SCROLL_TYPE_TOP_EDGE);
+ textAcc->ScrollSubstringTo(range.location, range.location + range.length,
+ nsIAccessibleScrollType::SCROLL_TYPE_TOP_EDGE);
return;
}
[super accessibilitySetValue:value forAttribute:attribute];
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (NSString*)subrole
{
if(mRole == roles::PASSWORD_TEXT)
return NSAccessibilitySecureTextFieldSubrole;
return nil;
}
-- (void)expire
-{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
-
- mGeckoTextAccessible = nullptr;
- [super expire];
-
- NS_OBJC_END_TRY_ABORT_BLOCK;
-}
-
#pragma mark -
- (BOOL)isReadOnly
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
if ([[self role] isEqualToString:NSAccessibilityStaticTextRole])
return YES;
- if (mGeckoTextAccessible)
- return (mGeckoAccessible->State() & states::READONLY) == 0;
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
+ if (textAcc)
+ return (accWrap->State() & states::READONLY) == 0;
return NO;
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
}
- (NSNumber*)caretLineNumber
{
- int32_t lineNumber = mGeckoTextAccessible ?
- mGeckoTextAccessible->CaretLineNumber() - 1 : -1;
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
+ int32_t lineNumber = textAcc ?
+ textAcc->CaretLineNumber() - 1 : -1;
return (lineNumber >= 0) ? [NSNumber numberWithInt:lineNumber] : nil;
}
- (void)setText:(NSString*)aNewString
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
- if (mGeckoTextAccessible) {
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
+ if (textAcc) {
nsString text;
nsCocoaUtils::GetStringForNSString(aNewString, text);
- mGeckoTextAccessible->ReplaceText(text);
+ textAcc->ReplaceText(text);
}
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (NSString*)text
{
- if (!mGeckoAccessible || !mGeckoTextAccessible)
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
+ if (!accWrap || !textAcc)
return nil;
// A password text field returns an empty value
if (mRole == roles::PASSWORD_TEXT)
return @"";
nsAutoString text;
- mGeckoTextAccessible->TextSubstring(0,
- nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT,
- text);
+ textAcc->TextSubstring(0, nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT, text);
return nsCocoaUtils::ToNSString(text);
}
- (long)textLength
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
- if (!mGeckoAccessible || !mGeckoTextAccessible)
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
+ if (!accWrap || !textAcc)
return 0;
- return mGeckoTextAccessible ? mGeckoTextAccessible->CharacterCount() : 0;
+ return textAcc ? textAcc->CharacterCount() : 0;
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
}
- (long)selectedTextLength
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
- if (mGeckoTextAccessible) {
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
+ if (textAcc) {
int32_t start = 0, end = 0;
- mGeckoTextAccessible->SelectionBoundsAt(0, &start, &end);
+ textAcc->SelectionBoundsAt(0, &start, &end);
return (end - start);
}
return 0;
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
}
- (NSString*)selectedText
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
- if (mGeckoTextAccessible) {
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
+ if (textAcc) {
int32_t start = 0, end = 0;
- mGeckoTextAccessible->SelectionBoundsAt(0, &start, &end);
+ textAcc->SelectionBoundsAt(0, &start, &end);
if (start != end) {
nsAutoString selText;
- mGeckoTextAccessible->TextSubstring(start, end, selText);
+ textAcc->TextSubstring(start, end, selText);
return nsCocoaUtils::ToNSString(selText);
}
}
return nil;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (NSValue*)selectedTextRange
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
- if (mGeckoTextAccessible) {
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
+ if (textAcc) {
int32_t start = 0;
int32_t end = 0;
- int32_t count = mGeckoTextAccessible->SelectionCount();
+ int32_t count = textAcc->SelectionCount();
if (count) {
- mGeckoTextAccessible->SelectionBoundsAt(0, &start, &end);
+ textAcc->SelectionBoundsAt(0, &start, &end);
return [NSValue valueWithRange:NSMakeRange(start, end - start)];
}
- start = mGeckoTextAccessible->CaretOffset();
+ start = textAcc->CaretOffset();
return [NSValue valueWithRange:NSMakeRange(start != -1 ? start : 0, 0)];
}
return [NSValue valueWithRange:NSMakeRange(0, 0)];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (NSValue*)visibleCharacterRange
{
// XXX this won't work with Textarea and such as we actually don't give
// the visible character range.
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
return [NSValue valueWithRange:
- NSMakeRange(0, mGeckoTextAccessible ?
- mGeckoTextAccessible->CharacterCount() : 0)];
+ NSMakeRange(0, textAcc ?
+ textAcc->CharacterCount() : 0)];
}
- (void)valueDidChange
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
NSAccessibilityPostNotification(GetObjectOrRepresentedView(self),
NSAccessibilityValueChangedNotification);
@@ -455,21 +455,26 @@ ToNSString(id aValue)
- (void)selectedTextDidChange
{
NSAccessibilityPostNotification(GetObjectOrRepresentedView(self),
NSAccessibilitySelectedTextChangedNotification);
}
- (NSString*)stringFromRange:(NSRange*)range
{
- NS_PRECONDITION(mGeckoTextAccessible && range, "no Gecko text accessible or range");
+ NS_PRECONDITION(range, "no range");
+
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
+ if (!textAcc)
+ return nil;
nsAutoString text;
- mGeckoTextAccessible->TextSubstring(range->location,
- range->location + range->length, text);
+ textAcc->TextSubstring(range->location,
+ range->location + range->length, text);
return nsCocoaUtils::ToNSString(text);
}
@end
@implementation mozTextLeafAccessible
- (NSArray*)accessibilityAttributeNames
@@ -491,23 +496,25 @@ ToNSString(id aValue)
if ([attribute isEqualToString:NSAccessibilityValueAttribute])
return [self text];
return [super accessibilityAttributeValue:attribute];
}
- (NSString*)text
{
- if (!mGeckoAccessible)
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ if (!accWrap)
return nil;
- return nsCocoaUtils::ToNSString(mGeckoAccessible->AsTextLeaf()->Text());
+ return nsCocoaUtils::ToNSString(accWrap->AsTextLeaf()->Text());
}
- (long)textLength
{
- if (!mGeckoAccessible)
+ AccessibleWrap* accWrap = [self getGeckoAccessible];
+ if (!accWrap)
return 0;
- return mGeckoAccessible->AsTextLeaf()->Text().Length();
+ return accWrap->AsTextLeaf()->Text().Length();
}
@end
--- a/accessible/other/Platform.cpp
+++ b/accessible/other/Platform.cpp
@@ -28,8 +28,18 @@ void
a11y::ProxyDestroyed(ProxyAccessible*)
{
}
void
a11y::ProxyEvent(ProxyAccessible*, uint32_t)
{
}
+
+void
+a11y::ProxyStateChangeEvent(ProxyAccessible*, uint64_t, bool)
+{
+}
+
+void
+a11y::ProxyCaretMoveEvent(ProxyAccessible* aTarget, int32_t aOffset)
+{
+}
--- a/accessible/tests/mochitest/elm/test_HTMLSpec.html
+++ b/accessible/tests/mochitest/elm/test_HTMLSpec.html
@@ -65,28 +65,28 @@
// HTML:abbr contained by HTML:td
obj = {
role: ROLE_CELL,
attributes: { abbr: "WWW" },
interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ],
children: [
{
- role: ROLE_TEXT_CONTAINER,
+ role: ROLE_TEXT,
children: [ { role: ROLE_TEXT_LEAF } ]
}
]
};
testElm("td_abbr", obj);
//////////////////////////////////////////////////////////////////////////
// HTML:address
obj = {
- todo_role: ROLE_PARAGRAPH,
+ role: ROLE_TEXT_CONTAINER,
interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ],
};
testElm("address", obj);
//////////////////////////////////////////////////////////////////////////
// HTML:area@href
obj = {
@@ -183,17 +183,17 @@
obj = {
role: ROLE_SECTION,
interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ],
children: [ { role: ROLE_PARAGRAPH } ]
};
testElm("blockquote", obj);
//////////////////////////////////////////////////////////////////////////
- // HTML:br
+ // HTML:br contained by paragraph
obj = {
role: ROLE_PARAGRAPH,
children: [ { role: ROLE_WHITESPACE } ]
};
testElm("br_container", obj);
//////////////////////////////////////////////////////////////////////////
@@ -1057,17 +1057,17 @@
}
};
testElm("output_input", obj);
//////////////////////////////////////////////////////////////////////////
// HTML:pre
obj = {
- role: ROLE_PARAGRAPH,
+ role: ROLE_TEXT_CONTAINER,
interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ]
};
testElm("pre", obj);
///////////////////////////////////////////////////////////////////////////
// HTML:progress
obj = {
@@ -1082,17 +1082,17 @@
states: STATE_MIXED
};
testElm("progress_indeterminate", obj);
//////////////////////////////////////////////////////////////////////////
// HTML:q
obj = {
- role: ROLE_TEXT_CONTAINER,
+ role: ROLE_TEXT,
interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ],
children: [
{ role: ROLE_STATICTEXT }, // left quote
{ role: ROLE_TEXT_LEAF }, // quoted text
{ role: ROLE_STATICTEXT } // right quote
]
};
testElm("q", obj);
@@ -1228,17 +1228,17 @@
interfaces: [ nsIAccessibleText, nsIAccessibleEditableText ]
};
testElm("textarea", obj);
//////////////////////////////////////////////////////////////////////////
// HTML:time
obj = {
- role: ROLE_TEXT_CONTAINER,
+ role: ROLE_TEXT,
attributes: { "xml-roles": "time", "datetime": "2001-05-15 19:00" },
interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ]
};
testElm("time", obj);
//////////////////////////////////////////////////////////////////////////
// HTML:u contained by paragraph
--- a/accessible/tests/mochitest/jsat/doc_content_integration.html
+++ b/accessible/tests/mochitest/jsat/doc_content_integration.html
@@ -50,16 +50,22 @@
}
function changeSliderValue() {
document.getElementById('slider').setAttribute('aria-valuenow', '5');
document.getElementById('slider').setAttribute(
'aria-valuetext', 'medium');
}
+ function toggleLight() {
+ var lightSwitch = document.getElementById('light');
+ lightSwitch.setAttribute('aria-checked',
+ lightSwitch.getAttribute('aria-checked') === 'true' ? 'false' : 'true');
+ }
+
</script>
<style>
#windows {
position: relative;
width: 320px;
height: 480px;
}
@@ -95,14 +101,15 @@
<p>Do you agree?</p>
<button onclick="setTimeout(hideAlert, 500)">Yes</button>
<button onclick="hideAlert()">No</button>
</div>
<div id="appframe"></div>
</div>
<button id="home">Home</button>
<button id="fruit" aria-label="apple"></button>
+ <span id="light" role="switch" aria-label="Light" aria-checked="false" onclick="toggleLight()"></span>
<div id="live" aria-live="polite" aria-label="live">
<div id="slider" role="slider" aria-label="slider" aria-valuemin="0"
aria-valuemax="10" aria-valuenow="0"></div>
</div>
</body>
</html>
--- a/accessible/tests/mochitest/jsat/doc_traversal.html
+++ b/accessible/tests/mochitest/jsat/doc_traversal.html
@@ -138,10 +138,12 @@
<tr>
<td>Dirt</td>
<td>Messy Stuff</td>
</tr>
</tbody>
</table>
<div id="statusbar-1" role="status">Last sync:<span>2 days ago</span></div>
<div aria-label="Last sync: 30min ago" id="statusbar-2" role="status"></div>
+
+ <span id="switch-1" role="switch" aria-checked="false" aria-label="Light switch"></span>
</body>
</html>
--- a/accessible/tests/mochitest/jsat/jsatcommon.js
+++ b/accessible/tests/mochitest/jsat/jsatcommon.js
@@ -612,16 +612,28 @@ function ExpectedCheckAction(aChecked, a
}, [{
eventType: AndroidEvent.VIEW_CLICKED,
checked: aChecked
}], aOptions);
}
ExpectedCheckAction.prototype = Object.create(ExpectedPresent.prototype);
+function ExpectedSwitchAction(aSwitched, aOptions) {
+ ExpectedPresent.call(this, {
+ eventType: 'action',
+ data: [{ string: aSwitched ? 'onAction' : 'offAction' }]
+ }, [{
+ eventType: AndroidEvent.VIEW_CLICKED,
+ checked: aSwitched
+ }], aOptions);
+}
+
+ExpectedSwitchAction.prototype = Object.create(ExpectedPresent.prototype);
+
function ExpectedNameChange(aName, aOptions) {
ExpectedPresent.call(this, {
eventType: 'name-change',
data: aName
}, null, aOptions);
}
ExpectedNameChange.prototype = Object.create(ExpectedPresent.prototype);
--- a/accessible/tests/mochitest/jsat/test_content_integration.html
+++ b/accessible/tests/mochitest/jsat/test_content_integration.html
@@ -53,21 +53,33 @@
new ExpectedCursorChange(['much range', {'string': 'label'}])],
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['much range', '5', {'string': 'slider'}])],
[ContentMessages.moveOrAdjustUp(), new ExpectedValueChange('6')],
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['Home', {'string': 'pushbutton'}])],
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['apple', {'string': 'pushbutton'}])],
+ [ContentMessages.simpleMoveNext,
+ new ExpectedCursorChange(['Light', {"string": "stateOff"}, {'string': 'switch'}])],
+ // switch on
+ [ContentMessages.activateCurrent(),
+ new ExpectedClickAction({ no_android: true }),
+ new ExpectedSwitchAction(true)],
[ContentMessages.simpleMoveNext,
new ExpectedCursorChange(['slider', '0', {'string': 'slider'}])],
// Simple traversal backward
[ContentMessages.simpleMovePrevious,
+ new ExpectedCursorChange(['Light', {"string": "stateOn"}, {'string': 'switch'}])],
+ // switch off
+ [ContentMessages.activateCurrent(),
+ new ExpectedClickAction({ no_android: true }),
+ new ExpectedSwitchAction(false)],
+ [ContentMessages.simpleMovePrevious,
new ExpectedCursorChange(['apple', {'string': 'pushbutton'}])],
[ContentMessages.simpleMovePrevious,
new ExpectedCursorChange(['Home', {'string': 'pushbutton'}])],
[ContentMessages.simpleMovePrevious,
new ExpectedCursorChange(['much range', '6', {'string': 'slider'}, 'such app'])],
[ContentMessages.moveOrAdjustDown(), new ExpectedValueChange('5')],
[ContentMessages.simpleMovePrevious,
new ExpectedCursorChange(['much range', {'string': 'label'}])],
--- a/accessible/tests/mochitest/jsat/test_output.html
+++ b/accessible/tests/mochitest/jsat/test_output.html
@@ -483,16 +483,31 @@ https://bugzilla.mozilla.org/show_bug.cg
["Last sync:", "2 days ago"]],
expectedBraille: [["Last sync:", "2 days ago"],
["Last sync:", "2 days ago"]]
}, {
accOrElmOrID: "statusbar-2",
expectedUtterance: [["Last sync: 30min ago"],
["Last sync: 30min ago"]],
expectedBraille: [["Last sync: 30min ago"], ["Last sync: 30min ago"]]
+ }, {
+ accOrElmOrID: "switch-1",
+ expectedUtterance: [[{"string": "stateOn"}, {"string": "switch"},
+ "Simple switch"], ["Simple switch", {"string": "stateOn"},
+ {"string": "switch"}]],
+ expectedBraille: [[{"string": "stateCheckedAbbr"}, "Simple switch"],
+ ["Simple switch", {"string": "stateCheckedAbbr"}]]
+ }, {
+ accOrElmOrID: "switch-2",
+ expectedUtterance: [[{"string": "stateOff"},
+ {"string": "switch"}, "Another switch"], ["Another switch",
+ {"string": "stateOff"}, {"string": "switch"}]],
+ expectedBraille: [
+ [{"string": "stateUncheckedAbbr"}, "Another switch"],
+ ["Another switch", {"string": "stateUncheckedAbbr"}]]
}];
// Test all possible utterance order preference values.
tests.forEach(function run(test) {
var utteranceOrderValues = [0, 1];
utteranceOrderValues.forEach(
function testUtteranceOrder(utteranceOrder) {
SpecialPowers.setIntPref(PREF_UTTERANCE_ORDER, utteranceOrder);
@@ -640,11 +655,13 @@ https://bugzilla.mozilla.org/show_bug.cg
</select>
<select id="labelled-combobox" aria-label="Intervals">
<option value="15">Every 15 min</option>
<option value="30">Every 30 min</option>
<option value="null" selected>Never</option>
</select>
<div id="statusbar-1" role="status">Last sync:<span>2 days ago</span></div>
<div aria-label="Last sync: 30min ago" id="statusbar-2" role="status"></div>
+ <span id="switch-1" role="switch" aria-label="Simple switch" aria-checked="true"></span>
+ <span id="switch-2" role="switch" aria-label="Another switch" aria-checked="false"></span>
</div>
</body>
</html>
--- a/accessible/tests/mochitest/jsat/test_traversal.html
+++ b/accessible/tests/mochitest/jsat/test_traversal.html
@@ -51,28 +51,29 @@
queueTraversalSequence(gQueue, docAcc, TraversalRules.FormElement, null,
['input-1-1', 'label-1-2', 'button-1-1',
'radio-1-1', 'radio-1-2', 'input-1-3',
'input-1-4', 'button-1-2', 'checkbox-1-1',
'select-1-1', 'select-1-2', 'checkbox-1-2',
'select-1-3', 'input-1-5', 'button-1-3',
'button-2-1', 'button-2-2', 'button-2-3',
- 'button-2-4', 'checkbox-1-5']);
+ 'button-2-4', 'checkbox-1-5', 'switch-1']);
queueTraversalSequence(gQueue, docAcc, TraversalRules.Button, null,
['button-1-1', 'button-1-2', 'button-1-3',
'button-2-1', 'button-2-2', 'button-2-3',
'button-2-4']);
queueTraversalSequence(gQueue, docAcc, TraversalRules.RadioButton, null,
['radio-1-1', 'radio-1-2']);
queueTraversalSequence(gQueue, docAcc, TraversalRules.Checkbox, null,
- ['checkbox-1-1', 'checkbox-1-2', 'checkbox-1-5']);
+ ['checkbox-1-1', 'checkbox-1-2', 'checkbox-1-5',
+ 'switch-1']);
queueTraversalSequence(gQueue, docAcc, TraversalRules.Combobox, null,
['select-1-1', 'select-1-2', 'select-1-3']);
queueTraversalSequence(gQueue, docAcc, TraversalRules.List, null,
['list-1', 'list-2', 'list-3']);
queueTraversalSequence(gQueue, docAcc, TraversalRules.ListItem, null,
@@ -117,17 +118,18 @@
'4. Standard Lisp', 'link-0', ' Lisp',
'checkbox-1-5', ' LeLisp', '• JavaScript',
'heading-5', 'image-2', 'image-3',
'Not actually an image', 'link-1', 'anchor-1',
'link-2', 'anchor-2', 'link-3', '3', '1', '4',
'1', 'Sunday', 'M', 'Week 1', '3', '4', '7', '2',
'5 8', 'gridcell4', 'Just an innocuous separator',
'Dirty Words', 'Meaning', 'Mud', 'Wet Dirt',
- 'Dirt', 'Messy Stuff', 'statusbar-1', 'statusbar-2']);
+ 'Dirt', 'Messy Stuff', 'statusbar-1', 'statusbar-2',
+ 'switch-1']);
gQueue.invoke();
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(function () {
/* We open a new browser because we need to test with a top-level content
document. */
--- a/accessible/tests/mochitest/role.js
+++ b/accessible/tests/mochitest/role.js
@@ -106,16 +106,17 @@ const ROLE_SECTION = nsIAccessibleRole.R
const ROLE_SEPARATOR = nsIAccessibleRole.ROLE_SEPARATOR;
const ROLE_SLIDER = nsIAccessibleRole.ROLE_SLIDER;
const ROLE_SPINBUTTON = nsIAccessibleRole.ROLE_SPINBUTTON;
const ROLE_STATICTEXT = nsIAccessibleRole.ROLE_STATICTEXT;
const ROLE_STATUSBAR = nsIAccessibleRole.ROLE_STATUSBAR;
const ROLE_SWITCH = nsIAccessibleRole.ROLE_SWITCH;
const ROLE_TABLE = nsIAccessibleRole.ROLE_TABLE;
const ROLE_TERM = nsIAccessibleRole.ROLE_TERM;
+const ROLE_TEXT = nsIAccessibleRole.ROLE_TEXT;
const ROLE_TEXT_CONTAINER = nsIAccessibleRole.ROLE_TEXT_CONTAINER;
const ROLE_TEXT_LEAF = nsIAccessibleRole.ROLE_TEXT_LEAF;
const ROLE_TOGGLE_BUTTON = nsIAccessibleRole.ROLE_TOGGLE_BUTTON;
const ROLE_TOOLBAR = nsIAccessibleRole.ROLE_TOOLBAR;
const ROLE_TOOLTIP = nsIAccessibleRole.ROLE_TOOLTIP;
const ROLE_TREE_TABLE = nsIAccessibleRole.ROLE_TREE_TABLE;
const ROLE_WHITESPACE = nsIAccessibleRole.ROLE_WHITESPACE;
--- a/accessible/tests/mochitest/role/test_aria.html
+++ b/accessible/tests/mochitest/role/test_aria.html
@@ -34,26 +34,26 @@
testRole("aria_gridcell", ROLE_GRID_CELL);
testRole("aria_group", ROLE_GROUPING);
testRole("aria_heading", ROLE_HEADING);
testRole("aria_img", ROLE_GRAPHIC);
testRole("aria_link", ROLE_LINK);
testRole("aria_list", ROLE_LIST);
testRole("aria_listbox", ROLE_LISTBOX);
testRole("aria_listitem", ROLE_LISTITEM);
- testRole("aria_log", ROLE_TEXT_CONTAINER); // weak role
+ testRole("aria_log", ROLE_TEXT); // weak role
testRole("aria_marquee", ROLE_ANIMATION);
testRole("aria_math", ROLE_FLAT_EQUATION);
testRole("aria_menu", ROLE_MENUPOPUP);
testRole("aria_menubar", ROLE_MENUBAR);
testRole("aria_menuitem", ROLE_MENUITEM);
testRole("aria_menuitemcheckbox", ROLE_CHECK_MENU_ITEM);
testRole("aria_menuitemradio", ROLE_RADIO_MENU_ITEM);
testRole("aria_note", ROLE_NOTE);
- testRole("aria_presentation", ROLE_TEXT_CONTAINER); // weak role
+ testRole("aria_presentation", ROLE_TEXT); // weak role
testRole("aria_progressbar", ROLE_PROGRESSBAR);
testRole("aria_radio", ROLE_RADIOBUTTON);
testRole("aria_radiogroup", ROLE_RADIO_GROUP);
testRole("aria_region", ROLE_PANE);
testRole("aria_row", ROLE_ROW);
testRole("aria_rowheader", ROLE_ROWHEADER);
testRole("aria_scrollbar", ROLE_SCROLLBAR);
testRole("aria_searchbox", ROLE_ENTRY);
@@ -61,17 +61,17 @@
testRole("aria_slider", ROLE_SLIDER);
testRole("aria_spinbutton", ROLE_SPINBUTTON);
testRole("aria_status", ROLE_STATUSBAR);
testRole("aria_switch", ROLE_SWITCH);
testRole("aria_tab", ROLE_PAGETAB);
testRole("aria_tablist", ROLE_PAGETABLIST);
testRole("aria_tabpanel", ROLE_PROPERTYPAGE);
testRole("aria_textbox", ROLE_ENTRY);
- testRole("aria_timer", ROLE_TEXT_CONTAINER); // weak role
+ testRole("aria_timer", ROLE_TEXT); // weak role
testRole("aria_toolbar", ROLE_TOOLBAR);
testRole("aria_tooltip", ROLE_TOOLTIP);
testRole("aria_tree", ROLE_OUTLINE);
testRole("aria_treegrid", ROLE_TREE_TABLE);
testRole("aria_treeitem", ROLE_OUTLINEITEM);
// Note:
// The phrase "weak foo" here means that there is no good foo-to-platform
--- a/accessible/tests/mochitest/role/test_general.html
+++ b/accessible/tests/mochitest/role/test_general.html
@@ -62,19 +62,19 @@
testRole("p", ROLE_PARAGRAPH);
// Test dl, dt, dd
testRole("definitionlist", ROLE_DEFINITION_LIST);
testRole("definitionterm", ROLE_TERM);
testRole("definitiondescription", ROLE_DEFINITION);
// Has click, mousedown or mouseup listeners.
- testRole("span1", ROLE_TEXT_CONTAINER);
- testRole("span2", ROLE_TEXT_CONTAINER);
- testRole("span3", ROLE_TEXT_CONTAINER);
+ testRole("span1", ROLE_TEXT);
+ testRole("span2", ROLE_TEXT);
+ testRole("span3", ROLE_TEXT);
// Test role of listbox inside combobox
testRole("listbox1", ROLE_COMBOBOX_LIST);
testRole("listbox2", ROLE_COMBOBOX_LIST);
SimpleTest.finish();
}
--- a/accessible/tests/mochitest/states/a11y.ini
+++ b/accessible/tests/mochitest/states/a11y.ini
@@ -10,16 +10,17 @@ support-files =
[test_aria.xul]
[test_aria_imgmap.html]
[test_aria_widgetitems.html]
[test_buttons.html]
[test_controls.html]
[test_controls.xul]
[test_doc.html]
[test_doc_busy.html]
+skip-if = os == 'mac' && os_version == '10.6'
[test_docarticle.html]
[test_editablebody.html]
[test_expandable.xul]
[test_frames.html]
[test_inputs.html]
[test_link.html]
[test_popup.xul]
[test_selects.html]
--- a/accessible/tests/mochitest/tree/test_aria_list.html
+++ b/accessible/tests/mochitest/tree/test_aria_list.html
@@ -30,17 +30,17 @@
//////////////////////////////////////////////////////////////////////////
// crazy list (mad mix of ARIA and HTML)
accTree = { // div@role="list"
role: ROLE_LIST,
children: [
{ // li
- role: ROLE_PARAGRAPH,
+ role: ROLE_TEXT_CONTAINER,
children: [
{ // li text leaf
role: ROLE_TEXT_LEAF,
name: "item1",
children: [ ]
}
]
},
--- a/accessible/tests/mochitest/tree/test_aria_presentation.html
+++ b/accessible/tests/mochitest/tree/test_aria_presentation.html
@@ -68,20 +68,20 @@
] }
] }
] };
testAccessibleTree("tblfocusable_cnt", tree);
// Presentation list, expose generic accesisble for list items.
tree =
{ SECTION: [ // container
- { PARAGRAPH: [ // li generic accessible inside 'presentation' role
+ { TEXT_CONTAINER: [ // li generic accessible inside 'presentation' role
{ TEXT_LEAF: [ ] } // li text
] },
- { PARAGRAPH: [ // li generic accessible inside 'none' role
+ { TEXT_CONTAINER: [ // li generic accessible inside 'none' role
{ TEXT_LEAF: [ ] } // li text
] }
] };
testAccessibleTree("list_cnt", tree);
// Has ARIA globals or referred by ARIA relationship, role='presentation'
// and role='none' are ignored.
tree =
--- a/accessible/tests/mochitest/tree/test_dockids.html
+++ b/accessible/tests/mochitest/tree/test_dockids.html
@@ -15,25 +15,25 @@
<script type="application/javascript"
src="../states.js"></script>
<script type="application/javascript">
function doTest()
{
var tree =
{ DOCUMENT: [
- { PARAGRAPH: [ // head
- { PARAGRAPH: [ // link
+ { TEXT_CONTAINER: [ // head
+ { TEXT_CONTAINER: [ // link
{ STATICTEXT: [] }, // generated content
{ STATICTEXT: [] } // generated content
] }
] },
{ TEXT_LEAF: [ ] }, // body text
{ ENTRY: [ ] }, // input under document element
- { PARAGRAPH: [ // link under document element
+ { TEXT_CONTAINER: [ // link under document element
{ TEXT_LEAF: [ ] }, // link content
{ STATICTEXT: [ ] }, // generated content
{ STATICTEXT: [ ] } // generated content
] },
{ LINK: [ // anchor under document element
{ TEXT_LEAF: [ ] } // anchor content
] },
] };
--- a/accessible/tests/mochitest/tree/test_invalid_img.xhtml
+++ b/accessible/tests/mochitest/tree/test_invalid_img.xhtml
@@ -15,17 +15,17 @@
<script>
<![CDATA[
function doTest()
{
document.getElementsByTagName("img")[0].firstChild.data = "2";
var accTree = {
- role: ROLE_TEXT_CONTAINER,
+ role: ROLE_TEXT,
children: [ { role: ROLE_TEXT_LEAF } ]
};
testAccessibleTree("the_img", accTree);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
--- a/accessible/tests/mochitest/tree/test_txtcntr.html
+++ b/accessible/tests/mochitest/tree/test_txtcntr.html
@@ -115,17 +115,17 @@
role: ROLE_SECTION,
children: [
{ // text leaf
role: ROLE_TEXT_LEAF,
name: "This ",
children: []
},
{ // abbr tag
- role: ROLE_TEXT_CONTAINER,
+ role: ROLE_TEXT,
name: "accessibility",
children: [
{ // text leaf with actual text
role: ROLE_TEXT_LEAF,
name: "a11y",
children: []
}
]
@@ -145,17 +145,17 @@
role: ROLE_SECTION,
children: [
{ // text leaf
role: ROLE_TEXT_LEAF,
name: "This ",
children: []
},
{ // acronym tag
- role: ROLE_TEXT_CONTAINER,
+ role: ROLE_TEXT,
name: "personal computer",
children: [
{ // text leaf with actual text
role: ROLE_TEXT_LEAF,
name: "PC",
children: []
}
]
--- a/accessible/tests/mochitest/treeupdate/test_textleaf.html
+++ b/accessible/tests/mochitest/treeupdate/test_textleaf.html
@@ -79,45 +79,45 @@
}
this.getID = function setOnClickAttr_getID()
{
return "make " + prettyName(aID) + " linkable";
}
}
- function removeTextData(aID)
+ function removeTextData(aID, aRole)
{
this.containerNode = getNode(aID);
this.textNode = this.containerNode.firstChild;
this.eventSeq = [
new invokerChecker(EVENT_REORDER, this.containerNode)
];
this.invoke = function removeTextData_invoke()
{
var tree = {
- role: ROLE_PARAGRAPH,
+ role: aRole,
children: [
{
role: ROLE_TEXT_LEAF,
name: "text"
}
]
};
testAccessibleTree(this.containerNode, tree);
this.textNode.data = "";
}
this.finalCheck = function removeTextData_finalCheck()
{
var tree = {
- role: ROLE_PARAGRAPH,
+ role: aRole,
children: []
};
testAccessibleTree(this.containerNode, tree);
}
this.getID = function removeTextData_finalCheck()
{
return "remove text data of text node inside '" + aID + "'.";
@@ -142,18 +142,18 @@
// remove onclick attribute, text leaf shouldn't have any action
gQueue.push(new removeOnClickAttr("div"));
// set onclick attribute making span accessible, it's inserted into tree
// and adopts text leaf accessible, text leaf should have an action
gQueue.push(new setOnClickNRoleAttrs("span"));
// text data removal of text node should remove its text accessible
- gQueue.push(new removeTextData("p"));
- gQueue.push(new removeTextData("pre"));
+ gQueue.push(new removeTextData("p", ROLE_PARAGRAPH));
+ gQueue.push(new removeTextData("pre", ROLE_TEXT_CONTAINER));
gQueue.invoke(); // SimpleTest.finish() will be called in the end
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
--- a/accessible/windows/ia2/ia2AccessibleAction.cpp
+++ b/accessible/windows/ia2/ia2AccessibleAction.cpp
@@ -19,17 +19,18 @@ using namespace mozilla::a11y;
STDMETHODIMP
ia2AccessibleAction::QueryInterface(REFIID iid, void** ppv)
{
if (!ppv)
return E_INVALIDARG;
*ppv = nullptr;
- if (IID_IAccessibleAction == iid) {
+ if (IID_IAccessibleAction == iid &&
+ !static_cast<AccessibleWrap*>(this)->IsProxy()) {
*ppv = static_cast<IAccessibleAction*>(this);
(reinterpret_cast<IUnknown*>(*ppv))->AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
--- a/accessible/windows/ia2/ia2AccessibleHyperlink.cpp
+++ b/accessible/windows/ia2/ia2AccessibleHyperlink.cpp
@@ -50,17 +50,19 @@ ia2AccessibleHyperlink::get_anchor(long
VariantInit(aAnchor);
Accessible* thisObj = static_cast<AccessibleWrap*>(this);
if (thisObj->IsProxy()) {
ProxyAccessible* anchor = thisObj->Proxy()->AnchorAt(aIndex);
if (!anchor)
return S_FALSE;
- aAnchor->punkVal = static_cast<IAccessibleHyperlink*>(WrapperFor(anchor));
+ IUnknown* tmp = static_cast<IAccessibleHyperlink*>(WrapperFor(anchor));
+ tmp->AddRef();
+ aAnchor->punkVal = tmp;
aAnchor->vt = VT_UNKNOWN;
return S_OK;
}
if (thisObj->IsDefunct())
return CO_E_OBJNOTCONNECTED;
if (aIndex < 0 || aIndex >= static_cast<long>(thisObj->AnchorCount()))
--- a/accessible/windows/msaa/AccessibleWrap.cpp
+++ b/accessible/windows/msaa/AccessibleWrap.cpp
@@ -110,56 +110,52 @@ AccessibleWrap::QueryInterface(REFIID ii
if (!ppv)
return E_INVALIDARG;
*ppv = nullptr;
if (IID_IUnknown == iid)
*ppv = static_cast<IAccessible*>(this);
-
- if (!*ppv && IsProxy())
- return E_NOINTERFACE;
-
- if (IID_IDispatch == iid || IID_IAccessible == iid)
+ else if (IID_IDispatch == iid || IID_IAccessible == iid)
*ppv = static_cast<IAccessible*>(this);
- else if (IID_IEnumVARIANT == iid) {
+ else if (IID_IEnumVARIANT == iid && !IsProxy()) {
// Don't support this interface for leaf elements.
if (!HasChildren() || nsAccUtils::MustPrune(this))
return E_NOINTERFACE;
*ppv = static_cast<IEnumVARIANT*>(new ChildrenEnumVariant(this));
- } else if (IID_IServiceProvider == iid)
+ } else if (IID_IServiceProvider == iid && !IsProxy())
*ppv = new ServiceProvider(this);
- else if (IID_ISimpleDOMNode == iid) {
+ else if (IID_ISimpleDOMNode == iid && !IsProxy()) {
if (IsDefunct() || (!HasOwnContent() && !IsDoc()))
return E_NOINTERFACE;
*ppv = static_cast<ISimpleDOMNode*>(new sdnAccessible(GetNode()));
}
if (nullptr == *ppv) {
HRESULT hr = ia2Accessible::QueryInterface(iid, ppv);
if (SUCCEEDED(hr))
return hr;
}
- if (nullptr == *ppv) {
+ if (nullptr == *ppv && !IsProxy()) {
HRESULT hr = ia2AccessibleComponent::QueryInterface(iid, ppv);
if (SUCCEEDED(hr))
return hr;
}
if (nullptr == *ppv) {
HRESULT hr = ia2AccessibleHyperlink::QueryInterface(iid, ppv);
if (SUCCEEDED(hr))
return hr;
}
- if (nullptr == *ppv) {
+ if (nullptr == *ppv && !IsProxy()) {
HRESULT hr = ia2AccessibleValue::QueryInterface(iid, ppv);
if (SUCCEEDED(hr))
return hr;
}
if (nullptr == *ppv)
return E_NOINTERFACE;
--- a/accessible/windows/msaa/Platform.cpp
+++ b/accessible/windows/msaa/Platform.cpp
@@ -53,8 +53,18 @@ a11y::ProxyDestroyed(ProxyAccessible* aP
aProxy->SetWrapper(0);
wrapper->Release();
}
void
a11y::ProxyEvent(ProxyAccessible*, uint32_t)
{
}
+
+void
+a11y::ProxyStateChangeEvent(ProxyAccessible*, uint64_t, bool)
+{
+}
+
+void
+a11y::ProxyCaretMoveEvent(ProxyAccessible* aTarget, int32_t aOffset)
+{
+}
--- a/accessible/windows/msaa/nsWinUtils.cpp
+++ b/accessible/windows/msaa/nsWinUtils.cpp
@@ -144,17 +144,20 @@ WindowProc(HWND hWnd, UINT msg, WPARAM w
{
// Note, this window's message handling should not invoke any call that
// may result in a cross-process ipc call. Doing so may violate RPC
// message semantics.
switch (msg) {
case WM_GETOBJECT:
{
- if (lParam == OBJID_CLIENT) {
+ // Do explicit casting to make it working on 64bit systems (see bug 649236
+ // for details).
+ int32_t objId = static_cast<DWORD>(lParam);
+ if (objId == OBJID_CLIENT) {
DocAccessible* document =
nsWinUtils::sHWNDCache->GetWeak(static_cast<void*>(hWnd));
if (document) {
IAccessible* msaaAccessible = nullptr;
document->GetNativeInterface((void**)&msaaAccessible); // does an addref
if (msaaAccessible) {
LRESULT result = ::LresultFromObject(IID_IAccessible, wParam,
msaaAccessible); // does an addref
--- a/accessible/windows/sdn/sdnAccessible.cpp
+++ b/accessible/windows/sdn/sdnAccessible.cpp
@@ -101,18 +101,21 @@ sdnAccessible::get_nodeInfo(BSTR __RPC_F
*aNameSpaceID = mNode->IsNodeOfType(nsINode::eCONTENT) ?
static_cast<short>(mNode->AsContent()->GetNameSpaceID()) : 0;
// This is a unique ID for every content node. The 3rd party accessibility
// application can compare this to the childID we return for events such as
// focus events, to correlate back to data nodes in their internal object
// model.
Accessible* accessible = GetAccessible();
- *aUniqueID = - NS_PTR_TO_INT32(accessible ? accessible->UniqueID() :
- static_cast<void*>(this));
+ if (accessible) {
+ *aUniqueID = AccessibleWrap::GetChildIDFor(accessible);
+ } else {
+ *aUniqueID = - NS_PTR_TO_INT32(static_cast<void*>(this));
+ }
*aNumChildren = mNode->GetChildCount();
return S_OK;
A11Y_TRYBLOCK_END
}
--- a/accessible/xpcom/moz.build
+++ b/accessible/xpcom/moz.build
@@ -15,18 +15,18 @@ UNIFIED_SOURCES += [
'xpcAccessibleImage.cpp',
'xpcAccessibleSelectable.cpp',
'xpcAccessibleTable.cpp',
'xpcAccessibleTableCell.cpp',
'xpcAccessibleTextRange.cpp',
'xpcAccessibleValue.cpp',
]
-GENERATED_SOURCES += [
- 'xpcAccEvents.cpp',
+SOURCES += [
+ '!xpcAccEvents.cpp',
]
LOCAL_INCLUDES += [
'/accessible/base',
'/accessible/generic',
]
if CONFIG['MOZ_ENABLE_GTK']:
--- a/addon-sdk/source/lib/sdk/net/url.js
+++ b/addon-sdk/source/lib/sdk/net/url.js
@@ -30,29 +30,24 @@ const { Services } = Cu.import("resource
* let promise = readURI('resource://gre/modules/NetUtil.jsm', {
* charset: 'US-ASCII'
* });
*/
function readURI(uri, options) {
options = options || {};
let charset = options.charset || 'UTF-8';
- let channel = NetUtil.newChannel2(uri,
- charset,
- null,
- null, // aLoadingNode
- Services.scriptSecurityManager.getSystemPrincipal(),
- null, // aTriggeringPrincipal
- Ci.nsILoadInfo.SEC_NORMAL,
- Ci.nsIContentPolicy.TYPE_OTHER);
+ let channel = NetUtil.newChannel({
+ uri: NetUtil.newURI(uri, charset),
+ loadUsingSystemPrincipal: true});
let { promise, resolve, reject } = defer();
try {
- NetUtil.asyncFetch2(channel, function (stream, result) {
+ NetUtil.asyncFetch(channel, function (stream, result) {
if (components.isSuccessCode(result)) {
let count = stream.available();
let data = NetUtil.readInputStreamToString(stream, count, { charset : charset });
resolve(data);
} else {
reject("Failed to read: '" + uri + "' (Error Code: " + result + ")");
}
@@ -78,24 +73,19 @@ exports.readURI = readURI;
* @returns {string} The content of the URI given.
*
* @example
* let data = readURISync('resource://gre/modules/NetUtil.jsm');
*/
function readURISync(uri, charset) {
charset = typeof charset === "string" ? charset : "UTF-8";
- let channel = NetUtil.newChannel2(uri,
- charset,
- null,
- null, // aLoadingNode
- Services.scriptSecurityManager.getSystemPrincipal(),
- null, // aTriggeringPrincipal
- Ci.nsILoadInfo.SEC_NORMAL,
- Ci.nsIContentPolicy.TYPE_OTHER);
+ let channel = NetUtil.newChannel({
+ uri: NetUtil.newURI(uri, charset),
+ loadUsingSystemPrincipal: true});
let stream = channel.open();
let count = stream.available();
let data = NetUtil.readInputStreamToString(stream, count, { charset : charset });
stream.close();
return data;
--- a/addon-sdk/source/lib/sdk/tabs/helpers.js
+++ b/addon-sdk/source/lib/sdk/tabs/helpers.js
@@ -22,11 +22,11 @@ function getTabForWindow(win) {
return modelFor(tab);
}
exports.getTabForWindow = getTabForWindow;
exports.getTabForRawTab = modelFor;
function getTabForBrowser(browser) {
- return modelFor(getRawTabForBrowser(browser));
+ return modelFor(getRawTabForBrowser(browser)) || null;
}
exports.getTabForBrowser = getTabForBrowser;
--- a/addon-sdk/source/lib/sdk/tabs/tab-fennec.js
+++ b/addon-sdk/source/lib/sdk/tabs/tab-fennec.js
@@ -4,24 +4,25 @@
'use strict';
const { Cc, Ci } = require('chrome');
const { Class } = require('../core/heritage');
const { tabNS, rawTabNS } = require('./namespace');
const { EventTarget } = require('../event/target');
const { activateTab, getTabTitle, setTabTitle, closeTab, getTabURL,
getTabContentWindow, getTabForBrowser, setTabURL, getOwnerWindow,
- getTabContentDocument, getTabContentType, getTabId } = require('./utils');
+ getTabContentDocument, getTabContentType, getTabId, isTab } = require('./utils');
const { emit } = require('../event/core');
const { isPrivate } = require('../private-browsing/utils');
const { isWindowPrivate } = require('../window/utils');
const { when: unload } = require('../system/unload');
const { BLANK } = require('../content/thumbnail');
const { viewFor } = require('../view/core');
const { EVENTS } = require('./events');
+const { modelFor } = require('../model/core');
const ERR_FENNEC_MSG = 'This method is not yet supported by Fennec';
const Tab = Class({
extends: EventTarget,
initialize: function initialize(options) {
options = options.tab ? options : { tab: options };
let tab = options.tab;
--- a/addon-sdk/source/lib/sdk/url.js
+++ b/addon-sdk/source/lib/sdk/url.js
@@ -147,30 +147,38 @@ function URL(url, base) {
this.__defineGetter__("hash", function() hash);
this.__defineGetter__("href", function() uri.spec);
this.__defineGetter__("origin", function() uri.prePath);
this.__defineGetter__("protocol", function() uri.scheme + ":");
this.__defineGetter__("search", function() search);
Object.defineProperties(this, {
toString: {
- value() new String(uri.spec).toString(),
+ value() {
+ return new String(uri.spec).toString();
+ },
enumerable: false
},
valueOf: {