diff --git a/edit/edit.js b/edit/edit.js index e7367620..9b25a902 100644 --- a/edit/edit.js +++ b/edit/edit.js @@ -154,7 +154,7 @@ function setCleanSection(section) { const cm = section.CodeMirror; if (cm) { section.savedValue = cm.changeGeneration(); - indicateCodeChange(cm); + updateTitle(); } } @@ -1570,6 +1570,7 @@ function fromMozillaFormat() { // parserlib contained in CSSLint-worker.js onDOMscripted(['vendor-overwrites/csslint/csslint-worker.js']).then(() => { doImportWhenReady(event.target); + editors.forEach(cm => updateLintReportIfEnabled(cm, 1)); editors.last.state.renderLintReportNow = true; }); } diff --git a/edit/lint.js b/edit/lint.js index eb97d1c4..a91622a9 100644 --- a/edit/lint.js +++ b/edit/lint.js @@ -152,9 +152,9 @@ function updateLinter({immediately} = {}) { if (guttersOption) { cm.setOption('guttersOption', guttersOption); updateGutters(cm, guttersOption); + cm.refresh(); } - cm.refresh(); - updateLintReport(cm); + setTimeout(updateLintReport, 0, cm); }); } @@ -188,6 +188,9 @@ function updateLinter({immediately} = {}) { updateEditors(); }); $('#linter-settings').style.display = !linter ? 'none' : 'inline-block'; + if (!linter) { + $('#lint > div').textContent = ''; + } } function updateLintReport(cm, delay) { @@ -203,7 +206,7 @@ function updateLintReport(cm, delay) { if (delay === 0) { // immediately show pending csslint/stylelint messages in onbeforeunload and save clearTimeout(state.lintTimeout); - update(cm); + updateLintReportInternal(cm); return; } if (delay > 0) { @@ -211,73 +214,79 @@ function updateLintReport(cm, delay) { state.lintTimeout = setTimeout(cm => { if (cm.performLint) { cm.performLint(); - update(cm); + updateLintReportInternal(cm); } }, delay, cm); return; } - // user is editing right now: postpone updating the report for the new issues (default: 500ms lint + 4500ms) - // or update it as soon as possible (default: 500ms lint + 100ms) in case an existing issue was just fixed - clearTimeout(state.reportTimeout); - state.reportTimeout = setTimeout(update, (state.options || {}).delay + 100, cm); - state.postponeNewIssues = delay === undefined || delay === null; + if (state.options) { + clearTimeout(state.reportTimeout); + const delay = cm && cm.state.renderLintReportNow ? 0 : state.options.delay + 100; + state.reportTimeout = setTimeout(updateLintReportInternal, delay, cm, { + postponeNewIssues: delay === undefined || delay === null + }); + } +} - function update(cm) { - const scope = cm ? [cm] : editors; - let changed = false; - let fixedOldIssues = false; - scope.forEach(cm => { - const scopedState = cm.state.lint || {}; - const oldMarkers = scopedState.markedLast || {}; - const newMarkers = {}; - const html = !scopedState.marked || scopedState.marked.length === 0 ? '' : '
' + - scopedState.marked.map(mark => { +function updateLintReportInternal(scope, {postponeNewIssues} = {}) { + scope = scope ? [scope] : editors; + let changed = false; + let fixedOldIssues = false; + const clipString = (str, limit) => + str.length <= limit ? str : str.substr(0, limit) + '...'; + scope.forEach(cm => { + const lintState = cm.state.lint || {}; + const oldMarkers = lintState.markedLast || new Map(); + const newMarkers = lintState.markedLast = new Map(); + const marked = lintState.marked || {}; + const activeLine = cm.getCursor().line; + if (marked.length) { + const body = $element({tag: 'tbody', + appendChild: marked.map(mark => { const info = mark.__annotation; - const isActiveLine = info.from.line === cm.getCursor().line; - const pos = isActiveLine ? 'cursor' : (info.from.line + ',' + info.from.ch); - // rule name added in parentheses at the end; extract it out for the info popup - const text = info.message; - const title = escapeHtml(text + `\n(${info.rule})`, {limit: 1000}); - const message = escapeHtml(text, {limit: 100}); + const {line, ch} = info.from; + const isActiveLine = line === activeLine; + const pos = isActiveLine ? 'cursor' : (line + ',' + ch); + const title = clipString(info.message, 1000) + `\n(${info.rule})`; + const message = clipString(info.message, 100); if (isActiveLine || oldMarkers[pos] === message) { - delete oldMarkers[pos]; + oldMarkers.delete(pos); } - newMarkers[pos] = message; - return `