Office.js revokes browser history features using history

The official version of office.js is available here:

https://appsforoffice.microsoft.com/lib/1/hosted/office.js 

It contains the following lines in code:

 window.history.replaceState = null; window.history.pushState = null; 

This breaks some history features in my Excel add-ins (I use react and react-router )

Why does office.js reset these history features? I can not find any explanation in the documentation.

+13
source share
3 answers

The browser control used in Excel does not support the history API, if replaceState and pushState were not excluded, they will be available to respond, but will always throw an exception when called. Until a new browser control is available, you will need to switch to hash routing or use polyfill for the history API. https://github.com/devote/HTML5-History-API seems to work if you included the script link after office.js.

+7
source

This works for me - cache objects before office-js removes them:

 <script type="text/javascript"> // Office js deletes window.history.pushState and window.history.replaceState. Cache them and restore them window._historyCache = { replaceState: window.history.replaceState, pushState: window.history.pushState }; </script> <script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script> <script type="text/javascript"> // Office js deletes window.history.pushState and window.history.replaceState. Restore them window.history.replaceState = window._historyCache.replaceState; window.history.pushState = window._historyCache.pushState; </script> 
+3
source

My version of Windows 10 Pro, the default browser is Edge 42.17134.1.0. But the right sidebar, where Outlook launches the add-in, uses the old IE10 mechanism; ((IE10 also exists on Windows as a browser.) I don’t know if this is true for all Windows or is it some special case for my version. IE10 supports history.replaceState and history.pushState , but inside Outlook I have problems with these methods, so simple recovery does not work for me.

A simple solution with history.replaceState and history.pushState cache does not work for me. In Outlook with IE10 inside, I get an unexpected error when my code calls history.replaceState or history.pushState . But I found one interesting thing. If you suppress the mistake, they do their job.

So my workaround:

  function isIE10 () { return !!document.documentMode } // Office js deletes window.history.pushState and window.history.replaceState. Cache them and restore them // Also there is an issue in Windows Outlook with 'pushState' and 'replaceState'. They throw an error but in the same time do their expected work // So I suppress errors for IE10 (we use it inside Window Outlook) window._historyCache = { replaceState: function (originalReplaceState) { return function () { try { return originalReplaceState.apply(window.history, arguments) } catch (e) { if (isIE10()) { console.warn("Unexpected error in 'window.history.replaceState', but we can continue to work :)"); return false; } throw(e); } } }(window.history.replaceState), pushState: function (originalFunction) { return function () { try { return originalFunction.apply(window.history, arguments) } catch (e) { if (isIE10()) { console.warn("Unexpected error in 'window.history.pushState', but we can continue to work :)"); return false; } throw(e); } } }(window.history.pushState) }; // In Window Outlook we have issue with 'replaceState' and 'pushState. So replaced it by wrapped version. window.history.replaceState = window._historyCache.replaceState; window.history.pushState = window._historyCache.pushState; //include the main code with react-router //include Office.js Office.initialize = function () { // Office js deletes window.history.pushState and window.history.replaceState. Restore them window.history.replaceState = window._historyCache.replaceState; window.history.pushState = window._historyCache.pushState; // Now you can start initialize&&run your application .... } 

Note. I have to replace history.replaceState and history.pushState before running any code that works with this API. In my case, it responds to the router.

0
source

Source: https://habr.com/ru/post/1015555/


All Articles