UNPKG

r2-navigator-js

Version:

Readium 2 'navigator' for NodeJS (TypeScript)

325 lines 16.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EpubCfiResolver = void 0; const ArrayUtils_js_1 = require("../common/ArrayUtils.js"); const DomUtils_js_1 = require("../common/DomUtils.js"); const Utils_js_1 = require("../common/Utils.js"); const EpubCfiParser_js_1 = require("../parser/EpubCfiParser.js"); const EpubCfiIntendedTargetType_js_1 = require("./EpubCfiIntendedTargetType.js"); const EpubCfiLocalPathResolver_js_1 = require("./EpubCfiLocalPathResolver.js"); const EpubCfiPathType_js_1 = require("./EpubCfiPathType.js"); const EpubCfiResolvedLocalPath_js_1 = require("./EpubCfiResolvedLocalPath.js"); const EpubCfiResolvedPath_js_1 = require("./EpubCfiResolvedPath.js"); const EpubCfiResolvedTarget_js_1 = require("./EpubCfiResolvedTarget.js"); const EpubCfiResolverErrorType_js_1 = require("./EpubCfiResolverErrorType.js"); const EpubCfiSideBias_js_1 = require("./EpubCfiSideBias.js"); const EpubCfiOffsetProcessor_js_1 = require("./offset/EpubCfiOffsetProcessor.js"); class EpubCfiResolver { constructor(epubCfi) { this._lastIndirectionElement = null; this._offsetProcessor = new EpubCfiOffsetProcessor_js_1.EpubCfiOffsetProcessor(); this._parentLocalPathIndex = 0; this._parentOffsetHandled = false; this._rangeEndLocalPathIndex = 0; this._rangeEndOffsetHandled = false; this._rangeStartLocalPathIndex = 0; this._rangeStartOffsetHandled = false; let rootNode = (0, Utils_js_1.isString)(epubCfi) ? EpubCfiParser_js_1.EpubCfiParser.parse(epubCfi) : epubCfi; this._rootNode = rootNode; this._parentPathNode = rootNode.parentPath; this._rangeStartPathNode = rootNode.rangeStartPath; this._rangeEndPathNode = rootNode.rangeEndPath; this._resolvedTarget = new EpubCfiResolvedTarget_js_1.EpubCfiResolvedTarget(rootNode); } continueResolving(targetNode, documentUrl) { var _a; let targetElement = null; if ((0, Utils_js_1.isDocument)(targetNode)) { targetElement = targetNode.documentElement; } else if ((0, Utils_js_1.isDocumentFragment)(targetNode) && (0, Utils_js_1.isElement)(targetNode.firstChild)) { targetElement = targetNode.firstChild; } else if ((0, Utils_js_1.isElement)(targetNode) && targetNode.parentNode) { targetElement = targetNode; } if (!targetElement) { this._resolvedTarget.indirectionErrors.push({ from: this._lastIndirectionElement, fromPath: ((_a = this.getNextIndirectionResult()) === null || _a === void 0 ? void 0 : _a.documentUrl) || null, target: targetElement, targetPath: documentUrl, }); return null; } if (this._parentPathNode) { const resolvedPath = this.resolveNextLocalPathFromStartElement(EpubCfiPathType_js_1.EpubCfiPathType.PARENT, targetElement, documentUrl); this.continueResolvingFromParentPath(resolvedPath, documentUrl); } else if (this._rangeStartPathNode) { const resolvedPath = this.resolveNextLocalPathFromStartElement(EpubCfiPathType_js_1.EpubCfiPathType.RANGE_START, targetElement, documentUrl); this.continueResolvingRangeStartPath(resolvedPath, documentUrl); } else if (this._rangeEndPathNode) { const resolvedPath = this.resolveNextLocalPathFromStartElement(EpubCfiPathType_js_1.EpubCfiPathType.RANGE_END, targetElement, documentUrl); this.continueResolvingRangeEndPath(resolvedPath, documentUrl); } const indirectionResult = this.getNextIndirectionResult(); this.maybeProcessOffsetsAndSideBias(); return indirectionResult; } getResolvedTarget() { return this._resolvedTarget; } skipNextIndirection() { this.handleUnresolvableIndirection(); const result = this.getNextIndirectionResult(); this.maybeProcessOffsetsAndSideBias(); return result; } addResolvedLocalPath(pathType, localPath) { let resolvedPath = this.getResolvedPathFromType(pathType); if (resolvedPath) { resolvedPath.addResolvedLocalPath(localPath); resolvedPath.indirectionsResolved = true; } else { switch (pathType) { case EpubCfiPathType_js_1.EpubCfiPathType.PARENT: resolvedPath = this._resolvedTarget.parentPath = new EpubCfiResolvedPath_js_1.EpubCfiResolvedPath(this._rootNode.parentPath, localPath); break; case EpubCfiPathType_js_1.EpubCfiPathType.RANGE_START: resolvedPath = this._resolvedTarget.rangeStartPath = new EpubCfiResolvedPath_js_1.EpubCfiResolvedPath(this._rootNode.rangeStartPath, localPath); break; case EpubCfiPathType_js_1.EpubCfiPathType.RANGE_END: resolvedPath = this._resolvedTarget.rangeEndPath = new EpubCfiResolvedPath_js_1.EpubCfiResolvedPath(this._rootNode.rangeEndPath, localPath); break; default: throw new Error(EpubCfiResolverErrorType_js_1.EpubCfiResolverErrorType.INVALID_PATH_TYPE); } } return resolvedPath; } consumeNextLocalPath(pathType) { let result = null; switch (pathType) { case EpubCfiPathType_js_1.EpubCfiPathType.PARENT: if (this._parentPathNode) { result = this.getLocalPathByIndex(this._parentPathNode, this._parentLocalPathIndex++); if (!this.getLocalPathByIndex(this._parentPathNode, this._parentLocalPathIndex)) { this._parentPathNode = null; } } break; case EpubCfiPathType_js_1.EpubCfiPathType.RANGE_START: if (this._rangeStartPathNode) { result = this.getLocalPathByIndex(this._rangeStartPathNode, this._rangeStartLocalPathIndex++); if (!this.getLocalPathByIndex(this._rangeStartPathNode, this._rangeStartLocalPathIndex)) { this._rangeStartPathNode = null; } } break; case EpubCfiPathType_js_1.EpubCfiPathType.RANGE_END: if (this._rangeEndPathNode) { result = this.getLocalPathByIndex(this._rangeEndPathNode, this._rangeEndLocalPathIndex++); if (!this.getLocalPathByIndex(this._rangeEndPathNode, this._rangeEndLocalPathIndex)) { this._rangeEndPathNode = null; } } break; } return result; } continueResolvingFromParentPath(resolvedParentPath, documentUrl) { while (this._parentPathNode) { if (this.hasNextLocalPathIndirection(EpubCfiPathType_js_1.EpubCfiPathType.PARENT)) { if (this._resolvedTarget.parentPath) { this._resolvedTarget.parentPath.indirectionsResolved = false; } return; } this.resolveNextLocalPathFromResolvedPath(EpubCfiPathType_js_1.EpubCfiPathType.PARENT, resolvedParentPath, documentUrl); } this.continueResolvingRangeStartPath(resolvedParentPath, documentUrl); this.continueResolvingRangeEndPath(resolvedParentPath, documentUrl); } continueResolvingRangeEndPath(resolvedPath, documentUrl) { while (this._rangeEndPathNode) { if (this.hasNextLocalPathIndirection(EpubCfiPathType_js_1.EpubCfiPathType.RANGE_END)) { if (this._resolvedTarget.rangeEndPath) { this._resolvedTarget.rangeEndPath.indirectionsResolved = false; } return; } resolvedPath = this.resolveNextLocalPathFromResolvedPath(EpubCfiPathType_js_1.EpubCfiPathType.RANGE_END, resolvedPath, documentUrl); } } continueResolvingRangeStartPath(resolvedPath, documentUrl) { while (this._rangeStartPathNode) { if (this.hasNextLocalPathIndirection(EpubCfiPathType_js_1.EpubCfiPathType.RANGE_START)) { if (this._resolvedTarget.rangeStartPath) { this._resolvedTarget.rangeStartPath.indirectionsResolved = false; } return; } resolvedPath = this.resolveNextLocalPathFromResolvedPath(EpubCfiPathType_js_1.EpubCfiPathType.RANGE_START, resolvedPath, documentUrl); } } getLocalPathByIndex(pathNode, index) { return index < pathNode.localPaths.length ? pathNode.localPaths[index] : null; } getNextIndirectionResult() { let resolvedPath = null; let result = null; if (this.hasNextLocalPathIndirection(EpubCfiPathType_js_1.EpubCfiPathType.PARENT)) { resolvedPath = this._resolvedTarget.parentPath; } else if (this.hasNextLocalPathIndirection(EpubCfiPathType_js_1.EpubCfiPathType.RANGE_START)) { resolvedPath = this._resolvedTarget.rangeStartPath || this._resolvedTarget.parentPath; } else if (this.hasNextLocalPathIndirection(EpubCfiPathType_js_1.EpubCfiPathType.RANGE_END)) { resolvedPath = this._resolvedTarget.rangeEndPath || this._resolvedTarget.parentPath; } if (resolvedPath) { const targetElement = resolvedPath.getTargetElement(); if (targetElement) { result = { documentUrl: resolvedPath.documentUrl, element: targetElement, }; } else { this._resolvedTarget.indirectionErrors.push({ from: resolvedPath.getTargetNode(), fromPath: resolvedPath.documentUrl, target: null, targetPath: null, }); this.handleUnresolvableIndirection(); result = this.getNextIndirectionResult(); } } return result; } getResolvedPathFromType(type) { switch (type) { case EpubCfiPathType_js_1.EpubCfiPathType.PARENT: return this._resolvedTarget.parentPath; case EpubCfiPathType_js_1.EpubCfiPathType.RANGE_END: return this._resolvedTarget.rangeEndPath; case EpubCfiPathType_js_1.EpubCfiPathType.RANGE_START: return this._resolvedTarget.rangeStartPath; } } handleSideBiasParameter(path) { let terminalAssertion = null; if (path.ast.offset && path.ast.offset.assertion) { terminalAssertion = path.ast.offset.assertion; } else { let terminalLocalPath = path.getTerminalLocalPath(); if (terminalLocalPath.ast) { let lastStep = ArrayUtils_js_1.ArrayUtils.last(terminalLocalPath.ast.steps); if (lastStep) { terminalAssertion = lastStep.assertion; } } } if (terminalAssertion) { let sideBiasParameter = terminalAssertion.parameters.find(param => param.name === 's' && param.values.length > 0); if (sideBiasParameter) { path.sideBias = sideBiasParameter.values[0] === 'b' ? EpubCfiSideBias_js_1.EpubCfiSideBias.BEFORE : EpubCfiSideBias_js_1.EpubCfiSideBias.AFTER; } } } handleUnresolvableIndirection() { if (this._parentPathNode) { this._parentPathNode = null; this._rangeStartPathNode = null; this._rangeEndPathNode = null; if (this._resolvedTarget.parentPath) { this._resolvedTarget.parentPath.indirectionsResolved = false; this._resolvedTarget.parentPath.stepsResolved = false; } } else if (this._rangeStartPathNode) { this._rangeStartPathNode = null; if (this._resolvedTarget.rangeStartPath) { this._resolvedTarget.rangeStartPath.indirectionsResolved = false; this._resolvedTarget.rangeStartPath.stepsResolved = false; } } else if (this._rangeEndPathNode) { this._rangeEndPathNode = null; if (this._resolvedTarget.rangeEndPath) { this._resolvedTarget.rangeEndPath.indirectionsResolved = false; this._resolvedTarget.rangeEndPath.stepsResolved = false; } } } hasNextLocalPathIndirection(pathType) { let result = false; switch (pathType) { case EpubCfiPathType_js_1.EpubCfiPathType.PARENT: if (this._parentPathNode) { const nextLocalPath = this.getLocalPathByIndex(this._parentPathNode, this._parentLocalPathIndex); result = nextLocalPath !== null && nextLocalPath.indirection; } break; case EpubCfiPathType_js_1.EpubCfiPathType.RANGE_START: if (this._rangeStartPathNode) { const nextLocalPath = this.getLocalPathByIndex(this._rangeStartPathNode, this._rangeStartLocalPathIndex); result = nextLocalPath !== null && nextLocalPath.indirection; } break; case EpubCfiPathType_js_1.EpubCfiPathType.RANGE_END: if (this._rangeEndPathNode) { const nextLocalPath = this.getLocalPathByIndex(this._rangeEndPathNode, this._rangeEndLocalPathIndex); result = nextLocalPath !== null && nextLocalPath.indirection; } break; } return result; } maybeProcessOffsetsAndSideBias() { if (this._resolvedTarget.parentPath && !this._parentPathNode && !this._parentOffsetHandled) { this._offsetProcessor.processOffset(this._resolvedTarget.parentPath); this.handleSideBiasParameter(this._resolvedTarget.parentPath); this._parentOffsetHandled = true; } if (this._resolvedTarget.rangeStartPath && !this._rangeStartPathNode && !this._rangeStartOffsetHandled) { this._offsetProcessor.processOffset(this._resolvedTarget.rangeStartPath); this.handleSideBiasParameter(this._resolvedTarget.rangeStartPath); this._rangeStartOffsetHandled = true; } if (this._resolvedTarget.rangeEndPath && !this._rangeEndPathNode && !this._rangeEndOffsetHandled) { this._offsetProcessor.processOffset(this._resolvedTarget.rangeEndPath); this.handleSideBiasParameter(this._resolvedTarget.rangeEndPath); this._rangeStartOffsetHandled = true; } } resolveNextLocalPathFromResolvedPath(pathType, existingResolvedPath, documentUrl) { const nextLocalPath = this.consumeNextLocalPath(pathType); let resolvedLocalPath; if (nextLocalPath) { resolvedLocalPath = EpubCfiLocalPathResolver_js_1.EpubCfiLocalPathResolver.createResolverFromExistingPath(nextLocalPath, existingResolvedPath).resolve(); } else { resolvedLocalPath = new EpubCfiResolvedLocalPath_js_1.EpubCfiResolvedLocalPath(null, documentUrl, existingResolvedPath.container, existingResolvedPath.offset, existingResolvedPath.intendedTargetType, existingResolvedPath.virtualTarget); } return this.addResolvedLocalPath(pathType, resolvedLocalPath); } resolveNextLocalPathFromStartElement(pathType, startElement, documentUrl) { const nextLocalPath = this.consumeNextLocalPath(pathType); let resolvedLocalPath; if (nextLocalPath) { resolvedLocalPath = EpubCfiLocalPathResolver_js_1.EpubCfiLocalPathResolver.createResolverFromElement(nextLocalPath, startElement, documentUrl).resolve(); } else { resolvedLocalPath = new EpubCfiResolvedLocalPath_js_1.EpubCfiResolvedLocalPath(null, documentUrl, startElement.parentNode, DomUtils_js_1.DomUtils.getNodeIndex(startElement), EpubCfiIntendedTargetType_js_1.EpubCfiIntendedTargetType.ELEMENT, null); } return this.addResolvedLocalPath(pathType, resolvedLocalPath); } } exports.EpubCfiResolver = EpubCfiResolver; //# sourceMappingURL=EpubCfiResolver.js.map