diff --git a/edit.html b/edit.html
index 950dfcad..da93b705 100644
--- a/edit.html
+++ b/edit.html
@@ -93,6 +93,7 @@
+
diff --git a/edit/linter-help-dialog.js b/edit/linter-help-dialog.js
new file mode 100644
index 00000000..98c11903
--- /dev/null
+++ b/edit/linter-help-dialog.js
@@ -0,0 +1,56 @@
+/* global showHelp editorWorker */
+'use strict';
+
+function createLinterHelpDialog(getIssues) {
+ let csslintRules;
+ let preparing;
+ return {show};
+
+ function show() {
+ // FIXME: implement a linterChooser?
+ const linter = $('#editor.linter').value;
+ const baseUrl = linter === 'stylelint'
+ ? 'https://stylelint.io/user-guide/rules/'
+ // some CSSLint rules do not have a url
+ : 'https://github.com/CSSLint/csslint/issues/535';
+ let headerLink, template;
+ if (linter === 'csslint') {
+ headerLink = $createLink('https://github.com/CSSLint/csslint/wiki/Rules', 'CSSLint');
+ template = ({rule: ruleID}) => {
+ const rule = csslintRules.find(rule => rule.id === ruleID);
+ return rule &&
+ $create('li', [
+ $create('b', $createLink(rule.url || baseUrl, rule.name)),
+ $create('br'),
+ rule.desc,
+ ]);
+ };
+ } else {
+ headerLink = $createLink(baseUrl, 'stylelint');
+ template = ({rule}) =>
+ $create('li',
+ rule === 'CssSyntaxError' ? rule : $createLink(baseUrl + rule, rule));
+ }
+ const header = t('linterIssuesHelp', '\x01').split('\x01');
+ const activeRules = getIssues();
+ Promise.resolve(linter === 'csslint' && prepareCsslintRules())
+ .then(() =>
+ showHelp(t('linterIssues'),
+ $create([
+ header[0], headerLink, header[1],
+ $create('ul.rules', [...activeRules.values()].map(template)),
+ ])
+ )
+ );
+ }
+
+ function prepareCsslintRules() {
+ if (!preparing) {
+ preparing = editorWorker.getCsslintRules()
+ .then(rules => {
+ csslintRules = rules;
+ });
+ }
+ return preparing;
+ }
+}
diff --git a/edit/linter-report.js b/edit/linter-report.js
index eec4bd9c..4800223a 100644
--- a/edit/linter-report.js
+++ b/edit/linter-report.js
@@ -1,8 +1,9 @@
-/* global linter editors clipString */
+/* global linter editors clipString createLinterHelpDialog makeSectionVisible */
'use strict';
var linterReport = (() => { // eslint-disable-line no-var
const cms = new Map();
+ const helpDialog = createLinterHelpDialog(getIssues);
linter.onChange((annotationsNotSorted, annotations, cm) => {
let table = cms.get(cm);
@@ -31,12 +32,22 @@ var linterReport = (() => { // eslint-disable-line no-var
});
document.addEventListener('DOMContentLoaded', () => {
- $('#lint-help').addEventListener('click', showLintHelp);
+ $('#lint-help').addEventListener('click', helpDialog.show);
$('#linter-settings').addEventListener('click', showLintConfig);
}, {once: true});
return {refresh};
+ function getIssues() {
+ const issues = new Set();
+ for (const table of cms.values()) {
+ for (const tr of table.trs) {
+ issues.add(tr.getAnnotation());
+ }
+ }
+ return issues;
+ }
+
function findNextSibling(cms, cm) {
let i = editors.indexOf(cm) + 1;
while (i < editors.length) {
@@ -55,7 +66,13 @@ var linterReport = (() => { // eslint-disable-line no-var
const table = $create('table', [caption, tbody]);
const trs = [];
let empty = true;
- return {updateAnnotations, update, isEmpty, element: table};
+ return {
+ element: table,
+ trs,
+ updateAnnotations,
+ update,
+ isEmpty
+ };
function isEmpty() {
return empty;
@@ -112,7 +129,8 @@ var linterReport = (() => { // eslint-disable-line no-var
]);
return {
element: trElement,
- update
+ update,
+ getAnnotation: () => anno
};
function update(_anno) {
@@ -135,7 +153,5 @@ var linterReport = (() => { // eslint-disable-line no-var
cm.setSelection(anno.from);
}
- function showLintHelp() {}
-
function showLintConfig() {}
})();