OutlineManager.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import './controllers/OutlineController'
  2. import './components/OutlinePane'
  3. import './components/OutlineRoot'
  4. import './components/OutlineList'
  5. import './components/OutlineItem'
  6. import { matchOutline, nestOutline } from './OutlineParser'
  7. import isValidTeXFile from '../../main/is-valid-tex-file'
  8. class OutlineManager {
  9. constructor(ide, scope) {
  10. this.ide = ide
  11. this.scope = scope
  12. this.shareJsDoc = null
  13. this.isTexFile = false
  14. this.flatOutline = []
  15. this.outline = []
  16. this.highlightedLine = null
  17. this.ignoreNextScroll = false
  18. this.ignoreNextCursorUpdate = false
  19. scope.$on('doc:after-opened', () => {
  20. this.ignoreNextScroll = true
  21. this.ignoreNextCursorUpdate = true
  22. this.shareJsDoc = scope.editor.sharejs_doc
  23. this.isTexFile = isValidTeXFile(scope.editor.open_doc_name)
  24. this.updateOutline()
  25. this.broadcastChangeEvent()
  26. })
  27. scope.$watch('openFile.name', openFileName => {
  28. this.isTexFile = isValidTeXFile(openFileName)
  29. this.updateOutline()
  30. this.broadcastChangeEvent()
  31. })
  32. scope.$on('doc:changed', () => {
  33. this.updateOutline()
  34. this.broadcastChangeEvent()
  35. })
  36. scope.$on('cursor:editor:update', (event, cursorPosition) => {
  37. if (!window.user.alphaProgram) return
  38. if (this.ignoreNextCursorUpdate) {
  39. this.ignoreNextCursorUpdate = false
  40. return
  41. }
  42. this.updateHighlightedLine(cursorPosition.row + 1)
  43. this.broadcastChangeEvent()
  44. })
  45. scope.$on('scroll:editor:update', (event, middleVisibleRow) => {
  46. if (!window.user.alphaProgram) return
  47. if (this.ignoreNextScroll) {
  48. this.ignoreNextScroll = false
  49. return
  50. }
  51. this.updateHighlightedLine(middleVisibleRow + 1)
  52. this.broadcastChangeEvent()
  53. })
  54. scope.$watch('editor.showRichText', () => {
  55. this.ignoreNextScroll = true
  56. this.ignoreNextCursorUpdate = true
  57. })
  58. }
  59. updateOutline() {
  60. this.outline = []
  61. if (this.isTexFile) {
  62. const content = this.ide.editorManager.getCurrentDocValue()
  63. if (content) {
  64. this.flatOutline = matchOutline(content)
  65. this.outline = nestOutline(this.flatOutline)
  66. }
  67. }
  68. }
  69. // set highlightedLine to the closest outline line above the editorLine
  70. updateHighlightedLine(editorLine) {
  71. let closestOutlineLine = null
  72. for (let lineId = 0; lineId < this.flatOutline.length; lineId++) {
  73. const outline = this.flatOutline[lineId]
  74. if (editorLine < outline.line) break // editorLine is above
  75. closestOutlineLine = outline.line
  76. }
  77. this.highlightedLine = closestOutlineLine
  78. }
  79. jumpToLine(line) {
  80. this.ignoreNextScroll = true
  81. this.ide.editorManager.jumpToLine({ gotoLine: line })
  82. }
  83. broadcastChangeEvent() {
  84. this.scope.$broadcast('outline-manager:outline-changed', {
  85. isTexFile: this.isTexFile,
  86. outline: this.outline,
  87. highlightedLine: this.highlightedLine
  88. })
  89. }
  90. }
  91. export default OutlineManager