From 3603c89bedc886e6594274a3728e47f5db92982f Mon Sep 17 00:00:00 2001 From: Aferdita Muriqi Date: Sat, 25 Mar 2023 00:03:50 -0400 Subject: [PATCH 1/4] refactored order of module init vs navigator --- package-lock.json | 4 +- package.json | 2 +- src/model/user-settings/UserSettings.ts | 6 +- src/modules/AnnotationModule.ts | 104 ++++----- src/modules/BookmarkModule.ts | 140 ++++++------ src/modules/TTS/TTSModule2.ts | 83 ++++--- src/modules/TTS/TTSSettings.ts | 1 - src/modules/citation/CitationModule.ts | 11 +- src/modules/consumption/ConsumptionModule.ts | 45 +++- src/modules/highlight/TextHighlighter.ts | 206 ++++++++--------- src/modules/history/HistoryModule.ts | 22 +- src/modules/linefocus/LineFocusModule.ts | 62 ++--- .../mediaoverlays/MediaOverlayModule.ts | 37 ++- src/modules/pagebreak/PageBreakModule.ts | 32 ++- src/modules/positions/TimelineModule.ts | 22 +- .../protection/ContentProtectionModule.ts | 172 +++++++------- .../sampleread/SampleReadEventHandler.ts | 37 +-- src/modules/search/DefinitionsModule.ts | 31 ++- src/modules/search/SearchModule.ts | 68 +++--- src/navigator/IFrameNavigator.ts | 216 ++++++++++++------ src/reader.ts | 76 +++--- src/views/BookView.ts | 2 +- src/views/FixedBookView.ts | 2 +- src/views/ReflowableBookView.ts | 26 +-- 24 files changed, 719 insertions(+), 688 deletions(-) diff --git a/package-lock.json b/package-lock.json index 515d46ee..1ec68cd5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@d-i-t-a/reader", - "version": "2.2.2", + "version": "2.3.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@d-i-t-a/reader", - "version": "2.2.2", + "version": "2.3.0", "license": "Apache-2.0", "dependencies": { "@types/pdfjs-dist": "^2.7.4", diff --git a/package.json b/package.json index b4993807..d171efa1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@d-i-t-a/reader", - "version": "2.2.2", + "version": "2.3.0", "description": "A viewer application for EPUB files.", "repository": "https://github.com/d-i-t-a/R2D2BC", "license": "Apache-2.0", diff --git a/src/model/user-settings/UserSettings.ts b/src/model/user-settings/UserSettings.ts index 0d9a9566..3d72af04 100644 --- a/src/model/user-settings/UserSettings.ts +++ b/src/model/user-settings/UserSettings.ts @@ -470,7 +470,7 @@ export class UserSettings implements IUserSettings { if (html) { const rootElement = document.documentElement; const body = HTMLUtilities.findRequiredElement(rootElement, "body"); - if (this.view?.delegate.publication.isReflowable) { + if (this.view?.navigator.publication.isReflowable) { // Apply font size if (await this.getProperty(ReadiumCSS.FONT_SIZE_KEY)) { html.style.setProperty( @@ -516,7 +516,7 @@ export class UserSettings implements IUserSettings { ?.toString() ?? null ); } - if (this.view?.delegate.publication.isReflowable) { + if (this.view?.navigator.publication.isReflowable) { // Apply text alignment if (await this.getProperty(ReadiumCSS.TEXT_ALIGNMENT_KEY)) { if ( @@ -601,7 +601,7 @@ export class UserSettings implements IUserSettings { HTMLUtilities.setAttr(rootElement, "data-viewer-theme", "day"); HTMLUtilities.setAttr(body, "data-viewer-theme", "day"); } - if (this.view?.delegate.publication.isReflowable) { + if (this.view?.navigator.publication.isReflowable) { // Apply font family if (await this.getProperty(ReadiumCSS.FONT_FAMILY_KEY)) { html.style.setProperty( diff --git a/src/modules/AnnotationModule.ts b/src/modules/AnnotationModule.ts index abe358a6..dfabe0f3 100644 --- a/src/modules/AnnotationModule.ts +++ b/src/modules/AnnotationModule.ts @@ -69,7 +69,6 @@ export interface AnnotationModuleConfig extends AnnotationModuleProperties { headerMenu?: HTMLElement | null; rights: Partial; publication: Publication; - delegate: IFrameNavigator; initialAnnotations?: any; api?: AnnotationModuleAPI; highlighter: TextHighlighter; @@ -84,7 +83,7 @@ export class AnnotationModule implements ReaderModule { private readonly headerMenu?: HTMLElement | null; private readonly highlighter?: TextHighlighter; private readonly initialAnnotations: any; - private delegate: IFrameNavigator; + navigator: IFrameNavigator; properties?: AnnotationModuleProperties; api?: AnnotationModuleAPI; activeAnnotationMarkerId?: string; @@ -95,7 +94,6 @@ export class AnnotationModule implements ReaderModule { config.annotator, config.rights || { enableAnnotations: false, enableTTS: false }, config.publication, - config.delegate, config.initialAnnotations || null, config as AnnotationModuleProperties, config.highlighter, @@ -110,7 +108,6 @@ export class AnnotationModule implements ReaderModule { annotator: Annotator, rights: Partial, publication: Publication, - delegate: IFrameNavigator, initialAnnotations: any, properties: AnnotationModuleProperties, highlighter: TextHighlighter, @@ -121,7 +118,6 @@ export class AnnotationModule implements ReaderModule { this.rights = rights; this.publication = publication; this.headerMenu = headerMenu; - this.delegate = delegate; this.initialAnnotations = initialAnnotations; this.highlighter = highlighter; this.properties = properties; @@ -133,8 +129,6 @@ export class AnnotationModule implements ReaderModule { } protected async start(): Promise { - this.delegate.annotationModule = this; - if (this.headerMenu) this.highlightsView = HTMLUtilities.findElement( this.headerMenu, @@ -150,8 +144,8 @@ export class AnnotationModule implements ReaderModule { setTimeout(() => { this.properties?.hideLayer - ? this.delegate.hideLayer("highlights") - : this.delegate.showLayer("highlights"); + ? this.navigator.hideLayer("highlights") + : this.navigator.showLayer("highlights"); }, 10); } private hide: HTMLLinkElement = HTMLUtilities.findElement( @@ -164,7 +158,7 @@ export class AnnotationModule implements ReaderModule { ); hideAnnotationLayer() { - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { const container = HTMLUtilities.findElement( doc, @@ -180,7 +174,7 @@ export class AnnotationModule implements ReaderModule { } } showAnnotationLayer() { - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { const container = HTMLUtilities.findElement( doc, @@ -211,7 +205,7 @@ export class AnnotationModule implements ReaderModule { this.drawHighlights(); this.showHighlights(); addEventListenerOptional( - this.delegate.iframes[0].contentDocument?.body, + this.navigator.iframes[0].contentDocument?.body, "click", this.click.bind(this) ); @@ -237,7 +231,7 @@ export class AnnotationModule implements ReaderModule { // menuItem.highlight.color = `#dc491d`; menuItem.highlight.style.default = null; menuItem.highlight.style.hover = null; - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { const selection = this.highlighter?.dom(doc.body).getSelection(); let range = selection.getRangeAt(0); @@ -251,7 +245,7 @@ export class AnnotationModule implements ReaderModule { function getCssSelector(element: Element): string { try { - let doc = self.delegate.iframes[0].contentDocument; + let doc = self.navigator.iframes[0].contentDocument; if (doc) { return uniqueCssSelector(element, doc, _getCssSelectorOptions); } else { @@ -271,8 +265,8 @@ export class AnnotationModule implements ReaderModule { rangeInfo: rangeInfo, }; - let book = this.delegate.highlighter?.createHighlight( - this.delegate.highlighter?.dom(doc.body).getWindow(), + let book = this.navigator.highlighter?.createHighlight( + this.navigator.highlighter?.dom(doc.body).getWindow(), selectionInfo, menuItem.highlight.color, true, @@ -297,7 +291,7 @@ export class AnnotationModule implements ReaderModule { log.log("still need to scroll to " + id); var element = await this.annotator?.getAnnotationElement( id, - this.delegate.iframes[0].contentWindow as any + this.navigator.iframes[0].contentWindow as any ); element.scrollIntoView({ block: "center", @@ -376,21 +370,21 @@ export class AnnotationModule implements ReaderModule { public async saveAnnotation(highlight: IHighlight): Promise { if (this.annotator) { var tocItem = this.publication.getTOCItem( - this.delegate.currentChapterLink.href + this.navigator.currentChapterLink.href ); - if (this.delegate.currentTocUrl) { - tocItem = this.publication.getTOCItem(this.delegate.currentTocUrl); + if (this.navigator.currentTocUrl) { + tocItem = this.publication.getTOCItem(this.navigator.currentTocUrl); } if (tocItem === undefined) { tocItem = this.publication.getTOCItemAbsolute( - this.delegate.currentChapterLink.href + this.navigator.currentChapterLink.href ); } - const bookmarkPosition = this.delegate.view?.getCurrentPosition(); + const bookmarkPosition = this.navigator.view?.getCurrentPosition(); - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { const body = HTMLUtilities.findRequiredIframeElement( doc, @@ -416,7 +410,7 @@ export class AnnotationModule implements ReaderModule { ) { const positions = this.publication.positionsByHref( this.publication.getRelativeHref( - this.delegate.currentChapterLink.href + this.navigator.currentChapterLink.href ) ); const positionIndex = Math.ceil( @@ -429,7 +423,7 @@ export class AnnotationModule implements ReaderModule { id: id, href: href, created: new Date(), - title: this.delegate.currentChapterLink.title, + title: this.navigator.currentChapterLink.title, highlight: highlight, text: { highlight: highlight.selectionInfo.cleanText, @@ -443,8 +437,8 @@ export class AnnotationModule implements ReaderModule { progression: progression, }, created: new Date(), - type: this.delegate.currentChapterLink.type, - title: this.delegate.currentChapterLink.title, + type: this.navigator.currentChapterLink.type, + title: this.navigator.currentChapterLink.title, highlight: highlight, text: { highlight: highlight.selectionInfo.cleanText, @@ -454,7 +448,7 @@ export class AnnotationModule implements ReaderModule { } if (annotation) { - this.delegate.consumptionModule?.trackAction( + this.navigator.consumptionModule?.trackAction( annotation, Action.HighlightCreated ); @@ -518,13 +512,13 @@ export class AnnotationModule implements ReaderModule { let highlights: Array = []; if (this.annotator) { highlights = this.annotator.getAnnotationsByChapter( - this.delegate.currentLocator().href + this.navigator.currentLocator().href ) as Array; } if ( this.highlighter && highlights && - this.delegate.iframes[0].contentDocument?.readyState === "complete" + this.navigator.iframes[0].contentDocument?.readyState === "complete" ) { await this.highlighter.destroyHighlights(HighlightType.Annotation); @@ -533,18 +527,18 @@ export class AnnotationModule implements ReaderModule { const annotation: Annotation = rangeRepresentation; - let currentLocation = this.delegate.currentChapterLink.href; + let currentLocation = this.navigator.currentChapterLink.href; var tocItem = this.publication.getTOCItem(currentLocation); - if (this.delegate.currentTocUrl !== undefined) { + if (this.navigator.currentTocUrl !== undefined) { tocItem = this.publication.getTOCItem( - this.delegate.currentTocUrl + this.navigator.currentTocUrl ); } if (tocItem === null) { tocItem = this.publication.getTOCItemAbsolute( - this.delegate.currentChapterLink.href + this.navigator.currentChapterLink.href ); } if (tocItem) { @@ -555,7 +549,7 @@ export class AnnotationModule implements ReaderModule { if (annotation.href === href) { await this.highlighter.createHighlightDom( - this.delegate.iframes[0].contentWindow as any, + this.navigator.iframes[0].contentWindow as any, rangeRepresentation.highlight ); @@ -565,7 +559,7 @@ export class AnnotationModule implements ReaderModule { ) { const position = await this.annotator?.getAnnotationPosition( rangeRepresentation.id, - this.delegate.iframes[0].contentWindow as any + this.navigator.iframes[0].contentWindow as any ); const commentTemplate = @@ -602,13 +596,13 @@ export class AnnotationModule implements ReaderModule { let highlights: Array = []; if (this.annotator) { highlights = this.annotator.getAnnotationsByChapter( - this.delegate.currentLocator().href + this.navigator.currentLocator().href ) as Array; } if ( this.highlighter && highlights && - this.delegate.iframes[0].contentDocument?.readyState === "complete" + this.navigator.iframes[0].contentDocument?.readyState === "complete" ) { await this.highlighter.destroyHighlights(HighlightType.Annotation); @@ -617,18 +611,18 @@ export class AnnotationModule implements ReaderModule { const annotation: Annotation = rangeRepresentation; - let currentLocation = this.delegate.currentChapterLink.href; + let currentLocation = this.navigator.currentChapterLink.href; let tocItem = this.publication.getTOCItem(currentLocation); - if (this.delegate.currentTocUrl) { + if (this.navigator.currentTocUrl) { tocItem = this.publication.getTOCItem( - this.delegate.currentTocUrl + this.navigator.currentTocUrl ); } if (tocItem === null) { tocItem = this.publication.getTOCItemAbsolute( - this.delegate.currentChapterLink.href + this.navigator.currentChapterLink.href ); } @@ -640,7 +634,7 @@ export class AnnotationModule implements ReaderModule { if (annotation.href === href) { await this.highlighter.createHighlightDom( - this.delegate.iframes[0].contentWindow as any, + this.navigator.iframes[0].contentWindow as any, rangeRepresentation.highlight ); @@ -650,7 +644,7 @@ export class AnnotationModule implements ReaderModule { ) { const position = await this.annotator?.getAnnotationPosition( rangeRepresentation.id, - this.delegate.iframes[0].contentWindow as any + this.navigator.iframes[0].contentWindow as any ); const commentTemplate = @@ -688,13 +682,13 @@ export class AnnotationModule implements ReaderModule { } repositionGutters(): any { - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { this.commentGutter = doc.getElementById( HighlightContainer.R2_ID_GUTTER_RIGHT_CONTAINER ) as HTMLDivElement; if ( - this.delegate.view?.isScrollMode() && + this.navigator.view?.isScrollMode() && this.properties?.enableComments ) { this.commentGutter?.style.removeProperty("display"); @@ -703,7 +697,7 @@ export class AnnotationModule implements ReaderModule { } if ( this.commentGutter && - this.delegate.view?.isScrollMode() && + this.navigator.view?.isScrollMode() && this.properties?.enableComments ) { this.commentGutter.innerHTML = ""; @@ -711,7 +705,7 @@ export class AnnotationModule implements ReaderModule { let highlights: Array = []; if (this.annotator) { highlights = this.annotator.getAnnotationsByChapter( - this.delegate.currentLocator().href + this.navigator.currentLocator().href ) as Array; if (highlights) { highlights = highlights.filter( @@ -849,8 +843,8 @@ export class AnnotationModule implements ReaderModule { title: linkElement.title, }; - this.delegate.stopReadAloud(); - this.delegate.navigate(position); + this.navigator.stopReadAloud(); + this.navigator.navigate(position); } ); @@ -950,7 +944,7 @@ export class AnnotationModule implements ReaderModule { ); bookmarkItem.appendChild(bookmarkLink); - if (self.delegate.sideNavExpanded) { + if (self.navigator.sideNavExpanded) { let bookmarkDeleteLink: HTMLElement = document.createElement( "button" ); @@ -1000,8 +994,8 @@ export class AnnotationModule implements ReaderModule { ): void { if (locator) { locator.href = this.publication.getAbsoluteHref(locator.href); - this.delegate.stopReadAloud(); - this.delegate.navigate(locator); + this.navigator.stopReadAloud(); + this.navigator.navigate(locator); } else { log.log("annotation data missing: ", event); } @@ -1035,7 +1029,7 @@ export class AnnotationModule implements ReaderModule { return this.annotator?.getAnnotationByID(id); } syncPosition(highlights: Array) { - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; const positionAnnotations = (newArray: Array, currentElement: any) => { let container = doc!.getElementById("R2_ID_HIGHLIGHTS_CONTAINER"); @@ -1067,7 +1061,7 @@ export class AnnotationModule implements ReaderModule { } reposition(highlights: Array) { - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; const positionAnnotations = ( newArray: Array, diff --git a/src/modules/BookmarkModule.ts b/src/modules/BookmarkModule.ts index e015ba8c..145dc250 100644 --- a/src/modules/BookmarkModule.ts +++ b/src/modules/BookmarkModule.ts @@ -58,7 +58,6 @@ export interface BookmarkModuleConfig extends BookmarkModuleProperties { headerMenu?: HTMLElement | null; rights: Partial; publication: Publication; - delegate: IFrameNavigator; initialAnnotations?: any; properties?: BookmarkModuleProperties; api?: BookmarkModuleAPI; @@ -72,7 +71,7 @@ export class BookmarkModule implements ReaderModule { private sideNavSectionBookmarks: HTMLElement; private readonly headerMenu?: HTMLElement | null; private readonly initialAnnotations: any; - private delegate: IFrameNavigator; + navigator: IFrameNavigator; // @ts-ignore private readonly properties: BookmarkModuleProperties; private readonly api?: BookmarkModuleAPI; @@ -82,7 +81,6 @@ export class BookmarkModule implements ReaderModule { config.annotator, config.rights || { enableBookmarks: false }, config.publication, - config.delegate, config as BookmarkModuleProperties, config.initialAnnotations, config.api, @@ -96,7 +94,6 @@ export class BookmarkModule implements ReaderModule { annotator: Annotator, rights: Partial, publication: Publication, - delegate: IFrameNavigator, properties: BookmarkModuleProperties, initialAnnotations?: any, api?: BookmarkModuleAPI, @@ -106,7 +103,6 @@ export class BookmarkModule implements ReaderModule { this.rights = rights; this.publication = publication; this.headerMenu = headerMenu; - this.delegate = delegate; this.initialAnnotations = initialAnnotations; this.properties = properties; this.api = api; @@ -117,8 +113,6 @@ export class BookmarkModule implements ReaderModule { } protected async start(): Promise { - this.delegate.bookmarkModule = this; - if (this.headerMenu) this.bookmarksView = HTMLUtilities.findElement( this.headerMenu, @@ -153,19 +147,17 @@ export class BookmarkModule implements ReaderModule { } } - await this.showBookmarks(); - await this.drawBookmarks(); - setTimeout(() => { - this.properties.hideLayer - ? this.delegate.hideLayer("highlights") - : this.delegate.showLayer("highlights"); - }, 10); } async handleResize() { setTimeout(async () => { await this.drawBookmarks(); await this.showBookmarks(); + setTimeout(() => { + this.properties.hideLayer + ? this.navigator.hideLayer("highlights") + : this.navigator.showLayer("highlights"); + }, 10); }, 100); } @@ -211,15 +203,15 @@ export class BookmarkModule implements ReaderModule { async saveBookmark(): Promise { if (this.annotator) { var tocItem = this.publication.getTOCItem( - this.delegate.currentChapterLink.href + this.navigator.currentChapterLink.href ); - if (this.delegate.currentTocUrl) { - tocItem = this.publication.getTOCItem(this.delegate.currentTocUrl); + if (this.navigator.currentTocUrl) { + tocItem = this.publication.getTOCItem(this.navigator.currentTocUrl); } if (tocItem === undefined) { tocItem = this.publication.getTOCItemAbsolute( - this.delegate.currentChapterLink.href + this.navigator.currentChapterLink.href ); } if (tocItem) { @@ -228,7 +220,7 @@ export class BookmarkModule implements ReaderModule { href = href.slice(0, href.indexOf("#")); } - const progression = this.delegate.view?.getCurrentPosition(); + const progression = this.navigator.view?.getCurrentPosition(); const id: string = uuid(); let bookmark: Bookmark; if ( @@ -237,7 +229,7 @@ export class BookmarkModule implements ReaderModule { ) { const positions = this.publication.positionsByHref( this.publication.getRelativeHref( - this.delegate.currentChapterLink.href + this.navigator.currentChapterLink.href ) ); @@ -251,7 +243,7 @@ export class BookmarkModule implements ReaderModule { id: id, href: href, created: new Date(), - title: this.delegate.currentChapterLink.title, + title: this.navigator.currentChapterLink.title, }; } else { bookmark = { @@ -261,12 +253,12 @@ export class BookmarkModule implements ReaderModule { progression: progression, }, created: new Date(), - type: this.delegate.currentChapterLink.type, - title: this.delegate.currentChapterLink.title, + type: this.navigator.currentChapterLink.type, + title: this.navigator.currentChapterLink.title, }; } if (!this.annotator.locatorExists(bookmark, AnnotationType.Bookmark)) { - this.delegate.consumptionModule?.trackAction( + this.navigator.consumptionModule?.trackAction( bookmark, Action.BookmarkCreated ); @@ -298,16 +290,16 @@ export class BookmarkModule implements ReaderModule { private async addBookmarkPlus(): Promise { let self = this; - let node = this.delegate.highlighter?.visibleTextRects[0]; - let doc = this.delegate.iframes[0].contentDocument; + let node = this.navigator.highlighter?.visibleTextRects[0]; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { - const range = this.delegate.highlighter + const range = this.navigator.highlighter ?.dom(doc.body) .getWindow() .document.createRange(); - const selection = this.delegate.highlighter - ?.dom(this.delegate.iframes[0].contentDocument?.body) + const selection = this.navigator.highlighter + ?.dom(this.navigator.iframes[0].contentDocument?.body) .getSelection(); selection.removeAllRanges(); if (node) { @@ -319,7 +311,7 @@ export class BookmarkModule implements ReaderModule { let index = 0; for (const rect of clientRects) { - if (!this.delegate.highlighter?.isOutsideViewport(rect)) { + if (!this.navigator.highlighter?.isOutsideViewport(rect)) { const endNode = selection.focusNode; const endOffset = selection.focusOffset; @@ -354,11 +346,11 @@ export class BookmarkModule implements ReaderModule { } function getCssSelector(element: Element): string | undefined { const options = {}; - let doc = self.delegate.iframes[0].contentDocument; + let doc = self.navigator.iframes[0].contentDocument; if (doc) { return uniqueCssSelector( element, - self.delegate.highlighter?.dom(doc.body).getDocument(), + self.navigator.highlighter?.dom(doc.body).getDocument(), options ); } else { @@ -366,7 +358,7 @@ export class BookmarkModule implements ReaderModule { } } - let win = this.delegate.iframes[0].contentWindow; + let win = this.navigator.iframes[0].contentWindow; let menuItem: SelectionMenuItem = { id: `bookmarkIcon`, marker: AnnotationMarker.Bookmark, @@ -397,15 +389,15 @@ export class BookmarkModule implements ReaderModule { if (win !== null) { let selectionInfo = getCurrentSelectionInfo(win, getCssSelector); if (selectionInfo === undefined) { - let doc = self.delegate.iframes[0].contentDocument; - selectionInfo = this.delegate.annotationModule?.annotator?.getTemporarySelectionInfo( + let doc = self.navigator.iframes[0].contentDocument; + selectionInfo = this.navigator.annotationModule?.annotator?.getTemporarySelectionInfo( doc ); } - let doc = self.delegate.iframes[0].contentDocument; + let doc = self.navigator.iframes[0].contentDocument; if (selectionInfo && doc) { - let book = this.delegate.highlighter?.createHighlight( - this.delegate.highlighter?.dom(doc.body).getWindow(), + let book = this.navigator.highlighter?.createHighlight( + this.navigator.highlighter?.dom(doc.body).getWindow(), selectionInfo, menuItem.highlight?.color, true, @@ -414,7 +406,7 @@ export class BookmarkModule implements ReaderModule { menuItem.popup, menuItem.highlight?.style ); - this.delegate.iframes[0].contentDocument + this.navigator.iframes[0].contentDocument ?.getSelection() ?.removeAllRanges(); if (book) { @@ -431,21 +423,21 @@ export class BookmarkModule implements ReaderModule { ): Promise { if (this.annotator) { var tocItem = this.publication.getTOCItem( - this.delegate.currentChapterLink.href + this.navigator.currentChapterLink.href ); - if (this.delegate.currentTocUrl) { - tocItem = this.publication.getTOCItem(this.delegate.currentTocUrl); + if (this.navigator.currentTocUrl) { + tocItem = this.publication.getTOCItem(this.navigator.currentTocUrl); } if (tocItem === null) { tocItem = this.publication.getTOCItemAbsolute( - this.delegate.currentChapterLink.href + this.navigator.currentChapterLink.href ); } - const bookmarkPosition = this.delegate.view?.getCurrentPosition(); + const bookmarkPosition = this.navigator.view?.getCurrentPosition(); - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { const body = HTMLUtilities.findRequiredIframeElement( doc, @@ -471,7 +463,7 @@ export class BookmarkModule implements ReaderModule { ) { const positions = this.publication.positionsByHref( this.publication.getRelativeHref( - this.delegate.currentChapterLink.href + this.navigator.currentChapterLink.href ) ); const positionIndex = Math.ceil( @@ -484,7 +476,7 @@ export class BookmarkModule implements ReaderModule { id: id, href: href, created: new Date(), - title: this.delegate.currentChapterLink.title, + title: this.navigator.currentChapterLink.title, highlight: highlight, text: { highlight: highlight.selectionInfo.cleanText, @@ -498,8 +490,8 @@ export class BookmarkModule implements ReaderModule { progression: progression, }, created: new Date(), - type: this.delegate.currentChapterLink.type, - title: this.delegate.currentChapterLink.title, + type: this.navigator.currentChapterLink.type, + title: this.navigator.currentChapterLink.title, highlight: highlight, text: { highlight: highlight.selectionInfo.cleanText, @@ -509,7 +501,7 @@ export class BookmarkModule implements ReaderModule { } if (annotation) { - this.delegate.consumptionModule?.trackAction( + this.navigator.consumptionModule?.trackAction( annotation, Action.BookmarkCreated ); @@ -566,18 +558,18 @@ export class BookmarkModule implements ReaderModule { } async drawBookmarks(): Promise { - if (this.rights.enableBookmarks && this.delegate.highlighter) { + if (this.rights.enableBookmarks && this.navigator.highlighter) { if (this.api) { let highlights: Array = []; if (this.annotator) { highlights = (await this.annotator.getAnnotations()) as Array; } if ( - this.delegate.highlighter && + this.navigator.highlighter && highlights && - this.delegate.iframes[0].contentDocument?.readyState === "complete" + this.navigator.iframes[0].contentDocument?.readyState === "complete" ) { - await this.delegate.highlighter.destroyHighlights( + await this.navigator.highlighter.destroyHighlights( HighlightType.Annotation ); @@ -586,18 +578,18 @@ export class BookmarkModule implements ReaderModule { const annotation: Annotation = rangeRepresentation; - let currentLocation = this.delegate.currentChapterLink.href; + let currentLocation = this.navigator.currentChapterLink.href; var tocItem = this.publication.getTOCItem(currentLocation); - if (this.delegate.currentTocUrl) { + if (this.navigator.currentTocUrl) { tocItem = this.publication.getTOCItem( - this.delegate.currentTocUrl + this.navigator.currentTocUrl ); } if (tocItem === undefined) { tocItem = this.publication.getTOCItemAbsolute( - this.delegate.currentChapterLink.href + this.navigator.currentChapterLink.href ); } @@ -608,8 +600,8 @@ export class BookmarkModule implements ReaderModule { } if (annotation.href === href) { - await this.delegate.highlighter.createHighlightDom( - this.delegate.iframes[0].contentWindow as any, + await this.navigator.highlighter.createHighlightDom( + this.navigator.iframes[0].contentWindow as any, rangeRepresentation.highlight ); } @@ -622,11 +614,11 @@ export class BookmarkModule implements ReaderModule { highlights = (await this.annotator.getAnnotations()) as Array; } if ( - this.delegate.highlighter && + this.navigator.highlighter && highlights && - this.delegate.iframes[0].contentDocument?.readyState === "complete" + this.navigator.iframes[0].contentDocument?.readyState === "complete" ) { - await this.delegate.highlighter.destroyHighlights( + await this.navigator.highlighter.destroyHighlights( HighlightType.Annotation ); @@ -635,18 +627,18 @@ export class BookmarkModule implements ReaderModule { const annotation: Annotation = rangeRepresentation; - let currentLocation = this.delegate.currentChapterLink.href; + let currentLocation = this.navigator.currentChapterLink.href; let tocItem = this.publication.getTOCItem(currentLocation); - if (this.delegate.currentTocUrl) { + if (this.navigator.currentTocUrl) { tocItem = this.publication.getTOCItem( - this.delegate.currentTocUrl + this.navigator.currentTocUrl ); } if (tocItem === undefined) { tocItem = this.publication.getTOCItemAbsolute( - this.delegate.currentChapterLink.href + this.navigator.currentChapterLink.href ); } if (tocItem) { @@ -656,8 +648,8 @@ export class BookmarkModule implements ReaderModule { } if (annotation.href === href) { - await this.delegate.highlighter.createHighlightDom( - this.delegate.iframes[0].contentWindow as any, + await this.navigator.highlighter.createHighlightDom( + this.navigator.iframes[0].contentWindow as any, rangeRepresentation.highlight ); } @@ -740,8 +732,8 @@ export class BookmarkModule implements ReaderModule { title: linkElement.title, }; - this.delegate.stopReadAloud(); - this.delegate.navigate(position); + this.navigator.stopReadAloud(); + this.navigator.navigate(position); } ); @@ -791,7 +783,7 @@ export class BookmarkModule implements ReaderModule { ); bookmarkItem.appendChild(bookmarkLink); - if (self.delegate.sideNavExpanded) { + if (self.navigator.sideNavExpanded) { let bookmarkDeleteLink: HTMLElement = document.createElement( "button" ); @@ -841,8 +833,8 @@ export class BookmarkModule implements ReaderModule { ): void { if (locator) { locator.href = this.publication.getAbsoluteHref(locator.href); - this.delegate.stopReadAloud(); - this.delegate.navigate(locator); + this.navigator.stopReadAloud(); + this.navigator.navigate(locator); } else { log.log("bookmark data missing: ", event); } diff --git a/src/modules/TTS/TTSModule2.ts b/src/modules/TTS/TTSModule2.ts index 709cdb8f..4fd862b3 100644 --- a/src/modules/TTS/TTSModule2.ts +++ b/src/modules/TTS/TTSModule2.ts @@ -49,7 +49,7 @@ export class TTSModule2 implements ReaderModule { private clean: any; private rights: Partial; private readonly highlighter: TextHighlighter; - private delegate: IFrameNavigator; + navigator: IFrameNavigator; private body: any; private hasEventListener: boolean = false; private readonly headerMenu?: HTMLElement | null; @@ -80,7 +80,7 @@ export class TTSModule2 implements ReaderModule { addEventListenerOptional(this.body, "wheel", this.wheel.bind(this)); addEventListenerOptional(document, "keydown", this.wheel.bind(this)); addEventListenerOptional( - this.delegate.iframes[0].contentDocument, + this.navigator.iframes[0].contentDocument, "keydown", this.wheel.bind(this) ); @@ -119,12 +119,12 @@ export class TTSModule2 implements ReaderModule { startX === this.startX && startY === this.startY ) { - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { let selection = this.highlighter.dom(doc.body).getSelection(); if (selection.isCollapsed) { - let doc = this.delegate.iframes[0].contentDocument; - const selectionInfo = this.delegate.annotationModule?.annotator?.getTemporarySelectionInfo( + let doc = this.navigator.iframes[0].contentDocument; + const selectionInfo = this.navigator.annotationModule?.annotator?.getTemporarySelectionInfo( doc ); selection.addRange(selectionInfo.range); @@ -225,7 +225,7 @@ export class TTSModule2 implements ReaderModule { cancel(api: boolean = true) { if (api) { if (this.api?.stopped) this.api?.stopped(); - this.delegate.emit("readaloud.stopped", "stopped"); + this.navigator.emit("readaloud.stopped", "stopped"); } this.userScrolled = false; this.speaking = false; @@ -234,7 +234,7 @@ export class TTSModule2 implements ReaderModule { }, 0); if (this._ttsQueueItemHighlightsWord) { - this.delegate.highlighter?.destroyHighlights(HighlightType.ReadAloud); + this.navigator.highlighter?.destroyHighlights(HighlightType.ReadAloud); this._ttsQueueItemHighlightsWord = undefined; } } @@ -247,7 +247,7 @@ export class TTSModule2 implements ReaderModule { callback: () => void ): Promise { if (this.api?.started) this.api?.started(); - this.delegate.emit("readaloud.started", "started"); + this.navigator.emit("readaloud.started", "started"); const self = this; this.userScrolled = false; @@ -260,12 +260,12 @@ export class TTSModule2 implements ReaderModule { ) as HTMLIFrameElement; let rootEl = iframe.contentWindow?.document.body; - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { let selection = this.highlighter.dom(doc.body).getSelection(); if (selection.isCollapsed) { - let doc = self.delegate.iframes[0].contentDocument; - const selectionInfo = self.delegate.annotationModule?.annotator?.getTemporarySelectionInfo( + let doc = self.navigator.iframes[0].contentDocument; + const selectionInfo = self.navigator.annotationModule?.annotator?.getTemporarySelectionInfo( doc ); selection.addRange(selectionInfo.range); @@ -427,7 +427,7 @@ export class TTSModule2 implements ReaderModule { log.log("initialVoice", initialVoice); var publicationVoiceHasHyphen = - self.delegate.publication.Metadata.Language[0].indexOf("-") !== -1; + self.navigator.publication.Metadata.Language[0].indexOf("-") !== -1; log.log("publicationVoiceHasHyphen", publicationVoiceHasHyphen); var publicationVoice; if (publicationVoiceHasHyphen === true) { @@ -437,10 +437,10 @@ export class TTSModule2 implements ReaderModule { var lang = v.lang.replace("_", "-"); return ( lang.startsWith( - self.delegate.publication.Metadata.Language[0] + self.navigator.publication.Metadata.Language[0] ) || lang.endsWith( - self.delegate.publication.Metadata.Language[0].toUpperCase() + self.navigator.publication.Metadata.Language[0].toUpperCase() ) ); })[0] @@ -451,10 +451,10 @@ export class TTSModule2 implements ReaderModule { ? this.voices.filter((v: any) => { return ( v.lang.startsWith( - self.delegate.publication.Metadata.Language[0] + self.navigator.publication.Metadata.Language[0] ) || v.lang.endsWith( - self.delegate.publication.Metadata.Language[0].toUpperCase() + self.navigator.publication.Metadata.Language[0].toUpperCase() ) ); })[0] @@ -552,14 +552,14 @@ export class TTSModule2 implements ReaderModule { log.log("utterance ended"); self.highlighter.doneSpeaking(); self.api?.finished(); - self.delegate.emit("readaloud.finished", "finished"); + self.navigator.emit("readaloud.finished", "finished"); } } } else { log.log("utterance ended"); self.highlighter.doneSpeaking(); self.api?.finished(); - self.delegate.emit("readaloud.finished", "finished"); + self.navigator.emit("readaloud.finished", "finished"); } }; } @@ -572,7 +572,7 @@ export class TTSModule2 implements ReaderModule { this.scrollPartial = true; this.cancel(false); if (this.api?.started) this.api?.started(); - this.delegate.emit("readaloud.started", "started"); + this.navigator.emit("readaloud.started", "started"); let self = this; let iframe = document.querySelector( @@ -589,7 +589,7 @@ export class TTSModule2 implements ReaderModule { function findVisibleText() { let node = self.highlighter.visibleTextRects[0]; - let doc = self.delegate.iframes[0].contentDocument; + let doc = self.navigator.iframes[0].contentDocument; if (doc) { const range = self.highlighter .dom(doc.body) @@ -597,7 +597,7 @@ export class TTSModule2 implements ReaderModule { .document.createRange(); const selection = self.highlighter - .dom(self.delegate.iframes[0].contentDocument?.body) + .dom(self.navigator.iframes[0].contentDocument?.body) .getSelection(); selection.removeAllRanges(); range.selectNodeContents(node.node); @@ -646,13 +646,13 @@ export class TTSModule2 implements ReaderModule { speakPause() { if (window.speechSynthesis.speaking) { if (this.api?.paused) this.api?.paused(); - this.delegate.emit("readaloud.paused", "paused"); + this.navigator.emit("readaloud.paused", "paused"); this.userScrolled = false; window.speechSynthesis.pause(); this.speaking = false; if (this._ttsQueueItemHighlightsWord) { - this.delegate.highlighter?.destroyHighlights(HighlightType.ReadAloud); + this.navigator.highlighter?.destroyHighlights(HighlightType.ReadAloud); this._ttsQueueItemHighlightsWord = undefined; } } @@ -661,7 +661,7 @@ export class TTSModule2 implements ReaderModule { speakResume() { if (window.speechSynthesis.speaking) { if (this.api?.resumed) this.api?.resumed(); - this.delegate.emit("readaloud.resumed", "resumed"); + this.navigator.emit("readaloud.resumed", "resumed"); this.userScrolled = false; window.speechSynthesis.resume(); this.speaking = true; @@ -670,7 +670,6 @@ export class TTSModule2 implements ReaderModule { public static async create(config: TTSModuleConfig) { const tts = new this( - config.delegate, config.tts, config.rights, config.highlighter, @@ -683,7 +682,6 @@ export class TTSModule2 implements ReaderModule { } public constructor( - delegate: IFrameNavigator, tts: TTSSettings, rights: Partial, highlighter: TextHighlighter, @@ -691,7 +689,6 @@ export class TTSModule2 implements ReaderModule { api?: TTSModuleAPI, headerMenu?: HTMLElement | null ) { - this.delegate = delegate; this.tts = tts; this.headerMenu = headerMenu; this.rights = rights; @@ -701,8 +698,6 @@ export class TTSModule2 implements ReaderModule { } protected async start(): Promise { - this.delegate.ttsModule = this; - if (this.headerMenu) { var menuTTS = HTMLUtilities.findElement( this.headerMenu, @@ -712,8 +707,8 @@ export class TTSModule2 implements ReaderModule { } setTimeout(() => { this.properties?.hideLayer - ? this.delegate.hideLayer("readaloud") - : this.delegate.showLayer("readaloud"); + ? this.navigator.hideLayer("readaloud") + : this.navigator.showLayer("readaloud"); }, 10); } @@ -742,7 +737,7 @@ export class TTSModule2 implements ReaderModule { removeEventListenerOptional(this.body, "wheel", this.wheel.bind(this)); removeEventListenerOptional(document, "keydown", this.wheel.bind(this)); removeEventListenerOptional( - this.delegate.iframes[0].contentDocument, + this.navigator.iframes[0].contentDocument, "keydown", this.wheel.bind(this) ); @@ -1019,7 +1014,7 @@ export class TTSModule2 implements ReaderModule { var self = this; var publicationVoiceHasHyphen = - self.delegate.publication.Metadata.Language[0].indexOf("-") !== -1; + self.navigator.publication.Metadata.Language[0].indexOf("-") !== -1; log.log("publicationVoiceHasHyphen", publicationVoiceHasHyphen); var publicationVoice; if (publicationVoiceHasHyphen === true) { @@ -1029,10 +1024,10 @@ export class TTSModule2 implements ReaderModule { var lang = v.lang.replace("_", "-"); return ( lang.startsWith( - self.delegate.publication.Metadata.Language[0] + self.navigator.publication.Metadata.Language[0] ) || lang.endsWith( - self.delegate.publication.Metadata.Language[0].toUpperCase() + self.navigator.publication.Metadata.Language[0].toUpperCase() ) ); })[0] @@ -1043,10 +1038,10 @@ export class TTSModule2 implements ReaderModule { ? this.voices.filter((v: any) => { return ( v.lang.startsWith( - self.delegate.publication.Metadata.Language[0] + self.navigator.publication.Metadata.Language[0] ) || v.lang.endsWith( - self.delegate.publication.Metadata.Language[0].toUpperCase() + self.navigator.publication.Metadata.Language[0].toUpperCase() ) ); })[0] @@ -1199,7 +1194,7 @@ export class TTSModule2 implements ReaderModule { log.log(charIndex, charLength, word, start, end); if (this._ttsQueueItemHighlightsWord) { - this.delegate.highlighter?.destroyHighlights(HighlightType.ReadAloud); + this.navigator.highlighter?.destroyHighlights(HighlightType.ReadAloud); this._ttsQueueItemHighlightsWord = undefined; } @@ -1241,7 +1236,7 @@ export class TTSModule2 implements ReaderModule { var self = this; function getCssSelector(element: Element): string { try { - let doc = self.delegate.iframes[0].contentDocument; + let doc = self.navigator.iframes[0].contentDocument; if (doc) { return uniqueCssSelector(element, doc, _getCssSelectorOptions); } else { @@ -1258,8 +1253,8 @@ export class TTSModule2 implements ReaderModule { return; } - let result = this.delegate.highlighter?.createHighlight( - this.delegate.iframes[0].contentWindow as any, + let result = this.navigator.highlighter?.createHighlight( + this.navigator.iframes[0].contentWindow as any, { rangeInfo: rangeInfo, cleanText: "", @@ -1289,7 +1284,7 @@ export class TTSModule2 implements ReaderModule { const shouldScroll = top > window.innerHeight / 2 - 65; if ( - this.delegate.view?.isScrollMode() && + this.navigator.view?.isScrollMode() && this.tts.autoScroll && !this.userScrolled && this.scrollPartial && @@ -1299,8 +1294,8 @@ export class TTSModule2 implements ReaderModule { block: "center", behavior: "smooth", }); - } else if (this.delegate.view?.isPaginated()) { - self.delegate.view?.snap(result[1]?.firstChild as HTMLElement); + } else if (this.navigator.view?.isPaginated()) { + self.navigator.view?.snap(result[1]?.firstChild as HTMLElement); } } } diff --git a/src/modules/TTS/TTSSettings.ts b/src/modules/TTS/TTSSettings.ts index 3df893da..79e91d85 100644 --- a/src/modules/TTS/TTSSettings.ts +++ b/src/modules/TTS/TTSSettings.ts @@ -51,7 +51,6 @@ export interface TTSModuleProperties { } export interface TTSModuleConfig extends TTSModuleProperties { - delegate: IFrameNavigator; rights: Partial; tts: TTSSettings; highlighter: TextHighlighter; diff --git a/src/modules/citation/CitationModule.ts b/src/modules/citation/CitationModule.ts index 6caedbdf..a83e8627 100644 --- a/src/modules/citation/CitationModule.ts +++ b/src/modules/citation/CitationModule.ts @@ -54,27 +54,24 @@ export interface CitationModuleAPI { export interface CitationModuleConfig extends CitationModuleProperties { publication: Publication; - delegate: IFrameNavigator; highlighter: TextHighlighter; api?: CitationModuleAPI; } export default class CitationModule implements ReaderModule { private publication: Publication; - private delegate: IFrameNavigator; + navigator: IFrameNavigator; private properties: CitationModuleProperties; private readonly highlighter?: TextHighlighter; api?: CitationModuleAPI; private constructor( - delegate: IFrameNavigator, publication: Publication, highlighter: TextHighlighter, properties: CitationModuleProperties, api?: CitationModuleAPI ) { this.highlighter = highlighter; - this.delegate = delegate; this.properties = properties; this.publication = publication; this.api = api; @@ -82,7 +79,6 @@ export default class CitationModule implements ReaderModule { public static async create(config: CitationModuleConfig) { const module = new this( - config.delegate, config.publication, config.highlighter, config as CitationModuleProperties, @@ -97,8 +93,8 @@ export default class CitationModule implements ReaderModule { } copyToClipboard(textToClipboard) { - if (this.delegate?.contentProtectionModule) { - this.delegate!.contentProtectionModule.citation = true; + if (this.navigator?.contentProtectionModule) { + this.navigator!.contentProtectionModule.citation = true; } let success = true; // @ts-ignore @@ -168,7 +164,6 @@ export default class CitationModule implements ReaderModule { } protected async start(): Promise { - this.delegate.citationModule = this; const self = this; const citationIconMenu = { diff --git a/src/modules/consumption/ConsumptionModule.ts b/src/modules/consumption/ConsumptionModule.ts index b6a74d92..06cfefe1 100644 --- a/src/modules/consumption/ConsumptionModule.ts +++ b/src/modules/consumption/ConsumptionModule.ts @@ -27,15 +27,21 @@ export interface ConsumptionModuleProperties { idleTimeout?: number; responseTimeout?: number; } +export interface ReadingSession { + time: any; + firstLocator: Locator; + lastLocator: Locator; + progress: any; +} + export interface ConsumptionModuleConfig extends ConsumptionModuleProperties { publication: Publication; - delegate: IFrameNavigator; properties?: ConsumptionModuleProperties; api?: ConsumptionModuleAPI; } export class ConsumptionModule implements ReaderModule { - private delegate: IFrameNavigator; + navigator: IFrameNavigator; private publication: Publication; private properties: ConsumptionModuleProperties; api?: ConsumptionModuleAPI; @@ -45,7 +51,7 @@ export class ConsumptionModule implements ReaderModule { startResearchTimer?: Date; researchSessionId: any; - readingSessions: any[]; + readingSessions: ReadingSession[]; readingSessionsInterval; startReadingTimer: Date; @@ -53,12 +59,10 @@ export class ConsumptionModule implements ReaderModule { lastReadingLocator: Locator; private constructor( - delegate: IFrameNavigator, publication: Publication, properties: ConsumptionModuleProperties, api?: ConsumptionModuleAPI ) { - this.delegate = delegate; this.publication = publication; this.properties = properties; this.api = api; @@ -66,7 +70,6 @@ export class ConsumptionModule implements ReaderModule { public static async create(config: ConsumptionModuleConfig) { const consumption = new this( - config.delegate, config.publication, config as ConsumptionModuleProperties, config.api @@ -75,7 +78,6 @@ export class ConsumptionModule implements ReaderModule { return consumption; } protected async start(): Promise { - this.delegate.consumptionModule = this; this.startResearchSession(); } async stop() { @@ -83,7 +85,7 @@ export class ConsumptionModule implements ReaderModule { this.endResearchSession(); } initialize() { - let win = this.delegate.iframes[0].contentWindow; + let win = this.navigator.iframes[0].contentWindow; if (win) { const self = this; win.onload = function () { @@ -110,6 +112,19 @@ export class ConsumptionModule implements ReaderModule { this.api?.actionTracked(locator, action); } startReadingSession(locator: Locator) { + if (this.firstReadingLocator && this.lastReadingLocator) { + let progress = + this.lastReadingLocator.locations.totalProgression! - + this.firstReadingLocator.locations.totalProgression!; + let timeElapsed = + (new Date().getTime() - this.startReadingTimer.getTime()) / 1000; + this.readingSessions.push({ + lastLocator: this.lastReadingLocator, + firstLocator: this.firstReadingLocator, + time: timeElapsed, + progress: Math.round(progress * 100), + }); + } this.firstReadingLocator = locator; this.startReadingTimer = new Date(); } @@ -165,6 +180,20 @@ export class ConsumptionModule implements ReaderModule { } endResearchSession() { if (this.properties.enableTrackingSession) { + if (this.firstReadingLocator && this.lastReadingLocator) { + let progress = + this.lastReadingLocator.locations.totalProgression! - + this.firstReadingLocator.locations.totalProgression!; + let timeElapsed = + (new Date().getTime() - this.startReadingTimer.getTime()) / 1000; + this.readingSessions.push({ + lastLocator: this.lastReadingLocator, + firstLocator: this.firstReadingLocator, + time: timeElapsed, + progress: Math.round(progress * 100), + }); + } + let timeElapsed = (new Date().getTime() - this.startResearchTimer!.getTime()) / 1000; this.api?.updateResearchSession( diff --git a/src/modules/highlight/TextHighlighter.ts b/src/modules/highlight/TextHighlighter.ts index 299000a5..959e1b95 100644 --- a/src/modules/highlight/TextHighlighter.ts +++ b/src/modules/highlight/TextHighlighter.ts @@ -134,14 +134,13 @@ export interface TextHighlighterProperties { } export interface TextHighlighterConfig extends TextHighlighterProperties { - delegate: IFrameNavigator; api?: TextSelectorAPI; layerSettings: LayerSettings; } export class TextHighlighter { private options: any; - private readonly delegate: IFrameNavigator; + navigator: IFrameNavigator; layerSettings: LayerSettings; private lastSelectedHighlight?: number = undefined; properties: TextHighlighterProperties; @@ -151,7 +150,6 @@ export class TextHighlighter { public static async create(config: TextHighlighterConfig): Promise { const module = new this( - config.delegate, config.layerSettings, config as TextHighlighterProperties, false, @@ -162,14 +160,12 @@ export class TextHighlighter { } private constructor( - delegate: IFrameNavigator, layerSettings: LayerSettings, properties: TextHighlighterProperties, hasEventListener: boolean, options: any, api?: TextSelectorAPI ) { - this.delegate = delegate; this.layerSettings = layerSettings; this.properties = properties; this.api = api; @@ -183,15 +179,14 @@ export class TextHighlighter { }, onAfterHighlight: function () {}, }); - this.delegate.highlighter = this; } async initialize() { - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { this.dom(doc.body).addClass(this.options.contextClass); } this.bindEvents( - this.delegate.iframes[0].contentDocument?.body, + this.navigator.iframes[0].contentDocument?.body, this, this.hasEventListener ); @@ -212,7 +207,7 @@ export class TextHighlighter { } } setTimeout(async () => { - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { await doc.body?.addEventListener("click", unselect); } @@ -726,7 +721,7 @@ export class TextHighlighter { */ destroy() { this.toolboxHide(); - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { this.unbindEvents(doc.body, this); this.dom(doc.body).removeClass(this.options.contextClass); @@ -792,7 +787,7 @@ export class TextHighlighter { self.toolboxMode("colors"); }); - if (this.delegate.rights.enableAnnotations) { + if (this.navigator.rights.enableAnnotations) { let index = 10; colors.forEach((color) => { index--; @@ -937,7 +932,7 @@ export class TextHighlighter { snapSelectionToWord(trimmed: boolean = false) { let self = this; - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { let selection = self.dom(doc.body)?.getSelection(); // Check for existence of window.getSelection() and that it has a @@ -1025,7 +1020,7 @@ export class TextHighlighter { "highlight-toolbox-mode-add" ); let range = this.dom( - this.delegate.iframes[0].contentDocument?.body + this.navigator.iframes[0].contentDocument?.body ).getRange(); if ((!range || range.collapsed) && toolboxAddOptions) { @@ -1038,7 +1033,7 @@ export class TextHighlighter { if (this.isIOS()) { setTimeout(function () { - let doc = self.delegate.iframes[0].contentDocument; + let doc = self.navigator.iframes[0].contentDocument; if (doc) { let selection = self.dom(doc.body).getSelection(); selection.removeAllRanges(); @@ -1053,7 +1048,7 @@ export class TextHighlighter { return _blacklistIdClassForCssSelectors.indexOf(str) < 0; }, }; - let doc = self.delegate.iframes[0].contentDocument; + let doc = self.navigator.iframes[0].contentDocument; if (doc) { return uniqueCssSelector(element, doc, options); } else { @@ -1061,12 +1056,12 @@ export class TextHighlighter { } } - let win = self.delegate.iframes[0].contentWindow; + let win = self.navigator.iframes[0].contentWindow; const selectionInfo = getCurrentSelectionInfo( win!, getCssSelector ); - self.delegate.annotationModule?.annotator?.saveTemporarySelectionInfo( + self.navigator.annotationModule?.annotator?.saveTemporarySelectionInfo( selectionInfo ); }, 5); @@ -1084,14 +1079,14 @@ export class TextHighlighter { if (!this.isSelectionMenuOpen) { this.isSelectionMenuOpen = true; if (this.api?.selectionMenuOpen) this.api?.selectionMenuOpen(); - this.delegate.emit("toolbox.opened", "opened"); + this.navigator.emit("toolbox.opened", "opened"); } }, 100); selectionMenuClosed = debounce(() => { if (this.isSelectionMenuOpen) { this.isSelectionMenuOpen = false; if (this.api?.selectionMenuClose) this.api?.selectionMenuClose(); - this.delegate.emit("toolbox.closed", "closed"); + this.navigator.emit("toolbox.closed", "closed"); } }, 100); @@ -1101,7 +1096,7 @@ export class TextHighlighter { toolboxPlacement() { let range = this.dom( - this.delegate.iframes[0].contentDocument?.body + this.navigator.iframes[0].contentDocument?.body ).getRange(); if (!range || range.collapsed) { return; @@ -1111,10 +1106,10 @@ export class TextHighlighter { let toolbox = document.getElementById("highlight-toolbox"); if (toolbox) { - const paginated = this.delegate.view?.isPaginated(); + const paginated = this.navigator.view?.isPaginated(); if (paginated) { toolbox.style.top = - rect.top + (this.delegate.attributes?.navHeight ?? 0) + "px"; + rect.top + (this.navigator.attributes?.navHeight ?? 0) + "px"; } else { toolbox.style.top = rect.top + "px"; } @@ -1127,7 +1122,7 @@ export class TextHighlighter { if (toolbox) { if (getComputedStyle(toolbox).display === "none") { toolbox.style.display = "block"; - const paginated = this.delegate.view?.isPaginated(); + const paginated = this.navigator.view?.isPaginated(); if (paginated) { toolbox.style.position = "absolute"; } else { @@ -1144,7 +1139,7 @@ export class TextHighlighter { let noteIcon = document.getElementById("noteIcon"); let colorIcon = document.getElementById("colorIcon"); let speakIcon = document.getElementById("speakIcon"); - if (this.delegate.rights.enableAnnotations) { + if (this.navigator.rights.enableAnnotations) { if (highlightIcon) { highlightIcon.style.display = "unset"; if (colorIcon) { @@ -1231,7 +1226,7 @@ export class TextHighlighter { collapseIcon.style.setProperty("display", "none"); } } - if (this.delegate.rights.enableTTS) { + if (this.navigator.rights.enableTTS) { if (speakIcon) { function speakEvent() { speakIcon?.removeEventListener("click", speakEvent); @@ -1268,7 +1263,7 @@ export class TextHighlighter { return _blacklistIdClassForCssSelectors.indexOf(str) < 0; }, }; - let doc = self.delegate.iframes[0].contentDocument; + let doc = self.navigator.iframes[0].contentDocument; if (doc) { return uniqueCssSelector(element, doc, options); } else { @@ -1276,15 +1271,15 @@ export class TextHighlighter { } } - let win = self.delegate.iframes[0].contentWindow; + let win = self.navigator.iframes[0].contentWindow; if (win) { let selectionInfo = getCurrentSelectionInfo( win, getCssSelector ); if (selectionInfo === undefined) { - let doc = self.delegate.iframes[0].contentDocument; - selectionInfo = self.delegate.annotationModule?.annotator?.getTemporarySelectionInfo( + let doc = self.navigator.iframes[0].contentDocument; + selectionInfo = self.navigator.annotationModule?.annotator?.getTemporarySelectionInfo( doc ); } @@ -1303,11 +1298,11 @@ export class TextHighlighter { if ( (marker === AnnotationMarker.Custom && - self.delegate.rights.enableAnnotations) || + self.navigator.rights.enableAnnotations) || (marker === AnnotationMarker.Bookmark && - self.delegate.rights.enableBookmarks) + self.navigator.rights.enableBookmarks) ) { - let doc = self.delegate.iframes[0].contentDocument; + let doc = self.navigator.iframes[0].contentDocument; if (doc) { let highlight = self.createHighlight( self.dom(doc.body).getWindow(), @@ -1321,17 +1316,17 @@ export class TextHighlighter { ); self.options.onAfterHighlight(highlight, marker); - if (self.delegate.rights.enableAnnotations) { - self.delegate.annotationModule + if (self.navigator.rights.enableAnnotations) { + self.navigator.annotationModule ?.saveAnnotation(highlight[0]) .then((anno) => { if (menuItem?.note) { if (anno.highlight) { // notes on custom icons , new note - self.delegate.annotationModule?.api + self.navigator.annotationModule?.api ?.addCommentToAnnotation(anno) .then((result) => { - self.delegate.annotationModule + self.navigator.annotationModule ?.updateAnnotation(result) .then(async () => { log.log( @@ -1342,8 +1337,8 @@ export class TextHighlighter { } } }); - } else if (self.delegate.rights.enableBookmarks) { - self.delegate.bookmarkModule?.saveAnnotation( + } else if (self.navigator.rights.enableBookmarks) { + self.navigator.bookmarkModule?.saveAnnotation( highlight[0] ); } @@ -1383,20 +1378,20 @@ export class TextHighlighter { return _blacklistIdClassForCssSelectors.indexOf(str) < 0; }, }; - let doc = self.delegate.iframes[0].contentDocument; + let doc = self.navigator.iframes[0].contentDocument; if (doc) { return uniqueCssSelector(element, doc, options); } else { return undefined; } } - let win = self.delegate.iframes[0].contentWindow; + let win = self.navigator.iframes[0].contentWindow; if (win) { let selectionInfo = getCurrentSelectionInfo(win, getCssSelector); if (selectionInfo === undefined) { - let doc = self.delegate.iframes[0].contentDocument; - selectionInfo = this.delegate.annotationModule?.annotator?.getTemporarySelectionInfo( + let doc = self.navigator.iframes[0].contentDocument; + selectionInfo = this.navigator.annotationModule?.annotator?.getTemporarySelectionInfo( doc ); } @@ -1408,7 +1403,7 @@ export class TextHighlighter { if (TextHighlighter.isHexColor(createColor)) { createColor = TextHighlighter.hexToRgbChannels(createColor); } - let doc = self.delegate.iframes[0].contentDocument; + let doc = self.navigator.iframes[0].contentDocument; if (doc) { let highlight = this.createHighlight( self.dom(doc.body).getWindow(), @@ -1421,28 +1416,28 @@ export class TextHighlighter { this.options.onAfterHighlight(highlight, marker); if ( - this.delegate.rights.enableAnnotations && + this.navigator.rights.enableAnnotations && marker !== AnnotationMarker.Bookmark ) { - this.delegate.annotationModule?.saveAnnotation(highlight[0]); + this.navigator.annotationModule?.saveAnnotation(highlight[0]); } else if ( - this.delegate.rights.enableBookmarks && + this.navigator.rights.enableBookmarks && marker === AnnotationMarker.Bookmark ) { - this.delegate.bookmarkModule?.saveAnnotation(highlight[0]); + this.navigator.bookmarkModule?.saveAnnotation(highlight[0]); } } } if (!keepRange) { this.dom( - this.delegate.iframes[0].contentDocument?.body + this.navigator.iframes[0].contentDocument?.body ).removeAllRanges(); } } else { if (!keepRange) { this.dom( - this.delegate.iframes[0].contentDocument?.body + this.navigator.iframes[0].contentDocument?.body ).removeAllRanges(); } } @@ -1450,7 +1445,7 @@ export class TextHighlighter { } speak() { - if (this.delegate.rights.enableTTS) { + if (this.navigator.rights.enableTTS) { let self = this; function getCssSelector(element: Element): string | undefined { const options = { @@ -1461,32 +1456,32 @@ export class TextHighlighter { return _blacklistIdClassForCssSelectors.indexOf(str) < 0; }, }; - let doc = self.delegate.iframes[0].contentDocument; + let doc = self.navigator.iframes[0].contentDocument; if (doc) { return uniqueCssSelector(element, doc, options); } else { return undefined; } } - let win = self.delegate.iframes[0].contentWindow; + let win = self.navigator.iframes[0].contentWindow; if (win) { let selectionInfo = getCurrentSelectionInfo(win, getCssSelector); if (selectionInfo === undefined) { - let doc = self.delegate.iframes[0].contentDocument; - selectionInfo = self.delegate.annotationModule?.annotator?.getTemporarySelectionInfo( + let doc = self.navigator.iframes[0].contentDocument; + selectionInfo = self.navigator.annotationModule?.annotator?.getTemporarySelectionInfo( doc ); } if (selectionInfo !== undefined) { - (this.delegate.ttsModule as TTSModule2).speak( + (this.navigator.ttsModule as TTSModule2).speak( selectionInfo as any, true, () => {} ); } } - let doc = self.delegate.iframes[0].contentDocument; + let doc = self.navigator.iframes[0].contentDocument; if (doc) { const selection = self.dom(doc.body).getSelection(); selection.removeAllRanges(); @@ -1499,14 +1494,14 @@ export class TextHighlighter { } } stopReadAloud() { - if (this.delegate.rights.enableTTS) { + if (this.navigator.rights.enableTTS) { this.doneSpeaking(); } } callbackComplete() { this.toolboxHide(); - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { this.dom(doc.body).removeAllRanges(); } @@ -1553,7 +1548,7 @@ export class TextHighlighter { } get visibleTextRects() { - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { const body = HTMLUtilities.findRequiredIframeElement( doc, @@ -1618,15 +1613,15 @@ export class TextHighlighter { } doneSpeaking(reload: boolean = false) { - if (this.delegate.rights.enableTTS) { + if (this.navigator.rights.enableTTS) { this.toolboxHide(); - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { this.dom(doc.body).removeAllRanges(); } - (this.delegate.ttsModule as TTSModule2).cancel(); + (this.navigator.ttsModule as TTSModule2).cancel(); if (reload) { - this.delegate.reload(); + this.navigator.reload(); } } } @@ -1854,7 +1849,7 @@ export class TextHighlighter { } resetHighlightAreaStyle(highlightArea: HTMLElement, id_container: string) { - let doc = this.delegate.iframes[0].contentWindow?.document; + let doc = this.navigator.iframes[0].contentWindow?.document; const id = highlightArea.parentNode && highlightArea.parentNode.nodeType === Node.ELEMENT_NODE && @@ -2118,7 +2113,7 @@ export class TextHighlighter { } setAndResetSearchHighlight(highlight, highlights) { - let doc = this.delegate.iframes[0].contentWindow?.document as any; + let doc = this.navigator.iframes[0].contentWindow?.document as any; const allHighlightAreas = Array.from( doc @@ -2241,7 +2236,7 @@ export class TextHighlighter { }; async processMouseEvent(ev: MouseEvent) { - const doc = this.delegate.iframes[0].contentWindow?.document; + const doc = this.navigator.iframes[0].contentWindow?.document; // relative to fixed window top-left corner // (unlike pageX/Y which is relative to top-left rendered content area, subject to scrolling) const x = ev.clientX; @@ -2259,7 +2254,7 @@ export class TextHighlighter { return; } - const paginated = this.delegate.view?.isPaginated(); + const paginated = this.navigator.view?.isPaginated(); const bodyRect = doc.body.getBoundingClientRect(); const scrollElement = this.getScrollingElement(doc); @@ -2397,18 +2392,18 @@ export class TextHighlighter { log.log(JSON.stringify(payload)); let self = this; let anno; - if (self.delegate.rights.enableAnnotations) { - anno = (await this.delegate.annotationModule?.getAnnotation( + if (self.navigator.rights.enableAnnotations) { + anno = (await this.navigator.annotationModule?.getAnnotation( payload.highlight )) as Annotation; - } else if (self.delegate.rights.enableBookmarks) { - anno = (await this.delegate.bookmarkModule?.getAnnotation( + } else if (self.navigator.rights.enableBookmarks) { + anno = (await this.navigator.bookmarkModule?.getAnnotation( payload.highlight )) as Annotation; } if (payload.highlight.type === HighlightType.Annotation) { - this.delegate.annotationModule?.api + this.navigator.annotationModule?.api ?.selectedAnnotation(anno) .then(async () => {}); } @@ -2421,7 +2416,7 @@ export class TextHighlighter { if (toolbox) { toolbox.style.top = - ev.clientY + (this.delegate.attributes?.navHeight ?? 0) + "px"; + ev.clientY + (this.navigator.attributes?.navHeight ?? 0) + "px"; toolbox.style.left = ev.clientX + "px"; if (getComputedStyle(toolbox).display === "none") { @@ -2440,10 +2435,10 @@ export class TextHighlighter { } function noteH() { // existing note - self.delegate.annotationModule?.api + self.navigator.annotationModule?.api ?.addCommentToAnnotation(anno) .then((result) => { - self.delegate.annotationModule + self.navigator.annotationModule ?.updateAnnotation(result) .then(async () => { log.log("update highlight " + result.id); @@ -2482,8 +2477,8 @@ export class TextHighlighter { } function deleteH() { - if (self.delegate.rights.enableAnnotations) { - self.delegate.annotationModule + if (self.navigator.rights.enableAnnotations) { + self.navigator.annotationModule ?.deleteSelectedHighlight(anno) .then(async () => { log.log("delete highlight " + anno.id); @@ -2492,8 +2487,8 @@ export class TextHighlighter { } self.selectionMenuClosed(); }); - } else if (self.delegate.rights.enableBookmarks) { - self.delegate.bookmarkModule + } else if (self.navigator.rights.enableBookmarks) { + self.navigator.bookmarkModule ?.deleteSelectedHighlight(anno) .then(async () => { log.log("delete highlight " + anno.id); @@ -2533,19 +2528,19 @@ export class TextHighlighter { } } else { if (foundElement.dataset.definition) { - const popup = new Popup(this.delegate); + const popup = new Popup(this.navigator); popup.showPopup(foundElement.dataset.definition, ev); } - let result = this.delegate.definitionsModule?.properties?.definitions?.filter( + let result = this.navigator.definitionsModule?.properties?.definitions?.filter( (el: any) => el.order === Number(foundElement?.dataset.order) )[0]; log.log(result); - if (this.delegate.definitionsModule?.api?.click) { - this.delegate.definitionsModule.api?.click( + if (this.navigator.definitionsModule?.api?.click) { + this.navigator.definitionsModule.api?.click( lodash.omit(result, "callbacks"), lodash.omit(foundHighlight, "definition") ); - this.delegate.emit("definition.click", result, foundHighlight); + this.navigator.emit("definition.click", result, foundHighlight); } } } @@ -2564,7 +2559,7 @@ export class TextHighlighter { if (id !== HighlightContainer.R2_ID_GUTTER_RIGHT_CONTAINER) { container.style.setProperty("pointer-events", "none"); } - if (this.delegate.view?.layout === "fixed") { + if (this.navigator.view?.layout === "fixed") { container.style.setProperty("position", "absolute"); container.style.setProperty("top", "0"); container.style.setProperty("left", "0"); @@ -2612,7 +2607,7 @@ export class TextHighlighter { } destroyHighlights(type: HighlightType) { - let doc = this.delegate.iframes[0].contentWindow?.document; + let doc = this.navigator.iframes[0].contentWindow?.document; if (doc) { let container; switch (type) { @@ -2771,7 +2766,7 @@ export class TextHighlighter { highlightParent.setAttribute("data-click", "1"); } - const paginated = this.delegate.view?.isPaginated(); + const paginated = this.navigator.view?.isPaginated(); // Resize Sensor sets body position to "relative" (default static), // which may breaks things! @@ -2982,7 +2977,7 @@ export class TextHighlighter { highlightParent.append(highlightAreaLine); } - let viewportWidth = this.delegate.iframes[0].contentWindow?.innerWidth; + let viewportWidth = this.navigator.iframes[0].contentWindow?.innerWidth; let columnCount = parseInt( getComputedStyle(doc.documentElement).getPropertyValue("column-count") ); @@ -3003,7 +2998,7 @@ export class TextHighlighter { getComputedStyle(doc.body).width.replace("px", "") ); } - let ratio = this.delegate.settings.fontSize / 100; + let ratio = this.navigator.settings.fontSize / 100; let addRight = 20 * ratio; if (ratio <= 1) { @@ -3027,7 +3022,7 @@ export class TextHighlighter { addRight; let pagemargin = parseInt( - this.delegate.iframes[0].contentDocument!!.documentElement.style.getPropertyValue( + this.navigator.iframes[0].contentDocument!!.documentElement.style.getPropertyValue( "--USER__pageMargins" ) ); @@ -3039,13 +3034,13 @@ export class TextHighlighter { if (!paginated) { left = parseInt( getComputedStyle( - this.delegate.iframes[0].contentDocument?.body!! + this.navigator.iframes[0].contentDocument?.body!! ).width.replace("px", "") ); right = parseInt( getComputedStyle( - this.delegate.iframes[0].contentDocument?.body!! + this.navigator.iframes[0].contentDocument?.body!! ).width.replace("px", "") ) - pageWidth; @@ -3086,7 +3081,8 @@ export class TextHighlighter { "style", `position: absolute;top:${position}px;left:${ right + - this.delegate.iframes[0].contentDocument?.scrollingElement?.scrollLeft + this.navigator.iframes[0].contentDocument?.scrollingElement + ?.scrollLeft }px;height:${size}px; width:${size}px;` ); } else if (highlight.icon?.position === "inline") { @@ -3138,7 +3134,7 @@ export class TextHighlighter { "style", `position: absolute;top:${position}px;left:${ left + - this.delegate.iframes[0].contentDocument?.scrollingElement + this.navigator.iframes[0].contentDocument?.scrollingElement ?.scrollLeft }px;height:${size}px; width:${size}px;` ); @@ -3147,7 +3143,7 @@ export class TextHighlighter { "style", `position: absolute;top:${position}px;left:${ left + - this.delegate.iframes[0].contentDocument?.scrollingElement + this.navigator.iframes[0].contentDocument?.scrollingElement ?.scrollLeft }px;height:${size}px; width:${size}px;` ); @@ -3213,15 +3209,15 @@ export class TextHighlighter { ) { highlightAreaIcon.addEventListener("click", async function (ev) { let anno; - if (self.delegate.rights.enableAnnotations) { - anno = (await self.delegate.annotationModule?.getAnnotationByID( + if (self.navigator.rights.enableAnnotations) { + anno = (await self.navigator.annotationModule?.getAnnotationByID( highlight.id )) as Annotation; - self.delegate.annotationModule?.api + self.navigator.annotationModule?.api ?.selectedAnnotation(anno) .then(async () => {}); - } else if (self.delegate.rights.enableBookmarks) { - anno = (await self.delegate.bookmarkModule?.getAnnotationByID( + } else if (self.navigator.rights.enableBookmarks) { + anno = (await self.navigator.bookmarkModule?.getAnnotationByID( highlight.id )) as Annotation; } @@ -3232,7 +3228,7 @@ export class TextHighlighter { let toolbox = document.getElementById("highlight-toolbox"); if (toolbox) { toolbox.style.top = - ev.clientY + (self.delegate.attributes?.navHeight ?? 0) + "px"; + ev.clientY + (self.navigator.attributes?.navHeight ?? 0) + "px"; toolbox.style.left = ev.clientX + "px"; if (getComputedStyle(toolbox).display === "none") { @@ -3262,16 +3258,16 @@ export class TextHighlighter { } function deleteH() { - if (self.delegate.rights.enableAnnotations) { - self.delegate.annotationModule + if (self.navigator.rights.enableAnnotations) { + self.navigator.annotationModule ?.deleteSelectedHighlight(anno) .then(async () => { log.log("delete highlight " + anno.id); toolbox!!.style.display = "none"; self.selectionMenuClosed(); }); - } else if (self.delegate.rights.enableBookmarks) { - self.delegate.bookmarkModule + } else if (self.navigator.rights.enableBookmarks) { + self.navigator.bookmarkModule ?.deleteSelectedHighlight(anno) .then(async () => { log.log("delete highlight " + anno.id); diff --git a/src/modules/history/HistoryModule.ts b/src/modules/history/HistoryModule.ts index 963fbc90..71825685 100644 --- a/src/modules/history/HistoryModule.ts +++ b/src/modules/history/HistoryModule.ts @@ -35,14 +35,13 @@ export interface HistoryModuleProperties { export interface HistoryModuleConfig extends HistoryModuleProperties { annotator: Annotator; - delegate: IFrameNavigator; headerMenu?: HTMLElement | null; publication: Publication; } export class HistoryModule implements ReaderModule { readonly annotator: Annotator | null; - private delegate: IFrameNavigator; + navigator: IFrameNavigator; private readonly headerMenu?: HTMLElement | null; private publication: Publication; private properties: HistoryModuleProperties; @@ -54,28 +53,25 @@ export class HistoryModule implements ReaderModule { private constructor( annotator: Annotator, - delegate: IFrameNavigator, publication: Publication, properties: HistoryModuleProperties, headerMenu?: HTMLElement | null ) { this.headerMenu = headerMenu; - this.delegate = delegate; this.publication = publication; this.properties = properties; this.annotator = annotator; } public static async create(config: HistoryModuleConfig) { - const pageBreak = new this( + const history = new this( config.annotator, - config.delegate, config.publication, config as HistoryModuleProperties, config.headerMenu ); - await pageBreak.start(); - return pageBreak; + await history.start(); + return history; } async stop() { @@ -134,8 +130,8 @@ export class HistoryModule implements ReaderModule { | undefined; if ( lastReadingPosition && - lastReadingPosition.locations.progression && - lastReadingPosition.locations.progression > 0 + lastReadingPosition?.locations.progression && + lastReadingPosition?.locations.progression > 0 ) { if (this.historyCurrentIndex < this.history.length - 1) { this.history = this.history.slice(0, this.historyCurrentIndex); @@ -172,8 +168,6 @@ export class HistoryModule implements ReaderModule { } protected async start(): Promise { - this.delegate.historyModule = this; - if (this.headerMenu) this.historyForwardAnchorElement = HTMLUtilities.findElement( this.headerMenu, @@ -210,7 +204,7 @@ export class HistoryModule implements ReaderModule { if (this.history.length > 0) { if (this.historyCurrentIndex + 1 < this.history.length) { this.historyCurrentIndex = this.historyCurrentIndex + 1; - await this.delegate.navigate( + await this.navigator.navigate( this.history[this.historyCurrentIndex], false ); @@ -228,7 +222,7 @@ export class HistoryModule implements ReaderModule { if (this.history.length > 0) { if (this.historyCurrentIndex > 0) { this.historyCurrentIndex = this.historyCurrentIndex - 1; - await this.delegate.navigate( + await this.navigator.navigate( this.history[this.historyCurrentIndex], false ); diff --git a/src/modules/linefocus/LineFocusModule.ts b/src/modules/linefocus/LineFocusModule.ts index 30c75468..22665d83 100644 --- a/src/modules/linefocus/LineFocusModule.ts +++ b/src/modules/linefocus/LineFocusModule.ts @@ -53,14 +53,13 @@ export interface LineFocusModuleProperties { export interface LineFocusModuleConfig extends LineFocusModuleProperties { api?: LineFocusModuleAPI; publication: Publication; - delegate: IFrameNavigator; highlighter: TextHighlighter; } export default class LineFocusModule implements ReaderModule { properties: LineFocusModuleProperties; api?: LineFocusModuleAPI; - private delegate: IFrameNavigator; + navigator: IFrameNavigator; private highlighter: TextHighlighter; private hasEventListener: boolean = false; @@ -76,7 +75,6 @@ export default class LineFocusModule implements ReaderModule { public static async create(config: LineFocusModuleConfig) { const search = new this( - config.delegate, config as LineFocusModuleProperties, config.highlighter, config.api @@ -87,12 +85,10 @@ export default class LineFocusModule implements ReaderModule { } private constructor( - delegate: IFrameNavigator, properties: LineFocusModuleProperties, highlighter: TextHighlighter, api?: LineFocusModuleAPI ) { - this.delegate = delegate; this.properties = properties; this.api = api; this.highlighter = highlighter; @@ -104,20 +100,18 @@ export default class LineFocusModule implements ReaderModule { removeEventListenerOptional(document, "keydown", this.keydown.bind(this)); removeEventListenerOptional(document, "keyup", this.keyup.bind(this)); removeEventListenerOptional( - this.delegate.iframes[0].contentDocument, + this.navigator.iframes[0].contentDocument, "keydown", this.keydown.bind(this) ); removeEventListenerOptional( - this.delegate.iframes[0].contentDocument, + this.navigator.iframes[0].contentDocument, "keyup", this.keyup.bind(this) ); } protected async start(): Promise { - this.delegate.lineFocusModule = this; - const wrapper = HTMLUtilities.findRequiredElement( document, "#iframe-wrapper" @@ -140,21 +134,27 @@ export default class LineFocusModule implements ReaderModule { this.readerContainer.style.overflow = "hidden"; } } - if (!this.hasEventListener) { - this.hasEventListener = true; - addEventListenerOptional(document, "keydown", this.keydown.bind(this)); - addEventListenerOptional(document, "keyup", this.keyup.bind(this)); - addEventListenerOptional( - this.delegate.iframes[0].contentDocument, - "keydown", - this.keydown.bind(this) - ); - addEventListenerOptional( - this.delegate.iframes[0].contentDocument, - "keyup", - this.keyup.bind(this) - ); - } + } + initialize() { + return new Promise(async (resolve) => { + await (document as any).fonts.ready; + if (!this.hasEventListener) { + this.hasEventListener = true; + addEventListenerOptional(document, "keydown", this.keydown.bind(this)); + addEventListenerOptional(document, "keyup", this.keyup.bind(this)); + addEventListenerOptional( + this.navigator.iframes[0].contentDocument, + "keydown", + this.keydown.bind(this) + ); + addEventListenerOptional( + this.navigator.iframes[0].contentDocument, + "keyup", + this.keyup.bind(this) + ); + } + resolve(null); + }); } private keydown(event: KeyboardEvent | MouseEvent | TouchEvent): void { @@ -193,7 +193,7 @@ export default class LineFocusModule implements ReaderModule { async enableLineFocus() { this.isActive = true; - await this.delegate.settings.scroll(true); + await this.navigator.settings.scroll(true); this.lineFocus(); } @@ -215,7 +215,7 @@ export default class LineFocusModule implements ReaderModule { this.index = 0; } - const doc = this.delegate.iframes[0].contentDocument; + const doc = this.navigator.iframes[0].contentDocument; const html = HTMLUtilities.findIframeElement( doc, "html" @@ -250,7 +250,7 @@ export default class LineFocusModule implements ReaderModule { "#iframe-wrapper" ) as HTMLDivElement; - const doc = this.delegate.iframes[0].contentDocument; + const doc = this.navigator.iframes[0].contentDocument; const html = HTMLUtilities.findIframeElement( doc, "html" @@ -421,10 +421,10 @@ export default class LineFocusModule implements ReaderModule { highlightArea.style.outline = "none"; highlightArea.tabIndex = 0; - const documant = (this.delegate.iframes[0].contentWindow as any) + const documant = (this.navigator.iframes[0].contentWindow as any) .document; - const paginated = this.delegate.view.isPaginated(); + const paginated = this.navigator.view.isPaginated(); if (paginated) { documant.body.style.position = "revert"; @@ -441,7 +441,7 @@ export default class LineFocusModule implements ReaderModule { let size = 24; let left, right; - let viewportWidth = this.delegate.iframes[0].contentWindow + let viewportWidth = this.navigator.iframes[0].contentWindow ?.innerWidth; let columnCount = parseInt( getComputedStyle(doc.documentElement).getPropertyValue( @@ -468,7 +468,7 @@ export default class LineFocusModule implements ReaderModule { ); } - let ratio = this.delegate.settings.fontSize / 100; + let ratio = this.navigator.settings.fontSize / 100; let addRight = 20 * ratio; if (ratio <= 1) { diff --git a/src/modules/mediaoverlays/MediaOverlayModule.ts b/src/modules/mediaoverlays/MediaOverlayModule.ts index 03e1c84f..b1497af2 100644 --- a/src/modules/mediaoverlays/MediaOverlayModule.ts +++ b/src/modules/mediaoverlays/MediaOverlayModule.ts @@ -55,14 +55,13 @@ export interface MediaOverlayModuleProperties { } export interface MediaOverlayModuleConfig extends MediaOverlayModuleProperties { publication: Publication; - delegate: IFrameNavigator; settings: MediaOverlaySettings; api?: MediaOverlayModuleAPI; } export class MediaOverlayModule implements ReaderModule { private publication: Publication; - private delegate: IFrameNavigator; + navigator: IFrameNavigator; private audioElement: HTMLMediaElement; settings: MediaOverlaySettings; private properties: MediaOverlayModuleProperties; @@ -89,7 +88,6 @@ export class MediaOverlayModule implements ReaderModule { public static create(config: MediaOverlayModuleConfig) { const mediaOverlay = new this( - config.delegate, config.publication, config.settings, config as MediaOverlayModuleProperties @@ -99,12 +97,10 @@ export class MediaOverlayModule implements ReaderModule { } private constructor( - delegate: IFrameNavigator, publication: Publication, settings: MediaOverlaySettings, properties: MediaOverlayModuleProperties ) { - this.delegate = delegate; this.publication = publication; this.settings = settings; this.properties = properties; @@ -115,7 +111,6 @@ export class MediaOverlayModule implements ReaderModule { } protected start() { - this.delegate.mediaOverlayModule = this; log.log("MediaOverlay module start"); } @@ -149,7 +144,7 @@ export class MediaOverlayModule implements ReaderModule { let response: Response; try { - response = await fetch(moUrlFull, this.delegate.requestConfig); + response = await fetch(moUrlFull, this.navigator.requestConfig); } catch (e) { console.error(e, moUrlFull); return; @@ -195,7 +190,7 @@ export class MediaOverlayModule implements ReaderModule { if (this.audioElement) { await this.audioElement.pause(); } - this.delegate.nextResource(); + this.navigator.nextResource(); } else { await this.stopReadAloud(); } @@ -204,7 +199,7 @@ export class MediaOverlayModule implements ReaderModule { } async startReadAloud() { - if (this.delegate.rights.enableMediaOverlays) { + if (this.navigator.rights.enableMediaOverlays) { this.settings.playing = true; if ( this.audioElement && @@ -224,7 +219,7 @@ export class MediaOverlayModule implements ReaderModule { await this.playLink(); } else { if (this.settings.autoTurn && this.settings.playing) { - this.delegate.nextResource(); + this.navigator.nextResource(); } else { await this.stopReadAloud(); } @@ -235,7 +230,7 @@ export class MediaOverlayModule implements ReaderModule { } } async stopReadAloud() { - if (this.delegate.rights.enableMediaOverlays) { + if (this.navigator.rights.enableMediaOverlays) { this.settings.playing = false; this.audioElement.pause(); @@ -244,7 +239,7 @@ export class MediaOverlayModule implements ReaderModule { } } pauseReadAloud() { - if (this.delegate.rights.enableMediaOverlays) { + if (this.navigator.rights.enableMediaOverlays) { this.settings.playing = false; this.audioElement.pause(); if (this.play) this.play.style.removeProperty("display"); @@ -252,7 +247,7 @@ export class MediaOverlayModule implements ReaderModule { } } async resumeReadAloud() { - if (this.delegate.rights.enableMediaOverlays) { + if (this.navigator.rights.enableMediaOverlays) { this.settings.playing = true; await this.audioElement.play(); if (this.play) this.play.style.display = "none"; @@ -386,7 +381,7 @@ export class MediaOverlayModule implements ReaderModule { this.audioElement.pause(); if (this.settings.autoTurn && this.settings.playing) { this.audioElement.pause(); - this.delegate.nextResource(); + this.navigator.nextResource(); } else { this.stopReadAloud(); } @@ -434,7 +429,7 @@ export class MediaOverlayModule implements ReaderModule { this.audioElement.pause(); if (this.settings.autoTurn && this.settings.playing) { this.audioElement.pause(); - this.delegate.nextResource(); + this.navigator.nextResource(); } else { this.stopReadAloud(); } @@ -706,7 +701,7 @@ export class MediaOverlayModule implements ReaderModule { } else { if (this.settings.autoTurn && this.settings.playing) { this.audioElement.pause(); - this.delegate.nextResource(); + this.navigator.nextResource(); } else { this.stopReadAloud(); } @@ -804,7 +799,7 @@ export class MediaOverlayModule implements ReaderModule { if (!classActive) { classActive = this.settings.color; } - const styleAttr = this.delegate.iframes[0].contentDocument?.documentElement.getAttribute( + const styleAttr = this.navigator.iframes[0].contentDocument?.documentElement.getAttribute( "style" ); const isNight = styleAttr @@ -829,11 +824,11 @@ export class MediaOverlayModule implements ReaderModule { let prevElement; if (this.currentLinkIndex === 0) { - prevElement = this.delegate.iframes[0].contentDocument?.getElementById( + prevElement = this.navigator.iframes[0].contentDocument?.getElementById( this.pid ); } else { - prevElement = this.delegate.iframes[1].contentDocument?.getElementById( + prevElement = this.navigator.iframes[1].contentDocument?.getElementById( this.pid ); } @@ -846,9 +841,9 @@ export class MediaOverlayModule implements ReaderModule { let current; if (id) { if (this.currentLinkIndex === 0) { - current = this.delegate.iframes[0].contentDocument?.getElementById(id); + current = this.navigator.iframes[0].contentDocument?.getElementById(id); } else { - current = this.delegate.iframes[1].contentDocument?.getElementById(id); + current = this.navigator.iframes[1].contentDocument?.getElementById(id); } if (current) { current.classList.add(classActive); diff --git a/src/modules/pagebreak/PageBreakModule.ts b/src/modules/pagebreak/PageBreakModule.ts index 5a9ec4f8..a4db2919 100644 --- a/src/modules/pagebreak/PageBreakModule.ts +++ b/src/modules/pagebreak/PageBreakModule.ts @@ -40,13 +40,12 @@ export interface PageBreakModuleProperties { } export interface PageBreakModuleConfig extends PageBreakModuleProperties { - delegate: IFrameNavigator; headerMenu?: HTMLElement | null; publication: Publication; } export class PageBreakModule implements ReaderModule { - private delegate: IFrameNavigator; + navigator: IFrameNavigator; private readonly headerMenu?: HTMLElement | null; private publication: Publication; private properties: PageBreakModuleProperties; @@ -57,7 +56,6 @@ export class PageBreakModule implements ReaderModule { public static async create(config: PageBreakModuleConfig) { const pageBreak = new this( - config.delegate, config.publication, config as PageBreakModuleProperties, config.headerMenu @@ -67,13 +65,11 @@ export class PageBreakModule implements ReaderModule { } private constructor( - delegate: IFrameNavigator, publication: Publication, properties: PageBreakModuleProperties, headerMenu?: HTMLElement | null ) { this.headerMenu = headerMenu; - this.delegate = delegate; this.publication = publication; this.properties = properties; } @@ -83,8 +79,6 @@ export class PageBreakModule implements ReaderModule { } protected async start(): Promise { - this.delegate.pageBreakModule = this; - if (this.headerMenu) this.goToPageView = HTMLUtilities.findElement( this.headerMenu, @@ -121,8 +115,8 @@ export class PageBreakModule implements ReaderModule { } setTimeout(() => { this.properties.hideLayer - ? this.delegate.hideLayer("pagebreak") - : this.delegate.showLayer("pagebreak"); + ? this.navigator.hideLayer("pagebreak") + : this.navigator.showLayer("pagebreak"); }, 10); } async goToPageNumber(event: any): Promise { @@ -157,19 +151,21 @@ export class PageBreakModule implements ReaderModule { title: firstPage.Title, }; - this.delegate.goTo(position); + this.navigator.goTo(position); } } } async handleResize() { - await this.delegate.highlighter?.destroyHighlights(HighlightType.PageBreak); + await this.navigator.highlighter?.destroyHighlights( + HighlightType.PageBreak + ); await this.drawPageBreaks(); } async drawPageBreaks() { setTimeout(() => { - const body = this.delegate.iframes[0].contentDocument?.body; + const body = this.navigator.iframes[0].contentDocument?.body; let pageBreaks = body?.querySelectorAll('[*|type="pagebreak"]'); if (pageBreaks?.length === 0) { pageBreaks = body?.querySelectorAll("[epub\\:type='pagebreak']"); @@ -178,7 +174,7 @@ export class PageBreakModule implements ReaderModule { function getCssSelector(element: Element): string { try { - let doc = self.delegate.iframes[0].contentDocument; + let doc = self.navigator.iframes[0].contentDocument; if (doc) { return uniqueCssSelector(element, doc, _getCssSelectorOptions); } else { @@ -207,13 +203,13 @@ export class PageBreakModule implements ReaderModule { img.innerHTML = title; hide = true; } - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { - const range = this.delegate.highlighter + const range = this.navigator.highlighter ?.dom(doc.body) .getWindow() .document.createRange(); - const selection = this.delegate.highlighter + const selection = this.navigator.highlighter ?.dom(doc.body) .getSelection(); selection.removeAllRanges(); @@ -266,8 +262,8 @@ export class PageBreakModule implements ReaderModule { }; _highlights.push(highlight); - let highlightDom = this.delegate.highlighter?.createHighlightDom( - this.delegate.iframes[0].contentWindow as any, + let highlightDom = this.navigator.highlighter?.createHighlightDom( + this.navigator.iframes[0].contentWindow as any, highlight ); highlight.position = parseInt( diff --git a/src/modules/positions/TimelineModule.ts b/src/modules/positions/TimelineModule.ts index 3f1280d6..d7f27bd7 100644 --- a/src/modules/positions/TimelineModule.ts +++ b/src/modules/positions/TimelineModule.ts @@ -28,23 +28,21 @@ import log from "loglevel"; export interface TimelineModuleConfig { publication: Publication; - delegate: IFrameNavigator; } export class TimelineModule implements ReaderModule { private publication: Publication; - private delegate: IFrameNavigator; + navigator: IFrameNavigator; private timelineContainer: HTMLDivElement; private positionSlider: HTMLInputElement; public static async create(config: TimelineModuleConfig) { - const timeline = new this(config.delegate, config.publication); + const timeline = new this(config.publication); await timeline.start(); return timeline; } - private constructor(delegate: IFrameNavigator, publication: Publication) { - this.delegate = delegate; + private constructor(publication: Publication) { this.publication = publication; } @@ -53,8 +51,6 @@ export class TimelineModule implements ReaderModule { } protected async start(): Promise { - this.delegate.timelineModule = this; - this.timelineContainer = HTMLUtilities.findElement( document, "#container-view-timeline" @@ -75,9 +71,9 @@ export class TimelineModule implements ReaderModule { return new Promise(async (resolve) => { await (document as any).fonts.ready; - let locator = this.delegate.currentLocator(); + let locator = this.navigator.currentLocator(); if ( - (this.delegate.rights.autoGeneratePositions && + (this.navigator.rights.autoGeneratePositions && this.publication.positions) || this.publication.positions ) { @@ -107,7 +103,7 @@ export class TimelineModule implements ReaderModule { var chapterHeight; if ( this.publication.positions && - this.delegate.view?.layout !== "fixed" + this.navigator.view?.layout !== "fixed" ) { if ((link as Link).contentWeight) { chapterHeight = (link as Link).contentWeight; @@ -136,7 +132,7 @@ export class TimelineModule implements ReaderModule { var position; if ( this.publication.positions || - (this.delegate.rights.autoGeneratePositions && + (this.navigator.rights.autoGeneratePositions && this.publication.positions) ) { position = { @@ -156,10 +152,10 @@ export class TimelineModule implements ReaderModule { }; } log.log(position); - this.delegate.navigate(position); + this.navigator.navigate(position); }); - if (tocHrefAbs === this.delegate.currentChapterLink.href) { + if (tocHrefAbs === this.navigator.currentChapterLink.href) { chapter.className += " active"; } else { chapter.className = chapter.className.replace(" active", ""); diff --git a/src/modules/protection/ContentProtectionModule.ts b/src/modules/protection/ContentProtectionModule.ts index 2371bfa8..9b20a89f 100644 --- a/src/modules/protection/ContentProtectionModule.ts +++ b/src/modules/protection/ContentProtectionModule.ts @@ -53,7 +53,6 @@ export interface ContentProtectionModuleProperties { export interface ContentProtectionModuleConfig extends Partial { - delegate: IFrameNavigator; api?: ContentProtectionModuleAPI; } @@ -74,7 +73,7 @@ interface ContentProtectionRect { export class ContentProtectionModule implements ReaderModule { private rects: Array; - private delegate: IFrameNavigator; + navigator: IFrameNavigator; properties?: ContentProtectionModuleProperties; private hasEventListener: boolean = false; private isHacked: boolean = false; @@ -95,19 +94,12 @@ export class ContentProtectionModule implements ReaderModule { } public static async create(config: ContentProtectionModuleConfig) { - const security = new this( - config.delegate, - config as ContentProtectionModuleProperties - ); + const security = new this(config as ContentProtectionModuleProperties); await security.start(); return security; } - public constructor( - delegate: IFrameNavigator, - properties?: ContentProtectionModuleProperties - ) { - this.delegate = delegate; + public constructor(properties?: ContentProtectionModuleProperties) { this.properties = properties; } @@ -155,8 +147,6 @@ export class ContentProtectionModule implements ReaderModule { } protected async start(): Promise { - this.delegate.contentProtectionModule = this; - if (this.properties?.enableObfuscation) { this.wrapper = HTMLUtilities.findRequiredElement( document, @@ -187,16 +177,16 @@ export class ContentProtectionModule implements ReaderModule { } if (this.properties?.disableKeys) { removeEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "keydown", this.disableSave ); removeEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "keydown", this.disableSave ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { removeEventListenerOptional( iframe.contentDocument, "keydown", @@ -214,16 +204,16 @@ export class ContentProtectionModule implements ReaderModule { if (this.properties?.disableCopy) { removeEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "copy", this.preventCopy ); removeEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "copy", this.preventCopy ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { removeEventListenerOptional( iframe.contentDocument, "copy", @@ -239,16 +229,16 @@ export class ContentProtectionModule implements ReaderModule { removeEventListenerOptional(window, "copy", this.preventCopy); removeEventListenerOptional(document, "copy", this.preventCopy); removeEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "cut", this.preventCopy ); removeEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "cut", this.preventCopy ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { removeEventListenerOptional( iframe.contentDocument, "cut", @@ -263,16 +253,16 @@ export class ContentProtectionModule implements ReaderModule { removeEventListenerOptional(window, "cut", this.preventCopy); removeEventListenerOptional(document, "cut", this.preventCopy); removeEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "keydown", this.preventCopyKey ); removeEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "keydown", this.preventCopyKey ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { removeEventListenerOptional( iframe.contentDocument, "keydown", @@ -288,16 +278,16 @@ export class ContentProtectionModule implements ReaderModule { removeEventListenerOptional(document, "keydown", this.preventCopyKey); } else if (this.properties?.canCopy) { removeEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "copy", this.restrictCopy ); removeEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "copy", this.restrictCopy ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { removeEventListenerOptional( iframe.contentDocument, "copy", @@ -313,16 +303,16 @@ export class ContentProtectionModule implements ReaderModule { removeEventListenerOptional(window, "copy", this.restrictCopy); removeEventListenerOptional(document, "copy", this.restrictCopy); removeEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "cut", this.restrictCopy ); removeEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "cut", this.restrictCopy ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { removeEventListenerOptional( iframe.contentDocument, "cut", @@ -337,16 +327,16 @@ export class ContentProtectionModule implements ReaderModule { removeEventListenerOptional(window, "cut", this.restrictCopy); removeEventListenerOptional(document, "cut", this.restrictCopy); removeEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "keydown", this.restrictCopyKey ); removeEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "keydown", this.restrictCopyKey ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { removeEventListenerOptional( iframe.contentDocument, "keydown", @@ -363,16 +353,16 @@ export class ContentProtectionModule implements ReaderModule { } if (this.properties?.disablePrint) { removeEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "beforeprint", this.beforePrint.bind(this) ); removeEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "beforeprint", this.beforePrint.bind(this) ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { removeEventListenerOptional( iframe.contentDocument, "beforeprint", @@ -387,16 +377,16 @@ export class ContentProtectionModule implements ReaderModule { removeEventListenerOptional(window, "beforeprint", this.beforePrint); removeEventListenerOptional(document, "beforeprint", this.beforePrint); removeEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "afterprint", this.afterPrint.bind(this) ); removeEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "afterprint", this.afterPrint.bind(this) ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { removeEventListenerOptional( iframe.contentDocument, "afterprint", @@ -421,16 +411,16 @@ export class ContentProtectionModule implements ReaderModule { } if (this.properties?.disableContextMenu) { removeEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "contextmenu", this.disableContext ); removeEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "contextmenu", this.disableContext ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { removeEventListenerOptional( iframe.contentDocument, "contextmenu", @@ -488,7 +478,7 @@ export class ContentProtectionModule implements ReaderModule { public async activate() { if (this.properties?.enableObfuscation) { this.observe(); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { if (iframe.contentDocument) { const body = HTMLUtilities.findRequiredIframeElement( iframe.contentDocument, @@ -505,16 +495,16 @@ export class ContentProtectionModule implements ReaderModule { private setupEvents(): void { if (this.properties?.disableKeys) { addEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "keydown", this.disableSave ); addEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "keydown", this.disableSave ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { addEventListenerOptional(iframe, "keydown", this.disableSave); addEventListenerOptional( iframe.ownerDocument, @@ -542,16 +532,16 @@ export class ContentProtectionModule implements ReaderModule { } if (this.properties?.disableCopy) { addEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "copy", this.preventCopy ); addEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "copy", this.preventCopy ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { addEventListenerOptional(iframe, "copy", this.preventCopy); addEventListenerOptional( iframe.ownerDocument, @@ -578,16 +568,16 @@ export class ContentProtectionModule implements ReaderModule { addEventListenerOptional(document, "copy", this.preventCopy); addEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "cut", this.preventCopy ); addEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "cut", this.preventCopy ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { addEventListenerOptional(iframe, "cut", this.preventCopy); addEventListenerOptional(iframe.ownerDocument, "cut", this.preventCopy); addEventListenerOptional( @@ -606,16 +596,16 @@ export class ContentProtectionModule implements ReaderModule { addEventListenerOptional(window, "cut", this.preventCopy); addEventListenerOptional(document, "cut", this.preventCopy); addEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "keydown", this.preventCopyKey ); addEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "keydown", this.preventCopyKey ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { addEventListenerOptional(iframe, "keydown", this.preventCopyKey); addEventListenerOptional( iframe.ownerDocument, @@ -642,16 +632,16 @@ export class ContentProtectionModule implements ReaderModule { addEventListenerOptional(document, "keydown", this.preventCopyKey); } else if (this.properties?.canCopy) { addEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "copy", this.restrictCopy.bind(this) ); addEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "copy", this.restrictCopy.bind(this) ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { addEventListenerOptional(iframe, "copy", this.restrictCopy); addEventListenerOptional( iframe.ownerDocument, @@ -678,16 +668,16 @@ export class ContentProtectionModule implements ReaderModule { addEventListenerOptional(document, "copy", this.restrictCopy.bind(this)); addEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "cut", this.restrictCopy.bind(this) ); addEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "cut", this.restrictCopy.bind(this) ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { addEventListenerOptional(iframe, "cut", this.restrictCopy.bind(this)); addEventListenerOptional( iframe.ownerDocument, @@ -714,16 +704,16 @@ export class ContentProtectionModule implements ReaderModule { addEventListenerOptional(window, "cut", this.restrictCopy.bind(this)); addEventListenerOptional(document, "cut", this.restrictCopy.bind(this)); addEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "keydown", this.restrictCopyKey.bind(this) ); addEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "keydown", this.restrictCopyKey.bind(this) ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { addEventListenerOptional( iframe, "keydown", @@ -763,16 +753,16 @@ export class ContentProtectionModule implements ReaderModule { } if (this.properties?.disablePrint) { addEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "beforeprint", this.beforePrint ); addEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "beforeprint", this.beforePrint ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { addEventListenerOptional( iframe, "beforeprint", @@ -811,16 +801,16 @@ export class ContentProtectionModule implements ReaderModule { ); addEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "afterprint", this.afterPrint ); addEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "afterprint", this.afterPrint ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { addEventListenerOptional( iframe, "afterprint", @@ -860,16 +850,16 @@ export class ContentProtectionModule implements ReaderModule { } if (this.properties?.disableContextMenu) { addEventListenerOptional( - this.delegate.mainElement, + this.navigator.mainElement, "contextmenu", this.disableContext ); addEventListenerOptional( - this.delegate.headerMenu, + this.navigator.headerMenu, "contextmenu", this.disableContext ); - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { addEventListenerOptional(iframe, "contextmenu", this.disableContext); addEventListenerOptional( iframe.ownerDocument, @@ -910,7 +900,7 @@ export class ContentProtectionModule implements ReaderModule { if (this.properties?.enableObfuscation) { return new Promise(async (resolve) => { await (document as any).fonts.ready; - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { if (iframe.contentDocument) { const body = HTMLUtilities.findRequiredIframeElement( iframe.contentDocument, @@ -1034,7 +1024,7 @@ export class ContentProtectionModule implements ReaderModule { return; } log.log("copy action initiated"); - let win = this.delegate.iframes[0].contentWindow; + let win = this.navigator.iframes[0].contentWindow; if (win) { let self = this; function getCssSelector(element: Element): string | undefined { @@ -1046,7 +1036,7 @@ export class ContentProtectionModule implements ReaderModule { return _blacklistIdClassForCssSelectors.indexOf(str) < 0; }, }; - let doc = self.delegate.iframes[0].contentDocument; + let doc = self.navigator.iframes[0].contentDocument; if (doc) { return uniqueCssSelector(element, doc, options); } else { @@ -1055,8 +1045,8 @@ export class ContentProtectionModule implements ReaderModule { } let selectionInfo = getCurrentSelectionInfo(win, getCssSelector); if (selectionInfo === undefined) { - let doc = this.delegate.iframes[0].contentDocument; - selectionInfo = this.delegate.annotationModule?.annotator?.getTemporarySelectionInfo( + let doc = this.navigator.iframes[0].contentDocument; + selectionInfo = this.navigator.annotationModule?.annotator?.getTemporarySelectionInfo( doc ); } @@ -1082,7 +1072,7 @@ export class ContentProtectionModule implements ReaderModule { ? event.metaKey : event.ctrlKey && (event.key === "c" || event.keyCode === 67) ) { - let win = this.delegate.iframes[0].contentWindow; + let win = this.navigator.iframes[0].contentWindow; if (win) { let self = this; function getCssSelector(element: Element): string | undefined { @@ -1094,7 +1084,7 @@ export class ContentProtectionModule implements ReaderModule { return _blacklistIdClassForCssSelectors.indexOf(str) < 0; }, }; - let doc = self.delegate.iframes[0].contentDocument; + let doc = self.navigator.iframes[0].contentDocument; if (doc) { return uniqueCssSelector(element, doc, options); } else { @@ -1103,8 +1093,8 @@ export class ContentProtectionModule implements ReaderModule { } let selectionInfo = getCurrentSelectionInfo(win, getCssSelector); if (selectionInfo === undefined) { - let doc = this.delegate.iframes[0].contentDocument; - selectionInfo = this.delegate.annotationModule?.annotator?.getTemporarySelectionInfo( + let doc = this.navigator.iframes[0].contentDocument; + selectionInfo = this.navigator.annotationModule?.annotator?.getTemporarySelectionInfo( doc ); } @@ -1204,9 +1194,9 @@ export class ContentProtectionModule implements ReaderModule { }) { log.log("before print"); - if (this.delegate && this.delegate.headerMenu) { - this.delegate.headerMenu.style.display = "none"; - this.delegate.mainElement.style.display = "none"; + if (this.navigator && this.navigator.headerMenu) { + this.navigator.headerMenu.style.display = "none"; + this.navigator.mainElement.style.display = "none"; } event.stopPropagation(); @@ -1219,9 +1209,9 @@ export class ContentProtectionModule implements ReaderModule { }) { log.log("after print"); - if (this.delegate && this.delegate.headerMenu) { - this.delegate.headerMenu.style.removeProperty("display"); - this.delegate.mainElement.style.removeProperty("display"); + if (this.navigator && this.navigator.headerMenu) { + this.navigator.headerMenu.style.removeProperty("display"); + this.navigator.mainElement.style.removeProperty("display"); } event.stopPropagation(); @@ -1237,7 +1227,7 @@ export class ContentProtectionModule implements ReaderModule { aElement.setAttribute("href", href); aElement.click(); } - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { const aElements = iframe.contentDocument?.querySelectorAll("a"); aElements?.forEach((aElement) => { @@ -1272,7 +1262,7 @@ export class ContentProtectionModule implements ReaderModule { const onDragstart = (evt) => { evt.preventDefault(); }; - for (const iframe of this.delegate.iframes) { + for (const iframe of this.navigator.iframes) { const bodyStyle = iframe.contentDocument?.body.getAttribute("style") || ""; diff --git a/src/modules/sampleread/SampleReadEventHandler.ts b/src/modules/sampleread/SampleReadEventHandler.ts index c379a91e..c7c83d06 100644 --- a/src/modules/sampleread/SampleReadEventHandler.ts +++ b/src/modules/sampleread/SampleReadEventHandler.ts @@ -21,21 +21,21 @@ import { debounce } from "debounce"; import { IFrameNavigator } from "../../navigator/IFrameNavigator"; export default class SampleReadEventHandler { - delegate: IFrameNavigator; - constructor(delegate: IFrameNavigator) { - this.delegate = delegate; + navigator: IFrameNavigator; + constructor(navigator: IFrameNavigator) { + this.navigator = navigator; } enforceSampleRead = debounce((position) => { let progress = Math.round(position.locations.totalProgression * 100); let valid = false; - if (this.delegate.sample?.limit) { - valid = progress <= this.delegate.sample?.limit; - if (this.delegate.view?.layout === "fixed") { + if (this.navigator.sample?.limit) { + valid = progress <= this.navigator.sample?.limit; + if (this.navigator.view?.layout === "fixed") { if ( !valid && - this.delegate.sample?.minimum && - position.locations.position <= this.delegate.sample?.minimum + this.navigator.sample?.minimum && + position.locations.position <= this.navigator.sample?.minimum ) { valid = true; } @@ -139,18 +139,19 @@ export default class SampleReadEventHandler { window.addEventListener("touchstart", TouchStartHandler, wheelOpt); if (!valid) { - this.delegate.iframes[0].blur(); - if (this.delegate.errorMessage) { - this.delegate.errorMessage.style.display = "block"; - this.delegate.errorMessage.style.backgroundColor = "rgb(255, 255, 255)"; - this.delegate.errorMessage.innerHTML = - this.delegate.sample?.popup ?? ""; + this.navigator.iframes[0].blur(); + if (this.navigator.errorMessage) { + this.navigator.errorMessage.style.display = "block"; + this.navigator.errorMessage.style.backgroundColor = + "rgb(255, 255, 255)"; + this.navigator.errorMessage.innerHTML = + this.navigator.sample?.popup ?? ""; } } else { - this.delegate.iframes[0].focus(); - if (this.delegate.errorMessage) { - this.delegate.errorMessage.style.display = "none"; - this.delegate.errorMessage.style.removeProperty("background-color"); + this.navigator.iframes[0].focus(); + if (this.navigator.errorMessage) { + this.navigator.errorMessage.style.display = "none"; + this.navigator.errorMessage.style.removeProperty("background-color"); } } }, 300); diff --git a/src/modules/search/DefinitionsModule.ts b/src/modules/search/DefinitionsModule.ts index 160b441c..a0e34afa 100644 --- a/src/modules/search/DefinitionsModule.ts +++ b/src/modules/search/DefinitionsModule.ts @@ -58,7 +58,6 @@ export interface DefinitionsModuleProperties { export interface DefinitionsModuleConfig extends DefinitionsModuleProperties { api?: DefinitionsModuleAPI; publication: Publication; - delegate: IFrameNavigator; highlighter: TextHighlighter; } @@ -67,14 +66,13 @@ export class DefinitionsModule implements ReaderModule { // @ts-ignore api?: DefinitionsModuleAPI; private publication: Publication; - private delegate: IFrameNavigator; + navigator: IFrameNavigator; private currentChapterPopupResult: any = []; private currentPopupHighlights: any = []; private highlighter: TextHighlighter; public static async create(config: DefinitionsModuleConfig) { const search = new this( - config.delegate, config.publication, config as DefinitionsModuleProperties, config.highlighter, @@ -86,13 +84,11 @@ export class DefinitionsModule implements ReaderModule { } private constructor( - delegate: IFrameNavigator, publication: Publication, properties: DefinitionsModuleProperties, highlighter: TextHighlighter, api?: DefinitionsModuleAPI ) { - this.delegate = delegate; this.publication = publication; this.properties = properties; this.api = api; @@ -104,25 +100,24 @@ export class DefinitionsModule implements ReaderModule { } protected async start(): Promise { - this.delegate.definitionsModule = this; setTimeout(() => { this.properties.hideLayer - ? this.delegate.hideLayer("definitions") - : this.delegate.showLayer("definitions"); + ? this.navigator.hideLayer("definitions") + : this.navigator.showLayer("definitions"); }, 10); } async searchAndPaint(item: Definition, callback: (result: any) => any) { const linkHref = this.publication.getAbsoluteHref( this.publication.readingOrder - ? this.publication.readingOrder[this.delegate.currentResource() ?? 0] + ? this.publication.readingOrder[this.navigator.currentResource() ?? 0] .Href : "" ); let tocItem = this.publication.getTOCItem(linkHref); if (tocItem === undefined && this.publication.readingOrder) { tocItem = this.publication.readingOrder[ - this.delegate.currentResource() ?? 0 + this.navigator.currentResource() ?? 0 ]; } let localSearchDefinitions: any = []; @@ -133,10 +128,10 @@ export class DefinitionsModule implements ReaderModule { if (tocItem) { await searchDocDomSeek( termKey, - this.delegate.iframes[0].contentDocument, + this.navigator.iframes[0].contentDocument, tocItem.Href, tocItem.Title, - this.delegate.definitionsModule?.properties.fullWordSearch + this.navigator.definitionsModule?.properties.fullWordSearch ).then((result) => { let i: number | undefined = undefined; if (item.result === 1) { @@ -184,11 +179,11 @@ export class DefinitionsModule implements ReaderModule { await this.searchAndPaint(item, async (result) => { if (this.api?.success) { this.api?.success(lodash.omit(item, "callbacks"), result); - this.delegate.emit("definition.success", result); + this.navigator.emit("definition.success", result); if (this.api?.visible) { result.forEach((highlight) => { - let highlightParent = this.delegate.iframes[0].contentDocument?.querySelector( + let highlightParent = this.navigator.iframes[0].contentDocument?.querySelector( `#${highlight.id}` ); const highlightFragments = highlightParent?.querySelectorAll( @@ -202,7 +197,7 @@ export class DefinitionsModule implements ReaderModule { lodash.omit(item, "callbacks"), lodash.omit(highlight, "definition") ); - this.delegate.emit("definition.visible", item, highlight); + this.navigator.emit("definition.visible", item, highlight); } }); }, @@ -228,7 +223,7 @@ export class DefinitionsModule implements ReaderModule { } createDefinitionHighlight(selectionInfo: ISelectionInfo, item: Definition) { try { - let createColor: any = this.delegate.definitionsModule?.properties.color; + let createColor: any = this.navigator.definitionsModule?.properties.color; if (TextHighlighter.isHexColor(createColor)) { createColor = TextHighlighter.hexToRgbChannels(createColor); } @@ -237,7 +232,7 @@ export class DefinitionsModule implements ReaderModule { const sha256Hex = SHA256.hash(uniqueStr); const id = "R2_DEFINITION_" + sha256Hex; this.highlighter.destroyHighlight( - this.delegate.iframes[0].contentDocument, + this.navigator.iframes[0].contentDocument, id ); @@ -252,7 +247,7 @@ export class DefinitionsModule implements ReaderModule { _highlights.push(highlight); let highlightDom = this.highlighter.createHighlightDom( - this.delegate.iframes[0].contentWindow as any, + this.navigator.iframes[0].contentWindow as any, highlight ); if (highlightDom) { diff --git a/src/modules/search/SearchModule.ts b/src/modules/search/SearchModule.ts index c0a751ab..e2e72d5b 100644 --- a/src/modules/search/SearchModule.ts +++ b/src/modules/search/SearchModule.ts @@ -48,7 +48,6 @@ export interface SearchModuleConfig extends SearchModuleProperties { api?: SearchModuleAPI; publication: Publication; headerMenu?: HTMLElement | null; - delegate: IFrameNavigator; highlighter: TextHighlighter; } @@ -58,7 +57,7 @@ export class SearchModule implements ReaderModule { private api?: SearchModuleAPI; private publication: Publication; private readonly headerMenu?: HTMLElement | null; - private delegate: IFrameNavigator; + navigator: IFrameNavigator; private searchInput: HTMLInputElement; private searchGo: HTMLElement; private currentChapterSearchResult: any = []; @@ -68,7 +67,6 @@ export class SearchModule implements ReaderModule { public static async create(config: SearchModuleConfig) { const search = new this( - config.delegate, config.publication, config as SearchModuleProperties, config.highlighter, @@ -81,14 +79,12 @@ export class SearchModule implements ReaderModule { } private constructor( - delegate: IFrameNavigator, publication: Publication, properties: SearchModuleProperties, highlighter: TextHighlighter, api?: SearchModuleAPI, headerMenu?: HTMLElement | null ) { - this.delegate = delegate; this.headerMenu = headerMenu; this.publication = publication; this.properties = properties; @@ -111,8 +107,6 @@ export class SearchModule implements ReaderModule { } protected async start(): Promise { - this.delegate.searchModule = this; - if (this.headerMenu) { this.searchInput = HTMLUtilities.findElement( this.headerMenu, @@ -140,8 +134,8 @@ export class SearchModule implements ReaderModule { } setTimeout(() => { this.properties.hideLayer - ? this.delegate.hideLayer("search") - : this.delegate.showLayer("search"); + ? this.navigator.hideLayer("search") + : this.navigator.showLayer("search"); }, 10); } @@ -155,7 +149,7 @@ export class SearchModule implements ReaderModule { async handleSearchChapter(index?: number) { var self = this; var searchVal = this.searchInput.value; - let currentLocation = this.delegate.currentChapterLink.href; + let currentLocation = this.navigator.currentChapterLink.href; const spineItem = this.publication.getSpineItem(currentLocation); if (this.headerMenu) { var searchResultDiv = HTMLUtilities.findElement( @@ -167,14 +161,14 @@ export class SearchModule implements ReaderModule { self.currentChapterSearchResult = []; self.currentSearchHighlights = []; var localSearchResultChapter: any = []; - if (this.delegate.rights.enableContentProtection) { - this.delegate.contentProtectionModule?.deactivate(); + if (this.navigator.rights.enableContentProtection) { + this.navigator.contentProtectionModule?.deactivate(); } await this.searchAndPaintChapter(searchVal, index, async (result) => { localSearchResultChapter = result; goToResultPage(1); - if (this.delegate.rights.enableContentProtection) { - this.delegate.contentProtectionModule?.recalculate(200); + if (this.navigator.rights.enableContentProtection) { + this.navigator.contentProtectionModule?.recalculate(200); } }); @@ -299,24 +293,24 @@ export class SearchModule implements ReaderModule { callback: (result: any) => any ) { const linkHref = this.publication.getAbsoluteHref( - this.publication.readingOrder[this.delegate.currentResource() ?? 0].Href + this.publication.readingOrder[this.navigator.currentResource() ?? 0].Href ); let tocItem = this.publication.getTOCItem(linkHref); if (tocItem === null) { tocItem = this.publication.readingOrder[ - this.delegate.currentResource() ?? 0 + this.navigator.currentResource() ?? 0 ]; } let localSearchResultChapter: any = []; // clear search results // needs more works this.highlighter?.destroyHighlights(HighlightType.Search); - if (this.delegate.rights.enableSearch) { + if (this.navigator.rights.enableSearch) { this.drawSearch(); } let i = 0; if (tocItem) { - let doc = this.delegate.iframes[0].contentDocument; + let doc = this.navigator.iframes[0].contentDocument; if (doc) { if (tocItem) { searchDocDomSeek(term, doc, tocItem.Href, tocItem.Title).then( @@ -378,7 +372,7 @@ export class SearchModule implements ReaderModule { }; let highlightDom = this.highlighter?.createHighlightDom( - this.delegate.iframes[0].contentWindow as any, + this.navigator.iframes[0].contentWindow as any, highlight ); highlight.position = parseInt( @@ -417,7 +411,7 @@ export class SearchModule implements ReaderModule { async goToSearchID(href: string, index: number, current: boolean) { var filteredIndex = index; var item; - let currentLocation = this.delegate.currentChapterLink.href; + let currentLocation = this.navigator.currentChapterLink.href; var absolutehref = this.publication.getAbsoluteHref(href); let filteredIndexes = this.bookSearchResult.filter( (el: any) => el.href === href @@ -451,7 +445,7 @@ export class SearchModule implements ReaderModule { // position.locations.totalProgression = self.delegate.calculateTotalProgresion(position) // position.locations.index = filteredIndex - this.delegate.navigate(position); + this.navigator.navigate(position); // Navigate to new chapter and search only in new current chapter, // this should refresh thesearch result of current chapter and highlight the selected index setTimeout(() => { @@ -468,7 +462,7 @@ export class SearchModule implements ReaderModule { async goToSearchIndex(href: string, index: number, current: boolean) { var filteredIndex = index; var item; - let currentLocation = this.delegate.currentChapterLink.href; + let currentLocation = this.navigator.currentChapterLink.href; var absolutehref = this.publication.getAbsoluteHref(href); let filteredIndexes = this.bookSearchResult.filter( (el: any) => el.href === href @@ -497,7 +491,7 @@ export class SearchModule implements ReaderModule { // position.locations.totalProgression = self.delegate.calculateTotalProgresion(position) // position.locations.index = filteredIndex - this.delegate.navigate(position); + this.navigator.navigate(position); // Navigate to new chapter and search only in new current chapter, // this should refresh thesearch result of current chapter and highlight the selected index setTimeout(() => { @@ -585,7 +579,7 @@ export class SearchModule implements ReaderModule { (el: any) => el === searchItem ); - let currentLocation = self.delegate.currentChapterLink.href; + let currentLocation = self.navigator.currentChapterLink.href; if (currentLocation === href) { self.jumpToMark(filteredIndex); @@ -604,7 +598,7 @@ export class SearchModule implements ReaderModule { // position.locations.totalProgression = self.delegate.calculateTotalProgresion(position) // position.locations.index = filteredIndex - self.delegate.navigate(position); + self.navigator.navigate(position); // Navigate to new chapter and search only in new current chapter, // this should refresh thesearch result of current chapter and highlight the selected index setTimeout(() => { @@ -718,8 +712,8 @@ export class SearchModule implements ReaderModule { } if (tocItem) { let href = this.publication.getAbsoluteHref(tocItem.Href); - if (this.delegate.api?.getContent) { - await this.delegate.api?.getContent(href).then((content) => { + if (this.navigator.api?.getContent) { + await this.navigator.api?.getContent(href).then((content) => { let parser = new DOMParser(); let doc = parser.parseFromString(content, "application/xhtml+xml"); if (tocItem) { @@ -734,12 +728,12 @@ export class SearchModule implements ReaderModule { } }); } else { - await fetch(href, this.delegate.requestConfig) + await fetch(href, this.navigator.requestConfig) .then((r) => r.text()) .then(async (data) => { let parser = new DOMParser(); let doc = parser.parseFromString( - this.delegate.requestConfig?.encoded + this.navigator.requestConfig?.encoded ? this.decodeBase64(data) : data, "application/xhtml+xml" @@ -777,19 +771,19 @@ export class SearchModule implements ReaderModule { async searchChapter(term: string): Promise { let localSearchResultBook: any = []; const linkHref = this.publication.getAbsoluteHref( - this.publication.readingOrder[this.delegate.currentResource() ?? 0].Href + this.publication.readingOrder[this.navigator.currentResource() ?? 0].Href ); let tocItem = this.publication.getTOCItem(linkHref); if (tocItem === null) { tocItem = this.publication.readingOrder[ - this.delegate.currentResource() ?? 0 + this.navigator.currentResource() ?? 0 ]; } if (tocItem) { let href = this.publication.getAbsoluteHref(tocItem.Href); - if (this.delegate.api?.getContent) { - await this.delegate.api?.getContent(href).then((content) => { + if (this.navigator.api?.getContent) { + await this.navigator.api?.getContent(href).then((content) => { let parser = new DOMParser(); let doc = parser.parseFromString(content, "application/xhtml+xml"); if (tocItem) { @@ -803,13 +797,13 @@ export class SearchModule implements ReaderModule { } }); } else { - await fetch(href, this.delegate.requestConfig) + await fetch(href, this.navigator.requestConfig) .then((r) => r.text()) .then(async (data) => { // ({ data, tocItem }); let parser = new DOMParser(); let doc = parser.parseFromString( - this.delegate.requestConfig?.encoded + this.navigator.requestConfig?.encoded ? this.decodeBase64(data) : data, "application/xhtml+xml" @@ -875,10 +869,10 @@ export class SearchModule implements ReaderModule { this.currentSearchHighlights ); - this.delegate.view?.goToCssSelector( + this.navigator.view?.goToCssSelector( current.rangeInfo.startContainerElementCssSelector ); - this.delegate.updatePositionInfo(); + this.navigator.updatePositionInfo(); } }, 200); } diff --git a/src/navigator/IFrameNavigator.ts b/src/navigator/IFrameNavigator.ts index e7c70673..248c9b64 100644 --- a/src/navigator/IFrameNavigator.ts +++ b/src/navigator/IFrameNavigator.ts @@ -143,6 +143,8 @@ export interface IFrameNavigatorConfig { services?: PublicationServices; sample?: SampleRead; requestConfig?: RequestConfig; + modules: ReaderModule[]; + highlighter: TextHighlighter; } export interface PublicationServices { positions?: URL; @@ -331,7 +333,9 @@ export class IFrameNavigator extends EventEmitter implements Navigator { config.attributes || { margin: 0 }, config.services, config.sample, - config.requestConfig + config.requestConfig, + config.highlighter, + config.modules ); await navigator.start( @@ -354,14 +358,81 @@ export class IFrameNavigator extends EventEmitter implements Navigator { attributes?: IFrameAttributes, services?: PublicationServices, sample?: SampleRead, - requestConfig?: RequestConfig + requestConfig?: RequestConfig, + highlighter?: TextHighlighter, + modules?: ReaderModule[] ) { super(); + this.highlighter = highlighter; + if (this.highlighter) { + this.highlighter.navigator = this; + } + for (const index in modules) { + let module = modules[index]; + module.navigator = this; + if (modules[index] instanceof AnnotationModule) { + this.annotationModule = module; + } + if (modules[index] instanceof BookmarkModule) { + this.bookmarkModule = module; + } + if (modules[index] instanceof TTSModule2) { + this.ttsModule = module; + } + if (modules[index] instanceof TTSModule2) { + this.ttsModule = module; + } + if (modules[index] instanceof SearchModule) { + this.searchModule = module; + } + if (modules[index] instanceof DefinitionsModule) { + this.definitionsModule = module; + } + if (modules[index] instanceof TimelineModule) { + this.timelineModule = module; + } + if (modules[index] instanceof ContentProtectionModule) { + this.contentProtectionModule = module; + } + if (modules[index] instanceof CitationModule) { + this.citationModule = module; + } + if (modules[index] instanceof MediaOverlayModule) { + this.mediaOverlayModule = module; + } + if (modules[index] instanceof PageBreakModule) { + this.pageBreakModule = module; + } + if (modules[index] instanceof LineFocusModule) { + this.lineFocusModule = module; + } + if (modules[index] instanceof HistoryModule) { + this.historyModule = module; + } + if (modules[index] instanceof ConsumptionModule) { + this.consumptionModule = module; + } + // modules: [ + // bookmarkModule, + // annotationModule, + // ttsModule, + // searchModule, + // definitionsModule, + // timelineModule, + // contentProtectionModule, + // citationModule, + // mediaOverlayModule, + // pageBreakModule, + // lineFocusModule, + // historyModule, + // consumptionModule, + // ], + } this.settings = settings; this.annotator = annotator; this.view = settings.view; this.view.attributes = attributes; - this.view.delegate = this; + this.view.navigator = this; this.eventHandler = new EventHandler(this); this.touchEventHandler = new TouchEventHandler(this); this.keyboardEventHandler = new KeyboardEventHandler(this); @@ -762,7 +833,7 @@ export class IFrameNavigator extends EventEmitter implements Navigator { if (menuSearch) menuSearch.parentElement?.style.setProperty("display", "none"); } - if (menuSearch && this.view?.delegate.publication.isFixedLayout) { + if (menuSearch && this.view?.navigator.publication.isFixedLayout) { menuSearch.parentElement?.style.setProperty("display", "none"); } if (this.hasMediaOverlays) { @@ -1083,42 +1154,37 @@ export class IFrameNavigator extends EventEmitter implements Navigator { } } }); - setTimeout(async () => { - await this.highlighter?.prepareContainers( - this.iframes[0].contentWindow as any - ); + if (!options?.skipDrawingAnnotations) { + setTimeout(async () => { + await this.highlighter?.prepareContainers( + this.iframes[0].contentWindow as any + ); - if (this.pageBreakModule !== undefined) { - await this.highlighter?.destroyHighlights(HighlightType.PageBreak); - await this.pageBreakModule.drawPageBreaks(); - } + if (this.highlighter) { + if (this.rights.enableAnnotations && this.annotationModule) { + await this.annotationModule.drawHighlights(); + } - if ( - !options?.skipDrawingAnnotations && - this.annotationModule !== undefined - ) { - await this.annotationModule.drawHighlights(); - } - if (this.bookmarkModule !== undefined) { - await this.bookmarkModule.drawBookmarks(); - } + if (this.rights.enableBookmarks && this.bookmarkModule) { + await this.bookmarkModule.drawBookmarks(); + } - if ( - this.rights.enableSearch && - this.searchModule !== undefined && - this.highlighter !== undefined - ) { - await this.highlighter.destroyHighlights(HighlightType.Search); - this.searchModule.drawSearch(); - } - if ( - this.rights.enableDefinitions && - this.definitionsModule !== undefined && - this.highlighter !== undefined - ) { - await this.definitionsModule.drawDefinitions(); - } - }, 200); + if (this.rights.enableSearch && this.searchModule) { + await this.highlighter.destroyHighlights(HighlightType.Search); + this.searchModule.drawSearch(); + } + + if (this.rights.enablePageBreaks && this.pageBreakModule) { + await this.highlighter.destroyHighlights(HighlightType.PageBreak); + await this.pageBreakModule.drawPageBreaks(); + } + + if (this.rights.enableDefinitions && this.definitionsModule) { + await this.definitionsModule.drawDefinitions(); + } + } + }, 200); + } } } @@ -1266,7 +1332,6 @@ export class IFrameNavigator extends EventEmitter implements Navigator { created: new Date(), title: startLink?.Title, }; - await this.navigate(position); } @@ -1340,6 +1405,7 @@ export class IFrameNavigator extends EventEmitter implements Navigator { this.nextChapterAnchorElement.className += " disabled"; } } + if (this.historyModule) { this.historyModule.setup(); } @@ -1404,17 +1470,6 @@ export class IFrameNavigator extends EventEmitter implements Navigator { }); } - if (this.rights.enableContentProtection) { - if (this.contentProtectionModule !== undefined) { - await this.contentProtectionModule.initialize(); - } - } - if (this.rights.enableConsumption) { - if (this.consumptionModule !== undefined) { - await this.consumptionModule.initialize(); - } - } - if (this.eventHandler) { for (const iframe of this.iframes) { this.eventHandler.setupEvents(iframe.contentDocument); @@ -1433,29 +1488,40 @@ export class IFrameNavigator extends EventEmitter implements Navigator { this.view?.setIframeHeight?.(this.iframes[0]); } } - if (this.annotationModule !== undefined) { + + if (this.rights.enableContentProtection && this.contentProtectionModule) { + await this.contentProtectionModule.initialize(); + } + + if (this.rights.enableConsumption && this.consumptionModule) { + await this.consumptionModule.initialize(); + } + + if (this.rights.enableAnnotations && this.annotationModule) { await this.annotationModule.initialize(); } - if (this.bookmarkModule !== undefined) { + + if (this.rights.enableBookmarks && this.bookmarkModule) { await this.bookmarkModule.initialize(); } - if (this.rights.enableTTS) { - for (const iframe of this.iframes) { - const body = iframe.contentDocument?.body; - if (this.ttsModule !== undefined) { - const ttsModule = this.ttsModule as TTSModule2; - await ttsModule.initialize(body); - } - } + + if (this.rights.enableLineFocus && this.lineFocusModule) { + await this.lineFocusModule.initialize(); + } + + if (this.rights.enableTTS && this.ttsModule) { + const body = this.iframes[0].contentDocument?.body; + const ttsModule = this.ttsModule as TTSModule2; + await ttsModule.initialize(body); } - if (this.timelineModule !== undefined) { + if (this.rights.enableTimeline && this.timelineModule) { await this.timelineModule.initialize(); } if ( this.rights.enableMediaOverlays && - this.mediaOverlayModule !== undefined && + this.mediaOverlayModule && this.hasMediaOverlays ) { await this.mediaOverlayModule.initialize(); @@ -1490,9 +1556,10 @@ export class IFrameNavigator extends EventEmitter implements Navigator { this.hideLoadingMessage(); this.showIframeContents(); + if ( this.rights.enableMediaOverlays && - this.mediaOverlayModule !== undefined && + this.mediaOverlayModule && this.hasMediaOverlays ) { let link = this.currentLink(); @@ -1501,7 +1568,7 @@ export class IFrameNavigator extends EventEmitter implements Navigator { await this.updatePositionInfo(); await this.view?.setSize(); setTimeout(() => { - if (this.mediaOverlayModule !== undefined) { + if (this.mediaOverlayModule) { this.mediaOverlayModule.settings.resourceReady = true; } }, 300); @@ -2748,13 +2815,13 @@ export class IFrameNavigator extends EventEmitter implements Navigator { } async navigate(locator: Locator, history: boolean = true): Promise { - if (this.consumptionModule) { + if (this.rights.enableConsumption && this.consumptionModule) { if (history) { this.consumptionModule.startReadingSession(locator); } } if (this.historyModule) { - this.historyModule.push(locator, history); + await this.historyModule.push(locator, history); } const exists = this.publication.getTOCItem(locator.href); @@ -2963,18 +3030,20 @@ export class IFrameNavigator extends EventEmitter implements Navigator { ) { await this.mediaOverlayModule.initializeResource(this.currentLink()); } + if ( this.rights.enableContentProtection && this.contentProtectionModule !== undefined ) { - this.contentProtectionModule.recalculate(300); + await this.contentProtectionModule.recalculate(300); } - if (this.bookmarkModule !== undefined) { + if (this.bookmarkModule) { await this.bookmarkModule.drawBookmarks(); await this.bookmarkModule.showBookmarks(); } - if (this.pageBreakModule !== undefined) { + + if (this.pageBreakModule) { await this.highlighter?.destroyHighlights(HighlightType.PageBreak); await this.pageBreakModule.drawPageBreaks(); } @@ -2990,16 +3059,13 @@ export class IFrameNavigator extends EventEmitter implements Navigator { if ( this.rights.enableDefinitions && - this.definitionsModule !== undefined && - this.highlighter !== undefined + this.definitionsModule && + this.highlighter ) { - this.definitionsModule.drawDefinitions(); + await this.definitionsModule.drawDefinitions(); } - if ( - this.rights.enableConsumption && - this.consumptionModule !== undefined - ) { + if (this.rights.enableConsumption && this.consumptionModule) { this.consumptionModule.continueReadingSession(locator); } diff --git a/src/reader.ts b/src/reader.ts index 454a4cc6..af5d8b1d 100644 --- a/src/reader.ts +++ b/src/reader.ts @@ -226,31 +226,8 @@ export default class D2Reader { : "reflowable", }); - // Navigator - const navigator = await IFrameNavigator.create({ - mainElement: mainElement, - headerMenu: headerMenu, - footerMenu: footerMenu, - publication: publication, - settings, - annotator: annotator, - initialLastReadingPosition: initialConfig.lastReadingPosition, - api: initialConfig.api, - rights: rights, - tts: initialConfig.tts, - sample: initialConfig.sample, - requestConfig: initialConfig.requestConfig, - injectables: - (publication.Metadata.Rendition?.Layout ?? "unknown") === "fixed" - ? initialConfig.injectablesFixed ?? [] - : initialConfig.injectables, - attributes: initialConfig.attributes, - services: initialConfig.services, - }); - // Highlighter const highlighter = await TextHighlighter.create({ - delegate: navigator, layerSettings: layers, ...initialConfig.highlighter, }); @@ -262,7 +239,6 @@ export default class D2Reader { headerMenu: headerMenu, rights: rights, publication: publication, - delegate: navigator, initialAnnotations: initialConfig.initialAnnotations, ...initialConfig.bookmarks, }) @@ -274,7 +250,6 @@ export default class D2Reader { annotator: annotator, rights: rights, publication: publication, - delegate: navigator, initialAnnotations: initialConfig.initialAnnotations, highlighter: highlighter, headerMenu: headerMenu, @@ -296,7 +271,6 @@ export default class D2Reader { if (ttsEnabled && ttsSettings) { ttsModule = await TTSModule2.create({ - delegate: navigator, tts: ttsSettings, headerMenu: headerMenu, rights: rights, @@ -309,7 +283,6 @@ export default class D2Reader { const searchModule = rights.enableSearch ? await SearchModule.create({ headerMenu: headerMenu, - delegate: navigator, publication: publication, highlighter: highlighter, ...initialConfig.search, @@ -318,7 +291,6 @@ export default class D2Reader { const definitionsModule = rights.enableDefinitions ? await DefinitionsModule.create({ - delegate: navigator, publication: publication, highlighter: highlighter, ...initialConfig.define, @@ -329,14 +301,12 @@ export default class D2Reader { const timelineModule = rights.enableTimeline ? await TimelineModule.create({ publication: publication, - delegate: navigator, }) : undefined; // Content Protection Module const contentProtectionModule = rights.enableContentProtection ? await ContentProtectionModule.create({ - delegate: navigator, ...initialConfig.protection, }) : undefined; @@ -344,7 +314,6 @@ export default class D2Reader { const citationModule = rights.enableCitations ? await CitationModule.create({ publication: publication, - delegate: navigator, highlighter: highlighter, ...initialConfig.citations, }) @@ -363,7 +332,6 @@ export default class D2Reader { const mediaOverlayModule = enableMediaOverlays ? await MediaOverlayModule.create({ publication: publication, - delegate: navigator, settings: mediaOverlaySettings, ...initialConfig.mediaOverlays, }) @@ -375,7 +343,6 @@ export default class D2Reader { ? await PageBreakModule.create({ publication: publication, headerMenu: headerMenu, - delegate: navigator, ...initialConfig.pagebreak, }) : undefined; @@ -383,7 +350,6 @@ export default class D2Reader { const lineFocusModule = rights.enableLineFocus ? await LineFocusModule.create({ publication: publication, - delegate: navigator, highlighter: highlighter, ...initialConfig.lineFocus, }) @@ -393,7 +359,6 @@ export default class D2Reader { ? await HistoryModule.create({ annotator: annotator, publication: publication, - delegate: navigator, headerMenu: headerMenu, }) : undefined; @@ -401,11 +366,48 @@ export default class D2Reader { const consumptionModule = rights.enableConsumption ? await ConsumptionModule.create({ publication: publication, - delegate: navigator, ...initialConfig.consumption, }) : undefined; + // Navigator + const navigator = await IFrameNavigator.create({ + mainElement: mainElement, + headerMenu: headerMenu, + footerMenu: footerMenu, + publication: publication, + settings, + annotator: annotator, + initialLastReadingPosition: initialConfig.lastReadingPosition, + api: initialConfig.api, + rights: rights, + tts: initialConfig.tts, + sample: initialConfig.sample, + requestConfig: initialConfig.requestConfig, + injectables: + (publication.Metadata.Rendition?.Layout ?? "unknown") === "fixed" + ? initialConfig.injectablesFixed ?? [] + : initialConfig.injectables, + attributes: initialConfig.attributes, + services: initialConfig.services, + highlighter, + modules: [ + bookmarkModule, + annotationModule, + ttsModule, + searchModule, + definitionsModule, + timelineModule, + contentProtectionModule, + citationModule, + mediaOverlayModule, + pageBreakModule, + lineFocusModule, + historyModule, + consumptionModule, + ], + }); + return new D2Reader( settings, navigator, @@ -971,6 +973,8 @@ export default class D2Reader { this.mediaOverlayModule?.stop(); this.pageBreakModule?.stop(); this.lineFocusModule?.stop(); + this.citationModule?.stop(); + this.consumptionModule?.stop(); }; } diff --git a/src/views/BookView.ts b/src/views/BookView.ts index a5c45004..179277a6 100644 --- a/src/views/BookView.ts +++ b/src/views/BookView.ts @@ -30,7 +30,7 @@ interface BookView { iframe: Element; sideMargin: number; height: number; - delegate: IFrameNavigator; + navigator: IFrameNavigator; attributes?: IFrameAttributes; setMode?(scroll: boolean); diff --git a/src/views/FixedBookView.ts b/src/views/FixedBookView.ts index 37eba845..00cb5ee3 100644 --- a/src/views/FixedBookView.ts +++ b/src/views/FixedBookView.ts @@ -26,7 +26,7 @@ import * as HTMLUtilities from "../utils/HTMLUtilities"; export default class FixedBookView implements BookView { layout = "fixed"; - delegate: IFrameNavigator; + navigator: IFrameNavigator; name: string; label: string; iframe: HTMLIFrameElement; diff --git a/src/views/ReflowableBookView.ts b/src/views/ReflowableBookView.ts index 4a57d290..d9581f40 100644 --- a/src/views/ReflowableBookView.ts +++ b/src/views/ReflowableBookView.ts @@ -34,7 +34,7 @@ export default class ReflowableBookView implements BookView { private readonly USERSETTINGS = "userSetting"; private readonly store: Store; private scrollMode: boolean; - delegate: IFrameNavigator; + navigator: IFrameNavigator; constructor(store: Store) { this.store = store; @@ -98,8 +98,8 @@ export default class ReflowableBookView implements BookView { } this.setSize(); } - if (this.delegate.rights.enableContentProtection) { - this.delegate.contentProtectionModule?.recalculate(); + if (this.navigator.rights.enableContentProtection) { + this.navigator.contentProtectionModule?.recalculate(); } } @@ -250,8 +250,8 @@ export default class ReflowableBookView implements BookView { element.style.height = originalHeight; this.setLeftColumnsWidth(roundedLeftWidth); - if (this.delegate.rights.enableContentProtection) { - this.delegate.contentProtectionModule?.recalculate(0); + if (this.navigator.rights.enableContentProtection) { + this.navigator.contentProtectionModule?.recalculate(0); } } } @@ -287,8 +287,8 @@ export default class ReflowableBookView implements BookView { // Restore element's original height. element.style.height = originalHeight; this.setLeftColumnsWidth(roundedLeftWidth); - if (this.delegate.rights.enableContentProtection) { - this.delegate.contentProtectionModule?.recalculate(200); + if (this.navigator.rights.enableContentProtection) { + this.navigator.contentProtectionModule?.recalculate(200); } } } @@ -351,10 +351,10 @@ export default class ReflowableBookView implements BookView { } else { this.setLeftColumnsWidth(0); } - this.delegate.checkResourcePosition(); + this.navigator.checkResourcePosition(); } - if (this.delegate.rights.enableContentProtection) { - this.delegate.contentProtectionModule?.recalculate(); + if (this.navigator.rights.enableContentProtection) { + this.navigator.contentProtectionModule?.recalculate(); } } @@ -384,10 +384,10 @@ export default class ReflowableBookView implements BookView { } else { this.setLeftColumnsWidth(scrollWidth); } - this.delegate.checkResourcePosition(); + this.navigator.checkResourcePosition(); } - if (this.delegate.rights.enableContentProtection) { - this.delegate.contentProtectionModule?.recalculate(); + if (this.navigator.rights.enableContentProtection) { + this.navigator.contentProtectionModule?.recalculate(); } } From 6b651aaf529cfa8a77b1e3d208ed8e5a08dc8e70 Mon Sep 17 00:00:00 2001 From: Aferdita Muriqi Date: Sat, 25 Mar 2023 00:06:57 -0400 Subject: [PATCH 2/4] fix lint errors --- src/modules/TTS/TTSSettings.ts | 2 +- src/modules/consumption/ConsumptionModule.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/TTS/TTSSettings.ts b/src/modules/TTS/TTSSettings.ts index 79e91d85..b275ac7a 100644 --- a/src/modules/TTS/TTSSettings.ts +++ b/src/modules/TTS/TTSSettings.ts @@ -27,7 +27,7 @@ import { JSONable, } from "../../model/user-settings/UserProperties"; import * as HTMLUtilities from "../../utils/HTMLUtilities"; -import { IFrameNavigator, ReaderRights } from "../../navigator/IFrameNavigator"; +import { ReaderRights } from "../../navigator/IFrameNavigator"; import { TextHighlighter } from "../highlight/TextHighlighter"; import { addEventListenerOptional } from "../../utils/EventHandler"; import log from "loglevel"; diff --git a/src/modules/consumption/ConsumptionModule.ts b/src/modules/consumption/ConsumptionModule.ts index 06cfefe1..3da27a9c 100644 --- a/src/modules/consumption/ConsumptionModule.ts +++ b/src/modules/consumption/ConsumptionModule.ts @@ -220,12 +220,12 @@ export class ConsumptionModule implements ReaderModule { /* Increment the timer seconds */ this.currSeconds++; - if (this.currSeconds == this.properties.idleTimeout) { + if (this.currSeconds === this.properties.idleTimeout) { this.api?.idleSince(this.currSeconds); this.updateResearchSession(); } if ( - this.currSeconds == + this.currSeconds === this.properties.idleTimeout! + this.properties.responseTimeout! ) { this.endResearchSession(); From 5d45729d84a6bd63011b6360e456472769643743 Mon Sep 17 00:00:00 2001 From: Aferdita Muriqi Date: Sat, 25 Mar 2023 00:44:12 -0400 Subject: [PATCH 3/4] check if module exists --- src/navigator/IFrameNavigator.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/navigator/IFrameNavigator.ts b/src/navigator/IFrameNavigator.ts index 248c9b64..5d34cf05 100644 --- a/src/navigator/IFrameNavigator.ts +++ b/src/navigator/IFrameNavigator.ts @@ -369,7 +369,9 @@ export class IFrameNavigator extends EventEmitter implements Navigator { } for (const index in modules) { let module = modules[index]; - module.navigator = this; + if (module) { + module.navigator = this; + } if (modules[index] instanceof AnnotationModule) { this.annotationModule = module; } From af65736fccea2bd1d2c97b31780564955707bd6c Mon Sep 17 00:00:00 2001 From: Aferdita Muriqi Date: Sat, 25 Mar 2023 00:50:36 -0400 Subject: [PATCH 4/4] check if audioelement exiss --- src/modules/mediaoverlays/MediaOverlayModule.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/mediaoverlays/MediaOverlayModule.ts b/src/modules/mediaoverlays/MediaOverlayModule.ts index b1497af2..2f3424d5 100644 --- a/src/modules/mediaoverlays/MediaOverlayModule.ts +++ b/src/modules/mediaoverlays/MediaOverlayModule.ts @@ -232,7 +232,8 @@ export class MediaOverlayModule implements ReaderModule { async stopReadAloud() { if (this.navigator.rights.enableMediaOverlays) { this.settings.playing = false; - this.audioElement.pause(); + + if (this.audioElement) this.audioElement.pause(); if (this.play) this.play.style.removeProperty("display"); if (this.pause) this.pause.style.display = "none";