import * as CFI from '../epubcfi.js'
const parser = new DOMParser()
const XML = str => parser.parseFromString(str, 'application/xml')
const XHTML = str => parser.parseFromString(str, 'application/xhtml+xml')
{
// example from EPUB CFI spec
const opf = XML(`
…
…
…
…
xxxyyy0123456789
…
…
…
…
`) // the exact same page with some text nodes removed, CDATA & comment added, // and characters changed to entities const page2 = XHTML(`…
…
…
…
xxxyyy4589
…
…
…
…
`) // the exact same page with nodes are to be ignored const page3 = XHTML(`Also ignored
…
…
…
…
xxxyyyNote: we put ignored text in this span but not the other ones because although the CFI library should ignore them, they won't be ignored by DOM Ranges, which will break the tests.0123456789
…
…
…
…
Hello, World
Hello, World
`) const filter = node => node.nodeType === 1 && node.classList?.contains('SKIP') ? NodeFilter.FILTER_SKIP : NodeFilter.FILTER_ACCEPT // cfi1 const para1 = page.getElementById('test-skip-1') const text1 = para1.firstChild const range1 = page.createRange() range1.setStart(text1, 3) range1.setEnd(text1, 8) const cfi1 = CFI.fromRange(range1, filter) const expected1 = 'epubcfi(/4/2[test-skip-1],/1:3,/1:8)' console.assert(cfi1 === expected1, `expected ${expected1}, got ${cfi1}`) // cfi2 const para2 = page.getElementById('test-skip-2') const skips = para2.querySelectorAll('.SKIP') const tail2 = para2.lastChild const range2 = page.createRange() range2.setStart(skips[1].firstChild, 1) range2.setEnd(tail2, 4) const cfi2 = CFI.fromRange(range2, filter) const expected2 = 'epubcfi(/4/4[test-skip-2],/1:3,/1:8)' console.assert(cfi2 === expected2, `expected ${expected2}, got ${cfi2}`) const rebuilt = CFI.toRange(page, CFI.parse('/4/4[test-skip-2],/1:3,/1:8'), filter) console.assert(rebuilt.toString() === 'lo, W', `expected lo, W, got ${rebuilt}`) const roundtrip = CFI.fromRange(rebuilt, filter) console.assert(roundtrip === expected2, `expected ${expected2}, got ${roundtrip}`) } { // special characters in ID assertions const opf = XML(`…
…
…
…
xxxyyy0123456789
…
…
…
…
`) for (const cfi of [ '/4[body0^]!/1^^]/10[para^]/0^,/5]/3:10', '/4[body0^]!/1^^]/16[s^]^[vgimg]', '/4[body0^]!/1^^]/10[para^]/0^,/5]/1:0', '/4[body0^]!/1^^]/10[para^]/0^,/5]/2/1:0', '/4[body0^]!/1^^]/10[para^]/0^,/5]/2/1:3', ]) { const range = CFI.toRange(page, CFI.parse(cfi)) const a = CFI.fromRange(range) const b = `epubcfi(${cfi})` console.assert(a === b, `expected ${b}, got ${a}`) } for (let i = 0; i < 10; i++) { const cfi = `/4[body0^]!/1^^]/10[para^]/0^,^/5],/3:${i},/3:${i+1}` const range = CFI.toRange(page, CFI.parse(cfi)) const n = `${i}` console.assert(range.toString() === n, `expected ${n}, got ${range}`) } } { for (const [a, b, c] of [ ['/6/4!/10', '/6/4!/10', 0], ['/6/4!/2/3:0', '/6/4!/2', 1], ['/6/4!/2/4/6/8/10/3:0', '/6/4!/4', -1], [ '/6/4[chap0^]!/1ref^^]!/4[body01^^]/10[para^]^,05^^]', '/6/4!/4/10', 0, ], [ '/6/4[chap0^]!/1ref^^]!/4[body01^^],/10[para^]^,05^^],/15:10[foo^]]', '/6/4!/4/12', -1, ], ['/6/4', '/6/4!/2', -1], ['/6/4!/2', '/6/4!/2!/2', -1], ]) { const x = CFI.compare(a, b) console.assert(x === c, `compare ${a} and ${b}, expected ${c}, got ${x}`) } }