Skip to content

Commit

Permalink
fix(report): report looks ok even if javascript is disabled
Browse files Browse the repository at this point in the history
All violations are listed in the raw HTML, and if you have JS, you can use filtering and sorting. This results in some duplication of code for populating the table (happens in the report generation as well as in the report's own javascript).

The tabs and a few other stylistic aspects are disabled unless js is present.

Closes #119
  • Loading branch information
marisademeglio committed Dec 29, 2017
1 parent 57b05d9 commit ac945f2
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 44 deletions.
54 changes: 45 additions & 9 deletions packages/ace-report/src/generate-html-report.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ module.exports = function generateHtmlReport(reportData) {
var flatListOfViolations = createFlatListOfViolations(reportData.assertions);
var violationStats = collectViolationStats(flatListOfViolations);
var violationFilters = createViolationFilters(flatListOfViolations);
var rulesetTagLabels = {
'wcag2a': 'WCAG 2.0 A',
'wcag2aa': 'WCAG 2.0 AA',
'EPUB': 'EPUB',
'best-practice': 'Best Practice',
'other': 'Other'
};

// return 5 data cells for each ruleset: critical, serious, moderate, minor, total
// a ruleset can be "wcag2a", "wcag2aa", "EPUB", "other", or "total" (all rulesets)
Expand All @@ -27,13 +34,6 @@ module.exports = function generateHtmlReport(reportData) {
// return a list of <option> elements containing the possible filters for given rule
handlebars.registerHelper('violation_filter', function(rule, options) {
var filterOptions = "";
var rulesetTagLabels = {
'wcag2a': 'WCAG 2.0 A',
'wcag2aa': 'WCAG 2.0 AA',
'EPUB': 'EPUB',
'best-practice': 'Best Practice',
'other': 'Other'
};
violationFilters[rule].forEach(function(value) {
// use nicer labels for ruleset options
if (rule == "ruleset") {
Expand All @@ -47,10 +47,46 @@ module.exports = function generateHtmlReport(reportData) {
});

// return a stringified json object representing a flat list of violations
handlebars.registerHelper('violations', function(options) {
handlebars.registerHelper('violationsJson', function(options) {
return new handlebars.SafeString(JSON.stringify(flatListOfViolations) + ";")
});

handlebars.registerHelper('violationRows', function(options) {
var htmlStr = '';
flatListOfViolations.forEach(function(violation) {
htmlStr += `<tr>
<td><span class='${violation['impact']}'>${violation['impact']}</span></td>
<td><span class='ruleset'>${rulesetTagLabels[violation['applicableRulesetTag']]}</span></td>
<td><em>\"${violation['fileTitle']}\"<br/><br/><code class='location'>${violation['location']}</code>`;

if (violation.html) {
htmlStr +=`<br/><br/><div class='snippet'>Snippet:<code>${violation.html.trim()}</code></div>`;
}

htmlStr += "</td>";
htmlStr += `<td>${violation['rule']}<br/><br/><span class='engine'>${violation['engine']}</span></td>`;

var desc = violation["desc"];
desc = desc.replace("Fix all of the following:", "");
desc = desc.replace("Fix any of the following:", "");

var detailsArr = desc.split("\n");
var listStr = '';
detailsArr.forEach(function(item) {
if (item != "") {
listStr += `<li>${item}</li>`;
}
});

htmlStr += `<td class='details'>
<ul>${listStr}</ul>
<p><a href='${violation['kburl']}' target='_blank'>Learn more about ${violation['kbtitle']}</a></p>
</td>`;

htmlStr += "</tr>";
});
return new handlebars.SafeString(htmlStr);
});

const content = fs.readFileSync(path.join(__dirname, "./resources/report-template.handlebars")).toString();
var template = handlebars.compile(content);
Expand Down Expand Up @@ -144,7 +180,7 @@ function createFlatListOfViolations(violations) {
"kburl": item["earl:test"]["help"]["url"],
"kbtitle": item["earl:test"]["help"]["title"],
"rule": item["earl:test"]["dct:title"],
"desc": item["earl:result"]["dct:description"],
"desc": escape(item["earl:result"]["dct:description"]),
"pointer": item["earl:result"]["earl:pointer"],
"impact": item["earl:test"]["earl:impact"],
"location": filename,
Expand Down
93 changes: 58 additions & 35 deletions packages/ace-report/src/resources/report-template.handlebars
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
.tab-content {
margin-top: 2em;
}
.tab-content h2 {
margin-bottom: 1em;
}
table th {
width: auto !important;
Expand All @@ -39,8 +36,21 @@
.tab-pane{
margin-top: 1.5em;
margin-left: 1em;
margin-bottom: 2em; /* useful for javascriptless (tab-less) linear display mode */
}
.pagenav {
font-style: italic;
font-size: small;
margin-top: 1em;
}
.sectionnav {
font-style: italic;
font-size: small;
margin-top: 1em;
margin-bottom: 2em;
}
/* metadata */
#metadata-table tr td:first-child {
font-family: 'Courier New';
Expand All @@ -57,7 +67,7 @@
content: "";
}
#a11y-metadata {
margin-top: 2em;
margin-top: 1em;
}
/* TOC outline */
Expand Down Expand Up @@ -161,7 +171,9 @@
#message {
margin-left: 1em;
}
#violations-table_wrapper {
padding-left: 0 !important;
}
</style>

Expand All @@ -170,6 +182,10 @@
<body>

<header>
<noscript>
<div class="alert alert-info">Please enable javascript for best performance.</div>
</noscript>

<h1>EPUB Accessibility Report</h1>
<p class="font-italic">Generated by
{{earl:assertedBy.doap:name}}
Expand All @@ -181,7 +197,7 @@
</header>

<nav>
<ul class="nav nav-tabs" id="navlist" role="tablist">
<ul id="navlist" role="tablist">
<li class="nav-item"><a class="nav-link active" data-toggle="list" href="#violations" role="tab" aria-controls="Violations" id="nav-violations">Violations</a></li>
<li class="nav-item"><a class="nav-link" data-toggle="list" href="#metadata" role="tab" aria-controls="Metadata" id="nav-metadata">Metadata</a></li>
<li class="nav-item"><a class="nav-link" data-toggle="list" href="#outlines" role="tab" aria-controls="Outlines" id="nav-outlines">Outlines</a></li>
Expand All @@ -194,10 +210,11 @@
<div class="tab-content">

<!-- VIOLATIONS TAB -->
<div class="tab-pane active" id="violations" role="tabpanel">
<p class="font-italic">Jump to <a href="#summary_of_violations">Summary of Violations</a> | <a href="#violations">All Violations</a> </p>
<div id="violations" role="tabpanel">
<h2>Violations</h2>
<p class="sectionnav">Go to <a href="#summary_of_violations">Summary of Violations</a> | <a href="#violations">All Violations</a> </p>

<h2 id="summary_of_violations">Summary of violations</h2>
<h3 id="summary_of_violations">Summary of violations</h3>
<table id="violations-summary-stats-table" class="table table-striped">
<caption>Violation count, by ruleset and severity.</caption>
<thead class="thead-inverse">
Expand Down Expand Up @@ -238,9 +255,9 @@
</tbody>
</table>

<h2 id="violations">All Violations</h2>
<h3 id="violations">All Violations</h3>

<div id="filters" class="py-3">
<div id="filters" class="d-none py-4">
<span class="filter-label">impact</span>
<select name="impact" aria-label="impact">
<option value="all" selected>All</option>
Expand Down Expand Up @@ -276,16 +293,18 @@
</tr>
</thead>
<tbody>
{{#violationRows}}{{/violationRows}}
</tbody>
</table>

<p class="pagenav">Go to <a href="#violations">Top of section</a> | <a href="#navlist">Page navigation</a></p>
</div>

<!-- METADATA TAB -->
<div class="tab-pane" id="metadata" role="tabpanel">
<div id="metadata" role="tabpanel">
<h2>Metadata</h2>

<p class="font-italic">Jump to <a href="#all-metadata">All Metadata</a> | <a href="#a11y-metadata">Accessibility Metadata</a> </p>
<p class="sectionnav">Go to <a href="#all-metadata">All Metadata</a> | <a href="#a11y-metadata">Accessibility Metadata</a> </p>

<h3 id="all-metadata">All Metadata</h3>
<table id="metadata-table" class="table table-bordered">
Expand Down Expand Up @@ -339,13 +358,13 @@
</p>
{{/if}}
{{/if}}

<p class="pagenav">Go to <a href="#metadata">Top of section</a> | <a href="#navlist">Page navigation</a></p>
</div>

<!-- OUTLINES TAB -->
<div class="tab-pane" id="outlines" role="tabpanel">
<div id="outlines" role="tabpanel">
<h2>Outlines</h2>
<p class="font-italic">Jump to <a href="#toc-outline">TOC Outline</a> | <a href="#headings-outline">Headings Outline</a> | <a href="#html-outline">HTML Outline</a> </p>
<p class="sectionnav">Go to <a href="#toc-outline">TOC Outline</a> | <a href="#headings-outline">Headings Outline</a> | <a href="#html-outline">HTML Outline</a> </p>

<div class="row">

Expand All @@ -364,10 +383,11 @@
{{{outlines.html}}}
</div>
</div>
<p class="pagenav">Go to <a href="#outlines">Top of section</a> | <a href="#navlist">Page navigation</a></p>
</div>

<!-- IMAGES TAB -->
<div class="tab-pane" id="images" role="tabpanel">
<div id="images" role="tabpanel">
<h2>Images</h2>
{{#if data.images}}
<table id="image-table" class="table table-striped table-bordered">
Expand Down Expand Up @@ -418,22 +438,25 @@
{{else}}
<p>No images found in this publication.</p>
{{/if}}
<p class="pagenav">Go to <a href="#images">Top of section</a> | <a href="#navlist">Page navigation</a></p>
</div>

</div> <!-- end div for tabs' contents -->


<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.15/js/dataTables.bootstrap4.min.js"></script>


<script type="text/javascript">
// keep a flat list of the violations in memory for table filtering
var violations = {{#violations}}{{/violations}}
var violations = {{#violationsJson}}{{/violationsJson}}
function updateTableContents(violationSubset, isFiltered) {
// update the contents of the table to reflec the filtering
function updateTableContents(violationSubset) {
// anything else is 'other'
var rulesetTagLabels = {
'wcag2a': 'WCAG 2.0 A',
Expand All @@ -444,21 +467,10 @@
};
$('#violations-table').dataTable().fnDestroy();
$("#message").remove();
if (violationSubset.length == 0) {
$("#message").remove();
var div = $("#violations");
if (isFiltered) {
div.append("<p id='message'>No matching violations found.</p>");
}
else {
div.append("<p id='message'>No violations found in this publication.</p>");
}
$("<p id='message'>No matching violations found.</p>").insertBefore("#violations .pagenav");
$("#violations-table").hide();
// we only want to remove the filters if there are no violations whatsoever
if (!isFiltered) {
$("#filters").hide();
}
return;
}
Expand Down Expand Up @@ -555,10 +567,21 @@
filterSelected();
}
// certain classes need to be added to elements if we're using javascript in the browser
function prepareForJS() {
$('#filters').removeClass('d-none');
$('#navlist').addClass('nav-tabs nav');
$('#violations').addClass('tab-pane active');
$('#metadata').addClass('tab-pane');
$('#outlines').addClass('tab-pane');
$('#images').addClass('tab-pane');
}
$(document).ready(function() {
prepareForJS();
$('#metadata-table').DataTable();
updateTableContents(violations, false);
$('select').change(filterSelected);
//updateTableContents(violations, false);
$('#violations-table').DataTable();
$('#filters > select').change(filterSelected);
});
</script>
Expand Down

0 comments on commit ac945f2

Please sign in to comment.