mirror of
https://github.com/overleaf/overleaf.git
synced 2024-12-14 23:50:58 -05:00
3f29aa2195
GitOrigin-RevId: 3551e02fab44fae7fcab5cb12886d45969e3990f
81 lines
1.9 KiB
TypeScript
81 lines
1.9 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
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A custom extension which adds a widget decoration at the start of each empty line in the viewport,
|
|
* so that the line is highlighted when part of tracked changes.
|
|
*/
|
|
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
|
|
},
|
|
}
|
|
),
|
|
emptyLineFillerTheme,
|
|
]
|
|
}
|
|
|
|
const emptyLineFillerTheme = EditorView.baseTheme({
|
|
'.ol-cm-filler': {
|
|
padding: '0 2px',
|
|
},
|
|
})
|