import { 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 Plugin from 'tinymce/plugins/lists/Plugin'; describe('browser.tinymce.plugins.lists.BackspaceDeleteTest', () => { const hook = TinyHooks.bddSetupLight({ plugins: 'lists', add_unload_trigger: false, disable_nodechange: true, indent: false, entities: 'raw', valid_elements: 'li[style|class|data-custom],ol[style|class|data-custom],' + 'ul[style|class|data-custom],dl,dt,dd,em,strong,span,#p,div,br', valid_styles: { '*': 'color,font-size,font-family,background-color,font-weight,' + 'font-style,text-decoration,float,margin,margin-top,margin-right,' + 'margin-bottom,margin-left,display,position,top,left,list-style-type' }, base_url: '/project/tinymce/js/tinymce' }, [ Plugin ]); it('TBA: Backspace at beginning of single LI in UL', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent(editor, '

a

'); assert.equal(editor.selection.getNode().nodeName, 'P'); }); it('TBA: Backspace at end of single LI in UL', () => { const editor = hook.editor(); const content = ''; editor.setContent(content); editor.focus(); // Special set rng, puts selection here:
  • a|
  • const li = editor.dom.select('li')[0]; const rng = editor.dom.createRng(); rng.setStart(li, 1); rng.setEnd(li, 1); editor.selection.setRng(rng); editor.plugins.lists.backspaceDelete(); // The content doesn't change here as it's not a real backspace, we're just ensuring the "delete list" code doesn't fire TinyAssertions.assertContent(editor, content); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('TBA: Backspace at end of single LI in UL with STRONG', () => { const editor = hook.editor(); const content = ''; editor.setContent(content); editor.focus(); // Special set rng, puts selection here:
  • a|b
  • const strong = editor.dom.select('strong')[0]; const rng = editor.dom.createRng(); rng.setStart(strong, 0); rng.setEnd(strong, 0); editor.selection.setRng(rng); editor.plugins.lists.backspaceDelete(); // The content doesn't change here as it's not a real backspace, we're just ensuring the "delete list" code doesn't fire TinyAssertions.assertContent(editor, content); assert.equal(editor.selection.getNode().nodeName, 'STRONG'); }); it('TBA: Backspace at beginning of first LI in UL', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent(editor, '

    a

    ' + '' ); assert.equal(editor.selection.getNode().nodeName, 'P'); }); it('TBA: Backspace at beginning of middle LI in UL', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li:nth-child(2)', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent(editor, '' ); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('TBA: Backspace at beginning of start LI in UL inside UL', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li li', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent(editor, '' ); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('TBA: Backspace at beginning of middle LI in UL inside UL', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li li:nth-child(2)', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent(editor, '' ); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('TBA: Backspace at beginning of LI with empty LI above in UL', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li:nth-child(3)', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent(editor, '' ); assert.equal(editor.selection.getNode().innerHTML, 'b'); }); it('TBA: Backspace at beginning of LI with BR padded empty LI above in UL', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li:nth-child(3)', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent(editor, '' ); assert.equal(editor.selection.getNode().innerHTML, 'b'); }); it('TBA: Backspace at empty LI (IE)', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li:nth-child(2)', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent(editor, '' ); assert.equal(editor.selection.getNode().innerHTML, 'a'); }); it('TBA: Backspace at beginning of LI with empty LI with STRING and BR above in UL', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li:nth-child(3)', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent(editor, '' ); assert.equal(editor.selection.getNode().innerHTML, 'b'); }); it('TBA: Backspace at nested LI with adjacent BR', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'ul ul ul li', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent(editor, ''); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('TBA: Backspace at LI selected with triple-click in UL', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li:nth-child(1)', 0, 'li:nth-child(2)', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent( editor, '' ); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('TBA: Backspace at partially selected list', () => { const editor = hook.editor(); editor.setContent( '

    abc

    ' + '' ); editor.focus(); LegacyUnit.setSelection(editor, 'p', 1, 'li:nth-child(2)', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent( editor, '

    ab

    ' + '' ); assert.equal(editor.selection.getNode().nodeName, 'P'); }); // Delete it('TBA: Delete at end of single LI in UL', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li', 1); editor.plugins.lists.backspaceDelete(true); TinyAssertions.assertContent(editor, '' ); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('TBA: Delete at end of first LI in UL', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li', 1); editor.plugins.lists.backspaceDelete(true); TinyAssertions.assertContent(editor, '' ); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('TBA: Delete at end of middle LI in UL', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li:nth-child(2)', 1); editor.plugins.lists.backspaceDelete(true); TinyAssertions.assertContent(editor, '' ); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('TBA: Delete at end of start LI in UL inside UL', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li li', 1); editor.plugins.lists.backspaceDelete(true); TinyAssertions.assertContent(editor, '' ); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('TBA: Delete at end of middle LI in UL inside UL with', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li li:nth-child(2)', 1); editor.plugins.lists.backspaceDelete(true); TinyAssertions.assertContent(editor, '' ); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('TBA: Delete at end of LI before empty LI', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li', 1); editor.plugins.lists.backspaceDelete(true); TinyAssertions.assertContent(editor, '' ); assert.equal(editor.selection.getNode().innerHTML, 'a'); }); it('TBA: Delete at end of LI before BR padded empty LI', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li', 1); editor.plugins.lists.backspaceDelete(true); TinyAssertions.assertContent(editor, '' ); assert.equal(editor.selection.getNode().innerHTML, 'a'); }); it('TBA: Delete at end of LI before empty LI with STRONG', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li', 1); editor.plugins.lists.backspaceDelete(true); TinyAssertions.assertContent(editor, '' ); assert.equal(editor.selection.getNode().innerHTML, 'a'); }); it('TBA: Delete at nested LI with adjacent BR', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); editor.selection.setCursorLocation(editor.dom.select('ul ul li')[0], 0); editor.plugins.lists.backspaceDelete(true); TinyAssertions.assertContent(editor, ''); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('TBA: Delete at BR before text in LI', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); editor.selection.setCursorLocation(editor.dom.select('li')[1], 1); editor.plugins.lists.backspaceDelete(false); TinyAssertions.assertContent(editor, ''); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('TBA: Backspace merge li elements', () => { const editor = hook.editor(); // IE allows you to place the caret inside a LI without children editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li:nth-child(2)', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent(editor, '' ); assert.equal(editor.selection.getNode().nodeName, 'LI'); assert.equal(editor.selection.getRng().startContainer.nodeType, 3, 'Should be a text node'); }); it('TBA: Backspace at block inside li element into li without block element', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'p', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent( editor, '' ); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('TBA: Backspace at block inside li element into li with block element', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li:nth-child(2) p', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent( editor, '' ); assert.equal(editor.selection.getNode().nodeName, 'P'); }); it('TBA: Backspace at block inside li element into li with multiple block elements', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li:nth-child(2) p', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent( editor, '' ); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('TBA: Delete at block inside li element into li without block element', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'p', 1); editor.plugins.lists.backspaceDelete(true); TinyAssertions.assertContent( editor, '' ); assert.equal(editor.selection.getNode().nodeName, 'P'); }); it('TBA: Delete at block inside li element into li with block element', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li:nth-child(1) p', 1); editor.plugins.lists.backspaceDelete(true); TinyAssertions.assertContent( editor, '' ); assert.equal(editor.selection.getNode().nodeName, 'P'); }); it('TBA: Delete at block inside li element into li with multiple block elements', () => { const editor = hook.editor(); editor.setContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li:nth-child(1)', 1); editor.plugins.lists.backspaceDelete(true); TinyAssertions.assertContent( editor, '' ); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('Backspace from indented list', () => { const editor = hook.editor(); editor.setContent( '
      ' + '
    1. a' + '
        ' + '
      1. ' + '
          ' + '
        1. b
        2. ' + '
        ' + '
      2. ' + '
      ' + '
    2. ' + '
    ' ); editor.focus(); LegacyUnit.setSelection(editor, 'ol li ol li ol li:nth-child(1)', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent( editor, '
      ' + '
    1. a' + '
        ' + '
      1. b
      2. ' + '
      ' + '
    2. ' + '
    ' ); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('Delete into indented list', () => { const editor = hook.editor(); editor.setContent( '
      ' + '
    1. a' + '
        ' + '
      1. ' + '
          ' + '
        1. b
        2. ' + '
        ' + '
      2. ' + '
      ' + '
    2. ' + '
    ' ); editor.focus(); LegacyUnit.setSelection(editor, 'ol li:nth-child(1)', 1); editor.plugins.lists.backspaceDelete(true); TinyAssertions.assertContent( editor, '
      ' + '
    1. ab
    2. ' + '
    ' ); assert.equal(editor.selection.getNode().nodeName, 'LI'); }); it('TBA: Backspace at beginning of LI in UL inside UL and then undo', () => { const editor = hook.editor(); editor.resetContent( '' ); editor.focus(); LegacyUnit.setSelection(editor, 'li li:nth-child(1)', 0); editor.plugins.lists.backspaceDelete(); TinyAssertions.assertContent( editor, '' ); assert.equal(editor.selection.getNode().nodeName, 'LI'); editor.undoManager.undo(); TinyAssertions.assertContent( editor, '' ); }); });