Skip to content

Instantly share code, notes, and snippets.

@mathiasbynens
Created August 13, 2011 13:21
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save mathiasbynens/1143845 to your computer and use it in GitHub Desktop.
Save mathiasbynens/1143845 to your computer and use it in GitHub Desktop.
`unsafeWindow` polyfill (for use in user scripts)
// ==UserScript==
// @name Emulate `unsafeWindow` in browsers that don’t support it.
// ==/UserScript==
// http://mths.be/unsafewindow
window.unsafeWindow || (
unsafeWindow = (function() {
var el = document.createElement('p');
el.setAttribute('onclick', 'return window;');
return el.onclick();
}())
);
// You can now use `unsafeWindow`, ehm, safely.
console.log(unsafeWindow);
// If the current document uses a JavaScript library, you can use it in
// your user script like this:
console.log(unsafeWindow.jQuery);
@mathiasbynens
Copy link
Author

Other things I’ve tried:

  • document.defaultView: returns a window object but doesn’t inherit global variables from the document (e.g. unsafeWindow.jQuery === undefined)
  • Function('return window')() (or even Function('return this')()) (suggested by @jdalton): same as above
  • window.wrappedJSObject (to which unsafeWindow is an alias in Greasemonkey)

P.S. It bothers me that in the fallback case, unsafeWindow is an implied global, but window.unsafeWindow = … (or this.unsafeWindow = …) don’t work.

@paulirish
Copy link

hott

@mathiasbynens
Copy link
Author

@hateradio
Copy link

[Update]

Used === instead of == and finally instead of an empty catch.

var gm_win = (function(){
    var a;
    try {
        a = unsafeWindow === window ? false : unsafeWindow;
    } finally {
        return a || (function(){
            var e = document.createElement('p');
            e.setAttribute('onclick', 'return window;');
            return e.onclick();
        }());
    }
}());

console.log(gm_win.SOMEAUTHKEY);

[Original]

This snippet is helpful, and it works when used in Opera and Chrome. However, I find that GM's unsafeWindow becomes invalid if this is used in Firefox. Probably because it's not part of the window object. In other words, I can't get it to work in Firefox.

Here's my solution.

var gm_uwin = (function(){
    var a;
    try {
        a = unsafeWindow == window ? false : unsafeWindow; // Chrome: window == unsafeWindow
    } catch(e) { }
    return a || (function(){
            var el = document.createElement('p');
            el.setAttribute('onclick', 'return window;');
            return el.onclick();
        }());
}());

console.log(gm_uwin.SOMEAUTHKEY); // This works in all three browsers.

Chrome creates an anon function that wraps window as the argument for unsafeWindow so they are actually the same safe-window object. Opera will throw an error. If a is false the fill is used, otherwise the real unsafeWindow is returned for Firefox.

@nstepien
Copy link

@mathiasbynens
Is it just me or did they fix it in the latest Canary?
It returns the safe window, not the unsafe one anymore.

@mwscriptfreak
Copy link

Think there is a issue on Canary Build 28.0.1477.2

@yahelc
Copy link

yahelc commented Aug 7, 2013

It seems like this no longer works in Chrome 29.

@mathiasbynens
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment