0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-07 05:32:41 +00:00

Render brew in Iframe to not crash editor

This commit is contained in:
Trevor Buckner
2020-10-21 20:39:43 -04:00
parent ac2d6fe9a8
commit c75ac3c0f5
4 changed files with 43 additions and 29 deletions

View File

@@ -10,6 +10,7 @@ const ErrorBar = require('./errorBar/errorBar.jsx');
//TODO: move to the brew renderer //TODO: move to the brew renderer
const RenderWarnings = require('homebrewery/renderWarnings/renderWarnings.jsx'); const RenderWarnings = require('homebrewery/renderWarnings/renderWarnings.jsx');
const NotificationPopup = require('./notificationPopup/notificationPopup.jsx'); const NotificationPopup = require('./notificationPopup/notificationPopup.jsx');
const Frame = require('react-frame-component').default;
const PAGE_HEIGHT = 1056; const PAGE_HEIGHT = 1056;
const PPR_THRESHOLD = 50; const PPR_THRESHOLD = 50;
@@ -29,17 +30,15 @@ const BrewRenderer = createClass({
height : 0, height : 0,
isMounted : false, isMounted : false,
pages : pages, pages : pages,
usePPR : pages.length >= PPR_THRESHOLD, usePPR : pages.length >= PPR_THRESHOLD,
visibility : 'hidden',
initialContent : `<!DOCTYPE html><html><head><link href='/homebrew/bundle.css' rel='stylesheet'></link></head><body style='overflow: hidden'><div></div></body></html>`
}; };
}, },
height : 0, height : 0,
lastRender : <div></div>, lastRender : <div></div>,
componentDidMount : function() {
this.updateSize();
window.addEventListener('resize', this.updateSize);
},
componentWillUnmount : function() { componentWillUnmount : function() {
window.removeEventListener('resize', this.updateSize); window.removeEventListener('resize', this.updateSize);
}, },
@@ -54,8 +53,9 @@ const BrewRenderer = createClass({
updateSize : function() { updateSize : function() {
this.setState({ this.setState({
height : this.refs.main.parentNode.clientHeight, height : this.refs.main.parentNode.clientHeight,
isMounted : true isMounted : true,
visibility : 'visible'
}); });
}, },
@@ -85,7 +85,7 @@ const BrewRenderer = createClass({
}, },
renderPageInfo : function(){ renderPageInfo : function(){
return <div className='pageInfo'> return <div className='pageInfo' ref='main'>
{this.state.viewablePageNumber + 1} / {this.state.pages.length} {this.state.viewablePageNumber + 1} / {this.state.pages.length}
</div>; </div>;
}, },
@@ -125,24 +125,33 @@ const BrewRenderer = createClass({
return this.lastRender; return this.lastRender;
}, },
frameDidMount : function(){ //This triggers when iFrame finishes internal "componentDidMount"
setTimeout(()=>{ //We still see a flicker where the style isn't applied yet, so wait 100ms before showing iFrame
this.updateSize();
window.addEventListener('resize', this.updateSize);
}, 100);
},
render : function(){ render : function(){
//render in iFrame so broken code doesn't crash the site.
return ( return (
<React.Fragment> <React.Fragment>
<div className='brewRenderer' <Frame initialContent={this.state.initialContent} style={{ width: '100%', height: '100%', visibility: this.state.visibility }} contentDidMount={this.frameDidMount}>
onScroll={this.handleScroll} <div className='brewRenderer'
ref='main' onScroll={this.handleScroll}
style={{ height: this.state.height }}> style={{ height: this.state.height }}>
<ErrorBar errors={this.props.errors} /> <ErrorBar errors={this.props.errors} />
<div className='popups'> <div className='popups'>
<RenderWarnings /> <RenderWarnings />
<NotificationPopup /> <NotificationPopup />
</div> </div>
<div className='pages' ref='pages'> <div className='pages' ref='pages'>
{this.renderPages()} {this.renderPages()}
</div>
</div> </div>
</div>; </Frame>
{this.renderPageInfo()} {this.renderPageInfo()}
{this.renderPPRmsg()} {this.renderPPRmsg()}
</React.Fragment> </React.Fragment>

5
package-lock.json generated
View File

@@ -5829,6 +5829,11 @@
} }
} }
}, },
"react-frame-component": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/react-frame-component/-/react-frame-component-4.1.3.tgz",
"integrity": "sha512-4PurhctiqnmC1F5prPZ+LdsalH7pZ3SFA5xoc0HBe8mSHctdLLt4Cr2WXfXOoajHBYq/yiipp9zOgx+vy8GiEA=="
},
"react-is": { "react-is": {
"version": "16.12.0", "version": "16.12.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz",

View File

@@ -63,6 +63,7 @@
"query-string": "6.13.5", "query-string": "6.13.5",
"react": "^16.13.1", "react": "^16.13.1",
"react-dom": "^16.13.1", "react-dom": "^16.13.1",
"react-frame-component": "4.1.3",
"react-router-dom": "5.2.0", "react-router-dom": "5.2.0",
"superagent": "^6.1.0", "superagent": "^6.1.0",
"vitreum": "github:calculuschild/vitreum#21a8e1c9421f1d3a3b474c12f480feb2fbd28c5b" "vitreum": "github:calculuschild/vitreum#21a8e1c9421f1d3a3b474c12f480feb2fbd28c5b"

View File

@@ -54,7 +54,7 @@ const SplitPane = createClass({
}, },
*/ */
renderDivider : function(){ renderDivider : function(){
return <div className='divider' onMouseDown={this.handleDown}> return <div className='divider' onMouseDown={this.handleDown} >
<div className='dots'> <div className='dots'>
<i className='fa fa-circle' /> <i className='fa fa-circle' />
<i className='fa fa-circle' /> <i className='fa fa-circle' />
@@ -67,16 +67,11 @@ const SplitPane = createClass({
return <div className='splitPane' onMouseMove={this.handleMove} onMouseUp={this.handleUp}> return <div className='splitPane' onMouseMove={this.handleMove} onMouseUp={this.handleUp}>
<Pane ref='pane1' width={this.state.size}>{this.props.children[0]}</Pane> <Pane ref='pane1' width={this.state.size}>{this.props.children[0]}</Pane>
{this.renderDivider()} {this.renderDivider()}
<Pane ref='pane2'>{this.props.children[1]}</Pane> <Pane ref='pane2' isDragging={this.state.isDragging}>{this.props.children[1]}</Pane>
</div>; </div>;
} }
}); });
const Pane = createClass({ const Pane = createClass({
getDefaultProps : function() { getDefaultProps : function() {
return { return {
@@ -90,12 +85,16 @@ const Pane = createClass({
flex : 'none', flex : 'none',
width : `${this.props.width}px` width : `${this.props.width}px`
}; };
} else {
styles = {
pointerEvents : this.props.isDragging ? 'none' : 'auto' //Disable mouse capture in the rightmost pane; dragging into the iframe drops the divider otherwise
};
} }
return <div className={cx('pane', this.props.className)} style={styles}> return <div className={cx('pane', this.props.className)} style={styles}>
{this.props.children} {this.props.children}
</div>; </div>;
} }
}); });
module.exports = SplitPane; module.exports = SplitPane;