event.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. 'use strict';
  2. var random = require('./random');
  3. var onUnload = {}
  4. , afterUnload = false
  5. // detect google chrome packaged apps because they don't allow the 'unload' event
  6. , isChromePackagedApp = global.chrome && global.chrome.app && global.chrome.app.runtime
  7. ;
  8. module.exports = {
  9. attachEvent: function(event, listener) {
  10. if (typeof global.addEventListener !== 'undefined') {
  11. global.addEventListener(event, listener, false);
  12. } else if (global.document && global.attachEvent) {
  13. // IE quirks.
  14. // According to: http://stevesouders.com/misc/test-postmessage.php
  15. // the message gets delivered only to 'document', not 'window'.
  16. global.document.attachEvent('on' + event, listener);
  17. // I get 'window' for ie8.
  18. global.attachEvent('on' + event, listener);
  19. }
  20. }
  21. , detachEvent: function(event, listener) {
  22. if (typeof global.addEventListener !== 'undefined') {
  23. global.removeEventListener(event, listener, false);
  24. } else if (global.document && global.detachEvent) {
  25. global.document.detachEvent('on' + event, listener);
  26. global.detachEvent('on' + event, listener);
  27. }
  28. }
  29. , unloadAdd: function(listener) {
  30. if (isChromePackagedApp) {
  31. return null;
  32. }
  33. var ref = random.string(8);
  34. onUnload[ref] = listener;
  35. if (afterUnload) {
  36. setTimeout(this.triggerUnloadCallbacks, 0);
  37. }
  38. return ref;
  39. }
  40. , unloadDel: function(ref) {
  41. if (ref in onUnload) {
  42. delete onUnload[ref];
  43. }
  44. }
  45. , triggerUnloadCallbacks: function() {
  46. for (var ref in onUnload) {
  47. onUnload[ref]();
  48. delete onUnload[ref];
  49. }
  50. }
  51. };
  52. var unloadTriggered = function() {
  53. if (afterUnload) {
  54. return;
  55. }
  56. afterUnload = true;
  57. module.exports.triggerUnloadCallbacks();
  58. };
  59. // 'unload' alone is not reliable in opera within an iframe, but we
  60. // can't use `beforeunload` as IE fires it on javascript: links.
  61. if (!isChromePackagedApp) {
  62. module.exports.attachEvent('unload', unloadTriggered);
  63. }