520 lines
15 KiB
HTML
520 lines
15 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
|
<html>
|
|
<head>
|
|
<style type="text/css">
|
|
@import "../../dojo/resources/dojo.css";
|
|
@import "../../dojox/grid/resources/Grid.css";
|
|
@import "../../dojox/grid/resources/soriaGrid.css";
|
|
|
|
html, body, #main{
|
|
width: 100%; /* make the body expand to fill the visible window */
|
|
height: 100%;
|
|
overflow: hidden; /* erase window level scrollbars */
|
|
padding: 0 0 0 0;
|
|
margin: 0 0 0 0;
|
|
font: 10pt Arial,Myriad,Tahoma,Verdana,sans-serif;
|
|
}
|
|
|
|
#checks label {
|
|
padding: 4px;
|
|
float: left;
|
|
}
|
|
#checks input {
|
|
float: right;
|
|
}
|
|
#checks div {
|
|
height: 15px;
|
|
padding: 4px;
|
|
margin-top: 5px;
|
|
}
|
|
</style>
|
|
|
|
<!-- required: the default dijit theme: -->
|
|
<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/soria/soria.css">
|
|
|
|
<!-- required: dojo.js -->
|
|
<script type="text/javascript" src="../../dojo/dojo.js"
|
|
djConfig="isDebug: true, parseOnLoad: true"></script>
|
|
|
|
<script type="text/javascript">
|
|
dojo.require("dijit.dijit"); // optimize: load dijit layer
|
|
dojo.require("dijit.layout.BorderContainer");
|
|
dojo.require("dijit.form.FilteringSelect");
|
|
dojo.require("dijit.form.Button");
|
|
dojo.require("dijit.form.ToggleButton");
|
|
dojo.require("dijit.layout.TabContainer");
|
|
dojo.require("dijit.layout.ContentPane");
|
|
dojo.require("dojox.grid.DataGrid");
|
|
dojo.require("dojo.data.ItemFileReadStore");
|
|
dojo.require("dojo.date.locale");
|
|
dojo.require("dijit.Dialog");
|
|
</script>
|
|
|
|
|
|
<script type="text/javascript" src="checkstyleUtil.js"></script>
|
|
<script type="text/javascript">
|
|
var singleFileStore;
|
|
var errorQuery;
|
|
var saveErrorMsg = "You may need to rename the checkstyle.php.rename.html file to checkstyle.php."
|
|
+ "\nPlease read the readme.txt file in the /util/checkstyle folder.";
|
|
|
|
dojo.addOnLoad(function(){
|
|
checkstyleStore.fetch({query: {date : '*'}, onComplete: function(items){
|
|
var checkstyleReportDate = new Date(checkstyleStore.getValue(items[0], "date"));
|
|
var dateStr = dojo.date.locale.format((new Date(checkstyleReportDate)), {formatLength: "medium"});
|
|
|
|
document.title = "Dojo Checkstyle report generated on " + dateStr;
|
|
dojo.byId("reportDate").innerHTML = dateStr;
|
|
}});
|
|
|
|
dojo.connect(dijit.byId("messagesGrid"), "onRowClick", doEdit);
|
|
|
|
});
|
|
var cachedFiles = {};
|
|
var changedFiles = [];
|
|
var navKeys = {};
|
|
dojo.forEach([dojo.keys.UP_ARROW, dojo.keys.DOWN_ARROW,
|
|
dojo.keys.LEFT_ARROW, dojo.keys.RIGHT_ARROW,
|
|
dojo.keys.ENTER], function(code){
|
|
navKeys[code] = true;
|
|
});
|
|
function updateLine(evt) {
|
|
evt = dojo.fixEvent(evt);
|
|
if (navKeys[evt.keyCode]) {
|
|
dojo.byId("lineNumber").innerHTML = getCursorPosition(evt.target);
|
|
}
|
|
}
|
|
|
|
function getCursorPosition(textarea) {
|
|
if(textarea.selectionStart){
|
|
return textarea.selectionStart;
|
|
}else if(dojo.doc.selection){ //IE
|
|
var range = dojo.doc.selection.createRange();
|
|
return range;
|
|
}
|
|
}
|
|
|
|
function onFolderClick(evt) {
|
|
var folderName = evt.grid.store.getValue(
|
|
evt.grid.getItem(evt.rowIndex), "file");
|
|
if (dojo.trim(folderName) == "All") {
|
|
folderName = "";
|
|
} else if (folderName.charAt(folderName.length - 1) != "/"){
|
|
folderName += "/";
|
|
}
|
|
|
|
showAllErrors({file: folderName + "*", folder: 0});
|
|
dijit.byId("mainTab").selectChild(dijit.byId("errorsTab"));
|
|
}
|
|
var chartInitialized = false;
|
|
|
|
dojo.subscribe("mainTab-selectChild", function(tab){
|
|
if(chartInitialized || tab.id != "chartTab"){
|
|
return;
|
|
}
|
|
chartInitialized = true;
|
|
checkstyleStore.fetch({query: {file: "*"}, onComplete: initializeChart});
|
|
});
|
|
function initializeChart(items) {
|
|
|
|
dojo.require("dojox.charting.DataChart");
|
|
dojo.require("dojox.charting.action2d.Highlight");
|
|
dojo.require("dojox.charting.action2d.Tooltip");
|
|
dojo.require("dojox.charting.plot2d.Columns");
|
|
|
|
var folderCounts = {};
|
|
|
|
dojo.forEach(items, function(item){
|
|
var fileName = checkstyleStore.getValue(item, "file");
|
|
|
|
var parts = fileName.split("/");
|
|
if (parts.length < 2) {
|
|
return;
|
|
}
|
|
var folderName = parts[0] + "/" + parts[1];
|
|
|
|
if (!folderCounts[folderName]) {
|
|
folderCounts[folderName] = 0;
|
|
}
|
|
folderCounts[folderName]++;
|
|
});
|
|
|
|
var folderCountsArr = [];
|
|
|
|
for (var x in folderCounts) {
|
|
folderCountsArr.push({"folder": x, count: folderCounts[x]});
|
|
}
|
|
folderCountsArr.sort(function(a, b){
|
|
if(a.count < b.count) {
|
|
return 1;
|
|
} else if(a.count > b.count){
|
|
return -1;
|
|
}
|
|
return 0;
|
|
});
|
|
|
|
if (folderCountsArr.length > 20) {
|
|
folderCountsArr = folderCountsArr.slice(0, 20);
|
|
}
|
|
dojo.forEach(folderCountsArr, function(item, index){
|
|
item.id = index + 1;
|
|
});
|
|
var chartStore = new dojo.data.ItemFileReadStore({
|
|
data: {
|
|
identifier: 'id',
|
|
label: 'folder',
|
|
items: folderCountsArr
|
|
}
|
|
});
|
|
var chart = new dojox.charting.DataChart("chart", {
|
|
displayRange:12,
|
|
yaxis:{
|
|
max: folderCountsArr[0].count + 10,
|
|
min: Math.max(0, folderCountsArr[folderCountsArr.length -1].count - 10),
|
|
majorTickStep: Math.round(folderCountsArr[0].count / 10),
|
|
maxLabelSize:20,
|
|
labelFunc: function(val) {
|
|
return val;
|
|
}
|
|
},
|
|
xaxis: {
|
|
labelFunc: "seriesLabels",
|
|
maxLabelSize:30
|
|
},
|
|
scroll:false,
|
|
type: dojox.charting.plot2d.Columns
|
|
});
|
|
|
|
|
|
var dc = dojox.charting;
|
|
new dc.action2d.Highlight(chart, "default");
|
|
new dc.action2d.Tooltip(chart, "default");
|
|
|
|
chart.setStore(chartStore, {folder: "*"}, "count");
|
|
}
|
|
|
|
function formatMessage(item) {
|
|
return (singleFileStore || checkstyleStore).getValue(item, "msg");
|
|
}
|
|
|
|
function doEdit(item) {
|
|
var grid = dijit.byId("messagesGrid");
|
|
var textarea = dojo.byId("editInput");
|
|
|
|
var q = {folder: 0};
|
|
|
|
if (errorQuery) {
|
|
q.file = errorQuery.file;
|
|
}
|
|
|
|
grid.store.fetch({
|
|
query: q,
|
|
start: item.rowIndex,
|
|
count: 1,
|
|
onComplete: function(items) {
|
|
var file = grid.store.getValue(items[0], "file");
|
|
var line = grid.store.getValue(items[0], "line");
|
|
|
|
if (textarea._file != file) {
|
|
if (textarea._file) {
|
|
if(cachedFiles[textarea._file] && cachedFiles[textarea._file] != textarea.value) {
|
|
changedFiles.push(textarea._file);
|
|
}
|
|
cachedFiles[textarea._file] = textarea.value;
|
|
}
|
|
textarea._file = file;
|
|
if (cachedFiles[file]) {
|
|
textarea.value = cachedFiles[file];
|
|
}
|
|
else {
|
|
loadFile(file, line);
|
|
}
|
|
} else {
|
|
gotoLine(line);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function loadFile(file, line) {
|
|
var textarea = dojo.byId("editInput");
|
|
textarea.value = "Loading....";
|
|
dojo.xhrGet({
|
|
url: "../../" + file,
|
|
type: "text",
|
|
load: function(text) {
|
|
textarea.value = text;
|
|
dijit.byId("showFileErrorsBtn").attr("disabled", false);
|
|
gotoLine(line);
|
|
}
|
|
});
|
|
}
|
|
|
|
function gotoLine(line) {
|
|
var count = line;
|
|
var textarea = dojo.byId("editInput");
|
|
var str = textarea.value;
|
|
var i;
|
|
for (i = 0; i < str.length && count > 1; i++) {
|
|
if (str.charAt(i) == "\n") {
|
|
count--;
|
|
}
|
|
}
|
|
var nextNL = str.indexOf("\n", i + 1);
|
|
selectChars(textarea, i, nextNL < 0 ? str.length - 1 : nextNL);
|
|
}
|
|
|
|
function selectChars(textarea, start, end) {
|
|
|
|
if(textarea.setSelectionRange){
|
|
setTimeout(function(){
|
|
// textarea.focus();
|
|
textarea.setSelectionRange(start, start + 1);
|
|
var ev = document.createEvent("KeyEvents");
|
|
ev.initKeyEvent("keypress", true, true, window, false, false, false, false, 0,
|
|
textarea.value.charCodeAt(start));
|
|
textarea.dispatchEvent(ev);
|
|
textarea.setSelectionRange(start, end);
|
|
textarea.focus();
|
|
}, 10);
|
|
|
|
}else if(dojo.doc.selection){ //IE
|
|
|
|
var range = dojo.doc.selection.createRange();
|
|
// delete overflow characters
|
|
range.moveStart("character", start);
|
|
range.text = '';
|
|
// show cursor
|
|
range.select();
|
|
}
|
|
}
|
|
|
|
function showCurrentErrors(){
|
|
dijit.byId("showAllErrorsBtn").attr("checked", false);
|
|
dijit.byId("showFileErrorsBtn").attr("checked", true);
|
|
|
|
var textarea = dojo.byId("editInput");
|
|
var value = textarea.value;
|
|
checkstyleUtil.clear();
|
|
|
|
checkstyleUtil.applyRules(textarea._file, value);
|
|
var report = checkstyleUtil.generateReport(true);
|
|
var storeData = dojo.eval("(" + report + ")");
|
|
|
|
singleFileStore = new dojo.data.ItemFileReadStore({
|
|
data: storeData
|
|
});
|
|
|
|
var grid = dijit.byId("messagesGrid");
|
|
errorQuery = null;
|
|
grid.setStore(singleFileStore, {folder: 0}, grid.attr("queryOptions"));
|
|
}
|
|
|
|
function showAllErrors(query){
|
|
errorQuery = query;
|
|
|
|
dijit.byId("showFileErrorsBtn").attr("checked", false);
|
|
dijit.byId("showAllErrorsBtn").attr("checked", true);
|
|
var grid = dijit.byId("messagesGrid");
|
|
singleFileStore = null;
|
|
grid.setStore(checkstyleStore, query || grid.attr("query"), grid.attr("queryOptions"));
|
|
}
|
|
|
|
function makeSimpleFixes() {
|
|
var textarea = dojo.byId("editInput");
|
|
|
|
textarea.value = checkstyleUtil.makeSimpleFixes(textarea.value);
|
|
|
|
if(dojo.indexOf(changedFiles, textarea._file) < 0) {
|
|
changedFiles.push(textarea._file);
|
|
}
|
|
showCurrentErrors();
|
|
}
|
|
|
|
function saveFile(fileName, contents, callback) {
|
|
var textarea = dojo.byId("editInput");
|
|
fileName = fileName || textarea._file;
|
|
contents = contents || textarea.value;
|
|
|
|
dojo.xhrPost({
|
|
url: "checkstyle.php",
|
|
content: {
|
|
action: "save",
|
|
filename: fileName,
|
|
contents: contents
|
|
},
|
|
handle: function(text, reqObj){
|
|
if (reqObj.xhr.readyState != 4) {
|
|
return;
|
|
}
|
|
if (reqObj.xhr.status == 200) {
|
|
if (!callback) {
|
|
alert("File " + fileName + " saved");
|
|
} else {
|
|
callback(true);
|
|
}
|
|
var idx = dojo.indexOf(changedFiles, fileName);
|
|
array.splice(idx, 1);
|
|
}
|
|
else if (callback){
|
|
callback(false);
|
|
} else {
|
|
alert("Failed to save file " + fileName + ". " + saveErrorMsg);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function showSaveDialog(){
|
|
if (changedFiles.length == 0) {
|
|
alert("No files have been altered yet.");
|
|
return;
|
|
}
|
|
|
|
var checksNode = dojo.byId("checks");
|
|
dojo.empty(checksNode);
|
|
|
|
dojo.forEach(changedFiles, function(fileName){
|
|
dojo.create("div", {
|
|
innerHTML: "<label for='" + fileName + "'>" + fileName + "</label>"
|
|
+ "<input type='checkbox' id='" + fileName + "'></input>"
|
|
}, checksNode);
|
|
});
|
|
dijit.byId("changedFilesDlg").show();
|
|
}
|
|
|
|
function saveAllChangedFiles(){
|
|
var successes = 0;
|
|
var inputs = dojo.query("input", "checks").forEach(
|
|
function(input) {
|
|
if (!input.checked) {
|
|
return;
|
|
}
|
|
var fileName = dojo.attr(input, "id");
|
|
saveFile(fileName, cachedFiles[fileName], function(success){
|
|
if (!success) {
|
|
alert("Failed to save " + fileName
|
|
+ saveErrorMsg);
|
|
} else {
|
|
successes++;
|
|
if (successes == inputs.length) {
|
|
alert("All files saved successfully");
|
|
dijit.byId("changedFilesDlg").hide();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
);
|
|
}
|
|
|
|
var checkstyleStore;
|
|
|
|
dojo.xhrGet({
|
|
url: "checkstyleData.js",
|
|
sync: true,
|
|
handleAs: "json",
|
|
load: function(data) {
|
|
checkstyleStore = new dojo.data.ItemFileReadStore({
|
|
data: data
|
|
});
|
|
},
|
|
error: function(){
|
|
alert("Error: could not load the checkstyle data. You should run the checkstyle tool in util/checkstyle/");
|
|
}
|
|
});
|
|
</script>
|
|
</head>
|
|
<body class="soria">
|
|
|
|
<div dojoType="dijit.layout.BorderContainer" design="sidebar" id="main">
|
|
<div id="folders" dojoType="dijit.layout.ContentPane" region="leading"
|
|
style="width: 200px;padding: 0;" splitter="true">
|
|
<table dojoType="dojox.grid.DataGrid"id="folderGrid"
|
|
store="checkstyleStore" style="height: 100%; width: 100%;"
|
|
query="{ folder: 1 }" rowsPerPage="20" rowSelector="20px"
|
|
onCellClick="onFolderClick(arguments[0])"
|
|
>
|
|
<thead>
|
|
<tr>
|
|
<th field="file" width="auto">Folders</th>
|
|
</tr>
|
|
</thead>
|
|
</table>
|
|
</div>
|
|
<div id="header" dojoType="dijit.layout.ContentPane" region="top" style="height: 50px;">
|
|
<h1>Checkstyle results from <span id="reportDate"></span>
|
|
Total errors:<span id="totalErrors"></span>
|
|
</h1>
|
|
</div>
|
|
<div id="mainTab" dojoType="dijit.layout.TabContainer" region="center" style="padding: 0;">
|
|
<div id="errorsTab" dojoType="dijit.layout.BorderContainer" title="Error List" style="height:100%;width:100%;">
|
|
<table dojoType="dojox.grid.DataGrid" id="messagesGrid"
|
|
class="checkstyleGrid" store="checkstyleStore"
|
|
query="{ folder: 0 }" rowsPerPage="50" rowSelector="20px"
|
|
region="top"
|
|
style="height:50%;"
|
|
>
|
|
<script type="dojo/connect" event="_onFetchBegin" args="size, req">
|
|
dojo.byId("totalErrors").innerHTML = size;
|
|
</script>
|
|
<thead>
|
|
<tr>
|
|
<th field="file" width="300px">File</th>
|
|
<th field="line" width="40px">Line</th>
|
|
<th field="msg" width="auto" formatter="formatMessage">Message</th>
|
|
</tr>
|
|
</thead>
|
|
</table>
|
|
<div dojoType="dijit.layout.ContentPane" region="bottom" splitter="true" style="height:45%;">
|
|
<div>
|
|
<div dojoType="dijit.form.ToggleButton"
|
|
id="showFileErrorsBtn"
|
|
label="Show File Errors"
|
|
iconClass="dijitRadioIcon"
|
|
onclick="showCurrentErrors()"
|
|
disabled="true"
|
|
></div>
|
|
<div dojoType="dijit.form.ToggleButton"
|
|
id="showAllErrorsBtn"
|
|
label="Show All Errors"
|
|
iconClass="dijitRadioIcon"
|
|
checked="true"
|
|
onclick="showAllErrors()"></div>
|
|
<div dojoType="dijit.form.Button"
|
|
id="makeFixesBtn"
|
|
label="Make Fixes"
|
|
onclick="makeSimpleFixes()"></div>
|
|
<div dojoType="dijit.form.Button"
|
|
id="saveFileBtn"
|
|
label="Save"
|
|
onclick="saveFile()"></div>
|
|
<div dojoType="dijit.form.Button"
|
|
id="saveAllFileBtn"
|
|
label="Save All"
|
|
onclick="showSaveDialog()"></div>
|
|
</div>
|
|
<div>
|
|
<textarea id="editInput" rows="7" cols="100"></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="chartTab" dojoType="dijit.layout.BorderContainer" style="width:100%;height:100%;" title="Worst Modules">
|
|
<div dojoType="dijit.layout.ContentPane" region="top">
|
|
This chart displays the folders of depth 2 in descending order of checkstyle violations.
|
|
</div>
|
|
<div dojoType="dijit.layout.ContentPane" region="center">
|
|
<div id="chart" style="height:400px; width: 1000px;"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div dojoType="dijit.Dialog" id="changedFilesDlg" title="Save Changed Files">
|
|
<div id="checks">
|
|
|
|
</div>
|
|
<div dojoType="dijit.form.Button" label="Save" onclick="saveAllChangedFiles()"></div>
|
|
<div dojoType="dijit.form.Button" label="Cancel" onclick="dijit.byId('changedFilesDlg').hide();"></div>
|
|
</div>
|
|
</body>
|
|
</html>
|