@openstax/highlighter
Advanced tools
Comparing version 1.1.7 to 1.1.8
{ | ||
"name": "@openstax/highlighter", | ||
"version": "1.1.7", | ||
"version": "1.1.8", | ||
"main": "dist/highlighter.js", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -9,3 +9,3 @@ import {DATA_ATTR} from '../../injectHighlightWrappers'; | ||
const isElement = node => node && node.nodeType === 1; | ||
const isTextOrElement = node => isText(node) || isElement(node); | ||
const isElementNotHighlight = node => isElement(node) && !isHighlight(node); | ||
@@ -41,3 +41,3 @@ const IS_PATH_PART_SELF = /^\.$/; | ||
// if target is text highlight, treat it like its text | ||
} else if (isTextHighlight(focus) && (isTextHighlight(element) || isText(element))) { | ||
} else if (isTextHighlight(focus) && isTextOrTextHighlight(element)) { | ||
offset = 0; | ||
@@ -52,3 +52,15 @@ | ||
} else if (isElement(focus)) { | ||
offset -= Array.prototype.filter.call(Array.prototype.slice.call(focus.childNodes, 0, offset), isHighlight).length; | ||
let search = focus.childNodes[offset]; | ||
while (search) { | ||
if (isTextOrTextHighlight(search)) { | ||
search = search.previousSibling; | ||
while(isTextOrTextHighlight(search)) { | ||
offset--; | ||
search = search.previousSibling; | ||
} | ||
} | ||
search = search ? search.previousSibling : null; | ||
} | ||
} | ||
@@ -62,12 +74,11 @@ | ||
// compensate by gobbling adjacent highlights and text | ||
if (isText(focus) && isTextHighlight(element)) { | ||
while(element && (isText(element) || isTextHighlight(element))) { | ||
if (isTextOrTextHighlight(focus) && isTextOrTextHighlight(element)) { | ||
while(isTextOrTextHighlight(element)) { | ||
element = element.previousSibling; | ||
} | ||
} | ||
if (element) { | ||
if (isTextOrElement(element) && !isHighlight(element) && element.nodeName === focus.nodeName) { // If it is ELEMENT_NODE or TEXT_NODE of the same name | ||
pos += 1; | ||
} else { | ||
if (isElementNotHighlight(focus) && isElementNotHighlight(element) && element.nodeName === focus.nodeName) { | ||
pos += 1; | ||
} | ||
element = element.previousSibling; | ||
@@ -104,4 +115,7 @@ } | ||
const highlightOrText = node => isHighlight(node) || isText(node); | ||
// the part following is greedy, so walk back to the first matching | ||
// textish node before computing offset | ||
while (isTextOrTextHighlight(node) && isTextOrTextHighlight(node.previousSibling)) { | ||
node = node.previousSibling; | ||
} | ||
// highligts split up text nodes that should be treated as one, iterate through | ||
@@ -111,5 +125,5 @@ // until we find the text node that the offset specifies, modifying the offset | ||
// adjacent highlights. | ||
while ((isHighlight(node) && offset >= node.textContent.length) || (isText(node) && offset > node.textContent.length)) { | ||
while ((isTextHighlight(node) && offset >= node.textContent.length) || (isText(node) && offset > node.textContent.length)) { | ||
offset -= node.textContent.length; | ||
node = highlightOrText(node.nextSibling) ? node.nextSibling : null; | ||
node = isTextOrTextHighlight(node.nextSibling) ? node.nextSibling : null; | ||
} | ||
@@ -147,3 +161,3 @@ | ||
while (search && (isText(search) || isHighlight(search))) { | ||
while (isTextOrTextHighlight(search)) { | ||
search = search.nextSibling; | ||
@@ -150,0 +164,0 @@ } |
@@ -83,6 +83,6 @@ import {DATA_ATTR} from '../../injectHighlightWrappers'; | ||
const reference = document.getElementById('reference'); | ||
const text = document.getElementById('target').previousSibling; | ||
const text = document.getElementById('target').nextSibling; | ||
const [result] = xpath.getXPathForElement(text, 0, reference); | ||
expect(result).toEqual("./*[name()='div'][3]/*[name()='div'][1]/*[name()='section'][1]/text()[1]"); | ||
expect(result).toEqual("./*[name()='div'][3]/*[name()='div'][1]/*[name()='section'][1]/text()[2]"); | ||
}); | ||
@@ -117,2 +117,16 @@ | ||
document.body.innerHTML = ` | ||
<div id="reference">qwer<span ${DATA_ATTR}>asdf</span><div id="target"></div><span ${DATA_ATTR}>as</span>asdfasdf</div> | ||
`; | ||
const reference = document.getElementById('reference'); | ||
const text = document.getElementById('target').nextSibling; | ||
const [result, offset] = xpath.getXPathForElement(reference, 4, reference); | ||
expect(result).toEqual("./text()[2]"); | ||
expect(offset).toEqual(2); | ||
}); | ||
it('does count highlights in offsets without adjacent text', () => { | ||
document.body.innerHTML = ` | ||
<div id="reference"> | ||
@@ -123,7 +137,3 @@ <div></div> | ||
werwerwerwer | ||
<div> | ||
qwer <span ${DATA_ATTR}>asdf</span> werewwer | ||
<div id="target"></div> | ||
asdfasdf | ||
</div> | ||
<div id="target"><span ${DATA_ATTR}>asdf</span></div> | ||
</div> | ||
@@ -135,6 +145,7 @@ <div></div> | ||
const reference = document.getElementById('reference'); | ||
const text = document.getElementById('target').nextSibling; | ||
const [result] = xpath.getXPathForElement(text, 0, reference); | ||
const element = document.getElementById('target'); | ||
const [result, offset] = xpath.getXPathForElement(element, 1, reference); | ||
expect(result).toEqual("./*[name()='div'][3]/*[name()='div'][1]/text()[2]"); | ||
expect(result).toEqual("./*[name()='div'][3]/*[name()='div'][1]"); | ||
expect(offset).toEqual(1); | ||
}); | ||
@@ -206,9 +217,9 @@ | ||
document.body.innerHTML = ` | ||
<div id="reference">qwer <span ${DATA_ATTR}>asdf</span> werewwer</div> | ||
<div id="reference">asdf<span></span>qwer <span ${DATA_ATTR}>asdf</span> werewwer</div> | ||
`; | ||
const reference = document.getElementById('reference'); | ||
const [result, offset] = xpath.getXPathForElement(reference, 1, reference); | ||
const [result, offset] = xpath.getXPathForElement(reference, 3, reference); | ||
expect(result).toEqual("./text()[1]"); | ||
expect(result).toEqual("./text()[2]"); | ||
expect(offset).toEqual(5); | ||
@@ -256,3 +267,3 @@ }); | ||
expect(result).toEqual("./*[name()='div'][1]"); | ||
expect(offset).toEqual(2); | ||
expect(offset).toEqual(1); | ||
}); | ||
@@ -259,0 +270,0 @@ }); |
Sorry, the diff of this file is too big to display
227044
5198