import { Assert, UnitTest } from '@ephox/bedrock-client'; import { Gene, TestUniverse, TextGene } from '@ephox/boss'; import { Unicode } from '@ephox/katamari'; import { KAssert } from '@ephox/katamari-assertions'; import * as Selection from 'ephox/robin/smartselect/Selection'; UnitTest.test('SelectionTest', () => { const doc1 = TestUniverse(Gene('root', 'root', [ Gene('p1', 'p', [ TextGene('a', 'There i'), TextGene('b', 's something'), TextGene('c', ' going on here that can'), TextGene('d', 'not be de'), TextGene('e', 'termined '), TextGene('f', 'and'), TextGene('g', ` it's driving me in`), Gene('s1', 'span', [ TextGene('h', 'sane') ]), Gene('image', 'img', []), TextGene('i', 'again.') ]), Gene('p2', 'p', [ TextGene('j', 'What now?') ]) ])); const doc2 = TestUniverse(Gene('root', 'root', [ TextGene('a', 'This is '), Gene('b', 'span', [ TextGene('c', 'som') ]), TextGene('d', 'eth'), Gene('e', 'b', [ TextGene('f', 'ing that you should') ]), TextGene('g', ' see.'), TextGene('h', 'plus again'), TextGene('i', Unicode.zeroWidth) ])); const doc3 = TestUniverse(Gene('root', 'root', [ TextGene('a', ' \uFEFF'), TextGene('b', '\uFEFF\uFEFF'), TextGene('c', '\uFEFF ') ])); interface Expected { startContainer: string; startOffset: number; endContainer: string; endOffset: number; } const check = (expected: Expected, doc: TestUniverse, id: string, offset: number) => { const item = doc.find(doc.get(), id).getOrDie('Could not find item: ' + id); const actual = Selection.word(doc, item, offset).getOrDie('Selection for: (' + id + ', ' + offset + ') yielded nothing'); Assert.eq('Selection for: (' + id + ', ' + offset + ') => startContainer', expected.startContainer, actual.startContainer.id); Assert.eq('Selection for: (' + id + ', ' + offset + ') => startOffset', expected.startOffset, actual.startOffset); Assert.eq('Selection for: (' + id + ', ' + offset + ') => endContainer', expected.endContainer, actual.endContainer.id); Assert.eq('Selection for: (' + id + ', ' + offset + ') => endOffset', expected.endOffset, actual.endOffset); }; const checkNone = (doc: TestUniverse, id: string, offset: number) => { const actual = doc.find(doc.get(), id).bind((item) => Selection.word(doc, item, offset) ); KAssert.eqNone('eq', actual); }; check({ startContainer: 'b', startOffset: 's '.length, // Note, this changed to end of node rather than start of new node. endContainer: 'b', endOffset: 's something'.length }, doc1, 'b', 's so'.length); check({ startContainer: 'c', startOffset: ' going on '.length, endContainer: 'c', endOffset: ' going on here'.length }, doc1, 'c', ' going on he'.length); check({ startContainer: 'a', startOffset: 'There '.length, endContainer: 'b', endOffset: 's'.length }, doc1, 'b', ''.length); check({ startContainer: 'd', startOffset: 'not be '.length, endContainer: 'e', endOffset: 'termined'.length }, doc1, 'e', 'term'.length); check({ startContainer: 'g', startOffset: ` it's driving me `.length, endContainer: 'h', endOffset: 'sane'.length }, doc1, 'g', ` it's driving me i`.length); check({ startContainer: 'c', startOffset: ''.length, endContainer: 'f', endOffset: 'ing'.length }, doc2, 'f', 'i'.length); checkNone(doc2, 'f', 'ing that you should'.length); checkNone(doc2, 'b', 0); checkNone(doc2, 'h', 'plus again'.length); checkNone(TestUniverse(Gene('root', 'root', [ TextGene('alpha', '\uFEFFfeff') ])), 'alpha', Unicode.zeroWidth.length); checkNone(doc3, 'b', ''.length); checkNone(doc3, 'b', Unicode.zeroWidth.length); checkNone(doc3, 'b', '\uFEFF\uFEFF'.length); const doc4 = TestUniverse(Gene('root', 'root', [ Gene('s1-fr', 'span', [ TextGene('t1-fr', 'da'), TextGene('t2-fr', 'aa bo'), TextGene('t3-fr', 'dytag') ], {}, { lang: 'fr' }), Gene('s2-en', 'span', [ TextGene('t4-en', 'span'), TextGene('t5-en', 'ning') ], {}, { lang: 'en' }), Gene('s3-en', 'span', [ TextGene('t6-en', 'bound'), TextGene('t7-en', 'aries and'), TextGene('t8-en', 'more') ], {}, { lang: 'en' }), Gene('s4-de', 'span', [ TextGene('t9-de', 'di'), TextGene('t10-de', 'ee '), TextGene('t11-de', ' der') ], {}, { lang: 'de' }) ])); check({ startContainer: 't1-fr', startOffset: ''.length, endContainer: 't2-fr', endOffset: 'aa'.length }, doc4, 't1-fr', 'd'.length); check({ startContainer: 't1-fr', startOffset: ''.length, endContainer: 't2-fr', endOffset: 'aa'.length }, doc4, 't2-fr', 'a'.length); check({ startContainer: 't2-fr', startOffset: 'aa '.length, endContainer: 't3-fr', endOffset: 'dytag'.length }, doc4, 't2-fr', 'aa b'.length); check({ startContainer: 't2-fr', startOffset: 'aa '.length, endContainer: 't3-fr', endOffset: 'dytag'.length }, doc4, 't3-fr', 'aa b'.length); check({ startContainer: 't4-en', startOffset: ''.length, endContainer: 't7-en', endOffset: 'aries'.length }, doc4, 't4-en', 's'.length); check({ startContainer: 't4-en', startOffset: ''.length, endContainer: 't7-en', endOffset: 'aries'.length }, doc4, 't5-en', 'n'.length); check({ startContainer: 't4-en', startOffset: ''.length, endContainer: 't7-en', endOffset: 'aries'.length }, doc4, 't6-en', 'bou'.length); check({ startContainer: 't4-en', startOffset: ''.length, endContainer: 't7-en', endOffset: 'aries'.length }, doc4, 't7-en', 'ari'.length); check({ startContainer: 't7-en', startOffset: 'aries '.length, endContainer: 't8-en', endOffset: 'more'.length }, doc4, 't7-en', 'aries an'.length); check({ startContainer: 't7-en', startOffset: 'aries '.length, endContainer: 't8-en', endOffset: 'more'.length }, doc4, 't8-en', 'mo'.length); check({ startContainer: 't9-de', startOffset: ''.length, endContainer: 't10-de', endOffset: 'ee'.length }, doc4, 't9-de', 'd'.length); check({ startContainer: 't9-de', startOffset: ''.length, endContainer: 't10-de', endOffset: 'ee'.length }, doc4, 't10-de', 'e'.length); check({ startContainer: 't11-de', startOffset: ' '.length, endContainer: 't11-de', endOffset: ' der'.length }, doc4, 't11-de', ' d'.length); });