1
0
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:
Kushagra Gour 2018-11-30 10:55:11 +05:30
parent 932bbe43dc
commit afbcd0a559
3 changed files with 160 additions and 109 deletions

View File

@ -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;
} }
} }

View File

@ -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); */}

View File

@ -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 : ''
} }