Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Office.js nullifies browser history functions breaking history usage

Tags:

office-js

The official version of office.js 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 of the history functionality in my Excel Add-ins (I'm using react and react-router)

Why is office.js nullifying those history functions? I cannot find any explanation in the documentation.

like image 937
Marcin Belczewski Avatar asked Mar 07 '17 07:03

Marcin Belczewski


3 Answers

This works for me - cache the objects before office-js deletes 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>
like image 198
stepper Avatar answered Nov 16 '22 06:11

stepper


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

like image 9
Dan Saunders - MSFT Avatar answered Nov 16 '22 05:11

Dan Saunders - MSFT


My Windows version is 10 Pro, default browser is Edge 42.17134.1.0 . But the right side bar where Outlook runs add-in uses the old IE10 engine ;( (IE10 as a browser also is in Windows). I don't know this is true for all Windows or it's some specific case for my version. IE10 supports history.replaceState and history.pushState, but inside Outlook I have problems with these methods, so simple restore doesn't work for me.

The simple solution with cache history.replaceState and history.pushState doesn't work fore me. In Outlook with IE10 inside I have some unexpected error when my code call history.replaceState or history.pushState. But I found one interesting thing. If suppress the error they do their work.

So my workaround is:

 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 should replace history.replaceState and history.pushState before the running any code which work with this API. In my case it's react-router.

like image 1
vyaz Avatar answered Nov 16 '22 06:11

vyaz