From f0b9e1f7e9f8bf01c8239d61b64a830bad4e45dd Mon Sep 17 00:00:00 2001 From: Paul Fitzpatrick Date: Thu, 27 Jul 2023 12:02:17 +0100 Subject: [PATCH] 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 --- app/client/lib/UrlState.ts | 22 ++++++++++++++++------ test/fixtures/docs/SelectBySummary.grist | Bin 618496 -> 622592 bytes test/nbrowser/SelectByRefList.ts | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/app/client/lib/UrlState.ts b/app/client/lib/UrlState.ts index d2487e9e..f2ad4d21 100644 --- a/app/client/lib/UrlState.ts +++ b/app/client/lib/UrlState.ts @@ -77,13 +77,23 @@ export class UrlState 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); } diff --git a/test/fixtures/docs/SelectBySummary.grist b/test/fixtures/docs/SelectBySummary.grist index c7d67c1b1b38743af931561d952e0409a3b63c20..453c483fad3d3776eb1fcdd04de12ae0e9cf850e 100644 GIT binary patch delta 2854 zcmbtVYfKbZ6rOwMb!T_y&MpWmunXhzE(ps$0BzH5u-gsp*fVX-(Ui1R;DT+F&+xCX|Hb=iq?fr%sF8UP=StcPb!2eyd3-R}oSl(9}&2uVE)3W};_S4fR1 z(Y}FrpB8b+-7T+n%d1<~1U9yH%jM;%E*4CfmRKpv9pNnc237O#aCbRBJ4{3nz;8{qf9Kewp&H=l3N}ALrRY?N=72m)U zV>TDu_F_694^Sj zESq}s3^Lf`N!yLvqASaeXC+T#8Lh@5Fbg)rv z=ep2{jmu@CnieNA19Hhf1%M-O(_kqR-#wrjhn%8C;%bE0YGF>^U`&l}PE}eh3bk&BIKzEDW9cXTAkzMnUNT&@H5l=Zhyv1Ev znb<1x_J#(KROXYKY2-(O%xsoCR%nJp5&$?zbs2P|+AH8TdMKIW;_a=iV1MO&Y7dW} zM^qm^EPJf_!(5kK(HD}}wRg9WVF0p>d=94$)xbS?p0b}t~ zy&K0Z{w{s|0g!M~G`&3@A6Qvin;y5@wOD+muff;QSgX~BG$mFW?O(rkXIty0$ol5h zWb`~*O0G;J&f5WaN)UAa#d^PxLafCnZKht-|7u(-Qhe~kUp9z-UaC|B}S*fCv%O`TyU;N_bwo2dUENL zBA3X&K$aZ+4#~5h-ZtmclWXJ1Mcf*EhAf}fSGOYiYWM7_#F&2-#$E|A-@Lyv-i*9{ tbB0_(-k(4$`C=Ls&+v>K$(IiT=xHD_EeRE=%VD9Jez!?r#u)28=|7w#7McJ6 delta 944 zcmZ9KO-PhM7{}+C_hV+rJ=ac10~eiYzw?$=t$>u-MWdC@WJ7Y;&VLL6q0fNc~+fRJl?Ev~2C$+Z|mez)nq_2+g&9SVa+>NVc~n_8jf(?m>3C@7-Dm zrrzJLWQZT*Z}=T9GQJ1LxW#7>F91qg+V&+nSKy$kqgu+Sh+k)e^;_!)Qz@GP|nKgk=28N`Z4;Y>*;jzd^j z8U&oJ8jR=VS0L|Kc8$KGmE^oWtw*(UN`+JCgKt>;h~Pp`*+A?39NQ{}LQv>b&xKm- zoSg^9yYeY#z(4b+{06_kle~#naF+4=UYjBQ8HE@tFn}4^<(D@!j&!ysk92hGY*huj z2)~pGTf6DSNR|hkWQU;xY3ydh8kZ@I21i=rFmfXSAE@jOtgm;|aW6 z-tmf4SBz7btu7%}SsC;%6|0KyZD*J6(BJM(luslgvhd>n zz^o|-%kk{Qg$^ml2NdV3AG*N}93j|fRaL=2)Y({!*MM_s8SbsJMcMJV|GA%%FvLgGg!HfP+TWS>`mg$-s-sGVu~VOcCkhL{&WumU$Deosl$IpjGxP3rMS{ii;rcZ<+8jbqH6 q?rAyYd9oG;v4=?