<p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. <ahref="#">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p>
<h2>Header Level 2</h2>
<ol>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
</ol>
<p>Lorem sed do eiusmod tempor.<br/></p>
<div>Humani generis<br/><br/>Lorem sed do eiusmod tempor.<br/><br/><br/>Mortalium animos</div>
<div>Humani generis<br/><p><br/></p>Lorem sed do eiusmod tempor.<br/><p><br/></p><br/>Mortalium animos</div>
<h2>Header Level 2</h2>
<p><span><!--anchor--></span><!--after-->
Mauris lacinia ipsum nulla, id iaculis quam egestas quis.
['/p',0,'/p',8,'Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.','Spanning multiple nodes, elementNode refs.'],
['/p[2]',0,'/p[2]',1,'Lorem sed do eiusmod tempor.','Full node contents with empty node at end.'],
['/div/text()[2]',0,'/div/text()[2]',28,'Lorem sed do eiusmod tempor.','Text between br tags, textNode refs'],
['/div/text()[2]',0,'/div',4,'Lorem sed do eiusmod tempor.','Text between br tags, elementNode ref at end'],
['/div/text()[2]',0,'/div',5,'Lorem sed do eiusmod tempor.','Text between br tags, with <br/> at end'],
['/div/text()[2]',0,'/div',6,'Lorem sed do eiusmod tempor.','Text between br tags, with <br/><br/> at end'],
['/div/text()[2]',0,'/div',7,'Lorem sed do eiusmod tempor.','Text between br tags, with <br/><br/><br/> at end'],
['/div',3,'/div/text()[2]',28,'Lorem sed do eiusmod tempor.','Text between br tags, elementNode ref at start'],
['/div',2,'/div/text()[2]',28,'Lorem sed do eiusmod tempor.','Text between br tags, with <br/> at start'],
['/div',1,'/div/text()[2]',28,'Lorem sed do eiusmod tempor.','Text between br tags, with <br/><br/> at start'],
['/div[2]/text()[2]',0,'/div[2]/text()[2]',28,'Lorem sed do eiusmod tempor.','Text between br tags, textNode refs'],
['/div[2]/text()[2]',0,'/div[2]',4,'Lorem sed do eiusmod tempor.','Text between br tags, elementNode ref at end'],
['/div[2]/text()[2]',0,'/div[2]',5,'Lorem sed do eiusmod tempor.','Text between br tags, with <br/> at end'],
['/div[2]/text()[2]',0,'/div[2]',6,'Lorem sed do eiusmod tempor.','Text between br tags, with <br/><p><br/></p> at end'],
['/div[2]/text()[2]',0,'/div[2]',7,'Lorem sed do eiusmod tempor.','Text between br tags, with <br/><p><br/></p><br/> at end'],
['/div[2]',3,'/div[2]/text()[2]',28,'Lorem sed do eiusmod tempor.','Text between br tags, elementNode ref at start'],
['/div[2]',2,'/div[2]/text()[2]',28,'Lorem sed do eiusmod tempor.','Text between br tags, with <p><br/></p> at the start'],
['/div[2]',1,'/div[2]/text()[2]',28,'Lorem sed do eiusmod tempor.','Text between br tags, with <br/><p><br/></p> at the start'],
['/h2[2]',0,'/p[4]',0,'Header Level 2\n\n\n Mauris lacinia ipsum nulla, id iaculis quam egestas quis.\n\n\n','No text node at the end and offset 0'],
];
/**
* Test cases for which describing the range is known to fail for certain
* selectors.
*/
varexpectedFailures=[
// [description, expectedFailureTypes]
['Full node contents with empty node at end.',{position:true,quote:true}],
['Text between br tags, elementNode ref at end',{position:true,quote:true}],
['Text between br tags, with <br/> at end',{position:true,quote:true}],
['Text between br tags, with <br/><br/> at end',{position:true,quote:true}],
['Text between br tags, with <br/> at start',{position:true,quote:true}],
['Text between br tags, with <br/><br/> at start',{position:true,quote:true}],
['Text between br tags, elementNode ref at end',{position:true,quote:true}],
['Text between br tags, with <br/> at end',{position:true,quote:true}],
['Text between br tags, with <br/><p><br/></p> at end',{position:true,quote:true}],
['Text between br tags, with <p><br/></p> at the start',{position:true,quote:true}],
['Text between br tags, with <br/><p><br/></p> at the start',{position:true,quote:true}],
['No text node at the end and offset 0',{position:true,quote:true,range:true}],
];
describe('HTML anchoring',function(){
varcontainer;
beforeEach(function(){
container=document.createElement('section');
container.innerHTML=fixture;
document.body.appendChild(container);
});
afterEach(function(){
container.remove();
});
vartestCases=rangeSpecs.map(function(data){
return{
range:{
startContainer:data[0],
startOffset:data[1],
endContainer:data[2],
endOffset:data[3],
},
quote:data[4],
description:data[5],
};
});
unroll('describes and anchors "#description"',function(testCase){
// Resolve the range descriptor to a DOM Range, verify that the expected
// text was selected.
varrange=toRange(container,testCase.range);
assert.equal(range.toString(),testCase.quote);
// Capture a set of selectors describing the range and perform basic sanity