ldx-widgets
Version:
widgets
119 lines (92 loc) • 3.42 kB
text/coffeescript
React = require 'react'
createClass = require 'create-react-class'
PropTypes = require 'prop-types'
{iframe} = React.DOM
###
@type - OPTIONAL - String
file type contained within the iframe
@src - REQUIRED - String
the source of the document to be loaded in the iframe
@id - OPTIONAL - String
the id attribute used on the iframe
@name - OPTIONAL - String
the name attribute used on the string. Also used when accessing frames[]
@className - OPTIONAL - String
the CSS class set to the iframe
@height - OPTIONAL - String | Number
a fixed height for the container
@width - OPTIONAL - String | Number
a fixed width for the container
@queryParams - OPTIONAL - Object
query params passed with iframe request
@resizeContentAfterLoad - OPTIONAL - Function
fired when the iframe finishes loading. This can be used to set a fixed height on a parent container in order to match the height of the embedded content. This is useful because iframes will not take the height of their content by default
@requestClass - REQUIRED - Function
required function that contains the server request class used for making service calls
###
IframeEmbedder = createClass
displayName: 'IframeEmbedder'
propTypes:
type: PropTypes.string
src: PropTypes.string.isRequired
id: PropTypes.string
name: PropTypes.string
className: PropTypes.string
height: PropTypes.oneOfType [
PropTypes.string
PropTypes.number
]
width: PropTypes.oneOfType [
PropTypes.string
PropTypes.number
]
resizeContentAfterLoad: PropTypes.func
queryParams: PropTypes.object
requestClass: PropTypes.func.isRequired
getDefaultProps: ->
height: '100%'
width: '100%'
className: 'iframe-embedded'
type: ''
id: ''
name: ''
render: ->
{width, height, className, id, name} = @props
iframe {
className: className
src: 'about:blank'
width: width
height: height
id: id
name: name
ref: 'embeddedFrame'
}
componentWillReceiveProps: (nextProps) ->
if @props.src isnt nextProps.src
@getDocument(nextProps)
getDocument: (props) ->
{src, queryParams, type, requestClass} = props
new requestClass
url: src
data: queryParams
.done (res) =>
if src and res?
# Wrap plain text
if type?.search('text/') > -1
unless type.search('xml') > -1 or type.search('html') > -1
res = "<pre style='white-space: pre-wrap;'>#{res}</pre>"
if @refs.embeddedFrame.contentDocument?
@refs.embeddedFrame.contentDocument.open()
@refs.embeddedFrame.contentDocument.writeln(res)
@refs.embeddedFrame.contentDocument.close()
@resizeContentAfterLoad()
componentDidMount: ->
@getDocument(@props)
resizeContentAfterLoad: ->
# What this does is it will size the iframe container to be the height of its content, removing the need for its own scrollbar
# Added an extra 40px to accommodate IE scrollbar
docHeight = @refs.embeddedFrame.contentDocument.getElementsByTagName('html')[0].scrollHeight
@props.resizeContentAfterLoad?(docHeight + 40)
shouldComponentUpdate: (nextProps) ->
@props.src isnt nextProps.src or @props.height isnt nextProps.height or @props.width isnt nextProps.width
module.exports = IframeEmbedder