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

feat(rule): Label and Name from Content mismatch WCAG21 (Issue #1149) #1335

Merged
merged 44 commits into from
Feb 21, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
8c80f14
chore(WIP): rewrite accessibleText
WilcoFiers Sep 20, 2018
82e5c74
Merge branch 'develop' into a11y-name
WilcoFiers Sep 26, 2018
9d2451e
chore: More refactoring for accname
WilcoFiers Sep 26, 2018
305c864
chore(WIP): More improvements to accessibleName
WilcoFiers Oct 10, 2018
8501f34
feat: Reimplement accessible name computation
WilcoFiers Oct 10, 2018
dec7220
chore: All accessible name tests passing
WilcoFiers Oct 13, 2018
abb0673
chore(accName): All tests passing
WilcoFiers Oct 13, 2018
4de5489
chore: Add tests
WilcoFiers Nov 9, 2018
a98448b
chore: Test form-control-value
WilcoFiers Nov 23, 2018
e264958
chore: Merge develop
WilcoFiers Nov 23, 2018
1aded4a
chore: Refactor and add docs to accessible-text
WilcoFiers Nov 24, 2018
6e67b52
chore: Add tests for namedFromContents
WilcoFiers Nov 25, 2018
2a5020e
chore: Refactor subtreeText method
WilcoFiers Nov 25, 2018
6ff002b
chore: Refactor native accessible text methods
WilcoFiers Nov 25, 2018
4c6c351
chore: Coverage for text.labelText
WilcoFiers Dec 3, 2018
6917ec9
Merge branch 'develop' into a11y-name
WilcoFiers Jan 7, 2019
73ded40
Merge branch 'develop' into a11y-name
jeeyyy Jan 23, 2019
2244ed2
fix: update to axe.commons.matches usage
jeeyyy Jan 23, 2019
6c35b51
Merge branch 'develop' into a11y-name
jeeyyy Jan 23, 2019
9bddd36
test: fix nativeTextboxValue tests
jeeyyy Jan 23, 2019
3f9a969
test: fix failing tests
jeeyyy Jan 25, 2019
1227102
chore: merge from develop
jeeyyy Jan 25, 2019
dfa1bd7
fix: compute includeHidden as a part of accessibleName fn
jeeyyy Jan 25, 2019
d0f45e7
fix: do not mutate context in accessibleText
jeeyyy Jan 25, 2019
c3a1bdc
Merge branch 'develop' into a11y-name
jeeyyy Jan 25, 2019
ef1c638
feat: rule for label and name from content mismatch
jeeyyy Jan 28, 2019
14b09b6
Merge branch 'develop' into new-rule-lcnm
jeeyyy Jan 28, 2019
7412de8
Merge branch 'develop' into new-rule-lcnm
jeeyyy Feb 1, 2019
d615dbe
fix: refactor based on review and add unicode computation
jeeyyy Feb 6, 2019
ad9aa2d
Merge branch 'develop' into new-rule-lcnm
jeeyyy Feb 6, 2019
ec2af57
Merge branch 'develop' into new-rule-lcnm
jeeyyy Feb 12, 2019
b21e631
Merge branch 'develop' into new-rule-lcnm
jeeyyy Feb 12, 2019
3945006
refactor: update based on code review
jeeyyy Feb 12, 2019
2b07290
test: update test
jeeyyy Feb 12, 2019
6696c5d
Merge branch 'develop' into new-rule-lcnm
jeeyyy Feb 18, 2019
9afed3f
Merge branch 'develop' into new-rule-lcnm
jeeyyy Feb 18, 2019
b18226f
chore: fix linting errors
jeeyyy Feb 18, 2019
866fe88
Merge branch 'develop' into new-rule-lcnm
jeeyyy Feb 19, 2019
5fefd54
refactor: updates based on code review
jeeyyy Feb 19, 2019
56e4680
merge from develop
jeeyyy Feb 19, 2019
fd003e7
Merge branch 'develop' into new-rule-lcnm
jeeyyy Feb 20, 2019
072711d
refactor: unicode and punctuation methods
jeeyyy Feb 20, 2019
eabb7dd
Merge branch 'develop' into new-rule-lcnm
jeeyyy Feb 21, 2019
92489be
test: update tests
jeeyyy Feb 21, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions lib/checks/label/label-content-name-mismatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,17 @@ function isStringContained(compare, compareWith) {
}

/**
* Curate given text, by removing emoji's, punctuations, unicode and trimming.
* Curate given text, by removing emoji's, punctuations, unicode and trim whitespace.
*
* @param {String} str given text to curate
* @returns {String}
*/
function curateString(str) {
return text.sanitize(
text.replacePunctuation(
text.replaceNonBmpUnicode(text.replaceEmojiUnicode(str))
)
const noEmojiUnicodeStr = text.replaceUnicode(str, (type = 'emoji'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not:

text.replaceUnicode(str, {
  emoji: true,
  nonBmp: true,
  punctuations: true
})

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Firstly, unicode only comprises emoji and nonBmp at the moment. Punctuations are handled separately. I wouldn't want to mix and match everything into the same options object as it can get verbose.

Hence went with the simpler type=* argument.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After discussion, updated as agreed.

const noNonBmpUnicodeStr = text.replaceUnicode(
noEmojiUnicodeStr,
(type = 'nonBmp')
);
const noPunctuationsStr = text.replacePunctuation(noNonBmpUnicodeStr);
return text.sanitize(noPunctuationsStr);
}
25 changes: 13 additions & 12 deletions lib/commons/text/is-human-interpretable.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,13 @@ text.isHumanInterpretable = function(str) {
}

// Step 1
if (str.length === 1) {
const alphaNumericIconMap = [
'x', // close
'i' // info
];
// Step 1a
if (alphaNumericIconMap.includes(str)) {
return 0;
}
const alphaNumericIconMap = [
'x', // close
'i' // info
];
// Step 1a
if (alphaNumericIconMap.includes(str)) {
return 0;
}

// Step 2 - handle punctuation
Expand All @@ -47,9 +45,12 @@ text.isHumanInterpretable = function(str) {

// Step 3
// a - check for astral (non bilingual multi plane unicode)
if (
!text.sanitize(text.replaceNonBmpUnicode(text.replaceEmojiUnicode(str)))
) {
const noEmojiUnicodeStr = text.replaceUnicode(str, (type = 'emoji'));
const noNonBmpUnicodeStr = text.replaceUnicode(
noEmojiUnicodeStr,
(type = 'nonBmp')
);
if (!text.sanitize(noNonBmpUnicodeStr)) {
return 0;
}

Expand Down
80 changes: 35 additions & 45 deletions lib/commons/text/unicode.js
Original file line number Diff line number Diff line change
@@ -1,72 +1,62 @@
/* global text */

/**
* Regex for matching unicode values out of Basic Multilingual Plane (BMP)
*
* Reference:
* - https://github.com/mathiasbynens/regenerate
* - https://unicode-table.com/
* - https://mathiasbynens.be/notes/javascript-unicode
* -
*/

/**
* Determine if a given string contains code points that are not from basic multilingual plane
* Determine if a given string contains unicode character points of specified type
* Allowed type(s):
* - 'nonBmp' -> Non Bilingual Multi Plane
* - 'emoji' -> Emoji
*
* @method isNonBmpUnicode
* @method hasUnicode
* @memberof axe.commons.text
* @instance
* @param {String} str string to verify
* @param {String} type type of unicode character set
* @returns {Boolean}
*/
text.isNonBmpUnicode = function isNonBmpUnicode(str) {
return getUnicodeNonBmpRegExp().test(str);
text.hasUnicode = function hasUnicode(str, type = 'nonBmp') {
switch (type.toLowerCase()) {
case 'emoji':
return axe.imports.emojiRegexText().test(str);
case 'nonbmp':
default:
return getUnicodeNonBmpRegExp().test(str);
}
};

/**
* Replace non basic multilingual plane characters with supplied alternative
* Replace specified type unicode characters with supplied alternative
* Allowed type(s):
* - 'nonBmp' -> Non Bilingual Multi Plane
* - 'emoji' -> Emoji
*
* @method replaceNonBmpUnicode
* @method replaceUnicode
* @memberof axe.commons.text
* @instance
* @param {String} str string to operate on
* @param {String} type type of unicode character set
* @param {String} replaceWith alternative character for replacement
* @returns {String}
*/
text.replaceNonBmpUnicode = function replaceNonBmpUnicode(
text.replaceUnicode = function replaceUnicode(
str,
type = 'nonBmp',
replaceWith = ''
) {
return str.replace(getUnicodeNonBmpRegExp(), replaceWith);
};

/**
* Determine if a given string contains emoji
*
* @method isEmojiUnicode
* @memberof axe.commons.text
* @instance
* @param {String} str string to verify
* @returns {Boolean}
*/
text.isEmojiUnicode = function isEmojiUnicode(str) {
return axe.imports.emojiRegexText().test(str);
};

/**
* Replace astral plane unicode with a given replacement value
*
* @method replaceEmojiUnicode
* @memberof axe.commons.text
* @instance
* @param {String} str string to operate on
* @returns {String}
*/
text.replaceEmojiUnicode = function replaceEmojiUnicode(str, replaceWith = '') {
return str.replace(axe.imports.emojiRegexText(), replaceWith);
switch (type.toLowerCase()) {
case 'emoji':
return str.replace(axe.imports.emojiRegexText(), replaceWith);
case 'nonbmp':
default:
return str.replace(getUnicodeNonBmpRegExp(), replaceWith);
}
};

/**
* Get regular expression for matching unicode
* Regex for matching unicode values out of Basic Multilingual Plane (BMP)
* Reference:
* - https://github.com/mathiasbynens/regenerate
* - https://unicode-table.com/
* - https://mathiasbynens.be/notes/javascript-unicode
*
* @returns {RegExp}
*/
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
"clone": "~2.1.1",
"css-selector-parser": "^1.3.0",
"dot": "~1.1.2",
"emoji-regex": "^7.0.3",
"emoji-regex": "7.0.3",
"es6-promise": "^4.2.5",
"eslint": "^5.9.0",
"eslint-config-prettier": "^3.4.0",
Expand Down
11 changes: 4 additions & 7 deletions test/commons/text/accessible-text.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ describe('text.accessibleTextVirtual', function() {

var target = axe.utils.querySelectorAll(axe._tree, '#t1')[0];
assert.equal(
axe.commons.text.accessibleTextVirtual(target, { debug: true }),
axe.commons.text.accessibleTextVirtual(target),
'This is a hidden secret'
);
});
Expand Down Expand Up @@ -260,7 +260,7 @@ describe('text.accessibleTextVirtual', function() {
// Chrome returns: This is This is a label of
// Firefox returns: This is ARIA Label
assert.equal(
axe.commons.text.accessibleTextVirtual(target, { debug: true }),
axe.commons.text.accessibleTextVirtual(target),
'This is This is a label of'
);
});
Expand Down Expand Up @@ -520,10 +520,7 @@ describe('text.accessibleTextVirtual', function() {
axe._tree = axe.utils.getFlattenedTree(fixture);

var target = axe.utils.querySelectorAll(axe._tree, 'a')[0];
assert.equal(
axe.commons.text.accessibleTextVirtual(target, { debug: true }),
'Hello'
);
assert.equal(axe.commons.text.accessibleTextVirtual(target), 'Hello');
});

it('should give text even for role=none on buttons', function() {
Expand Down Expand Up @@ -2895,7 +2892,7 @@ describe('text.accessibleTextVirtual', function() {
// Chrome 70: "My name is Garaventa the weird. (QED) Where are my marbles?"
// Firefox 62: "Hello, My name is Eli the weird. (QED)"
assert.equal(
accessibleText(target, { debug: true }),
accessibleText(target),
'My name is Eli the weird. (QED) Where are my marbles?'
);
});
Expand Down
Loading