You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

history.ts 1.4KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import { Data } from "types"
  2. import { BaseCommand } from "./commands/command"
  3. // A singleton to manage history changes.
  4. class History<T> {
  5. private stack: BaseCommand<T>[] = []
  6. private pointer = -1
  7. private maxLength = 100
  8. private _enabled = true
  9. execute = (data: T, command: BaseCommand<T>) => {
  10. if (this.disabled) return
  11. this.stack = this.stack.slice(0, this.pointer + 1)
  12. this.stack.push(command)
  13. command.redo(data, true)
  14. this.pointer++
  15. if (this.stack.length > this.maxLength) {
  16. this.stack = this.stack.slice(this.stack.length - this.maxLength)
  17. this.pointer = this.maxLength - 1
  18. }
  19. this.save(data)
  20. }
  21. undo = (data: T) => {
  22. if (this.disabled) return
  23. if (this.pointer === -1) return
  24. const command = this.stack[this.pointer]
  25. command.undo(data)
  26. this.pointer--
  27. this.save(data)
  28. }
  29. redo = (data: T) => {
  30. if (this.disabled) return
  31. if (this.pointer === this.stack.length - 1) return
  32. const command = this.stack[this.pointer + 1]
  33. command.redo(data, false)
  34. this.pointer++
  35. this.save(data)
  36. }
  37. save = (data: T) => {
  38. if (typeof window === "undefined") return
  39. if (typeof localStorage === "undefined") return
  40. localStorage.setItem("code_slate_0.0.1", JSON.stringify(data))
  41. }
  42. disable = () => {
  43. this._enabled = false
  44. }
  45. enable = () => {
  46. this._enabled = true
  47. }
  48. get disabled() {
  49. return !this._enabled
  50. }
  51. }
  52. export default new History<Data>()