74 lines
2.0 KiB
JavaScript
74 lines
2.0 KiB
JavaScript
|
'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);
|
||
|
}
|