diff --git a/src/content-handlers/iiif/extensions/uv-default-extension/Extension.ts b/src/content-handlers/iiif/extensions/uv-default-extension/Extension.ts index 4ae835f95..ea6b01fda 100644 --- a/src/content-handlers/iiif/extensions/uv-default-extension/Extension.ts +++ b/src/content-handlers/iiif/extensions/uv-default-extension/Extension.ts @@ -88,7 +88,7 @@ export default class Extension extends BaseExtension } if (this.isTextRightPanelEnabled()) { - this.textRightPanel = new TextRightPanel(this.shell.$textRightPanel); + this.textRightPanel = new TextRightPanel(this.shell.$textRightPanel, this.shell); } if (this.isFooterPanelEnabled()) { diff --git a/src/content-handlers/iiif/extensions/uv-model-viewer-extension/Extension.ts b/src/content-handlers/iiif/extensions/uv-model-viewer-extension/Extension.ts index 9ef8b381a..825d70187 100644 --- a/src/content-handlers/iiif/extensions/uv-model-viewer-extension/Extension.ts +++ b/src/content-handlers/iiif/extensions/uv-model-viewer-extension/Extension.ts @@ -105,7 +105,7 @@ export default class ModelViewerExtension extends BaseExtension { } if (this.isTextRightPanelEnabled()) { - this.textRightPanel = new TextRightPanel(this.shell.$textRightPanel); + this.textRightPanel = new TextRightPanel(this.shell.$textRightPanel, this.shell); } if (this.isFooterPanelEnabled()) { diff --git a/src/content-handlers/iiif/extensions/uv-openseadragon-extension/Extension.ts b/src/content-handlers/iiif/extensions/uv-openseadragon-extension/Extension.ts index c782bfa5c..3c5710366 100644 --- a/src/content-handlers/iiif/extensions/uv-openseadragon-extension/Extension.ts +++ b/src/content-handlers/iiif/extensions/uv-openseadragon-extension/Extension.ts @@ -569,7 +569,7 @@ export default class OpenSeadragonExtension extends BaseExtension { } if (this.isTextRightPanelEnabled()) { - this.textRightPanel = new TextRightPanel(this.shell.$textRightPanel); + this.textRightPanel = new TextRightPanel(this.shell.$textRightPanel, this.shell); } else { this.shell.$textRightPanel.hide(); } diff --git a/src/content-handlers/iiif/modules/uv-shared-module/css/right-panel.less b/src/content-handlers/iiif/modules/uv-shared-module/css/right-panel.less index 8868ca14c..f5e02c674 100644 --- a/src/content-handlers/iiif/modules/uv-shared-module/css/right-panel.less +++ b/src/content-handlers/iiif/modules/uv-shared-module/css/right-panel.less @@ -82,7 +82,7 @@ width: 230px; padding: 5px 5px 5px 7px; - p { + div { padding: 5px; margin: 0; } diff --git a/src/content-handlers/iiif/modules/uv-textrightpanel-module/TextRightPanel.ts b/src/content-handlers/iiif/modules/uv-textrightpanel-module/TextRightPanel.ts index a0a57c8f9..d61399281 100644 --- a/src/content-handlers/iiif/modules/uv-textrightpanel-module/TextRightPanel.ts +++ b/src/content-handlers/iiif/modules/uv-textrightpanel-module/TextRightPanel.ts @@ -5,6 +5,9 @@ import { Events } from "../../../../Events"; import OpenSeadragonExtension from "../../extensions/uv-openseadragon-extension/Extension"; import OpenSeadragon from "openseadragon"; import { Clipboard } from "@edsilv/utils"; +import { IExternalImageResourceData } from "manifesto.js"; +import { OpenSeadragonCenterPanel } from "../../modules/uv-openseadragoncenterpanel-module/OpenSeadragonCenterPanel"; +import { Shell } from "../uv-shared-module/Shell"; export class TextRightPanel extends RightPanel { $transcribedText: JQuery; @@ -12,10 +15,15 @@ export class TextRightPanel extends RightPanel { $copyButton: JQuery; $copiedText: JQuery; currentCanvasIndex: number = 0; + offsetX: number = 0; + index: number = 0; clipboardText: string = ''; + shell: Shell; + centerPanel: OpenSeadragonCenterPanel; - constructor($element: JQuery) { + constructor($element: JQuery, shell: Shell) { super($element); + this.shell = shell; } create(): void { @@ -62,7 +70,13 @@ export class TextRightPanel extends RightPanel { } this.extensionHost.on(Events.LOAD, async (e) => { - if (this.currentCanvasIndex == this.extension.helper.canvasIndex) { + this.centerPanel = ((this.extension)).centerPanel; + let canvases = this.extension.getCurrentCanvases(); + canvases.sort((a, b) => (a.index as number - b.index as number)); + + let canvasExists = canvases.some(x => x.index === this.currentCanvasIndex) + + if (canvasExists) { this.$existingAnnotation = $('.lineAnnotation.current'); } else { this.$existingAnnotation = $(); @@ -72,27 +86,44 @@ export class TextRightPanel extends RightPanel { this.$main.html(''); this.clipboardText = ''; this.removeLineAnnotationRects(); - let canvases = this.extension.getCurrentCanvases(); - canvases.sort((a, b) => (a.index as number - b.index as number)); for (let i = 0; i < canvases.length; i++) { const c = canvases[i]; let seeAlso = c.getProperty('seeAlso'); let header; + if (i === 0 && canvases.length > 1) { header = this.content.leftPage; } else if (i === 1 && canvases.length > 1) { header = this.content.rightPage; } + // Find offset if showing more pages than one + let res = this.extension.resources; + this.offsetX = -1; + this.index = -1; + if (res !== null) { + let resource: any = res.filter( + (x) => x.index === c.index + )[0]; + this.index = res.indexOf(resource); + this.offsetX = 0; + + if (this.index > 0) { + this.offsetX = (( + res[this.index - 1] + )).width; + } + } + // We need to see if seeAlso contains an ALTO file and maybe allow for other HTR/OCR formats in the future // and make sure which version of IIIF Presentation API is used if (seeAlso.length === undefined) { // This is IIIF Presentation API < 3 if (seeAlso.profile.includes('alto')) { - await this.processAltoFile(seeAlso['@id'], header); + await this.processAltoFile(seeAlso['@id'], c.index, header); } } else { // This is IIIF Presentation API >= 3 if (seeAlso[0].profile.includes('alto')) { - await this.processAltoFile(seeAlso[0]['id'], header); + await this.processAltoFile(seeAlso[0]['id'], c.index, header); } } }; @@ -122,7 +153,7 @@ export class TextRightPanel extends RightPanel { } // Let's load the ALTO file and do some parsing - processAltoFile = async (altoUrl, header?): Promise => { + processAltoFile = async (altoUrl, canvasIndex, header?): Promise => { try { const response = await fetch(altoUrl); const data = await response.text(); @@ -134,23 +165,31 @@ export class TextRightPanel extends RightPanel { let t = Array.from(strings).map((e, i) => { return e.getAttribute('CONTENT'); }); - const x = Number(e.getAttribute('HPOS')); + let x = Number(e.getAttribute('HPOS')); const y = Number(e.getAttribute('VPOS')); const width = Number(e.getAttribute('WIDTH')); const height = Number(e.getAttribute('HEIGHT')); + x = x + this.offsetX + (this.index > 0 ? this.centerPanel.config.options.pageGap : 0); + let text = t.join(' '); this.clipboardText += text; - let line = $('

' + text + '

'); + let line = $('
' + text + '
'); if (!this.extension.isMobile()) { - let div = $('
'); + let div = $('
'); $(div).on('keydown', (e: any) => { if (e.keyCode === 13) { $(e.target).trigger('click'); } }); $(div).on('click', (e: any) => { + let canvasIndex = Number(e.target.getAttribute('id').split('-')[2]); + // We change the current canvas index to the clicked page (if we're in two page view) + if (canvasIndex !== this.currentCanvasIndex) { + this.extension.helper.canvasIndex = canvasIndex; + this.currentCanvasIndex = canvasIndex; + } this.clearLineAnnotationRects(); this.clearLineAnnotations(); this.setCurrentLineAnnotation(e.target, true); @@ -167,6 +206,12 @@ export class TextRightPanel extends RightPanel { }); // Sync line click with line annotation line.on('click', (e: any) => { + let canvasIndex = Number(e.target.getAttribute('id').split('-')[2]); + // We change the current canvas index to the clicked page (if we're in two page view) + if (canvasIndex !== this.currentCanvasIndex) { + this.extension.helper.canvasIndex = canvasIndex; + this.currentCanvasIndex = canvasIndex; + } this.clearLineAnnotationRects(); this.clearLineAnnotations(); this.setCurrentLineAnnotation(e.target, false); @@ -191,9 +236,10 @@ export class TextRightPanel extends RightPanel { // If we already have a selected line annotation, make sure it's selected again after load if (this.$existingAnnotation[0] !== undefined) { let id = $(this.$existingAnnotation).attr('id'); - this.setCurrentLineAnnotation($(this.$existingAnnotation)[0], true); - this.setCurrentLineAnnotationRect($('div#' + id)[0]); - this.$existingAnnotation = $(); + if ($('div#' + id).length > 0) { // Make sure the line annotation exists in the DOM + this.setCurrentLineAnnotation($('div#' + id)[0], true); + this.setCurrentLineAnnotationRect($('div#' + id)[0]); + } } } catch (error) { @@ -217,7 +263,7 @@ export class TextRightPanel extends RightPanel { $(lineAnnotationRect).removeClass('current'); } }); - $('div#' + e.getAttribute('id')).addClass('current'); + $('div#' + e.getAttribute('id') + '.lineAnnotationRect').addClass('current'); } setCurrentLineAnnotation(e: any, scrollIntoView: Boolean): void { @@ -226,9 +272,9 @@ export class TextRightPanel extends RightPanel { $(lineAnnotation).removeClass('current'); } }); - $('p#' + e.getAttribute('id')).addClass('current'); + $('div#' + e.getAttribute('id') + '.lineAnnotation').addClass('current'); if (scrollIntoView) { - $('p#' + e.getAttribute('id'))[0].scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'nearest' }); + $('div#' + e.getAttribute('id') + '.lineAnnotation')[0].scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'nearest' }); } }