123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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 "OuterDocAccessible.h"
- #include "Accessible-inl.h"
- #include "nsAccUtils.h"
- #include "DocAccessible-inl.h"
- #include "mozilla/a11y/DocAccessibleParent.h"
- #include "mozilla/dom/TabParent.h"
- #include "Role.h"
- #include "States.h"
- #ifdef A11Y_LOG
- #include "Logging.h"
- #endif
- using namespace mozilla;
- using namespace mozilla::a11y;
- ////////////////////////////////////////////////////////////////////////////////
- // OuterDocAccessible
- ////////////////////////////////////////////////////////////////////////////////
- OuterDocAccessible::
- OuterDocAccessible(nsIContent* aContent, DocAccessible* aDoc) :
- AccessibleWrap(aContent, aDoc)
- {
- mType = eOuterDocType;
- // Request document accessible for the content document to make sure it's
- // created. It will appended to outerdoc accessible children asynchronously.
- nsIDocument* outerDoc = mContent->GetUncomposedDoc();
- if (outerDoc) {
- nsIDocument* innerDoc = outerDoc->GetSubDocumentFor(mContent);
- if (innerDoc)
- GetAccService()->GetDocAccessible(innerDoc);
- }
- }
- OuterDocAccessible::~OuterDocAccessible()
- {
- }
- ////////////////////////////////////////////////////////////////////////////////
- // nsISupports
- NS_IMPL_ISUPPORTS_INHERITED0(OuterDocAccessible,
- Accessible)
- ////////////////////////////////////////////////////////////////////////////////
- // Accessible public (DON'T add methods here)
- role
- OuterDocAccessible::NativeRole()
- {
- return roles::INTERNAL_FRAME;
- }
- Accessible*
- OuterDocAccessible::ChildAtPoint(int32_t aX, int32_t aY,
- EWhichChildAtPoint aWhichChild)
- {
- nsIntRect docRect = Bounds();
- if (aX < docRect.x || aX >= docRect.x + docRect.width ||
- aY < docRect.y || aY >= docRect.y + docRect.height)
- return nullptr;
- // Always return the inner doc as direct child accessible unless bounds
- // outside of it.
- Accessible* child = GetChildAt(0);
- NS_ENSURE_TRUE(child, nullptr);
- if (aWhichChild == eDeepestChild)
- return child->ChildAtPoint(aX, aY, eDeepestChild);
- return child;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Accessible public
- void
- OuterDocAccessible::Shutdown()
- {
- #ifdef A11Y_LOG
- if (logging::IsEnabled(logging::eDocDestroy))
- logging::OuterDocDestroy(this);
- #endif
- Accessible* child = mChildren.SafeElementAt(0, nullptr);
- if (child) {
- #ifdef A11Y_LOG
- if (logging::IsEnabled(logging::eDocDestroy)) {
- logging::DocDestroy("outerdoc's child document rebind is scheduled",
- child->AsDoc()->DocumentNode());
- }
- #endif
- RemoveChild(child);
- // XXX: sometimes outerdoc accessible is shutdown because of layout style
- // change however the presshell of underlying document isn't destroyed and
- // the document doesn't get pagehide events. Schedule a document rebind
- // to its parent document. Otherwise a document accessible may be lost if
- // its outerdoc has being recreated (see bug 862863 for details).
- if (!mDoc->IsDefunct()) {
- mDoc->BindChildDocument(child->AsDoc());
- }
- }
- AccessibleWrap::Shutdown();
- }
- bool
- OuterDocAccessible::InsertChildAt(uint32_t aIdx, Accessible* aAccessible)
- {
- MOZ_RELEASE_ASSERT(aAccessible->IsDoc(),
- "OuterDocAccessible can have a document child only!");
- // We keep showing the old document for a bit after creating the new one,
- // and while building the new DOM and frame tree. That's done on purpose
- // to avoid weird flashes of default background color.
- // The old viewer will be destroyed after the new one is created.
- // For a11y, it should be safe to shut down the old document now.
- if (mChildren.Length())
- mChildren[0]->Shutdown();
- if (!AccessibleWrap::InsertChildAt(0, aAccessible))
- return false;
- #ifdef A11Y_LOG
- if (logging::IsEnabled(logging::eDocCreate)) {
- logging::DocCreate("append document to outerdoc",
- aAccessible->AsDoc()->DocumentNode());
- logging::Address("outerdoc", this);
- }
- #endif
- return true;
- }
- bool
- OuterDocAccessible::RemoveChild(Accessible* aAccessible)
- {
- Accessible* child = mChildren.SafeElementAt(0, nullptr);
- if (child != aAccessible) {
- NS_ERROR("Wrong child to remove!");
- return false;
- }
- #ifdef A11Y_LOG
- if (logging::IsEnabled(logging::eDocDestroy)) {
- logging::DocDestroy("remove document from outerdoc",
- child->AsDoc()->DocumentNode(), child->AsDoc());
- logging::Address("outerdoc", this);
- }
- #endif
- bool wasRemoved = AccessibleWrap::RemoveChild(child);
- NS_ASSERTION(!mChildren.Length(),
- "This child document of outerdoc accessible wasn't removed!");
- return wasRemoved;
- }
- bool
- OuterDocAccessible::IsAcceptableChild(nsIContent* aEl) const
- {
- // outer document accessible doesn't not participate in ordinal tree
- // mutations.
- return false;
- }
- #if defined(XP_WIN)
- // On Windows e10s, since we don't cache in the chrome process, these next two
- // functions must be implemented so that we properly cross the chrome-to-content
- // boundary when traversing.
- uint32_t
- OuterDocAccessible::ChildCount() const
- {
- uint32_t result = mChildren.Length();
- if (!result && RemoteChildDoc()) {
- result = 1;
- }
- return result;
- }
- Accessible*
- OuterDocAccessible::GetChildAt(uint32_t aIndex) const
- {
- Accessible* result = AccessibleWrap::GetChildAt(aIndex);
- if (result || aIndex) {
- return result;
- }
- // If we are asking for child 0 and GetChildAt doesn't return anything, try
- // to get the remote child doc and return that instead.
- ProxyAccessible* remoteChild = RemoteChildDoc();
- if (!remoteChild) {
- return nullptr;
- }
- return WrapperFor(remoteChild);
- }
- #endif // defined(XP_WIN)
- ProxyAccessible*
- OuterDocAccessible::RemoteChildDoc() const
- {
- dom::TabParent* tab = dom::TabParent::GetFrom(GetContent());
- if (!tab)
- return nullptr;
- return tab->GetTopLevelDocAccessible();
- }
|