{"version":3,"file":"locations.mjs","sources":["../../../../../node_modules/epubjs/src/locations.js"],"sourcesContent":["import {qs, sprint, locationOf, defer} from \"./utils/core\";\nimport Queue from \"./utils/queue\";\nimport EpubCFI from \"./epubcfi\";\nimport { EVENTS } from \"./utils/constants\";\nimport EventEmitter from \"event-emitter\";\n\n/**\n * Find Locations for a Book\n * @param {Spine} spine\n * @param {request} request\n * @param {number} [pause=100]\n */\nclass Locations {\n\tconstructor(spine, request, pause) {\n\t\tthis.spine = spine;\n\t\tthis.request = request;\n\t\tthis.pause = pause || 100;\n\n\t\tthis.q = new Queue(this);\n\t\tthis.epubcfi = new EpubCFI();\n\n\t\tthis._locations = [];\n\t\tthis._locationsWords = [];\n\t\tthis.total = 0;\n\n\t\tthis.break = 150;\n\n\t\tthis._current = 0;\n\n\t\tthis._wordCounter = 0;\n\n\t\tthis.currentLocation = '';\n\t\tthis._currentCfi ='';\n\t\tthis.processingTimeout = undefined;\n\t}\n\n\t/**\n\t * Load all of sections in the book to generate locations\n\t * @param  {int} chars how many chars to split on\n\t * @return {Promise<Array<string>>} locations\n\t */\n\tgenerate(chars) {\n\n\t\tif (chars) {\n\t\t\tthis.break = chars;\n\t\t}\n\n\t\tthis.q.pause();\n\n\t\tthis.spine.each(function(section) {\n\t\t\tif (section.linear) {\n\t\t\t\tthis.q.enqueue(this.process.bind(this), section);\n\t\t\t}\n\t\t}.bind(this));\n\n\t\treturn this.q.run().then(function() {\n\t\t\tthis.total = this._locations.length - 1;\n\n\t\t\tif (this._currentCfi) {\n\t\t\t\tthis.currentLocation = this._currentCfi;\n\t\t\t}\n\n\t\t\treturn this._locations;\n\t\t\t// console.log(this.percentage(this.book.rendition.location.start), this.percentage(this.book.rendition.location.end));\n\t\t}.bind(this));\n\n\t}\n\n\tcreateRange () {\n\t\treturn {\n\t\t\tstartContainer: undefined,\n\t\t\tstartOffset: undefined,\n\t\t\tendContainer: undefined,\n\t\t\tendOffset: undefined\n\t\t};\n\t}\n\n\tprocess(section) {\n\n\t\treturn section.load(this.request)\n\t\t\t.then(function(contents) {\n\t\t\t\tvar completed = new defer();\n\t\t\t\tvar locations = this.parse(contents, section.cfiBase);\n\t\t\t\tthis._locations = this._locations.concat(locations);\n\n\t\t\t\tsection.unload();\n\n\t\t\t\tthis.processingTimeout = setTimeout(() => completed.resolve(locations), this.pause);\n\t\t\t\treturn completed.promise;\n\t\t\t}.bind(this));\n\n\t}\n\n\tparse(contents, cfiBase, chars) {\n\t\tvar locations = [];\n\t\tvar range;\n\t\tvar doc = contents.ownerDocument;\n\t\tvar body = qs(doc, \"body\");\n\t\tvar counter = 0;\n\t\tvar prev;\n\t\tvar _break = chars || this.break;\n\t\tvar parser = function(node) {\n\t\t\tvar len = node.length;\n\t\t\tvar dist;\n\t\t\tvar pos = 0;\n\n\t\t\tif (node.textContent.trim().length === 0) {\n\t\t\t\treturn false; // continue\n\t\t\t}\n\n\t\t\t// Start range\n\t\t\tif (counter == 0) {\n\t\t\t\trange = this.createRange();\n\t\t\t\trange.startContainer = node;\n\t\t\t\trange.startOffset = 0;\n\t\t\t}\n\n\t\t\tdist = _break - counter;\n\n\t\t\t// Node is smaller than a break,\n\t\t\t// skip over it\n\t\t\tif(dist > len){\n\t\t\t\tcounter += len;\n\t\t\t\tpos = len;\n\t\t\t}\n\n\n\t\t\twhile (pos < len) {\n\t\t\t\tdist = _break - counter;\n\n\t\t\t\tif (counter === 0) {\n\t\t\t\t\t// Start new range\n\t\t\t\t\tpos += 1;\n\t\t\t\t\trange = this.createRange();\n\t\t\t\t\trange.startContainer = node;\n\t\t\t\t\trange.startOffset = pos;\n\t\t\t\t}\n\n\t\t\t\t// pos += dist;\n\n\t\t\t\t// Gone over\n\t\t\t\tif(pos + dist >= len){\n\t\t\t\t\t// Continue counter for next node\n\t\t\t\t\tcounter += len - pos;\n\t\t\t\t\t// break\n\t\t\t\t\tpos = len;\n\t\t\t\t// At End\n\t\t\t\t} else {\n\t\t\t\t\t// Advance pos\n\t\t\t\t\tpos += dist;\n\n\t\t\t\t\t// End the previous range\n\t\t\t\t\trange.endContainer = node;\n\t\t\t\t\trange.endOffset = pos;\n\t\t\t\t\t// cfi = section.cfiFromRange(range);\n\t\t\t\t\tlet cfi = new EpubCFI(range, cfiBase).toString();\n\t\t\t\t\tlocations.push(cfi);\n\t\t\t\t\tcounter = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\tprev = node;\n\t\t};\n\n\t\tsprint(body, parser.bind(this));\n\n\t\t// Close remaining\n\t\tif (range && range.startContainer && prev) {\n\t\t\trange.endContainer = prev;\n\t\t\trange.endOffset = prev.length;\n\t\t\tlet cfi = new EpubCFI(range, cfiBase).toString();\n\t\t\tlocations.push(cfi);\n\t\t\tcounter = 0;\n\t\t}\n\n\t\treturn locations;\n\t}\n\n\n\t/**\n\t * Load all of sections in the book to generate locations\n\t * @param  {string} startCfi start position\n\t * @param  {int} wordCount how many words to split on\n\t * @param  {int} count result count\n\t * @return {object} locations\n\t */\n\tgenerateFromWords(startCfi, wordCount, count) {\n\t\tvar start = startCfi ? new EpubCFI(startCfi) : undefined;\n\t\tthis.q.pause();\n\t\tthis._locationsWords = [];\n\t\tthis._wordCounter = 0;\n\n\t\tthis.spine.each(function(section) {\n\t\t\tif (section.linear) {\n\t\t\t\tif (start) {\n\t\t\t\t\tif (section.index >= start.spinePos) {\n\t\t\t\t\t\tthis.q.enqueue(this.processWords.bind(this), section, wordCount, start, count);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthis.q.enqueue(this.processWords.bind(this), section, wordCount, start, count);\n\t\t\t\t}\n\t\t\t}\n\t\t}.bind(this));\n\n\t\treturn this.q.run().then(function() {\n\t\t\tif (this._currentCfi) {\n\t\t\t\tthis.currentLocation = this._currentCfi;\n\t\t\t}\n\n\t\t\treturn this._locationsWords;\n\t\t}.bind(this));\n\n\t}\n\n\tprocessWords(section, wordCount, startCfi, count) {\n\t\tif (count && this._locationsWords.length >= count) {\n\t\t\treturn Promise.resolve();\n\t\t}\n\n\t\treturn section.load(this.request)\n\t\t\t.then(function(contents) {\n\t\t\t\tvar completed = new defer();\n\t\t\t\tvar locations = this.parseWords(contents, section, wordCount, startCfi);\n\t\t\t\tvar remainingCount = count - this._locationsWords.length;\n\t\t\t\tthis._locationsWords = this._locationsWords.concat(locations.length >= count ? locations.slice(0, remainingCount) : locations);\n\n\t\t\t\tsection.unload();\n\n\t\t\t\tthis.processingTimeout = setTimeout(() => completed.resolve(locations), this.pause);\n\t\t\t\treturn completed.promise;\n\t\t\t}.bind(this));\n\t}\n\n\t//http://stackoverflow.com/questions/18679576/counting-words-in-string\n\tcountWords(s) {\n\t\ts = s.replace(/(^\\s*)|(\\s*$)/gi, \"\");//exclude  start and end white-space\n\t\ts = s.replace(/[ ]{2,}/gi, \" \");//2 or more space to 1\n\t\ts = s.replace(/\\n /, \"\\n\"); // exclude newline with a start spacing\n\t\treturn s.split(\" \").length;\n\t}\n\n\tparseWords(contents, section, wordCount, startCfi) {\n\t\tvar cfiBase = section.cfiBase;\n\t\tvar locations = [];\n\t\tvar doc = contents.ownerDocument;\n\t\tvar body = qs(doc, \"body\");\n\t\tvar prev;\n\t\tvar _break = wordCount;\n\t\tvar foundStartNode = startCfi ? startCfi.spinePos !== section.index : true;\n\t\tvar startNode;\n\t\tif (startCfi && section.index === startCfi.spinePos) {\n\t\t\tstartNode = startCfi.findNode(startCfi.range ? startCfi.path.steps.concat(startCfi.start.steps) : startCfi.path.steps, contents.ownerDocument);\n\t\t}\n\t\tvar parser = function(node) {\n\t\t\tif (!foundStartNode) {\n\t\t\t\tif (node === startNode) {\n\t\t\t\t\tfoundStartNode = true;\n\t\t\t\t} else {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (node.textContent.length < 10) {\n\t\t\t\tif (node.textContent.trim().length === 0) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar len  = this.countWords(node.textContent);\n\t\t\tvar dist;\n\t\t\tvar pos = 0;\n\n\t\t\tif (len === 0) {\n\t\t\t\treturn false; // continue\n\t\t\t}\n\n\t\t\tdist = _break - this._wordCounter;\n\n\t\t\t// Node is smaller than a break,\n\t\t\t// skip over it\n\t\t\tif (dist > len) {\n\t\t\t\tthis._wordCounter += len;\n\t\t\t\tpos = len;\n\t\t\t}\n\n\n\t\t\twhile (pos < len) {\n\t\t\t\tdist = _break - this._wordCounter;\n\n\t\t\t\t// Gone over\n\t\t\t\tif (pos + dist >= len) {\n\t\t\t\t\t// Continue counter for next node\n\t\t\t\t\tthis._wordCounter += len - pos;\n\t\t\t\t\t// break\n\t\t\t\t\tpos = len;\n\t\t\t\t\t// At End\n\t\t\t\t} else {\n\t\t\t\t\t// Advance pos\n\t\t\t\t\tpos += dist;\n\n\t\t\t\t\tlet cfi = new EpubCFI(node, cfiBase);\n\t\t\t\t\tlocations.push({ cfi: cfi.toString(), wordCount: this._wordCounter });\n\t\t\t\t\tthis._wordCounter = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\tprev = node;\n\t\t};\n\n\t\tsprint(body, parser.bind(this));\n\n\t\treturn locations;\n\t}\n\n\t/**\n\t * Get a location from an EpubCFI\n\t * @param {EpubCFI} cfi\n\t * @return {number}\n\t */\n\tlocationFromCfi(cfi){\n\t\tlet loc;\n\t\tif (EpubCFI.prototype.isCfiString(cfi)) {\n\t\t\tcfi = new EpubCFI(cfi);\n\t\t}\n\t\t// Check if the location has not been set yet\n\t\tif(this._locations.length === 0) {\n\t\t\treturn -1;\n\t\t}\n\n\t\tloc = locationOf(cfi, this._locations, this.epubcfi.compare);\n\n\t\tif (loc > this.total) {\n\t\t\treturn this.total;\n\t\t}\n\n\t\treturn loc;\n\t}\n\n\t/**\n\t * Get a percentage position in locations from an EpubCFI\n\t * @param {EpubCFI} cfi\n\t * @return {number}\n\t */\n\tpercentageFromCfi(cfi) {\n\t\tif(this._locations.length === 0) {\n\t\t\treturn null;\n\t\t}\n\t\t// Find closest cfi\n\t\tvar loc = this.locationFromCfi(cfi);\n\t\t// Get percentage in total\n\t\treturn this.percentageFromLocation(loc);\n\t}\n\n\t/**\n\t * Get a percentage position from a location index\n\t * @param {number} location\n\t * @return {number}\n\t */\n\tpercentageFromLocation(loc) {\n\t\tif (!loc || !this.total) {\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn (loc / this.total);\n\t}\n\n\t/**\n\t * Get an EpubCFI from location index\n\t * @param {number} loc\n\t * @return {EpubCFI} cfi\n\t */\n\tcfiFromLocation(loc){\n\t\tvar cfi = -1;\n\t\t// check that pg is an int\n\t\tif(typeof loc != \"number\"){\n\t\t\tloc = parseInt(loc);\n\t\t}\n\n\t\tif(loc >= 0 && loc < this._locations.length) {\n\t\t\tcfi = this._locations[loc];\n\t\t}\n\n\t\treturn cfi;\n\t}\n\n\t/**\n\t * Get an EpubCFI from location percentage\n\t * @param {number} percentage\n\t * @return {EpubCFI} cfi\n\t */\n\tcfiFromPercentage(percentage){\n\t\tlet loc;\n\t\tif (percentage > 1) {\n\t\t\tconsole.warn(\"Normalize cfiFromPercentage value to between 0 - 1\");\n\t\t}\n\n\t\t// Make sure 1 goes to very end\n\t\tif (percentage >= 1) {\n\t\t\tlet cfi = new EpubCFI(this._locations[this.total]);\n\t\t\tcfi.collapse();\n\t\t\treturn cfi.toString();\n\t\t}\n\n\t\tloc = Math.ceil(this.total * percentage);\n\t\treturn this.cfiFromLocation(loc);\n\t}\n\n\t/**\n\t * Load locations from JSON\n\t * @param {json} locations\n\t */\n\tload(locations){\n\t\tif (typeof locations === \"string\") {\n\t\t\tthis._locations = JSON.parse(locations);\n\t\t} else {\n\t\t\tthis._locations = locations;\n\t\t}\n\t\tthis.total = this._locations.length - 1;\n\t\treturn this._locations;\n\t}\n\n\t/**\n\t * Save locations to JSON\n\t * @return {json}\n\t */\n\tsave(){\n\t\treturn JSON.stringify(this._locations);\n\t}\n\n\tgetCurrent(){\n\t\treturn this._current;\n\t}\n\n\tsetCurrent(curr){\n\t\tvar loc;\n\n\t\tif(typeof curr == \"string\"){\n\t\t\tthis._currentCfi = curr;\n\t\t} else if (typeof curr == \"number\") {\n\t\t\tthis._current = curr;\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\tif(this._locations.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tif(typeof curr == \"string\"){\n\t\t\tloc = this.locationFromCfi(curr);\n\t\t\tthis._current = loc;\n\t\t} else {\n\t\t\tloc = curr;\n\t\t}\n\n\t\tthis.emit(EVENTS.LOCATIONS.CHANGED, {\n\t\t\tpercentage: this.percentageFromLocation(loc)\n\t\t});\n\t}\n\n\t/**\n\t * Get the current location\n\t */\n\tget currentLocation() {\n\t\treturn this._current;\n\t}\n\n\t/**\n\t * Set the current location\n\t */\n\tset currentLocation(curr) {\n\t\tthis.setCurrent(curr);\n\t}\n\n\t/**\n\t * Locations length\n\t */\n\tlength () {\n\t\treturn this._locations.length;\n\t}\n\n\tdestroy () {\n\t\tthis.spine = undefined;\n\t\tthis.request = undefined;\n\t\tthis.pause = undefined;\n\n\t\tthis.q.stop();\n\t\tthis.q = undefined;\n\t\tthis.epubcfi = undefined;\n\n\t\tthis._locations = undefined\n\t\tthis.total = undefined;\n\n\t\tthis.break = undefined;\n\t\tthis._current = undefined;\n\n\t\tthis.currentLocation = undefined;\n\t\tthis._currentCfi = undefined;\n\t\tclearTimeout(this.processingTimeout);\n\t}\n}\n\nEventEmitter(Locations.prototype);\n\nexport default Locations;\n"],"names":["Locations","spine","request","pause","Queue","EpubCFI","chars","section","contents","completed","defer","locations","cfiBase","range","doc","body","qs","counter","prev","_break","parser","node","len","dist","pos","cfi","sprint","startCfi","wordCount","count","start","remainingCount","s","foundStartNode","startNode","loc","locationOf","percentage","curr","EVENTS","EventEmitter"],"mappings":"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","x_google_ignoreList":[0]}