Source: singletons/history.js

  1. /**
  2. * @class
  3. * @classdesc Manages and stores [Actions]{@link Syntree.Action}
  4. */
  5. Syntree.History = {
  6. /**
  7. * Actions is stored as a queue with the most recent action at the end (index length-1).
  8. * Note that it is returned as an array with the most recent action at the front (index 0).
  9. *
  10. * @see Syntree.History.getAll()
  11. */
  12. actions: [],
  13. /**
  14. * While this is set to true, no [Actions]{@link Syntree.Action} are added to the history.
  15. * This is used so that we don't have to worry about creating new [Actions]{@link Syntree.Action} while undoing old ones.
  16. */
  17. silent: false,
  18. /**
  19. * Add an action to the history.
  20. *
  21. * @see Syntree.History.actions
  22. */
  23. addAction: function(action) {
  24. action = Syntree.Lib.checkArg(action, 'action');
  25. if (!this.silent) {
  26. this.actions.push(action);
  27. }
  28. },
  29. /**
  30. * Get the most recent [Action]{@link Syntree.Action}.
  31. *
  32. * @see Syntree.History.actions
  33. * @returns {Syntree.Action} - the most recent action.
  34. */
  35. getLast: function() {
  36. return this.actions[this.actions.length-1];
  37. },
  38. /**
  39. * Get all [Actions]{@link Syntree.Action}, reversed so that the most recent is at the front.
  40. *
  41. * @returns {Syntree.Action[]} - all actions in the history.
  42. *
  43. * @see Syntree.History.actions
  44. */
  45. getAll: function() {
  46. return this.actions.slice().reverse();
  47. },
  48. /**
  49. * Get all [Actions]{@link Syntree.Action}, reversed so that the most recent is at the front.
  50. * Filter by given type.
  51. *
  52. * @param {string} - type of action to filter by, e.g. 'select'
  53. * @returns {Syntree.Action[]} - all actions matching the given type
  54. *
  55. * @see Syntree.History.getAll
  56. * @see Syntree.History.actions
  57. */
  58. getAllByType: function(type) {
  59. type = Syntree.Lib.checkArg(type, 'string');
  60. var filtered = this.actions.filter(function(value) {
  61. return value.type === type;
  62. });
  63. return filtered.slice().reverse();
  64. },
  65. /**
  66. * Get the most recent [Action]{@link Syntree.Action} of given type.
  67. *
  68. * @param {string} - type of action to filter by, e.g. 'select'
  69. * @returns {Syntree.Action} - most recent action of given type
  70. *
  71. * @see Syntree.History.getLast
  72. * @see Syntree.History.actions
  73. */
  74. getLastOfType: function(type) {
  75. type = Syntree.Lib.checkArg(type, 'string');
  76. var actions = this.getByType(type);
  77. return actions[actions.length-1];
  78. },
  79. /**
  80. * Undo the most recent undoable [Action]{@link Syntree.Action}.
  81. * During this function, History is silenced so that it does not collect eroneously produced [Actions]{@link Syntree.Action}.
  82. *
  83. * @see Syntree.History.silent
  84. */
  85. undo: function() {
  86. this.silent = true;
  87. var all = this.getAll();
  88. for (i=0; i<all.length; i++) {
  89. if (typeof all[i].undo !== 'undefined') {
  90. this.removeAction(all[i]);
  91. all[i].undo();
  92. this.silent = false;
  93. return;
  94. }
  95. }
  96. this.silent = false;
  97. },
  98. /**
  99. * Remove the given [Action]{@link Syntree.Action} from the history.
  100. *
  101. * @param {Syntree.Action} - action to remove
  102. *
  103. * @see Syntree.History.actions
  104. */
  105. removeAction: function(a) {
  106. a = Syntree.Lib.checkArg(a, 'action');
  107. this.actions.splice(this.actions.indexOf(a),1);
  108. },
  109. /**
  110. * Get all [Actions]{@link Syntree.Action} representing a Node selection.
  111. * This is a convenience function, so that we don't have to filter for selected element type inline.
  112. *
  113. * @returns {Syntree.Action[]} - all Node select actions, most recent at index 0
  114. *
  115. * @see Syntree.History.actions
  116. */
  117. getNodeSelects: function() {
  118. var res = this.getAllByType('select');
  119. res = res.filter(function(x) {
  120. return Syntree.Lib.checkType(x.selected_obj, 'node');
  121. });
  122. return res;
  123. },
  124. toString: function() {
  125. return '[object History]';
  126. }
  127. }