Skip to content

Commit

Permalink
Merge pull request #14 from blinkboxbooks/dev
Browse files Browse the repository at this point in the history
Added support for ranges between element and text nodes when generating range CFIs
  • Loading branch information
jccr committed Oct 20, 2014
2 parents 2e8e2f6 + 4240fbd commit 3a8c53a
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 1 deletion.
71 changes: 70 additions & 1 deletion spec/javascripts/models/cfi_generation_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,76 @@ describe("CFI GENERATOR", function () {
expect(generatedCFI).toEqual("/2[startParent]/2");
});

it("can generate a range component between a text node and an element node", function () {

var dom =
"<html>"
+ "<div></div>"
+ "<div>"
+ "<div id='startParent'>"
+ "textnode"
+ "<div></div>"
+ "textnode1"
+ "<div></div>"
+ "</div>"
+ "</div>"
+ "<div></div>"
+ "</html>";
var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml"));

var $startElement1 = $($('#startParent', $dom).contents()[0]);
var $startElement2 = $($('#startParent', $dom).contents()[1]);
var generatedCFI = EPUBcfi.Generator.generateRangeComponent($startElement1[0], 1, $startElement2[0], 0);
expect(generatedCFI).toEqual("/4/2[startParent],/1:1,/2");
});

it("can generate a range component between an element node and a text node", function () {

var dom =
"<html>"
+ "<div></div>"
+ "<div>"
+ "<div id='startParent'>"
+ "textnode"
+ "<div></div>"
+ "textnode1"
+ "<div></div>"
+ "</div>"
+ "</div>"
+ "<div></div>"
+ "</html>";
var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml"));

var $startElement1 = $($('#startParent', $dom).contents()[1]);
var $startElement2 = $($('#startParent', $dom).contents()[2]);
var generatedCFI = EPUBcfi.Generator.generateRangeComponent($startElement1[0], 0, $startElement2[0], 1);
expect(generatedCFI).toEqual("/4/2[startParent],/2,/3:1");
});

it("can generate a range component between an element node and a text node with different parents", function () {

var dom =
"<html>"
+ "<div></div>"
+ "<div>"
+ "<div id='startParent'>"
+ "textnode"
+ "<div></div>"
+ "textnode1"
+ "<div></div>"
+ "</div>"
+ "</div>"
+ "<div id='end'></div>"
+ "</html>";
var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml"));

var $startElement1 = $($('#startParent', $dom).contents()[0]);
var $startElement2 = $($('#end', $dom)[0]);
var generatedCFI = EPUBcfi.Generator.generateRangeComponent($startElement1[0], 1, $startElement2[0], 0);
expect(generatedCFI).toEqual("/2,/4/2[startParent]/1:1,/6[end]");
});


it("can generate an element range CFI for a node with a period in the ID", function () {

var dom =
Expand Down Expand Up @@ -372,7 +442,6 @@ describe("CFI GENERATOR", function () {

);

console.log(generatedCFI);
expect(generatedCFI).toEqual("/4/2[startParent],/1:14,/1:18");
});

Expand Down
54 changes: 54 additions & 0 deletions src/models/cfi_generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,60 @@ EPUBcfi.Generator = {
return commonCFIComponent.substring(1, commonCFIComponent.length) + "," + range1CFI + "," + range2CFI;
},

generateRangeComponent : function (rangeStartElement, startOffset, rangeEndElement, endOffset, classBlacklist, elementBlacklist, idBlacklist) {
if(rangeStartElement.nodeType === Node.ELEMENT_NODE && rangeEndElement.nodeType === Node.ELEMENT_NODE){
return this.generateElementRangeComponent(rangeStartElement, rangeEndElement, classBlacklist, elementBlacklist, idBlacklist);
} else if(rangeStartElement.nodeType === Node.TEXT_NODE && rangeEndElement.nodeType === Node.TEXT_NODE){
return this.generateCharOffsetRangeComponent(rangeStartElement, startOffset, rangeEndElement, endOffset, classBlacklist, elementBlacklist, idBlacklist);
} else {
var docRange;
var range1CFI;
var range1OffsetStep;
var range2CFI;
var range2OffsetStep;

// Create a document range to find the common ancestor
docRange = document.createRange();
docRange.setStart(rangeStartElement, startOffset);
docRange.setEnd(rangeEndElement, endOffset);
commonAncestor = docRange.commonAncestorContainer;

if(rangeStartElement.nodeType === Node.ELEMENT_NODE){
this.validateStartElement(rangeStartElement);
range1CFI = this.createCFIElementSteps($(rangeStartElement), commonAncestor, classBlacklist, elementBlacklist, idBlacklist);
} else {
this.validateStartTextNode(rangeStartElement);
// Generate terminating offset and range 1
range1OffsetStep = this.createCFITextNodeStep($(rangeStartElement), startOffset, classBlacklist, elementBlacklist, idBlacklist);
if($(rangeStartElement).parent().is(commonAncestor)){
range1CFI = range1OffsetStep;
} else {
range1CFI = this.createCFIElementSteps($(rangeStartElement).parent(), commonAncestor, classBlacklist, elementBlacklist, idBlacklist) + range1OffsetStep;
}
}

if(rangeEndElement.nodeType === Node.ELEMENT_NODE){
this.validateStartElement(rangeEndElement);
range2CFI = this.createCFIElementSteps($(rangeEndElement), commonAncestor, classBlacklist, elementBlacklist, idBlacklist);
} else {
this.validateStartTextNode(rangeEndElement);
// Generate terminating offset and range 2
range2OffsetStep = this.createCFITextNodeStep($(rangeEndElement), endOffset, classBlacklist, elementBlacklist, idBlacklist);
if($(rangeEndElement).parent().is(commonAncestor)){
range2CFI = range2OffsetStep;
} else {
range2CFI = this.createCFIElementSteps($(rangeEndElement).parent(), commonAncestor, classBlacklist, elementBlacklist, idBlacklist) + range2OffsetStep;
}
}

// Generate shared component
commonCFIComponent = this.createCFIElementSteps($(commonAncestor), "html", classBlacklist, elementBlacklist, idBlacklist);

// Return the result
return commonCFIComponent.substring(1, commonCFIComponent.length) + "," + range1CFI + "," + range2CFI;
}
},

// Description: Generates a character offset CFI
// Arguments: The text node that contains the offset referenced by the cfi, the offset value, the name of the
// content document that contains the text node, the package document for this EPUB.
Expand Down
3 changes: 3 additions & 0 deletions src/templates/cfi_library_template.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@
},
generateElementRangeComponent : function (rangeStartElement, rangeEndElement, classBlacklist, elementBlacklist, idBlacklist) {
return generator.generateElementRangeComponent(rangeStartElement, rangeEndElement, classBlacklist, elementBlacklist, idBlacklist);
},
generateRangeComponent : function (rangeStartElement, startOffset, rangeEndElement, endOffset, classBlacklist, elementBlacklist, idBlacklist) {
return generator.generateRangeComponent(rangeStartElement, startOffset, rangeEndElement, endOffset, classBlacklist, elementBlacklist, idBlacklist);
}
};

Expand Down

0 comments on commit 3a8c53a

Please sign in to comment.