WIP: install page + editor
This commit is contained in:
parent
18fd15317e
commit
24cd85688f
|
@ -415,8 +415,13 @@
|
|||
}
|
||||
},
|
||||
"installUpdateFromLabel": {
|
||||
"message": "Install update from this URL",
|
||||
"description": "Label for the checkbox to save current URL for update check"
|
||||
"message": "Install update from $url$",
|
||||
"description": "Label for the checkbox to save current URL for update check",
|
||||
"placeholders": {
|
||||
"url": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"license": {
|
||||
"message": "License",
|
||||
|
|
|
@ -59,6 +59,9 @@
|
|||
<script src="vendor/codemirror/keymap/sublime.js"></script>
|
||||
<script src="vendor/codemirror/keymap/emacs.js"></script>
|
||||
<script src="vendor/codemirror/keymap/vim.js"></script>
|
||||
|
||||
<script src="/vendor-overwrites/codemirror/codemirror-default.js"></script>
|
||||
<link rel="stylesheet" href="/vendor-overwrites/codemirror/codemirror-default.css">
|
||||
<link id="cm-theme" rel="stylesheet">
|
||||
|
||||
<template data-id="appliesTo">
|
||||
|
|
|
@ -167,20 +167,10 @@ h2 .svg-icon, label .svg-icon {
|
|||
margin-left: 0.25rem;
|
||||
}
|
||||
/* code */
|
||||
.CodeMirror-hint:hover {
|
||||
color: white;
|
||||
background: #08f;
|
||||
}
|
||||
.code {
|
||||
height: 10rem;
|
||||
width: 40rem;
|
||||
}
|
||||
.CodeMirror {
|
||||
border: solid #CCC 1px;
|
||||
}
|
||||
.CodeMirror-lint-mark-warning {
|
||||
background: none;
|
||||
}
|
||||
.resize-grip-enabled .CodeMirror-scroll {
|
||||
height: auto !important;;
|
||||
position: absolute !important;
|
||||
|
@ -198,22 +188,6 @@ h2 .svg-icon, label .svg-icon {
|
|||
.resize-grip-enabled .CodeMirror-scrollbar-filler {
|
||||
bottom: 7px; /* make space for resize-grip */
|
||||
}
|
||||
.CodeMirror-dialog {
|
||||
-webkit-animation: highlight 3s ease-out;
|
||||
}
|
||||
.CodeMirror-focused {
|
||||
outline: -webkit-focus-ring-color auto 5px;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
.CodeMirror-search-field {
|
||||
width: 10em;
|
||||
}
|
||||
.CodeMirror-jump-field {
|
||||
width: 5em;
|
||||
}
|
||||
.CodeMirror-search-hint {
|
||||
color: #888;
|
||||
}
|
||||
body[data-match-highlight="token"] .cm-matchhighlight-approved .cm-matchhighlight,
|
||||
body[data-match-highlight="token"] .CodeMirror-selection-highlight-scrollbar {
|
||||
animation: fadein-match-highlighter 1s cubic-bezier(.97,.01,.42,.98);
|
||||
|
|
99
edit/edit.js
99
edit/edit.js
|
@ -164,111 +164,16 @@ function setCleanSection(section) {
|
|||
|
||||
function initCodeMirror() {
|
||||
const CM = CodeMirror;
|
||||
const isWindowsOS = navigator.appVersion.indexOf('Windows') > 0;
|
||||
// lint.js is not loaded initially
|
||||
// CodeMirror miserably fails on keyMap='' so let's ensure it's not
|
||||
if (!prefs.get('editor.keyMap')) {
|
||||
prefs.reset('editor.keyMap');
|
||||
}
|
||||
|
||||
// default option values
|
||||
Object.assign(CM.defaults, {
|
||||
mode: 'css',
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
foldGutter: true,
|
||||
gutters: [
|
||||
'CodeMirror-linenumbers',
|
||||
'CodeMirror-foldgutter',
|
||||
...(prefs.get('editor.linter') ? ['CodeMirror-lint-markers'] : []),
|
||||
],
|
||||
matchBrackets: true,
|
||||
highlightSelectionMatches: {showToken: /[#.\-\w]/, annotateScrollbar: true},
|
||||
hintOptions: {},
|
||||
lint: linterConfig.getForCodeMirror(),
|
||||
lintReportDelay: prefs.get('editor.lintReportDelay'),
|
||||
styleActiveLine: true,
|
||||
theme: 'default',
|
||||
keyMap: prefs.get('editor.keyMap'),
|
||||
extraKeys: {
|
||||
// independent of current keyMap
|
||||
'Alt-Enter': 'toggleStyle',
|
||||
'Alt-PageDown': 'nextEditor',
|
||||
'Alt-PageUp': 'prevEditor'
|
||||
}
|
||||
}, prefs.get('editor.options'));
|
||||
CM.defaults.lint = linterConfig.getForCodeMirror();
|
||||
|
||||
// additional commands
|
||||
CM.commands.jumpToLine = jumpToLine;
|
||||
CM.commands.nextEditor = cm => nextPrevEditor(cm, 1);
|
||||
CM.commands.prevEditor = cm => nextPrevEditor(cm, -1);
|
||||
CM.commands.save = save;
|
||||
CM.commands.blockComment = cm => {
|
||||
cm.blockComment(cm.getCursor('from'), cm.getCursor('to'), {fullLines: false});
|
||||
};
|
||||
CM.commands.toggleStyle = toggleStyle;
|
||||
|
||||
// 'basic' keymap only has basic keys by design, so we skip it
|
||||
|
||||
const extraKeysCommands = {};
|
||||
Object.keys(CM.defaults.extraKeys).forEach(key => {
|
||||
extraKeysCommands[CM.defaults.extraKeys[key]] = true;
|
||||
});
|
||||
if (!extraKeysCommands.jumpToLine) {
|
||||
CM.keyMap.sublime['Ctrl-G'] = 'jumpToLine';
|
||||
CM.keyMap.emacsy['Ctrl-G'] = 'jumpToLine';
|
||||
CM.keyMap.pcDefault['Ctrl-J'] = 'jumpToLine';
|
||||
CM.keyMap.macDefault['Cmd-J'] = 'jumpToLine';
|
||||
}
|
||||
if (!extraKeysCommands.autocomplete) {
|
||||
// will be used by 'sublime' on PC via fallthrough
|
||||
CM.keyMap.pcDefault['Ctrl-Space'] = 'autocomplete';
|
||||
// OSX uses Ctrl-Space and Cmd-Space for something else
|
||||
CM.keyMap.macDefault['Alt-Space'] = 'autocomplete';
|
||||
// copied from 'emacs' keymap
|
||||
CM.keyMap.emacsy['Alt-/'] = 'autocomplete';
|
||||
// 'vim' and 'emacs' define their own autocomplete hotkeys
|
||||
}
|
||||
if (!extraKeysCommands.blockComment) {
|
||||
CM.keyMap.sublime['Shift-Ctrl-/'] = 'blockComment';
|
||||
}
|
||||
|
||||
if (isWindowsOS) {
|
||||
// 'pcDefault' keymap on Windows should have F3/Shift-F3
|
||||
if (!extraKeysCommands.findNext) {
|
||||
CM.keyMap.pcDefault['F3'] = 'findNext';
|
||||
}
|
||||
if (!extraKeysCommands.findPrev) {
|
||||
CM.keyMap.pcDefault['Shift-F3'] = 'findPrev';
|
||||
}
|
||||
|
||||
// try to remap non-interceptable Ctrl-(Shift-)N/T/W hotkeys
|
||||
['N', 'T', 'W'].forEach(char => {
|
||||
[
|
||||
{from: 'Ctrl-', to: ['Alt-', 'Ctrl-Alt-']},
|
||||
// Note: modifier order in CM is S-C-A
|
||||
{from: 'Shift-Ctrl-', to: ['Ctrl-Alt-', 'Shift-Ctrl-Alt-']}
|
||||
].forEach(remap => {
|
||||
const oldKey = remap.from + char;
|
||||
Object.keys(CM.keyMap).forEach(keyMapName => {
|
||||
const keyMap = CM.keyMap[keyMapName];
|
||||
const command = keyMap[oldKey];
|
||||
if (!command) {
|
||||
return;
|
||||
}
|
||||
remap.to.some(newMod => {
|
||||
const newKey = newMod + char;
|
||||
if (!(newKey in keyMap)) {
|
||||
delete keyMap[oldKey];
|
||||
keyMap[newKey] = command;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// user option values
|
||||
CM.getOption = o => CodeMirror.defaults[o];
|
||||
CM.setOption = (o, v) => {
|
||||
|
@ -278,8 +183,6 @@ function initCodeMirror() {
|
|||
});
|
||||
};
|
||||
|
||||
CM.modeURL = '/vendor/codemirror/mode/%N/%N.js';
|
||||
|
||||
CM.prototype.getSection = function () {
|
||||
return this.display.wrapper.parentNode;
|
||||
};
|
||||
|
|
|
@ -6,11 +6,6 @@
|
|||
'use strict';
|
||||
|
||||
function createSourceEditor(style) {
|
||||
const MODE = {
|
||||
stylus: 'stylus',
|
||||
uso: 'css'
|
||||
};
|
||||
|
||||
// style might be an object reference to background page
|
||||
style = deepCopy(style);
|
||||
|
||||
|
@ -403,10 +398,9 @@ function createSourceEditor(style) {
|
|||
$('#enabled').checked = style.enabled;
|
||||
$('#url').href = style.url;
|
||||
const {usercssData: {preprocessor}} = style;
|
||||
cm.setOption('mode', MODE[preprocessor] || 'css');
|
||||
CodeMirror.autoLoadMode(cm, MODE[preprocessor] || 'css');
|
||||
cm.setPreprocessor(preprocessor);
|
||||
// beautify only works with regular CSS
|
||||
$('#beautify').disabled = MODE[preprocessor] && MODE[preprocessor] !== 'css';
|
||||
$('#beautify').disabled = cm.getOption('mode') !== 'css';
|
||||
updateTitle();
|
||||
}
|
||||
|
||||
|
|
|
@ -10,16 +10,17 @@ body {
|
|||
|
||||
.container {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
height: 100vh;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.header {
|
||||
width: 280px;
|
||||
flex: 0 0 280px;
|
||||
padding: 15px;
|
||||
border-right: 1px dashed #aaa;
|
||||
box-shadow: 0 0 50px -18px black;
|
||||
overflow-wrap: break-word;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.header > :first-child {
|
||||
|
@ -51,8 +52,8 @@ h1 small {
|
|||
}
|
||||
|
||||
.actions label {
|
||||
width: fit-content;
|
||||
width: -moz-fit-content;
|
||||
max-width: fit-content;
|
||||
max-width: -moz-fit-content;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0.5em 0;
|
||||
|
@ -60,6 +61,11 @@ h1 small {
|
|||
|
||||
.actions label input {
|
||||
margin: 0 0.5em 0 0;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.actions label span {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.external {
|
||||
|
@ -75,7 +81,13 @@ h1 small {
|
|||
}
|
||||
|
||||
.main {
|
||||
flex-grow: 1;
|
||||
flex: 1 1 auto;
|
||||
overflow: hidden;
|
||||
overflow-wrap: break-word;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.main .code,
|
||||
.main .CodeMirror {
|
||||
height: 100%;
|
||||
}
|
||||
|
|
|
@ -6,13 +6,44 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Loading...</title>
|
||||
<link rel="stylesheet" href="install-usercss.css">
|
||||
<script src="/js/messaging.js"></script>
|
||||
<script src="/js/prefs.js"></script>
|
||||
<script src="/js/dom.js"></script>
|
||||
<script src="/js/localization.js"></script>
|
||||
<script src="/vendor/node-semver/semver.js"></script>
|
||||
|
||||
<!-- FIXME: do we need all of these? -->
|
||||
<script src="/vendor/codemirror/lib/codemirror.js"></script>
|
||||
<script src="/vendor/codemirror/keymap/sublime.js"></script>
|
||||
<script src="/vendor/codemirror/keymap/emacs.js"></script>
|
||||
<script src="/vendor/codemirror/keymap/vim.js"></script>
|
||||
|
||||
<script src="/vendor-overwrites/codemirror/codemirror-default.js"></script>
|
||||
<link rel="stylesheet" href="/vendor-overwrites/codemirror/codemirror-default.css">
|
||||
|
||||
<link rel="stylesheet" href="/vendor/codemirror/lib/codemirror.css">
|
||||
<script src="/vendor/codemirror/mode/css/css.js"></script>
|
||||
<link rel="stylesheet" href="/vendor/codemirror/addon/dialog/dialog.css">
|
||||
<link rel="stylesheet" href="/vendor/codemirror/addon/search/matchesonscrollbar.css">
|
||||
<script src="/vendor/codemirror/addon/scroll/annotatescrollbar.js"></script>
|
||||
<script src="/vendor/codemirror/addon/search/matchesonscrollbar.js"></script>
|
||||
<script src="/vendor-overwrites/codemirror/addon/search/match-highlighter.js"></script>
|
||||
<script src="/vendor/codemirror/addon/dialog/dialog.js"></script>
|
||||
<script src="/vendor/codemirror/addon/search/searchcursor.js"></script>
|
||||
<script src="/vendor/codemirror/addon/search/search.js"></script>
|
||||
<script src="/vendor/codemirror/addon/comment/comment.js"></script>
|
||||
<script src="/vendor/codemirror/addon/selection/active-line.js"></script>
|
||||
<link rel="stylesheet" href="/vendor/codemirror/addon/fold/foldgutter.css" />
|
||||
<script src="/vendor/codemirror/addon/fold/foldcode.js"></script>
|
||||
<script src="/vendor/codemirror/addon/fold/foldgutter.js"></script>
|
||||
<script src="/vendor/codemirror/addon/fold/brace-fold.js"></script>
|
||||
<script src="/vendor/codemirror/addon/fold/comment-fold.js"></script>
|
||||
<script src="/vendor/codemirror/addon/edit/matchbrackets.js"></script>
|
||||
<link rel="stylesheet" href="/vendor/codemirror/addon/lint/lint.css" />
|
||||
<link rel="stylesheet" href="/vendor/codemirror/addon/hint/show-hint.css" />
|
||||
<script src="/vendor/codemirror/addon/hint/show-hint.js"></script>
|
||||
<script src="/vendor/codemirror/addon/hint/css-hint.js"></script>
|
||||
<script src="/vendor/codemirror/addon/mode/loadmode.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
@ -21,7 +52,7 @@
|
|||
<button class="install" i18n-text="installButton"></button>
|
||||
<label class="set-update-url">
|
||||
<input type="checkbox">
|
||||
<span i18n-text="installUpdateFromLabel"></span>
|
||||
<span></span>
|
||||
</label>
|
||||
</div>
|
||||
<h1>
|
||||
|
|
|
@ -13,10 +13,18 @@
|
|||
port.onMessage.addListener(msg => {
|
||||
switch (msg.method) {
|
||||
case 'getSourceCodeResponse':
|
||||
initSourceCode(msg.sourceCode);
|
||||
if (msg.error) {
|
||||
alert(msg.error);
|
||||
} else {
|
||||
initSourceCode(msg.sourceCode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
port.onDisconnect.addListener(() => {
|
||||
// FIXME: Firefox: 1) window.close doesn't work. 2) onDisconnect is fired only if the tab is closed.
|
||||
window.close();
|
||||
});
|
||||
|
||||
const cm = CodeMirror.fromTextArea($('.code textarea'), {readOnly: true});
|
||||
|
||||
|
@ -38,11 +46,11 @@
|
|||
.then(result => {
|
||||
$$('.warning')
|
||||
.forEach(el => el.remove());
|
||||
$('button.install').textContent = 'Installed';
|
||||
$('button.install').disabled = true;
|
||||
$('button.install').classList.add('installed');
|
||||
$('.set-update-url').disabled = true;
|
||||
$('.set-update-url-label').title = result.updateUrl ?
|
||||
$('.install').textContent = 'Installed';
|
||||
$('.install').disabled = true;
|
||||
$('.install').classList.add('installed');
|
||||
$('.set-update-url input[type=checkbox]').disabled = true;
|
||||
$('.set-update-url').title = result.updateUrl ?
|
||||
t('installUpdateFrom', result.updateUrl) : '';
|
||||
window.dispatchEvent(new CustomEvent('installed', {detail: result}));
|
||||
})
|
||||
|
@ -76,6 +84,7 @@
|
|||
const dupData = dup && dup.usercssData;
|
||||
const versionTest = dup && semverCompare(data.version, dupData.version);
|
||||
|
||||
// update UI
|
||||
if (versionTest < 0) {
|
||||
$('.actions').parentNode.insertBefore(
|
||||
$element({className: 'warning', textContent: t('versionInvalidOlder')}),
|
||||
|
@ -94,8 +103,10 @@
|
|||
}
|
||||
};
|
||||
|
||||
// set updateUrl
|
||||
const setUpdate = $('.set-update-url input[type=checkbox]');
|
||||
const updateUrl = new URL(params.updateUrl);
|
||||
$('.set-update-url > span').textContent = t('installUpdateFromLabel', updateUrl.href);
|
||||
if (dup && dup.updateUrl === updateUrl.href) {
|
||||
setUpdate.checked = true;
|
||||
// there is no way to "unset" updateUrl, you can only overwrite it.
|
||||
|
@ -112,6 +123,9 @@
|
|||
}
|
||||
};
|
||||
|
||||
// update editor
|
||||
cm.setPreprocessor(data.preprocessor);
|
||||
|
||||
// update metas
|
||||
document.title = data.name;
|
||||
|
||||
|
|
26
vendor-overwrites/codemirror/codemirror-default.css
Normal file
26
vendor-overwrites/codemirror/codemirror-default.css
Normal file
|
@ -0,0 +1,26 @@
|
|||
.CodeMirror-hint:hover {
|
||||
color: white;
|
||||
background: #08f;
|
||||
}
|
||||
.CodeMirror {
|
||||
border: solid #CCC 1px;
|
||||
}
|
||||
.CodeMirror-lint-mark-warning {
|
||||
background: none;
|
||||
}
|
||||
.CodeMirror-dialog {
|
||||
-webkit-animation: highlight 3s ease-out;
|
||||
}
|
||||
.CodeMirror-focused {
|
||||
outline: -webkit-focus-ring-color auto 5px;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
.CodeMirror-search-field {
|
||||
width: 10em;
|
||||
}
|
||||
.CodeMirror-jump-field {
|
||||
width: 5em;
|
||||
}
|
||||
.CodeMirror-search-hint {
|
||||
color: #888;
|
||||
}
|
114
vendor-overwrites/codemirror/codemirror-default.js
Normal file
114
vendor-overwrites/codemirror/codemirror-default.js
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* global CodeMirror prefs */
|
||||
|
||||
'use strict';
|
||||
|
||||
(function () {
|
||||
// CodeMirror miserably fails on keyMap='' so let's ensure it's not
|
||||
if (!prefs.get('editor.keyMap')) {
|
||||
prefs.reset('editor.keyMap');
|
||||
}
|
||||
|
||||
const defaults = {
|
||||
mode: 'css',
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
foldGutter: true,
|
||||
gutters: [
|
||||
'CodeMirror-linenumbers',
|
||||
'CodeMirror-foldgutter',
|
||||
...(prefs.get('editor.linter') ? ['CodeMirror-lint-markers'] : []),
|
||||
],
|
||||
matchBrackets: true,
|
||||
highlightSelectionMatches: {showToken: /[#.\-\w]/, annotateScrollbar: true},
|
||||
hintOptions: {},
|
||||
lintReportDelay: prefs.get('editor.lintReportDelay'),
|
||||
styleActiveLine: true,
|
||||
theme: 'default',
|
||||
keyMap: prefs.get('editor.keyMap'),
|
||||
extraKeys: {
|
||||
// independent of current keyMap
|
||||
'Alt-Enter': 'toggleStyle',
|
||||
'Alt-PageDown': 'nextEditor',
|
||||
'Alt-PageUp': 'prevEditor'
|
||||
}
|
||||
};
|
||||
|
||||
Object.assign(CodeMirror.defaults, defaults, prefs.get('editor.options'));
|
||||
|
||||
CodeMirror.commands.blockComment = cm => {
|
||||
cm.blockComment(cm.getCursor('from'), cm.getCursor('to'), {fullLines: false});
|
||||
};
|
||||
|
||||
// 'basic' keymap only has basic keys by design, so we skip it
|
||||
|
||||
const extraKeysCommands = {};
|
||||
Object.keys(CodeMirror.defaults.extraKeys).forEach(key => {
|
||||
extraKeysCommands[CodeMirror.defaults.extraKeys[key]] = true;
|
||||
});
|
||||
if (!extraKeysCommands.jumpToLine) {
|
||||
CodeMirror.keyMap.sublime['Ctrl-G'] = 'jumpToLine';
|
||||
CodeMirror.keyMap.emacsy['Ctrl-G'] = 'jumpToLine';
|
||||
CodeMirror.keyMap.pcDefault['Ctrl-J'] = 'jumpToLine';
|
||||
CodeMirror.keyMap.macDefault['Cmd-J'] = 'jumpToLine';
|
||||
}
|
||||
if (!extraKeysCommands.autocomplete) {
|
||||
// will be used by 'sublime' on PC via fallthrough
|
||||
CodeMirror.keyMap.pcDefault['Ctrl-Space'] = 'autocomplete';
|
||||
// OSX uses Ctrl-Space and Cmd-Space for something else
|
||||
CodeMirror.keyMap.macDefault['Alt-Space'] = 'autocomplete';
|
||||
// copied from 'emacs' keymap
|
||||
CodeMirror.keyMap.emacsy['Alt-/'] = 'autocomplete';
|
||||
// 'vim' and 'emacs' define their own autocomplete hotkeys
|
||||
}
|
||||
if (!extraKeysCommands.blockComment) {
|
||||
CodeMirror.keyMap.sublime['Shift-Ctrl-/'] = 'blockComment';
|
||||
}
|
||||
|
||||
if (navigator.appVersion.includes('Windows')) {
|
||||
// 'pcDefault' keymap on Windows should have F3/Shift-F3
|
||||
if (!extraKeysCommands.findNext) {
|
||||
CodeMirror.keyMap.pcDefault['F3'] = 'findNext';
|
||||
}
|
||||
if (!extraKeysCommands.findPrev) {
|
||||
CodeMirror.keyMap.pcDefault['Shift-F3'] = 'findPrev';
|
||||
}
|
||||
|
||||
// try to remap non-interceptable Ctrl-(Shift-)N/T/W hotkeys
|
||||
['N', 'T', 'W'].forEach(char => {
|
||||
[
|
||||
{from: 'Ctrl-', to: ['Alt-', 'Ctrl-Alt-']},
|
||||
// Note: modifier order in CodeMirror is S-C-A
|
||||
{from: 'Shift-Ctrl-', to: ['Ctrl-Alt-', 'Shift-Ctrl-Alt-']}
|
||||
].forEach(remap => {
|
||||
const oldKey = remap.from + char;
|
||||
Object.keys(CodeMirror.keyMap).forEach(keyMapName => {
|
||||
const keyMap = CodeMirror.keyMap[keyMapName];
|
||||
const command = keyMap[oldKey];
|
||||
if (!command) {
|
||||
return;
|
||||
}
|
||||
remap.to.some(newMod => {
|
||||
const newKey = newMod + char;
|
||||
if (!(newKey in keyMap)) {
|
||||
delete keyMap[oldKey];
|
||||
keyMap[newKey] = command;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
CodeMirror.modeURL = '/vendor/codemirror/mode/%N/%N.js';
|
||||
|
||||
const MODE = {
|
||||
stylus: 'stylus',
|
||||
uso: 'css'
|
||||
};
|
||||
|
||||
CodeMirror.prototype.setPreprocessor = function(preprocessor) {
|
||||
this.setOption('mode', MODE[preprocessor] || 'css');
|
||||
CodeMirror.autoLoadMode(this, MODE[preprocessor] || 'css');
|
||||
};
|
||||
})();
|
Loading…
Reference in New Issue
Block a user