Skip to content

Commit e6dac05

Browse files
committed
Add TPEN context messaging for tool iframes
Introduce unified TPEN context and messaging helpers for tools embedded in the right pane. Adds private getters (#getCurrentLineId, #getCanvasId, #getCanvasImageUrl) and context builders (#buildTPENContext, #postToTool, #sendTPENContextToTool), and tracks the active tool iframe (#activeToolIframe). Use these helpers when creating iframes and sending initial messages (canvas/annotation info and CURRENT_LINE_INDEX), send updated context on line selection, and respond to REQUEST_TPEN_CONTEXT messages from tools. Also minor refactor to centralize message origin validation.
1 parent 19d8c32 commit e6dac05

File tree

1 file changed

+60
-8
lines changed

1 file changed

+60
-8
lines changed

components/simple-transcription/index.js

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export default class SimpleTranscriptionInterface extends HTMLElement {
1818
#page
1919
#canvas
2020
#activeLine = null
21+
#activeToolIframe = null
2122
#imgTopOriginalHeight = 0
2223
#imgTopOriginalWidth = 0
2324
#imgBottomPositionRatio = 1
@@ -806,6 +807,47 @@ export default class SimpleTranscriptionInterface extends HTMLElement {
806807
})) ?? []
807808
}
808809

810+
#getCurrentLineId() {
811+
return this.#page?.items?.[TPEN.activeLineIndex]?.id ?? null
812+
}
813+
814+
#getCanvasId() {
815+
return this.#canvas?.id ?? this.#canvas?.['@id'] ?? this.#canvas ?? ''
816+
}
817+
818+
#getCanvasImageUrl() {
819+
return this.#canvas?.items?.[0]?.items?.[0]?.body?.id
820+
?? this.#canvas?.images?.[0]?.resource?.['@id']
821+
?? this.#canvas?.images?.[0]?.resource?.id
822+
?? null
823+
}
824+
825+
#buildTPENContext() {
826+
const currentPageId = TPEN.screen?.pageInQuery
827+
const projectPage = TPEN.activeProject?.layers
828+
?.flatMap(layer => layer.pages || [])
829+
.find(p => p.id.split('/').pop() === currentPageId)
830+
831+
return {
832+
type: 'TPEN_CONTEXT',
833+
projectId: TPEN.activeProject?.id ?? TPEN.activeProject?._id ?? TPEN.screen?.projectInQuery ?? null,
834+
pageId: this.fetchCurrentPageId() ?? this.#page?.id ?? currentPageId ?? null,
835+
canvasId: this.#getCanvasId(),
836+
imageUrl: this.#getCanvasImageUrl(),
837+
currentLineId: this.#getCurrentLineId(),
838+
columns: projectPage?.columns || []
839+
}
840+
}
841+
842+
#postToTool(message, targetWindow = this.#activeToolIframe?.contentWindow) {
843+
if (!this._iframeOrigin || !targetWindow) return
844+
targetWindow.postMessage(message, this._iframeOrigin)
845+
}
846+
847+
#sendTPENContextToTool(targetWindow = this.#activeToolIframe?.contentWindow) {
848+
this.#postToTool(this.#buildTPENContext(), targetWindow)
849+
}
850+
809851
loadRightPaneContent() {
810852
const rightPane = this.shadowRoot.querySelector('.tools')
811853
let tool = this.getToolByName(this.state.activeTool)
@@ -858,6 +900,7 @@ export default class SimpleTranscriptionInterface extends HTMLElement {
858900

859901
if (tool.url && !tagName && tool.location === 'pane') {
860902
const iframe = document.createElement('iframe')
903+
this.#activeToolIframe = iframe
861904
iframe.id = tool.toolName
862905
iframe.style.width = '100%'
863906
iframe.style.height = '100%'
@@ -872,14 +915,17 @@ export default class SimpleTranscriptionInterface extends HTMLElement {
872915
const projectPage = TPEN.activeProject?.layers
873916
?.flatMap(layer => layer.pages || [])
874917
.find(p => p.id.split('/').pop() === currentPageId)
918+
919+
// New consolidated context payload for pane tools.
920+
this.#sendTPENContextToTool(iframe.contentWindow)
875921

876922
iframe.contentWindow?.postMessage(
877923
{
878924
type: "MANIFEST_CANVAS_ANNOTATIONPAGE_ANNOTATION",
879925
manifest: TPEN.activeProject?.manifest?.[0] ?? '',
880-
canvas: this.#canvas?.id ?? this.#canvas?.['@id'] ?? this.#canvas ?? '',
926+
canvas: this.#getCanvasId(),
881927
annotationPage: this.fetchCurrentPageId() ?? this.#page?.id ?? '',
882-
annotation: TPEN.activeLineIndex >= 0 ? this.#page?.items?.[TPEN.activeLineIndex]?.id ?? null : null,
928+
annotation: TPEN.activeLineIndex >= 0 ? this.#getCurrentLineId() : null,
883929
columns: projectPage?.columns || []
884930
},
885931
this._iframeOrigin
@@ -896,7 +942,7 @@ export default class SimpleTranscriptionInterface extends HTMLElement {
896942
iframe.contentWindow?.postMessage(
897943
{
898944
type: "CURRENT_LINE_INDEX",
899-
lineId: this.#page?.items?.[TPEN.activeLineIndex]?.id ?? null
945+
lineId: this.#getCurrentLineId()
900946
},
901947
this._iframeOrigin
902948
)
@@ -906,7 +952,8 @@ export default class SimpleTranscriptionInterface extends HTMLElement {
906952
this.#cleanupToolLineListeners()
907953

908954
const sendLineSelection = () => {
909-
const activeLineId = this.#page?.items?.[TPEN.activeLineIndex]?.id ?? null
955+
const activeLineId = this.#getCurrentLineId()
956+
this.#sendTPENContextToTool(iframe.contentWindow)
910957
iframe.contentWindow?.postMessage(
911958
{ type: "SELECT_ANNOTATION", lineId: activeLineId },
912959
this._iframeOrigin
@@ -933,10 +980,15 @@ export default class SimpleTranscriptionInterface extends HTMLElement {
933980
}
934981

935982
#handleToolMessages(event) {
936-
// Validate message origin if iframe origin is set
937-
if (this._iframeOrigin && event.origin !== this._iframeOrigin) {
938-
return
939-
}
983+
// Validate message origin if iframe origin is set
984+
if (this._iframeOrigin && event.origin !== this._iframeOrigin) {
985+
return
986+
}
987+
988+
if (event.data?.type === 'REQUEST_TPEN_CONTEXT') {
989+
this.#sendTPENContextToTool(event.source)
990+
return
991+
}
940992

941993
// Handle incoming messages from tools
942994
const lineId = event.data?.lineId ?? event.data?.lineid ?? event.data?.annotation // handle different casing and properties

0 commit comments

Comments
 (0)