Open Source Web Application Framework for ASP.NET Core
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

146 lines
3.8 KiB

import { EditorState } from '@codemirror/state';
import { EditorView } from '@codemirror/view';
import { basicSetup, minimalSetup } from 'codemirror';
import { css } from '@codemirror/lang-css';
import { javascript } from '@codemirror/lang-javascript';
const modeFactories = {
css: css,
javascript: javascript,
js: javascript
};
function getModeExtension(mode) {
if (!mode) {
return null;
}
const modeName = typeof mode === 'string'
? mode
: (mode.name || mode.mode || mode.helperType || '');
const factory = modeFactories[modeName.toLowerCase()];
return factory ? factory() : null;
}
function normalizeWrapperClasses(textarea) {
return (textarea.className || '')
.split(/\s+/)
.filter(Boolean)
.filter(name => name !== 'form-control' && name !== 'valid' && name !== 'input-validation-error')
.join(' ');
}
function syncTextarea(textarea, view) {
textarea.value = view.state.doc.toString();
}
function createWrapper(textarea) {
const wrapper = document.createElement('div');
const extraClasses = normalizeWrapperClasses(textarea);
const style = window.getComputedStyle(textarea);
wrapper.className = extraClasses
? 'abp-codemirror ' + extraClasses
: 'abp-codemirror';
if (textarea.id) {
wrapper.id = textarea.id + '__codemirror';
}
wrapper.style.width = '100%';
if (style.height && style.height !== 'auto' && style.height !== '0px') {
wrapper.style.height = style.height;
} else {
wrapper.style.minHeight = '12rem';
}
return wrapper;
}
function getEditorSetup(options) {
// CodeMirror 5 default: line numbers off unless lineNumbers === true
return options.lineNumbers === true ? basicSetup : minimalSetup;
}
function createState(textarea, options) {
const extensions = [
getEditorSetup(options),
EditorView.updateListener.of(update => {
if (update.docChanged) {
syncTextarea(textarea, update.view);
}
})
];
const modeExtension = getModeExtension(options.mode);
if (modeExtension) {
extensions.push(modeExtension);
}
if (options.readOnly) {
extensions.push(EditorState.readOnly.of(true));
}
return EditorState.create({
doc: textarea.value || '',
extensions
});
}
function createCompatibilityEditor(textarea, options) {
const wrapper = createWrapper(textarea);
textarea.parentNode.insertBefore(wrapper, textarea.nextSibling);
textarea.style.display = 'none';
textarea.setAttribute('aria-hidden', 'true');
const view = new EditorView({
state: createState(textarea, options || {}),
parent: wrapper
});
const save = function () {
syncTextarea(textarea, view);
};
if (textarea.form) {
textarea.form.addEventListener('submit', save);
}
return {
getValue: function () {
return view.state.doc.toString();
},
setValue: function (value) {
view.dispatch({
changes: {
from: 0,
to: view.state.doc.length,
insert: value || ''
}
});
save();
},
refresh: function () {
if (typeof view.requestMeasure === 'function') {
view.requestMeasure();
}
},
focus: function () {
view.focus();
},
save: save,
getWrapperElement: function () {
return wrapper;
}
};
}
window.CodeMirror = window.CodeMirror || {};
window.CodeMirror.loadedModes = window.CodeMirror.loadedModes || {};
window.CodeMirror.fromTextArea = function (textarea, options) {
return createCompatibilityEditor(textarea, options || {});
};