mirror of
https://github.com/chinchang/web-maker.git
synced 2025-07-09 16:06:21 +02:00
Merge pull request #327 from chinchang/fix-319-console-detached
Fix 319 console detached
This commit is contained in:
70
src/components/Console.jsx
Normal file
70
src/components/Console.jsx
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import { h } from 'preact';
|
||||||
|
import CodeMirrorBox from './CodeMirrorBox';
|
||||||
|
|
||||||
|
export function Console({
|
||||||
|
isConsoleOpen,
|
||||||
|
onConsoleHeaderDblClick,
|
||||||
|
onClearConsoleBtnClick,
|
||||||
|
toggleConsole,
|
||||||
|
onEvalInputKeyup,
|
||||||
|
onReady
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
id="consoleEl"
|
||||||
|
class={`console ${isConsoleOpen ? '' : 'is-minimized'}`}
|
||||||
|
>
|
||||||
|
<div id="consoleLogEl" class="console__log">
|
||||||
|
<div
|
||||||
|
class="js-console__header code-wrap__header"
|
||||||
|
title="Double click to toggle console"
|
||||||
|
onDblClick={onConsoleHeaderDblClick}
|
||||||
|
>
|
||||||
|
<span class="code-wrap__header-label">
|
||||||
|
Console (<span id="logCountEl">0</span>)
|
||||||
|
</span>
|
||||||
|
<div class="code-wrap__header-right-options">
|
||||||
|
<a
|
||||||
|
class="code-wrap__header-btn"
|
||||||
|
title="Clear console (CTRL + L)"
|
||||||
|
onClick={onClearConsoleBtnClick}
|
||||||
|
>
|
||||||
|
<svg>
|
||||||
|
<use xlinkHref="#cancel-icon" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="code-wrap__header-btn code-wrap__collapse-btn"
|
||||||
|
title="Toggle console"
|
||||||
|
onClick={toggleConsole}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<CodeMirrorBox
|
||||||
|
options={{
|
||||||
|
mode: 'javascript',
|
||||||
|
lineWrapping: true,
|
||||||
|
theme: 'monokai',
|
||||||
|
foldGutter: true,
|
||||||
|
readOnly: true,
|
||||||
|
gutters: ['CodeMirror-foldgutter']
|
||||||
|
}}
|
||||||
|
onCreation={el => onReady(el)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="consolePromptEl"
|
||||||
|
class="console__prompt flex flex-v-center flex-shrink-0"
|
||||||
|
>
|
||||||
|
<svg width="18" height="18" fill="#346fd2">
|
||||||
|
<use xlinkHref="#chevron-icon" />
|
||||||
|
</svg>
|
||||||
|
<input
|
||||||
|
tabIndex={isConsoleOpen ? 0 : -1}
|
||||||
|
onKeyUp={onEvalInputKeyup}
|
||||||
|
class="console-exec-input"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -6,7 +6,7 @@ import { log, writeFile, loadJS, getCompleteHtml } from '../utils';
|
|||||||
import { SplitPane } from './SplitPane.jsx';
|
import { SplitPane } from './SplitPane.jsx';
|
||||||
import { trackEvent } from '../analytics';
|
import { trackEvent } from '../analytics';
|
||||||
import CodeMirror from '../CodeMirror';
|
import CodeMirror from '../CodeMirror';
|
||||||
import CodeMirrorBox from './CodeMirrorBox';
|
import { Console } from './Console';
|
||||||
import { deferred } from '../deferred';
|
import { deferred } from '../deferred';
|
||||||
import CssSettingsModal from './CssSettingsModal';
|
import CssSettingsModal from './CssSettingsModal';
|
||||||
const minCodeWrapSize = 33;
|
const minCodeWrapSize = 33;
|
||||||
@ -52,7 +52,7 @@ export default class ContentWrap extends Component {
|
|||||||
}
|
}
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
// HACK: becuase its a DOM manipulation
|
// HACK: becuase its a DOM manipulation
|
||||||
window.logCountEl.textContent = this.logCount;
|
this.updateLogCount();
|
||||||
|
|
||||||
// log('🚀', 'didupdate', this.props.currentItem);
|
// log('🚀', 'didupdate', this.props.currentItem);
|
||||||
// if (this.isValidItem(this.props.currentItem)) {
|
// if (this.isValidItem(this.props.currentItem)) {
|
||||||
@ -549,6 +549,7 @@ export default class ContentWrap extends Component {
|
|||||||
trackEvent('ui', 'updateCodeMode', mode);
|
trackEvent('ui', 'updateCodeMode', mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
detachPreview() {
|
detachPreview() {
|
||||||
if (this.detachedWindow) {
|
if (this.detachedWindow) {
|
||||||
this.detachedWindow.focus();
|
this.detachedWindow.focus();
|
||||||
@ -558,7 +559,6 @@ export default class ContentWrap extends Component {
|
|||||||
const iframeWidth = iframeBounds.width;
|
const iframeWidth = iframeBounds.width;
|
||||||
const iframeHeight = iframeBounds.height;
|
const iframeHeight = iframeBounds.height;
|
||||||
document.body.classList.add('is-detached-mode');
|
document.body.classList.add('is-detached-mode');
|
||||||
window.globalConsoleContainerEl.insertBefore(window.consoleEl, null);
|
|
||||||
|
|
||||||
this.detachedWindow = window.open(
|
this.detachedWindow = window.open(
|
||||||
'./preview.html',
|
'./preview.html',
|
||||||
@ -574,7 +574,6 @@ export default class ContentWrap extends Component {
|
|||||||
if (this.detachedWindow && this.detachedWindow.closed) {
|
if (this.detachedWindow && this.detachedWindow.closed) {
|
||||||
clearInterval(intervalID);
|
clearInterval(intervalID);
|
||||||
document.body.classList.remove('is-detached-mode');
|
document.body.classList.remove('is-detached-mode');
|
||||||
$('#js-demo-side').insertBefore(window.consoleEl, null);
|
|
||||||
this.detachedWindow = null;
|
this.detachedWindow = null;
|
||||||
// Update main frame preview to get latest changes (which were not
|
// Update main frame preview to get latest changes (which were not
|
||||||
// getting reflected while detached window was open)
|
// getting reflected while detached window was open)
|
||||||
@ -583,6 +582,12 @@ export default class ContentWrap extends Component {
|
|||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateLogCount() {
|
||||||
|
if (window.logCountEl) {
|
||||||
|
logCountEl.textContent = this.logCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMessageFromConsole() {
|
onMessageFromConsole() {
|
||||||
/* eslint-disable no-param-reassign */
|
/* eslint-disable no-param-reassign */
|
||||||
[...arguments].forEach(arg => {
|
[...arguments].forEach(arg => {
|
||||||
@ -614,7 +619,7 @@ export default class ContentWrap extends Component {
|
|||||||
this.consoleCm.scrollTo(0, Infinity);
|
this.consoleCm.scrollTo(0, Infinity);
|
||||||
this.logCount++;
|
this.logCount++;
|
||||||
});
|
});
|
||||||
logCountEl.textContent = this.logCount;
|
this.updateLogCount();
|
||||||
|
|
||||||
/* eslint-enable no-param-reassign */
|
/* eslint-enable no-param-reassign */
|
||||||
}
|
}
|
||||||
@ -638,7 +643,7 @@ export default class ContentWrap extends Component {
|
|||||||
clearConsole() {
|
clearConsole() {
|
||||||
this.consoleCm.setValue('');
|
this.consoleCm.setValue('');
|
||||||
this.logCount = 0;
|
this.logCount = 0;
|
||||||
window.logCountEl.textContent = this.logCount;
|
this.updateLogCount();
|
||||||
}
|
}
|
||||||
clearConsoleBtnClickHandler() {
|
clearConsoleBtnClickHandler() {
|
||||||
this.clearConsole();
|
this.clearConsole();
|
||||||
@ -884,62 +889,16 @@ export default class ContentWrap extends Component {
|
|||||||
id="demo-frame"
|
id="demo-frame"
|
||||||
allowfullscreen
|
allowfullscreen
|
||||||
/>
|
/>
|
||||||
<div
|
<Console
|
||||||
id="consoleEl"
|
isConsoleOpen={this.state.isConsoleOpen}
|
||||||
class={`console ${this.state.isConsoleOpen ? '' : 'is-minimized'}`}
|
onConsoleHeaderDblClick={this.consoleHeaderDblClickHandler.bind(
|
||||||
>
|
this
|
||||||
<div id="consoleLogEl" class="console__log">
|
)}
|
||||||
<div
|
onClearConsoleBtnClick={this.clearConsoleBtnClickHandler.bind(this)}
|
||||||
class="js-console__header code-wrap__header"
|
toggleConsole={this.toggleConsole.bind(this)}
|
||||||
title="Double click to toggle console"
|
onEvalInputKeyup={this.evalConsoleExpr.bind(this)}
|
||||||
onDblClick={this.consoleHeaderDblClickHandler.bind(this)}
|
onReady={el => (this.consoleCm = el)}
|
||||||
>
|
|
||||||
<span class="code-wrap__header-label">
|
|
||||||
Console (<span id="logCountEl">0</span>)
|
|
||||||
</span>
|
|
||||||
<div class="code-wrap__header-right-options">
|
|
||||||
<a
|
|
||||||
class="code-wrap__header-btn"
|
|
||||||
title="Clear console (CTRL + L)"
|
|
||||||
onClick={this.clearConsoleBtnClickHandler.bind(this)}
|
|
||||||
>
|
|
||||||
<svg>
|
|
||||||
<use xlinkHref="#cancel-icon" />
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="code-wrap__header-btn code-wrap__collapse-btn"
|
|
||||||
title="Toggle console"
|
|
||||||
onClick={this.toggleConsole.bind(this)}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<CodeMirrorBox
|
|
||||||
options={{
|
|
||||||
mode: 'javascript',
|
|
||||||
lineWrapping: true,
|
|
||||||
theme: 'monokai',
|
|
||||||
foldGutter: true,
|
|
||||||
readOnly: true,
|
|
||||||
gutters: ['CodeMirror-foldgutter']
|
|
||||||
}}
|
|
||||||
onCreation={el => (this.consoleCm = el)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
id="consolePromptEl"
|
|
||||||
class="console__prompt flex flex-v-center flex-shrink-0"
|
|
||||||
>
|
|
||||||
<svg width="18" height="18" fill="#346fd2">
|
|
||||||
<use xlinkHref="#chevron-icon" />
|
|
||||||
</svg>
|
|
||||||
<input
|
|
||||||
tabIndex={this.state.isConsoleOpen ? 0 : -1}
|
|
||||||
onKeyUp={this.evalConsoleExpr.bind(this)}
|
|
||||||
class="console-exec-input"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<CssSettingsModal
|
<CssSettingsModal
|
||||||
show={this.state.isCssSettingsModalOpen}
|
show={this.state.isCssSettingsModalOpen}
|
||||||
closeHandler={() =>
|
closeHandler={() =>
|
||||||
|
@ -1181,7 +1181,7 @@ export default class App extends Component {
|
|||||||
onEditorFocus={this.editorFocusHandler.bind(this)}
|
onEditorFocus={this.editorFocusHandler.bind(this)}
|
||||||
onSplitUpdate={this.splitUpdateHandler.bind(this)}
|
onSplitUpdate={this.splitUpdateHandler.bind(this)}
|
||||||
/>
|
/>
|
||||||
<div class="global-console-container" id="globalConsoleContainerEl" />
|
|
||||||
<Footer
|
<Footer
|
||||||
prefs={this.state.prefs}
|
prefs={this.state.prefs}
|
||||||
layoutBtnClickHandler={this.layoutBtnClickHandler.bind(this)}
|
layoutBtnClickHandler={this.layoutBtnClickHandler.bind(this)}
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
--color-button: #d3a447;
|
--color-button: #d3a447;
|
||||||
--color-focus-outline: #d3a447;
|
--color-focus-outline: #d3a447;
|
||||||
--color-form-control-bg: #2c214b;
|
--color-form-control-bg: #2c214b;
|
||||||
|
|
||||||
|
--footer-height: 37px;
|
||||||
|
--console-height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@ -403,7 +406,9 @@ body:not(.light-version).overlay-visible .main-container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.is-detached-mode .demo-side {
|
.is-detached-mode .demo-side {
|
||||||
display: none;
|
/* display: none; */
|
||||||
|
width: 0px !important;
|
||||||
|
height: 0px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.is-detached-mode .code-side {
|
.is-detached-mode .code-side {
|
||||||
@ -721,12 +726,12 @@ body > #demo-frame {
|
|||||||
.footer a > svg,
|
.footer a > svg,
|
||||||
.footer button > svg {
|
.footer button > svg {
|
||||||
transition: 0.3s ease;
|
transition: 0.3s ease;
|
||||||
fill: rgba(255, 255, 255, 0.5);
|
fill: rgba(255, 255, 255, 0.35);
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer a:hover svg,
|
.footer a:hover svg,
|
||||||
.footer button:hover svg {
|
.footer button:hover svg {
|
||||||
fill: rgba(255, 255, 255, 0.45);
|
fill: rgba(255, 255, 255, 0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mode-btn svg {
|
.mode-btn svg {
|
||||||
@ -735,7 +740,7 @@ body > #demo-frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.mode-btn.selected svg {
|
.mode-btn.selected svg {
|
||||||
fill: rgba(255, 255, 255, 0.45);
|
fill: rgba(255, 255, 255, 0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
.gutter {
|
.gutter {
|
||||||
@ -1418,12 +1423,6 @@ body > #demo-frame {
|
|||||||
cursor: ns-resize;
|
cursor: ns-resize;
|
||||||
}
|
}
|
||||||
|
|
||||||
.global-console-container {
|
|
||||||
display: none;
|
|
||||||
position: relative;
|
|
||||||
height: 35px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Detached mode */
|
/* Detached mode */
|
||||||
|
|
||||||
.is-detached-mode .console,
|
.is-detached-mode .console,
|
||||||
@ -1431,8 +1430,14 @@ body > #demo-frame {
|
|||||||
z-index: 4;
|
z-index: 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.is-detached-mode .global-console-container {
|
.is-detached-mode .console {
|
||||||
display: block;
|
position: fixed;
|
||||||
|
bottom: var(--footer-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-detached-mode .content-wrap {
|
||||||
|
/* So that there is space for console */
|
||||||
|
padding-bottom: var(--console-height);
|
||||||
}
|
}
|
||||||
|
|
||||||
.kbd-shortcut__keys {
|
.kbd-shortcut__keys {
|
||||||
|
Reference in New Issue
Block a user