Skip to content

Commit

Permalink
Merge pull request #910 from stevapple/sync-title
Browse files Browse the repository at this point in the history
fix(web): keep title in sync with iframe
  • Loading branch information
randombenj authored Oct 25, 2024
2 parents 7988aa5 + 3090258 commit 8cd1eb3
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 6 deletions.
34 changes: 29 additions & 5 deletions web/src/components/IFrame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,30 @@ import { uniqueId } from 'lodash'
import styles from '../style/components/IFrame.module.css'
interface Props {
src: string
onPageChanged: (page: string, hash: string) => void
onPageChanged: (page: string, hash: string, title?: string) => void
onHashChanged: (hash: string) => void
onTitleChanged: (title: string) => void
onNotFound: () => void
}

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

const onIframeLoad = (): void => {
if (iFrameRef.current == null) {
if (iFrameRef.current === null) {
console.error('iFrameRef is null')
return
}

// remove the hashchange event listener to prevent memory leaks
// remove the event listeners to prevent memory leaks
iFrameRef.current.contentWindow?.removeEventListener(
'hashchange',
hashChangeEventListener
)
iFrameRef.current.contentWindow?.removeEventListener(
'titlechange',
titleChangeEventListener
)

const url = iFrameRef.current?.contentDocument?.location.href
if (url == null) {
Expand Down Expand Up @@ -69,6 +74,10 @@ export default function IFrame(props: Props): JSX.Element {
'hashchange',
hashChangeEventListener
)
iFrameRef.current.contentWindow?.addEventListener(
'titlechange',
titleChangeEventListener
)

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

props.onPageChanged(urlPage, urlHash)
props.onPageChanged(urlPage, urlHash, title)
}

const hashChangeEventListener = (): void => {
if (iFrameRef.current == null) {
if (iFrameRef.current === null) {
console.error('hashChangeEvent from iframe but iFrameRef is null')
return
}
Expand All @@ -102,6 +112,20 @@ export default function IFrame(props: Props): JSX.Element {
props.onHashChanged(hash)
}

const titleChangeEventListener = (): void => {
if (iFrameRef.current === null) {
console.error('titleChangeEvent from iframe but iFrameRef is null')
return
}

const title = iFrameRef.current?.contentDocument?.title
if (title == null) {
return
}

props.onTitleChanged(title)
}

return (
<iframe
ref={iFrameRef}
Expand Down
10 changes: 9 additions & 1 deletion web/src/pages/Docs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,14 @@ export default function Docs(): JSX.Element {
window.history.pushState(null, '', url)
}

const iFramePageChanged = (urlPage: string, urlHash: string): void => {
const updateTitle = (newTitle: string): void => {
document.title = newTitle
}

const iFramePageChanged = (urlPage: string, urlHash: string, title?: string): void => {
if (title != null && title !== document.title) {
updateTitle(title)
}
if (urlPage === page.current) {
return
}
Expand Down Expand Up @@ -225,6 +232,7 @@ export default function Docs(): JSX.Element {
src={iFrameSrc}
onPageChanged={iFramePageChanged}
onHashChanged={iFrameHashChanged}
onTitleChanged={updateTitle}
onNotFound={iFrameNotFound}
/>
{!hideUi && (
Expand Down

0 comments on commit 8cd1eb3

Please sign in to comment.