593685a98cc70a3cca93af1f7523a3c1ccb4ca4fc0d2847a283cba3f123f41c23ae8ddfe09aa3bfc94ef28f50d606b58e9c79acdde1e346ceb228c18cb8305 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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. * When quota is reached on a storage area, this shifts incoming values to
  8. * fake storage, so they last only as long as the page does. This is useful
  9. * because it is more burdensome for localStorage to recover from quota errors
  10. * than incomplete caches. In other words, it is wiser to rely on store.js
  11. * never complaining than never missing data. You should already be checking
  12. * the integrity of cached data on every page load.
  13. *
  14. * Status: BETA
  15. */
  16. ;(function(store, _) {
  17. var _set = _.set,
  18. _get = _.get,
  19. _remove = _.remove,
  20. _key = _.key,
  21. _length = _.length,
  22. _clear = _.clear;
  23. _.overflow = function(area, create) {
  24. var name = area === _.areas.local ? '+local+' :
  25. area === _.areas.session ? '+session+' : false;
  26. if (name) {
  27. var overflow = _.areas[name];
  28. if (create && !overflow) {
  29. overflow = store.area(name)._area;// area() copies to _.areas
  30. } else if (create === false) {
  31. delete _.areas[name];
  32. delete store[name];
  33. }
  34. return overflow;
  35. }
  36. };
  37. _.set = function(area, key, string) {
  38. try {
  39. _set.apply(this, arguments);
  40. } catch (e) {
  41. if (e.name === 'QUOTA_EXCEEDED_ERR' ||
  42. e.name === 'NS_ERROR_DOM_QUOTA_REACHED' ||
  43. e.toString().indexOf("QUOTA_EXCEEDED_ERR") !== -1 ||
  44. e.toString().indexOf("QuotaExceededError") !== -1) {
  45. // the e.toString is needed for IE9 / IE10, cos name is empty there
  46. return _.set(_.overflow(area, true), key, string);
  47. }
  48. throw e;
  49. }
  50. };
  51. _.get = function(area, key) {
  52. var overflow = _.overflow(area);
  53. return (overflow && _get.call(this, overflow, key)) ||
  54. _get.apply(this, arguments);
  55. };
  56. _.remove = function(area, key) {
  57. var overflow = _.overflow(area);
  58. if (overflow){ _remove.call(this, overflow, key); }
  59. _remove.apply(this, arguments);
  60. };
  61. _.key = function(area, i) {
  62. var overflow = _.overflow(area);
  63. if (overflow) {
  64. var l = _length.call(this, area);
  65. if (i >= l) {
  66. i = i - l;// make i overflow-relative
  67. for (var j=0, m=_length.call(this, overflow); j<m; j++) {
  68. if (j === i) {// j is overflow index
  69. return _key.call(this, overflow, j);
  70. }
  71. }
  72. }
  73. }
  74. return _key.apply(this, arguments);
  75. };
  76. _.length = function(area) {
  77. var length = _length(area),
  78. overflow = _.overflow(area);
  79. return overflow ? length + _length(overflow) : length;
  80. };
  81. _.clear = function(area) {
  82. _.overflow(area, false);
  83. _clear.apply(this, arguments);
  84. };
  85. })(window.store, window.store._);