Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move getCodiconAriaLabel to iconLabels #171262

Merged
merged 4 commits into from
Jan 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 0 additions & 11 deletions src/vs/base/common/codicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,9 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { ThemeIcon } from 'vs/base/common/themables';
import { isString } from 'vs/base/common/types';

// Selects all codicon names encapsulated in the `$()` syntax and wraps the
// results with spaces so that screen readers can read the text better.
export function getCodiconAriaLabel(text: string | undefined) {
if (!text) {
return '';
}

return text.replace(/\$\((.*?)\)/g, (_match, codiconName) => ` ${codiconName} `).trim();
}

const _codiconFontCharacters: { [id: string]: number } = Object.create(null);

function register(id: string, fontCharacter: number | string): ThemeIcon {
Expand Down
19 changes: 19 additions & 0 deletions src/vs/base/common/iconLabels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export function markdownEscapeEscapedIcons(text: string): string {
}

const stripIconsRegex = new RegExp(`(\\s)?(\\\\)?${iconsRegex.source}(\\s)?`, 'g');

/**
* Takes a label with icons (`$(iconId)xyz`) and strips the icons out (`xyz`)
*/
export function stripIcons(text: string): string {
if (text.indexOf(iconStartMarker) === -1) {
return text;
Expand All @@ -32,13 +36,28 @@ export function stripIcons(text: string): string {
}


/**
* Takes a label with icons (`$(iconId)xyz`), removes the icon syntax adds whitespace so that screen readers can read the text better.
*/
export function getCodiconAriaLabel(text: string | undefined) {
if (!text) {
return '';
}

return text.replace(/\$\((.*?)\)/g, (_match, codiconName) => ` ${codiconName} `).trim();
}


export interface IParsedLabelWithIcons {
readonly text: string;
readonly iconOffsets?: readonly number[];
}

const _parseIconsRegex = new RegExp(`\\$\\(${ThemeIcon.iconNameCharacter}+\\)`, 'g');

/**
* Takes a label with icons (`abc $(iconId)xyz`) and returns the text (`abc xyz`) and the offsets of the icons (`[3]`)
*/
export function parseLabelWithIcons(input: string): IParsedLabelWithIcons {

_parseIconsRegex.lastIndex = 0;
Expand Down
3 changes: 1 addition & 2 deletions src/vs/base/parts/quickinput/browser/quickInputList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ import { IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/lis
import { IListAccessibilityProvider, IListOptions, IListStyles, List } from 'vs/base/browser/ui/list/listWidget';
import { IAction } from 'vs/base/common/actions';
import { range } from 'vs/base/common/arrays';
import { getCodiconAriaLabel } from 'vs/base/common/codicons';
import { compareAnything } from 'vs/base/common/comparers';
import { memoize } from 'vs/base/common/decorators';
import { Emitter, Event } from 'vs/base/common/event';
import { IMatch } from 'vs/base/common/filters';
import { IParsedLabelWithIcons, matchesFuzzyIconAware, parseLabelWithIcons } from 'vs/base/common/iconLabels';
import { getCodiconAriaLabel, IParsedLabelWithIcons, matchesFuzzyIconAware, parseLabelWithIcons } from 'vs/base/common/iconLabels';
import { KeyCode } from 'vs/base/common/keyCodes';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import * as platform from 'vs/base/common/platform';
Expand Down
28 changes: 0 additions & 28 deletions src/vs/base/test/common/codicons.test.ts

This file was deleted.

22 changes: 21 additions & 1 deletion src/vs/base/test/common/iconLabels.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import * as assert from 'assert';
import { IMatch } from 'vs/base/common/filters';
import { escapeIcons, IParsedLabelWithIcons, markdownEscapeEscapedIcons, matchesFuzzyIconAware, parseLabelWithIcons, stripIcons } from 'vs/base/common/iconLabels';
import { escapeIcons, getCodiconAriaLabel, IParsedLabelWithIcons, markdownEscapeEscapedIcons, matchesFuzzyIconAware, parseLabelWithIcons, stripIcons } from 'vs/base/common/iconLabels';

interface IIconFilter {
// Returns null if word doesn't match.
Expand All @@ -21,6 +21,26 @@ function filterOk(filter: IIconFilter, word: string, target: IParsedLabelWithIco
}

suite('Icon Labels', () => {

test('Can get proper aria labels', () => {
// note, the spaces in the results are important
const testCases = new Map<string, string>([
['', ''],
['asdf', 'asdf'],
['asdf$(squirrel)asdf', 'asdf squirrel asdf'],
['asdf $(squirrel) asdf', 'asdf squirrel asdf'],
['$(rocket)asdf', 'rocket asdf'],
['$(rocket) asdf', 'rocket asdf'],
['$(rocket)$(rocket)$(rocket)asdf', 'rocket rocket rocket asdf'],
['$(rocket) asdf $(rocket)', 'rocket asdf rocket'],
['$(rocket)asdf$(rocket)', 'rocket asdf rocket'],
]);

for (const [input, expected] of testCases) {
assert.strictEqual(getCodiconAriaLabel(input), expected);
}
});

test('matchesFuzzyIconAware', () => {

// Camel Case
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/api/browser/mainThreadStatusBar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/ext
import { dispose } from 'vs/base/common/lifecycle';
import { Command } from 'vs/editor/common/languages';
import { IAccessibilityInformation } from 'vs/platform/accessibility/common/accessibility';
import { getCodiconAriaLabel } from 'vs/base/common/codicons';
import { IMarkdownString } from 'vs/base/common/htmlContent';
import { getCodiconAriaLabel } from 'vs/base/common/iconLabels';

@extHostNamedCustomer(MainContext.MainThreadStatusBar)
export class MainThreadStatusBar implements MainThreadStatusBarShape {
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/contrib/remote/browser/remoteIndicator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { truncate } from 'vs/base/common/strings';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { getRemoteName } from 'vs/platform/remote/common/remoteHosts';
import { getVirtualWorkspaceLocation } from 'vs/platform/workspace/common/virtualWorkspace';
import { getCodiconAriaLabel } from 'vs/base/common/codicons';
import { getCodiconAriaLabel } from 'vs/base/common/iconLabels';
import { ILogService } from 'vs/platform/log/common/log';
import { ReloadWindowAction } from 'vs/workbench/browser/actions/windowActions';
import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
Expand Down