diff --git a/CHANGELOG.md b/CHANGELOG.md index a5d6b2b4b3..0e1453759d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ - Made the lookup better reflect the cursor position ([#278](https://github.com/birchill/10ten-ja-reader/discussions/278)). +- Fixed a hang when using 10ten together with the LiveTL extension + ([#733](https://github.com/birchill/10ten-ja-reader/discussions/733)). ## 1.2.2 (2021-08-19) diff --git a/src/content.ts b/src/content.ts index ab7793d12f..8c9af5161c 100644 --- a/src/content.ts +++ b/src/content.ts @@ -622,6 +622,18 @@ export class ContentHandler { } onContentMessage(ev: MessageEvent) { + // In the following we need to be careful to avoid creating an infinite loop + // of messages. + // + // This is because many of the methods we call will simply forward the + // message on to topmost window if needed. + // + // However, the LiveTL add-on naively forwards all messages to its topmost + // window on to its iframes creating an infinite loop. + // + // To avoid this, for any message that is only intended to be sent to a + // topmost window, we ensure that we are the topmost window before + // calling the corresponding method. switch (ev.data.kind) { case '10ten(ja):lookup': { @@ -646,40 +658,59 @@ export class ContentHandler { // clear any mouse target we previously stored. this.lastMouseTarget = null; + // We don't bother checking isTopMostWindow() here because lookupText + // doesn't delegate its work to the topmost window by calling + // postMessage. this.lookupText({ ...ev.data, source: ev.source }); } break; case '10ten(ja):clearResult': - this.clearResult(); + if (isTopMostWindow()) { + this.clearResult(); + } break; case '10ten(ja):nextDictionary': - this.showNextDictionary(); + if (isTopMostWindow()) { + this.showNextDictionary(); + } break; case '10ten(ja):toggleDefinition': - this.toggleDefinition(); + if (isTopMostWindow()) { + this.toggleDefinition(); + } break; case '10ten(ja):movePopup': - this.movePopup(ev.data.direction); + if (isTopMostWindow()) { + this.movePopup(ev.data.direction); + } break; case '10ten(ja):enterCopyMode': - this.enterCopyMode(); + if (isTopMostWindow()) { + this.enterCopyMode(); + } break; case '10ten(ja):exitCopyMode': - this.exitCopyMode(); + if (isTopMostWindow()) { + this.exitCopyMode(); + } break; case '10ten(ja):nextCopyEntry': - this.nextCopyEntry(); + if (isTopMostWindow()) { + this.nextCopyEntry(); + } break; case '10ten(ja):copyCurrentEntry': - this.copyCurrentEntry(ev.data.copyType); + if (isTopMostWindow()) { + this.copyCurrentEntry(ev.data.copyType); + } break; case '10ten(ja):highlightText':