Dynamically load linter when selected
This commit is contained in:
parent
b1a7f8d4a2
commit
29851a8de9
15
edit.html
15
edit.html
|
@ -34,16 +34,6 @@
|
||||||
|
|
||||||
<script src="vendor/codemirror/addon/edit/matchbrackets.js"></script>
|
<script src="vendor/codemirror/addon/edit/matchbrackets.js"></script>
|
||||||
|
|
||||||
<!-- CSSLint -->
|
|
||||||
<script src="vendor/csslint/csslint-worker.js"></script>
|
|
||||||
<!-- stylelint -->
|
|
||||||
<script src="vendor-overwrites/stylelint/stylelint-bundle.min.js"></script>
|
|
||||||
<script src="vendor-overwrites/codemirror/addon/lint/stylelint-config.js"></script>
|
|
||||||
<!-- linter -->
|
|
||||||
<link rel="stylesheet" href="vendor/codemirror/addon/lint/lint.css" />
|
|
||||||
<script src="vendor/codemirror/addon/lint/lint.js"></script>
|
|
||||||
<script src="vendor-overwrites/codemirror/addon/lint/css-lint.js"></script>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="vendor/codemirror/addon/hint/show-hint.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/show-hint.js"></script>
|
||||||
<script src="vendor/codemirror/addon/hint/css-hint.js"></script>
|
<script src="vendor/codemirror/addon/hint/css-hint.js"></script>
|
||||||
|
@ -196,12 +186,13 @@
|
||||||
<label id="linter-label" for="editor.linter" i18n-text="cm_linter"></label>
|
<label id="linter-label" for="editor.linter" i18n-text="cm_linter"></label>
|
||||||
<select id="editor.linter">
|
<select id="editor.linter">
|
||||||
<option value="csslint" selected>CSSLint</option>
|
<option value="csslint" selected>CSSLint</option>
|
||||||
<option value="stylelint">stylelint</option>
|
<option value="stylelint">Stylelint</option>
|
||||||
|
<option value="null" i18n-text="genericDisabledLabel"></option>
|
||||||
</select>
|
</select>
|
||||||
<span class="linter-settings" i18n-title="stylelintConfig">
|
<span class="linter-settings" i18n-title="stylelintConfig">
|
||||||
<svg id="stylelint-settings" class="svg-icon settings">
|
<svg id="stylelint-settings" class="svg-icon settings">
|
||||||
<use xlink:href="#svg-icon-settings"/>
|
<use xlink:href="#svg-icon-settings"/>
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
</section>
|
</section>
|
||||||
<section id="lint"><h2 i18n-text="issues">: <span id="issue-count"></span><svg id="lint-help" class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg></h2><div></div></section>
|
<section id="lint"><h2 i18n-text="issues">: <span id="issue-count"></span><svg id="lint-help" class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg></h2><div></div></section>
|
||||||
|
|
21
edit/edit.js
21
edit/edit.js
|
@ -154,6 +154,9 @@ function setCleanSection(section) {
|
||||||
function initCodeMirror() {
|
function initCodeMirror() {
|
||||||
const CM = CodeMirror;
|
const CM = CodeMirror;
|
||||||
const isWindowsOS = navigator.appVersion.indexOf('Windows') > 0;
|
const isWindowsOS = navigator.appVersion.indexOf('Windows') > 0;
|
||||||
|
// lint.js is not loaded initially
|
||||||
|
const hasLinter = typeof getLinterConfigForCodeMirror !== 'undefined' ?
|
||||||
|
getLinterConfigForCodeMirror(prefs.get('editor.linter')) : false;
|
||||||
|
|
||||||
// CodeMirror miserably fails on keyMap='' so let's ensure it's not
|
// CodeMirror miserably fails on keyMap='' so let's ensure it's not
|
||||||
if (!prefs.get('editor.keyMap')) {
|
if (!prefs.get('editor.keyMap')) {
|
||||||
|
@ -170,7 +173,7 @@ function initCodeMirror() {
|
||||||
matchBrackets: true,
|
matchBrackets: true,
|
||||||
highlightSelectionMatches: {showToken: /[#.\-\w]/, annotateScrollbar: true},
|
highlightSelectionMatches: {showToken: /[#.\-\w]/, annotateScrollbar: true},
|
||||||
hintOptions: {},
|
hintOptions: {},
|
||||||
lint: getLinterConfigForCodeMirror(prefs.get('editor.linter')),
|
lint: hasLinter,
|
||||||
lintReportDelay: prefs.get('editor.lintReportDelay'),
|
lintReportDelay: prefs.get('editor.lintReportDelay'),
|
||||||
styleActiveLine: true,
|
styleActiveLine: true,
|
||||||
theme: 'default',
|
theme: 'default',
|
||||||
|
@ -352,9 +355,7 @@ function acmeEventListener(event) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'linter':
|
case 'linter':
|
||||||
if (value !== null && editors.length) {
|
|
||||||
updateLinter(value);
|
updateLinter(value);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CodeMirror.setOption(option, value);
|
CodeMirror.setOption(option, value);
|
||||||
|
@ -427,7 +428,7 @@ function indicateCodeChange(cm) {
|
||||||
const section = cm.getSection();
|
const section = cm.getSection();
|
||||||
setCleanItem(section, cm.isClean(section.savedValue));
|
setCleanItem(section, cm.isClean(section.savedValue));
|
||||||
updateTitle();
|
updateTitle();
|
||||||
updateLintReport(cm);
|
updateLintReportIfEnabled(cm);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSectionForChild(e) {
|
function getSectionForChild(e) {
|
||||||
|
@ -554,7 +555,7 @@ window.onbeforeunload = () => {
|
||||||
if (isCleanGlobal()) {
|
if (isCleanGlobal()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateLintReport(null, 0);
|
updateLintReportIfEnabled(null, 0);
|
||||||
return confirm(t('styleChangesNotSaved'));
|
return confirm(t('styleChangesNotSaved'));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1223,6 +1224,7 @@ function initWithStyle({style, codeIsUpdated}) {
|
||||||
const sectionDiv = addSection(null, queue.shift());
|
const sectionDiv = addSection(null, queue.shift());
|
||||||
maximizeCodeHeight(sectionDiv, !queue.length);
|
maximizeCodeHeight(sectionDiv, !queue.length);
|
||||||
const cm = sectionDiv.CodeMirror;
|
const cm = sectionDiv.CodeMirror;
|
||||||
|
if (CodeMirror.lint) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
cm.setOption('lint', CodeMirror.defaults.lint);
|
cm.setOption('lint', CodeMirror.defaults.lint);
|
||||||
// update lint issue table after a short delay
|
// update lint issue table after a short delay
|
||||||
|
@ -1230,6 +1232,7 @@ function initWithStyle({style, codeIsUpdated}) {
|
||||||
}, prefs.get('editor.lintDelay'));
|
}, prefs.get('editor.lintDelay'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function initHooks() {
|
function initHooks() {
|
||||||
document.querySelectorAll('#header .style-contributor').forEach(node => {
|
document.querySelectorAll('#header .style-contributor').forEach(node => {
|
||||||
|
@ -1365,8 +1368,14 @@ function validate() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateLintReportIfEnabled(cm, time) {
|
||||||
|
if (CodeMirror.lint) {
|
||||||
|
updateLintReport(cm, time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function save() {
|
function save() {
|
||||||
updateLintReport(null, 0);
|
updateLintReportIfEnabled(null, 0);
|
||||||
|
|
||||||
// save the contents of the CodeMirror editors back into the textareas
|
// save the contents of the CodeMirror editors back into the textareas
|
||||||
for (let i = 0; i < editors.length; i++) {
|
for (let i = 0; i < editors.length; i++) {
|
||||||
|
|
61
edit/lint.js
61
edit/lint.js
|
@ -1,5 +1,5 @@
|
||||||
/* global CodeMirror CSSLint editors makeSectionVisible showHelp showCodeMirrorPopup */
|
/* global CodeMirror CSSLint editors makeSectionVisible showHelp showCodeMirrorPopup */
|
||||||
/* global stylelintDefaultConfig onDOMscripted */
|
/* global stylelintDefaultConfig onDOMscripted injectCSS require */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function initLint() {
|
function initLint() {
|
||||||
|
@ -23,19 +23,29 @@ function setStylelintRules(rules = {}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLinterConfigForCodeMirror(name) {
|
function getLinterConfigForCodeMirror(name) {
|
||||||
return {
|
return CodeMirror.lint && CodeMirror.lint[name] ? {
|
||||||
getAnnotations: CodeMirror.lint[name],
|
getAnnotations: CodeMirror.lint[name],
|
||||||
delay: prefs.get('editor.lintDelay')
|
delay: prefs.get('editor.lintDelay')
|
||||||
};
|
} : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateLinter(name = 'csslint') {
|
function updateLinter(name) {
|
||||||
|
function updateEditors() {
|
||||||
|
const options = getLinterConfigForCodeMirror(name);
|
||||||
|
CodeMirror.defaults.lint = options === 'null' ? false : options;
|
||||||
|
editors.forEach(cm => {
|
||||||
|
// set lint to "null" to disable
|
||||||
|
cm.setOption('lint', options);
|
||||||
|
cm.refresh(); // enabling/disabling linting changes the gutter width
|
||||||
|
updateLintReport(cm, 200);
|
||||||
|
});
|
||||||
|
}
|
||||||
if (prefs.get('editor.linter') !== name) {
|
if (prefs.get('editor.linter') !== name) {
|
||||||
prefs.set('editor.linter', name);
|
prefs.set('editor.linter', name);
|
||||||
}
|
}
|
||||||
editors.forEach(cm => {
|
// load scripts
|
||||||
cm.setOption('lint', getLinterConfigForCodeMirror(name));
|
loadSelectedLinter(name).then(() => {
|
||||||
updateLintReport(cm, 200);
|
updateEditors();
|
||||||
});
|
});
|
||||||
$('#stylelint-settings').style.display = name === 'stylelint' ?
|
$('#stylelint-settings').style.display = name === 'stylelint' ?
|
||||||
'inline-block' : 'none';
|
'inline-block' : 'none';
|
||||||
|
@ -228,7 +238,7 @@ function setupStylelintSettingsEvents(popup) {
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
popup.querySelector('reset').addEventListener('click', event => {
|
popup.querySelector('.reset').addEventListener('click', event => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
setStylelintRules();
|
setStylelintRules();
|
||||||
popup.codebox.setValue(JSON.stringify({rules: stylelintDefaultConfig.rules}, null, 2));
|
popup.codebox.setValue(JSON.stringify({rules: stylelintDefaultConfig.rules}, null, 2));
|
||||||
|
@ -254,6 +264,7 @@ function setupStylelintPopup(rules) {
|
||||||
}
|
}
|
||||||
function setJSONMode(cm) {
|
function setJSONMode(cm) {
|
||||||
cm.setOption('mode', 'application/json');
|
cm.setOption('mode', 'application/json');
|
||||||
|
cm.setOption('lint', 'json');
|
||||||
}
|
}
|
||||||
const popup = showCodeMirrorPopup(t('setStylelintRules'), $element({
|
const popup = showCodeMirrorPopup(t('setStylelintRules'), $element({
|
||||||
className: 'contents',
|
className: 'contents',
|
||||||
|
@ -278,18 +289,32 @@ function setupStylelintPopup(rules) {
|
||||||
]
|
]
|
||||||
}));
|
}));
|
||||||
const contents = popup.querySelector('.contents');
|
const contents = popup.querySelector('.contents');
|
||||||
|
const loadJSON = window.jsonlint ? [] : ['vendor/codemirror/addon/lint/json-lint.js'];
|
||||||
contents.insertBefore(popup.codebox.display.wrapper, contents.firstElementChild);
|
contents.insertBefore(popup.codebox.display.wrapper, contents.firstElementChild);
|
||||||
popup.codebox.focus();
|
popup.codebox.focus();
|
||||||
popup.codebox.setValue(rules);
|
popup.codebox.setValue(rules);
|
||||||
if (!$('script[src*="json-lint.js"]')) {
|
onDOMscripted(loadJSON, () => { setJSONMode(popup.codebox); });
|
||||||
onDOMscripted(
|
|
||||||
['vendor/codemirror/addon/lint/json-lint.js'],
|
|
||||||
() => {
|
|
||||||
setJSONMode(popup.codebox);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
setJSONMode(popup.codebox);
|
|
||||||
}
|
|
||||||
setupStylelintSettingsEvents(popup);
|
setupStylelintSettingsEvents(popup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadSelectedLinter(name) {
|
||||||
|
let scripts = [];
|
||||||
|
if (name !== 'null' && !$('script[src*="css-lint.js"]')) {
|
||||||
|
// inject css
|
||||||
|
injectCSS('vendor/codemirror/addon/lint/lint.css');
|
||||||
|
// load CodeMirror lint code
|
||||||
|
scripts = scripts.concat([
|
||||||
|
'vendor/codemirror/addon/lint/lint.js',
|
||||||
|
'vendor-overwrites/codemirror/addon/lint/css-lint.js'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (name === 'csslint' && !window.CSSLint) {
|
||||||
|
scripts.push('vendor/csslint/csslint-worker.js');
|
||||||
|
} else if (name === 'stylelint' && !window.stylelint) {
|
||||||
|
scripts = scripts.concat([
|
||||||
|
'vendor-overwrites/stylelint/stylelint-bundle.min.js',
|
||||||
|
'vendor-overwrites/codemirror/addon/lint/stylelint-config.js'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
return onDOMscripted(scripts);
|
||||||
|
}
|
||||||
|
|
|
@ -64,8 +64,8 @@ CodeMirror.registerHelper("lint", "csslint", function(text) {
|
||||||
|
|
||||||
CodeMirror.registerHelper("lint", "stylelint", function(text) {
|
CodeMirror.registerHelper("lint", "stylelint", function(text) {
|
||||||
let found = [];
|
let found = [];
|
||||||
const stylelint = require('stylelint').lint;
|
window.stylelint = require('stylelint').lint;
|
||||||
if (stylelint) {
|
if (window.stylelint) {
|
||||||
return BG.chromeLocal.getValue('editorStylelintRules').then((rules = stylelintDefaultConfig.rules) => {
|
return BG.chromeLocal.getValue('editorStylelintRules').then((rules = stylelintDefaultConfig.rules) => {
|
||||||
// stylelintDefaultConfig stored in stylelint-config.js & loaded by edit.html
|
// stylelintDefaultConfig stored in stylelint-config.js & loaded by edit.html
|
||||||
if (Object.keys(rules).length === 0) {
|
if (Object.keys(rules).length === 0) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const stylelintDefaultConfig = (defaultSeverity => ({
|
window.stylelintDefaultConfig = (defaultSeverity => ({
|
||||||
// 'sugarss' is a indent-based syntax like Sass or Stylus
|
// 'sugarss' is a indent-based syntax like Sass or Stylus
|
||||||
// ref: https://github.com/postcss/postcss#syntaxes
|
// ref: https://github.com/postcss/postcss#syntaxes
|
||||||
syntax: 'sugarss',
|
syntax: 'sugarss',
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -21,3 +21,4 @@ Stylelint bundle file created by:
|
||||||
This prevents a js error when stylelint attempts to access a local file. The
|
This prevents a js error when stylelint attempts to access a local file. The
|
||||||
other `fs.readFile` entries are not accessed because we're using stylelint's
|
other `fs.readFile` entries are not accessed because we're using stylelint's
|
||||||
standalone method.
|
standalone method.
|
||||||
|
5. The script was then "minified" by manually running it through Google's [Closure Compiler](http://closure-compiler.appspot.com/home) set to "Whitespace only".
|
||||||
|
|
Loading…
Reference in New Issue
Block a user