mirror of
https://github.com/chinchang/web-maker.git
synced 2025-05-06 02:25:19 +02:00
add monaco firt draft. fixes #275
This commit is contained in:
parent
d9d1643b22
commit
0d97564138
255
src/components/CodeEditor.jsx
Normal file
255
src/components/CodeEditor.jsx
Normal file
@ -0,0 +1,255 @@
|
||||
import { h, Component } from 'preact';
|
||||
import CodeMirror from '../CodeMirror';
|
||||
|
||||
import 'codemirror/addon/edit/matchbrackets.js';
|
||||
import 'codemirror/addon/edit/matchtags.js';
|
||||
import 'codemirror/addon/edit/closebrackets.js';
|
||||
import 'codemirror/addon/edit/closetag.js';
|
||||
import 'codemirror/addon/comment/comment.js';
|
||||
import 'codemirror/addon/fold/foldcode.js';
|
||||
import 'codemirror/addon/fold/foldgutter.js';
|
||||
import 'codemirror/addon/fold/xml-fold.js';
|
||||
import 'codemirror/addon/fold/indent-fold.js';
|
||||
import 'codemirror/addon/fold/comment-fold.js';
|
||||
import 'codemirror/addon/fold/brace-fold.js';
|
||||
import 'codemirror/addon/hint/show-hint.js';
|
||||
import 'codemirror/addon/hint/javascript-hint.js';
|
||||
import 'codemirror/addon/hint/xml-hint.js';
|
||||
import 'codemirror/addon/hint/html-hint.js';
|
||||
import 'codemirror/addon/hint/css-hint.js';
|
||||
import 'codemirror/addon/selection/active-line.js';
|
||||
import 'codemirror/addon/search/searchcursor.js';
|
||||
import 'codemirror/addon/search/search.js';
|
||||
import 'codemirror/addon/dialog/dialog.js';
|
||||
import 'codemirror/addon/search/jump-to-line.js';
|
||||
|
||||
import 'codemirror/mode/xml/xml.js';
|
||||
import 'codemirror/mode/css/css.js';
|
||||
import 'codemirror/mode/javascript/javascript.js';
|
||||
import 'codemirror/mode/htmlmixed/htmlmixed.js';
|
||||
import 'codemirror/keymap/sublime.js';
|
||||
import 'codemirror/keymap/vim.js';
|
||||
import 'code-blast-codemirror/code-blast.js';
|
||||
|
||||
import emmet from '@emmetio/codemirror-plugin';
|
||||
import { prettify } from '../utils';
|
||||
|
||||
import '../lib/monaco/monaco.bundle';
|
||||
import '../lib/monaco/monaco.css';
|
||||
|
||||
emmet(CodeMirror);
|
||||
window.MonacoEnvironment = {
|
||||
getWorkerUrl(moduleId, label) {
|
||||
let MonacoWorker;
|
||||
|
||||
switch (label) {
|
||||
case 'html':
|
||||
return 'lib/monaco/workers/html.worker.bundle.js';
|
||||
case 'json':
|
||||
return 'lib/monaco/workers/json.worker.bundle.js';
|
||||
case 'css':
|
||||
return 'lib/monaco/workers/css.worker.bundle.js';
|
||||
case 'typescript':
|
||||
case 'javascript':
|
||||
return 'lib/monaco/workers/ts.worker.bundle.js';
|
||||
default:
|
||||
return 'lib/monaco/workers/editor.worker.bundle.js';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default class CodeEditor extends Component {
|
||||
componentDidMount() {
|
||||
this.initEditor();
|
||||
}
|
||||
shouldComponentUpdate(nextProps) {
|
||||
if (nextProps.prefs !== this.props.prefs) {
|
||||
const { prefs } = nextProps;
|
||||
|
||||
this.instance.setOption('indentWithTabs', prefs.indentWith !== 'spaces');
|
||||
this.instance.setOption(
|
||||
'blastCode',
|
||||
prefs.isCodeBlastOn ? { effect: 2, shake: false } : false
|
||||
);
|
||||
this.instance.setOption('theme', prefs.editorTheme);
|
||||
|
||||
this.instance.setOption('indentUnit', +prefs.indentSize);
|
||||
this.instance.setOption('tabSize', +prefs.indentSize);
|
||||
|
||||
this.instance.setOption('keyMap', prefs.keymap);
|
||||
this.instance.setOption('lineWrapping', prefs.lineWrap);
|
||||
this.instance.setOption('lineWrapping', prefs.autoCloseTags);
|
||||
|
||||
this.instance.refresh();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
setModel(model) {
|
||||
this.instance.swapDoc
|
||||
? this.instance.swapDoc(model)
|
||||
: this.instance.setModel(model);
|
||||
}
|
||||
setValue(value) {
|
||||
this.instance.setValue
|
||||
? this.instance.setValue(value)
|
||||
: this.instance.setModel(model);
|
||||
}
|
||||
getValue() {
|
||||
return this.instance.getValue();
|
||||
}
|
||||
saveViewState() {
|
||||
if (this.props.mode === 'monaco') {
|
||||
return this.instance.saveViewState();
|
||||
}
|
||||
}
|
||||
restoreViewState(state) {
|
||||
if (this.props.mode === 'monaco') {
|
||||
this.instance.restoreViewState(state);
|
||||
}
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.instance.refresh ? this.instance.refresh() : this.instance.layout();
|
||||
}
|
||||
focus() {
|
||||
this.instance.focus();
|
||||
}
|
||||
|
||||
initEditor() {
|
||||
const { options, prefs } = this.props;
|
||||
if (this.props.mode === 'monaco') {
|
||||
this.instance = monaco.editor.create(this.textarea, {
|
||||
language: 'javascript',
|
||||
roundedSelection: false,
|
||||
scrollBeyondLastLine: false,
|
||||
theme: 'vs-dark',
|
||||
fontSize: prefs.fontSize,
|
||||
minimap: {
|
||||
enabled: false
|
||||
},
|
||||
wordWrap: 'on',
|
||||
fontLigatures: true,
|
||||
automaticLayout: true
|
||||
});
|
||||
window.monacoInstance = this.instance;
|
||||
this.instance.onDidChangeModelContent(this.props.onChange);
|
||||
setTimeout(() => {
|
||||
// this.instance.layout();
|
||||
}, 1000);
|
||||
} else {
|
||||
this.instance = CodeMirror.fromTextArea(
|
||||
this.textarea.querySelector('textarea'),
|
||||
{
|
||||
mode: options.mode,
|
||||
lineNumbers: true,
|
||||
lineWrapping: !!prefs.lineWrap,
|
||||
autofocus: options.autofocus || false,
|
||||
autoCloseBrackets: true,
|
||||
autoCloseTags: !!prefs.autoCloseTags,
|
||||
matchBrackets: true,
|
||||
matchTags: options.matchTags || false,
|
||||
tabMode: 'indent',
|
||||
keyMap: prefs.keyMap || 'sublime',
|
||||
theme: prefs.editorTheme || 'monokai',
|
||||
lint: !!options.lint,
|
||||
tabSize: +prefs.indentSize || 2,
|
||||
indentWithTabs: prefs.indentWith !== 'spaces',
|
||||
indentUnit: +prefs.indentSize,
|
||||
foldGutter: true,
|
||||
styleActiveLine: true,
|
||||
gutters: options.gutters || [],
|
||||
// cursorScrollMargin: '20', has issue with scrolling
|
||||
profile: options.profile || '',
|
||||
extraKeys: {
|
||||
Up: function(editor) {
|
||||
// Stop up/down keys default behavior when saveditempane is open
|
||||
// if (isSavedItemsPaneOpen) {
|
||||
// return;
|
||||
// }
|
||||
CodeMirror.commands.goLineUp(editor);
|
||||
},
|
||||
Down: function(editor) {
|
||||
// if (isSavedItemsPaneOpen) {
|
||||
// return;
|
||||
// }
|
||||
CodeMirror.commands.goLineDown(editor);
|
||||
},
|
||||
'Shift-Tab': function(editor) {
|
||||
CodeMirror.commands.indentAuto(editor);
|
||||
},
|
||||
'Shift-Ctrl-F': function(editor) {
|
||||
if (options.prettier) {
|
||||
prettify({
|
||||
content: editor.getValue(),
|
||||
type: options.prettierParser
|
||||
}).then(formattedCode => editor.setValue(formattedCode));
|
||||
}
|
||||
},
|
||||
Tab: function(editor) {
|
||||
if (options.emmet) {
|
||||
const didEmmetWork = editor.execCommand(
|
||||
'emmetExpandAbbreviation'
|
||||
);
|
||||
if (didEmmetWork === true) {
|
||||
return;
|
||||
}
|
||||
const input = $('[data-setting=indentWith]:checked');
|
||||
if (
|
||||
!editor.somethingSelected() &&
|
||||
(!prefs.indentWith || prefs.indentWith === 'spaces')
|
||||
) {
|
||||
// softtabs adds spaces. This is required because by default tab key will put tab, but we want
|
||||
// to indent with spaces if `spaces` is preferred mode of indentation.
|
||||
// `somethingSelected` needs to be checked otherwise, all selected code is replaced with softtab.
|
||||
CodeMirror.commands.insertSoftTab(editor);
|
||||
} else {
|
||||
CodeMirror.commands.defaultTab(editor);
|
||||
}
|
||||
}
|
||||
},
|
||||
Enter: 'emmetInsertLineBreak'
|
||||
}
|
||||
}
|
||||
);
|
||||
this.instance.on('focus', editor => {
|
||||
if (typeof this.props.onFocus === 'function')
|
||||
this.props.onFocus(editor);
|
||||
});
|
||||
this.instance.on('change', this.props.onChange);
|
||||
this.instance.addKeyMap({
|
||||
'Ctrl-Space': 'autocomplete'
|
||||
});
|
||||
this.instance.on('inputRead', (editor, input) => {
|
||||
// Process further If this has autocompletition on and also the global
|
||||
// autocomplete setting is on.
|
||||
if (
|
||||
!this.props.options.noAutocomplete &&
|
||||
this.props.prefs.autoComplete
|
||||
) {
|
||||
if (
|
||||
input.origin !== '+input' ||
|
||||
input.text[0] === ';' ||
|
||||
input.text[0] === ',' ||
|
||||
input.text[0] === ' '
|
||||
) {
|
||||
return;
|
||||
}
|
||||
CodeMirror.commands.autocomplete(editor, null, {
|
||||
completeSingle: false
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// this.props.onCreation(this.instance);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div ref={el => (this.textarea = el)} style="width:100%;height:100%;">
|
||||
{this.props.mode === 'monaco' ? null : <textarea />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { h, Component } from 'preact';
|
||||
import UserCodeMirror from './UserCodeMirror.jsx';
|
||||
import CodeEditor from './CodeEditor.jsx';
|
||||
import { computeHtml, computeCss, computeJs } from '../computes';
|
||||
import { modes, HtmlModes, CssModes, JsModes } from '../codeModes';
|
||||
import { log, writeFile, loadJS, getCompleteHtml } from '../utils';
|
||||
@ -13,7 +13,7 @@ import { PreviewDimension } from './PreviewDimension.jsx';
|
||||
const minCodeWrapSize = 33;
|
||||
|
||||
/* global htmlCodeEl
|
||||
*/
|
||||
*/
|
||||
|
||||
export default class ContentWrap extends Component {
|
||||
constructor(props) {
|
||||
@ -708,7 +708,7 @@ export default class ContentWrap extends Component {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<UserCodeMirror
|
||||
<CodeEditor
|
||||
options={{
|
||||
mode: 'htmlmixed',
|
||||
profile: 'xhtml',
|
||||
@ -775,7 +775,7 @@ export default class ContentWrap extends Component {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<UserCodeMirror
|
||||
<CodeEditor
|
||||
options={{
|
||||
mode: 'css',
|
||||
gutters: [
|
||||
@ -830,7 +830,7 @@ export default class ContentWrap extends Component {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<UserCodeMirror
|
||||
<CodeEditor
|
||||
options={{
|
||||
mode: 'javascript',
|
||||
gutters: [
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { h, Component } from 'preact';
|
||||
import UserCodeMirror from './UserCodeMirror';
|
||||
import CodeEditor from './CodeEditor';
|
||||
import { modes, HtmlModes, CssModes, JsModes } from '../codeModes';
|
||||
import { log, loadJS } from '../utils';
|
||||
|
||||
@ -24,7 +24,7 @@ import { PreviewDimension } from './PreviewDimension';
|
||||
const minCodeWrapSize = 33;
|
||||
|
||||
/* global htmlCodeEl
|
||||
*/
|
||||
*/
|
||||
export default class ContentWrapFiles extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@ -86,7 +86,7 @@ export default class ContentWrapFiles extends Component {
|
||||
this.state.selectedFile &&
|
||||
this.fileBuffers[this.state.selectedFile.path]
|
||||
) {
|
||||
this.fileBuffers[this.state.selectedFile.path].setValue(
|
||||
this.fileBuffers[this.state.selectedFile.path].model.setValue(
|
||||
getFileFromPath(
|
||||
nextProps.currentItem.files,
|
||||
this.state.selectedFile.path
|
||||
@ -168,32 +168,43 @@ export default class ContentWrapFiles extends Component {
|
||||
CodeMirror.autoLoadMode(this.cm, mode);
|
||||
}
|
||||
if (mime === 'application/json') {
|
||||
mime = 'application/ld+json';
|
||||
mime = this.props.prefs.isMonacoEditorOn ? 'json' : 'application/ld+json';
|
||||
}
|
||||
if (!this.props.prefs.isMonacoEditorOn) {
|
||||
this.fileBuffers[file.path] = {
|
||||
model: CodeMirror.Doc(
|
||||
file.content || '',
|
||||
detectedMode ? mime : 'text/plain'
|
||||
)
|
||||
};
|
||||
} else {
|
||||
this.fileBuffers[file.path] = {
|
||||
model: monaco.editor.createModel(
|
||||
file.content || '',
|
||||
mime || 'javascript'
|
||||
)
|
||||
};
|
||||
}
|
||||
this.fileBuffers[file.path] = CodeMirror.Doc(
|
||||
file.content || '',
|
||||
detectedMode ? mime : 'text/plain'
|
||||
);
|
||||
}
|
||||
|
||||
onHtmlCodeChange(editor, change) {
|
||||
this.cmCodes.html = editor.getValue();
|
||||
this.cmCodes.html = this.editor.getValue();
|
||||
|
||||
this.props.onCodeChange(
|
||||
this.state.selectedFile,
|
||||
this.cmCodes.html,
|
||||
change.origin !== 'setValue'
|
||||
change ? change.origin !== 'setValue' : true
|
||||
);
|
||||
this.onCodeChange(editor, change);
|
||||
this.onCodeChange(change);
|
||||
}
|
||||
|
||||
onCodeChange(editor, change) {
|
||||
onCodeChange(change) {
|
||||
clearTimeout(this.updateTimer);
|
||||
|
||||
this.updateTimer = setTimeout(() => {
|
||||
// This is done so that multiple simultaneous setValue don't trigger too many preview refreshes
|
||||
// and in turn too many file writes on a single file (eg. preview.html).
|
||||
if (change.origin !== 'setValue') {
|
||||
if (change ? change.origin !== 'setValue' : true) {
|
||||
// Specifically checking for false so that the condition doesn't get true even
|
||||
// on absent key - possible when the setting key hasn't been fetched yet.
|
||||
if (this.prefs.autoPreview !== false) {
|
||||
@ -249,7 +260,9 @@ export default class ContentWrapFiles extends Component {
|
||||
}
|
||||
}
|
||||
cleanupErrors() {
|
||||
this.cm.clearGutter('error-gutter');
|
||||
if (!this.props.prefs.isMonacoEditorOn) {
|
||||
// this.editor.clearGutter('error-gutter');
|
||||
}
|
||||
}
|
||||
|
||||
showErrors(lang, errors) {
|
||||
@ -305,9 +318,11 @@ export default class ContentWrapFiles extends Component {
|
||||
}
|
||||
refreshEditor() {
|
||||
if (this.state.selectedFile) {
|
||||
this.cm.setValue(this.state.selectedFile.content);
|
||||
this.editor.setValue(this.state.selectedFile.content);
|
||||
}
|
||||
if (this.editor) {
|
||||
this.editor.refresh();
|
||||
}
|
||||
this.cm.refresh();
|
||||
window.cm = this.cm;
|
||||
|
||||
this.clearConsole();
|
||||
@ -401,6 +416,7 @@ export default class ContentWrapFiles extends Component {
|
||||
}, 1);
|
||||
}
|
||||
this.updateSplits();
|
||||
// this.editor.refresh();
|
||||
}
|
||||
mainSplitDragHandler() {
|
||||
this.previewDimension.update({
|
||||
@ -498,15 +514,24 @@ export default class ContentWrapFiles extends Component {
|
||||
this.props.onFolderSelect(file);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.fileBuffers[file.path]) {
|
||||
this.createEditorDoc(file);
|
||||
}
|
||||
|
||||
const currentState = this.editor.saveViewState();
|
||||
if (currentState && this.state.selectedFile) {
|
||||
this.fileBuffers[this.state.selectedFile.path].state = currentState;
|
||||
}
|
||||
this.setState({
|
||||
editorOptions: this.getEditorOptions(file.name),
|
||||
selectedFile: file
|
||||
});
|
||||
if (!this.fileBuffers[file.path]) {
|
||||
this.createEditorDoc(file);
|
||||
}
|
||||
this.cm.swapDoc(this.fileBuffers[file.path]);
|
||||
|
||||
this.editor.setModel(this.fileBuffers[file.path].model);
|
||||
if (this.fileBuffers[file.path].state) {
|
||||
this.editor.restoreViewState(this.fileBuffers[file.path].state);
|
||||
}
|
||||
// var cmMode = 'html';
|
||||
// if (file.name.match(/\.css$/)) {
|
||||
// this.updateCssMode('css');
|
||||
@ -516,7 +541,7 @@ export default class ContentWrapFiles extends Component {
|
||||
// this.updateCssMode('html');
|
||||
// }
|
||||
// this.cm.setValue(file.content || '');
|
||||
this.cm.focus();
|
||||
this.editor.focus();
|
||||
}
|
||||
|
||||
onMessageFromConsole() {
|
||||
@ -637,15 +662,15 @@ export default class ContentWrapFiles extends Component {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<UserCodeMirror
|
||||
mode={'monaco'}
|
||||
<CodeEditor
|
||||
mode={this.props.prefs.isMonacoEditorOn ? 'monaco' : 'codemirror'}
|
||||
value={
|
||||
this.state.selectedFile ? this.state.selectedFile.content : ''
|
||||
}
|
||||
options={this.state.editorOptions}
|
||||
prefs={this.props.prefs}
|
||||
onChange={this.onHtmlCodeChange.bind(this)}
|
||||
onCreation={editor => (this.cm = editor)}
|
||||
ref={editor => (this.editor = editor)}
|
||||
onFocus={this.editorFocusHandler.bind(this)}
|
||||
/>
|
||||
</div>
|
||||
|
@ -151,6 +151,13 @@ export default class Settings extends Component {
|
||||
<TabPanel label="Editor">
|
||||
<div>
|
||||
<div>
|
||||
<CheckboxSetting
|
||||
title="Use experimental Monaco editor"
|
||||
label="Use Monaco Editor"
|
||||
pref={prefs.isMonacoEditorOn}
|
||||
onChange={e => this.updateSetting(e, 'isMonacoEditorOn')}
|
||||
/>
|
||||
<Divider />
|
||||
<div class="line">
|
||||
<span>Default Preprocessors</span>
|
||||
<div class="flex">
|
||||
@ -321,7 +328,8 @@ export default class Settings extends Component {
|
||||
Make the app ready to build some games for{' '}
|
||||
<a href="https://js13kgames.com/" target="_blank" rel="noopener">
|
||||
Js13kGames
|
||||
</a>.
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
</TabPanel>
|
||||
<TabPanel label="Advanced">
|
||||
|
@ -1,199 +0,0 @@
|
||||
import { h, Component } from 'preact';
|
||||
import CodeMirror from '../CodeMirror';
|
||||
|
||||
import 'codemirror/addon/edit/matchbrackets.js';
|
||||
import 'codemirror/addon/edit/matchtags.js';
|
||||
import 'codemirror/addon/edit/closebrackets.js';
|
||||
import 'codemirror/addon/edit/closetag.js';
|
||||
import 'codemirror/addon/comment/comment.js';
|
||||
import 'codemirror/addon/fold/foldcode.js';
|
||||
import 'codemirror/addon/fold/foldgutter.js';
|
||||
import 'codemirror/addon/fold/xml-fold.js';
|
||||
import 'codemirror/addon/fold/indent-fold.js';
|
||||
import 'codemirror/addon/fold/comment-fold.js';
|
||||
import 'codemirror/addon/fold/brace-fold.js';
|
||||
import 'codemirror/addon/hint/show-hint.js';
|
||||
import 'codemirror/addon/hint/javascript-hint.js';
|
||||
import 'codemirror/addon/hint/xml-hint.js';
|
||||
import 'codemirror/addon/hint/html-hint.js';
|
||||
import 'codemirror/addon/hint/css-hint.js';
|
||||
import 'codemirror/addon/selection/active-line.js';
|
||||
import 'codemirror/addon/search/searchcursor.js';
|
||||
import 'codemirror/addon/search/search.js';
|
||||
import 'codemirror/addon/dialog/dialog.js';
|
||||
import 'codemirror/addon/search/jump-to-line.js';
|
||||
|
||||
import 'codemirror/mode/xml/xml.js';
|
||||
import 'codemirror/mode/css/css.js';
|
||||
import 'codemirror/mode/javascript/javascript.js';
|
||||
import 'codemirror/mode/htmlmixed/htmlmixed.js';
|
||||
import 'codemirror/keymap/sublime.js';
|
||||
import 'codemirror/keymap/vim.js';
|
||||
import 'code-blast-codemirror/code-blast.js';
|
||||
|
||||
import emmet from '@emmetio/codemirror-plugin';
|
||||
import { prettify } from '../utils';
|
||||
|
||||
emmet(CodeMirror);
|
||||
|
||||
export default class UserCodeMirror extends Component {
|
||||
componentDidMount() {
|
||||
this.initEditor();
|
||||
}
|
||||
shouldComponentUpdate(nextProps) {
|
||||
if (nextProps.prefs !== this.props.prefs) {
|
||||
const { prefs } = nextProps;
|
||||
|
||||
this.cm.setOption('indentWithTabs', prefs.indentWith !== 'spaces');
|
||||
this.cm.setOption(
|
||||
'blastCode',
|
||||
prefs.isCodeBlastOn ? { effect: 2, shake: false } : false
|
||||
);
|
||||
this.cm.setOption('theme', prefs.editorTheme);
|
||||
|
||||
this.cm.setOption('indentUnit', +prefs.indentSize);
|
||||
this.cm.setOption('tabSize', +prefs.indentSize);
|
||||
|
||||
this.cm.setOption('keyMap', prefs.keymap);
|
||||
this.cm.setOption('lineWrapping', prefs.lineWrap);
|
||||
this.cm.setOption('lineWrapping', prefs.autoCloseTags);
|
||||
|
||||
this.cm.refresh();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
initEditor() {
|
||||
const { options, prefs } = this.props;
|
||||
if (this.props.mode === 'monaco') {
|
||||
this.instance = monaco.editor.create(el, {
|
||||
language: options.language,
|
||||
roundedSelection: false,
|
||||
scrollBeyondLastLine: false,
|
||||
theme: 'vs-dark',
|
||||
fontSize: 16,
|
||||
minimap: {
|
||||
enabled: false
|
||||
},
|
||||
wordWrap: 'on',
|
||||
fontLigatures: true
|
||||
});
|
||||
this.instance.onDidChangeModelContent(onChange);
|
||||
} else {
|
||||
this.instance = CodeMirror.fromTextArea(this.textarea, {
|
||||
mode: options.mode,
|
||||
lineNumbers: true,
|
||||
lineWrapping: !!prefs.lineWrap,
|
||||
autofocus: options.autofocus || false,
|
||||
autoCloseBrackets: true,
|
||||
autoCloseTags: !!prefs.autoCloseTags,
|
||||
matchBrackets: true,
|
||||
matchTags: options.matchTags || false,
|
||||
tabMode: 'indent',
|
||||
keyMap: prefs.keyMap || 'sublime',
|
||||
theme: prefs.editorTheme || 'monokai',
|
||||
lint: !!options.lint,
|
||||
tabSize: +prefs.indentSize || 2,
|
||||
indentWithTabs: prefs.indentWith !== 'spaces',
|
||||
indentUnit: +prefs.indentSize,
|
||||
foldGutter: true,
|
||||
styleActiveLine: true,
|
||||
gutters: options.gutters || [],
|
||||
// cursorScrollMargin: '20', has issue with scrolling
|
||||
profile: options.profile || '',
|
||||
extraKeys: {
|
||||
Up: function(editor) {
|
||||
// Stop up/down keys default behavior when saveditempane is open
|
||||
// if (isSavedItemsPaneOpen) {
|
||||
// return;
|
||||
// }
|
||||
CodeMirror.commands.goLineUp(editor);
|
||||
},
|
||||
Down: function(editor) {
|
||||
// if (isSavedItemsPaneOpen) {
|
||||
// return;
|
||||
// }
|
||||
CodeMirror.commands.goLineDown(editor);
|
||||
},
|
||||
'Shift-Tab': function(editor) {
|
||||
CodeMirror.commands.indentAuto(editor);
|
||||
},
|
||||
'Shift-Ctrl-F': function(editor) {
|
||||
if (options.prettier) {
|
||||
prettify({
|
||||
content: editor.getValue(),
|
||||
type: options.prettierParser
|
||||
}).then(formattedCode => editor.setValue(formattedCode));
|
||||
}
|
||||
},
|
||||
Tab: function(editor) {
|
||||
if (options.emmet) {
|
||||
const didEmmetWork = editor.execCommand(
|
||||
'emmetExpandAbbreviation'
|
||||
);
|
||||
if (didEmmetWork === true) {
|
||||
return;
|
||||
}
|
||||
const input = $('[data-setting=indentWith]:checked');
|
||||
if (
|
||||
!editor.somethingSelected() &&
|
||||
(!prefs.indentWith || prefs.indentWith === 'spaces')
|
||||
) {
|
||||
// softtabs adds spaces. This is required because by default tab key will put tab, but we want
|
||||
// to indent with spaces if `spaces` is preferred mode of indentation.
|
||||
// `somethingSelected` needs to be checked otherwise, all selected code is replaced with softtab.
|
||||
CodeMirror.commands.insertSoftTab(editor);
|
||||
} else {
|
||||
CodeMirror.commands.defaultTab(editor);
|
||||
}
|
||||
}
|
||||
},
|
||||
Enter: 'emmetInsertLineBreak'
|
||||
}
|
||||
});
|
||||
this.instance.on('focus', editor => {
|
||||
if (typeof this.props.onFocus === 'function')
|
||||
this.props.onFocus(editor);
|
||||
});
|
||||
this.instance.on('change', this.props.onChange);
|
||||
this.instance.addKeyMap({
|
||||
'Ctrl-Space': 'autocomplete'
|
||||
});
|
||||
this.instance.on('inputRead', (editor, input) => {
|
||||
// Process further If this has autocompletition on and also the global
|
||||
// autocomplete setting is on.
|
||||
if (
|
||||
!this.props.options.noAutocomplete &&
|
||||
this.props.prefs.autoComplete
|
||||
) {
|
||||
if (
|
||||
input.origin !== '+input' ||
|
||||
input.text[0] === ';' ||
|
||||
input.text[0] === ',' ||
|
||||
input.text[0] === ' '
|
||||
) {
|
||||
return;
|
||||
}
|
||||
CodeMirror.commands.autocomplete(editor, null, {
|
||||
completeSingle: false
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.props.onCreation(this.instance);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<textarea
|
||||
ref={el => (this.textarea = el)}
|
||||
name=""
|
||||
id=""
|
||||
cols="30"
|
||||
rows="10"
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
@ -133,7 +133,8 @@ export default class App extends Component {
|
||||
layoutMode: 2,
|
||||
isJs13kModeOn: false,
|
||||
autoCloseTags: true,
|
||||
lang: 'en'
|
||||
lang: 'en',
|
||||
isMonacoEditorOn: false
|
||||
};
|
||||
this.prefs = {};
|
||||
|
||||
@ -1537,7 +1538,7 @@ export default class App extends Component {
|
||||
<input
|
||||
type="hidden"
|
||||
name="data"
|
||||
value="{"title": "New Pen!", "html": "<div>Hello, World!</div>"}"
|
||||
value='{"title": "New Pen!", "html": "<div>Hello, World!</div>"}'
|
||||
/>
|
||||
</form>
|
||||
|
||||
@ -1674,7 +1675,7 @@ export default class App extends Component {
|
||||
<input
|
||||
type="hidden"
|
||||
name="data"
|
||||
value="{"title": "New Pen!", "html": "<div>Hello, World!</div>"}"
|
||||
value='{"title": "New Pen!", "html": "<div>Hello, World!</div>"}'
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
|
6
src/lib/monaco/monaco.bundle.js
Normal file
6
src/lib/monaco/monaco.bundle.js
Normal file
File diff suppressed because one or more lines are too long
3843
src/lib/monaco/monaco.css
Normal file
3843
src/lib/monaco/monaco.css
Normal file
File diff suppressed because one or more lines are too long
2
src/lib/monaco/workers/css.worker.bundle.js
Normal file
2
src/lib/monaco/workers/css.worker.bundle.js
Normal file
File diff suppressed because one or more lines are too long
2
src/lib/monaco/workers/editor.worker.bundle.js
Normal file
2
src/lib/monaco/workers/editor.worker.bundle.js
Normal file
File diff suppressed because one or more lines are too long
8
src/lib/monaco/workers/html.worker.bundle.js
Normal file
8
src/lib/monaco/workers/html.worker.bundle.js
Normal file
File diff suppressed because one or more lines are too long
2
src/lib/monaco/workers/json.worker.bundle.js
Normal file
2
src/lib/monaco/workers/json.worker.bundle.js
Normal file
File diff suppressed because one or more lines are too long
17
src/lib/monaco/workers/ts.worker.bundle.js
Normal file
17
src/lib/monaco/workers/ts.worker.bundle.js
Normal file
File diff suppressed because one or more lines are too long
@ -1931,10 +1931,6 @@ while the theme CSS file is loading */
|
||||
.tabs__tabpanel-wrap {
|
||||
flex: 1;
|
||||
}
|
||||
.monaco-editor {
|
||||
width: 100%;
|
||||
height: 300px !important; /* 25px for header */
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
body {
|
||||
|
Loading…
x
Reference in New Issue
Block a user