Skip to content

Commit

Permalink
v1.2.3
Browse files Browse the repository at this point in the history
  • Loading branch information
mynamesleon committed Nov 1, 2020
1 parent 6e2c787 commit 79af457
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 11 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

All notable changes to this project will be documented in this file.

## [1.2.2] - 2020-11-01
## [1.2.3] - 2020-11-01

### Fixed

- The `create` option not applying to starting values.
- The `create` option persistence now correctly only applies when the autocomplete is used to progressively enhance a `<select>` or checkbox list.
- Various HTML injection risks, particularly with the `create` and `onItemRender` options.

## [1.2.0] - 2020-10-31

Expand Down Expand Up @@ -85,7 +86,7 @@ All notable changes to this project will be documented in this file.
- Issue when clicking on a single-select autocomplete with minLength of 0 with a current selection, which was correctly searching with an empty string, but the polling method was then triggering a search with the value afterwards.
- Screen reader announcements for results ignoring the number of results rendered

[1.2.2]: https://github.com/mynamesleon/aria-autocomplete/compare/v1.2.0...v1.2.2
[1.2.3]: https://github.com/mynamesleon/aria-autocomplete/compare/v1.2.0...v1.2.3
[1.2.0]: https://github.com/mynamesleon/aria-autocomplete/compare/v1.1.4...v1.2.0
[1.1.4]: https://github.com/mynamesleon/aria-autocomplete/compare/v1.1.3...v1.1.4
[1.1.3]: https://github.com/mynamesleon/aria-autocomplete/compare/v1.1.2...v1.1.3
Expand Down
2 changes: 1 addition & 1 deletion dist/aria-autocomplete.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "aria-autocomplete",
"version": "1.2.2",
"version": "1.2.3",
"description": "Accessible, extensible, JavaScript autocomplete with multi-select",
"main": "dist/aria-autocomplete.min.js",
"style": "dist/aria-autocomplete.css",
Expand Down
11 changes: 10 additions & 1 deletion src/autocomplete-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,14 @@ export const KEYCODES = {
UP: 38,
RIGHT: 39,
DOWN: 40,
DELETE: 46
DELETE: 46,
};

export const UNESCAPED_HTML_REGEX = /[&<>"']/g;
export const HTML_REPLACEMENTS = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#39;',
};
12 changes: 11 additions & 1 deletion src/autocomplete-helpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CLEANED_LABEL_PROP } from './autocomplete-constants';
import { CLEANED_LABEL_PROP, UNESCAPED_HTML_REGEX, HTML_REPLACEMENTS } from './autocomplete-constants';

/**
* remove start and end whitespace from string
Expand All @@ -7,6 +7,16 @@ export function trimString(theString?: any): string {
return theString == null ? '' : (theString + '').trim();
}

/**
* convert &, <, >, ", and ' in a string to their HTML entities
*/
export function escapeHtml(value: string): string {
if (typeof value !== 'string' || !value) {
return '';
}
return value.replace(UNESCAPED_HTML_REGEX, (character) => HTML_REPLACEMENTS[character]);
}

const REGEX_AMPERSAND = /&/g;
const REGEX_DUPE_WHITESPACE = /\s\s+/g;
const REGEX_TO_IGNORE = /[\u2018\u2019',:\u2013-]/g;
Expand Down
13 changes: 9 additions & 4 deletions src/autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {

import {
trimString,
escapeHtml,
cleanString,
mergeObjects,
dispatchEvent,
Expand Down Expand Up @@ -846,11 +847,11 @@ export default class Autocomplete {
for (let i = 0; i < lengthToUse; i += 1) {
const thisSource: any = this.filteredSource[i];
const callbackResponse = checkCallback && this.triggerOptionCallback('onItemRender', [thisSource]);
const itemContent = callbackResponse || thisSource.label;
const itemContent = typeof callbackResponse === 'string' ? callbackResponse : thisSource.label;
toShow.push(
`<li tabindex="-1" aria-selected="false" role="option" class="${optionClassName}" ` +
`id="${optionId}--${i}" aria-posinset="${i + 1}" ` +
`aria-setsize="${lengthToUse}">${itemContent}</li>`
`aria-setsize="${lengthToUse}">${escapeHtml(itemContent)}</li>`
);
}

Expand All @@ -869,7 +870,9 @@ export default class Autocomplete {
const { noResultsText: noText } = this.options;
if (noResults && typeof noText === 'string' && noText.length) {
announce = noText;
toShow.push(`<li class="${optionClassName} ${optionClassName}--no-results">${noText}</li>`);
toShow.push(
`<li class="${optionClassName} ${optionClassName}--no-results">${escapeHtml(noText)}</li>`
);
}

// remove loading class(es) and reset variables
Expand Down Expand Up @@ -1766,7 +1769,9 @@ export default class Autocomplete {
);

// add the screen reader assistance element
newHtml.push(`<p id="${this.ids.SR_ASSISTANCE}" style="display:none;">${o.srAssistiveText}</p>`);
newHtml.push(
`<p id="${this.ids.SR_ASSISTANCE}" style="display:none;">${escapeHtml(o.srAssistiveText)}</p>`
);

// close all and append
newHtml.push(`</div>`);
Expand Down

0 comments on commit 79af457

Please sign in to comment.