mirror of
https://github.com/chinchang/web-maker.git
synced 2025-05-08 19:45:17 +02:00
get language in monaco and misc fixes
This commit is contained in:
parent
932bbe43dc
commit
afbcd0a559
@ -33,6 +33,7 @@ import 'code-blast-codemirror/code-blast.js';
|
|||||||
|
|
||||||
import emmet from '@emmetio/codemirror-plugin';
|
import emmet from '@emmetio/codemirror-plugin';
|
||||||
import { prettify } from '../utils';
|
import { prettify } from '../utils';
|
||||||
|
import { modes } from '../codeModes';
|
||||||
|
|
||||||
import '../lib/monaco/monaco.bundle';
|
import '../lib/monaco/monaco.bundle';
|
||||||
import '../lib/monaco/monaco.css';
|
import '../lib/monaco/monaco.css';
|
||||||
@ -40,14 +41,14 @@ import '../lib/monaco/monaco.css';
|
|||||||
emmet(CodeMirror);
|
emmet(CodeMirror);
|
||||||
window.MonacoEnvironment = {
|
window.MonacoEnvironment = {
|
||||||
getWorkerUrl(moduleId, label) {
|
getWorkerUrl(moduleId, label) {
|
||||||
let MonacoWorker;
|
|
||||||
|
|
||||||
switch (label) {
|
switch (label) {
|
||||||
case 'html':
|
case 'html':
|
||||||
return 'lib/monaco/workers/html.worker.bundle.js';
|
return 'lib/monaco/workers/html.worker.bundle.js';
|
||||||
case 'json':
|
case 'json':
|
||||||
return 'lib/monaco/workers/json.worker.bundle.js';
|
return 'lib/monaco/workers/json.worker.bundle.js';
|
||||||
case 'css':
|
case 'css':
|
||||||
|
case 'scss':
|
||||||
|
case 'less':
|
||||||
return 'lib/monaco/workers/css.worker.bundle.js';
|
return 'lib/monaco/workers/css.worker.bundle.js';
|
||||||
case 'typescript':
|
case 'typescript':
|
||||||
case 'javascript':
|
case 'javascript':
|
||||||
@ -66,7 +67,7 @@ export default class CodeEditor extends Component {
|
|||||||
if (nextProps.prefs !== this.props.prefs) {
|
if (nextProps.prefs !== this.props.prefs) {
|
||||||
const { prefs } = nextProps;
|
const { prefs } = nextProps;
|
||||||
|
|
||||||
if (this.props.mode === 'monaco') {
|
if (this.props.type === 'monaco') {
|
||||||
this.instance.updateOptions({ fontSize: prefs.fontSize });
|
this.instance.updateOptions({ fontSize: prefs.fontSize });
|
||||||
} else {
|
} else {
|
||||||
this.instance.setOption(
|
this.instance.setOption(
|
||||||
@ -90,8 +91,26 @@ export default class CodeEditor extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nextProps.type !== this.props.type) {
|
||||||
|
// debugger;
|
||||||
|
if (
|
||||||
|
this.node.parentElement.querySelector('.monaco-editor, .CodeMirror')
|
||||||
|
) {
|
||||||
|
this.node.parentElement
|
||||||
|
.querySelector('.monaco-editor, .CodeMirror')
|
||||||
|
.remove();
|
||||||
|
}
|
||||||
|
console.log('CODEEDITOR SHOULD UPDATE');
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
componentDidUpdate(prevProps) {
|
||||||
|
console.log('CODEEDITOR UPDATED');
|
||||||
|
this.initEditor();
|
||||||
|
}
|
||||||
setModel(model) {
|
setModel(model) {
|
||||||
this.instance.swapDoc
|
this.instance.swapDoc
|
||||||
? this.instance.swapDoc(model)
|
? this.instance.swapDoc(model)
|
||||||
@ -106,15 +125,33 @@ export default class CodeEditor extends Component {
|
|||||||
return this.instance.getValue();
|
return this.instance.getValue();
|
||||||
}
|
}
|
||||||
saveViewState() {
|
saveViewState() {
|
||||||
if (this.props.mode === 'monaco') {
|
if (this.props.type === 'monaco') {
|
||||||
return this.instance.saveViewState();
|
return this.instance.saveViewState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
restoreViewState(state) {
|
restoreViewState(state) {
|
||||||
if (this.props.mode === 'monaco') {
|
if (this.props.type === 'monaco') {
|
||||||
this.instance.restoreViewState(state);
|
this.instance.restoreViewState(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setOption(option, value) {}
|
||||||
|
setLanguage(value) {
|
||||||
|
console.log('setting', this.props.type, modes[value].cmMode);
|
||||||
|
if (this.props.type === 'monaco') {
|
||||||
|
monaco.editor.setModelLanguage(
|
||||||
|
this.instance.getModel(),
|
||||||
|
this.getMonacoLanguageFromMode(modes[value].cmMode)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.instance.setOption('mode', modes[value].cmMode);
|
||||||
|
CodeMirror.autoLoadMode(
|
||||||
|
this.instance,
|
||||||
|
modes[value].cmPath || modes[value].cmMode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clearGutter(gutterName) {}
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
this.instance.refresh ? this.instance.refresh() : this.instance.layout();
|
this.instance.refresh ? this.instance.refresh() : this.instance.layout();
|
||||||
@ -123,11 +160,25 @@ export default class CodeEditor extends Component {
|
|||||||
this.instance.focus();
|
this.instance.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMonacoLanguageFromMode(mode) {
|
||||||
|
if (['htmlmixed'].includes(mode)) {
|
||||||
|
return 'html';
|
||||||
|
}
|
||||||
|
if (['css', 'sass', 'scss', 'less', 'stylus'].includes(mode)) {
|
||||||
|
return 'css';
|
||||||
|
}
|
||||||
|
if (['javascript', 'text/typescript-jsx', 'jsx'].includes(mode)) {
|
||||||
|
return 'javascript';
|
||||||
|
}
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
initEditor() {
|
initEditor() {
|
||||||
const { options, prefs } = this.props;
|
const { options, prefs } = this.props;
|
||||||
if (this.props.mode === 'monaco') {
|
console.log(this.props.type);
|
||||||
this.instance = monaco.editor.create(this.textarea, {
|
if (this.props.type === 'monaco') {
|
||||||
language: 'javascript',
|
this.instance = monaco.editor.create(this.node, {
|
||||||
|
language: this.getMonacoLanguageFromMode(options.mode),
|
||||||
roundedSelection: false,
|
roundedSelection: false,
|
||||||
scrollBeyondLastLine: false,
|
scrollBeyondLastLine: false,
|
||||||
theme: 'vs-dark',
|
theme: 'vs-dark',
|
||||||
@ -141,85 +192,92 @@ export default class CodeEditor extends Component {
|
|||||||
automaticLayout: true
|
automaticLayout: true
|
||||||
});
|
});
|
||||||
window.monacoInstance = this.instance;
|
window.monacoInstance = this.instance;
|
||||||
this.instance.onDidChangeModelContent(this.props.onChange);
|
this.instance.onDidChangeModelContent(change => {
|
||||||
setTimeout(() => {
|
this.props.onChange(this.instance, { ...change, origin: '+input' });
|
||||||
// this.instance.layout();
|
});
|
||||||
}, 1000);
|
this.instance.addCommand(
|
||||||
} else {
|
monaco.KeyMod.WinCtrl | monaco.KeyMod.Shift | monaco.KeyCode.KEY_F,
|
||||||
this.instance = CodeMirror.fromTextArea(
|
() => {
|
||||||
this.textarea.querySelector('textarea'),
|
if (options.prettier) {
|
||||||
{
|
prettify({
|
||||||
mode: options.mode,
|
content: this.instance.getValue(),
|
||||||
lineNumbers: true,
|
type: options.prettierParser
|
||||||
lineWrapping: !!prefs.lineWrap,
|
}).then(formattedCode => this.instance.setValue(formattedCode));
|
||||||
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'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
this.instance = CodeMirror.fromTextArea(this.node, {
|
||||||
|
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 => {
|
this.instance.on('focus', editor => {
|
||||||
if (typeof this.props.onFocus === 'function')
|
if (typeof this.props.onFocus === 'function')
|
||||||
this.props.onFocus(editor);
|
this.props.onFocus(editor);
|
||||||
@ -254,10 +312,12 @@ export default class CodeEditor extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
const node =
|
||||||
<div ref={el => (this.textarea = el)} style="width:100%;height:100%;">
|
this.props.type === 'monaco' ? (
|
||||||
{this.props.mode === 'monaco' ? null : <textarea />}
|
<div ref={el => (this.node = el)} style="width:100%;height:100%;" />
|
||||||
</div>
|
) : (
|
||||||
);
|
<textarea ref={el => (this.node = el)} />
|
||||||
|
);
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -488,35 +488,23 @@ export default class ContentWrap extends Component {
|
|||||||
updateHtmlMode(value) {
|
updateHtmlMode(value) {
|
||||||
this.props.onCodeModeChange('html', value);
|
this.props.onCodeModeChange('html', value);
|
||||||
this.props.currentItem.htmlMode = value;
|
this.props.currentItem.htmlMode = value;
|
||||||
this.cm.html.setOption('mode', modes[value].cmMode);
|
this.cm.html.setLanguage(value);
|
||||||
CodeMirror.autoLoadMode(
|
|
||||||
this.cm.html,
|
|
||||||
modes[value].cmPath || modes[value].cmMode
|
|
||||||
);
|
|
||||||
return this.handleModeRequirements(value);
|
return this.handleModeRequirements(value);
|
||||||
}
|
}
|
||||||
updateCssMode(value) {
|
updateCssMode(value) {
|
||||||
this.props.onCodeModeChange('css', value);
|
this.props.onCodeModeChange('css', value);
|
||||||
this.props.currentItem.cssMode = value;
|
this.props.currentItem.cssMode = value;
|
||||||
this.cm.css.setOption('mode', modes[value].cmMode);
|
|
||||||
this.cm.css.setOption('readOnly', modes[value].cmDisable);
|
this.cm.css.setOption('readOnly', modes[value].cmDisable);
|
||||||
window.cssSettingsBtn.classList[
|
window.cssSettingsBtn.classList[
|
||||||
modes[value].hasSettings ? 'remove' : 'add'
|
modes[value].hasSettings ? 'remove' : 'add'
|
||||||
]('hide');
|
]('hide');
|
||||||
CodeMirror.autoLoadMode(
|
this.cm.css.setLanguage(value);
|
||||||
this.cm.css,
|
|
||||||
modes[value].cmPath || modes[value].cmMode
|
|
||||||
);
|
|
||||||
return this.handleModeRequirements(value);
|
return this.handleModeRequirements(value);
|
||||||
}
|
}
|
||||||
updateJsMode(value) {
|
updateJsMode(value) {
|
||||||
this.props.onCodeModeChange('js', value);
|
this.props.onCodeModeChange('js', value);
|
||||||
this.props.currentItem.jsMode = value;
|
this.props.currentItem.jsMode = value;
|
||||||
this.cm.js.setOption('mode', modes[value].cmMode);
|
this.cm.js.setLanguage(value);
|
||||||
CodeMirror.autoLoadMode(
|
|
||||||
this.cm.js,
|
|
||||||
modes[value].cmPath || modes[value].cmMode
|
|
||||||
);
|
|
||||||
return this.handleModeRequirements(value);
|
return this.handleModeRequirements(value);
|
||||||
}
|
}
|
||||||
codeModeChangeHandler(e) {
|
codeModeChangeHandler(e) {
|
||||||
@ -709,6 +697,7 @@ export default class ContentWrap extends Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<CodeEditor
|
<CodeEditor
|
||||||
|
type={this.props.prefs.isMonacoEditorOn ? 'monaco' : 'codemirror'}
|
||||||
options={{
|
options={{
|
||||||
mode: 'htmlmixed',
|
mode: 'htmlmixed',
|
||||||
profile: 'xhtml',
|
profile: 'xhtml',
|
||||||
@ -721,7 +710,7 @@ export default class ContentWrap extends Component {
|
|||||||
}}
|
}}
|
||||||
prefs={this.props.prefs}
|
prefs={this.props.prefs}
|
||||||
onChange={this.onHtmlCodeChange.bind(this)}
|
onChange={this.onHtmlCodeChange.bind(this)}
|
||||||
onCreation={el => (this.cm.html = el)}
|
ref={editor => (this.cm.html = editor)}
|
||||||
onFocus={this.editorFocusHandler.bind(this)}
|
onFocus={this.editorFocusHandler.bind(this)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -776,6 +765,7 @@ export default class ContentWrap extends Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<CodeEditor
|
<CodeEditor
|
||||||
|
type={this.props.prefs.isMonacoEditorOn ? 'monaco' : 'codemirror'}
|
||||||
options={{
|
options={{
|
||||||
mode: 'css',
|
mode: 'css',
|
||||||
gutters: [
|
gutters: [
|
||||||
@ -789,7 +779,7 @@ export default class ContentWrap extends Component {
|
|||||||
}}
|
}}
|
||||||
prefs={this.props.prefs}
|
prefs={this.props.prefs}
|
||||||
onChange={this.onCssCodeChange.bind(this)}
|
onChange={this.onCssCodeChange.bind(this)}
|
||||||
onCreation={el => (this.cm.css = el)}
|
ref={editor => (this.cm.css = editor)}
|
||||||
onFocus={this.editorFocusHandler.bind(this)}
|
onFocus={this.editorFocusHandler.bind(this)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -831,6 +821,7 @@ export default class ContentWrap extends Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<CodeEditor
|
<CodeEditor
|
||||||
|
type={this.props.prefs.isMonacoEditorOn ? 'monaco' : 'codemirror'}
|
||||||
options={{
|
options={{
|
||||||
mode: 'javascript',
|
mode: 'javascript',
|
||||||
gutters: [
|
gutters: [
|
||||||
@ -844,7 +835,7 @@ export default class ContentWrap extends Component {
|
|||||||
prefs={this.props.prefs}
|
prefs={this.props.prefs}
|
||||||
autoComplete={this.props.prefs.autoComplete}
|
autoComplete={this.props.prefs.autoComplete}
|
||||||
onChange={this.onJsCodeChange.bind(this)}
|
onChange={this.onJsCodeChange.bind(this)}
|
||||||
onCreation={el => (this.cm.js = el)}
|
ref={editor => (this.cm.js = editor)}
|
||||||
onFocus={this.editorFocusHandler.bind(this)}
|
onFocus={this.editorFocusHandler.bind(this)}
|
||||||
/>
|
/>
|
||||||
{/* Inlet(scope.cm.js); */}
|
{/* Inlet(scope.cm.js); */}
|
||||||
|
@ -188,7 +188,7 @@ export default class ContentWrapFiles extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onHtmlCodeChange(editor, change) {
|
onHtmlCodeChange(editor, change) {
|
||||||
this.cmCodes.html = this.editor.getValue();
|
this.cmCodes.html = editor.getValue();
|
||||||
|
|
||||||
this.props.onCodeChange(
|
this.props.onCodeChange(
|
||||||
this.state.selectedFile,
|
this.state.selectedFile,
|
||||||
@ -663,7 +663,7 @@ export default class ContentWrapFiles extends Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<CodeEditor
|
<CodeEditor
|
||||||
mode={this.props.prefs.isMonacoEditorOn ? 'monaco' : 'codemirror'}
|
type={this.props.prefs.isMonacoEditorOn ? 'monaco' : 'codemirror'}
|
||||||
value={
|
value={
|
||||||
this.state.selectedFile ? this.state.selectedFile.content : ''
|
this.state.selectedFile ? this.state.selectedFile.content : ''
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user