import Mathematics from '../src/math'; import AutoMath from '../src/automath'; import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor'; import Clipboard from '@ckeditor/ckeditor5-clipboard/src/clipboard'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; import Undo from '@ckeditor/ckeditor5-undo/src/undo'; import Typing from '@ckeditor/ckeditor5-typing/src/typing'; import global from '@ckeditor/ckeditor5-utils/src/dom/global'; import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; import { expect } from 'chai'; import type { SinonFakeTimers } from 'sinon'; describe( 'AutoMath - integration', () => { let editorElement: HTMLDivElement, editor: ClassicEditor; beforeEach( async () => { editorElement = global.document.createElement( 'div' ); global.document.body.appendChild( editorElement ); return ClassicEditor .create( editorElement, { plugins: [ Mathematics, AutoMath, Typing, Paragraph ], math: { engine: ( equation, element, display ) => { if ( display ) { element.innerHTML = '\\[' + equation + '\\]'; } else { element.innerHTML = '\\(' + equation + '\\)'; } } } } ) .then( newEditor => { editor = newEditor; } ); } ); afterEach( () => { editorElement.remove(); return editor.destroy(); } ); it( 'should load Clipboard plugin', () => { expect( editor.plugins.get( Clipboard ) ).to.instanceOf( Clipboard ); } ); it( 'should load Undo plugin', () => { expect( editor.plugins.get( Undo ) ).to.instanceOf( Undo ); } ); it( 'has proper name', () => { expect( AutoMath.pluginName ).to.equal( 'AutoMath' ); } ); describe( 'use fake timers', () => { let clock: SinonFakeTimers; beforeEach( () => { clock = sinon.useFakeTimers(); } ); afterEach( () => { clock.restore(); } ); it( 'replaces pasted text with mathtex element after 100ms', () => { setData( editor.model, '[]' ); pasteHtml( editor, '\\[x^2\\]' ); expect( getData( editor.model ) ).to.equal( '\\[x^2\\][]' ); clock.tick( 100 ); expect( getData( editor.model ) ).to.equal( '[]' ); } ); it( 'replaces pasted text with inline mathtex element after 100ms', () => { setData( editor.model, '[]' ); pasteHtml( editor, '\\(x^2\\)' ); expect( getData( editor.model ) ).to.equal( '\\(x^2\\)[]' ); clock.tick( 100 ); expect( getData( editor.model ) ).to.equal( '[]' ); } ); it( 'can undo auto-mathing', () => { setData( editor.model, '[]' ); pasteHtml( editor, '\\[x^2\\]' ); expect( getData( editor.model ) ).to.equal( '\\[x^2\\][]' ); clock.tick( 100 ); editor.commands.execute( 'undo' ); expect( getData( editor.model ) ).to.equal( '\\[x^2\\][]' ); } ); it( 'works for not collapsed selection inside single element', () => { setData( editor.model, '[Foo]' ); pasteHtml( editor, '\\[x^2\\]' ); clock.tick( 100 ); expect( getData( editor.model ) ).to.equal( '[]' ); } ); it( 'works for not collapsed selection over a few elements', () => { setData( editor.model, 'Fo[oBa]r' ); pasteHtml( editor, '\\[x^2\\]' ); clock.tick( 100 ); expect( getData( editor.model ) ).to.equal( 'Fo[]r' ); } ); it( 'inserts mathtex in-place (collapsed selection)', () => { setData( editor.model, 'Foo []Bar' ); pasteHtml( editor, '\\[x^2\\]' ); clock.tick( 100 ); expect( getData( editor.model ) ).to.equal( 'Foo ' + '[]' + 'Bar' ); } ); it( 'inserts math in-place (non-collapsed selection)', () => { setData( editor.model, 'Foo [Bar] Baz' ); pasteHtml( editor, '\\[x^2\\]' ); clock.tick( 100 ); expect( getData( editor.model ) ).to.equal( 'Foo ' + '[]' + ' Baz' ); } ); it( 'does nothing if pasted two equation as text', () => { setData( editor.model, '[]' ); pasteHtml( editor, '\\[x^2\\] \\[\\sqrt{x}2\\]' ); clock.tick( 100 ); expect( getData( editor.model ) ).to.equal( '\\[x^2\\] \\[\\sqrt{x}2\\][]' ); } ); } ); function pasteHtml( editor: ClassicEditor, html: string ) { editor.editing.view.document.fire( 'paste', { dataTransfer: createDataTransfer( { 'text/html': html } ), preventDefault() { return undefined; } } ); } function createDataTransfer( data: Record ) { return { getData( type: string ) { return data[ type ]; } }; } } );