| 'use strict'; |
| |
| var random = require('./random'); |
| |
| var onUnload = {} |
| , afterUnload = false |
| // detect google chrome packaged apps because they don't allow the 'unload' event |
| , isChromePackagedApp = global.chrome && global.chrome.app && global.chrome.app.runtime |
| ; |
| |
| module.exports = { |
| attachEvent: function(event, listener) { |
| if (typeof global.addEventListener !== 'undefined') { |
| global.addEventListener(event, listener, false); |
| } else if (global.document && global.attachEvent) { |
| // IE quirks. |
| // According to: http://stevesouders.com/misc/test-postmessage.php |
| // the message gets delivered only to 'document', not 'window'. |
| global.document.attachEvent('on' + event, listener); |
| // I get 'window' for ie8. |
| global.attachEvent('on' + event, listener); |
| } |
| } |
| |
| , detachEvent: function(event, listener) { |
| if (typeof global.addEventListener !== 'undefined') { |
| global.removeEventListener(event, listener, false); |
| } else if (global.document && global.detachEvent) { |
| global.document.detachEvent('on' + event, listener); |
| global.detachEvent('on' + event, listener); |
| } |
| } |
| |
| , unloadAdd: function(listener) { |
| if (isChromePackagedApp) { |
| return null; |
| } |
| |
| var ref = random.string(8); |
| onUnload[ref] = listener; |
| if (afterUnload) { |
| setTimeout(this.triggerUnloadCallbacks, 0); |
| } |
| return ref; |
| } |
| |
| , unloadDel: function(ref) { |
| if (ref in onUnload) { |
| delete onUnload[ref]; |
| } |
| } |
| |
| , triggerUnloadCallbacks: function() { |
| for (var ref in onUnload) { |
| onUnload[ref](); |
| delete onUnload[ref]; |
| } |
| } |
| }; |
| |
| var unloadTriggered = function() { |
| if (afterUnload) { |
| return; |
| } |
| afterUnload = true; |
| module.exports.triggerUnloadCallbacks(); |
| }; |
| |
| // 'unload' alone is not reliable in opera within an iframe, but we |
| // can't use `beforeunload` as IE fires it on javascript: links. |
| if (!isChromePackagedApp) { |
| module.exports.attachEvent('unload', unloadTriggered); |
| } |