ModuleLoader.require([ "tinymce/caret/CaretPosition", "tinymce/caret/CaretContainer", "tinymce/util/VK", "tinymce/text/Zwsp" ], function(CaretPosition, CaretContainer, VK, Zwsp) { module("tinymce.SelectionOverrides", { setupModule: function() { QUnit.stop(); tinymce.init({ selector: "textarea", add_unload_trigger: false, disable_nodechange: true, skin: false, entities: 'raw', indent: false, init_instance_callback: function(ed) { window.editor = ed; QUnit.start(); } }); } }); function pressKey(key) { return function() { Utils.pressKey({keyCode: key}); }; } function exitPreTest(arrow, offset, expectedContent) { return function() { editor.setContent('
abc
'); Utils.setSelection('pre', 1); arrow(); equal(editor.getContent(), '
abc
'); equal(editor.selection.getNode().nodeName, 'PRE'); Utils.setSelection('pre', offset); arrow(); equal(editor.getContent(), expectedContent); equal(editor.selection.getNode().nodeName, 'P'); }; } function assertCaretInCaretBlockContainer() { var beforeRng = editor.selection.getRng(); equal(CaretContainer.isCaretContainerBlock(beforeRng.startContainer.parentNode), true, 'Not in caret block container.'); } var leftArrow = pressKey(VK.LEFT); var rightArrow = pressKey(VK.RIGHT); var backspace = pressKey(VK.BACKSPACE); var forwardDelete = pressKey(VK.DELETE); var upArrow = pressKey(VK.UP); var downArrow = pressKey(VK.DOWN); test('left/right over cE=false inline', function() { editor.setContent('1'); editor.selection.select(editor.$('span')[0]); leftArrow(); equal(editor.getContent(), '

1

'); equal(CaretContainer.isCaretContainerInline(editor.selection.getRng().startContainer), true); equal(editor.selection.getRng().startContainer, editor.$('p')[0].firstChild); rightArrow(); equal(editor.getContent(), '

1

'); equal(editor.selection.getNode(), editor.$('span')[0]); rightArrow(); equal(editor.getContent(), '

1

'); equal(CaretContainer.isCaretContainerInline(editor.selection.getRng().startContainer), true); equal(editor.selection.getRng().startContainer, editor.$('p')[0].lastChild); }); test('left/right over cE=false block', function() { editor.setContent('

1

'); editor.selection.select(editor.$('p')[0]); leftArrow(); equal(editor.getContent(), '

1

'); equal(CaretContainer.isCaretContainerBlock(editor.selection.getRng().startContainer), true); rightArrow(); equal(editor.getContent(), '

1

'); equal(editor.selection.getNode(), editor.$('p')[0]); rightArrow(); equal(editor.getContent(), '

1

'); equal(CaretContainer.isCaretContainerBlock(editor.selection.getRng().startContainer), true); }); test('left before cE=false block and type', function() { editor.setContent('

1

'); editor.selection.select(editor.$('p')[0]); leftArrow(); Utils.type('a'); equal(editor.getContent(), '

a

1

'); equal(CaretContainer.isCaretContainerBlock(editor.selection.getRng().startContainer.parentNode), false); }); test('right after cE=false block and type', function() { editor.setContent('

1

'); editor.selection.select(editor.$('p')[0]); rightArrow(); Utils.type('a'); equal(editor.getContent(), '

1

a

'); equal(CaretContainer.isCaretContainerBlock(editor.selection.getRng().startContainer.parentNode), false); }); test('up from P to inline cE=false', function() { editor.setContent('

a1

abc

'); Utils.setSelection('p:last', 3); upArrow(); equal(CaretContainer.isCaretContainerInline(editor.$('p:first')[0].lastChild), true); }); test('down from P to inline cE=false', function() { editor.setContent('

abc

a1

'); Utils.setSelection('p:first', 3); downArrow(); equal(CaretContainer.isCaretContainerInline(editor.$('p:last')[0].lastChild), true); }); test('backspace on selected cE=false block', function() { editor.setContent('

1

'); editor.selection.select(editor.$('p')[0]); backspace(); equal(editor.getContent(), ''); equal(editor.selection.getRng().startContainer, editor.$('p')[0]); }); test('backspace after cE=false block', function() { editor.setContent('

1

'); editor.selection.select(editor.$('p')[0]); rightArrow(); backspace(); equal(editor.getContent(), ''); equal(editor.selection.getRng().startContainer, editor.$('p')[0]); }); test('delete on selected cE=false block', function() { editor.setContent('

1

'); editor.selection.select(editor.$('p')[0]); forwardDelete(); equal(editor.getContent(), ''); equal(editor.selection.getRng().startContainer, editor.$('p')[0]); }); test('delete inside nested cE=true block element', function() { editor.setContent('
1
2
3
'); Utils.setSelection('div div', 1); Utils.type('\b'); equal(Utils.cleanHtml(editor.getBody().innerHTML), '
1

3
'); equal(editor.selection.getRng().startContainer, editor.$('div div')[0]); }); test('backspace from block to after cE=false inline', function() { editor.setContent('

12

3

'); Utils.setSelection('p:nth-child(2)', 0); Utils.type('\b'); equal(editor.getContent(), '

123

'); ok(Zwsp.isZwsp(editor.selection.getRng().startContainer.data)); equal(editor.selection.getRng().startContainer.previousSibling.nodeName, 'SPAN'); }); test('delete from block to before cE=false inline', function() { editor.setContent('

1

23

'); Utils.setSelection('p:nth-child(1)', 1); forwardDelete(); equal(editor.getContent(), '

123

'); ok(Zwsp.isZwsp(editor.selection.getRng().startContainer.data)); equal(editor.selection.getRng().startContainer.nextSibling.nodeName, 'SPAN'); }); test('backspace from before cE=false block to text', function() { editor.setContent('

1

2

3

'); editor.selection.select(editor.dom.select('p')[1]); editor.selection.collapse(true); assertCaretInCaretBlockContainer(); Utils.type('\b'); var rng = editor.selection.getRng(); equal(editor.getContent(), '

1

2

3

'); equal(rng.startContainer, editor.dom.select('p')[0].firstChild); equal(rng.startOffset, 1); equal(rng.collapsed, true); }); test('backspace from before first cE=false block', function() { editor.setContent('

1

2

'); editor.selection.select(editor.dom.select('p')[0]); editor.selection.collapse(true); assertCaretInCaretBlockContainer(); Utils.type('\b'); equal(editor.getContent(), '

1

2

'); assertCaretInCaretBlockContainer(); }); test('backspace from before cE=false block to after cE=false block', function() { editor.setContent('

1

2

'); editor.selection.select(editor.dom.select('p')[1]); editor.selection.collapse(true); assertCaretInCaretBlockContainer(); Utils.type('\b'); var rng = editor.selection.getRng(); equal(editor.getContent(), '

1

2

'); assertCaretInCaretBlockContainer(); equal(rng.startContainer.parentNode.previousSibling, editor.dom.select('p')[0]); }); test('delete from after cE=false block to text', function() { editor.setContent('

1

2

3

'); editor.selection.select(editor.dom.select('p')[1]); editor.selection.collapse(false); assertCaretInCaretBlockContainer(); forwardDelete(); var rng = editor.selection.getRng(); equal(editor.getContent(), '

1

2

3

'); equal(rng.startContainer, editor.dom.select('p')[2].firstChild); equal(rng.startOffset, 0); equal(rng.collapsed, true); }); test('delete from after last cE=false block', function() { editor.setContent('

1

2

'); editor.selection.select(editor.dom.select('p')[1]); editor.selection.collapse(false); assertCaretInCaretBlockContainer(); forwardDelete(); equal(editor.getContent(), '

1

2

'); assertCaretInCaretBlockContainer(); }); test('delete from after cE=false block to before cE=false block', function() { editor.setContent('

1

2

'); editor.selection.select(editor.dom.select('p')[0]); rightArrow(); assertCaretInCaretBlockContainer(); forwardDelete(); var rng = editor.selection.getRng(); equal(editor.getContent(), '

1

2

'); assertCaretInCaretBlockContainer(); equal(rng.startContainer.parentNode.nextSibling, editor.dom.select('p')[2]); }); test('delete from block to before cE=false inline', function() { editor.setContent('

1

23

'); Utils.setSelection('p:nth-child(1)', 1); forwardDelete(); equal(editor.getContent(), '

123

'); ok(Zwsp.isZwsp(editor.selection.getRng().startContainer.data)); equal(editor.selection.getRng().startContainer.nextSibling.nodeName, 'SPAN'); }); test('backspace from empty block to after cE=false', function() { editor.getBody().innerHTML = '

1


'; Utils.setSelection('p:nth-child(2)', 0); backspace(); equal(editor.getContent(), '

1

'); assertCaretInCaretBlockContainer(); }); test('delete from empty block to before cE=false', function() { editor.getBody().innerHTML = '


2

'; Utils.setSelection('p:nth-child(1)', 0); forwardDelete(); equal(editor.getContent(), '

2

'); assertCaretInCaretBlockContainer(); }); test('exit pre block (up)', exitPreTest(upArrow, 0, '

\u00a0

abc
')); test('exit pre block (left)', exitPreTest(leftArrow, 0, '

\u00a0

abc
')); test('exit pre block (down)', exitPreTest(downArrow, 3, '
abc

\u00a0

')); test('exit pre block (right)', exitPreTest(rightArrow, 3, '
abc

\u00a0

')); test('click on link in cE=false', function() { editor.setContent('

link

'); var evt = editor.fire('click', {target: editor.$('strong')[0]}); equal(evt.isDefaultPrevented(), true); }); test('click next to cE=false block', function() { editor.setContent( '' + '' + '' + '' + '' + '
1
2
' ); var firstTd = editor.dom.select('td')[0]; var rect = editor.dom.getRect(firstTd); editor.fire('mousedown', { target: firstTd, clientX: rect.x + rect.w, clientY: rect.y + 10 }); // Since we can't do a real click we need to check if it gets sucked in towards the cE=false block equal(editor.selection.getNode().nodeName !== 'P', true); }); });