From 50fecf0fcde217edc796daffc177e6436ba4e2db Mon Sep 17 00:00:00 2001 From: danielweck Date: Thu, 4 Feb 2016 21:21:02 +0000 Subject: [PATCH 1/4] DOMParser wrapper (utility function) to handle XML version="1.1" failure in some browsers, see https://github.com/readium/readium-js-viewer/issues/467 --- dev/index.js | 23 ++++--- dev/index_NO-RequireJS.html | 2 + dev/index_NO-RequireJS_TESTS.html | 2 + js/XmlParse.js | 72 ++++++++++++++++++++++ js/cfi_API.js | 10 +-- tests/spec/models/cfi_generator_spec.js | 70 ++++++++++----------- tests/spec/models/cfi_instructions_spec.js | 54 ++++++++-------- tests/spec/models/cfi_interpreter_spec.js | 28 ++++----- 8 files changed, 170 insertions(+), 91 deletions(-) create mode 100644 js/XmlParse.js diff --git a/dev/index.js b/dev/index.js index 212d64b..a26037f 100644 --- a/dev/index.js +++ b/dev/index.js @@ -1,15 +1,17 @@ -var check = function(cfiParser, cfiInterpreter, cfiInstructions, cfiRuntimeErrors, cfiGenerator) { +var check = function(cfiParser, cfiInterpreter, cfiInstructions, cfiRuntimeErrors, cfiGenerator, xmlParse) { $(document).ready(function () { console.log(window.EPUBcfi); - function checkAPI(obj, globalName) { + function checkAPI(obj, globalName, anchor) { - if (obj && obj === window.EPUBcfi[globalName]) { - console.log("OKAY => EPUBcfi." + globalName); + if (!anchor) anchor = window.EPUBcfi; + + if (obj && obj === anchor[globalName]) { + console.log("OKAY => " + globalName); } else { - console.log("ERROR! => EPUBcfi." + globalName); + console.log("ERROR! => " + globalName); } } @@ -21,7 +23,7 @@ var check = function(cfiParser, cfiInterpreter, cfiInstructions, cfiRuntimeError checkAPI(cfiRuntimeErrors.OutOfRangeError, "OutOfRangeError"); checkAPI(cfiRuntimeErrors.TerminusError, "TerminusError"); checkAPI(cfiRuntimeErrors.CFIAssertionError, "CFIAssertionError"); - + checkAPI(xmlParse, "XmlParse", window); }); }; @@ -33,10 +35,10 @@ if (typeof define == 'function' && typeof define.amd == 'object') { require(["readium_cfi_js/cfi_API"], function () { // to access individual feature APIs, via dependency injection (not the global window-attached objects) - require(['jquery', 'readium_cfi_js/cfi_parser', 'readium_cfi_js/cfi_interpreter', 'readium_cfi_js/cfi_instructions', 'readium_cfi_js/cfi_runtime_errors', 'readium_cfi_js/cfi_generator'], - function ($, cfiParser, cfiInterpreter, cfiInstructions, cfiRuntimeErrors, cfiGenerator) { + require(['jquery', 'readium_cfi_js/cfi_parser', 'readium_cfi_js/cfi_interpreter', 'readium_cfi_js/cfi_instructions', 'readium_cfi_js/cfi_runtime_errors', 'readium_cfi_js/cfi_generator', 'readium_cfi_js/XmlParse'], + function ($, cfiParser, cfiInterpreter, cfiInstructions, cfiRuntimeErrors, cfiGenerator, xmlParse) { - check(cfiParser, cfiInterpreter, cfiInstructions, cfiRuntimeErrors, cfiGenerator); + check(cfiParser, cfiInterpreter, cfiInstructions, cfiRuntimeErrors, cfiGenerator, xmlParse); }); }); @@ -57,5 +59,6 @@ if (typeof define == 'function' && typeof define.amd == 'object') { TerminusError: window.EPUBcfi.TerminusError, CFIAssertionError: window.EPUBcfi.CFIAssertionError }, - window.EPUBcfi.Generator); + window.EPUBcfi.Generator, + window.XmlParse); } diff --git a/dev/index_NO-RequireJS.html b/dev/index_NO-RequireJS.html index a9e1847..9cfd465 100644 --- a/dev/index_NO-RequireJS.html +++ b/dev/index_NO-RequireJS.html @@ -21,6 +21,8 @@ + + diff --git a/dev/index_NO-RequireJS_TESTS.html b/dev/index_NO-RequireJS_TESTS.html index 910c57b..8ebd881 100644 --- a/dev/index_NO-RequireJS_TESTS.html +++ b/dev/index_NO-RequireJS_TESTS.html @@ -21,6 +21,8 @@ + + diff --git a/js/XmlParse.js b/js/XmlParse.js new file mode 100644 index 0000000..abb0385 --- /dev/null +++ b/js/XmlParse.js @@ -0,0 +1,72 @@ +// LauncherOSX +// +// Created by Boris Schneiderman. +// Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation and/or +// other materials provided with the distribution. +// 3. Neither the name of the organization nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +// OF THE POSSIBILITY OF SUCH DAMAGE. + +(function(global) { + + +var init = function() { + var XmlParse = {}; + + XmlParse.fromString = function(str, contentType) { + + if (!contentType) contentType = "text/xml" + + if (str && (str.indexOf('version="1.1"') > 0)) { + + console.warn("Replacing XML v1.1 with v1.0 (web browser compatibility)."); + + console.log(str.substr(0, 50)); + + str = str.replace(/(<\?xml[\s\S]+?)version="1.1"([\s\S]+?\?>)/, '$1version="1.0"$2'); + + console.log(str.substr(0, 50)); + } + + var parser = new window.DOMParser; + return parser.parseFromString(str, contentType); + }; + + global.XmlParse = XmlParse; + return XmlParse; +}; + + +if (typeof define == 'function' && typeof define.amd == 'object') { + console.log("RequireJS ... XmlParse"); + + define([], + function () { + return init(); + }); +} else { + console.log("!RequireJS ... XmlParse"); + + //global.XmlParse = + init(); +} + +})(typeof window !== "undefined" ? window : this); diff --git a/js/cfi_API.js b/js/cfi_API.js index 8734aba..9d3c67f 100644 --- a/js/cfi_API.js +++ b/js/cfi_API.js @@ -13,7 +13,7 @@ (function(global) { -var init = function(cfiParser, cfiInterpreter, cfiInstructions, cfiRuntimeErrors, cfiGenerator) { +var init = function(cfiParser, cfiInterpreter, cfiInstructions, cfiRuntimeErrors, cfiGenerator, xmlParse) { if (typeof cfiParser === "undefined") { throw new Error("UNDEFINED?! cfiParser"); @@ -122,10 +122,10 @@ var init = function(cfiParser, cfiInterpreter, cfiInstructions, cfiRuntimeErrors if (typeof define == 'function' && typeof define.amd == 'object') { console.log("RequireJS ... cfi_API"); - define(['readium_cfi_js/cfi_parser', './cfi_interpreter', './cfi_instructions', './cfi_runtime_errors', './cfi_generator'], - function (cfiParser, cfiInterpreter, cfiInstructions, cfiRuntimeErrors, cfiGenerator) { + define(['readium_cfi_js/cfi_parser', './cfi_interpreter', './cfi_instructions', './cfi_runtime_errors', './cfi_generator', './XmlParse'], + function (cfiParser, cfiInterpreter, cfiInstructions, cfiRuntimeErrors, cfiGenerator, xmlParse) { - return init(cfiParser, cfiInterpreter, cfiInstructions, cfiRuntimeErrors, cfiGenerator); + return init(cfiParser, cfiInterpreter, cfiInstructions, cfiRuntimeErrors, cfiGenerator, xmlParse); }); } else { console.log("!RequireJS ... cfi_API"); @@ -143,7 +143,7 @@ if (typeof define == 'function' && typeof define.amd == 'object') { TerminusError: global.EPUBcfi.TerminusError, CFIAssertionError: global.EPUBcfi.CFIAssertionError }, - global.EPUBcfi.Generator); + global.EPUBcfi.Generator, global.XmlParse); } })(typeof window !== "undefined" ? window : this); diff --git a/tests/spec/models/cfi_generator_spec.js b/tests/spec/models/cfi_generator_spec.js index 7c70aba..75cf6fc 100644 --- a/tests/spec/models/cfi_generator_spec.js +++ b/tests/spec/models/cfi_generator_spec.js @@ -18,7 +18,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var commonAncestor = $($dom.children()[0]).children()[1]; var $startElement = $($('#startParent', $dom).contents()[0]); @@ -41,7 +41,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement1 = $($('#startParent', $dom).contents()[0]); var $startElement2 = $($('#startParent', $dom).contents()[1]); @@ -64,7 +64,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement1 = $($('#startParent', $dom).contents()[1]); var $startElement2 = $($('#startParent', $dom).contents()[2]); @@ -87,7 +87,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement1 = $($('#startElement', $dom).contents()[0]); var $startElement2 = $($('#startParent', $dom).contents()[2]); @@ -110,7 +110,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement1 = $($('#startParent', $dom).contents()[0]); var $startElement2 = $($('#end', $dom)[0]); @@ -135,7 +135,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement1 = $($('#startParent', $dom).children()[0]); var $startElement2 = $($('#startParent', $dom).children()[2]); @@ -161,7 +161,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement1 = $($('#startParent', $dom).children()[0]); var $startElement2 = $($('#startParent', $dom).children()[2]); @@ -186,7 +186,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement1 = $($('#startParent', $dom).children()[0]); var $startElement2 = $($('#startParent', $dom).children()[0]); @@ -217,7 +217,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement = $($('#startParent', $dom).children()[0].firstChild); var $endElement = $($('#startParent', $dom).children()[2].firstChild); @@ -247,7 +247,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement = $($('#startParent', $dom).children()[0].firstChild); var $endElement = $($('#startParent', $dom).children()[0].firstChild); @@ -275,7 +275,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement = $($('#startParent', $dom).contents()[0]); var $endElement = $($('#startParent', $dom).children()[0].firstChild); @@ -300,7 +300,7 @@ describe("CFI GENERATOR", function () { " " + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); // per the issue The CFI for "important text" should be : /2/4, /2/1:5, /3:5 var $startElement = $($("strong", $dom).contents()[0]); // "very important" var $endElement = $($("p", $dom).contents()[2]); // " text" @@ -333,7 +333,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement = $($('#startParent', $dom).contents()[1]); var $endElement = $($('#startParent', $dom).contents()[5]); @@ -361,7 +361,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement = $($('#startParent', $dom).contents()[0]); var $endElement = $($('#startParent', $dom).contents()[2]); @@ -388,7 +388,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement = $($('#startParent', $dom).contents()[1]); var $endElement = $($('#startParent', $dom).contents()[1]); @@ -415,7 +415,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement = $($('#startParent', $dom).contents()[0]); var $endElement = $($('#startParent', $dom).contents()[2]); @@ -441,7 +441,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement = $($('#startParent', $dom).contents()[1]); var $endElement = $($('#startParent', $dom).contents()[1]); @@ -466,7 +466,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement = $($('#startParent', $dom).contents()[0]); var $endElement = $($('#startParent', $dom).contents()[0]) @@ -524,7 +524,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement = $($('#startParent', $dom).contents()[1]); var $endElement = $($('#startParent', $dom).contents()[3]); @@ -554,7 +554,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement = $($('#startParent', $dom).contents()[4]); var $endElement = $($('#startParent', $dom).contents()[4]) @@ -586,7 +586,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement = $($('#startParent', $dom).contents()[4]); var $endElement = $($('#startParent', $dom).contents()[4]) @@ -614,7 +614,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startElement = $($('#startParent', $dom).contents()[4]); var $endElement = $($('#startParent', $dom).contents()[4]) var generatedCFI = EPUBcfi.Generator.generateCharOffsetRangeComponent( @@ -651,7 +651,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var generatedCFI = EPUBcfi.Generator.createCFIElementSteps($($('#startParent', $dom).contents()[0]), "html"); expect(generatedCFI).toEqual("!/4/2[startParent]/2"); @@ -677,7 +677,7 @@ describe("CFI GENERATOR", function () { + "" + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var $startNode = $($('#startParent', $dom).contents()[5]); var textTerminus = EPUBcfi.Generator.createCFITextNodeStep($startNode, 3, ["cfi-marker"]); var generatedCFI = EPUBcfi.Generator.createCFIElementSteps($startNode.parent(), "html", ["cfi-marker"]) + textTerminus; @@ -700,7 +700,7 @@ describe("CFI GENERATOR", function () { + "" + ""; - var packageDoc = (new window.DOMParser).parseFromString(packageDocXhtml, "text/xml"); + var packageDoc = XmlParse.fromString(packageDocXhtml); var packageDocCFIComponent = EPUBcfi.Generator.generatePackageDocumentCFIComponentWithSpineIndex(2, packageDoc); expect(packageDocCFIComponent).toEqual("/6/2/6!"); // [ te,xtn] }); @@ -735,8 +735,8 @@ describe("CFI GENERATOR", function () { + "
" + ""; - var contentDoc = (new window.DOMParser).parseFromString(contentDocXhtml, "text/xml"); - var packageDoc = (new window.DOMParser).parseFromString(packageDocXhtml, "text/xml"); + var contentDoc = XmlParse.fromString(contentDocXhtml); + var packageDoc = XmlParse.fromString(packageDocXhtml); var contentDocCFIComponent = EPUBcfi.Generator.generateCharacterOffsetCFIComponent($('#startParent', contentDoc).contents()[1], 3); var packageDocCFIComponent = EPUBcfi.Generator.generatePackageDocumentCFIComponent("contentDocId", packageDoc); @@ -748,9 +748,9 @@ describe("CFI GENERATOR", function () { it('can generate a CFI for an actual epub', function () { var contentDocXhtml = jasmine.getFixtures().read("moby_dick_content_doc.xhtml"); - var contentDoc = (new window.DOMParser).parseFromString(contentDocXhtml, "text/xml"); + var contentDoc = XmlParse.fromString(contentDocXhtml); var packageDocXhtml = jasmine.getFixtures().read("moby_dick_package.opf"); - var packageDoc = (new window.DOMParser).parseFromString(packageDocXhtml, "text/xml"); + var packageDoc = XmlParse.fromString(packageDocXhtml); var contentDocCFIComponent = EPUBcfi.Generator.generateCharacterOffsetCFIComponent($("#c01p0008", contentDoc)[0].firstChild, 103); var packageDocCFIComponent = EPUBcfi.Generator.generatePackageDocumentCFIComponent("xchapter_001", packageDoc); @@ -762,9 +762,9 @@ describe("CFI GENERATOR", function () { it("can generate a CFI without a terminus", function () { var contentDocXhtml = jasmine.getFixtures().read("moby_dick_content_doc.xhtml"); - var contentDoc = (new window.DOMParser).parseFromString(contentDocXhtml, "text/xml"); + var contentDoc = XmlParse.fromString(contentDocXhtml); var packageDocXhtml = jasmine.getFixtures().read("moby_dick_package.opf"); - var packageDoc = (new window.DOMParser).parseFromString(packageDocXhtml, "text/xml"); + var packageDoc = XmlParse.fromString(packageDocXhtml); var contentDocCFIComponent = EPUBcfi.Generator.generateElementCFIComponent($("#c01p0008", contentDoc)[0]); var packageDocCFIComponent = EPUBcfi.Generator.generatePackageDocumentCFIComponent("xchapter_001", packageDoc); @@ -776,9 +776,9 @@ describe("CFI GENERATOR", function () { it("can generate a CFI without a terminus when the start element is the 'html' element", function () { var contentDocXhtml = jasmine.getFixtures().read("moby_dick_content_doc.xhtml"); - var contentDoc = (new window.DOMParser).parseFromString(contentDocXhtml, "text/xml"); + var contentDoc = XmlParse.fromString(contentDocXhtml); var packageDocXhtml = jasmine.getFixtures().read("moby_dick_package.opf"); - var packageDoc = (new window.DOMParser).parseFromString(packageDocXhtml, "text/xml"); + var packageDoc = XmlParse.fromString(packageDocXhtml); var contentDocCFIComponent = EPUBcfi.Generator.generateElementCFIComponent($("html", contentDoc)[0]); var packageDocCFIComponent = EPUBcfi.Generator.generatePackageDocumentCFIComponent("xchapter_001", packageDoc); @@ -799,9 +799,9 @@ describe("CFI GENERATOR", function () { beforeEach(function () { contentDocXhtml = jasmine.getFixtures().read("moby_dick_content_doc.xhtml"); - contentDoc = (new window.DOMParser).parseFromString(contentDocXhtml, "text/xml"); + contentDoc = XmlParse.fromString(contentDocXhtml); packageDocXhtml = jasmine.getFixtures().read("moby_dick_package.opf"); - packageDoc = (new window.DOMParser).parseFromString(packageDocXhtml, "text/xml"); + packageDoc = XmlParse.fromString(packageDocXhtml); startTextNode = $("#c01p0008", contentDoc)[0].firstChild; }); diff --git a/tests/spec/models/cfi_instructions_spec.js b/tests/spec/models/cfi_instructions_spec.js index 8b56a48..ecc55bd 100644 --- a/tests/spec/models/cfi_instructions_spec.js +++ b/tests/spec/models/cfi_instructions_spec.js @@ -3,8 +3,8 @@ describe("CFI INSTRUCTION OBJECT", function () { it("finds the target element on an index step", function () { var contentDocXHTML = jasmine.getFixtures().read('moby_dick_content_doc.xhtml'); - var domParser = new window.DOMParser(); - var contentDoc = domParser.parseFromString(contentDocXHTML, "text/xml"); + + var contentDoc = XmlParse.fromString(contentDocXHTML); var $nextNode = EPUBcfi.CFIInstructions.getNextNode(4, $(contentDoc.firstChild), ["cfiMarker"]); var nodeType = $nextNode.is("body"); @@ -62,8 +62,8 @@ describe("CFI INSTRUCTION OBJECT", function () { it("injects text at the specified offset", function () { var contentDocXHTML = jasmine.getFixtures().read('moby_dick_content_doc.xhtml'); - var domParser = new window.DOMParser(); - var contentDoc = domParser.parseFromString(contentDocXHTML, "text/xml"); + + var contentDoc = XmlParse.fromString(contentDocXHTML); var $injectedElement = EPUBcfi.CFIInstructions.textTermination($($("#c01p0002", $(contentDoc))[0].firstChild), 4, ''); @@ -102,9 +102,9 @@ describe("CFI INSTRUCTION OBJECT", function () { it('excludes elements that have a class that indicates they are "cfi markers" and returns a list of text nodes', function () { - var domParser = new window.DOMParser(); + var xhtml = '
asdfsd
ddfd
'; - var doc = domParser.parseFromString(xhtml, 'text/xml'); + var doc = XmlParse.fromString(xhtml); var $currentNode = $(doc.firstChild.firstChild); var $result = EPUBcfi.CFIInstructions.getNextNode(1, $currentNode, ["cfiMarker"], []); @@ -115,9 +115,9 @@ describe("CFI INSTRUCTION OBJECT", function () { it('returns the correct text node if the first text node is empty', function () { - var domParser = new window.DOMParser(); + var xhtml = '
text1
text2
'; - var doc = domParser.parseFromString(xhtml, 'text/xml'); + var doc = XmlParse.fromString(xhtml); var $currentNode = $(doc.firstChild); var $result = EPUBcfi.CFIInstructions.getNextNode(3, $currentNode, ["cfiMarker"], []); @@ -127,9 +127,9 @@ describe("CFI INSTRUCTION OBJECT", function () { it('returns the correct text node if a previous one contains a comment node', function () { - var domParser = new window.DOMParser(); + var xhtml = '
text1text2
text
text3
'; - var doc = domParser.parseFromString(xhtml, 'text/xml'); + var doc = XmlParse.fromString(xhtml); var $currentNode = $(doc.firstChild); var $result = EPUBcfi.CFIInstructions.getNextNode(3, $currentNode, ["cfiMarker"], []); @@ -139,9 +139,9 @@ describe("CFI INSTRUCTION OBJECT", function () { it('returns the correct text node if it contains a comment node', function () { - var domParser = new window.DOMParser(); + var xhtml = '
text1
text
text2text3
'; - var doc = domParser.parseFromString(xhtml, 'text/xml'); + var doc = XmlParse.fromString(xhtml); var $currentNode = $(doc.firstChild); var $result = EPUBcfi.CFIInstructions.getNextNode(3, $currentNode, ["cfiMarker"], []); @@ -153,9 +153,9 @@ describe("CFI INSTRUCTION OBJECT", function () { it('returns the correct text node if it contains a processing instruction node', function () { - var domParser = new window.DOMParser(); + var xhtml = '
text1
text
text2text3
'; - var doc = domParser.parseFromString(xhtml, 'text/xml'); + var doc = XmlParse.fromString(xhtml); var $currentNode = $(doc.firstChild); var $result = EPUBcfi.CFIInstructions.getNextNode(3, $currentNode, ["cfiMarker"], []); @@ -167,9 +167,9 @@ describe("CFI INSTRUCTION OBJECT", function () { it('returns the correct text node if it start with a processing instruction node', function () { - var domParser = new window.DOMParser(); + var xhtml = '
text
'; - var doc = domParser.parseFromString(xhtml, 'text/xml'); + var doc = XmlParse.fromString(xhtml); var $currentNode = $(doc.firstChild); var $result = EPUBcfi.CFIInstructions.getNextNode(1, $currentNode, ["cfiMarker"], []); @@ -180,9 +180,9 @@ describe("CFI INSTRUCTION OBJECT", function () { it('returns the correct text node if the node is in the first position of a set of child nodes', function () { - var domParser = new window.DOMParser(); + var xhtml = '
text1
text2
text3
'; - var doc = domParser.parseFromString(xhtml, 'text/xml'); + var doc = XmlParse.fromString(xhtml); var $currentNode = $(doc.firstChild); var $result = EPUBcfi.CFIInstructions.getNextNode(1, $currentNode, ["cfiMarker"], []); @@ -192,9 +192,9 @@ describe("CFI INSTRUCTION OBJECT", function () { it('returns the correct text node if the node is between elements in a set of child nodes', function () { - var domParser = new window.DOMParser(); + var xhtml = '
text1
text2
text3
'; - var doc = domParser.parseFromString(xhtml, 'text/xml'); + var doc = XmlParse.fromString(xhtml); var $currentNode = $(doc.firstChild); var $result = EPUBcfi.CFIInstructions.getNextNode(3, $currentNode, ["cfiMarker"], []); @@ -204,9 +204,9 @@ describe("CFI INSTRUCTION OBJECT", function () { it('returns the correct text node if the node is the last in a set of child nodes', function () { - var domParser = new window.DOMParser(); + var xhtml = '
text1
text2
text3
'; - var doc = domParser.parseFromString(xhtml, 'text/xml'); + var doc = XmlParse.fromString(xhtml); var $currentNode = $(doc.firstChild); var $result = EPUBcfi.CFIInstructions.getNextNode(5, $currentNode, ["cfiMarker"], []); @@ -337,8 +337,8 @@ describe('CFI INSTRUCTION ERROR HANDLING', function () { it('throws an out of range error for an index step', function () { var contentDocXHTML = jasmine.getFixtures().read('moby_dick_content_doc.xhtml'); - var domParser = new window.DOMParser(); - var contentDoc = domParser.parseFromString(contentDocXHTML, "text/xml"); + + var contentDoc = XmlParse.fromString(contentDocXHTML); // A step of 16 is greater than the number of child elements of the content document expect(function () { @@ -377,9 +377,9 @@ describe('CFI INSTRUCTION ERROR HANDLING', function () { var packageDocXML = jasmine.getFixtures().read('moby_dick_package.opf'); var contentDocXHTML = jasmine.getFixtures().read('moby_dick_content_doc.xhtml'); - var domParser = new window.DOMParser(); - var packageDoc = domParser.parseFromString(packageDocXML, "text/xml"); - var contentDoc = domParser.parseFromString(contentDocXHTML, "text/xml"); + + var packageDoc = XmlParse.fromString(packageDocXML); + var contentDoc = XmlParse.fromString(contentDocXHTML); var spineElement = $($(packageDoc.firstChild).children()[2]).children()[6]; var nextNode; diff --git a/tests/spec/models/cfi_interpreter_spec.js b/tests/spec/models/cfi_interpreter_spec.js index c0f4591..8060e61 100644 --- a/tests/spec/models/cfi_interpreter_spec.js +++ b/tests/spec/models/cfi_interpreter_spec.js @@ -14,18 +14,18 @@ describe('CFI INTERPRETER OBJECT', function () { CFIAST = EPUBcfi.Parser.parse(CFI); // Set up package document - var domParser = new window.DOMParser(); + var packageDocXML = jasmine.getFixtures().read("moby_dick_package.opf"); - $packageDocument = $(domParser.parseFromString(packageDocXML, "text/xml")); + $packageDocument = $(XmlParse.fromString(packageDocXML)); // Set up content document var contentDocXHTML = jasmine.getFixtures().read("moby_dick_content_doc.xhtml"); - contentDocument = domParser.parseFromString(contentDocXHTML, 'text/xml'); + contentDocument = XmlParse.fromString(contentDocXHTML); $contentDocument = $(contentDocument); spyOn($, "ajax").and.callFake(function (params) { - params.success(domParser.parseFromString(contentDocXHTML, 'text/xml')); + params.success(XmlParse.fromString(contentDocXHTML)); }); }); @@ -49,7 +49,7 @@ describe('CFI INTERPRETER OBJECT', function () { + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var CFI = "epubcfi(/6/14!/4/2[startParent],/1:22,/1:27)"; @@ -79,7 +79,7 @@ describe('CFI INTERPRETER OBJECT', function () { + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var CFI = "epubcfi(/6/14!/4/2[startParent],/1:57,/1:62)"; @@ -110,7 +110,7 @@ describe('CFI INTERPRETER OBJECT', function () { + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var CFI = "epubcfi(/6/14!/4/2[startParent],/1:73,/1:78)"; @@ -143,7 +143,7 @@ describe('CFI INTERPRETER OBJECT', function () { + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var CFI = "epubcfi(/6/14!/4/2[startParent],/1:6,/1:7)"; @@ -194,7 +194,7 @@ describe('CFI INTERPRETER OBJECT', function () { + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var CFI = "epubcfi(/6/14!/4/2[start.Parent],/1:6,/1:8)"; @@ -229,7 +229,7 @@ describe('CFI INTERPRETER OBJECT', function () { + "
" + ""; - var $dom = $((new window.DOMParser).parseFromString(dom, "text/xml")); + var $dom = $(XmlParse.fromString(dom)); var CFI = "epubcfi(/6/14!/4/2[startParent],/1:6,/1:8)"; @@ -489,17 +489,17 @@ describe('ERROR HANDLING FOR ID AND TEXT ASSERTIONS', function () { beforeEach(function () { // Set up package document - var domParser = new window.DOMParser(); + var packageDocXML = jasmine.getFixtures().read("moby_dick_package.opf"); - $packageDocument = $(domParser.parseFromString(packageDocXML, "text/xml")); + $packageDocument = $(XmlParse.fromString(packageDocXML)); // Set up content document var contentDocXHTML = jasmine.getFixtures().read("moby_dick_content_doc.xhtml"); - $contentDocument = $(domParser.parseFromString(contentDocXHTML, 'text/xml')); + $contentDocument = $(XmlParse.fromString(contentDocXHTML)); spyOn($, "ajax").and.callFake(function (params) { - params.success(domParser.parseFromString(contentDocXHTML, 'text/xml')); + params.success(XmlParse.fromString(contentDocXHTML)); }); }); From 3413dc7e7b35956156c05abedd0d3bb9532891a4 Mon Sep 17 00:00:00 2001 From: danielweck Date: Thu, 4 Feb 2016 22:48:31 +0000 Subject: [PATCH 2/4] extracted preprocessing routine for XML v1.1 utility parser (window.DOMParser wrapper) --- js/XmlParse.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/js/XmlParse.js b/js/XmlParse.js index abb0385..464013f 100644 --- a/js/XmlParse.js +++ b/js/XmlParse.js @@ -31,10 +31,8 @@ var init = function() { var XmlParse = {}; - XmlParse.fromString = function(str, contentType) { + XmlParse.preprocess = function(str) { - if (!contentType) contentType = "text/xml" - if (str && (str.indexOf('version="1.1"') > 0)) { console.warn("Replacing XML v1.1 with v1.0 (web browser compatibility)."); @@ -46,6 +44,15 @@ var init = function() { console.log(str.substr(0, 50)); } + return str; + }; + + XmlParse.fromString = function(str, contentType) { + + if (!contentType) contentType = "text/xml"; + + str = XmlParse.preprocess(str); + var parser = new window.DOMParser; return parser.parseFromString(str, contentType); }; From d0441cf77481b63a11b3194976da740e4e8683a5 Mon Sep 17 00:00:00 2001 From: danielweck Date: Mon, 8 Feb 2016 18:11:09 +0000 Subject: [PATCH 3/4] minor debugging code change --- js/XmlParse.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/js/XmlParse.js b/js/XmlParse.js index 464013f..1f867e5 100644 --- a/js/XmlParse.js +++ b/js/XmlParse.js @@ -54,7 +54,9 @@ var init = function() { str = XmlParse.preprocess(str); var parser = new window.DOMParser; - return parser.parseFromString(str, contentType); + var dom = parser.parseFromString(str, contentType); + + return dom; }; global.XmlParse = XmlParse; From afbdb858f34174c3c50e82efef91df4e3cb636da Mon Sep 17 00:00:00 2001 From: danielweck Date: Thu, 2 Aug 2018 11:24:45 +0100 Subject: [PATCH 4/4] removed obsolete XmlParser --- js/XmlParse.js | 81 -------------------------------------------------- 1 file changed, 81 deletions(-) delete mode 100644 js/XmlParse.js diff --git a/js/XmlParse.js b/js/XmlParse.js deleted file mode 100644 index 1f867e5..0000000 --- a/js/XmlParse.js +++ /dev/null @@ -1,81 +0,0 @@ -// LauncherOSX -// -// Created by Boris Schneiderman. -// Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation and/or -// other materials provided with the distribution. -// 3. Neither the name of the organization nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. - -(function(global) { - - -var init = function() { - var XmlParse = {}; - - XmlParse.preprocess = function(str) { - - if (str && (str.indexOf('version="1.1"') > 0)) { - - console.warn("Replacing XML v1.1 with v1.0 (web browser compatibility)."); - - console.log(str.substr(0, 50)); - - str = str.replace(/(<\?xml[\s\S]+?)version="1.1"([\s\S]+?\?>)/, '$1version="1.0"$2'); - - console.log(str.substr(0, 50)); - } - - return str; - }; - - XmlParse.fromString = function(str, contentType) { - - if (!contentType) contentType = "text/xml"; - - str = XmlParse.preprocess(str); - - var parser = new window.DOMParser; - var dom = parser.parseFromString(str, contentType); - - return dom; - }; - - global.XmlParse = XmlParse; - return XmlParse; -}; - - -if (typeof define == 'function' && typeof define.amd == 'object') { - console.log("RequireJS ... XmlParse"); - - define([], - function () { - return init(); - }); -} else { - console.log("!RequireJS ... XmlParse"); - - //global.XmlParse = - init(); -} - -})(typeof window !== "undefined" ? window : this);