From b854df6dd050da4762eaf75eca1a7a62673b3828 Mon Sep 17 00:00:00 2001 From: Westbrook Johnson Date: Sat, 24 Oct 2020 23:47:34 -0400 Subject: [PATCH] feat(shared): conditionally apply focus-visible polyfill --- package.json | 2 +- packages/shared/src/focus-visible.ts | 49 +++++++++++++++------------- scripts/css-processing.js | 2 +- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index 52a6543b39..a97500661d 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "build": "gulp css && tsc --build packages/**/tsconfig.json", "build:watch": "tsc --build packages/**/tsconfig.json -w", "build:tests": "tsc --build test/tsconfig.json && tsc --build test/tsconfig-node.json", - "build:clear-cache": "rm -rf packages/*/lib && rm -rf packages/*/tsconfig.tsbuildinfo", + "build:clear-cache": "rimraf packages/*/lib && rimraf packages/*/tsconfig.tsbuildinfo", "watch": "gulp watch", "prestorybook": "wca analyze 'packages/*/*.d.ts' --format json --outFile custom-elements.json && node ./scripts/add-custom-properties.js --src='custom-elements.json'", "storybook": "yarn storybook:stories:build && run-p watch build:watch storybook:stories:watch storybook:start", diff --git a/packages/shared/src/focus-visible.ts b/packages/shared/src/focus-visible.ts index fa41550431..8c96c5c63b 100644 --- a/packages/shared/src/focus-visible.ts +++ b/packages/shared/src/focus-visible.ts @@ -36,6 +36,14 @@ type EndPolyfillCoordinationCallback = () => void; import 'focus-visible'; +let hasFocusVisible = true; + +try { + document.body.querySelector(':focus-visible'); +} catch (error) { + hasFocusVisible = false; +} + /** * This mixin function is designed to be applied to a class that inherits * from HTMLElement. It makes it easy for a custom element to coordinate with @@ -108,7 +116,6 @@ export const FocusVisiblePolyfillMixin = < }; const $endPolyfillCoordination = Symbol('endPolyfillCoordination'); - const $polyfillReadyResolver = Symbol('polyfillReadyResolver'); // IE11 doesn't natively support custom elements or JavaScript class // syntax The mixin implementation assumes that the user will take the @@ -116,38 +123,34 @@ export const FocusVisiblePolyfillMixin = < class FocusVisibleCoordinator extends SuperClass { private [$endPolyfillCoordination]: EndPolyfillCoordinationCallback | null = null; - public focusVisiblePolyfillReady!: Promise; - - private [$polyfillReadyResolver]!: () => void; - // Attempt to coordinate with the polyfill when connected to the // document: connectedCallback(): void { super.connectedCallback && super.connectedCallback(); - this.focusVisiblePolyfillReady = new Promise( - (res) => (this[$polyfillReadyResolver] = res) - ); - requestAnimationFrame(() => { - if (this[$endPolyfillCoordination] == null) { - this[$endPolyfillCoordination] = coordinateWithPolyfill( - this - ); - } - this[$polyfillReadyResolver](); - }); + if (!hasFocusVisible) { + requestAnimationFrame(() => { + if (this[$endPolyfillCoordination] == null) { + this[$endPolyfillCoordination] = coordinateWithPolyfill( + this + ); + } + }); + } } disconnectedCallback(): void { super.disconnectedCallback && super.disconnectedCallback(); // It's important to remove the polyfill event listener when we // disconnect, otherwise we will leak the whole element via window: - requestAnimationFrame(() => { - if (this[$endPolyfillCoordination] != null) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - this[$endPolyfillCoordination]!(); - this[$endPolyfillCoordination] = null; - } - }); + if (!hasFocusVisible) { + requestAnimationFrame(() => { + if (this[$endPolyfillCoordination] != null) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + this[$endPolyfillCoordination]!(); + this[$endPolyfillCoordination] = null; + } + }); + } } } diff --git a/scripts/css-processing.js b/scripts/css-processing.js index 6c93faa02d..213d538edb 100644 --- a/scripts/css-processing.js +++ b/scripts/css-processing.js @@ -22,7 +22,6 @@ const postCSSPlugins = (resourcePath) => { require('postcss-preset-env')({ stage: 0, }), - require('postcss-focus-visible')({ preserve: false }), // minify the css with cssnano presets require('cssnano')({ preset: [ @@ -32,6 +31,7 @@ const postCSSPlugins = (resourcePath) => { }, ], }), + require('postcss-focus-visible')(), ]; };