import { before, describe, it } from '@ephox/bedrock-client'; import { LegacyUnit, TinyAssertions, TinyHooks } from '@ephox/wrap-mcagar'; import { assert } from 'chai'; import Editor from 'tinymce/core/api/Editor'; import Env from 'tinymce/core/api/Env'; describe('browser.tinymce.core.util.QuirksWebkitTest', () => { before(function () { if (!Env.browser.isChromium() && !Env.browser.isSafari()) { this.skip(); } }); const hook = TinyHooks.bddSetupLight({ add_unload_trigger: false, indent: false, disable_nodechange: true, base_url: '/project/tinymce/js/tinymce' }, [], true); it('Delete from beginning of P into H1', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

b

'; LegacyUnit.setSelection(editor, 'p', 0); editor.execCommand('Delete'); TinyAssertions.assertContent(editor, '

ab

'); assert.equal(editor.selection.getStart().nodeName, 'H1'); }); it('Delete between empty paragraphs', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a



b

'; LegacyUnit.setSelection(editor, 'p:last-of-type', 0); editor.execCommand('Delete'); TinyAssertions.assertRawContent(editor, '

a


b

'); assert.equal(editor.selection.getStart().nodeName, 'P'); }); it('Delete range from middle of H1 to middle of span in P', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

ab

bcd

'; LegacyUnit.setSelection(editor, 'h1', 1, 'span', 1); editor.execCommand('Delete'); TinyAssertions.assertContent(editor, '

ad

'); assert.equal(editor.selection.getStart().nodeName, 'H1'); }); it('Delete from beginning of P with style span inside into H1 with inline block', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

bc

'; LegacyUnit.setSelection(editor, 'p', 0); editor.execCommand('Delete'); TinyAssertions.assertContent(editor, '

abc

'); assert.equal(editor.selection.getNode().nodeName, 'H1'); }); it('Delete from beginning of P with style span inside into H1', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

bc

'; LegacyUnit.setSelection(editor, 'p', 0); editor.execCommand('Delete'); TinyAssertions.assertContent(editor, '

abc

'); assert.equal(editor.selection.getStart().nodeName, 'H1'); }); it('Delete from beginning of P into H1 with contentEditable:false', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

bc

'; LegacyUnit.setSelection(editor, 'p', 0); editor.execCommand('Delete'); TinyAssertions.assertContent(editor, '

a

bc

'); assert.equal(editor.selection.getNode().nodeName, 'P'); }); it('Delete from beginning of P with style span inside into H1 with trailing BR', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

bc

'; LegacyUnit.setSelection(editor, 'p', 0); editor.execCommand('Delete'); TinyAssertions.assertContent(editor, '

abc

'); assert.equal(editor.selection.getStart().nodeName, 'H1'); }); it('Delete from empty P with style span inside into H1', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

b

'; LegacyUnit.setSelection(editor, 'span', 0); editor.execCommand('Delete'); TinyAssertions.assertContent(editor, '

ab

'); assert.equal(editor.selection.getNode().nodeName, 'H1'); }); it('Delete from beginning of P with span style to H1', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

b

'; LegacyUnit.setSelection(editor, 'span', 0); editor.execCommand('Delete'); TinyAssertions.assertContent(editor, '

ab

'); assert.equal(editor.selection.getNode().nodeName, 'H1'); }); it('Delete from beginning of P with BR line to H1', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

b
c

'; LegacyUnit.setSelection(editor, 'p', 0); editor.execCommand('Delete'); TinyAssertions.assertContent(editor, '

ab
c

'); assert.equal(editor.selection.getStart().nodeName, 'H1'); }); it('Delete from after image to paragraph', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

'; const rng = editor.dom.createRng(); rng.setStartAfter(editor.dom.select('img')[0]); rng.setEndAfter(editor.dom.select('img')[0]); editor.selection.setRng(rng); editor.execCommand('Delete'); TinyAssertions.assertRawContent(editor, '

a


'); assert.equal(editor.selection.getNode().nodeName, 'P'); }); it('ForwardDelete from end of H1 to P with style span', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

b

'; LegacyUnit.setSelection(editor, 'h1', 1); editor.execCommand('ForwardDelete'); TinyAssertions.assertContent(editor, '

ab

'); assert.equal(editor.selection.getNode().nodeName, 'H1'); }); it('ForwardDelete from end of H1 with trailing BR to P with style span', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

b

'; LegacyUnit.setSelection(editor, 'h1', 1); editor.execCommand('ForwardDelete'); TinyAssertions.assertContent(editor, '

ab

'); assert.equal(editor.selection.getNode().nodeName, 'H1'); }); it('ForwardDelete from end of H1 with two trailing BR:s to P with style span', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

b

'; LegacyUnit.setSelection(editor, 'h1', 1); editor.execCommand('ForwardDelete'); TinyAssertions.assertContent(editor, '

a

b

'); assert.equal(editor.selection.getStart().nodeName, 'H1'); }); it('ForwardDelete from end of H1 to P with style and inline block element', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

b

'; LegacyUnit.setSelection(editor, 'h1', 1); editor.execCommand('ForwardDelete'); TinyAssertions.assertContent(editor, '

ab

'); assert.equal(editor.selection.getStart().nodeName, 'H1'); }); it('ForwardDelete from end of H1 with BR line to P', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a
b

c

'; const rng = editor.selection.getRng(); rng.setStart(editor.dom.select('h1')[0].lastChild as Text, 1); rng.setEnd(editor.dom.select('h1')[0].lastChild as Text, 1); editor.selection.setRng(rng); editor.execCommand('ForwardDelete'); TinyAssertions.assertContent(editor, '

a
bc

'); assert.equal(editor.selection.getStart().nodeName, 'H1'); }); it('ForwardDelete from end of H1 into P', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

b

'; LegacyUnit.setSelection(editor, 'h1', 1); editor.execCommand('ForwardDelete'); TinyAssertions.assertContent(editor, '

ab

'); assert.equal(editor.selection.getStart().nodeName, 'H1'); }); it('ForwardDelete from end of H1 into P with contentEditable:false', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

b

'; LegacyUnit.setSelection(editor, 'h1', 1); editor.execCommand('ForwardDelete'); TinyAssertions.assertContent(editor, '

a

b

'); }); it('ForwardDelete from end of H1 into P with style span inside', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

bc

'; LegacyUnit.setSelection(editor, 'h1', 1); editor.execCommand('ForwardDelete'); TinyAssertions.assertContent(editor, '

abc

'); assert.equal(editor.selection.getStart().nodeName, 'H1'); }); it('Backspace key from beginning of P into H1', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

b

'; LegacyUnit.setSelection(editor, 'p', 0); editor.dispatch('keydown', { keyCode: 8, shiftKey: false, ctrlKey: false, altKey: false, metaKey: false } as KeyboardEvent); TinyAssertions.assertContent(editor, '

ab

'); assert.equal(editor.selection.getNode().nodeName, 'H1'); }); it('Delete key from end of H1 into P', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

a

b

'; LegacyUnit.setSelection(editor, 'h1', 1); editor.dispatch('keydown', { keyCode: 46, shiftKey: false, ctrlKey: false, altKey: false, metaKey: false } as KeyboardEvent); TinyAssertions.assertContent(editor, '

ab

'); assert.equal(editor.selection.getStart().nodeName, 'H1'); }); /* // These used to be supported in the Quirks branch however not sure if // we need to deal with this very uncommon operations. If we do we need // to re-introduce them in the new Backspace/Delete logic it('Backspace previous word', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

abc 123

'; LegacyUnit.setSelection(editor, 'p', 7); editor.fire("keydown", { keyCode: 8, ctrlKey: true }); TinyAssertions.assertContent(editor, '

abc 

'); assert.equal(editor.selection.getStart().nodeName, 'P'); }); it('Backspace previous line', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

abc 123

'; LegacyUnit.setSelection(editor, 'p', 7); editor.fire("keydown", { keyCode: 8, metaKey: true }); TinyAssertions.assertContent(editor, '


'); assert.equal(editor.selection.getStart().nodeName, 'BR'); }); it('Delete next word', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

abc 123

'; LegacyUnit.setSelection(editor, 'p', 0); editor.dispatch("keydown", { keyCode: 46, ctrlKey: true }); // Remove nbsp since very old WebKit has an slight issue assert.equal(editor.getContent().replace(' ', ''), '

123

'); assert.equal(editor.selection.getStart().nodeName, 'P'); }); it('Delete next line', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

abc 123

'; LegacyUnit.setSelection(editor, 'p', 0); editor.fire("keydown", { keyCode: 46, metaKey: true }); TinyAssertions.assertContent(editor, '


'); assert.equal(editor.selection.getStart().nodeName, 'BR'); }); it('Type over bold text in fully selected block and keep bold', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

x

y

'; LegacyUnit.setSelection(editor, 'b', 0, 'b', 1); editor.fire("keypress", { keyCode: 65, charCode: 65 }); TinyAssertions.assertContent(editor, '

a

y

'); assert.equal(editor.selection.getStart().nodeName, 'B'); }); it('Type over partial bold text and keep bold', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

xy

'; LegacyUnit.setSelection(editor, 'b', 0, 'b', 1); editor.fire("keypress", { keyCode: 65, charCode: 65 }); TinyAssertions.assertContent(editor, '

ay

'); assert.equal(editor.selection.getStart().nodeName, 'B'); }); it('Type over bold text wrapped inside other formats', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

123

'; LegacyUnit.setSelection(editor, 'b', 0, 'b', 1); editor.fire("keypress", { keyCode: 65, charCode: 65 }); TinyAssertions.assertContent(editor, '

1a3

'); assert.equal(editor.selection.getStart().nodeName, 'B'); }); it('Delete last character in formats', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

b

'; LegacyUnit.setSelection(editor, 'i', 1); editor.fire("keydown", { keyCode: 8 }); TinyAssertions.assertContent(editor, '


'); assert.equal(editor.selection.getStart(true).nodeName, 'I'); }); it('ForwardDelete last character in formats', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

b

'; LegacyUnit.setSelection(editor, 'i', 0); editor.fire("keydown", { keyCode: 46 }); TinyAssertions.assertContent(editor, '


'); assert.equal(editor.selection.getStart(true).nodeName, 'I'); }); it('Delete in empty in formats text block', () => { const editor = hook.editor(); var rng; editor.getBody().innerHTML = '

a



'; rng = editor.dom.createRng(); rng.setStartBefore(editor.$('br:last')[0]); rng.setEndBefore(editor.$('br:last')[0]); editor.selection.setRng(rng); editor.fire("keydown", { keyCode: 8 }); TinyAssertions.assertContent(editor, '

a


'); assert.equal(editor.selection.getStart(true).nodeName, 'I'); }); it('ForwardDelete in empty formats text block', () => { const editor = hook.editor(); var rng; editor.getBody().innerHTML = '

a



'; rng = editor.dom.createRng(); rng.setStartBefore(editor.$('br:first')[0]); rng.setEndBefore(editor.$('br:first')[0]); editor.selection.setRng(rng); editor.fire("keydown", { keyCode: 46 }); TinyAssertions.assertContent(editor, '

a


'); assert.equal(editor.selection.getStart(true).nodeName, 'I'); }); it('Type over all contents', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

abc

'; LegacyUnit.setSelection(editor, 'p', 0, 'p', 3); editor.fire('keypress', { charCode: 97 }); TinyAssertions.assertContent(editor, '

a

'); assert.equal(editor.selection.getRng().startContainer.data, 'a'); assert.equal(editor.selection.getRng().startOffset, 1); }); */ it('ForwardDelete all contents', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

abc

'; LegacyUnit.setSelection(editor, 'p', 0, 'p', 3); editor.dispatch('keydown', { keyCode: 46 } as KeyboardEvent); TinyAssertions.assertRawContent(editor, '


'); assert.equal(editor.selection.getStart(true).nodeName, 'P'); }); it('Delete all contents', () => { const editor = hook.editor(); editor.getBody().innerHTML = '

abc

'; LegacyUnit.setSelection(editor, 'p', 0, 'p', 3); editor.dispatch('keydown', { keyCode: 8 } as KeyboardEvent); TinyAssertions.assertRawContent(editor, '


'); assert.equal(editor.selection.getStart(true).nodeName, 'P'); }); });