Пример #1
0
NS_IMETHODIMP
xpcAccessible::GetRelationByType(uint32_t aType,
                                 nsIAccessibleRelation** aRelation)
{
  NS_ENSURE_ARG_POINTER(aRelation);
  *aRelation = nullptr;

  NS_ENSURE_ARG(aType <= static_cast<uint32_t>(RelationType::LAST));

  if (IntlGeneric().IsNull())
    return NS_ERROR_FAILURE;

  if (IntlGeneric().IsAccessible()) {
    Relation rel = Intl()->RelationByType(static_cast<RelationType>(aType));
    NS_ADDREF(*aRelation = new nsAccessibleRelation(aType, &rel));
    return NS_OK;
  }

  ProxyAccessible* proxy = IntlGeneric().AsProxy();
  nsTArray<ProxyAccessible*> targets =
    proxy->RelationByType(static_cast<RelationType>(aType));
  NS_ADDREF(*aRelation = new nsAccessibleRelation(aType, &targets));

  return NS_OK;
}
Пример #2
0
NS_IMETHODIMP
xpcAccessible::GetAttributes(nsIPersistentProperties** aAttributes)
{
  NS_ENSURE_ARG_POINTER(aAttributes);
  *aAttributes = nullptr;

  if (IntlGeneric().IsNull()) {
    return NS_ERROR_FAILURE;
  }

  if (Accessible* acc = Intl()) {
    nsCOMPtr<nsIPersistentProperties> attributes = acc->Attributes();
    attributes.swap(*aAttributes);
    return NS_OK;
  }

  ProxyAccessible* proxy = IntlGeneric().AsProxy();
  AutoTArray<Attribute, 10> attrs;
  proxy->Attributes(&attrs);

  nsCOMPtr<nsIPersistentProperties> props =
    do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
  uint32_t attrCount = attrs.Length();
  nsAutoString unused;
  for (uint32_t i = 0; i < attrCount; i++) {
    props->SetStringProperty(attrs[i].Name(), attrs[i].Value(), unused);
  }

  props.forget(aAttributes);
  return NS_OK;
}
Пример #3
0
AtkAttributeSet *
getAttributesCB(AtkObject *aAtkObj)
{
  AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
  if (accWrap)
    return GetAttributeSet(accWrap);

  ProxyAccessible* proxy = GetProxy(aAtkObj);
  if (!proxy)
    return nullptr;

  nsAutoTArray<Attribute, 10> attrs;
  proxy->Attributes(&attrs);
  if (attrs.IsEmpty())
    return nullptr;

  AtkAttributeSet* objAttributeSet = nullptr;
  for (uint32_t i = 0; i < attrs.Length(); i++) {
    AtkAttribute *objAttr = (AtkAttribute *)g_malloc(sizeof(AtkAttribute));
    objAttr->name = g_strdup(attrs[i].Name().get());
    objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(attrs[i].Value()).get());
    objAttributeSet = g_slist_prepend(objAttributeSet, objAttr);
  }

  return objAttributeSet;
}
Пример #4
0
ipc::IPCResult
DocAccessibleParent::AddChildDoc(DocAccessibleParent* aChildDoc,
                                 uint64_t aParentID, bool aCreating)
{
  // We do not use GetAccessible here because we want to be sure to not get the
  // document it self.
  ProxyEntry* e = mAccessibles.GetEntry(aParentID);
  if (!e) {
    return IPC_FAIL(this, "binding to nonexistant proxy!");
  }

  ProxyAccessible* outerDoc = e->mProxy;
  MOZ_ASSERT(outerDoc);

  // OuterDocAccessibles are expected to only have a document as a child.
  // However for compatibility we tolerate replacing one document with another
  // here.
  if (outerDoc->ChildrenCount() > 1 ||
      (outerDoc->ChildrenCount() == 1 && !outerDoc->ChildAt(0)->IsDoc())) {
    return IPC_FAIL(this, "binding to proxy that can't be a outerDoc!");
  }

  aChildDoc->SetParent(outerDoc);
  outerDoc->SetChildDoc(aChildDoc);
  mChildDocs.AppendElement(aChildDoc->mActorID);
  aChildDoc->mParentDoc = mActorID;

  if (aCreating) {
    ProxyCreated(aChildDoc, Interfaces::DOCUMENT | Interfaces::HYPERTEXT);
  }

  return IPC_OK();
}
Пример #5
0
bool
DocAccessibleParent::RecvHideEvent(const uint64_t& aRootID)
{
  if (mShutdown)
    return true;

  MOZ_DIAGNOSTIC_ASSERT(CheckDocTree());

  // We shouldn't actually need this because mAccessibles shouldn't have an
  // entry for the document itself, but it doesn't hurt to be explicit.
  if (!aRootID) {
    NS_ERROR("trying to hide entire document?");
    return false;
  }

  ProxyEntry* rootEntry = mAccessibles.GetEntry(aRootID);
  if (!rootEntry) {
    NS_ERROR("invalid root being removed!");
    return true;
  }

  ProxyAccessible* root = rootEntry->mProxy;
  if (!root) {
    NS_ERROR("invalid root being removed!");
    return true;
  }

  ProxyAccessible* parent = root->Parent();
  parent->RemoveChild(root);
  root->Shutdown();

  MOZ_DIAGNOSTIC_ASSERT(CheckDocTree());

  return true;
}
bool
DocAccessibleParent::AddChildDoc(DocAccessibleParent* aChildDoc,
                                 uint64_t aParentID, bool aCreating)
{
  // We do not use GetAccessible here because we want to be sure to not get the
  // document it self.
  ProxyEntry* e = mAccessibles.GetEntry(aParentID);
  if (!e)
    return false;

  ProxyAccessible* outerDoc = e->mProxy;
  MOZ_ASSERT(outerDoc);

  // OuterDocAccessibles are expected to only have a document as a child.
  // However for compatibility we tolerate replacing one document with another
  // here.
  if (outerDoc->ChildrenCount() > 1 ||
      (outerDoc->ChildrenCount() == 1 && !outerDoc->ChildAt(0)->IsDoc())) {
    return false;
  }

  aChildDoc->mParent = outerDoc;
  outerDoc->SetChildDoc(aChildDoc);
  mChildDocs.AppendElement(aChildDoc);
  aChildDoc->mParentDoc = this;

  if (aCreating) {
    ProxyCreated(aChildDoc, Interfaces::DOCUMENT | Interfaces::HYPERTEXT);
  }

  return true;
}
Пример #7
0
AtkRole
getRoleCB(AtkObject *aAtkObj)
{
  if (aAtkObj->role != ATK_ROLE_INVALID)
    return aAtkObj->role;

  AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
  a11y::role role;
  if (!accWrap) {
    ProxyAccessible* proxy = GetProxy(aAtkObj);
    if (!proxy)
      return ATK_ROLE_INVALID;

    role = proxy->Role();
  } else {
#ifdef DEBUG
    NS_ASSERTION(nsAccUtils::IsTextInterfaceSupportCorrect(accWrap),
                 "Does not support Text interface when it should");
#endif

    role = accWrap->Role();
  }

#define ROLE(geckoRole, stringRole, atkRole, macRole, \
             msaaRole, ia2Role, nameRule) \
  case roles::geckoRole: \
    aAtkObj->role = atkRole; \
    break;

  switch (role) {
#include "RoleMap.h"
    default:
      MOZ_CRASH("Unknown role.");
  };

