allow Grist front-end to function when location history is unavailable (#596)

* allow Grist front-end to function when location history is unavailable

When the Grist front-end is embedded in an iframe, using a srcdoc
attribute, history.pushState and similar methods are unavailable.
Currently, that makes it impossible to navigate between Grist pages,
since an access error is thrown (behavior may be browser dependent).
With this change, navigation succeeds.

* give unrelated possibly slow test a little more time
pull/586/head
Paul Fitzpatrick 10 months ago committed by GitHub
parent ab6807c342
commit f0b9e1f7e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -77,13 +77,23 @@ export class UrlState<IUrlState extends object> extends Disposable {
if (samePage) {
await this._stateImpl.delayPushUrl(prevState, newState);
if (options.replace) {
this._window.history.replaceState(null, '', newUrl);
} else {
this._window.history.pushState(null, '', newUrl);
try {
if (options.replace) {
this._window.history.replaceState(null, '', newUrl);
} else {
this._window.history.pushState(null, '', newUrl);
}
// pushState/replaceState above do not trigger 'popstate' event, so we call loadState() manually.
this.loadState();
} catch (e) {
// If we fail, we may be in a context where Grist doesn't have
// control over history, e.g. an iframe with srcdoc. Go ahead
// and apply the application state change (e.g. switching to a
// different Grist page). The back button won't work, but what
// it should do in an embedded context is full of nuance anyway.
log.debug(`pushUrl failure: ${e}`);
this.state.set(this._stateImpl.decodeUrl(new URL(newUrl)));
}
// pushState/replaceState above do not trigger 'popstate' event, so we call loadState() manually.
this.loadState();
} else {
this._window._urlStateLoadPage!(newUrl);
}

Binary file not shown.

@ -4,7 +4,7 @@ import * as gu from 'test/nbrowser/gristUtils';
import {server, setupTestSuite} from 'test/nbrowser/testUtils';
describe('SelectByRefList', function() {
this.timeout(60000);
this.timeout(80000);
setupTestSuite();
addToRepl('gu2', gu);
gu.bigScreen();

Loading…
Cancel
Save