OutlineManager.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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 (this.ignoreNextCursorUpdate) {
  38. this.ignoreNextCursorUpdate = false
  39. return
  40. }
  41. this.updateHighlightedLine(cursorPosition.row + 1)
  42. this.broadcastChangeEvent()
  43. })
  44. scope.$on('scroll:editor:update', (event, middleVisibleRow) => {
  45. if (this.ignoreNextScroll) {
  46. this.ignoreNextScroll = false
  47. return
  48. }
  49. this.updateHighlightedLine(middleVisibleRow + 1)
  50. })
  51. scope.$watch('editor.showRichText', () => {
  52. this.ignoreNextScroll = true
  53. this.ignoreNextCursorUpdate = true
  54. })
  55. }
  56. updateOutline() {
  57. this.outline = []
  58. if (this.isTexFile) {
  59. const content = this.ide.editorManager.getCurrentDocValue()
  60. if (content) {
  61. this.flatOutline = matchOutline(content)
  62. this.outline = nestOutline(this.flatOutline)
  63. }
  64. }
  65. }
  66. // set highlightedLine to the closest outline line above the editorLine
  67. updateHighlightedLine(editorLine) {
  68. let closestOutlineLine = null
  69. for (let lineId = 0; lineId < this.flatOutline.length; lineId++) {
  70. const outline = this.flatOutline[lineId]
  71. if (editorLine < outline.line) break // editorLine is above
  72. closestOutlineLine = outline.line
  73. }
  74. if (closestOutlineLine === this.highlightedLine) return
  75. this.highlightedLine = closestOutlineLine
  76. this.broadcastChangeEvent()
  77. }
  78. jumpToLine(line) {
  79. this.ignoreNextScroll = true
  80. this.ide.editorManager.jumpToLine({ gotoLine: line })
  81. }
  82. broadcastChangeEvent() {
  83. this.scope.$broadcast('outline-manager:outline-changed', {
  84. isTexFile: this.isTexFile,
  85. outline: this.outline,
  86. highlightedLine: this.highlightedLine
  87. })
  88. }
  89. }
  90. export default OutlineManager