/* 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 "RootAccessible.h" #include "mozilla/ArrayUtils.h" #include "mozilla/PresShell.h" // for nsAccUtils::GetDocAccessibleFor() #define CreateEvent CreateEventA #include "Accessible-inl.h" #include "DocAccessible-inl.h" #include "nsAccessibilityService.h" #include "nsAccUtils.h" #include "nsCoreUtils.h" #include "nsEventShell.h" #include "Relation.h" #include "Role.h" #include "States.h" #ifdef MOZ_XUL # include "XULTreeAccessible.h" #endif #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/CustomEvent.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/ScriptSettings.h" #include "nsIDocShellTreeOwner.h" #include "mozilla/dom/Event.h" #include "mozilla/dom/EventTarget.h" #include "nsIDOMXULMultSelectCntrlEl.h" #include "mozilla/dom/Document.h" #include "nsIInterfaceRequestorUtils.h" #include "nsIPropertyBag2.h" #include "nsPIDOMWindow.h" #include "nsIWebBrowserChrome.h" #include "nsReadableUtils.h" #include "nsFocusManager.h" #include "nsGlobalWindow.h" #ifdef MOZ_XUL # include "nsIXULWindow.h" #endif using namespace mozilla; using namespace mozilla::a11y; using namespace mozilla::dom; //////////////////////////////////////////////////////////////////////////////// // nsISupports NS_IMPL_ISUPPORTS_INHERITED(RootAccessible, DocAccessible, nsIDOMEventListener) //////////////////////////////////////////////////////////////////////////////// // Constructor/destructor RootAccessible::RootAccessible(Document* aDocument, PresShell* aPresShell) : DocAccessibleWrap(aDocument, aPresShell) { mType = eRootType; } RootAccessible::~RootAccessible() {} //////////////////////////////////////////////////////////////////////////////// // Accessible ENameValueFlag RootAccessible::Name(nsString& aName) const { aName.Truncate(); if (ARIARoleMap()) { Accessible::Name(aName); if (!aName.IsEmpty()) return eNameOK; } mDocumentNode->GetTitle(aName); return eNameOK; } role RootAccessible::NativeRole() const { // If it's a or , use roles::DIALOG instead dom::Element* rootElm = mDocumentNode->GetRootElement(); if (rootElm && rootElm->IsAnyOfXULElements(nsGkAtoms::dialog, nsGkAtoms::wizard)) return roles::DIALOG; return DocAccessibleWrap::NativeRole(); } // RootAccessible protected member #ifdef MOZ_XUL uint32_t RootAccessible::GetChromeFlags() const { // Return the flag set for the top level window as defined // by nsIWebBrowserChrome::CHROME_WINDOW_[FLAGNAME] // Not simple: nsIXULWindow is not just a QI from nsIDOMWindow nsCOMPtr docShell = nsCoreUtils::GetDocShellFor(mDocumentNode); NS_ENSURE_TRUE(docShell, 0); nsCOMPtr treeOwner; docShell->GetTreeOwner(getter_AddRefs(treeOwner)); NS_ENSURE_TRUE(treeOwner, 0); nsCOMPtr xulWin(do_GetInterface(treeOwner)); if (!xulWin) { return 0; } uint32_t chromeFlags; xulWin->GetChromeFlags(&chromeFlags); return chromeFlags; } #endif uint64_t RootAccessible::NativeState() const { uint64_t state = DocAccessibleWrap::NativeState(); if (state & states::DEFUNCT) return state; #ifdef MOZ_XUL uint32_t chromeFlags = GetChromeFlags(); if (chromeFlags & nsIWebBrowserChrome::CHROME_WINDOW_RESIZE) state |= states::SIZEABLE; // If it has a titlebar it's movable // XXX unless it's minimized or maximized, but not sure // how to detect that if (chromeFlags & nsIWebBrowserChrome::CHROME_TITLEBAR) state |= states::MOVEABLE; if (chromeFlags & nsIWebBrowserChrome::CHROME_MODAL) state |= states::MODAL; #endif nsFocusManager* fm = nsFocusManager::GetFocusManager(); if (fm && fm->GetActiveWindow() == mDocumentNode->GetWindow()) state |= states::ACTIVE; return state; } const char* const kEventTypes[] = { #ifdef DEBUG_DRAGDROPSTART // Capture mouse over events and fire fake DRAGDROPSTART event to simplify // debugging a11y objects with event viewers. "mouseover", #endif // Fired when list or tree selection changes. "select", // Fired when value changes immediately, wether or not focused changed. "ValueChange", "AlertActive", "TreeRowCountChanged", "TreeInvalidated", // add ourself as a OpenStateChange listener (custom event fired in // tree.xml) "OpenStateChange", // add ourself as a CheckboxStateChange listener (custom event fired in // HTMLInputElement.cpp) "CheckboxStateChange", // add ourself as a RadioStateChange Listener (custom event fired in in // HTMLInputElement.cpp & radio.js) "RadioStateChange", "popupshown", "popuphiding", "DOMMenuInactive", "DOMMenuItemActive", "DOMMenuItemInactive", "DOMMenuBarActive", "DOMMenuBarInactive"}; nsresult RootAccessible::AddEventListeners() { // EventTarget interface allows to register event listeners to // receive untrusted events (synthetic events generated by untrusted code). // For example, XBL bindings implementations for elements that are hosted in // non chrome document fire untrusted events. // We must use the window's parent target in order to receive events from // iframes and shadow DOM; e.g. ValueChange events from a