f44eae4912
A block quote role exists in all of WAI-ARIA 1.3 (role "blockquote", [1]), IAccessible2 (`IA2_ROLE_BLOCK_QUOTE`, [2]) and AT-SPI (`ROLE_BLOCK_QUOTE`, [3]). Take over the definition that is the same in WAI-ARIA and IAccessible2: > A section of content that is quoted from another source. The intended use for now is for a Writer paragraph using the "Block Quotation" paragraph style, similar to how the HEADING role is used for paragraphs using a corresponding paragraph style. For gtk3 (ATK) and winaccessibility (IAccessible2), map the new role to the equivalant roles. For macOS and the gtk4 as well as the Qt-based VCL plugins on Linux which currently don't have an equivalent role, fall back to the same role that the PARAGRAPH role is mapped to. This way, the behavior there will remain unchanged once the BLOCK_QUOTE role is used for Writer paragraphs with the corresponding style. In general, treat BLOCK_QUOTE like PARAGRAPH in code applying special handling for the PARAGRAPH role. [1] https://w3c.github.io/aria/#blockquote [2]3d8c7f0b83/api/AccessibleRole.idl (L318)
[3]7cc4cee53d/xml/Accessible.xml (L615-616)
Change-Id: I248c183a2e7ec5d6f0a89bf3cb4829bbd8588c77 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158573 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
296 lines
15 KiB
Text
296 lines
15 KiB
Text
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* 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/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
|
|
#include <osx/a11yfactory.h>
|
|
|
|
#include "a11yrolehelper.h"
|
|
|
|
#include <com/sun/star/accessibility/AccessibleRole.hpp>
|
|
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
|
|
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
|
|
|
|
#include <sal/log.hxx>
|
|
|
|
using namespace ::com::sun::star::accessibility;
|
|
using namespace ::com::sun::star::lang;
|
|
using namespace ::com::sun::star::uno;
|
|
|
|
@implementation AquaA11yRoleHelper
|
|
|
|
+(id)simpleMapNativeRoleFrom: (XAccessibleContext *) accessibleContext {
|
|
id nativeRole = nil;
|
|
|
|
if (accessibleContext == nullptr)
|
|
return nativeRole;
|
|
|
|
switch( accessibleContext -> getAccessibleRole() ) {
|
|
#define MAP(a,b) \
|
|
case a: nativeRole = b; break
|
|
|
|
MAP( AccessibleRole::UNKNOWN, NSAccessibilityUnknownRole );
|
|
MAP( AccessibleRole::ALERT, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::BLOCK_QUOTE, NSAccessibilityTextAreaRole );
|
|
MAP( AccessibleRole::COLUMN_HEADER, NSAccessibilityColumnRole );
|
|
MAP( AccessibleRole::CANVAS, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::CHECK_BOX, NSAccessibilityCheckBoxRole );
|
|
MAP( AccessibleRole::CHECK_MENU_ITEM, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::COLOR_CHOOSER, NSAccessibilityColorWellRole ); // FIXME
|
|
MAP( AccessibleRole::COMBO_BOX, NSAccessibilityComboBoxRole );
|
|
MAP( AccessibleRole::DATE_EDITOR, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::DESKTOP_ICON, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::DESKTOP_PANE, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::DIRECTORY_PANE, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::DIALOG, NSAccessibilityGroupRole );
|
|
MAP( AccessibleRole::DOCUMENT, NSAccessibilityGroupRole );
|
|
MAP( AccessibleRole::EMBEDDED_OBJECT, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::END_NOTE, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::FILE_CHOOSER, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::FILLER, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::FONT_CHOOSER, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::FOOTER, NSAccessibilityGroupRole ); // FIXME
|
|
MAP( AccessibleRole::FOOTNOTE, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::FRAME, NSAccessibilityWindowRole );
|
|
MAP( AccessibleRole::GLASS_PANE, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::GRAPHIC, NSAccessibilityImageRole );
|
|
MAP( AccessibleRole::GROUP_BOX, NSAccessibilityGroupRole );
|
|
MAP( AccessibleRole::HEADER, NSAccessibilityGroupRole ); // FIXME
|
|
MAP( AccessibleRole::HEADING, NSAccessibilityTextAreaRole ); // FIXME
|
|
MAP( AccessibleRole::HYPER_LINK, NSAccessibilityLinkRole );
|
|
MAP( AccessibleRole::ICON, NSAccessibilityImageRole );
|
|
MAP( AccessibleRole::INTERNAL_FRAME, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::LABEL, NSAccessibilityStaticTextRole );
|
|
MAP( AccessibleRole::LAYERED_PANE, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::LIST, NSAccessibilityMenuRole );
|
|
MAP( AccessibleRole::LIST_ITEM, NSAccessibilityMenuItemRole );
|
|
MAP( AccessibleRole::MENU, NSAccessibilityMenuRole );
|
|
MAP( AccessibleRole::MENU_BAR, NSAccessibilityMenuBarRole );
|
|
MAP( AccessibleRole::MENU_ITEM, NSAccessibilityMenuItemRole );
|
|
MAP( AccessibleRole::OPTION_PANE, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::PAGE_TAB, NSAccessibilityButtonRole );
|
|
MAP( AccessibleRole::PAGE_TAB_LIST, NSAccessibilityTabGroupRole );
|
|
MAP( AccessibleRole::PANEL, NSAccessibilityGroupRole );
|
|
MAP( AccessibleRole::PARAGRAPH, NSAccessibilityTextAreaRole );
|
|
MAP( AccessibleRole::PASSWORD_TEXT, NSAccessibilityTextFieldRole );
|
|
MAP( AccessibleRole::POPUP_MENU, NSAccessibilityMenuRole );
|
|
MAP( AccessibleRole::PUSH_BUTTON, NSAccessibilityButtonRole );
|
|
MAP( AccessibleRole::PROGRESS_BAR, NSAccessibilityProgressIndicatorRole );
|
|
MAP( AccessibleRole::RADIO_BUTTON, NSAccessibilityRadioButtonRole );
|
|
MAP( AccessibleRole::RADIO_MENU_ITEM, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::ROW_HEADER, NSAccessibilityRowRole );
|
|
MAP( AccessibleRole::ROOT_PANE, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::SCROLL_BAR, NSAccessibilityScrollBarRole );
|
|
MAP( AccessibleRole::SCROLL_PANE, NSAccessibilityScrollAreaRole );
|
|
MAP( AccessibleRole::SHAPE, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::SEPARATOR, NSAccessibilitySplitterRole ); // FIXME
|
|
MAP( AccessibleRole::SLIDER, NSAccessibilitySliderRole );
|
|
MAP( AccessibleRole::SPIN_BOX, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::SPLIT_PANE, NSAccessibilitySplitGroupRole );
|
|
MAP( AccessibleRole::STATUS_BAR, NSAccessibilityGroupRole ); // FIXME
|
|
MAP( AccessibleRole::TABLE, NSAccessibilityTableRole );
|
|
MAP( AccessibleRole::TABLE_CELL, NSAccessibilityTextFieldRole );
|
|
MAP( AccessibleRole::TEXT, NSAccessibilityTextAreaRole );
|
|
MAP( AccessibleRole::TEXT_FRAME, NSAccessibilityGroupRole );
|
|
MAP( AccessibleRole::TOGGLE_BUTTON, NSAccessibilityCheckBoxRole );
|
|
MAP( AccessibleRole::TOOL_BAR, NSAccessibilityToolbarRole );
|
|
MAP( AccessibleRole::TOOL_TIP, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::TREE, NSAccessibilityGroupRole );
|
|
MAP( AccessibleRole::VIEW_PORT, NSAccessibilityUnknownRole ); // FIXME
|
|
MAP( AccessibleRole::WINDOW, NSAccessibilityWindowRole );
|
|
|
|
MAP( AccessibleRole::BUTTON_DROPDOWN, NSAccessibilityMenuButtonRole );
|
|
MAP( AccessibleRole::BUTTON_MENU, NSAccessibilityMenuButtonRole );
|
|
MAP( AccessibleRole::CAPTION, NSAccessibilityUnknownRole );
|
|
MAP( AccessibleRole::CHART, NSAccessibilityUnknownRole );
|
|
MAP( AccessibleRole::FORM, NSAccessibilityUnknownRole );
|
|
MAP( AccessibleRole::IMAGE_MAP, NSAccessibilityUnknownRole );
|
|
MAP( AccessibleRole::NOTE, NSAccessibilityUnknownRole );
|
|
MAP( AccessibleRole::PAGE, NSAccessibilityUnknownRole );
|
|
MAP( AccessibleRole::RULER, NSAccessibilityUnknownRole );
|
|
MAP( AccessibleRole::SECTION, NSAccessibilityUnknownRole );
|
|
MAP( AccessibleRole::TREE_ITEM, NSAccessibilityUnknownRole );
|
|
MAP( AccessibleRole::TREE_TABLE, NSAccessibilityUnknownRole );
|
|
|
|
MAP( AccessibleRole::DOCUMENT_PRESENTATION, NSAccessibilityGroupRole );
|
|
MAP( AccessibleRole::DOCUMENT_SPREADSHEET, NSAccessibilityGroupRole );
|
|
MAP( AccessibleRole::DOCUMENT_TEXT, NSAccessibilityGroupRole );
|
|
MAP( AccessibleRole::STATIC, NSAccessibilityStaticTextRole );
|
|
MAP( AccessibleRole::NOTIFICATION, NSAccessibilityStaticTextRole );
|
|
|
|
#undef MAP
|
|
default:
|
|
break;
|
|
}
|
|
return nativeRole;
|
|
}
|
|
|
|
+(id)getNativeRoleFrom: (XAccessibleContext *) accessibleContext {
|
|
id nativeRole = [ AquaA11yRoleHelper simpleMapNativeRoleFrom: accessibleContext ];
|
|
if ( accessibleContext -> getAccessibleRole() == AccessibleRole::LABEL ) {
|
|
if ( accessibleContext -> getAccessibleChildCount() > 0 ) {
|
|
[ nativeRole release ];
|
|
nativeRole = NSAccessibilityOutlineRole;
|
|
} else if ( accessibleContext -> getAccessibleParent().is() ) {
|
|
Reference < XAccessibleContext > rxParentContext = accessibleContext -> getAccessibleParent() -> getAccessibleContext();
|
|
if ( rxParentContext.is() ) {
|
|
NSString * roleParent = static_cast<NSString *>([ AquaA11yRoleHelper simpleMapNativeRoleFrom: rxParentContext.get() ]);
|
|
if ( [ roleParent isEqualToString: NSAccessibilityOutlineRole ] ) {
|
|
[ nativeRole release ];
|
|
nativeRole = NSAccessibilityRowRole;
|
|
}
|
|
[ roleParent release ];
|
|
}
|
|
}
|
|
} else if ( accessibleContext -> getAccessibleRole() == AccessibleRole::COMBO_BOX ) {
|
|
try {
|
|
Reference < XAccessible > rxAccessible = accessibleContext -> getAccessibleChild(0);
|
|
if ( rxAccessible.is() ) {
|
|
Reference < XAccessibleContext > rxAccessibleContext = rxAccessible -> getAccessibleContext();
|
|
if ( rxAccessibleContext.is() && rxAccessibleContext -> getAccessibleRole() == AccessibleRole::TEXT ) {
|
|
sal_Int64 nStateSet = rxAccessibleContext -> getAccessibleStateSet();
|
|
if ( !(nStateSet & AccessibleStateType::EDITABLE ) ) {
|
|
[ nativeRole release ];
|
|
nativeRole = NSAccessibilityPopUpButtonRole;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (const IndexOutOfBoundsException&)
|
|
{
|
|
SAL_WARN("vcl", "No valid accessible objects in parent");
|
|
}
|
|
}
|
|
return nativeRole;
|
|
}
|
|
|
|
+(id)getNativeSubroleFrom: (sal_Int16) nRole {
|
|
id nativeSubrole = nil;
|
|
switch( nRole ) {
|
|
#define MAP(a,b) \
|
|
case a: nativeSubrole = b; break
|
|
|
|
MAP( AccessibleRole::UNKNOWN, NSAccessibilityUnknownSubrole );
|
|
MAP( AccessibleRole::ALERT, NSAccessibilitySystemDialogSubrole );
|
|
MAP( AccessibleRole::BLOCK_QUOTE, @"" );
|
|
MAP( AccessibleRole::COLUMN_HEADER, @"" );
|
|
MAP( AccessibleRole::CANVAS, @"" );
|
|
MAP( AccessibleRole::CHECK_BOX, @"" );
|
|
MAP( AccessibleRole::CHECK_MENU_ITEM, @"" );
|
|
MAP( AccessibleRole::COLOR_CHOOSER, @"" );
|
|
MAP( AccessibleRole::COMBO_BOX, @"" );
|
|
MAP( AccessibleRole::DATE_EDITOR, @"" );
|
|
MAP( AccessibleRole::DESKTOP_ICON, @"" );
|
|
MAP( AccessibleRole::DESKTOP_PANE, @"" );
|
|
MAP( AccessibleRole::DIRECTORY_PANE, @"" );
|
|
MAP( AccessibleRole::DIALOG, NSAccessibilityDialogSubrole );
|
|
MAP( AccessibleRole::DOCUMENT, @"" );
|
|
MAP( AccessibleRole::EMBEDDED_OBJECT, @"" );
|
|
MAP( AccessibleRole::END_NOTE, @"" );
|
|
MAP( AccessibleRole::FILE_CHOOSER, @"" );
|
|
MAP( AccessibleRole::FILLER, @"" );
|
|
MAP( AccessibleRole::FONT_CHOOSER, @"" );
|
|
MAP( AccessibleRole::FOOTER, @"" );
|
|
MAP( AccessibleRole::FOOTNOTE, @"" );
|
|
MAP( AccessibleRole::FRAME, @"" );
|
|
MAP( AccessibleRole::GLASS_PANE, @"" );
|
|
MAP( AccessibleRole::GRAPHIC, @"" );
|
|
MAP( AccessibleRole::GROUP_BOX, @"" );
|
|
MAP( AccessibleRole::HEADER, @"" );
|
|
MAP( AccessibleRole::HEADING, @"" );
|
|
MAP( AccessibleRole::HYPER_LINK, NSAccessibilityTextLinkSubrole );
|
|
MAP( AccessibleRole::ICON, @"" );
|
|
MAP( AccessibleRole::INTERNAL_FRAME, @"" );
|
|
MAP( AccessibleRole::LABEL, @"" );
|
|
MAP( AccessibleRole::LAYERED_PANE, @"" );
|
|
MAP( AccessibleRole::LIST, @"" );
|
|
MAP( AccessibleRole::LIST_ITEM, NSAccessibilityOutlineRowSubrole );
|
|
MAP( AccessibleRole::MENU, @"" );
|
|
MAP( AccessibleRole::MENU_BAR, @"" );
|
|
MAP( AccessibleRole::MENU_ITEM, @"" );
|
|
MAP( AccessibleRole::OPTION_PANE, @"" );
|
|
MAP( AccessibleRole::PAGE_TAB, @"" );
|
|
MAP( AccessibleRole::PAGE_TAB_LIST, @"" );
|
|
MAP( AccessibleRole::PANEL, @"" );
|
|
MAP( AccessibleRole::PARAGRAPH, @"" );
|
|
MAP( AccessibleRole::PASSWORD_TEXT, NSAccessibilitySecureTextFieldSubrole );
|
|
MAP( AccessibleRole::POPUP_MENU, @"" );
|
|
MAP( AccessibleRole::PUSH_BUTTON, @"" );
|
|
MAP( AccessibleRole::PROGRESS_BAR, @"" );
|
|
MAP( AccessibleRole::RADIO_BUTTON, @"" );
|
|
MAP( AccessibleRole::RADIO_MENU_ITEM, @"" );
|
|
MAP( AccessibleRole::ROW_HEADER, @"" );
|
|
MAP( AccessibleRole::ROOT_PANE, @"" );
|
|
MAP( AccessibleRole::SCROLL_BAR, @"" );
|
|
MAP( AccessibleRole::SCROLL_PANE, @"" );
|
|
MAP( AccessibleRole::SHAPE, @"" );
|
|
MAP( AccessibleRole::SEPARATOR, @"" );
|
|
MAP( AccessibleRole::SLIDER, @"" );
|
|
MAP( AccessibleRole::SPIN_BOX, @"" );
|
|
MAP( AccessibleRole::SPLIT_PANE, @"" );
|
|
MAP( AccessibleRole::STATUS_BAR, @"" );
|
|
MAP( AccessibleRole::TABLE, @"" );
|
|
MAP( AccessibleRole::TABLE_CELL, @"" );
|
|
MAP( AccessibleRole::TEXT, @"" );
|
|
MAP( AccessibleRole::TEXT_FRAME, @"" );
|
|
MAP( AccessibleRole::TOGGLE_BUTTON, @"" );
|
|
MAP( AccessibleRole::TOOL_BAR, @"" );
|
|
MAP( AccessibleRole::TOOL_TIP, @"" );
|
|
MAP( AccessibleRole::TREE, @"" );
|
|
MAP( AccessibleRole::VIEW_PORT, @"" );
|
|
MAP( AccessibleRole::WINDOW, NSAccessibilityStandardWindowSubrole );
|
|
|
|
MAP( AccessibleRole::BUTTON_DROPDOWN, @"" );
|
|
MAP( AccessibleRole::BUTTON_MENU, @"" );
|
|
MAP( AccessibleRole::CAPTION, @"" );
|
|
MAP( AccessibleRole::CHART, @"" );
|
|
MAP( AccessibleRole::FORM, @"" );
|
|
MAP( AccessibleRole::IMAGE_MAP, @"" );
|
|
MAP( AccessibleRole::NOTE, @"" );
|
|
MAP( AccessibleRole::PAGE, @"" );
|
|
MAP( AccessibleRole::RULER, @"" );
|
|
MAP( AccessibleRole::SECTION, @"" );
|
|
MAP( AccessibleRole::TREE_ITEM, @"" );
|
|
MAP( AccessibleRole::TREE_TABLE, @"" );
|
|
|
|
MAP( AccessibleRole::DOCUMENT_PRESENTATION, @"" );
|
|
MAP( AccessibleRole::DOCUMENT_SPREADSHEET, @"" );
|
|
MAP( AccessibleRole::DOCUMENT_TEXT, @"" );
|
|
|
|
MAP( AccessibleRole::STATIC, @"" );
|
|
MAP( AccessibleRole::NOTIFICATION, @"" );
|
|
|
|
#undef MAP
|
|
default:
|
|
break;
|
|
}
|
|
return nativeSubrole;
|
|
}
|
|
|
|
+(id)getRoleDescriptionFrom: (NSString *) role with: (NSString *) subRole {
|
|
id roleDescription;
|
|
if ( [ subRole length ] == 0 )
|
|
roleDescription = NSAccessibilityRoleDescription( role, nil );
|
|
else
|
|
roleDescription = NSAccessibilityRoleDescription( role, subRole );
|
|
return roleDescription;
|
|
}
|
|
|
|
@end
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|