Skip to content

Commit

Permalink
Merge pull request #808 from ONEARMY/feat/academy-embed-routing
Browse files Browse the repository at this point in the history
Feat/academy embed routing
  • Loading branch information
BenGamma authored Dec 1, 2019
2 parents c6bc57e + 3c97cab commit eef8436
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 5 deletions.
2 changes: 1 addition & 1 deletion cypress/integration/academy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ describe('[Academy]', () => {
it('[By Everyone]', () => {
cy.visit(Page.ACADEMY)
cy.step('Load instructions from another github repo')
const githubDoc = 'https://onearmy.github.io/academy/intro'
const githubDoc = 'https://onearmy.github.io/academy'
cy.get('iframe')
.should('have.attr', 'src')
.and('equal', githubDoc)
Expand Down
55 changes: 52 additions & 3 deletions src/components/ExternalEmbed/ExternalEmbed.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,59 @@
import * as React from 'react'
import { RouteComponentProps } from 'react-router'

interface IProps {
/*************************************************************************************
* Embed an Iframe
*
* NOTE - it is designed to only set the src on initial mount (not on prop change).
* This is so that postmessages can be used to communicate nav changes from the iframe
* up to the parent component, update the parent url and avoid double-refresh of the
* page.
*************************************************************************************/

interface IProps extends RouteComponentProps {
src: string
}
interface IState {
src: string
}

export class ExternalEmbed extends React.Component<IProps> {
export class ExternalEmbed extends React.Component<IProps, IState> {
constructor(props) {
super(props)
this.state = {
src: this.props.src,
}
}

componentDidMount() {
// TODO - possible compatibility fallback for addEventListener (IE8)
// Example: https://davidwalsh.name/window-iframe
window.addEventListener('message', this.handlePostmessageFromIframe, false)
}
componentWillUnmount() {
window.removeEventListener(
'message',
this.handlePostmessageFromIframe,
false,
)
}

/**
* Custom method to allow communication from Iframe to parent via postmessage
* Currently configured to receive the pathname of the onearmy github academy page
* and use to update the relative url on the parent router.
*/
handlePostmessageFromIframe = (e: MessageEvent) => {
// only allow messages from specific sites (academy dev and live)
if (
['http://localhost:3001', 'https://onearmy.github.io'].includes(e.origin)
) {
if (e.data && e.data.pathname) {
this.props.history.push(e.data.pathname)
}
}
}

render() {
return (
<div
Expand All @@ -14,7 +63,7 @@ export class ExternalEmbed extends React.Component<IProps> {
}}
>
<iframe
src={this.props.src}
src={this.state.src}
style={{
border: 0,
height: '100%',
Expand Down
13 changes: 12 additions & 1 deletion src/pages/PageList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import SignInPage from './SignIn/SignIn'
import { ForgotPasswordPage } from './Password/ForgotPassword'
import { ForgotPasswordMessagePage } from './Password/ForgotPasswordMessage'
import { CSSObject } from '@styled-system/css'
import { Route } from 'react-router'

export interface IPageMeta {
path: string
Expand Down Expand Up @@ -45,7 +46,17 @@ const user = {
}
const academy = {
path: '/academy',
component: <ExternalEmbed src="https://onearmy.github.io/academy/intro" />,
component: (
<Route
render={props => (
// NOTE - for embed to work github.io site also must host at same path, i.e. /academy
<ExternalEmbed
src={`https://onearmy.github.io${props.location.pathname}`}
{...props}
/>
)}
/>
),
title: 'Academy',
description: 'Demo external page embed',
customStyles: { position: 'absolute', height: '100%', width: '100%' },
Expand Down

0 comments on commit eef8436

Please sign in to comment.