From b9dd81bafe54a95e9d9b731b875965d3dda02a5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Oddsson?= Date: Fri, 12 Nov 2021 13:38:09 +0000 Subject: [PATCH 1/4] Add missing `package-lock.json` file --- package-lock.json | 328 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 328 insertions(+) diff --git a/package-lock.json b/package-lock.json index cefb2b3..1d0ed26 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "eslint": "^7.25.0", "eslint-plugin-custom-elements": "^0.0.2", "eslint-plugin-github": "^4.1.3", + "http-server": "^14.0.0", "karma": "^6.3.2", "karma-chai": "^0.1.0", "karma-chrome-launcher": "^3.1.0", @@ -547,6 +548,15 @@ "node": ">=8" } }, + "node_modules/async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -571,6 +581,24 @@ "node": "^4.5.0 || >= 5.9" } }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dev": true, + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/basic-auth/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -874,6 +902,15 @@ "node": ">= 0.10" } }, + "node_modules/corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -2110,6 +2147,18 @@ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/http-errors": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", @@ -2146,6 +2195,45 @@ "node": ">=6.0.0" } }, + "node_modules/http-server": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.0.0.tgz", + "integrity": "sha512-XTePIXAo5x72bI8SlKFSqsg7UuSHwsOa4+RJIe56YeMUvfTvGDy7TxFkTEhfIRmM/Dnf6x29ut541ythSBZdkQ==", + "dev": true, + "dependencies": { + "basic-auth": "^2.0.1", + "colors": "^1.4.0", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.5", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + }, + "bin": { + "http-server": "bin/http-server" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-server/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -2766,6 +2854,18 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/mocha": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", @@ -3148,6 +3248,15 @@ "wrappy": "1" } }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "bin": { + "opener": "bin/opener-bin.js" + } + }, "node_modules/optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -3315,6 +3424,29 @@ "node": ">=4" } }, + "node_modules/portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "dev": true, + "dependencies": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -3663,6 +3795,12 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "node_modules/secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha1-8aAymzCLIh+uN7mXTz1XjQypmeM=", + "dev": true + }, "node_modules/semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -4173,6 +4311,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dev": true, + "dependencies": { + "qs": "^6.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -4200,6 +4350,12 @@ "punycode": "^2.1.0" } }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true + }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -4243,6 +4399,30 @@ "node": ">=0.10.0" } }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -4856,6 +5036,15 @@ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -4874,6 +5063,23 @@ "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", "dev": true }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -5122,6 +5328,12 @@ "vary": "^1" } }, + "corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", + "dev": true + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -6091,6 +6303,15 @@ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, + "html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "requires": { + "whatwg-encoding": "^2.0.0" + } + }, "http-errors": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", @@ -6123,6 +6344,35 @@ "requires-port": "^1.0.0" } }, + "http-server": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.0.0.tgz", + "integrity": "sha512-XTePIXAo5x72bI8SlKFSqsg7UuSHwsOa4+RJIe56YeMUvfTvGDy7TxFkTEhfIRmM/Dnf6x29ut541ythSBZdkQ==", + "dev": true, + "requires": { + "basic-auth": "^2.0.1", + "colors": "^1.4.0", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.5", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + }, + "dependencies": { + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + } + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -6597,6 +6847,15 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "mocha": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", @@ -6870,6 +7129,12 @@ "wrappy": "1" } }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true + }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -6989,6 +7254,28 @@ "find-up": "^2.1.0" } }, + "portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "dev": true, + "requires": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -7221,6 +7508,12 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha1-8aAymzCLIh+uN7mXTz1XjQypmeM=", + "dev": true + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -7611,6 +7904,15 @@ "which-boxed-primitive": "^1.0.2" } }, + "union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dev": true, + "requires": { + "qs": "^6.4.0" + } + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -7632,6 +7934,12 @@ "punycode": "^2.1.0" } }, + "url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true + }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -7666,6 +7974,26 @@ "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", "dev": true }, + "whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "requires": { + "iconv-lite": "0.6.3" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", From 34b07f8644653643aabd59342e7c7a186bc85d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Oddsson?= Date: Fri, 12 Nov 2021 13:38:28 +0000 Subject: [PATCH 2/4] Inline all the screen reader announcements By inlining the screen reader announcement text we remove a layer of indirection. --- src/autocomplete.ts | 14 ++++---------- src/screen-reader-announcements.ts | 19 ------------------- 2 files changed, 4 insertions(+), 29 deletions(-) delete mode 100644 src/screen-reader-announcements.ts diff --git a/src/autocomplete.ts b/src/autocomplete.ts index 12e2d6f..b09d24d 100644 --- a/src/autocomplete.ts +++ b/src/autocomplete.ts @@ -1,12 +1,6 @@ import type AutocompleteElement from './auto-complete-element' import debounce from './debounce' import {fragment} from './send' -import { - createOptionsHiddenString, - createOptionsString, - createOptionsWithAutoselectString, - createSelectionString -} from './screen-reader-announcements' import Combobox from '@github/combobox-nav' // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -122,11 +116,11 @@ export default class Autocomplete { this.container.open = false if (selected instanceof HTMLAnchorElement) return const value = selected.getAttribute('data-autocomplete-value') || selected.textContent! - this.updateFeedbackForScreenReaders(createSelectionString(selected.textContent || '')) + this.updateFeedbackForScreenReaders(`${selected.textContent || ''} selected.`) this.container.value = value if (!value) { - this.updateFeedbackForScreenReaders(createOptionsHiddenString()) + this.updateFeedbackForScreenReaders(`Suggestions hidden.`) } } @@ -187,10 +181,10 @@ export default class Autocomplete { const firstOptionValue = firstOption?.textContent if (this.autoselectEnabled && firstOptionValue) { this.updateFeedbackForScreenReaders( - createOptionsWithAutoselectString(numOptions.toString(), firstOptionValue) + `${numOptions} suggested options. Press Enter to select ${firstOptionValue}.` ) } else { - this.updateFeedbackForScreenReaders(createOptionsString(numOptions.toString())) + this.updateFeedbackForScreenReaders(`${numOptions} suggested options.`) } this.container.open = hasResults diff --git a/src/screen-reader-announcements.ts b/src/screen-reader-announcements.ts deleted file mode 100644 index a3541f3..0000000 --- a/src/screen-reader-announcements.ts +++ /dev/null @@ -1,19 +0,0 @@ -export function createAutoselectString(firstOption: string): string { - return `Press Enter to select ${firstOption}.` -} - -export function createOptionsString(numOptions: string): string { - return `${numOptions} suggested options.` -} - -export function createOptionsHiddenString(): string { - return `Suggestions hidden.` -} - -export function createSelectionString(selectionText: string): string { - return `${selectionText} selected.` -} - -export function createOptionsWithAutoselectString(numOptions: string, firstOption: string): string { - return `${createOptionsString(numOptions)} ${createAutoselectString(firstOption)}` -} From ee9a3632431921a62469544e28f930aad20cd2f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Oddsson?= Date: Fri, 12 Nov 2021 13:52:33 +0000 Subject: [PATCH 3/4] Replace `sr-update` event dispatch with a MutationObserver The event fired has no effect in production which indicates that it shouldn't be in the code at all. What we want to do in the tests is to wait for the feedback element to have text so we should instead use a MutationObserver to wait for the element to change before running our assertion. --- test/test.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/test/test.js b/test/test.js index 450632d..c1b8a8a 100644 --- a/test/test.js +++ b/test/test.js @@ -89,11 +89,9 @@ describe('auto-complete element', function () { triggerInput(input, 'hub') await once(container, 'loadend') - await once(container, 'sr-update') + await waitForElementToChange(feedback) - if (feedback) { - assert.equal('5 suggested options.', feedback.innerHTML) - } + assert.equal('5 suggested options.', feedback.innerHTML) }) it('commits on Enter', async function () { @@ -220,15 +218,26 @@ describe('auto-complete element', function () { triggerInput(input, 'hub') await once(container, 'loadend') + await waitForElementToChange(feedback) - await once(container, 'sr-update') + assert.equal(`5 suggested options. Press Enter to select first.`, feedback.innerHTML) + }) + }) +}) - if (feedback) { - assert.equal(`5 suggested options. Press Enter to select first.`, feedback.innerHTML) +function waitForElementToChange(el) { + return new Promise(resolve => { + const observer = new MutationObserver(mutations => { + for (const mutation of mutations) { + if (mutation.addedNodes.length > 0) { + observer.disconnect() + resolve() + } } }) + observer.observe(el, {childList: true, subtree: true}) }) -}) +} function once(element, eventName) { return new Promise(resolve => { From 35dc743ac7dfd748dfd11f2d83edea654017f506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Oddsson?= Date: Fri, 12 Nov 2021 14:05:29 +0000 Subject: [PATCH 4/4] Inline listbox ID in tests We remove a level of indirection by inlining the list box ID. It's more apparent to the reader of the tests what elements are being referred to without having to find the definition of the `listboxId` variable. --- test/test.js | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/test/test.js b/test/test.js index c1b8a8a..703b57c 100644 --- a/test/test.js +++ b/test/test.js @@ -1,5 +1,3 @@ -const listboxId = 'popup' - describe('auto-complete element', function () { describe('element creation', function () { it('creates from document.createElement', function () { @@ -19,8 +17,8 @@ describe('auto-complete element', function () {
-
    -
    + +
    ` @@ -29,7 +27,7 @@ describe('auto-complete element', function () { it('requests html fragment', async function () { const container = document.querySelector('auto-complete') const input = container.querySelector('input') - const popup = container.querySelector(`#${listboxId}`) + const popup = container.querySelector(`#popup`) triggerInput(input, 'hub') await once(container, 'loadend') @@ -40,7 +38,7 @@ describe('auto-complete element', function () { it('respects arrow keys', async function () { const container = document.querySelector('auto-complete') const input = container.querySelector('input') - const popup = container.querySelector(`#${listboxId}`) + const popup = container.querySelector(`#popup`) assert.isTrue(keydown(input, 'ArrowDown')) triggerInput(input, 'hub') @@ -85,7 +83,7 @@ describe('auto-complete element', function () { it('summarizes the available options on keypress', async function () { const container = document.querySelector('auto-complete') const input = container.querySelector('input') - const feedback = container.querySelector(`#${listboxId}-feedback`) + const feedback = container.querySelector(`#popup-feedback`) triggerInput(input, 'hub') await once(container, 'loadend') @@ -112,7 +110,7 @@ describe('auto-complete element', function () { it('does not commit on disabled option', async function () { const container = document.querySelector('auto-complete') const input = container.querySelector('input') - const popup = container.querySelector(`#${listboxId}`) + const popup = container.querySelector(`#popup`) triggerInput(input, 'hub') await once(container, 'loadend') @@ -165,7 +163,7 @@ describe('auto-complete element', function () { it('closes on Escape', async function () { const container = document.querySelector('auto-complete') const input = container.querySelector('input') - const popup = container.querySelector(`#${listboxId}`) + const popup = container.querySelector(`#popup`) triggerInput(input, 'hub') await once(container, 'loadend') @@ -180,7 +178,7 @@ describe('auto-complete element', function () { it('opens and closes on alt + ArrowDown and alt + ArrowUp', async function () { const container = document.querySelector('auto-complete') const input = container.querySelector('input') - const popup = container.querySelector(`#${listboxId}`) + const popup = container.querySelector(`#popup`) triggerInput(input, 'hub') await once(container, 'loadend') @@ -204,8 +202,8 @@ describe('auto-complete element', function () {
    -
      -
      + +
      ` @@ -214,7 +212,7 @@ describe('auto-complete element', function () { it('summarizes the available options and informs what will happen on Enter', async function () { const container = document.querySelector('auto-complete') const input = container.querySelector('input') - const feedback = container.querySelector(`#${listboxId}-feedback`) + const feedback = container.querySelector(`#popup-feedback`) triggerInput(input, 'hub') await once(container, 'loadend')