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.5KB

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