48e56a02f508f0bf766b95ec7c0515fbad550359706cc034669833eaaecedf911aeeb4eedc285dfbeda101b3b51b0657e3e9f980d8b0f2bbb2231b02d5202c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /**
  2. * Copyright (c) 2013 ESHA Research
  3. * Dual licensed under the MIT and GPL licenses:
  4. * http://www.opensource.org/licenses/mit-license.php
  5. * http://www.gnu.org/licenses/gpl.html
  6. *
  7. * Makes it easy to watch for storage events by enhancing the events and
  8. * allowing binding to particular keys and/or namespaces.
  9. *
  10. * // listen to particular key storage events (yes, this is namespace sensitive)
  11. * store.on('foo', function listenToFoo(e){ console.log('foo was changed:', e); });
  12. * store.off('foo', listenToFoo);
  13. *
  14. * // listen to all storage events
  15. * store.on(function storageEvent(e){ console.log('web storage:', e); });
  16. * store.off(storageEvent);
  17. *
  18. * Status: ALPHA - useful, if you don't mind incomplete browser support for events
  19. */
  20. ;(function(window, document, _) {
  21. _.fn('on', function(key, fn) {
  22. if (!fn) { fn = key; key = ''; }// shift args when needed
  23. var s = this,
  24. bound,
  25. id = _.id(this._area);
  26. if (window.addEventListener) {
  27. window.addEventListener("storage", bound = function(e) {
  28. var k = s._out(e.key);
  29. if (k && (!key || k === key)) {// must match key if listener has one
  30. var eid = _.id(e.storageArea);
  31. if (!eid || id === eid) {// must match area, if event has a known one
  32. return fn.call(s, _.event(k, s, e));
  33. }
  34. }
  35. }, false);
  36. } else {
  37. document.attachEvent("onstorage", bound = function() {
  38. return fn.call(s, window.event);
  39. });
  40. }
  41. fn['_'+key+'listener'] = bound;
  42. return s;
  43. });
  44. _.fn('off', function(key, fn) {
  45. if (!fn) { fn = key; key = ''; }// shift args when needed
  46. var bound = fn['_'+key+'listener'];
  47. if (window.removeEventListener) {
  48. window.removeEventListener("storage", bound);
  49. } else {
  50. document.detachEvent("onstorage", bound);
  51. }
  52. return this;
  53. });
  54. _.event = function(k, s, e) {
  55. var event = {
  56. key: k,
  57. namespace: s.namespace(),
  58. newValue: _.parse(e.newValue),
  59. oldValue: _.parse(e.oldValue),
  60. url: e.url || e.uri,
  61. storageArea: e.storageArea,
  62. source: e.source,
  63. timeStamp: e.timeStamp,
  64. originalEvent: e
  65. };
  66. if (_.cache) {
  67. var min = _.expires(e.newValue || e.oldValue);
  68. if (min) {
  69. event.expires = _.when(min);
  70. }
  71. }
  72. return event;
  73. };
  74. _.id = function(area) {
  75. for (var id in _.areas) {
  76. if (area === _.areas[id]) {
  77. return id;
  78. }
  79. }
  80. };
  81. })(window, document, window.store._);