-
Notifications
You must be signed in to change notification settings - Fork 127
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2203 from tf/iframe-resize
Add option to resize iframe embed based on message sent from embed
- Loading branch information
Showing
7 changed files
with
252 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
entry_types/scrolled/config/locales/new/iframe_resize.de.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
de: | ||
pageflow_scrolled: | ||
editor: | ||
content_elements: | ||
iframeEmbed: | ||
attributes: | ||
autoResize: | ||
label: Dynamische Höhenanpassungen | ||
inline_help: Höhe automatisch an den Inhalt des Elements anpassen. | ||
help_texts: | ||
autoResize: |- | ||
Diese Option erfordert die Integration eines | ||
Skripts in die eingebettete Seite. Weitere | ||
Informationen findest du in diesem <a target="_blank" rel="noopener noreferrer" | ||
href="https://pageflow.freshdesk.com/de/support/solutions/articles/11000130710-wie-passe-ich-die-gr%C3%B6%C3%9Fe-von-iframe-embeds-automatisch-an-den-inhalt-an-">Hilfeartikel</a>. |
13 changes: 13 additions & 0 deletions
13
entry_types/scrolled/config/locales/new/iframe_resize.en.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
en: | ||
pageflow_scrolled: | ||
editor: | ||
content_elements: | ||
iframeEmbed: | ||
attributes: | ||
autoResize: | ||
label: Dynamic Height | ||
inline_help: Adapt height to content automatically. | ||
help_texts: | ||
autoResize: |- | ||
This option requires a custom script in the embedded | ||
page. <a target="_blank" rel="noopener noreferrer" href="https://pageflow.freshdesk.com/en/support/solutions/articles/11000130710-how-to-automatically-resize-iframe-embeds-to-fit-the-content">More info</a>. |
145 changes: 145 additions & 0 deletions
145
entry_types/scrolled/package/spec/contentElements/iframeEmbed/useIframeHeight-spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
import {useIframeHeight} from 'contentElements/iframeEmbed/useIframeHeight'; | ||
|
||
import {renderHook} from '@testing-library/react-hooks'; | ||
import {asyncHandlingOf} from 'support/asyncHandlingOf/forHooks'; | ||
|
||
describe('useIframeHeight', () => { | ||
it('is undefined by default', async () => { | ||
const {result} = renderHook(() => | ||
useIframeHeight({src: 'https://example.com/some/', | ||
active: true}) | ||
); | ||
|
||
expect(result.current).toEqual('400px'); | ||
}); | ||
|
||
it('sets height from message matching iframe location', async () => { | ||
const {result} = renderHook(() => | ||
useIframeHeight({src: 'https://example.com/some/', | ||
active: true}) | ||
); | ||
|
||
await asyncHandlingOf(() => { | ||
window.postMessage(JSON.stringify({ | ||
context: 'iframe.resize', | ||
height: 350, | ||
src: 'https://example.com/some/' | ||
}), '*'); | ||
}); | ||
|
||
expect(result.current).toEqual('350px'); | ||
}); | ||
|
||
it('removes listener on cleanup', async () => { | ||
const {result, unmount} = renderHook(() => | ||
useIframeHeight({src: 'https://example.com/some/', | ||
active: true}) | ||
); | ||
|
||
unmount(); | ||
await asyncHandlingOf(() => { | ||
window.postMessage(JSON.stringify({ | ||
context: 'iframe.resize', | ||
height: 350, | ||
src: 'https://example.com/some/' | ||
}), '*'); | ||
}); | ||
|
||
expect(result.current).toEqual('400px'); | ||
}); | ||
|
||
it('ignores messages if src does not match', async () => { | ||
const {result} = renderHook(() => | ||
useIframeHeight({src: 'https://example.com/some/', | ||
active: true}) | ||
); | ||
|
||
await asyncHandlingOf(() => { | ||
window.postMessage(JSON.stringify({ | ||
context: 'iframe.resize', | ||
height: 350, | ||
src: 'https://example.com/other/' | ||
}), '*'); | ||
}); | ||
|
||
expect(result.current).toEqual('400px'); | ||
}); | ||
|
||
it('ignores messages if context is not iframe.resize', async () => { | ||
const {result} = renderHook(() => | ||
useIframeHeight({src: 'https://example.com/some/', | ||
active: true}) | ||
); | ||
|
||
await asyncHandlingOf(() => { | ||
window.postMessage(JSON.stringify({ | ||
context: 'whatever', | ||
height: 350, | ||
src: 'https://example.com/some/' | ||
}), '*'); | ||
}); | ||
|
||
expect(result.current).toEqual('400px'); | ||
}); | ||
|
||
it('ignores non-string messages', async () => { | ||
const {result} = renderHook(() => | ||
useIframeHeight({src: 'https://example.com/some/', | ||
active: true}) | ||
); | ||
|
||
await asyncHandlingOf(() => { | ||
window.postMessage({ | ||
some: 'value' | ||
}, '*'); | ||
}); | ||
|
||
expect(result.current).toEqual('400px'); | ||
}); | ||
|
||
it('ignores string messages that do not parse as JSON', async () => { | ||
const {result} = renderHook(() => | ||
useIframeHeight({src: 'https://example.com/some/', | ||
active: true}) | ||
); | ||
|
||
await asyncHandlingOf(() => { | ||
window.postMessage('hello', '*'); | ||
}); | ||
|
||
expect(result.current).toEqual('400px'); | ||
}); | ||
|
||
it('ignores messages if not active', async () => { | ||
const {result} = renderHook(() => | ||
useIframeHeight({src: 'https://example.com/some/', | ||
active: false}) | ||
); | ||
|
||
await asyncHandlingOf(() => { | ||
window.postMessage(JSON.stringify({ | ||
context: 'iframe.resize', | ||
height: 350, | ||
src: 'https://example.com/some/' | ||
}), '*'); | ||
}); | ||
|
||
expect(result.current).toEqual('400px'); | ||
}); | ||
|
||
it('never regards undefined source as matching', async () => { | ||
const {result} = renderHook(() => | ||
useIframeHeight({src: undefined, | ||
active: true}) | ||
); | ||
|
||
await asyncHandlingOf(() => { | ||
window.postMessage(JSON.stringify({ | ||
context: 'iframe.resize', | ||
height: 350 | ||
}), '*'); | ||
}); | ||
|
||
expect(result.current).toEqual('400px'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
entry_types/scrolled/package/src/contentElements/iframeEmbed/useIframeHeight.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import {useEffect, useState} from 'react'; | ||
|
||
export function useIframeHeight({src, active}) { | ||
const [height, setHeight] = useState('400px'); | ||
|
||
useEffect(() => { | ||
if (!active) { | ||
return; | ||
} | ||
|
||
window.addEventListener('message', receive); | ||
|
||
function receive(event) { | ||
const data = parse(event.data); | ||
|
||
if (src && data.context === 'iframe.resize' && data.src === src) { | ||
setHeight(data.height + 'px'); | ||
} | ||
} | ||
|
||
return () => window.removeEventListener('message', receive); | ||
}, [active, src]); | ||
|
||
return height; | ||
} | ||
|
||
function parse(data) { | ||
try { | ||
return JSON.parse(data); | ||
} | ||
catch(e) { | ||
return {}; | ||
} | ||
} |