ModuleLoader.require([
"tinymce/Env",
"tinymce/caret/CaretWalker",
"tinymce/caret/CaretPosition"
], function(Env, CaretWalker, CaretPosition) {
module("tinymce.caret.CaretWalker");
if (!Env.ceFalse) {
return;
}
function getRoot() {
return document.getElementById('view');
}
function setupHtml(html) {
tinymce.$(getRoot()).empty();
getRoot().innerHTML = html;
}
function findElm(selector) {
return tinymce.$(selector, getRoot())[0];
}
function findElmPos(selector, offset) {
return CaretPosition(tinymce.$(selector, getRoot())[0], offset);
}
function findTextPos(selector, offset) {
return CaretPosition(tinymce.$(selector, getRoot())[0].firstChild, offset);
}
var assertCaretPosition = Utils.assertCaretPosition,
logicalCaret = new CaretWalker(getRoot());
test('inside empty root', function() {
setupHtml('');
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 0)), null);
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 0)), null);
});
test('on null', function() {
setupHtml('');
assertCaretPosition(logicalCaret.next(null), null);
assertCaretPosition(logicalCaret.prev(null), null);
});
test('within text node in root', function() {
setupHtml('abc');
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 0)), CaretPosition(getRoot().firstChild, 1));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 1)), CaretPosition(getRoot().firstChild, 2));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 2)), CaretPosition(getRoot().firstChild, 3));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 3)), null);
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().firstChild, 3)), CaretPosition(getRoot().firstChild, 2));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().firstChild, 2)), CaretPosition(getRoot().firstChild, 1));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().firstChild, 1)), CaretPosition(getRoot().firstChild, 0));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().firstChild, 0)), null);
});
test('within text node in element', function() {
setupHtml('
abc
');
assertCaretPosition(logicalCaret.next(findTextPos('p', 0)), findTextPos('p', 1));
assertCaretPosition(logicalCaret.next(findTextPos('p', 1)), findTextPos('p', 2));
assertCaretPosition(logicalCaret.next(findTextPos('p', 2)), findTextPos('p', 3));
assertCaretPosition(logicalCaret.next(findTextPos('p', 3)), null);
assertCaretPosition(logicalCaret.prev(findTextPos('p', 3)), findTextPos('p', 2));
assertCaretPosition(logicalCaret.prev(findTextPos('p', 2)), findTextPos('p', 1));
assertCaretPosition(logicalCaret.prev(findTextPos('p', 1)), findTextPos('p', 0));
assertCaretPosition(logicalCaret.prev(findTextPos('p', 0)), null);
});
test('from index text node over comment', function() {
setupHtml('abcdabcd');
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 0)), CaretPosition(getRoot().firstChild, 0));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 1)), CaretPosition(getRoot().lastChild, 0));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), CaretPosition(getRoot().firstChild, 4));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 3)), CaretPosition(getRoot().lastChild, 4));
});
test('from text to text across elements', function() {
setupHtml('abc
abc
');
assertCaretPosition(logicalCaret.next(findTextPos('p:first', 3)), findTextPos('p:last', 0));
assertCaretPosition(logicalCaret.prev(findTextPos('p:last', 0)), findTextPos('p:first', 3));
});
test('from text to text across elements with siblings', function() {
setupHtml('abc
abc
');
assertCaretPosition(logicalCaret.next(findTextPos('p:first', 3)), CaretPosition(findElm('p:last').lastChild, 0));
assertCaretPosition(logicalCaret.prev(CaretPosition(findElm('p:last').lastChild)), findTextPos('p:first', 3));
});
test('from input to text', function() {
setupHtml('123 456');
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 2)), CaretPosition(getRoot().lastChild, 0));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 1)), CaretPosition(getRoot().firstChild, 3));
});
test('from input to input across elements', function() {
setupHtml('
');
assertCaretPosition(logicalCaret.next(CaretPosition(findElm('p:first'), 1)), CaretPosition(findElm('p:last'), 0));
assertCaretPosition(logicalCaret.prev(CaretPosition(findElm('p:last'), 0)), CaretPosition(findElm('p:first'), 1));
});
test('next br to br across elements', function() {
setupHtml('
');
assertCaretPosition(logicalCaret.next(CaretPosition(findElm('p:first'), 0)), CaretPosition(findElm('p:last'), 0));
});
test('prev br to br across elements', function() {
setupHtml('
');
assertCaretPosition(logicalCaret.prev(CaretPosition(findElm('p:last'), 0)), CaretPosition(findElm('p:first'), 0));
});
test('from before/after br to text', function() {
setupHtml(' 123 456 789');
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 0)), CaretPosition(getRoot(), 1));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 2)), CaretPosition(getRoot(), 3));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 4)), CaretPosition(getRoot(), 5));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 5)), CaretPosition(getRoot().lastChild, 0));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 5)), CaretPosition(getRoot(), 4));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 4)), CaretPosition(getRoot().childNodes[3], 3));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 1)), CaretPosition(getRoot(), 0));
});
test('over br', function() {
setupHtml(' ');
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 0)), CaretPosition(getRoot(), 1));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 1)), CaretPosition(getRoot(), 2));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 2)), CaretPosition(getRoot(), 3));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 3)), null);
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 3)), CaretPosition(getRoot(), 2));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), CaretPosition(getRoot(), 1));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 1)), CaretPosition(getRoot(), 0));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 0)), null);
});
test('over input', function() {
setupHtml(' ');
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 0)), CaretPosition(getRoot(), 1));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 1)), CaretPosition(getRoot(), 2));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 2)), CaretPosition(getRoot(), 3));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 3)), null);
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 3)), CaretPosition(getRoot(), 2));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), CaretPosition(getRoot(), 1));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 1)), CaretPosition(getRoot(), 0));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 0)), null);
});
test('over img', function() {
setupHtml(' ');
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 0)), CaretPosition(getRoot(), 1));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 1)), CaretPosition(getRoot(), 2));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 2)), CaretPosition(getRoot(), 3));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 3)), null);
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 3)), CaretPosition(getRoot(), 2));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), CaretPosition(getRoot(), 1));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 1)), CaretPosition(getRoot(), 0));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 0)), null);
});
test('over script/style/textarea', function() {
setupHtml('abcd');
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 1)), CaretPosition(getRoot().childNodes[2], 0));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().childNodes[2], 1)), CaretPosition(getRoot().childNodes[4], 0));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 5)), CaretPosition(getRoot(), 6));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 6)), CaretPosition(getRoot(), 5));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().childNodes[4], 0)), CaretPosition(getRoot().childNodes[2], 1));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), CaretPosition(getRoot().childNodes[0], 1));
});
test('around tables', function() {
setupHtml('ab');
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 1)), CaretPosition(getRoot(), 1));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 1)), findTextPos('td:first', 0));
assertCaretPosition(logicalCaret.next(findTextPos('td:first', 1)), CaretPosition(getRoot(), 2));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 2)), findTextPos('td:last', 0));
assertCaretPosition(logicalCaret.next(findTextPos('table:last td', 1)), CaretPosition(getRoot(), 3));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 3)), CaretPosition(getRoot().lastChild, 0));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().lastChild, 0)), CaretPosition(getRoot(), 3));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 3)), findTextPos('td:last', 1));
assertCaretPosition(logicalCaret.prev(findTextPos('td:last', 0)), CaretPosition(getRoot(), 2));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), findTextPos('td:first', 1));
assertCaretPosition(logicalCaret.prev(findTextPos('td:first', 0)), CaretPosition(getRoot(), 1));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 1)), CaretPosition(getRoot().firstChild, 1));
});
test('over cE=false', function() {
setupHtml('123a 456');
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 3)), CaretPosition(getRoot(), 1));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 1)), CaretPosition(getRoot(), 2));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), CaretPosition(getRoot(), 1));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().lastChild, 0)), CaretPosition(getRoot(), 2));
});
/*
test('from outside cE=false to nested cE=true', function() {
setupHtml('abcbc def');
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 3)), CaretPosition(getRoot(), 1));
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 1)), findTextPos('span span', 0));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().lastChild, 0)), CaretPosition(getRoot(), 2));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), findTextPos('span span', 1));
});
test('from outside cE=false to nested cE=true before/after cE=false', function() {
setupHtml('ab d');
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot(), 1)), CaretPosition(findElm('span span'), 0));
assertCaretPosition(logicalCaret.next(CaretPosition(findElm('span span'), 1)), CaretPosition(getRoot(), 2));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot(), 2)), CaretPosition(findElm('span span'), 1));
});
*/
test('from inside cE=true in cE=false to after cE=false', function() {
setupHtml(
'' +
'' +
'' +
'abc' +
' ' +
'def' +
' ' +
'
' +
'abc
'
);
assertCaretPosition(logicalCaret.next(findTextPos('span span', 3)), CaretPosition(findElm('p'), 1));
});
test('around cE=false inside nested cE=true', function() {
setupHtml(
'' +
'' +
'1 ' +
'2 ' +
'3 ' +
' ' +
' '
);
assertCaretPosition(logicalCaret.next(CaretPosition(findElm('span span'), 0)), CaretPosition(findElm('span span'), 1));
assertCaretPosition(logicalCaret.next(CaretPosition(findElm('span span'), 1)), CaretPosition(findElm('span span'), 2));
assertCaretPosition(logicalCaret.next(CaretPosition(findElm('span span'), 2)), CaretPosition(findElm('span span'), 3));
assertCaretPosition(logicalCaret.next(CaretPosition(findElm('span span'), 3)), CaretPosition(getRoot(), 1));
assertCaretPosition(logicalCaret.prev(CaretPosition(findElm('span span'), 0)), CaretPosition(getRoot(), 0));
assertCaretPosition(logicalCaret.prev(CaretPosition(findElm('span span'), 1)), CaretPosition(findElm('span span'), 0));
assertCaretPosition(logicalCaret.prev(CaretPosition(findElm('span span'), 2)), CaretPosition(findElm('span span'), 1));
assertCaretPosition(logicalCaret.prev(CaretPosition(findElm('span span'), 3)), CaretPosition(findElm('span span'), 2));
});
test('next from last node', function() {
setupHtml(
'
' +
' ' +
'
'
);
assertCaretPosition(logicalCaret.next(findElmPos('p:first', 1)), CaretPosition(getRoot(), 1));
assertCaretPosition(logicalCaret.next(findElmPos('p:last', 1)), null);
});
test('left/right between cE=false inlines in different blocks', function() {
setupHtml(
'' +
'abc ' +
'
' +
'' +
'def ' +
'
'
);
assertCaretPosition(logicalCaret.next(findElmPos('p:first', 1)), findElmPos('p:last', 0));
assertCaretPosition(logicalCaret.prev(findElmPos('p:last', 0)), findElmPos('p:first', 1));
});
test('never into caret containers', function() {
setupHtml('abcdef ghi');
assertCaretPosition(logicalCaret.next(CaretPosition(getRoot().firstChild, 3)), CaretPosition(getRoot().lastChild, 0));
assertCaretPosition(logicalCaret.prev(CaretPosition(getRoot().lastChild, 0)), CaretPosition(getRoot().firstChild, 3));
});
});