blob: 1dabf7d32181d52cd5c406c34a465da6d6eabb08 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Include test fixture.
GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
/**
* Test fixture.
* @constructor
* @extends {ChromeVoxUnitTestBase}
*/
function ChromeVoxContentEditableExtractorUnitTest() {}
ChromeVoxContentEditableExtractorUnitTest.prototype = {
__proto__: ChromeVoxUnitTestBase.prototype,
/** @override */
closureModuleDeps: [
'cvox.ContentEditableExtractor',
]
};
/**
* Helper function to set the selection
* @param {Node} startNode The base/start node of the range.
* @param {number} startOffset The 0-based character index of the start.
* @param {Node} endNode The extent/end node of the range.
* @param {number} endOffset The 0-based character index of the end.
*/
function setSelection(startNode, startOffset, endNode, endOffset) {
var r = document.createRange();
r.setStart(startNode, startOffset);
r.setEnd(endNode, endOffset);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(r);
}
TEST_F('ChromeVoxContentEditableExtractorUnitTest', 'EmptyElement', function() {
this.loadDoc(function() {/*!
<div>
<div id="textbox" contentEditable="true"></div>
</div>
*/});
var textbox = $('textbox');
var extractor = new cvox.ContentEditableExtractor();
extractor.update(textbox);
assertEquals('', extractor.getText());
assertEquals(0, extractor.getStartIndex());
assertEquals(0, extractor.getEndIndex(0));
assertEquals(0, extractor.getLineIndex(0));
assertEquals(0, extractor.getLineStart(0));
assertEquals(0, extractor.getLineEnd(0));
});
/**
* Test getting text and selections from a single contenteditable node.
*/
TEST_F('ChromeVoxContentEditableExtractorUnitTest', 'SingleTextNode',
function() {
this.loadDoc(function() {/*!
<div>
<div id="textbox" contentEditable="true">Hello</div>
</div>
*/});
var textbox = $('textbox');
var extractor = new cvox.ContentEditableExtractor();
extractor.update(textbox);
assertEquals('Hello', extractor.getText());
assertEquals(0, extractor.getLineIndex(0));
assertEquals(0, extractor.getLineStart(0));
assertEquals(5, extractor.getLineEnd(0));
assertEquals(5, extractor.getStartIndex());
assertEquals(5, extractor.getEndIndex());
// Test all possible cursor positions.
for (var i = 0; i <= 5; i++) {
setSelection(textbox.firstChild, i, textbox.firstChild, i);
extractor.update(textbox);
assertEquals(i, extractor.getStartIndex());
assertEquals(i, extractor.getEndIndex());
}
// Test all possible ways to select one character.
for (i = 0; i < 5; i++) {
setSelection(textbox.firstChild, i, textbox.firstChild, i + 1);
extractor.update(textbox);
assertEquals(i, extractor.getStartIndex());
assertEquals(i + 1, extractor.getEndIndex());
}
// Test selecting everything.
setSelection(textbox.firstChild, 0, textbox.firstChild, 5);
extractor.update(textbox);
assertEquals(0, extractor.getStartIndex());
assertEquals(5, extractor.getEndIndex());
});
/**
* Test getting text and selections from a contenteditable node with
* nonprinted whitespace.
*/
TEST_F('ChromeVoxContentEditableExtractorUnitTest', 'TextWithWhitespace',
function() {
this.loadDoc(function() {/*!
<div>
<div id="textbox" contentEditable="true"> Hello World </div>
</div>
*/});
var textbox = $('textbox');
var extractor = new cvox.ContentEditableExtractor();
extractor.update(textbox);
assertEquals('Hello World', extractor.getText());
assertEquals(0, extractor.getLineIndex(0));
assertEquals(0, extractor.getLineStart(0));
assertEquals(11, extractor.getLineEnd(0));
assertEquals(11, extractor.getStartIndex());
assertEquals(11, extractor.getEndIndex());
// Test all *reasonable* indexes of a selection into this text node
// and the logical index into the text that these should result in.
var expectedIndexMap = {
0: 0,
1: 0,
2: 1,
3: 2,
4: 3,
5: 4,
6: 5,
// Note: index=7 should never happen
8: 6,
9: 7,
10: 8,
11: 9,
12: 10,
13: 11,
14: 11
};
for (var srcIndex in expectedIndexMap) {
var dstIndex = expectedIndexMap[srcIndex];
setSelection(textbox.firstChild, srcIndex, textbox.firstChild, srcIndex);
extractor.update(textbox);
assertEquals(dstIndex, extractor.getStartIndex());
assertEquals(dstIndex, extractor.getEndIndex());
}
});
/**
* Test getting text and selections from a contenteditable node with
* preformatted text.
*/
TEST_F('ChromeVoxContentEditableExtractorUnitTest', 'Preformatted', function() {
this.loadDoc(function() {/*!
<div>
<pre id="textbox" contentEditable="true">aaaaaaaaaa
bbbbbbbbbb
cccccccccc</pre>
</div>
*/});
var textbox = $('textbox');
var extractor = new cvox.ContentEditableExtractor();
extractor.update(textbox);
assertEquals('aaaaaaaaaa\nbbbbbbbbbb\ncccccccccc', extractor.getText());
assertEquals(0, extractor.getLineStart(0));
assertEquals(11, extractor.getLineEnd(0));
assertEquals(11, extractor.getLineStart(1));
assertEquals(22, extractor.getLineEnd(1));
assertEquals(22, extractor.getLineStart(2));
assertEquals(32, extractor.getLineEnd(2));
// Test all possible cursor positions.
for (var i = 0; i <= 32; i++) {
setSelection(textbox.firstChild, i, textbox.firstChild, i);
extractor.update(textbox);
assertEquals(i, extractor.getStartIndex());
assertEquals(i, extractor.getEndIndex());
}
});
/**
* Test getting text and selections from a contenteditable node with
* wrapping.
*/
TEST_F('ChromeVoxContentEditableExtractorUnitTest', 'WordWrap', function() {
this.loadDoc(function() {/*!
<div>
<div id="textbox"
style="width: 1em; word-wrap: normal"
contentEditable="true">One two three</div>
</div>
*/});
var textbox = $('textbox');
var extractor = new cvox.ContentEditableExtractor();
extractor.update(textbox);
assertEquals('One\ntwo\nthree', extractor.getText());
assertEquals(0, extractor.getLineStart(0));
assertEquals(4, extractor.getLineEnd(0));
assertEquals(4, extractor.getLineStart(1));
assertEquals(8, extractor.getLineEnd(1));
assertEquals(8, extractor.getLineStart(2));
assertEquals(13, extractor.getLineEnd(2));
// Test all possible cursor positions.
for (var i = 0; i <= 13; i++) {
setSelection(textbox.firstChild, i, textbox.firstChild, i);
extractor.update(textbox);
assertEquals(i, extractor.getStartIndex());
assertEquals(i, extractor.getEndIndex());
}
});
/**
* Test getting text and lines from a contenteditable region
* containing two paragraphs and an explicit line break.
*/
TEST_F('ChromeVoxContentEditableExtractorUnitTest', 'TwoParas', function() {
this.loadDoc(function() {/*!
<div>
<div id="textbox" contentEditable="true">
<p>One</p>
<p>Two<br>Three</p>
</div>
</div>
*/});
var textbox = $('textbox');
var extractor = new cvox.ContentEditableExtractor();
extractor.update(textbox);
assertEquals('One\nTwo\nThree',
extractor.getText());
assertEquals(0, extractor.getLineStart(0));
assertEquals(4, extractor.getLineEnd(0));
assertEquals(4, extractor.getLineStart(1));
assertEquals(8, extractor.getLineEnd(1));
assertEquals(8, extractor.getLineStart(2));
assertEquals(13, extractor.getLineEnd(2));
});
/**
* Test getting text and lines from a contenteditable region
* containing two paragraphs, this time with added whitespace.
*/
TEST_F('ChromeVoxContentEditableExtractorUnitTest', 'TwoParasWithWhitespace',
function() {
this.loadDoc(function() {/*!
<div>
<div id="textbox" contentEditable="true">
<p> One </p>
<p> Two <br> Three </p>
</div>
</div>
*/});
var textbox = $('textbox');
var extractor = new cvox.ContentEditableExtractor();
extractor.update(textbox);
assertEquals('One\nTwo Three',
extractor.getText());
assertEquals(0, extractor.getLineStart(0));
assertEquals(4, extractor.getLineEnd(0));
assertEquals(4, extractor.getLineStart(1));
assertEquals(8, extractor.getLineEnd(1));
assertEquals(8, extractor.getLineStart(2));
assertEquals(13, extractor.getLineEnd(2));
});
/**
* Test getting text and lines from a contenteditable region
* containing some raw text and then some text in a block-level element.
*/
TEST_F('ChromeVoxContentEditableExtractorUnitTest', 'NodePlusElement',
function() {
this.loadDoc(function() {/*!
<div>
<div id="textbox"
contentEditable="true">One<div>Two<br>Three</div></div>
</div>
*/});
var textbox = $('textbox');
var extractor = new cvox.ContentEditableExtractor();
extractor.update(textbox);
assertEquals('One\nTwo\nThree',
extractor.getText());
assertEquals(0, extractor.getLineStart(0));
assertEquals(4, extractor.getLineEnd(0));
assertEquals(4, extractor.getLineStart(1));
assertEquals(8, extractor.getLineEnd(1));
assertEquals(8, extractor.getLineStart(2));
assertEquals(13, extractor.getLineEnd(2));
var oneTextNode = textbox.firstChild;
assertEquals('One', oneTextNode.data);
var twoTextNode = textbox.firstElementChild.firstChild;
assertEquals('Two', twoTextNode.data);
var threeTextNode = twoTextNode.nextSibling.nextSibling;
assertEquals('Three', threeTextNode.data);
// End of first line.
setSelection(oneTextNode, 3, oneTextNode, 3);
extractor.update(textbox);
assertEquals(3, extractor.getStartIndex());
assertEquals(3, extractor.getEndIndex());
// Beginning of second line.
setSelection(twoTextNode, 0, twoTextNode, 0);
extractor.update(textbox);
assertEquals(4, extractor.getStartIndex());
assertEquals(4, extractor.getEndIndex());
// End of second line.
setSelection(twoTextNode, 3, twoTextNode, 3);
extractor.update(textbox);
assertEquals(7, extractor.getStartIndex());
assertEquals(7, extractor.getEndIndex());
// Beginning of third line.
setSelection(threeTextNode, 0, threeTextNode, 0);
extractor.update(textbox);
assertEquals(8, extractor.getStartIndex());
assertEquals(8, extractor.getEndIndex());
});