jpgohlke/twitch-chat-filter — pull request #160 by MattiasBuelens (2014-08-10 16:05:19+00:00)
Title: Added support for Greasemonkey 2.0.

[Greasemonkey 2.0 made some backwards incompatible changes](http://www.greasespot.net/2014/06/greasemonkey-20-release.html) regarding the `unsafeWindow`. In short, directly writing non-primitive values to `unsafeWindow` from the script's context into the page's context is no longer supported. This way, other scripts on the page are prevented from breaking into the sandbox by calling a function or modifying an object added by a user script.

In order to safely write values to the page, user scripts now need to use `cloneInto`, `exportFunction` and/or `createObjectIn` to export safe object clones and/or export functions which accept and return safe values.

The first part of the solution is to use our own instance of jQuery for DOM manipulation. The DOM is still shared between the script's context and the page's context, and by running in `noConflict` mode we prevent our instance from interfering with the instance already loaded on the page. Because our instance runs in our sandbox, we don't need to worry about exporting objects or cloning functions to run in the page's context.

The second part of the solution is a bit more tricky, since we need to inter-operate with Twitch's JS code on the page: for example we need to modify `App.Room.prototype` for `addMessage`/`send` and we need to load emoticons with `Twitch.api.get` for the emoticons filter. In these cases, we need to export some of our functions in the sandbox to the page so they can be called from the page's context. These functions are exported to `window.TppChatFilterBridge` on the page. Additionally, we need to inject some glue code into page to wire the bridge up with Twitch's functions. However, the rest of our code still runs inside the sandbox.

This is an alternative solution for #157. @hugomg implemented a different solution in #158, in which **all** of the script's code is injected into the page. This is an easier and simpler solution, but it's less secure.