import { describe, it } from '@ephox/bedrock-client'; import { TinyHooks, TinySelections } from '@ephox/wrap-mcagar'; import { assert } from 'chai'; import Editor from 'tinymce/core/api/Editor'; import { BeforeGetContentEvent } from 'tinymce/core/api/EventTypes'; import { EditorEvent } from 'tinymce/core/api/util/EventDispatcher'; import { GetSelectionContentArgs } from 'tinymce/core/content/ContentTypes'; import { getContent } from 'tinymce/core/selection/GetSelectionContent'; describe('browser.tinymce.selection.GetSelectionContentTest', () => { const hook = TinyHooks.bddSetupLight({ indent: false, base_url: '/project/tinymce/js/tinymce' }, []); const testDivId = 'testDiv1'; const assertSelectedRadioButtons = (editor: Editor, nrOfInputs: number, shouldBeSelected: number) => { const total = editor.getBody().querySelectorAll('input').length; const selected = editor.getBody().querySelectorAll('input:checked').length; assert.equal(total, nrOfInputs, 'Should have the right amount of inputs'); assert.equal(selected, shouldBeSelected, 'Should have exactly one radio button'); }; const focusDiv = () => { const input = document.querySelector('#' + testDivId) as HTMLDivElement; input.focus(); }; const removeTestDiv = () => { const input = document.querySelector('#' + testDivId); if (input) { input.parentNode?.removeChild(input); } }; const addTestDiv = () => { const div = document.createElement('div'); div.innerHTML = 'xxx'; div.contentEditable = 'true'; div.id = testDivId; document.body.appendChild(div); }; const getSelectionContent = (editor: Editor, args: Partial) => getContent(editor, args).toString().replace(/[\r]+/g, ''); const assertGetContent = (label: string, editor: Editor, expectedContent: string, args: Partial = {}) => { const content = getSelectionContent(editor, args); assert.equal(content, expectedContent, label + ': Should be expected contents'); }; const assertGetContentOverrideBeforeGetContent = (label: string, editor: Editor, expectedContent: string, args: Partial = {}) => { const handler = (e: EditorEvent) => { if (e.selection === true) { e.preventDefault(); e.content = expectedContent; } }; editor.on('BeforeGetContent', handler); const content = getSelectionContent(editor, args); assert.equal(content, expectedContent, label + ': Should be expected contents'); editor.off('BeforeGetContent', handler); }; it('TBA: Should be empty contents on a caret selection', () => { const editor = hook.editor(); editor.setContent('

a

'); TinySelections.setSelection(editor, [ 0, 0 ], 0, [ 0, 0 ], 0); assertGetContent('Should be empty selection on caret', editor, ''); }); it('TBA: Should be text contents on a range selection', () => { const editor = hook.editor(); editor.setContent('

a

'); TinySelections.setSelection(editor, [ 0, 0 ], 0, [ 0, 0 ], 1); assertGetContent('Should be some content', editor, 'a'); }); it('TBA: Should be text contents provided by override handler', () => { const editor = hook.editor(); editor.setContent('

a

'); TinySelections.setSelection(editor, [ 0, 0 ], 0, [ 0, 0 ], 1); assertGetContentOverrideBeforeGetContent('Should be overridden content', editor, 'X'); }); it(`TBA: Should be text contents when editor isn't focused and format is text`, () => { const editor = hook.editor(); addTestDiv(); editor.setContent('

ab

'); TinySelections.setSelection(editor, [ 0, 0 ], 0, [ 0, 0 ], 2); focusDiv(); assertGetContent('Should be some content', editor, 'ab', { format: 'text' }); removeTestDiv(); }); it('TBA: Should be text content with newline', () => { const editor = hook.editor(); editor.setContent('

ab
cd

'); TinySelections.setSelection(editor, [ 0, 0 ], 0, [ 0, 2 ], 2); assertGetContent('Should be some content', editor, 'ab\ncd', { format: 'text' }); }); it('TBA: Should be text content with leading visible spaces', () => { const editor = hook.editor(); editor.setContent('

content Leading space

'); TinySelections.setSelection(editor, [ 0 ], 1, [ 0 ], 2); assertGetContent('Should be some content', editor, ' Leading space', { format: 'text' }); }); it('TBA: Should be text content with trailing visible spaces', () => { const editor = hook.editor(); editor.setContent('

Trailing space content

'); TinySelections.setSelection(editor, [ 0 ], 0, [ 0 ], 1); assertGetContent('Should be some content', editor, 'Trailing space ', { format: 'text' }); }); it('TINY-6448: pre blocks should have preserved spaces', () => { const editor = hook.editor(); editor.setContent('
          This      Has\n     Spaces
'); TinySelections.setSelection(editor, [ 0 ], 0, [ 0 ], 1); assertGetContent('Should be some content', editor, ' This Has\n Spaces', { format: 'text' }); }); it('TINY-6448: p blocks should not preserve spaces', () => { const editor = hook.editor(); editor.setContent('

This Has\n Spaces

'); TinySelections.setSelection(editor, [ ], 0, [ ], 1); assertGetContent('Should be some content', editor, 'This Has Spaces', { format: 'text' }); }); it('TINY-7981: inputs should not be deselected', () => { const editor = hook.editor(); editor.setContent('

Option 1Option 2Option 3

'); TinySelections.setSelection(editor, [ 0 ], 0, [ 0 ], 6); assertGetContent('Should be some content', editor, 'Option 1Option 2Option 3', { format: 'text' }); assertSelectedRadioButtons(editor, 3, 1); }); it('TBA: Should be text content without non-visible leading/trailing spaces', () => { const editor = hook.editor(); editor.setContent('

spaces

'); TinySelections.setSelection(editor, [ 0 ], 0, [ 0 ], 1); assertGetContent('Should be some content', editor, 'spaces', { format: 'text' }); editor.setContent('

spaces

'); TinySelections.setSelection(editor, [], 0, [], 1); assertGetContent('Should be some content', editor, 'spaces', { format: 'text' }); }); });