blob: 9c3bab6c5abdafc5a6c58343db0c5c6b21d64812 [file] [log] [blame]
'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);
}