Skip to content

Instantly share code, notes, and snippets.

@wilkerlucio
Created November 13, 2013 20:33
Show Gist options
  • Select an option

  • Save wilkerlucio/7455883 to your computer and use it in GitHub Desktop.

Select an option

Save wilkerlucio/7455883 to your computer and use it in GitHub Desktop.
describe "Range", ->
quickRange = (startContainer, startOffset, endContainer, endOffset) ->
_.tap document.createRange(), (range) ->
range.setStart(startContainer, startOffset)
range.setEnd(endContainer, endOffset)
describe ".previousSiblingsOffset", ->
{previousSiblingsOffset} = RangeTools
it "calculates the offset text of a text node given it's siblings", ->
$("body").html("<p>some text <b>inside</b> more</p>")
p = $("p")[0]
nodes = p.childNodes
expect(previousSiblingsOffset(nodes[0])).eq 0
expect(previousSiblingsOffset(nodes[1])).eq 10
expect(previousSiblingsOffset(nodes[2])).eq 16
describe ".findTextElement", ->
{findTextElement} = RangeTools
it "concatenates endpoint with given path", ->
$("body").html "<p>some text <b>with bold</b> in parts</p>"
p = $("p")[0]
text = p.childNodes
expect(findTextElement(p, 0)).eql [text[0], 0]
expect(findTextElement(p, 9)).eql [text[0], 9]
expect(findTextElement(p, 10)).eql [text[1], 0]
expect(findTextElement(p, 18)).eql [text[1], 8]
expect(findTextElement(p, 19)).eql [text[2], 0]
describe ".extractRangeData", ->
{extractRangeData} = RangeTools
it "extracts the range information with correct XPath and offset", ->
$("body").html("<p>some text <b>inside</b> more</p>")
nodes = $("p")[0].childNodes
rangeInfo = extractRangeData(quickRange(nodes[0], 1, nodes[2], 2))
expect(rangeInfo).eql
start: "/html/body/p"
end: "/html/body/p"
startOffset: 1
endOffset: 18
describe ".wrappableBreaks", ->
{wrappableBreaks} = RangeTools
testBreaks = (singleRange, infoList...) ->
breaks = wrappableBreaks(singleRange)
expect(breaks).length(infoList.length)
for [range, info] in _.zip(breaks, infoList)
expect(range.startContainer).eq info[0]
expect(range.startOffset).eq info[1]
expect(range.endContainer).eq info[2]
expect(range.endOffset).eq info[3]
it "returns an array with the original range when it doesn't need breaks simple", ->
$("body").html("<p>x</p>")
[p] = document.querySelector("p").childNodes
testBreaks quickRange(p, 0, p, 1),
[p, 0, p, 1]
it "returns an array with the original range when it doesn't need breaks by having same parent", ->
$("body").html("<p>x<b>y</b>z</p>")
[p, b, p2] = document.querySelector("p").childNodes
testBreaks quickRange(p, 0, p2, 1),
[p, 0, p2, 1]
it "breaking from parent to child", ->
$("body").html("<p>x<b>y</b></p>")
[p, b] = document.querySelector("p").childNodes
b = b.firstChild
testBreaks quickRange(p, 0, b, 1),
[p, 0, p, 1]
[b, 0, b, 1]
it "breaking from child to parent", ->
$("body").html("<p><b>xx</b>yy</p>")
[b, p] = document.querySelector("p").childNodes
b = b.firstChild
testBreaks quickRange(b, 1, p, 2),
[b, 1, b, 2]
[p, 0, p, 2]
it "breaks multilevel ascending", ->
$("body").html("<p>x<b>y<i>z</i></b></p>")
[p, b] = document.querySelector("p").childNodes
[b, i] = b.childNodes
i = i.firstChild
testBreaks quickRange(p, 0, i, 1),
[p, 0, p, 1]
[b, 0, b, 1]
[i, 0, i, 1]
it "breaks multilevel descending", ->
$("body").html("<p><b><i>z</i>y</b>x</p>")
[b, p] = document.querySelector("p").childNodes
[i, b] = b.childNodes
i = i.firstChild
testBreaks quickRange(i, 0, p, 1),
[i, 0, i, 1]
[b, 0, b, 1]
[p, 0, p, 1]
it "breaks multilevel around", ->
$("body").html("<p><b>x</b>y<i>z</i></p>")
[b, p, i] = document.querySelector("p").childNodes
b = b.firstChild
i = i.firstChild
testBreaks quickRange(b, 0, i, 1),
[b, 0, b, 1]
[p, 0, p, 1]
[i, 0, i, 1]
it "breaks multilevel around with deep middle", ->
$("body").html("<p><b>x</b>y<span>a</span>b<i>z</i></p>")
[x, y, a, b, z] = document.querySelector("p").childNodes
x = x.firstChild
a = a.firstChild
z = z.firstChild
testBreaks quickRange(x, 0, z, 1),
[x, 0, x, 1]
[y, 0, y, 1]
[a, 0, a, 1]
[b, 0, b, 1]
[z, 0, z, 1]
describe ".flattenTextNodes", ->
{flattenTextNodes} = RangeTools
it "returns the text node if it's only it", ->
$("body").html "<p>x</p>"
ancestor = document.querySelector("p")
x = ancestor.firstChild
expect(flattenTextNodes([x])).eql [x]
it "returns the text nodes inside other tags", ->
$("body").html "<p>x<span>y</span></p>"
ancestor = document.querySelector("p")
[x, y] = ancestor.childNodes
yc = y.firstChild
expect(flattenTextNodes([x, y])).eql [x, yc]
describe ".ancestorTextNodesRight", ->
{ancestorTextNodesRight} = RangeTools
it "returns current text node when the common ancestor is the current parent", ->
$("body").html "<p>x</p>"
ancestor = document.querySelector("p")
x = ancestor.firstChild
expect(ancestorTextNodesRight(x, ancestor)).eql [x]
it "returns right ancestors", ->
$("body").html """
<p>
<span>
a
<span>
b
<span>c</span>
</span>
d
</span>
e
</p>
""".replace(/\s/g, '')
ancestor = document.querySelector("p")
[a, e] = ancestor.childNodes
[a, b, d] = a.childNodes
[b, c] = b.childNodes
c = c.firstChild
expect(ancestorTextNodesRight(b, ancestor)).eql [b, c, d]
describe ".ancestorTextNodesLeft", ->
{ancestorTextNodesLeft} = RangeTools
it "returns current text node when the common ancestor is the current parent", ->
$("body").html "<p>x</p>"
ancestor = document.querySelector("p")
x = ancestor.firstChild
expect(ancestorTextNodesLeft(x, ancestor)).eql [x]
it "returns left ancestors", ->
$("body").html """
<p>
<span>
a
<span>
b
<span>c</span>
</span>
d
</span>
e
</p>
""".replace(/\s/g, '')
ancestor = document.querySelector("p")
[a, e] = ancestor.childNodes
[a, b, d] = a.childNodes
[b, c] = b.childNodes
c = c.firstChild
expect(ancestorTextNodesLeft(b, ancestor)).eql [a, b]
describe ".immediateChildForAncestorIndex", ->
it "returns the index when the parent is already the ancestor", ->
$("body").html "<p>x</p>"
[x] = document.querySelector()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment