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>
|
||||
|
||||
<!-- 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" />
|
||||
<script src="vendor/codemirror/addon/hint/show-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>
|
||||
<select id="editor.linter">
|
||||
<option value="csslint" selected>CSSLint</option>
|
||||
<option value="stylelint">stylelint</option>
|
||||
<option value="stylelint">Stylelint</option>
|
||||
<option value="null" i18n-text="genericDisabledLabel"></option>
|
||||
</select>
|
||||
<span class="linter-settings" i18n-title="stylelintConfig">
|
||||
<svg id="stylelint-settings" class="svg-icon settings">
|
||||
<use xlink:href="#svg-icon-settings"/>
|
||||
</svg>
|
||||
</svg>
|
||||
</span>
|
||||
</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() {
|
||||
const CM = CodeMirror;
|
||||
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
|
||||
if (!prefs.get('editor.keyMap')) {
|
||||
|
@ -170,7 +173,7 @@ function initCodeMirror() {
|
|||
matchBrackets: true,
|
||||
highlightSelectionMatches: {showToken: /[#.\-\w]/, annotateScrollbar: true},
|
||||
hintOptions: {},
|
||||
lint: getLinterConfigForCodeMirror(prefs.get('editor.linter')),
|
||||
lint: hasLinter,
|
||||
lintReportDelay: prefs.get('editor.lintReportDelay'),
|
||||
styleActiveLine: true,
|
||||
theme: 'default',
|
||||
|
@ -352,9 +355,7 @@ function acmeEventListener(event) {
|
|||
}
|
||||
break;
|
||||
case 'linter':
|
||||
if (value !== null && editors.length) {
|
||||
updateLinter(value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
CodeMirror.setOption(option, value);
|
||||
|
@ -427,7 +428,7 @@ function indicateCodeChange(cm) {
|
|||
const section = cm.getSection();
|
||||
setCleanItem(section, cm.isClean(section.savedValue));
|
||||
updateTitle();
|
||||
updateLintReport(cm);
|
||||
updateLintReportIfEnabled(cm);
|
||||
}
|
||||
|
||||
function getSectionForChild(e) {
|
||||
|
@ -554,7 +555,7 @@ window.onbeforeunload = () => {
|
|||
if (isCleanGlobal()) {
|
||||
return;
|
||||
}
|
||||
updateLintReport(null, 0);
|
||||
updateLintReportIfEnabled(null, 0);
|
||||
return confirm(t('styleChangesNotSaved'));
|
||||
};
|
||||
|
||||
|
@ -1223,12 +1224,14 @@ function initWithStyle({style, codeIsUpdated}) {
|
|||
const sectionDiv = addSection(null, queue.shift());
|
||||
maximizeCodeHeight(sectionDiv, !queue.length);
|
||||
const cm = sectionDiv.CodeMirror;
|
||||
if (CodeMirror.lint) {
|
||||
setTimeout(() => {
|
||||
cm.setOption('lint', CodeMirror.defaults.lint);
|
||||
// update lint issue table after a short delay
|
||||
updateLintReport(cm, 200);
|
||||
}, prefs.get('editor.lintDelay'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function initHooks() {
|
||||
|
@ -1365,8 +1368,14 @@ function validate() {
|
|||
return null;
|
||||
}
|
||||
|
||||
function updateLintReportIfEnabled(cm, time) {
|
||||
if (CodeMirror.lint) {
|
||||
updateLintReport(cm, time);
|
||||
}
|
||||
}
|
||||
|
||||
function save() {
|
||||
updateLintReport(null, 0);
|
||||
updateLintReportIfEnabled(null, 0);
|
||||
|
||||
// save the contents of the CodeMirror editors back into the textareas
|
||||
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 stylelintDefaultConfig onDOMscripted */
|
||||
/* global stylelintDefaultConfig onDOMscripted injectCSS require */
|
||||
'use strict';
|
||||
|
||||
function initLint() {
|
||||
|
@ -23,19 +23,29 @@ function setStylelintRules(rules = {}) {
|
|||
}
|
||||
|
||||
function getLinterConfigForCodeMirror(name) {
|
||||
return {
|
||||
return CodeMirror.lint && CodeMirror.lint[name] ? {
|
||||
getAnnotations: CodeMirror.lint[name],
|
||||
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) {
|
||||
prefs.set('editor.linter', name);
|
||||
}
|
||||
editors.forEach(cm => {
|
||||
cm.setOption('lint', getLinterConfigForCodeMirror(name));
|
||||
updateLintReport(cm, 200);
|
||||
// load scripts
|
||||
loadSelectedLinter(name).then(() => {
|
||||
updateEditors();
|
||||
});
|
||||
$('#stylelint-settings').style.display = name === 'stylelint' ?
|
||||
'inline-block' : 'none';
|
||||
|
@ -228,7 +238,7 @@ function setupStylelintSettingsEvents(popup) {
|
|||
}, 3000);
|
||||
}
|
||||
});
|
||||
popup.querySelector('reset').addEventListener('click', event => {
|
||||
popup.querySelector('.reset').addEventListener('click', event => {
|
||||
event.preventDefault();
|
||||
setStylelintRules();
|
||||
popup.codebox.setValue(JSON.stringify({rules: stylelintDefaultConfig.rules}, null, 2));
|
||||
|
@ -254,6 +264,7 @@ function setupStylelintPopup(rules) {
|
|||
}
|
||||
function setJSONMode(cm) {
|
||||
cm.setOption('mode', 'application/json');
|
||||
cm.setOption('lint', 'json');
|
||||
}
|
||||
const popup = showCodeMirrorPopup(t('setStylelintRules'), $element({
|
||||
className: 'contents',
|
||||
|
@ -278,18 +289,32 @@ function setupStylelintPopup(rules) {
|
|||
]
|
||||
}));
|
||||
const contents = popup.querySelector('.contents');
|
||||
const loadJSON = window.jsonlint ? [] : ['vendor/codemirror/addon/lint/json-lint.js'];
|
||||
contents.insertBefore(popup.codebox.display.wrapper, contents.firstElementChild);
|
||||
popup.codebox.focus();
|
||||
popup.codebox.setValue(rules);
|
||||
if (!$('script[src*="json-lint.js"]')) {
|
||||
onDOMscripted(
|
||||
['vendor/codemirror/addon/lint/json-lint.js'],
|
||||
() => {
|
||||
setJSONMode(popup.codebox);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
setJSONMode(popup.codebox);
|
||||
}
|
||||
onDOMscripted(loadJSON, () => { setJSONMode(popup.codebox); });
|
||||
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) {
|
||||
let found = [];
|
||||
const stylelint = require('stylelint').lint;
|
||||
if (stylelint) {
|
||||
window.stylelint = require('stylelint').lint;
|
||||
if (window.stylelint) {
|
||||
return BG.chromeLocal.getValue('editorStylelintRules').then((rules = stylelintDefaultConfig.rules) => {
|
||||
// stylelintDefaultConfig stored in stylelint-config.js & loaded by edit.html
|
||||
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
|
||||
// ref: https://github.com/postcss/postcss#syntaxes
|
||||
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
|
||||
other `fs.readFile` entries are not accessed because we're using stylelint's
|
||||
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