Skip to content

Commit 8cd1eb3

Browse files
authored
Merge pull request #910 from stevapple/sync-title
fix(web): keep title in sync with iframe
2 parents 7988aa5 + 3090258 commit 8cd1eb3

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

web/src/components/IFrame.tsx

+29-5
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,30 @@ import { uniqueId } from 'lodash'
44
import styles from '../style/components/IFrame.module.css'
55
interface Props {
66
src: string
7-
onPageChanged: (page: string, hash: string) => void
7+
onPageChanged: (page: string, hash: string, title?: string) => void
88
onHashChanged: (hash: string) => void
9+
onTitleChanged: (title: string) => void
910
onNotFound: () => void
1011
}
1112

1213
export default function IFrame(props: Props): JSX.Element {
1314
const iFrameRef = useRef<HTMLIFrameElement>(null)
1415

1516
const onIframeLoad = (): void => {
16-
if (iFrameRef.current == null) {
17+
if (iFrameRef.current === null) {
1718
console.error('iFrameRef is null')
1819
return
1920
}
2021

21-
// remove the hashchange event listener to prevent memory leaks
22+
// remove the event listeners to prevent memory leaks
2223
iFrameRef.current.contentWindow?.removeEventListener(
2324
'hashchange',
2425
hashChangeEventListener
2526
)
27+
iFrameRef.current.contentWindow?.removeEventListener(
28+
'titlechange',
29+
titleChangeEventListener
30+
)
2631

2732
const url = iFrameRef.current?.contentDocument?.location.href
2833
if (url == null) {
@@ -69,6 +74,10 @@ export default function IFrame(props: Props): JSX.Element {
6974
'hashchange',
7075
hashChangeEventListener
7176
)
77+
iFrameRef.current.contentWindow?.addEventListener(
78+
'titlechange',
79+
titleChangeEventListener
80+
)
7281

7382
const parts = url.split('/doc/').slice(1).join('/doc/').split('/')
7483
const urlPageAndHash = parts.slice(2).join('/')
@@ -77,12 +86,13 @@ export default function IFrame(props: Props): JSX.Element {
7786
: urlPageAndHash.length
7887
const urlPage = urlPageAndHash.slice(0, hashIndex)
7988
const urlHash = urlPageAndHash.slice(hashIndex)
89+
const title = iFrameRef.current?.contentDocument?.title
8090

81-
props.onPageChanged(urlPage, urlHash)
91+
props.onPageChanged(urlPage, urlHash, title)
8292
}
8393

8494
const hashChangeEventListener = (): void => {
85-
if (iFrameRef.current == null) {
95+
if (iFrameRef.current === null) {
8696
console.error('hashChangeEvent from iframe but iFrameRef is null')
8797
return
8898
}
@@ -102,6 +112,20 @@ export default function IFrame(props: Props): JSX.Element {
102112
props.onHashChanged(hash)
103113
}
104114

115+
const titleChangeEventListener = (): void => {
116+
if (iFrameRef.current === null) {
117+
console.error('titleChangeEvent from iframe but iFrameRef is null')
118+
return
119+
}
120+
121+
const title = iFrameRef.current?.contentDocument?.title
122+
if (title == null) {
123+
return
124+
}
125+
126+
props.onTitleChanged(title)
127+
}
128+
105129
return (
106130
<iframe
107131
ref={iFrameRef}

web/src/pages/Docs.tsx

+9-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,14 @@ export default function Docs(): JSX.Element {
117117
window.history.pushState(null, '', url)
118118
}
119119

120-
const iFramePageChanged = (urlPage: string, urlHash: string): void => {
120+
const updateTitle = (newTitle: string): void => {
121+
document.title = newTitle
122+
}
123+
124+
const iFramePageChanged = (urlPage: string, urlHash: string, title?: string): void => {
125+
if (title != null && title !== document.title) {
126+
updateTitle(title)
127+
}
121128
if (urlPage === page.current) {
122129
return
123130
}
@@ -225,6 +232,7 @@ export default function Docs(): JSX.Element {
225232
src={iFrameSrc}
226233
onPageChanged={iFramePageChanged}
227234
onHashChanged={iFrameHashChanged}
235+
onTitleChanged={updateTitle}
228236
onNotFound={iFrameNotFound}
229237
/>
230238
{!hideUi && (

0 commit comments

Comments
 (0)