diff --git a/src/GrampsJs.js b/src/GrampsJs.js
index 54b6de23..c000d24f 100644
--- a/src/GrampsJs.js
+++ b/src/GrampsJs.js
@@ -68,6 +68,7 @@ import './views/GrampsjsViewRecent.js'
import './views/GrampsjsViewBookmarks.js'
import './views/GrampsjsViewMap.js'
import './views/GrampsjsViewTree.js'
+import './views/GrampsjsViewTopola.js'
import './views/GrampsjsViewNewPerson.js'
import './views/GrampsjsViewNewFamily.js'
import './views/GrampsjsViewNewEvent.js'
@@ -554,6 +555,10 @@ export class GrampsJs extends LitElement {
${this._('Family Tree')}
${renderIcon(mdiFamilyTree)}
+
+ ${this._('Interactive Tree')}
+ ${renderIcon(mdiFamilyTree)}
+
${this._('History')}
@@ -675,6 +680,13 @@ export class GrampsJs extends LitElement {
.strings="${this._strings}"
.settings="${this.settings}"
>
+
`
+ }
+
+ /** Initializes communication with the iframe. */
+ async firstUpdated() {
+ window.addEventListener('message', this._onMessage.bind(this))
+
+ const url = '/api/exporters/ged/file'
+ const downloadUrl = getExporterDownloadUrl(url)
+ const response = await fetch(downloadUrl)
+ const gedcom = await response.text()
+ this.gedcom = gedcom
+ this._maybeSendData()
+ }
+
+ /** Handles incoming messages. */
+ _onMessage(message) {
+ if (message.data.message === 'ready') {
+ this.ready = true
+ this._maybeSendData()
+ }
+ }
+
+ /**
+ * Sends data to the iframe when both the iframe is ready and the data is
+ * present.
+ */
+ _maybeSendData() {
+ if (!this.ready || !this.gedcom) {
+ return
+ }
+ const frame = this.shadowRoot.getElementById('topolaFrame')
+ frame.contentWindow.postMessage(
+ {message: 'gedcom', gedcom: this.gedcom},
+ '*'
+ )
+ }
+
+ /** Registers listening for home person changes. */
+ connectedCallback() {
+ super.connectedCallback()
+ window.addEventListener(
+ 'pedigree:person-selected',
+ this._selectPerson.bind(this)
+ )
+ }
+
+ /** Sets the home person based on a received event. */
+ async _selectPerson(event) {
+ const {grampsId} = event.detail
+ this.grampsId = grampsId
+ }
+}
+
+window.customElements.define('grampsjs-view-topola', GrampsjsViewTopola)