DOM Window Wrapper Update

A quick update to my previous post about creating a DOM window wrapper. My colleague Tomas pointed out that Browserify breaks if it is running inside the wrapper, due some code in the shim it uses for the NodeJS process module. The code compares the source of an event with the window. In our case the window object has been replaced by our wrapper, so the comparison fails and breakage ensues.

To fix this, we need a special version of addEventListener:

wrapper.addEventListener = function(type, listener, useCapture) {
  if ('message' === type) {
    listener = (function(originalListener) {
      return function(event) {
        var newEvent = document.createEvent('MessageEvent');
        newEvent.initMessageEvent(
          'message',
          event.bubbles,
          event.cancelable,
          event.data,
          event.origin,
          event.lastEventId,
          wrapper,
          event.ports
        );
        originalListener(newEvent);
      }
    })(listener);
  }
  window.addEventListener.call(window, type, listener, useCapture);
};

We’re doing our best to avoid exposing the real window to the content script environment, and this fix deals with one particular area where the real window was still leaking through. There are certainly mainly more APIs that will need to be adapted for other use cases, and we’d love to hear about any you stumble upon. After a few years of edge cases the wrapper may end up looking like jQuery, but with this adaptation it appears to be holding its own against our current requirements.

Matthew Gertner

Matthew Gertner