overleaf/services/web/frontend/js/features/source-editor/extensions/empty-line-filler.ts
Mathias Jakobsen c2292a8567 Merge pull request #12677 from overleaf/ae-codemirror-view-upgrade
[cm6] Upgrade CodeMirror dependencies

GitOrigin-RevId: cc973b1c5b23eca0fc93a9b3a970c832212e47af
2023-04-21 08:02:53 +00:00

76 lines
1.8 KiB
TypeScript

import {
Decoration,
DecorationSet,
EditorView,
ViewPlugin,
ViewUpdate,
WidgetType,
} from '@codemirror/view'
import browser from './browser'
class EmptyLineWidget extends WidgetType {
toDOM(view: EditorView): HTMLElement {
const element = document.createElement('span')
element.className = 'ol-cm-filler'
return element
}
eq(widget: EmptyLineWidget) {
return true
}
}
export const emptyLineFiller = () => {
if (browser.ios) {
// disable on iOS as it breaks Backspace across empty lines
// https://github.com/overleaf/internal/issues/12192
return []
}
return [
ViewPlugin.fromClass(
class {
decorations: DecorationSet
constructor(view: EditorView) {
this.decorations = this.buildDecorations(view)
}
update(update: ViewUpdate) {
if (update.docChanged || update.viewportChanged)
this.decorations = this.buildDecorations(update.view)
}
buildDecorations(view: EditorView) {
const decorations = []
const { from, to } = view.viewport
const { doc } = view.state
let pos = from
while (pos <= to) {
const line = doc.lineAt(pos)
if (line.length === 0) {
const decoration = Decoration.widget({
widget: new EmptyLineWidget(),
side: 1,
})
decorations.push(decoration.range(pos))
}
pos = line.to + 1
}
return Decoration.set(decorations)
}
},
{
decorations(value) {
return value.decorations
},
}
),
EditorView.baseTheme({
'.ol-cm-filler': {
display: 'inline',
padding: '2px',
},
}),
]
}