Add stylelint settings popup & cleanup
This commit is contained in:
parent
07dce1006d
commit
06cd78b643
|
@ -506,6 +506,23 @@
|
|||
"message": "Remove section",
|
||||
"description": "Label for the button to remove a section"
|
||||
},
|
||||
"setStylelintLink": {
|
||||
"message": "Get a full list of rules from $link$",
|
||||
"description": "Stylelint rules link",
|
||||
"placeholders": {
|
||||
"link": {
|
||||
"content": "$1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"setStylelintRules": {
|
||||
"message": "Set stylelint rules",
|
||||
"description": "Stylelint popup header"
|
||||
},
|
||||
"setStylelintError": {
|
||||
"message": "Invalid JSON format",
|
||||
"description": "Stylelint invalid JSON message"
|
||||
},
|
||||
"shortcuts": {
|
||||
"message": "Shortcuts",
|
||||
"description": "Go to shortcut configuration"
|
||||
|
|
|
@ -198,6 +198,9 @@
|
|||
<option value="csslint" selected>CSSLint</option>
|
||||
<option value="stylelint">stylelint</option>
|
||||
</select>
|
||||
<svg id="stylelint-settings" class="svg-icon settings">
|
||||
<use xlink:href="#svg-icon-settings"/>
|
||||
</svg>
|
||||
</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>
|
||||
</div>
|
||||
|
@ -219,6 +222,9 @@
|
|||
<symbol id="svg-icon-close" height="16" width="12" viewBox="0 0 12 16">
|
||||
<path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"></path>
|
||||
</symbol>
|
||||
<symbol id="svg-icon-settings" height="12" width="12" viewBox="0 0 16 16">
|
||||
<path d="M16 9.45V6.52l-1.8-.3c-.14-.5-.34-.95-.56-1.35L14.7 3.4l-2.07-2.1-1.5 1.03c-.43-.24-.9-.43-1.37-.56L9.46 0H6.54l-.3 1.8c-.5.13-.94.33-1.36.55L3.4 1.32 1.3 3.4l1.07 1.45c-.24.45-.44.92-.57 1.42L0 6.53v2.95l1.8.3c.14.52.33.95.57 1.37l-1.07 1.5 2.06 2.08 1.5-1.07c.44.24.9.45 1.4.57l.3 1.77H9.5l.32-1.8c.47-.13.95-.32 1.34-.56l1.5 1.06 2.07-2.05-1.03-1.5c.24-.45.44-.9.56-1.36L16 9.44v-.02zm-8 1.6C6.3 11.05 4.93 9.7 4.93 8S6.33 4.9 8 4.9s3.06 1.4 3.06 3.1S9.7 11.04 8 11.04z"/>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
||||
</body>
|
||||
|
|
|
@ -77,16 +77,19 @@ input[type="checkbox"] {
|
|||
h2 .svg-icon, label .svg-icon {
|
||||
margin-top: -1px;
|
||||
}
|
||||
.svg-icon.info {
|
||||
.svg-icon.info,
|
||||
.svg-icon.settings {
|
||||
width: 14px;
|
||||
height: 16px;
|
||||
}
|
||||
.svg-icon:hover,
|
||||
.svg-icon.info {
|
||||
.svg-icon.info,
|
||||
.svg-icon.settings {
|
||||
fill: #666;
|
||||
}
|
||||
.svg-icon,
|
||||
.svg-icon.info:hover {
|
||||
.svg-icon.info:hover,
|
||||
.svg-icon.settings:hover {
|
||||
fill: #000;
|
||||
}
|
||||
#enabled {
|
||||
|
@ -365,11 +368,28 @@ body[data-match-highlight="selection"] .CodeMirror-selection-highlight-scrollbar
|
|||
max-height: calc(100vh - 8rem);
|
||||
overflow-y: auto;
|
||||
}
|
||||
#help-popup .settings {
|
||||
min-width: 500px;
|
||||
min-height: 200px;
|
||||
max-width: 48vw;
|
||||
}
|
||||
#help-popup .dismiss {
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
top: .5em;
|
||||
}
|
||||
#help-popup .error {
|
||||
display: none;
|
||||
margin-left: 10px;
|
||||
color: #900;
|
||||
font-weight: bold;
|
||||
}
|
||||
#help-popup .error a {
|
||||
color: #f00;
|
||||
}
|
||||
#help-popup .error.show {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.keymap-list {
|
||||
font-size: 85%;
|
||||
|
@ -417,7 +437,6 @@ body[data-match-highlight="selection"] .CodeMirror-selection-highlight-scrollbar
|
|||
border-spacing: 0;
|
||||
margin-bottom: 1rem;
|
||||
line-height: 1.0;
|
||||
width: 245px;
|
||||
}
|
||||
#lint table:last-child {
|
||||
margin-bottom: 0;
|
||||
|
|
16
edit/edit.js
16
edit/edit.js
|
@ -1,5 +1,5 @@
|
|||
/* eslint brace-style: 0, operator-linebreak: 0 */
|
||||
/* global CodeMirror exports css_beautify parserlib CSSLint initLintHooks setLinter updateLintReport renderLintReport */
|
||||
/* global CodeMirror exports css_beautify parserlib CSSLint initLint setLinter updateLintReport renderLintReport updateLinter */
|
||||
'use strict';
|
||||
|
||||
let styleId = null;
|
||||
|
@ -168,7 +168,7 @@ function initCodeMirror() {
|
|||
matchBrackets: true,
|
||||
highlightSelectionMatches: {showToken: /[#.\-\w]/, annotateScrollbar: true},
|
||||
hintOptions: {},
|
||||
lint: setLinter('csslint'),
|
||||
lint: setLinter(prefs.get('editor.linter')),
|
||||
lintReportDelay: prefs.get('editor.lintReportDelay'),
|
||||
styleActiveLine: true,
|
||||
theme: 'default',
|
||||
|
@ -351,15 +351,7 @@ function acmeEventListener(event) {
|
|||
break;
|
||||
case 'linter':
|
||||
if (value !== null && editors.length) {
|
||||
if (prefs.get(el.id) !== value) {
|
||||
prefs.set(el.id, value || 'csslint');
|
||||
}
|
||||
editors.forEach(cm => {
|
||||
console.log('set linter to', value);
|
||||
cm.setOption('lint', setLinter(value || 'csslint'));
|
||||
});
|
||||
// CodeMirror.signal(editors.lastActive || editors[0], "change");
|
||||
// save();
|
||||
updateLinter(value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1251,7 +1243,7 @@ function initHooks() {
|
|||
document.getElementById('sections-help').addEventListener('click', showSectionHelp, false);
|
||||
document.getElementById('keyMap-help').addEventListener('click', showKeyMapHelp, false);
|
||||
document.getElementById('cancel-button').addEventListener('click', goBackToManage);
|
||||
initLintHooks();
|
||||
initLint();
|
||||
|
||||
if (!FIREFOX) {
|
||||
$$([
|
||||
|
|
73
edit/lint.js
73
edit/lint.js
|
@ -1,15 +1,24 @@
|
|||
/* global CodeMirror CSSLint editors makeSectionVisible showHelp */
|
||||
/* global CodeMirror CSSLint editors makeSectionVisible showHelp stylelintDefaultConfig BG */
|
||||
'use strict';
|
||||
|
||||
function initLintHooks() {
|
||||
function initLint() {
|
||||
document.getElementById('lint-help').addEventListener('click', showLintHelp);
|
||||
document.getElementById('lint').addEventListener('click', gotoLintIssue);
|
||||
window.addEventListener('resize', resizeLintReport);
|
||||
document.getElementById('stylelint-settings').addEventListener('click', openStylelintSettings);
|
||||
|
||||
// touch devices don't have onHover events so the element we'll be toggled via clicking (touching)
|
||||
if ('ontouchstart' in document.body) {
|
||||
document.querySelector('#lint h2').addEventListener('click', toggleLintReport);
|
||||
}
|
||||
BG.chromeLocal.getValue('editorStylelintRules').then(rules => setStylelintRules(rules));
|
||||
}
|
||||
|
||||
function setStylelintRules(rules = {}) {
|
||||
if (Object.keys(rules).length === 0) {
|
||||
rules = deepCopy(stylelintDefaultConfig.rules);
|
||||
}
|
||||
BG.chromeLocal.setValue('editorStylelintRules', rules);
|
||||
}
|
||||
|
||||
function setLinter(name) {
|
||||
|
@ -19,6 +28,18 @@ function setLinter(name) {
|
|||
};
|
||||
}
|
||||
|
||||
function updateLinter(name = 'csslint') {
|
||||
if (prefs.get('editor.linter') !== name) {
|
||||
prefs.set('editor.linter', name);
|
||||
}
|
||||
editors.forEach(cm => {
|
||||
cm.setOption('lint', setLinter(name));
|
||||
updateLintReport(cm, 200);
|
||||
});
|
||||
$('#stylelint-settings').style.display = name === 'stylelint' ?
|
||||
'inline-block' : 'none';
|
||||
}
|
||||
|
||||
function updateLintReport(cm, delay) {
|
||||
if (delay === 0) {
|
||||
// immediately show pending csslint/stylelint messages in onbeforeunload and save
|
||||
|
@ -178,3 +199,51 @@ function showLintHelp() {
|
|||
}
|
||||
return showHelp(t('issues'), header + list + '</ul>');
|
||||
}
|
||||
|
||||
function setupStylelintSettingsEvents() {
|
||||
let timer;
|
||||
$('#help-popup .save').addEventListener('click', () => {
|
||||
try {
|
||||
setStylelintRules(JSON.parse($('#help-popup textarea').value).rules);
|
||||
// it is possible to have stylelint rules popup open & switch to csslint
|
||||
if (prefs.get('editor.linter') === 'stylelint') {
|
||||
updateLinter('stylelint');
|
||||
}
|
||||
} catch (err) {
|
||||
$('#help-popup .error').classList.add('show');
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(() => {
|
||||
// popup may be closed at this point
|
||||
const error = $('#help-popup .error');
|
||||
if (error) {
|
||||
error.classList.remove('show');
|
||||
}
|
||||
}, 3000);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
$('#help-popup .reset').addEventListener('click', () => {
|
||||
setStylelintRules();
|
||||
$('#help-popup .settings').value = JSON.stringify({rules: stylelintDefaultConfig.rules}, null, 2);
|
||||
if (prefs.get('editor.linter') === 'stylelint') {
|
||||
updateLinter('stylelint');
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
function openStylelintSettings() {
|
||||
BG.chromeLocal.getValue('editorStylelintRules').then((rules = stylelintDefaultConfig.rules) => {
|
||||
const link = '<a target="_blank" href="https://stylelint.io/demo/">Stylelint</a>';
|
||||
const text = JSON.stringify({rules: rules}, null, 2);
|
||||
const content = `<textarea class="contents settings">${text}</textarea>
|
||||
<p>${t('setStylelintLink', link)}</p>
|
||||
<button class="save" type="button">Save</button>
|
||||
<button class="reset" type="button">Reset</button>
|
||||
<span class="error">
|
||||
${t('setStylelintError')} (<a target="_blank" href="https://jsonlint.com/">JSONLint</a>)
|
||||
</span>`;
|
||||
showHelp(t('setStylelintRules'), content);
|
||||
setupStylelintSettingsEvents();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -66,26 +66,34 @@ CodeMirror.registerHelper("lint", "stylelint", function(text) {
|
|||
let found = [];
|
||||
const stylelint = require('stylelint').lint;
|
||||
if (stylelint) {
|
||||
return stylelint({
|
||||
code: text,
|
||||
// stylelintConfig stored in stylelint-config.js & loaded by edit.html
|
||||
config: stylelintConfig
|
||||
}).then(output => {
|
||||
const warnings = output.results.length ? output.results[0].warnings : [],
|
||||
len = warnings.length;
|
||||
let i, warning;
|
||||
if (len) {
|
||||
for (i = 0; i < len; i++) {
|
||||
warning = warnings[i];
|
||||
found.push({
|
||||
from: CodeMirror.Pos(warning.line - 1, warning.column - 1),
|
||||
to: CodeMirror.Pos(warning.line - 1, warning.column),
|
||||
message: warning.text,
|
||||
severity : warning.severity
|
||||
});
|
||||
}
|
||||
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) {
|
||||
rules = stylelintDefaultConfig.rules;
|
||||
}
|
||||
return found;
|
||||
return stylelint({
|
||||
code: text,
|
||||
config: {
|
||||
syntax: stylelintDefaultConfig.syntax,
|
||||
rules: rules
|
||||
}
|
||||
}).then(output => {
|
||||
const warnings = output.results.length ? output.results[0].warnings : [],
|
||||
len = warnings.length;
|
||||
let i, warning;
|
||||
if (len) {
|
||||
for (i = 0; i < len; i++) {
|
||||
warning = warnings[i];
|
||||
found.push({
|
||||
from: CodeMirror.Pos(warning.line - 1, warning.column - 1),
|
||||
to: CodeMirror.Pos(warning.line - 1, warning.column),
|
||||
message: warning.text,
|
||||
severity : warning.severity
|
||||
});
|
||||
}
|
||||
}
|
||||
return found;
|
||||
});
|
||||
});
|
||||
}
|
||||
return found;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const stylelintConfig = {
|
||||
const stylelintDefaultConfig = {
|
||||
// 'sugarss' is a indent-based syntax like Sass or Stylus
|
||||
// ref: https://github.com/postcss/postcss#syntaxes
|
||||
syntax: 'sugarss',
|
||||
|
|
Loading…
Reference in New Issue
Block a user