#undef ROLE

  if (aAtkObj->role == ATK_ROLE_LIST_BOX && !IsAtkVersionAtLeast(2, 1))
    aAtkObj->role = ATK_ROLE_LIST;
  else if (aAtkObj->role == ATK_ROLE_TABLE_ROW && !IsAtkVersionAtLeast(2, 1))
    aAtkObj->role = ATK_ROLE_LIST_ITEM;
  else if (aAtkObj->role == ATK_ROLE_MATH && !IsAtkVersionAtLeast(2, 12))
    aAtkObj->role = ATK_ROLE_PANEL;
  else if (aAtkObj->role == ATK_ROLE_STATIC && !IsAtkVersionAtLeast(2, 16))
    aAtkObj->role = ATK_ROLE_TEXT;
  else if ((aAtkObj->role == ATK_ROLE_MATH_FRACTION ||
            aAtkObj->role == ATK_ROLE_MATH_ROOT) && !IsAtkVersionAtLeast(2, 16))
    aAtkObj->role = ATK_ROLE_UNKNOWN;

  return aAtkObj->role;
}
Пример #8
0
NS_IMETHODIMP
xpcAccessible::GetId(nsAString& aID)
{
  ProxyAccessible* proxy = IntlGeneric().AsProxy();
  if (!proxy) {
    return NS_ERROR_FAILURE;
  }

  nsString id;
  proxy->DOMNodeID(id);
  aID.Assign(id);

  return NS_OK;
}
uint32_t
DocAccessibleParent::AddSubtree(ProxyAccessible* aParent,
                                const nsTArray<a11y::AccessibleData>& aNewTree,
                                uint32_t aIdx, uint32_t aIdxInParent)
{
  if (aNewTree.Length() <= aIdx) {
    NS_ERROR("bad index in serialized tree!");
    return 0;
  }

  const AccessibleData& newChild = aNewTree[aIdx];
  if (newChild.Role() > roles::LAST_ROLE) {
    NS_ERROR("invalid role");
    return 0;
  }

  if (mAccessibles.Contains(newChild.ID())) {
    NS_ERROR("ID already in use");
    return 0;
  }

  auto role = static_cast<a11y::role>(newChild.Role());

  ProxyAccessible* newProxy =
    new ProxyAccessible(newChild.ID(), aParent, this, role,
                        newChild.Interfaces());

  aParent->AddChildAt(aIdxInParent, newProxy);
  mAccessibles.PutEntry(newChild.ID())->mProxy = newProxy;
  ProxyCreated(newProxy, newChild.Interfaces());

#if defined(XP_WIN)
  WrapperFor(newProxy)->SetID(newChild.MsaaID());
#endif

  uint32_t accessibles = 1;
  uint32_t kids = newChild.ChildrenCount();
  for (uint32_t i = 0; i < kids; i++) {
    uint32_t consumed = AddSubtree(newProxy, aNewTree, aIdx + accessibles, i);
    if (!consumed)
      return 0;

    accessibles += consumed;
  }

  MOZ_ASSERT(newProxy->ChildrenCount() == kids);

  return accessibles;
}
Пример #10
0
bool
DocAccessibleParent::AddChildDoc(DocAccessibleParent* aChildDoc,
                                 uint64_t aParentID)
{
  ProxyAccessible* outerDoc = mAccessibles.GetEntry(aParentID)->mProxy;
  if (!outerDoc)
    return false;

  aChildDoc->mParent = outerDoc;
  outerDoc->SetChildDoc(aChildDoc);
  mChildDocs.AppendElement(aChildDoc);
  aChildDoc->mParentDoc = this;
  ProxyCreated(aChildDoc, 0);
  return true;
}
Пример #11
0
static gboolean
setCurrentValueCB(AtkValue *obj, const GValue *value)
{
  ProxyAccessible* proxy = nullptr;
  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(obj));
  if (!accWrap) {
    proxy = GetProxy(ATK_OBJECT(obj));
    if (!proxy) {
      return FALSE;
    }
  }

  double accValue =g_value_get_double(value);
  return accWrap ? accWrap->SetCurValue(accValue) : proxy->SetCurValue(accValue);
}
bool
ProxyAccessibleWrap::WrapperRangeInfo(double* aCurVal,
                                      double* aMinVal,
                                      double* aMaxVal,
                                      double* aStep)
{
  if (HasNumericValue()) {
    ProxyAccessible* proxy = Proxy();
    *aCurVal = proxy->CurValue();
    *aMinVal = proxy->MinValue();
    *aMaxVal = proxy->MaxValue();
    *aStep = proxy->Step();
    return true;
  }

  return false;
}
Пример #13
0
const gchar *
getDocumentAttributeValueCB(AtkDocument *aDocument,
                            const gchar *aAttrName)
{
  ProxyAccessible* proxy = nullptr;
  DocAccessible* document = nullptr;
  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument));
  if (accWrap) {
    if (!accWrap->IsDoc()) {
      return nullptr;
    }

    document = accWrap->AsDoc();
  } else {
    proxy = GetProxy(ATK_OBJECT(aDocument));
    if (!proxy) {
      return nullptr;
    }
  }

  nsAutoString attrValue;
  if (!strcasecmp(aAttrName, kDocTypeName)) {
    if (document) {
      document->DocType(attrValue);
    } else {
      proxy->DocType(attrValue);
    }
  } else if (!strcasecmp(aAttrName, kDocUrlName)) {
    if (document) {
      document->URL(attrValue);
    } else {
      proxy->URL(attrValue);
    }
  } else if (!strcasecmp(aAttrName, kMimeTypeName)) {
    if (document) {
      document->MimeType(attrValue);
    } else {
      proxy->MimeType(attrValue);
    }
  } else {
    return nullptr;
  }

  return attrValue.IsEmpty() ? nullptr : AccessibleWrap::ReturnString(attrValue);
}
Пример #14
0
bool
DocAccessibleParent::RecvShowEvent(const ShowEventData& aData)
{
  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;
  }

  // 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;
  }

  uint32_t newChildIdx = aData.Idx();
  if (newChildIdx > parent->ChildrenCount()) {
    NS_ERROR("invalid index to add child at");
    return false;
  }

  uint32_t consumed = AddSubtree(parent, aData.NewTree(), 0, newChildIdx);
  MOZ_ASSERT(consumed == aData.NewTree().Length());
