Commit e1f314b3 authored by Robert Knight's avatar Robert Knight

Gracefully abort startup in old browsers

Run a series of feature tests at the very start of the boot process and
abort with a console warning if they fail.

We display a console warning rather than a louder warning to avoid being
disruptive on sites maintained by publishers which embed Hypothesis and
which still want to support older browsers. On those sites the
Hypothesis annotation feature will simply be missing.
parent 60100581
/**
* Run a series of representative feature tests to see if the browser is new
* enough to support Hypothesis.
*
* We use feature tests to try to avoid false negatives, accepting some risk of
* false positives due to the host page having loaded polyfills for APIs in order
* to support older browsers.
*
* @return {boolean}
*/
export function isBrowserSupported() {
const checks = [
// ES APIs.
() => Promise.resolve(),
() => new Map(),
// DOM API checks for frequently-used APIs.
() => new URL(document.location.href), // URL constructor.
() => new Request('https://hypothes.is'), // Part of the `fetch` API.
// DOM API checks for less frequently-used APIs.
// These are less likely to have been polyfilled by the host page.
() => document.evaluate('/html/body', document), // XPath evaluation.
];
try {
checks.forEach(check => check());
return true;
} catch (err) {
return false;
}
}
...@@ -13,14 +13,24 @@ import { jsonConfigsFrom } from '../shared/settings'; ...@@ -13,14 +13,24 @@ import { jsonConfigsFrom } from '../shared/settings';
import boot from './boot'; import boot from './boot';
import processUrlTemplate from './url-template'; import processUrlTemplate from './url-template';
import { isBrowserSupported } from './browser-check';
const settings = jsonConfigsFrom(document); if (isBrowserSupported()) {
const settings = jsonConfigsFrom(document);
boot(document, { boot(document, {
assetRoot: processUrlTemplate(settings.assetRoot || '__ASSET_ROOT__'), assetRoot: processUrlTemplate(settings.assetRoot || '__ASSET_ROOT__'),
// @ts-ignore - `__MANIFEST__` is injected by the build script // @ts-ignore - `__MANIFEST__` is injected by the build script
manifest: __MANIFEST__, manifest: __MANIFEST__,
sidebarAppUrl: processUrlTemplate( sidebarAppUrl: processUrlTemplate(
settings.sidebarAppUrl || '__SIDEBAR_APP_URL__' settings.sidebarAppUrl || '__SIDEBAR_APP_URL__'
), ),
}); });
} else {
// Show a "quiet" warning to avoid being disruptive on non-Hypothesis sites
// that embed the client.
//
// In Via or when using the bookmarklet we could show something louder.
console.warn(
'The Hypothesis annotation tool is not supported in this browser. See https://web.hypothes.is/help/which-browsers-are-supported-by-hypothesis/.'
);
}
import { isBrowserSupported } from '../browser-check';
describe('isBrowserSupported', () => {
it('returns true in a modern browser', () => {
assert.isTrue(isBrowserSupported());
});
it('returns false if a check fails', () => {
// Override `Document.prototype.evaluate`.
document.evaluate = null;
assert.isFalse(isBrowserSupported());
// Remove override.
delete document.evaluate;
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment