mirror of
https://github.com/chinchang/web-maker.git
synced 2025-07-16 19:46:19 +02:00
port console
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import { h, Component } from 'preact';
|
import { h, Component } from 'preact';
|
||||||
import { jsLibs, cssLibs } from '../libraryList';
|
import { jsLibs, cssLibs } from '../libraryList';
|
||||||
|
import { trackEvent } from '../analytics';
|
||||||
|
|
||||||
export default class AddLibrary extends Component {
|
export default class AddLibrary extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -21,7 +22,7 @@ export default class AddLibrary extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// trackEvent('ui', 'addLibrarySelect', target.selectedOptions[0].label);
|
trackEvent('ui', 'addLibrarySelect', target.selectedOptions[0].label);
|
||||||
this.props.onChange({ js: this.state.js, css: this.state.css });
|
this.props.onChange({ js: this.state.js, css: this.state.css });
|
||||||
// Reset the select to the default value
|
// Reset the select to the default value
|
||||||
target.value = '';
|
target.value = '';
|
||||||
|
@@ -6,6 +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 { deferred } from '../deferred';
|
import { deferred } from '../deferred';
|
||||||
|
|
||||||
const BASE_PATH = chrome.extension || window.DEBUG ? '/' : '/app';
|
const BASE_PATH = chrome.extension || window.DEBUG ? '/' : '/app';
|
||||||
@@ -14,6 +15,9 @@ const minCodeWrapSize = 33;
|
|||||||
export default class ContentWrap extends Component {
|
export default class ContentWrap extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
isConsoleOpen: false
|
||||||
|
};
|
||||||
this.updateTimer = null;
|
this.updateTimer = null;
|
||||||
this.updateDelay = 500;
|
this.updateDelay = 500;
|
||||||
this.htmlMode = HtmlModes.HTML;
|
this.htmlMode = HtmlModes.HTML;
|
||||||
@@ -24,6 +28,12 @@ export default class ContentWrap extends Component {
|
|||||||
this.codeInPreview = { html: null, css: null, js: null };
|
this.codeInPreview = { html: null, css: null, js: null };
|
||||||
this.cmCodes = { html: props.currentItem.html, css: '', js: '' };
|
this.cmCodes = { html: props.currentItem.html, css: '', js: '' };
|
||||||
this.cm = {};
|
this.cm = {};
|
||||||
|
this.logCount = 0;
|
||||||
|
|
||||||
|
window.onMessageFromConsole = this.onMessageFromConsole.bind(this);
|
||||||
|
|
||||||
|
// `clearConsole` is on window because it gets called from inside iframe also.
|
||||||
|
window.clearConsole = this.clearConsole.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onHtmlCodeChange(editor, change) {
|
onHtmlCodeChange(editor, change) {
|
||||||
@@ -188,6 +198,9 @@ export default class ContentWrap extends Component {
|
|||||||
return !!item.title;
|
return !!item.title;
|
||||||
}
|
}
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
|
// HACK: becuase its a DOM manipulation
|
||||||
|
window.logCountEl.textContent = this.logCount;
|
||||||
|
|
||||||
// log('🚀', 'didupdate', this.props.currentItem);
|
// log('🚀', 'didupdate', this.props.currentItem);
|
||||||
// if (this.isValidItem(this.props.currentItem)) {
|
// if (this.isValidItem(this.props.currentItem)) {
|
||||||
// this.refreshEditor();
|
// this.refreshEditor();
|
||||||
@@ -330,6 +343,14 @@ export default class ContentWrap extends Component {
|
|||||||
this.toggleCodeWrapCollapse(codeWrapParent);
|
this.toggleCodeWrapCollapse(codeWrapParent);
|
||||||
trackEvent('ui', 'paneCollapseBtnClick', codeWrapParent.dataset.type);
|
trackEvent('ui', 'paneCollapseBtnClick', codeWrapParent.dataset.type);
|
||||||
}
|
}
|
||||||
|
codeWrapHeaderDblClickHandler(e) {
|
||||||
|
if (!e.target.classList.contains('js-code-wrap__header')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const codeWrapParent = e.target.parentElement;
|
||||||
|
this.toggleCodeWrapCollapse(codeWrapParent);
|
||||||
|
trackEvent('ui', 'paneHeaderDblClick', codeWrapParent.dataset.type);
|
||||||
|
}
|
||||||
|
|
||||||
resetSplitting() {
|
resetSplitting() {
|
||||||
const codeSplitSizes = this.getCodeSplitSizes();
|
const codeSplitSizes = this.getCodeSplitSizes();
|
||||||
@@ -505,6 +526,64 @@ export default class ContentWrap extends Component {
|
|||||||
var intervalID = window.setInterval(checkWindow.bind(this), 500);
|
var intervalID = window.setInterval(checkWindow.bind(this), 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMessageFromConsole() {
|
||||||
|
const self = this;
|
||||||
|
/* eslint-disable no-param-reassign */
|
||||||
|
[...arguments].forEach(arg => {
|
||||||
|
if (
|
||||||
|
arg &&
|
||||||
|
arg.indexOf &&
|
||||||
|
arg.indexOf('filesystem:chrome-extension') !== -1
|
||||||
|
) {
|
||||||
|
arg = arg.replace(
|
||||||
|
/filesystem:chrome-extension.*\.js:(\d+):*(\d*)/g,
|
||||||
|
'script $1:$2'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.consoleCm.replaceRange(
|
||||||
|
arg +
|
||||||
|
' ' +
|
||||||
|
((arg + '').match(/\[object \w+]/) ? JSON.stringify(arg) : '') +
|
||||||
|
'\n',
|
||||||
|
{
|
||||||
|
line: Infinity
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
this.consoleCm.replaceRange('🌀\n', {
|
||||||
|
line: Infinity
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.consoleCm.scrollTo(0, Infinity);
|
||||||
|
this.logCount++;
|
||||||
|
});
|
||||||
|
logCountEl.textContent = this.logCount;
|
||||||
|
|
||||||
|
/* eslint-enable no-param-reassign */
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleConsole() {
|
||||||
|
this.setState({ isConsoleOpen: !this.state.isConsoleOpen });
|
||||||
|
trackEvent('ui', 'consoleToggle');
|
||||||
|
}
|
||||||
|
consoleHeaderDblClickHandler(e) {
|
||||||
|
if (!e.target.classList.contains('js-console__header')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
trackEvent('ui', 'consoleToggleDblClick');
|
||||||
|
this.toggleConsole();
|
||||||
|
}
|
||||||
|
clearConsole() {
|
||||||
|
this.consoleCm.setValue('');
|
||||||
|
this.logCount = 0;
|
||||||
|
window.logCountEl.textContent = this.logCount;
|
||||||
|
}
|
||||||
|
clearConsoleBtnClickHandler() {
|
||||||
|
this.clearConsole();
|
||||||
|
trackEvent('ui', 'consoleClearBtnClick');
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<SplitPane
|
<SplitPane
|
||||||
@@ -540,6 +619,7 @@ export default class ContentWrap extends Component {
|
|||||||
<div
|
<div
|
||||||
class="js-code-wrap__header code-wrap__header"
|
class="js-code-wrap__header code-wrap__header"
|
||||||
title="Double click to toggle code pane"
|
title="Double click to toggle code pane"
|
||||||
|
onDblClick={this.codeWrapHeaderDblClickHandler.bind(this)}
|
||||||
>
|
>
|
||||||
<label class="btn-group" dropdow title="Click to change">
|
<label class="btn-group" dropdow title="Click to change">
|
||||||
<span id="js-html-mode-label" class="code-wrap__header-label">
|
<span id="js-html-mode-label" class="code-wrap__header-label">
|
||||||
@@ -586,6 +666,7 @@ export default class ContentWrap extends Component {
|
|||||||
<div
|
<div
|
||||||
class="js-code-wrap__header code-wrap__header"
|
class="js-code-wrap__header code-wrap__header"
|
||||||
title="Double click to toggle code pane"
|
title="Double click to toggle code pane"
|
||||||
|
onDblClick={this.codeWrapHeaderDblClickHandler.bind(this)}
|
||||||
>
|
>
|
||||||
<label class="btn-group" title="Click to change">
|
<label class="btn-group" title="Click to change">
|
||||||
<span id="js-css-mode-label" class="code-wrap__header-label">
|
<span id="js-css-mode-label" class="code-wrap__header-label">
|
||||||
@@ -646,6 +727,7 @@ export default class ContentWrap extends Component {
|
|||||||
<div
|
<div
|
||||||
class="js-code-wrap__header code-wrap__header"
|
class="js-code-wrap__header code-wrap__header"
|
||||||
title="Double click to toggle code pane"
|
title="Double click to toggle code pane"
|
||||||
|
onDblClick={this.codeWrapHeaderDblClickHandler.bind(this)}
|
||||||
>
|
>
|
||||||
<label class="btn-group" title="Click to change">
|
<label class="btn-group" title="Click to change">
|
||||||
<span id="js-js-mode-label" class="code-wrap__header-label">
|
<span id="js-js-mode-label" class="code-wrap__header-label">
|
||||||
@@ -680,6 +762,7 @@ export default class ContentWrap extends Component {
|
|||||||
'CodeMirror-foldgutter'
|
'CodeMirror-foldgutter'
|
||||||
]
|
]
|
||||||
}}
|
}}
|
||||||
|
autoComplete={this.props.prefs.autoComplete}
|
||||||
onChange={this.onJsCodeChange.bind(this)}
|
onChange={this.onJsCodeChange.bind(this)}
|
||||||
onCreation={el => (this.cm.js = el)}
|
onCreation={el => (this.cm.js = el)}
|
||||||
/>
|
/>
|
||||||
@@ -694,11 +777,15 @@ export default class ContentWrap extends Component {
|
|||||||
id="demo-frame"
|
id="demo-frame"
|
||||||
allowfullscreen
|
allowfullscreen
|
||||||
/>
|
/>
|
||||||
<div id="consoleEl" class="console is-minimized">
|
<div
|
||||||
<div id="consoleLogEl" class="console__log" class="code">
|
id="consoleEl"
|
||||||
|
class={`console ${this.state.isConsoleOpen ? '' : 'is-minimized'}`}
|
||||||
|
>
|
||||||
|
<div id="consoleLogEl" class="console__log">
|
||||||
<div
|
<div
|
||||||
class="js-console__header code-wrap__header"
|
class="js-console__header code-wrap__header"
|
||||||
title="Double click to toggle console"
|
title="Double click to toggle console"
|
||||||
|
onDblClick={this.toggleConsole.bind(this)}
|
||||||
>
|
>
|
||||||
<span class="code-wrap__header-label">
|
<span class="code-wrap__header-label">
|
||||||
Console (<span id="logCountEl">0</span>)
|
Console (<span id="logCountEl">0</span>)
|
||||||
@@ -707,7 +794,7 @@ export default class ContentWrap extends Component {
|
|||||||
<a
|
<a
|
||||||
class="code-wrap__header-btn"
|
class="code-wrap__header-btn"
|
||||||
title="Clear console (CTRL + L)"
|
title="Clear console (CTRL + L)"
|
||||||
d-click="onClearConsoleBtnClick"
|
onClick={this.clearConsoleBtnClickHandler.bind(this)}
|
||||||
>
|
>
|
||||||
<svg>
|
<svg>
|
||||||
<use xlinkHref="#cancel-icon" />
|
<use xlinkHref="#cancel-icon" />
|
||||||
@@ -716,10 +803,21 @@ export default class ContentWrap extends Component {
|
|||||||
<a
|
<a
|
||||||
class="code-wrap__header-btn code-wrap__collapse-btn"
|
class="code-wrap__header-btn code-wrap__collapse-btn"
|
||||||
title="Toggle console"
|
title="Toggle console"
|
||||||
d-click="toggleConsole"
|
onClick={this.toggleConsole.bind(this)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<CodeMirrorBox
|
||||||
|
options={{
|
||||||
|
mode: 'javascript',
|
||||||
|
lineWrapping: true,
|
||||||
|
theme: 'monokai',
|
||||||
|
foldGutter: true,
|
||||||
|
readOnly: true,
|
||||||
|
gutters: ['CodeMirror-foldgutter']
|
||||||
|
}}
|
||||||
|
onCreation={el => (this.consoleCm = el)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
id="consolePromptEl"
|
id="consolePromptEl"
|
||||||
|
@@ -3,17 +3,19 @@ import Split from 'split.js';
|
|||||||
import { log } from '../utils';
|
import { log } from '../utils';
|
||||||
|
|
||||||
export class SplitPane extends Component {
|
export class SplitPane extends Component {
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
// shouldComponentUpdate(nextProps, nextState) {
|
||||||
return (
|
// return (
|
||||||
nextProps.direction !== this.props.direction ||
|
// nextProps.direction !== this.props.direction ||
|
||||||
nextProps.sizes.join('') !== this.props.sizes.join('')
|
// nextProps.sizes.join('') !== this.props.sizes.join('')
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.updateSplit();
|
this.updateSplit();
|
||||||
}
|
}
|
||||||
componentWillUpdate() {
|
componentWillUpdate() {
|
||||||
this.splitInstance.destroy();
|
if (this.splitInstance) {
|
||||||
|
this.splitInstance.destroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
this.updateSplit();
|
this.updateSplit();
|
||||||
|
@@ -108,9 +108,9 @@ export default class UserCodeMirror extends Component {
|
|||||||
'Ctrl-Space': 'autocomplete'
|
'Ctrl-Space': 'autocomplete'
|
||||||
});
|
});
|
||||||
if (!options.noAutocomplete) {
|
if (!options.noAutocomplete) {
|
||||||
this.cm.on('inputRead', function onChange(editor, input) {
|
this.cm.on('inputRead', (editor, input) => {
|
||||||
if (
|
if (
|
||||||
!prefs.autoComplete ||
|
!this.props.autoComplete ||
|
||||||
input.origin !== '+input' ||
|
input.origin !== '+input' ||
|
||||||
input.text[0] === ';' ||
|
input.text[0] === ';' ||
|
||||||
input.text[0] === ',' ||
|
input.text[0] === ',' ||
|
||||||
|
@@ -1289,7 +1289,7 @@ body>#demo-frame {
|
|||||||
transform: translateY(calc(100% - 29px));
|
transform: translateY(calc(100% - 29px));
|
||||||
}
|
}
|
||||||
|
|
||||||
.console .Codemirror {
|
.console .CodeMirror {
|
||||||
height: calc(100% - 55px);
|
height: calc(100% - 55px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user