chronology.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // chronology.js v0.4 - Copyright (c) 2013 Wout Fierens - Licensed under the MIT license
  2. ;(function() {
  3. // Main class
  4. var Chronology = function(settings) {
  5. /* default settings */
  6. this.settings = {
  7. limit: 20
  8. , call: true
  9. }
  10. /* merge settings */
  11. this.set(settings)
  12. /* initialize stacks */
  13. this.clear()
  14. }
  15. // Change settings
  16. Chronology.prototype.set = function(settings) {
  17. for (var s in settings)
  18. this.settings[s] = settings[s]
  19. return this
  20. }
  21. // Add occurence
  22. Chronology.prototype.add = function(occurence) {
  23. /* clear redo stack */
  24. this.redos = []
  25. /* typecast occurence */
  26. if (!occurence instanceof Chronology.Occurence)
  27. occurence = new Chronology.Occurence(occurence)
  28. /* store new occurence */
  29. this.undos.unshift(occurence)
  30. /* call new current action */
  31. if (occurence.call === true || (typeof occurence.call == 'undefined' && this.settings.call === true))
  32. occurence.up()
  33. /* trim the undos stack to length of limit */
  34. if (this.settings.limit)
  35. this.undos.splice(this.settings.limit)
  36. /* call back */
  37. if (typeof this.settings.onAdd == 'function')
  38. this.settings.onAdd(occurence)
  39. return this
  40. }
  41. // Set the values to their initial state
  42. Chronology.prototype.clear = function() {
  43. /* clear arrays, retain state */
  44. this.redos = []
  45. this.undos = []
  46. /* call back for action */
  47. if (typeof this.settings.onClear == 'function')
  48. this.settings.onClear()
  49. return this
  50. }
  51. // Set the values to their initial state
  52. Chronology.prototype.revert = function() {
  53. var occurence
  54. /* walk back to initial state */
  55. while(occurence = this.undos.shift())
  56. occurence.down()
  57. /* clear everything out */
  58. return this.clear()
  59. }
  60. // Undo last added action
  61. Chronology.prototype.undo = function() {
  62. var occurence
  63. /* get most recent undo */
  64. if (occurence = this.undos.shift()) {
  65. /* move current action to redos */
  66. this.redos.unshift(occurence)
  67. /* restore to previous state */
  68. occurence.down()
  69. /* call back for action */
  70. if (typeof this.settings.onUndo == 'function')
  71. this.settings.onUndo(occurence)
  72. /* call back when reaching beginning of time */
  73. if (this.undos.length == 0 && typeof this.settings.onBegin == 'function')
  74. this.settings.onBegin(occurence)
  75. }
  76. return this
  77. }
  78. // Redo the last action
  79. Chronology.prototype.redo = function() {
  80. var occurence
  81. /* get most recent redo */
  82. if (occurence = this.redos.shift()) {
  83. /* move current action to undos */
  84. this.undos.unshift(occurence)
  85. /* restore to next state */
  86. occurence.up()
  87. /* call back for action */
  88. if (typeof this.settings.onRedo == 'function')
  89. this.settings.onRedo(occurence)
  90. /* call back when reaching beginning of time */
  91. if (this.redos.length == 0 && typeof this.settings.onEnd == 'function')
  92. this.settings.onEnd(occurence)
  93. }
  94. return this
  95. }
  96. // Occurence class
  97. Chronology.Occurence = function(states) {
  98. states = states || {}
  99. this.up = states.up || function() {}
  100. this.down = states.down || function() {}
  101. }
  102. // Use AMD or CommonJS, fall back on global scope if both are not present.
  103. if (typeof define === 'function' && define.amd)
  104. define(function() { return Chronology })
  105. else if (typeof exports !== 'undefined')
  106. exports.Chronology = Chronology
  107. else
  108. this.Chronology = Chronology
  109. }).call(this)