2020-06-29 09:05:08 -04:00
|
|
|
import './controllers/OutlineController'
|
|
|
|
import './components/OutlinePane'
|
|
|
|
import './components/OutlineRoot'
|
|
|
|
import './components/OutlineList'
|
|
|
|
import './components/OutlineItem'
|
2020-07-28 05:37:46 -04:00
|
|
|
import { matchOutline, nestOutline } from './OutlineParser'
|
2020-06-29 09:05:08 -04:00
|
|
|
import isValidTeXFile from '../../main/is-valid-tex-file'
|
|
|
|
|
|
|
|
class OutlineManager {
|
|
|
|
constructor(ide, scope) {
|
|
|
|
this.ide = ide
|
|
|
|
this.scope = scope
|
|
|
|
this.shareJsDoc = null
|
|
|
|
this.isTexFile = false
|
2020-07-28 05:37:46 -04:00
|
|
|
this.flatOutline = []
|
2020-06-29 09:05:08 -04:00
|
|
|
this.outline = []
|
2020-07-28 05:37:46 -04:00
|
|
|
this.highlightedLine = null
|
|
|
|
this.ignoreNextScroll = false
|
|
|
|
this.ignoreNextCursorUpdate = false
|
2020-06-29 09:05:08 -04:00
|
|
|
|
2020-07-16 06:09:01 -04:00
|
|
|
scope.$on('doc:after-opened', () => {
|
2020-07-28 05:37:46 -04:00
|
|
|
this.ignoreNextScroll = true
|
|
|
|
this.ignoreNextCursorUpdate = true
|
2020-07-16 10:03:51 -04:00
|
|
|
this.shareJsDoc = scope.editor.sharejs_doc
|
2020-06-29 09:05:08 -04:00
|
|
|
this.isTexFile = isValidTeXFile(scope.editor.open_doc_name)
|
|
|
|
this.updateOutline()
|
|
|
|
this.broadcastChangeEvent()
|
|
|
|
})
|
|
|
|
|
|
|
|
scope.$watch('openFile.name', openFileName => {
|
|
|
|
this.isTexFile = isValidTeXFile(openFileName)
|
|
|
|
this.updateOutline()
|
|
|
|
this.broadcastChangeEvent()
|
|
|
|
})
|
|
|
|
|
|
|
|
scope.$on('doc:changed', () => {
|
|
|
|
this.updateOutline()
|
|
|
|
this.broadcastChangeEvent()
|
|
|
|
})
|
2020-07-28 05:37:46 -04:00
|
|
|
|
|
|
|
scope.$on('cursor:editor:update', (event, cursorPosition) => {
|
|
|
|
if (this.ignoreNextCursorUpdate) {
|
|
|
|
this.ignoreNextCursorUpdate = false
|
|
|
|
return
|
|
|
|
}
|
|
|
|
this.updateHighlightedLine(cursorPosition.row + 1)
|
|
|
|
this.broadcastChangeEvent()
|
|
|
|
})
|
|
|
|
|
|
|
|
scope.$on('scroll:editor:update', (event, middleVisibleRow) => {
|
|
|
|
if (this.ignoreNextScroll) {
|
|
|
|
this.ignoreNextScroll = false
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
this.updateHighlightedLine(middleVisibleRow + 1)
|
|
|
|
})
|
|
|
|
|
|
|
|
scope.$watch('editor.showRichText', () => {
|
|
|
|
this.ignoreNextScroll = true
|
|
|
|
this.ignoreNextCursorUpdate = true
|
|
|
|
})
|
2020-06-29 09:05:08 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
updateOutline() {
|
|
|
|
this.outline = []
|
|
|
|
if (this.isTexFile) {
|
|
|
|
const content = this.ide.editorManager.getCurrentDocValue()
|
|
|
|
if (content) {
|
2020-07-28 05:37:46 -04:00
|
|
|
this.flatOutline = matchOutline(content)
|
|
|
|
this.outline = nestOutline(this.flatOutline)
|
2020-06-29 09:05:08 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-28 05:37:46 -04:00
|
|
|
// set highlightedLine to the closest outline line above the editorLine
|
|
|
|
updateHighlightedLine(editorLine) {
|
|
|
|
let closestOutlineLine = null
|
|
|
|
for (let lineId = 0; lineId < this.flatOutline.length; lineId++) {
|
|
|
|
const outline = this.flatOutline[lineId]
|
|
|
|
if (editorLine < outline.line) break // editorLine is above
|
|
|
|
closestOutlineLine = outline.line
|
|
|
|
}
|
2020-08-06 05:04:45 -04:00
|
|
|
if (closestOutlineLine === this.highlightedLine) return
|
2020-07-28 05:37:46 -04:00
|
|
|
this.highlightedLine = closestOutlineLine
|
2020-08-06 05:04:45 -04:00
|
|
|
this.broadcastChangeEvent()
|
2020-07-28 05:37:46 -04:00
|
|
|
}
|
|
|
|
|
2020-06-29 09:05:08 -04:00
|
|
|
jumpToLine(line) {
|
2020-07-28 05:37:46 -04:00
|
|
|
this.ignoreNextScroll = true
|
|
|
|
this.ide.editorManager.jumpToLine({ gotoLine: line })
|
2020-06-29 09:05:08 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
broadcastChangeEvent() {
|
|
|
|
this.scope.$broadcast('outline-manager:outline-changed', {
|
|
|
|
isTexFile: this.isTexFile,
|
2020-07-28 05:37:46 -04:00
|
|
|
outline: this.outline,
|
|
|
|
highlightedLine: this.highlightedLine
|
2020-06-29 09:05:08 -04:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default OutlineManager
|