1524d2942ebf874096c78a1957b49e16275f93a58f68e770b634a4379d8aa12971d6d68773a92a35c034833734852c458408f8c79ab7ce6bf616e672fa1bc1 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. * If fake (non-persistent) storage for users stuck in the dark ages
  8. * does not satisfy you, this will replace it with the a reasonable imitator for their
  9. * pathetic, incompetent browser. Note that the session replacement here is potentially
  10. * insecure as it uses window.name without any fancy protections.
  11. *
  12. * Status: BETA - unsupported, useful, needs testing & refining
  13. */
  14. ;(function(window, document, store, _) {
  15. function addUpdateFn(area, name, update) {
  16. var old = area[name];
  17. area[name] = function() {
  18. var ret = old.apply(this, arguments);
  19. update.apply(this, arguments);
  20. return ret;
  21. };
  22. }
  23. function create(name, items, update) {
  24. var length = 0;
  25. for (var k in items) {
  26. if (items.hasOwnProperty(k)) {
  27. length++;
  28. }
  29. }
  30. var area = _.inherit(_.storageAPI, { items:items, length:length, name:name });
  31. if (update) {
  32. addUpdateFn(area, 'setItem', update);
  33. addUpdateFn(area, 'removeItem', update);
  34. }
  35. return area;
  36. }
  37. if (store.isFake()) {
  38. var area;
  39. if (document.documentElement.addBehavior) {// IE userData
  40. var el = document.createElement('div'),
  41. sn = 'localStorage',
  42. body = document.body,
  43. wrap = function wrap(fn) {
  44. return function() {
  45. body.appendChild(el);
  46. el.addBehavior('#default#userData');
  47. el.load(sn);
  48. var ret = fn.apply(store._area, arguments);
  49. el.save(sn);
  50. body.removeChild(el);
  51. return ret;
  52. };
  53. },
  54. has = function has(key){
  55. return el.getAttribute(key) !== null;
  56. },
  57. UserDataStorage = function UserDataStorage(){};
  58. UserDataStorage.prototype = {
  59. length: (wrap(function(){
  60. return el.XMLDocument.documentElement.attributes.length;
  61. }))(),
  62. has: wrap(has),
  63. key: wrap(function(i) {
  64. return el.XMLDocument.documentElement.attributes[i];
  65. }),
  66. setItem: wrap(function(k, v) {
  67. if (!has(k)) {
  68. this.length++;
  69. }
  70. el.setAttribute(k, v);
  71. }),
  72. removeItem: wrap(function(k) {
  73. if (has(k)) {
  74. el.removeAttribute(k);
  75. this.length--;
  76. }
  77. }),
  78. getItem: wrap(function(k){ return el.getAttribute(k); }),
  79. clear: wrap(function() {
  80. var all = el.XMLDocument.documentElement.attributes;
  81. for (var i=0, a; !!(a = all[i]); i++) {
  82. el.removeAttribute(a.name);
  83. }
  84. this.length = 0;
  85. })
  86. };
  87. area = new UserDataStorage();
  88. } else if ('globalStorage' in window && window.globalStorage) {// FF globalStorage
  89. area = create('global', window.globalStorage[window.location.hostname]);
  90. } else {// cookie
  91. var date = new Date(),
  92. key = 'store.local',
  93. items = {},
  94. cookies = document.cookie.split(';');
  95. date.setTime(date.getTime()+(5*365*24*60*60*1000));//5 years out
  96. date = date.toGMTString();
  97. for (var i=0,m=cookies.length; i<m; i++) {
  98. var c = cookies[i];
  99. while (c.charAt(0) === ' ') {
  100. c = c.substring(1, c.length);
  101. }
  102. if (c.indexOf(key) === 0) {
  103. items = JSON.parse(c.substring(key.length+1));
  104. }
  105. }
  106. area = create('cookie', items, function() {
  107. document.cookie = key+"="+JSON.stringify(this.items)+"; expires="+date+"; path=/";
  108. });
  109. }
  110. // replace local's fake storage
  111. store._area = _.areas.local = area;
  112. }
  113. if (store.session.isFake()) {
  114. var sItems = window.name ? JSON.parse(window.name)[document.domain]||{} : {};
  115. store.session._area = _.areas.session =
  116. create('windowName', sItems, function() {
  117. var o = {};
  118. o[document.domain] = this.items;
  119. window.name = JSON.stringify(o);
  120. });
  121. }
  122. })(window, document, window.store, window.store._);