async function loadCodeMirror(options = {}) {
const {
version = 'latest',
themes = [],
modes = [],
minify = true,
view = false,
viewLabel = (version, modes, themes) => `CodeMirror ${version}${!modes.length ? '' : ` (${modes.join(', ')})`}`,
} = options;
const suffix = minify ? '.min' : '';
const PATH = (await require.resolve(`codemirror@${version}/.`)).slice(0, -2);
const cm = require(`${PATH}/lib/codemirror${suffix}.js`).then(cm => {
if(!modes.length) return cm;
return require.alias({'../../lib/codemirror': cm})(
...modes.map(mode => `${PATH}/mode/${mode}/${mode}${suffix}.js`)
)
.then(() => cm);
});
const isUrl = str => {
try { new URL(str); return true }
catch(e) { return false }
};
const fetchText = async url => {
const r = await fetch(url);
if(!r.ok) throw Error(`${r.status} (${url})`);
return r.text();
};
const css = Promise.all([
fetchText(`${PATH}/lib/codemirror${suffix}.css`),
...themes.map(name => fetchText(isUrl(name) ? name : `${PATH}/theme/${name}${suffix}.css`))
]);
return Promise.all([cm, css]).then(([cm, css]) => {
Object.assign(css, { toString() { return this.join('\n') } });
if(view) return Object.defineProperty(
html`<pre>${viewLabel(cm.version, modes, themes)}</pre><style>${css}`,
'value',
{ value: cm }
);
cm.CSS = css;
return cm;
});
}