mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1139576 - make accessible creation by tag name faster, r=marcoz
This commit is contained in:
parent
7ec519ab2d
commit
8fb9ff8f4d
111
accessible/base/MarkupMap.h
Normal file
111
accessible/base/MarkupMap.h
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim:expandtab:shiftwidth=2:tabstop=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/. */
|
||||||
|
|
||||||
|
MARKUPMAP(a,
|
||||||
|
New_HTMLLink)
|
||||||
|
|
||||||
|
MARKUPMAP(abbr,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(acronym,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(article,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(aside,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(blockquote,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(dd,
|
||||||
|
New_HTMLDefinition)
|
||||||
|
|
||||||
|
MARKUPMAP(dl,
|
||||||
|
New_HTMLList)
|
||||||
|
|
||||||
|
MARKUPMAP(dt,
|
||||||
|
New_HTMLListitem)
|
||||||
|
|
||||||
|
MARKUPMAP(figcaption,
|
||||||
|
New_HTMLFigcaption)
|
||||||
|
|
||||||
|
MARKUPMAP(figure,
|
||||||
|
New_HTMLFigure)
|
||||||
|
|
||||||
|
MARKUPMAP(form,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(footer,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(header,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(h1,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(h2,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(h3,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(h4,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(h5,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(h6,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(label,
|
||||||
|
New_HTMLLabel)
|
||||||
|
|
||||||
|
MARKUPMAP(legend,
|
||||||
|
New_HTMLLegend)
|
||||||
|
|
||||||
|
MARKUPMAP(li,
|
||||||
|
New_HTMLListitem)
|
||||||
|
|
||||||
|
MARKUPMAP(nav,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(ol,
|
||||||
|
New_HTMLList)
|
||||||
|
|
||||||
|
MARKUPMAP(option,
|
||||||
|
New_HTMLOption)
|
||||||
|
|
||||||
|
MARKUPMAP(optgroup,
|
||||||
|
New_HTMLOptgroup)
|
||||||
|
|
||||||
|
MARKUPMAP(output,
|
||||||
|
New_HTMLOutput)
|
||||||
|
|
||||||
|
MARKUPMAP(progress,
|
||||||
|
New_HTMLProgress)
|
||||||
|
|
||||||
|
MARKUPMAP(q,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(section,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(time,
|
||||||
|
New_HyperText)
|
||||||
|
|
||||||
|
MARKUPMAP(td,
|
||||||
|
New_HTMLTableHeaderCellIfScope)
|
||||||
|
|
||||||
|
MARKUPMAP(th,
|
||||||
|
New_HTMLTableHeaderCell)
|
||||||
|
|
||||||
|
MARKUPMAP(ul,
|
||||||
|
New_HTMLList)
|
@ -133,6 +133,107 @@ MustBeAccessible(nsIContent* aContent, DocAccessible* aDocument)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Accessible constructors
|
||||||
|
|
||||||
|
Accessible*
|
||||||
|
New_HTMLLink(nsIContent* aContent, Accessible* aContext)
|
||||||
|
{
|
||||||
|
// Only some roles truly enjoy life as HTMLLinkAccessibles, for details
|
||||||
|
// see closed bug 494807.
|
||||||
|
nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(aContent);
|
||||||
|
if (roleMapEntry && roleMapEntry->role != roles::NOTHING &&
|
||||||
|
roleMapEntry->role != roles::LINK) {
|
||||||
|
return new HyperTextAccessibleWrap(aContent, aContext->Document());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new HTMLLinkAccessible(aContent, aContext->Document());
|
||||||
|
}
|
||||||
|
|
||||||
|
Accessible* New_HyperText(nsIContent* aContent, Accessible* aContext)
|
||||||
|
{ return new HyperTextAccessibleWrap(aContent, aContext->Document()); }
|
||||||
|
|
||||||
|
Accessible* New_HTMLFigcaption(nsIContent* aContent, Accessible* aContext)
|
||||||
|
{ return new HTMLFigcaptionAccessible(aContent, aContext->Document()); }
|
||||||
|
|
||||||
|
Accessible* New_HTMLFigure(nsIContent* aContent, Accessible* aContext)
|
||||||
|
{ return new HTMLFigureAccessible(aContent, aContext->Document()); }
|
||||||
|
|
||||||
|
Accessible* New_HTMLLegend(nsIContent* aContent, Accessible* aContext)
|
||||||
|
{ return new HTMLLegendAccessible(aContent, aContext->Document()); }
|
||||||
|
|
||||||
|
Accessible* New_HTMLOption(nsIContent* aContent, Accessible* aContext)
|
||||||
|
{ return new HTMLSelectOptionAccessible(aContent, aContext->Document()); }
|
||||||
|
|
||||||
|
Accessible* New_HTMLOptgroup(nsIContent* aContent, Accessible* aContext)
|
||||||
|
{ return new HTMLSelectOptGroupAccessible(aContent, aContext->Document()); }
|
||||||
|
|
||||||
|
Accessible* New_HTMLList(nsIContent* aContent, Accessible* aContext)
|
||||||
|
{ return new HTMLListAccessible(aContent, aContext->Document()); }
|
||||||
|
|
||||||
|
Accessible*
|
||||||
|
New_HTMLListitem(nsIContent* aContent, Accessible* aContext)
|
||||||
|
{
|
||||||
|
// If list item is a child of accessible list then create an accessible for
|
||||||
|
// it unconditionally by tag name. nsBlockFrame creates the list item
|
||||||
|
// accessible for other elements styled as list items.
|
||||||
|
if (aContext->IsList() && aContext->GetContent() == aContent->GetParent())
|
||||||
|
return new HTMLLIAccessible(aContent, aContext->Document());
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Accessible*
|
||||||
|
New_HTMLDefinition(nsIContent* aContent, Accessible* aContext)
|
||||||
|
{
|
||||||
|
if (aContext->IsList())
|
||||||
|
return new HyperTextAccessibleWrap(aContent, aContext->Document());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Accessible* New_HTMLLabel(nsIContent* aContent, Accessible* aContext)
|
||||||
|
{ return new HTMLLabelAccessible(aContent, aContext->Document()); }
|
||||||
|
|
||||||
|
Accessible* New_HTMLOutput(nsIContent* aContent, Accessible* aContext)
|
||||||
|
{ return new HTMLOutputAccessible(aContent, aContext->Document()); }
|
||||||
|
|
||||||
|
Accessible* New_HTMLProgress(nsIContent* aContent, Accessible* aContext)
|
||||||
|
{ return new HTMLProgressMeterAccessible(aContent, aContext->Document()); }
|
||||||
|
|
||||||
|
Accessible*
|
||||||
|
New_HTMLTableHeaderCell(nsIContent* aContent, Accessible* aContext)
|
||||||
|
{
|
||||||
|
if (aContext->IsTableRow() && aContext->GetContent() == aContent->GetParent())
|
||||||
|
return new HTMLTableHeaderCellAccessibleWrap(aContent, aContext->Document());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Accessible*
|
||||||
|
New_HTMLTableHeaderCellIfScope(nsIContent* aContent, Accessible* aContext)
|
||||||
|
{
|
||||||
|
if (aContext->IsTableRow() && aContext->GetContent() == aContent->GetParent() &&
|
||||||
|
aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::scope))
|
||||||
|
return new HTMLTableHeaderCellAccessibleWrap(aContent, aContext->Document());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Markup maps array.
|
||||||
|
|
||||||
|
struct MarkupMapInfo {
|
||||||
|
nsIAtom** tag;
|
||||||
|
New_Accessible* new_func;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MARKUPMAP(atom, new_func) \
|
||||||
|
{ &nsGkAtoms::atom, new_func },
|
||||||
|
|
||||||
|
static const MarkupMapInfo sMarkupMapList[] = {
|
||||||
|
#include "MarkupMap.h"
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef MARKUPMAP
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// nsAccessibilityService
|
// nsAccessibilityService
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -143,7 +244,7 @@ xpcAccessibleApplication* nsAccessibilityService::gXPCApplicationAccessible = nu
|
|||||||
bool nsAccessibilityService::gIsShutdown = true;
|
bool nsAccessibilityService::gIsShutdown = true;
|
||||||
|
|
||||||
nsAccessibilityService::nsAccessibilityService() :
|
nsAccessibilityService::nsAccessibilityService() :
|
||||||
DocManager(), FocusManager()
|
DocManager(), FocusManager(), mMarkupMap(ArrayLength(sMarkupMapList))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -977,9 +1078,11 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
|||||||
if (!isARIATableOrCell ||
|
if (!isARIATableOrCell ||
|
||||||
frame->AccessibleType() == eHTMLTableCellType ||
|
frame->AccessibleType() == eHTMLTableCellType ||
|
||||||
frame->AccessibleType() == eHTMLTableType) {
|
frame->AccessibleType() == eHTMLTableType) {
|
||||||
// Prefer to use markup (mostly tag name, perhaps attributes) to decide if
|
// Prefer to use markup to decide if and what kind of accessible to create,
|
||||||
// and what kind of accessible to create,
|
New_Accessible* new_func = mMarkupMap.Get(content->NodeInfo()->NameAtom());
|
||||||
newAcc = CreateHTMLAccessibleByMarkup(frame, content, aContext);
|
if (new_func)
|
||||||
|
newAcc = new_func(content, aContext);
|
||||||
|
|
||||||
if (!newAcc) // try by frame accessible type.
|
if (!newAcc) // try by frame accessible type.
|
||||||
newAcc = CreateAccessibleByFrameType(frame, content, aContext);
|
newAcc = CreateAccessibleByFrameType(frame, content, aContext);
|
||||||
}
|
}
|
||||||
@ -1116,6 +1219,9 @@ nsAccessibilityService::Init()
|
|||||||
static const char16_t kInitIndicator[] = { '1', 0 };
|
static const char16_t kInitIndicator[] = { '1', 0 };
|
||||||
observerService->NotifyObservers(nullptr, "a11y-init-or-shutdown", kInitIndicator);
|
observerService->NotifyObservers(nullptr, "a11y-init-or-shutdown", kInitIndicator);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < ArrayLength(sMarkupMapList); i++)
|
||||||
|
mMarkupMap.Put(*sMarkupMapList[i].tag, sMarkupMapList[i].new_func);
|
||||||
|
|
||||||
#ifdef A11Y_LOG
|
#ifdef A11Y_LOG
|
||||||
logging::CheckEnv();
|
logging::CheckEnv();
|
||||||
#endif
|
#endif
|
||||||
@ -1373,143 +1479,6 @@ nsAccessibilityService::CreateAccessibleByType(nsIContent* aContent,
|
|||||||
return accessible.forget();
|
return accessible.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<Accessible>
|
|
||||||
nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame* aFrame,
|
|
||||||
nsIContent* aContent,
|
|
||||||
Accessible* aContext)
|
|
||||||
{
|
|
||||||
DocAccessible* document = aContext->Document();
|
|
||||||
if (aContext->IsTableRow()) {
|
|
||||||
if (nsCoreUtils::IsHTMLTableHeader(aContent) &&
|
|
||||||
aContext->GetContent() == aContent->GetParent()) {
|
|
||||||
nsRefPtr<Accessible> accessible =
|
|
||||||
new HTMLTableHeaderCellAccessibleWrap(aContent, document);
|
|
||||||
return accessible.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This method assumes we're in an HTML namespace.
|
|
||||||
if (aContent->IsHTMLElement(nsGkAtoms::figcaption)) {
|
|
||||||
nsRefPtr<Accessible> accessible =
|
|
||||||
new HTMLFigcaptionAccessible(aContent, document);
|
|
||||||
return accessible.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aContent->IsHTMLElement(nsGkAtoms::figure)) {
|
|
||||||
nsRefPtr<Accessible> accessible =
|
|
||||||
new HTMLFigureAccessible(aContent, document);
|
|
||||||
return accessible.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aContent->IsHTMLElement(nsGkAtoms::legend)) {
|
|
||||||
nsRefPtr<Accessible> accessible =
|
|
||||||
new HTMLLegendAccessible(aContent, document);
|
|
||||||
return accessible.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aContent->IsHTMLElement(nsGkAtoms::option)) {
|
|
||||||
nsRefPtr<Accessible> accessible =
|
|
||||||
new HTMLSelectOptionAccessible(aContent, document);
|
|
||||||
return accessible.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aContent->IsHTMLElement(nsGkAtoms::optgroup)) {
|
|
||||||
nsRefPtr<Accessible> accessible =
|
|
||||||
new HTMLSelectOptGroupAccessible(aContent, document);
|
|
||||||
return accessible.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aContent->IsAnyOfHTMLElements(nsGkAtoms::ul,
|
|
||||||
nsGkAtoms::ol,
|
|
||||||
nsGkAtoms::dl)) {
|
|
||||||
nsRefPtr<Accessible> accessible =
|
|
||||||
new HTMLListAccessible(aContent, document);
|
|
||||||
return accessible.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aContent->IsHTMLElement(nsGkAtoms::a)) {
|
|
||||||
// Only some roles truly enjoy life as HTMLLinkAccessibles, for details
|
|
||||||
// see closed bug 494807.
|
|
||||||
nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(aContent);
|
|
||||||
if (roleMapEntry && roleMapEntry->role != roles::NOTHING &&
|
|
||||||
roleMapEntry->role != roles::LINK) {
|
|
||||||
nsRefPtr<Accessible> accessible =
|
|
||||||
new HyperTextAccessibleWrap(aContent, document);
|
|
||||||
return accessible.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<Accessible> accessible =
|
|
||||||
new HTMLLinkAccessible(aContent, document);
|
|
||||||
return accessible.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aContext->IsList()) {
|
|
||||||
// If list item is a child of accessible list then create an accessible for
|
|
||||||
// it unconditionally by tag name. nsBlockFrame creates the list item
|
|
||||||
// accessible for other elements styled as list items.
|
|
||||||
if (aContext->GetContent() == aContent->GetParent()) {
|
|
||||||
if (aContent->IsAnyOfHTMLElements(nsGkAtoms::dt, nsGkAtoms::li)) {
|
|
||||||
nsRefPtr<Accessible> accessible =
|
|
||||||
new HTMLLIAccessible(aContent, document);
|
|
||||||
return accessible.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aContent->IsHTMLElement(nsGkAtoms::dd)) {
|
|
||||||
nsRefPtr<Accessible> accessible =
|
|
||||||
new HyperTextAccessibleWrap(aContent, document);
|
|
||||||
return accessible.forget();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aContent->IsAnyOfHTMLElements(nsGkAtoms::abbr,
|
|
||||||
nsGkAtoms::acronym,
|
|
||||||
nsGkAtoms::article,
|
|
||||||
nsGkAtoms::aside,
|
|
||||||
nsGkAtoms::blockquote,
|
|
||||||
nsGkAtoms::form,
|
|
||||||
nsGkAtoms::footer,
|
|
||||||
nsGkAtoms::header,
|
|
||||||
nsGkAtoms::h1,
|
|
||||||
nsGkAtoms::h2,
|
|
||||||
nsGkAtoms::h3,
|
|
||||||
nsGkAtoms::h4,
|
|
||||||
nsGkAtoms::h5,
|
|
||||||
nsGkAtoms::h6,
|
|
||||||
nsGkAtoms::nav,
|
|
||||||
nsGkAtoms::q,
|
|
||||||
nsGkAtoms::section,
|
|
||||||
nsGkAtoms::time)) {
|
|
||||||
nsRefPtr<Accessible> accessible =
|
|
||||||
new HyperTextAccessibleWrap(aContent, document);
|
|
||||||
return accessible.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aContent->IsHTMLElement(nsGkAtoms::label)) {
|
|
||||||
nsRefPtr<Accessible> accessible =
|
|
||||||
new HTMLLabelAccessible(aContent, document);
|
|
||||||
return accessible.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aContent->IsHTMLElement(nsGkAtoms::output)) {
|
|
||||||
nsRefPtr<Accessible> accessible =
|
|
||||||
new HTMLOutputAccessible(aContent, document);
|
|
||||||
return accessible.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aContent->IsHTMLElement(nsGkAtoms::progress)) {
|
|
||||||
nsRefPtr<Accessible> accessible =
|
|
||||||
new HTMLProgressMeterAccessible(aContent, document);
|
|
||||||
return accessible.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<Accessible>
|
already_AddRefed<Accessible>
|
||||||
nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame,
|
nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame,
|
||||||
nsIContent* aContent,
|
nsIContent* aContent,
|
||||||
|
@ -41,6 +41,8 @@ SelectionManager* SelectionMgr();
|
|||||||
ApplicationAccessible* ApplicationAcc();
|
ApplicationAccessible* ApplicationAcc();
|
||||||
xpcAccessibleApplication* XPCApplicationAcc();
|
xpcAccessibleApplication* XPCApplicationAcc();
|
||||||
|
|
||||||
|
typedef Accessible* (New_Accessible)(nsIContent* aContent, Accessible* aContext);
|
||||||
|
|
||||||
} // namespace a11y
|
} // namespace a11y
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
@ -190,13 +192,6 @@ private:
|
|||||||
already_AddRefed<Accessible>
|
already_AddRefed<Accessible>
|
||||||
CreateAccessibleByType(nsIContent* aContent, DocAccessible* aDoc);
|
CreateAccessibleByType(nsIContent* aContent, DocAccessible* aDoc);
|
||||||
|
|
||||||
/**
|
|
||||||
* Create accessible for HTML node by tag name.
|
|
||||||
*/
|
|
||||||
already_AddRefed<Accessible>
|
|
||||||
CreateHTMLAccessibleByMarkup(nsIFrame* aFrame, nsIContent* aContent,
|
|
||||||
Accessible* aContext);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an accessible whose type depends on the given frame.
|
* Create an accessible whose type depends on the given frame.
|
||||||
*/
|
*/
|
||||||
@ -228,6 +223,8 @@ private:
|
|||||||
*/
|
*/
|
||||||
static bool gIsShutdown;
|
static bool gIsShutdown;
|
||||||
|
|
||||||
|
nsDataHashtable<nsPtrHashKey<const nsIAtom>, mozilla::a11y::New_Accessible*> mMarkupMap;
|
||||||
|
|
||||||
friend nsAccessibilityService* GetAccService();
|
friend nsAccessibilityService* GetAccService();
|
||||||
friend mozilla::a11y::FocusManager* mozilla::a11y::FocusMgr();
|
friend mozilla::a11y::FocusManager* mozilla::a11y::FocusMgr();
|
||||||
friend mozilla::a11y::SelectionManager* mozilla::a11y::SelectionMgr();
|
friend mozilla::a11y::SelectionManager* mozilla::a11y::SelectionMgr();
|
||||||
|
Loading…
Reference in New Issue
Block a user