Editor: show a list of all CSSLint messages

This commit is contained in:
tophf 2015-05-22 15:28:05 +03:00
parent c61b715e2f
commit 1250bb970e
3 changed files with 149 additions and 0 deletions

View File

@ -173,6 +173,14 @@
"message": "Install update", "message": "Install update",
"description": "Label for the button to install an update for a single style" "description": "Label for the button to install an update for a single style"
}, },
"issues": {
"message": "Issues",
"description": "Label for the CSSLint issues block on the style edit page"
},
"issuesHelp": {
"message": "The issues found by <a href='https:\/\/github.com\/CSSLint\/csslint' target='_blank'>CSSLint<\/a> with these rules enabled:",
"description": "Help popup message for the CSSLint issues block on the style edit page"
},
"manageFilters": { "manageFilters": {
"message": "Filters", "message": "Filters",
"description": "Label for filters container" "description": "Label for filters container"

View File

@ -131,6 +131,14 @@
content: "*"; content: "*";
font-weight: bold; font-weight: bold;
} }
#sections {
counter-reset: codebox;
}
#sections > div > label::after {
counter-increment: codebox;
content: counter(codebox);
margin-left: 0.25rem;
}
/* code */ /* code */
.code { .code {
height: 10rem; height: 10rem;
@ -264,6 +272,50 @@
padding-right: 0.5rem; padding-right: 0.5rem;
} }
/************ lint ************/
#lint {
display: none;
}
#lint > div {
overflow-y: auto;
}
#lint table {
font-size: 100%;
border-spacing: 0;
margin-bottom: 1rem;
line-height: 1.0;
}
#lint table:last-child {
margin-bottom: 0;
}
#lint caption {
text-align: left;
font-weight: bold;
}
#lint tbody {
font-size: 85%;
cursor: pointer;
}
#lint tr:hover {
background-color: rgba(0, 0, 0, 0.1);
}
#lint td[role="severity"] {
font-size: 0;
width: 16px;
padding-right: 0.25rem;
}
#lint td[role="line"], #lint td[role="sep"] {
text-align: right;
padding-right: 0;
}
#lint td[role="col"] {
text-align: left;
padding-right: 0.25rem;
}
#lint td[role="message"] {
text-align: left;
}
/************ reponsive layouts ************/ /************ reponsive layouts ************/
@media(max-width:737px) { @media(max-width:737px) {
#header { #header {
@ -405,6 +457,7 @@
<select data-option="theme" id="editor.theme"></select> <select data-option="theme" id="editor.theme"></select>
</div> </div>
</section> </section>
<section id="lint"><h2 i18n-text="issues"><img id="lint-help" src="help.png" i18n-alt="helpAlt"></h2><div></div></section>
</div> </div>
<section id="sections"> <section id="sections">
<h2><span id="sections-heading" i18n-text="styleSectionsTitle"></span><img id="sections-help" src="help.png" i18n-alt="helpAlt"></h2> <h2><span id="sections-heading" i18n-text="styleSectionsTitle"></span><img id="sections-help" src="help.png" i18n-alt="helpAlt"></h2>

88
edit.js
View File

@ -354,6 +354,7 @@ function indicateCodeChange(cm) {
var section = getSectionForCodeMirror(cm); var section = getSectionForCodeMirror(cm);
setCleanItem(section, cm.isClean(section.savedValue)); setCleanItem(section, cm.isClean(section.savedValue));
updateTitle(); updateTitle();
updateLintReport(cm);
} }
function getSectionForCodeMirror(cm) { function getSectionForCodeMirror(cm) {
@ -513,6 +514,7 @@ function addSection(event, section) {
var cm = setupCodeMirror(codeElement, newIndex); var cm = setupCodeMirror(codeElement, newIndex);
makeSectionVisible(cm); makeSectionVisible(cm);
cm.focus() cm.focus()
renderLintReport();
} else { } else {
sections.appendChild(div); sections.appendChild(div);
setupCodeMirror(codeElement); setupCodeMirror(codeElement);
@ -536,6 +538,7 @@ function removeSection(event) {
var cm = section.querySelector(".CodeMirror").CodeMirror; var cm = section.querySelector(".CodeMirror").CodeMirror;
removeAreaAndSetDirty(section); removeAreaAndSetDirty(section);
editors.splice(editors.indexOf(cm), 1); editors.splice(editors.indexOf(cm), 1);
renderLintReport();
} }
function removeAreaAndSetDirty(area) { function removeAreaAndSetDirty(area) {
@ -748,6 +751,80 @@ function getEditorInSight(nearbyElement) {
} }
} }
function updateLintReport(cm) {
var state = cm.state.lint;
clearTimeout(state.reportTimeout);
state.reportTimeout = setTimeout(update.bind(cm), (state.options.delay || 500) + 500);
function update() { // this == cm
var html = this.state.lint.marked.length == 0 ? "" : "<tbody>" +
this.state.lint.marked.map(function(mark) {
var info = mark.__annotation;
return "<tr class='" + info.severity + "'>" +
"<td role='severity' class='CodeMirror-lint-marker-" + info.severity + "'>" +
info.severity + "</td>" +
"<td role='line'>" + (info.from.line+1) + "</td>" +
"<td role='sep'>:</td>" +
"<td role='col'>" + (info.from.ch+1) + "</td>" +
"<td role='message'>" + info.message.replace(/ at line \d.+$/, "") + "</td></tr>";
}).join("") + "</tbody>";
if (this.state.lint.html != html) {
this.state.lint.html = html;
renderLintReport(true);
}
}
}
function renderLintReport(blockChanged) {
var container = document.getElementById("lint");
var content = container.children[1];
var label = t("sectionCode");
var newContent = content.cloneNode(false);
editors.forEach(function(cm, index) {
if (cm.state.lint.html) {
var newBlock = newContent.appendChild(document.createElement("table"));
var html = "<caption>" + label + " " + (index+1) + "</caption>" + cm.state.lint.html;
newBlock.innerHTML = html;
newBlock.cm = cm;
if (!blockChanged) {
var block = content.children[newContent.children.length - 1];
blockChanged = !block || cm != block.cm || html != block.innerHTML;
}
}
});
if (blockChanged || newContent.children.length != content.children.length) {
container.replaceChild(newContent, content);
container.style.display = newContent.children.length ? "block" : "none";
resizeLintReport(null, newContent);
}
}
function resizeLintReport(event, content) {
content = content || document.getElementById("lint").children[1];
if (content.children.length) {
var header = document.getElementById("header");
var headerHeight = parseFloat(getComputedStyle(header).height);
var contentTop = content.getBoundingClientRect().top - header.getBoundingClientRect().top;
var newMaxHeight = Math.max(100, headerHeight - contentTop) + "px";
if (newMaxHeight != content.style.maxHeight) {
content.style.maxHeight = newMaxHeight;
}
}
}
function gotoLintIssue(event) {
var issue = querySelectorParent(event.target, "tr");
if (!issue) {
return;
}
var block = querySelectorParent(issue, "table");
makeSectionVisible(block.cm);
block.cm.focus();
block.cm.setSelection({
line: parseInt(issue.querySelector("td[role='line']").textContent) - 1,
ch: parseInt(issue.querySelector("td[role='col']").textContent) - 1
});
}
window.addEventListener("load", init, false); window.addEventListener("load", init, false);
function init() { function init() {
@ -810,6 +887,9 @@ function initHooks() {
document.getElementById("sections-help").addEventListener("click", showSectionHelp, false); document.getElementById("sections-help").addEventListener("click", showSectionHelp, false);
document.getElementById("keyMap-help").addEventListener("click", showKeyMapHelp, false); document.getElementById("keyMap-help").addEventListener("click", showKeyMapHelp, false);
document.getElementById("cancel-button").addEventListener("click", goBackToManage); document.getElementById("cancel-button").addEventListener("click", goBackToManage);
document.getElementById("lint-help").addEventListener("click", showLintHelp);
document.getElementById("lint").addEventListener("click", gotoLintIssue);
window.addEventListener("resize", resizeLintReport);
setupGlobalSearch(); setupGlobalSearch();
setCleanGlobal(); setCleanGlobal();
@ -1074,6 +1154,14 @@ function showKeyMapHelp() {
} }
} }
function showLintHelp() {
showHelp(t("issues"), t("issuesHelp") + "<ul>" +
CSSLint.getRules().map(function(rule) {
return "<li><b>" + rule.name + "</b><br>" + rule.desc + "</li>";
}).join("") + "</ul"
);
}
function showHelp(title, text) { function showHelp(title, text) {
var div = document.getElementById("help-popup"); var div = document.getElementById("help-popup");
div.querySelector(".contents").innerHTML = text; div.querySelector(".contents").innerHTML = text;