diff --git a/.babelrc b/.babelrc index 43925d1..6e53678 100644 --- a/.babelrc +++ b/.babelrc @@ -1,5 +1,4 @@ { - "presets": ["preact-cli/babel"], "env": { "test": { "presets": [["preact-cli/babel", { "modules": "commonjs" }]] diff --git a/src/components/Console.jsx b/src/components/Console.jsx index befb87a..5ad9e2c 100644 --- a/src/components/Console.jsx +++ b/src/components/Console.jsx @@ -1,6 +1,7 @@ import { h, Component } from 'preact'; import { Inspector, chromeDark } from 'react-inspector'; import { Trans } from '@lingui/macro'; +import { PureComponent } from 'preact-compat'; class LogRow extends Component { shouldComponentUpdate() { @@ -22,7 +23,7 @@ class LogRow extends Component { } } -export class Console extends Component { +export class Console extends PureComponent { componentWillUpdate(nextProps) { if (nextProps.logs != this.props.logs) { // Scroll down after new log dom is inserted diff --git a/src/components/ContentWrap.jsx b/src/components/ContentWrap.jsx index 60f5349..6a93da1 100644 --- a/src/components/ContentWrap.jsx +++ b/src/components/ContentWrap.jsx @@ -9,9 +9,10 @@ import CodeMirror from '../CodeMirror'; import { Console } from './Console'; import { deferred } from '../deferred'; import CssSettingsModal from './CssSettingsModal'; +import { PreviewDimension } from './PreviewDimension.jsx'; const minCodeWrapSize = 33; -/* global htmlCodeEl, jsCodeEl, cssCodeEl, logCountEl +/* global htmlCodeEl */ export default class ContentWrap extends Component { @@ -22,6 +23,7 @@ export default class ContentWrap extends Component { isCssSettingsModalOpen: false, logs: [] }; + this.updateTimer = null; this.updateDelay = 500; this.htmlMode = HtmlModes.HTML; @@ -37,6 +39,15 @@ export default class ContentWrap extends Component { window.previewException = this.previewException.bind(this); // `clearConsole` is on window because it gets called from inside iframe also. window.clearConsole = this.clearConsole.bind(this); + + this.consoleHeaderDblClickHandler = this.consoleHeaderDblClickHandler.bind( + this + ); + this.clearConsoleBtnClickHandler = this.clearConsoleBtnClickHandler.bind( + this + ); + this.toggleConsole = this.toggleConsole.bind(this); + this.evalConsoleExpr = this.evalConsoleExpr.bind(this); } shouldComponentUpdate(nextProps, nextState) { return ( @@ -416,6 +427,12 @@ export default class ContentWrap extends Component { } this.updateSplits(); } + mainSplitDragHandler() { + this.previewDimension.update({ + w: this.frame.clientWidth, + h: this.frame.clientHeight + }); + } codeSplitDragStart() { document.body.classList.add('is-dragging'); } @@ -627,6 +644,8 @@ export default class ContentWrap extends Component { } render() { + log('contentwrap update'); + return ( + + (this.previewDimension = comp)} /> +
@@ -638,15 +657,14 @@ export default class ContentWrapFiles extends Component { id="demo-frame" allowfullscreen /> + (this.previewDimension = comp)} />
diff --git a/src/components/SplitPane.jsx b/src/components/SplitPane.jsx index cbd5cb0..de87362 100644 --- a/src/components/SplitPane.jsx +++ b/src/components/SplitPane.jsx @@ -2,42 +2,45 @@ import { h, Component } from 'preact'; import Split from 'split.js'; export class SplitPane extends Component { - // shouldComponentUpdate(nextProps, nextState) { - // return ( - // nextProps.direction !== this.props.direction || - // nextProps.sizes.join('') !== this.props.sizes.join('') - // ); - // } componentDidMount() { this.updateSplit(); } - componentWillUpdate() { - if (this.splitInstance) { - this.splitInstance.destroy(); + + componentDidUpdate(prevProps) { + if (this.hasGutter() && !this.hasPropsChanged(prevProps, this.props)) { + return; } - } - componentDidUpdate() { this.updateSplit(); } + componentWillUnmount() { + this.splitInstance.destroy(); + delete this.splitInstance; + } + hasGutter() { + return ( + [...this.parent.children].indexOf( + this.parent.querySelector('.gutter') + ) !== -1 + ); + } + hasPropsChanged(a, b) { + return ( + a.direction !== b.direction || + (a.sizes && b.sizes && a.sizes.join('') !== b.sizes.join('')) + ); + } updateSplit() { - const options = { - direction: this.props.direction, - minSize: this.props.minSize, - gutterSize: 6, - sizes: this.props.sizes - }; - if (this.props.onDragEnd) { - options.onDragEnd = this.props.onDragEnd; - } - if (this.props.onDragStart) { - options.onDragStart = this.props.onDragStart; + const { children, ...options } = this.props; + options.gutterSize = 6; + + if (this.splitInstance && this.hasGutter()) { + this.splitInstance.destroy(); } /* eslint-disable new-cap */ - this.splitInstance = Split( - this.props.children.map(node => '#' + node.attributes.id), - options - ); + this.splitInstance = Split([...this.parent.children], options); + console.log('recreating split'); + /* eslint-enable new-cap */ if (this.props.onSplit) { @@ -49,6 +52,10 @@ export class SplitPane extends Component { const { children, ...props } = this.props; /* eslint-enable no-unused-vars */ - return
{this.props.children}
; + return ( +
(this.parent = el)} {...props}> + {this.props.children} +
+ ); } } diff --git a/src/components/UserCodeMirror.jsx b/src/components/UserCodeMirror.jsx index 19a794f..270ddc0 100644 --- a/src/components/UserCodeMirror.jsx +++ b/src/components/UserCodeMirror.jsx @@ -43,7 +43,6 @@ export default class UserCodeMirror extends Component { shouldComponentUpdate(nextProps) { if (nextProps.prefs !== this.props.prefs) { const { prefs } = nextProps; - console.log('updating CM prefs', prefs); this.cm.setOption('indentWithTabs', prefs.indentWith !== 'spaces'); this.cm.setOption( diff --git a/src/components/app.jsx b/src/components/app.jsx index 1430210..fc0de15 100644 --- a/src/components/app.jsx +++ b/src/components/app.jsx @@ -255,7 +255,7 @@ export default class App extends Component { } getLanguageDefinition() { - console.log('🇯🇲 fetching defninition'); + // console.log('🇯🇲 fetching defninition'); const { lang } = this.state.prefs; if (!lang || lang === 'en') { return {}; diff --git a/src/style.css b/src/style.css index 898f531..820f11d 100644 --- a/src/style.css +++ b/src/style.css @@ -1812,6 +1812,16 @@ while the theme CSS file is loading */ margin-left: 10px; font-size: 0.8em; } + +.preview-dimension { + position: absolute; + right: 0; + top: 0; + background: #ccc; + color: black; + padding: 5px; + z-index: 1; +} @media screen and (max-width: 600px) { body { font-size: 70%;