#ifdef DEBUG
  for (uint32_t i = 0; i < consumed; i++) {
    uint64_t id = aData.NewTree()[i].ID();
    MOZ_ASSERT(mAccessibles.GetEntry(id));
  }
#endif

  return consumed != 0;
}
bool
DocAccessibleParent::RecvHideEvent(const uint64_t& aRootID,
                                   const bool& aFromUser)
{
  if (mShutdown)
    return true;

  MOZ_DIAGNOSTIC_ASSERT(CheckDocTree());

  // We shouldn't actually need this because mAccessibles shouldn't have an
  // entry for the document itself, but it doesn't hurt to be explicit.
  if (!aRootID) {
    NS_ERROR("trying to hide entire document?");
    return false;
  }

  ProxyEntry* rootEntry = mAccessibles.GetEntry(aRootID);
  if (!rootEntry) {
    NS_ERROR("invalid root being removed!");
    return true;
  }

  ProxyAccessible* root = rootEntry->mProxy;
  if (!root) {
    NS_ERROR("invalid root being removed!");
    return true;
  }

  ProxyAccessible* parent = root->Parent();
  ProxyShowHideEvent(root, parent, false, aFromUser);

  RefPtr<xpcAccHideEvent> event = nullptr;
  if (nsCoreUtils::AccEventObserversExist()) {
    uint32_t type = nsIAccessibleEvent::EVENT_HIDE;
    xpcAccessibleGeneric* xpcAcc = GetXPCAccessible(root);
    xpcAccessibleGeneric* xpcParent = GetXPCAccessible(parent);
    ProxyAccessible* next = root->NextSibling();
    xpcAccessibleGeneric* xpcNext = next ? GetXPCAccessible(next) : nullptr;
    ProxyAccessible* prev = root->PrevSibling();
    xpcAccessibleGeneric* xpcPrev = prev ? GetXPCAccessible(prev) : nullptr;
    xpcAccessibleDocument* doc = GetAccService()->GetXPCDocument(this);
    nsIDOMNode* node = nullptr;
    event = new xpcAccHideEvent(type, xpcAcc, doc, node, aFromUser, xpcParent,
                                xpcNext, xpcPrev);
  }

  parent->RemoveChild(root);
  root->Shutdown();

  MOZ_DIAGNOSTIC_ASSERT(CheckDocTree());

  if (event) {
    nsCoreUtils::DispatchAccEvent(Move(event));
  }

  return true;
}
Пример #16
0
NS_IMETHODIMP
xpcAccessible::GetPreviousSibling(nsIAccessible** aPreviousSibling)
{
  NS_ENSURE_ARG_POINTER(aPreviousSibling);
  *aPreviousSibling = nullptr;
  if (IntlGeneric().IsNull())
    return NS_ERROR_FAILURE;

  if (IntlGeneric().IsAccessible()) {
    nsresult rv = NS_OK;
    NS_IF_ADDREF(*aPreviousSibling = ToXPC(Intl()->GetSiblingAtOffset(-1, &rv)));
    return rv;
  }

  ProxyAccessible* proxy = IntlGeneric().AsProxy();
  NS_ENSURE_STATE(proxy);

  NS_IF_ADDREF(*aPreviousSibling = ToXPC(proxy->PrevSibling()));
  return *aPreviousSibling ? NS_OK : NS_ERROR_FAILURE;
}
Пример #17
0
static void
getMinimumIncrementCB(AtkValue *obj, GValue *minimumIncrement)
{
  ProxyAccessible* proxy = nullptr;
  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(obj));
  if (!accWrap) {
    proxy = GetProxy(ATK_OBJECT(obj));
    if (!proxy) {
      return;
    }
  }

  memset(minimumIncrement,  0, sizeof (GValue));
  double accValue = accWrap ? accWrap->Step() : proxy->Step();
  if (IsNaN(accValue))
    accValue = 0; // zero if the minimum increment is undefined

  g_value_init(minimumIncrement, G_TYPE_DOUBLE);
  g_value_set_double(minimumIncrement, accValue);
}
Пример #18
0
static void
getMinimumValueCB(AtkValue *obj, GValue *value)
{
  ProxyAccessible* proxy = nullptr;
  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(obj));
  if (!accWrap) {
    proxy = GetProxy(ATK_OBJECT(obj));
    if (!proxy) {
      return;
    }
  }

  memset(value,  0, sizeof (GValue));
  double accValue = accWrap ? accWrap->MinValue() : proxy->MinValue();
  if (IsNaN(accValue))
    return;

  g_value_init(value, G_TYPE_DOUBLE);
  g_value_set_double(value, accValue);
}
Пример #19
0
bool
DocAccessibleParent::RecvHideEvent(const uint64_t& aRootID)
{
  ProxyEntry* rootEntry = mAccessibles.GetEntry(aRootID);
  if (!rootEntry) {
    NS_ERROR("invalid root being removed!");
    return true;
  }

  ProxyAccessible* root = rootEntry->mProxy;
  if (!root) {
    NS_ERROR("invalid root being removed!");
    return true;
  }

  ProxyAccessible* parent = root->Parent();
  parent->RemoveChild(root);
  root->Shutdown();

  return true;
}
Пример #20
0
xpcAccessibleGeneric::~xpcAccessibleGeneric()
{
  if (mIntl.IsNull()) {
    return;
  }

  xpcAccessibleDocument* xpcDoc = nullptr;
  if (mIntl.IsAccessible()) {
    Accessible* acc = mIntl.AsAccessible();
    if (!acc->IsDoc() && !acc->IsApplication()) {
      xpcDoc = GetAccService()->GetXPCDocument(acc->Document());
      xpcDoc->NotifyOfShutdown(acc);
    }
  } else {
    ProxyAccessible* proxy = mIntl.AsProxy();
    if (!proxy->IsDoc()) {
      xpcDoc = GetAccService()->GetXPCDocument(proxy->Document());
      xpcDoc->NotifyOfShutdown(proxy);
    }
  }
}
Пример #21
0
static AtkAttributeSet*
getDefaultAttributesCB(AtkText *aText)
{
  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
  if (accWrap) {
    HyperTextAccessible* text = accWrap->AsHyperText();
    if (!text || !text->IsTextRole()) {
      return nullptr;
    }

    nsCOMPtr<nsIPersistentProperties> attributes = text->DefaultTextAttributes();
    return ConvertToAtkTextAttributeSet(attributes);
  }

  ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText));
  if (!proxy) {
    return nullptr;
  }

  nsAutoTArray<Attribute, 10> attrs;
  proxy->DefaultTextAttributes(&attrs);
  return ConvertToAtkTextAttributeSet(attrs);
}
Пример #22
0
bool
DocAccessibleParent::AddChildDoc(DocAccessibleParent* aChildDoc,
                                 uint64_t aParentID, bool aCreating)
{
  // We do not use GetAccessible here because we want to be sure to not get the
  // document it self.
  ProxyEntry* e = mAccessibles.GetEntry(aParentID);
  if (!e)
    return false;

  ProxyAccessible* outerDoc = e->mProxy;
  MOZ_ASSERT(outerDoc);

  aChildDoc->mParent = outerDoc;
  outerDoc->SetChildDoc(aChildDoc);
  mChildDocs.AppendElement(aChildDoc);
  aChildDoc->mParentDoc = this;

  if (aCreating) {
    ProxyCreated(aChildDoc, Interfaces::DOCUMENT | Interfaces::HYPERTEXT);
  }

  return true;
}
Пример #23
0
static AtkAttributeSet*
getRunAttributesCB(AtkText *aText, gint aOffset,
                   gint *aStartOffset,
                   gint *aEndOffset)
{
  *aStartOffset = -1;
  *aEndOffset = -1;
  int32_t startOffset = 0, endOffset = 0;

  AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
  if (accWrap) {
    HyperTextAccessible* text = accWrap->AsHyperText();
    if (!text || !text->IsTextRole()) {
      return nullptr;
    }

    nsCOMPtr<nsIPersistentProperties> attributes =
      text->TextAttributes(false, aOffset, &startOffset, &endOffset);

    *aStartOffset = startOffset;
    *aEndOffset = endOffset;

    return ConvertToAtkTextAttributeSet(attributes);
  }

  ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText));
  if (!proxy) {
    return nullptr;
  }

  nsAutoTArray<Attribute, 10> attrs;
  proxy->TextAttributes(false, aOffset, &attrs, &startOffset, &endOffset);
  *aStartOffset = startOffset;
  *aEndOffset = endOffset;
  return ConvertToAtkTextAttributeSet(attrs);
}
bool
DocAccessibleParent::RecvShowEvent(const ShowEventData& aData,
                                   const bool& aFromUser)
{
  if (mShutdown)
    return true;

  MOZ_DIAGNOSTIC_ASSERT(CheckDocTree());

  if (aData.NewTree().IsEmpty()) {
    NS_ERROR("no children being added");
    return false;
  }

  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 true;
  }

  uint32_t newChildIdx = aData.Idx();
  if (newChildIdx > parent->ChildrenCount()) {
    NS_ERROR("invalid index to add child at");
    return true;
  }

  uint32_t consumed = AddSubtree(parent, aData.NewTree(), 0, newChildIdx);
  MOZ_ASSERT(consumed == aData.NewTree().Length());

  // XXX This shouldn't happen, but if we failed to add children then the below
  // is pointless and can crash.
  if (!consumed) {
    return true;
  }

#ifdef DEBUG
  for (uint32_t i = 0; i < consumed; i++) {
    uint64_t id = aData.NewTree()[i].ID();
    MOZ_ASSERT(mAccessibles.GetEntry(id));
  }
#endif

  MOZ_DIAGNOSTIC_ASSERT(CheckDocTree());

  ProxyAccessible* target = parent->ChildAt(newChildIdx);
  ProxyShowHideEvent(target, parent, true, aFromUser);

  if (!nsCoreUtils::AccEventObserversExist()) {
    return true;
  }

  uint32_t type = nsIAccessibleEvent::EVENT_SHOW;
  xpcAccessibleGeneric* xpcAcc = GetXPCAccessible(target);
  xpcAccessibleDocument* doc = GetAccService()->GetXPCDocument(this);
  nsIDOMNode* node = nullptr;
  RefPtr<xpcAccEvent> event = new xpcAccEvent(type, xpcAcc, doc, node,
                                              aFromUser);
  nsCoreUtils::DispatchAccEvent(Move(event));

  return true;
}