mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
Make editor focusable in view-only mode GitOrigin-RevId: ed9b079fa379d84f7f410669fa2d865f82e21cb1
131 lines
3.7 KiB
TypeScript
131 lines
3.7 KiB
TypeScript
import { expect } from 'chai'
|
|
import { EditorState } from '@codemirror/state'
|
|
import { EditorView } from '@codemirror/view'
|
|
import {
|
|
editable,
|
|
setEditable,
|
|
} from '../../../../../frontend/js/features/source-editor/extensions/editable'
|
|
|
|
const doc = `\\documentclass{article}
|
|
\\begin{document}
|
|
Hello world
|
|
\\end{document}`
|
|
|
|
describe('editable extension', function () {
|
|
let view: EditorView
|
|
let container: HTMLElement
|
|
|
|
beforeEach(function () {
|
|
container = document.createElement('div')
|
|
document.body.appendChild(container)
|
|
})
|
|
|
|
afterEach(function () {
|
|
view?.destroy()
|
|
container?.remove()
|
|
})
|
|
|
|
function createView(extensions = [editable()]) {
|
|
view = new EditorView({
|
|
parent: container,
|
|
state: EditorState.create({
|
|
doc,
|
|
extensions,
|
|
}),
|
|
})
|
|
return view
|
|
}
|
|
|
|
describe('initial read-only state', function () {
|
|
beforeEach(function () {
|
|
createView()
|
|
})
|
|
|
|
it('should set EditorState.readOnly to true', function () {
|
|
expect(view.state.readOnly).to.be.true
|
|
})
|
|
|
|
it('should set EditorView.editable to false', function () {
|
|
expect(view.state.facet(EditorView.editable)).to.be.false
|
|
})
|
|
|
|
it('should set contenteditable="false" on the content element', function () {
|
|
expect(view.contentDOM.getAttribute('contenteditable')).to.equal('false')
|
|
})
|
|
|
|
it('should set tabindex="0" to allow focus in read-only mode', function () {
|
|
expect(view.contentDOM.getAttribute('tabindex')).to.equal('0')
|
|
})
|
|
|
|
it('should allow the editor to receive focus via tabindex', function () {
|
|
view.contentDOM.focus()
|
|
expect(document.activeElement).to.equal(view.contentDOM)
|
|
})
|
|
})
|
|
|
|
describe('setEditable(true) - switching to editable mode', function () {
|
|
beforeEach(function () {
|
|
createView()
|
|
view.dispatch(setEditable(true))
|
|
})
|
|
|
|
it('should set EditorState.readOnly to false', function () {
|
|
expect(view.state.readOnly).to.be.false
|
|
})
|
|
|
|
it('should set EditorView.editable to true', function () {
|
|
expect(view.state.facet(EditorView.editable)).to.be.true
|
|
})
|
|
|
|
it('should set contenteditable="true" on the content element', function () {
|
|
expect(view.contentDOM.getAttribute('contenteditable')).to.equal('true')
|
|
})
|
|
|
|
it('should not have tabindex attribute (not needed when contenteditable)', function () {
|
|
expect(view.contentDOM.getAttribute('tabindex')).to.be.null
|
|
})
|
|
|
|
it('should allow document modifications', function () {
|
|
view.dispatch({
|
|
changes: { from: 0, insert: 'New text ' },
|
|
})
|
|
|
|
expect(view.state.doc.toString().startsWith('New text ')).to.be.true
|
|
})
|
|
|
|
it('should allow the editor to receive focus', function () {
|
|
view.contentDOM.focus()
|
|
expect(document.activeElement).to.equal(view.contentDOM)
|
|
})
|
|
})
|
|
|
|
describe('setEditable(false) - switching to read-only mode', function () {
|
|
beforeEach(function () {
|
|
createView()
|
|
view.dispatch(setEditable(true))
|
|
view.dispatch(setEditable(false))
|
|
})
|
|
|
|
it('should set EditorState.readOnly to true', function () {
|
|
expect(view.state.readOnly).to.be.true
|
|
})
|
|
|
|
it('should set EditorView.editable to false', function () {
|
|
expect(view.state.facet(EditorView.editable)).to.be.false
|
|
})
|
|
|
|
it('should set contenteditable="false" on the content element', function () {
|
|
expect(view.contentDOM.getAttribute('contenteditable')).to.equal('false')
|
|
})
|
|
|
|
it('should restore tabindex="0" for focusability', function () {
|
|
expect(view.contentDOM.getAttribute('tabindex')).to.equal('0')
|
|
})
|
|
|
|
it('should still allow the editor to receive focus after switching modes', function () {
|
|
view.contentDOM.focus()
|
|
expect(document.activeElement).to.equal(view.contentDOM)
|
|
})
|
|
})
|
|
})
|