mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-31 10:51:44 +02:00
Added example skeleton. IFrame component + basic usage
This commit is contained in:
7
examples/iframe-rendering/Readme.md
Normal file
7
examples/iframe-rendering/Readme.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
# IFrame rendering example
|
||||||
|
|
||||||
|
This example shows how to render Slate into IFrame, preserving single react component tree.
|
||||||
|
You may need this if you want to have separate styles for editor content & application.
|
||||||
|
|
||||||
|
Check out the [Examples readme](..) to see how to run it!
|
93
examples/iframe-rendering/index.js
Normal file
93
examples/iframe-rendering/index.js
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import ReactDOM from 'react-dom'
|
||||||
|
|
||||||
|
function resolveDocument (reactIFrameElementNode) {
|
||||||
|
const iFrame = ReactDOM.findDOMNode(reactIFrameElementNode);
|
||||||
|
return iFrame.contentDocument
|
||||||
|
}
|
||||||
|
|
||||||
|
//appending context to body > div, to suppress react warning
|
||||||
|
function getRootDiv (doc) {
|
||||||
|
let rootDiv = doc.querySelector('div#root')
|
||||||
|
if (!rootDiv) {
|
||||||
|
rootDiv = doc.createElement('div')
|
||||||
|
rootDiv.setAttribute('id', 'root')
|
||||||
|
rootDiv.id = 'root'
|
||||||
|
rootDiv.setAttribute('style', 'width: 100%; height: 100%')
|
||||||
|
|
||||||
|
doc.body.appendChild(rootDiv)
|
||||||
|
}
|
||||||
|
return rootDiv
|
||||||
|
}
|
||||||
|
|
||||||
|
class IFrame extends React.Component {
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
head: React.PropTypes.node,
|
||||||
|
children: React.PropTypes.node,
|
||||||
|
}
|
||||||
|
|
||||||
|
//rendering plain frame.
|
||||||
|
render () {
|
||||||
|
return <iframe style={{border: 'solid 1px black', width: '100%'}}></iframe>
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount = () => {
|
||||||
|
this.renderContents()
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate = () => {
|
||||||
|
this.renderContents()
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount = () => this.getDocument().then((doc) => {
|
||||||
|
ReactDOM.unmountComponentAtNode(doc.body)
|
||||||
|
if (this.props.head) {
|
||||||
|
ReactDOM.unmountComponentAtNode(doc.head)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
renderContents = () => this.getDocument().then((doc) => {
|
||||||
|
if (this.props.head) {
|
||||||
|
ReactDOM.unstable_renderSubtreeIntoContainer(this, this.props.head, doc.head)
|
||||||
|
}
|
||||||
|
const rootDiv = getRootDiv(doc)
|
||||||
|
ReactDOM.unstable_renderSubtreeIntoContainer(this, this.props.children, rootDiv)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
getDocument = () => new Promise((resolve) => {
|
||||||
|
const resolveTick = () => { //using arrow function to preserve `this` context
|
||||||
|
let doc = resolveDocument(this)
|
||||||
|
if (doc && doc.readyState === 'complete') {
|
||||||
|
resolve(doc)
|
||||||
|
} else {
|
||||||
|
window.requestAnimationFrame(resolveTick)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolveTick()
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class IFrameRendering extends React.Component {
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const bootstrapCDN =
|
||||||
|
<link
|
||||||
|
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
|
||||||
|
rel="stylesheet"
|
||||||
|
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
|
||||||
|
crossOrigin="anonymous">
|
||||||
|
</link>
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IFrame head={bootstrapCDN}>
|
||||||
|
<div>I'm in iframe</div>
|
||||||
|
</IFrame>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default IFrameRendering
|
@@ -22,6 +22,7 @@ import RTL from './rtl'
|
|||||||
import Tables from './tables'
|
import Tables from './tables'
|
||||||
import DevPerformancePlain from './development/performance-plain'
|
import DevPerformancePlain from './development/performance-plain'
|
||||||
import DevPerformanceRich from './development/performance-rich'
|
import DevPerformanceRich from './development/performance-rich'
|
||||||
|
import IFrameRendering from './iframe-rendering'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perf.
|
* Perf.
|
||||||
@@ -76,6 +77,7 @@ class App extends React.Component {
|
|||||||
{this.renderTab('Read-only', 'read-only')}
|
{this.renderTab('Read-only', 'read-only')}
|
||||||
{this.renderTab('RTL', 'rtl')}
|
{this.renderTab('RTL', 'rtl')}
|
||||||
{this.renderTab('Plugins', 'plugins')}
|
{this.renderTab('Plugins', 'plugins')}
|
||||||
|
{this.renderTab('IFrame', 'iframe')}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -134,6 +136,7 @@ const router = (
|
|||||||
<Route path="tables" component={Tables} />
|
<Route path="tables" component={Tables} />
|
||||||
<Route path="dev-performance-plain" component={DevPerformancePlain} />
|
<Route path="dev-performance-plain" component={DevPerformancePlain} />
|
||||||
<Route path="dev-performance-rich" component={DevPerformanceRich} />
|
<Route path="dev-performance-rich" component={DevPerformanceRich} />
|
||||||
|
<Route path="iframe" component={IFrameRendering}/>
|
||||||
</Route>
|
</Route>
|
||||||
</Router>
|
</Router>
|
||||||
)
|
)
|
||||||
|
Reference in New Issue
Block a user