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
008bcbebc1
commit
9c6b92383f
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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -143,7 +244,7 @@ xpcAccessibleApplication* nsAccessibilityService::gXPCApplicationAccessible = nu
|
||||
bool nsAccessibilityService::gIsShutdown = true;
|
||||
|
||||
nsAccessibilityService::nsAccessibilityService() :
|
||||
DocManager(), FocusManager()
|
||||
DocManager(), FocusManager(), mMarkupMap(ArrayLength(sMarkupMapList))
|
||||
{
|
||||
}
|
||||
|
||||
@ -977,9 +1078,11 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
||||
if (!isARIATableOrCell ||
|
||||
frame->AccessibleType() == eHTMLTableCellType ||
|
||||
frame->AccessibleType() == eHTMLTableType) {
|
||||
// Prefer to use markup (mostly tag name, perhaps attributes) to decide if
|
||||
// and what kind of accessible to create,
|
||||
newAcc = CreateHTMLAccessibleByMarkup(frame, content, aContext);
|
||||
// Prefer to use markup to decide if and what kind of accessible to create,
|
||||
New_Accessible* new_func = mMarkupMap.Get(content->NodeInfo()->NameAtom());
|
||||
if (new_func)
|
||||
newAcc = new_func(content, aContext);
|
||||
|
||||
if (!newAcc) // try by frame accessible type.
|
||||
newAcc = CreateAccessibleByFrameType(frame, content, aContext);
|
||||
}
|
||||
@ -1116,6 +1219,9 @@ nsAccessibilityService::Init()
|
||||
static const char16_t kInitIndicator[] = { '1', 0 };
|
||||
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
|
||||
logging::CheckEnv();
|
||||
#endif
|
||||
@ -1373,143 +1479,6 @@ nsAccessibilityService::CreateAccessibleByType(nsIContent* aContent,
|
||||
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>
|
||||
nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame,
|
||||
nsIContent* aContent,
|
||||
|
@ -41,6 +41,8 @@ SelectionManager* SelectionMgr();
|
||||
ApplicationAccessible* ApplicationAcc();
|
||||
xpcAccessibleApplication* XPCApplicationAcc();
|
||||
|
||||
typedef Accessible* (New_Accessible)(nsIContent* aContent, Accessible* aContext);
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
@ -190,13 +192,6 @@ private:
|
||||
already_AddRefed<Accessible>
|
||||
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.
|
||||
*/
|
||||
@ -228,6 +223,8 @@ private:
|
||||
*/
|
||||
static bool gIsShutdown;
|
||||
|
||||
nsDataHashtable<nsPtrHashKey<const nsIAtom>, mozilla::a11y::New_Accessible*> mMarkupMap;
|
||||
|
||||
friend nsAccessibilityService* GetAccService();
|
||||
friend mozilla::a11y::FocusManager* mozilla::a11y::FocusMgr();
|
||||
friend mozilla::a11y::SelectionManager* mozilla::a11y::SelectionMgr();
|
||||
|
Loading…
Reference in New Issue
Block a user