Commit 0f7ee503 authored by Robert Knight's avatar Robert Knight

Remove unused `toRange` implementation

This has been replaced by the `TextRange.toRange` method in `text-range.js`.
The test cases are covered by the tests for `TextRange` and
`TextPosition`.
parent e92b7fe9
import { toRange } from '../text-position';
describe('text-position', () => {
let container;
before(() => {
container = document.createElement('div');
container.innerHTML = `<h1>Test article</h1>
<p>First paragraph.</p>
<p>Second paragraph.</p>`;
});
after(() => {
container.remove();
});
describe('toRange', () => {
const testCase = (description, text) => ({
description,
text,
expected: text,
});
[
testCase('start text of root', 'Test article'),
testCase('a whole text node', 'First paragraph.'),
testCase('end text of root', 'Second paragraph.'),
testCase('part of a text node', 'rst paragraph'),
{
description: 'negative start offset',
start: -5,
end: 5,
expected: new Error('invalid start offset'),
},
{
description: 'invalid start offset',
start: 1000,
end: 1010,
expected: new Error('invalid start offset'),
},
{
description: 'invalid end offset',
start: 0,
end: 1000,
expected: new Error('invalid end offset'),
},
{
description: 'an empty range',
start: 0,
end: 0,
expected: '',
},
{
description: 'a range with end < start',
start: 10,
end: 5,
expected: '',
},
].forEach(({ description, start, end, expected, text }) => {
it(`returns a range with the correct text (${description})`, () => {
if (text) {
start = container.textContent.indexOf(text);
end = start + text.length;
}
if (expected instanceof Error) {
assert.throws(() => {
toRange(container, start, end);
}, expected.message);
} else {
const range = toRange(container, start, end);
assert.equal(range.toString(), expected);
}
});
});
});
});
/**
* Functions to convert between DOM ranges and characters offsets within the
* `textContent` of HTML elements.
*
* These were added to work around issues in `dom-anchor-text-position`'s
* `toRange` implementation. When the issue is resolved upstream, we may still
* want to keep the test suite for this module.
*
* See https://github.com/hypothesis/client/issues/1329
*/
/**
* Convert `start` and `end` character offset positions within the `textContent`
* of a `root` element into a `Range`.
*
* Throws if the `start` or `end` offsets are outside of the range `[0,
* root.textContent.length]`.
*
* @param {HTMLElement} root
* @param {number} start - Character offset within `root.textContent`
* @param {number} end - Character offset within `root.textContent`
* @return {Range} Range spanning text from `start` to `end`
*/
export function toRange(root, start, end) {
// The `filter` and `expandEntityReferences` arguments are mandatory in IE
// although optional according to the spec.
const nodeIter = root.ownerDocument.createNodeIterator(
root,
NodeFilter.SHOW_TEXT
);
let startContainer;
let startOffset = 0;
let endContainer;
let endOffset = 0;
let textLength = 0;
let node;
while ((node = nodeIter.nextNode()) && (!startContainer || !endContainer)) {
const nodeText = /** @type {string} */ (node.nodeValue);
if (
!startContainer &&
start >= textLength &&
start <= textLength + nodeText.length
) {
startContainer = node;
startOffset = start - textLength;
}
if (
!endContainer &&
end >= textLength &&
end <= textLength + nodeText.length
) {
endContainer = node;
endOffset = end - textLength;
}
textLength += nodeText.length;
}
if (!startContainer) {
throw new Error('invalid start offset');
}
if (!endContainer) {
throw new Error('invalid end offset');
}
const range = root.ownerDocument.createRange();
range.setStart(startContainer, startOffset);
range.setEnd(endContainer, endOffset);
return range;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment