aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Trevor Elliott <trevor@galois.com>2013-07-15 15:26:00 -0700
committerGravatar Trevor Elliott <trevor@galois.com>2013-07-15 15:26:00 -0700
commitbca26d5a785f2c41d4d223ee049465b7be361154 (patch)
treeddeec68d4b377bebf644150d93b0e5bafc124477
parent2618fb0c74567b42ec238706132937f087f8fc06 (diff)
parent265f160e55d98b37aa8d8f9b16a1a5ccb32bdb0d (diff)
Merge remote-tracking branch 'origin/master' into new-ui
-rw-r--r--guidelines/WCAG-1.0/guideline-1.js27
-rw-r--r--guidelines/WCAG-1.0/guideline-2.js11
-rw-r--r--guidelines/WCAG-1.0/guideline-3.js57
-rw-r--r--guidelines/WCAG-1.0/guideline-5.js34
-rw-r--r--guidelines/WCAG-1.0/guideline-test.json6
-rw-r--r--guidelines/WCAG-1.0/test5.html40
6 files changed, 118 insertions, 57 deletions
diff --git a/guidelines/WCAG-1.0/guideline-1.js b/guidelines/WCAG-1.0/guideline-1.js
index 61e1384..ebbd823 100644
--- a/guidelines/WCAG-1.0/guideline-1.js
+++ b/guidelines/WCAG-1.0/guideline-1.js
@@ -3,7 +3,7 @@
*/
exports.name = "Equivalent Alternatives";
-exports.description = "";
+exports.description = "Web Accessibility Guideline: Provide equivalent alternatives to auditory and visual content";
exports.rule = function(report) {
@@ -11,21 +11,21 @@ exports.rule = function(report) {
/* Checkpoint 1.1 [Priority 1] **********************************************/
var hasAlt = function(ix) {
- // TODO: strip space from the alt attribute to prevent ' ' from passing
- // the test
- if(_.isEmpty($(this).attr('alt')) && _.isEmpty($(this).attr('longdesc'))) {
+ var alt = $.trim($(this).attr('alt'));
+ var longdesc = $.trim($(this).attr('longdesc'));
+ if(_.isEmpty(alt) && _.isEmpty(longdesc)) {
report.error('No alt/longdesc specified', this);
}
};
var hasText = function(ix) {
- // TODO: strip space from the text to prevent ' ' from passing the test
- if(_.isEmpty($(this).text())) {
+ if(_.isEmpty($.trim($(this).text()))) {
report.error('No text node', this);
}
};
// images with semantic meaning should have an alt attribute.
+ // TODO add a heuristic for detecting large images
$5('a').find('img')
.add($5('dl').find('img'))
.add($5('dd').find('img'))
@@ -40,8 +40,6 @@ exports.rule = function(report) {
// All `object` tags must have a text node
$5('object').each(hasText).each(hasAlt);
- // TODO: what's the best way to classify content that's `complex`?
-
// All `area` elements of an image map should have alt attributes. It's also a
// bit overzealous, as it looks at all maps, not just maps that are referenced
// from images.
@@ -62,23 +60,12 @@ exports.rule = function(report) {
// everything that the server does. It's more of a sanity check, that this
// has been thought of.
$5('img').filter('[ismap]').each(function(ix) {
- if(_.isEmpty($(this).attr('usemap'))) {
+ if(_.isEmpty($.trim($(this).attr('usemap')))) {
report.error('No usemap attribute to supplement a use of ismap', this);
}
});
- /* Checkpoint 1.3 [Priority 1] **********************************************/
-
- // TODO: Not really sure if this is something that we can check; the guideline
- // seems to be more of a subjective check.
-
-
- /* Checkpoint 1.4 [Priority 1] **********************************************/
-
- // TODO: Again, not sure if this is something we can check here.
-
-
/* Checkpoint 1.5 [Priority 3] **********************************************/
// Make sure that every link in an image map has a corresponding text link
diff --git a/guidelines/WCAG-1.0/guideline-2.js b/guidelines/WCAG-1.0/guideline-2.js
index 7dcf28d..206dd3e 100644
--- a/guidelines/WCAG-1.0/guideline-2.js
+++ b/guidelines/WCAG-1.0/guideline-2.js
@@ -1,13 +1,7 @@
-exports.name = "colorDifference";
-exports.description = "Elements should provide sufficient color difference";
+exports.name = "Color Difference";
+exports.description = "Web Accessibility Guideline: Don't rely on color alone";
exports.rule = function(report) {
- /* Checkpoint 2.1 ***********************************************************/
-
- // TODO: not sure about the best way to test that information isn't hidden
- // when colors go away.
-
-
/* Checkpoint 2.2 ***********************************************************/
var fc = fiveui.color;
@@ -30,7 +24,6 @@ exports.rule = function(report) {
return $this.children().length == 0 && $.trim($this.text()).length > 0;
})
.each(function (i) {
- // TODO take into account fg alpha values
var fg = fc.colorToRGB($(this).css('color'));
var bg = fc.findBGColor($(this));
if (fg && bg) {
diff --git a/guidelines/WCAG-1.0/guideline-3.js b/guidelines/WCAG-1.0/guideline-3.js
index 1be4354..0f6055b 100644
--- a/guidelines/WCAG-1.0/guideline-3.js
+++ b/guidelines/WCAG-1.0/guideline-3.js
@@ -1,20 +1,11 @@
-exports.name = 'W3C Guideline 3';
-exports.description = '';
+exports.name = 'Proper Markup and Stylesheets';
+exports.description = 'Web Accessibility Guideline: Use markup and style sheets and do so properly';
exports.rule = function(report) {
- /* Checkpoint 3.1 [Priority 2] **********************************************/
-
- // TODO: this seems pretty subjective, as you have to be able to understand
- // the intent of the content. The math example is tough, as you'd have to be
- // able to pick out a situation where text wasn't marked up, but was also
- // mathematical notation.
-
-
/* Checkpoint 3.2 [Priority 2] **********************************************/
// require that the document contains a dtd.
- // TODO: how should we apply this check to iframes and such?
if(!document.doctype) {
report.error('No doctype given for the document', null);
}
@@ -36,22 +27,36 @@ exports.rule = function(report) {
report.error('Use css instead of the font attribute for formatting', this);
});
- // TODO: there are other cases to handle here, not sure about the best path
- // forward.
-
-
- /* Checkpoint 3.4 [Priority 2] **********************************************/
-
- // TODO: not sure what the best way to select everything that's not
- // automatically positioned. Additionally, many fancy user interfaces will
- // use pixels when positioning content, which isn't necessarily wrong.
-
/* Checkpoint 3.5 [Priority 2] **********************************************/
- // TODO: what's the best way to select siblings that match a given pattern in
- // jquery? Essentially, we just want to match situations where h1 is followed
- // by something that's both a header, and not h2 (for example).
+ // header transitions which are not allowed
+ var avoids = [ ["H1", "H3"]
+ , ["H1", "H4"]
+ , ["H1", "H5"]
+ , ["H2", "H4"]
+ , ["H2", "H5"]
+ , ["H3", "H5"] ];
+
+ // return true if the value `p` is in `avoids`. underscore's
+ // _.contains doesn't work here because it compares array references
+ var badPair = function (p) {
+ return _.find(avoids, function (s) {
+ return s[0] == p[0] && s[1] == p[1];
+ });
+ };
+
+ // examine the sequence of headings in each <div> for
+ // proper order
+ $('div').each(function (i, elt) {
+ var hs = $(elt).find(':header');
+ var ts = $(hs).map(function () { return this.tagName; });
+ for (var j=0; j < hs.length-1; j++) {
+ if (badPair([ts[j], ts[j+1]])) {
+ report.error('Invalid use of headers ' + ts[j] + ' -> ' + ts[j+1], hs[j+1]);
+ }
+ }
+ });
/* Checkpoint 3.6 [Priority 2] **********************************************/
@@ -59,8 +64,4 @@ exports.rule = function(report) {
/* Checkpoint 3.7 [Priority 2] **********************************************/
- // TODO: is there any way that we can detect quotations that aren't inside of
- // a blockquote region?
-
-
};
diff --git a/guidelines/WCAG-1.0/guideline-5.js b/guidelines/WCAG-1.0/guideline-5.js
new file mode 100644
index 0000000..48feb49
--- /dev/null
+++ b/guidelines/WCAG-1.0/guideline-5.js
@@ -0,0 +1,34 @@
+exports.name = "WCAG 1.0 Guideline 5: Tables";
+exports.description = "Web Accessibility Guideline: Create tables that transform gracefully";
+exports.rule = function(report) {
+
+ /* Checkpoint 5.1 ***********************************************************
+ *
+ * For data tables, identify row and column headers.
+ */
+
+ $('table').each(function () {
+ if ($(this).find('th').length == 0) {
+ report.error('Table does not have column headers <TH>', this);
+ }
+ });
+
+
+ /* Checkpoint 5.5 ***********************************************************
+ *
+ * Provide summaries for tables.
+ */
+
+ $('table').each(function () {
+ var $cap = $(this).find('caption');
+ var title = $.trim($(this).attr('title'));
+ var sum = $.trim($(this).attr('summary'));
+ if ($cap.length == 0 && (title === undefined || title == '')) {
+ report.error('Table has no caption or title attribute', this);
+ }
+ if (sum === undefined || sum == '') {
+ report.error('Table has no summary attribute', this);
+ }
+ });
+
+};
diff --git a/guidelines/WCAG-1.0/guideline-test.json b/guidelines/WCAG-1.0/guideline-test.json
new file mode 100644
index 0000000..29bfaa3
--- /dev/null
+++ b/guidelines/WCAG-1.0/guideline-test.json
@@ -0,0 +1,6 @@
+{ "name": "guideline-test"
+, "description": "Test WCAG guidelines"
+, "license": "BSD3"
+, "rules":
+ [ "guideline-5.js" ]
+}
diff --git a/guidelines/WCAG-1.0/test5.html b/guidelines/WCAG-1.0/test5.html
new file mode 100644
index 0000000..8700531
--- /dev/null
+++ b/guidelines/WCAG-1.0/test5.html
@@ -0,0 +1,40 @@
+<html>
+ <head>
+ <title>Test 5</title>
+ <style type="txt/css">
+ table { border: 2px solid black; }
+ </style>
+ </head>
+ <body>
+
+ Hello World!
+
+ <!-- expect caption/title failure, summary failure, headers failure -->
+ <table>
+ <tbody>
+ <tr><td>A first row that's not a header</td><td>Another col</td></tr>
+ <tr><td>A first row that's not a header</td><td>Another col</td></tr>
+ </tbody></table>
+
+ Hello Wisconsin!
+
+ <!-- expect headers failure -->
+ <table title='some table' summary='summary of a table'>
+ <tbody>
+ <tr><td>WI</td> <td>A first row that's not a header</td><td>Another col</td></tr>
+ <tr><td>WI</td> <td>A first row that's not a header</td><td>Another col</td></tr>
+ </tbody></table>
+
+ Hello Oregon!
+
+ <!-- expect no failures-->
+ <table title='some table with headers' summary='summary of a table with headers'>
+ <caption>A mighty good table</caption>
+ <tbody>
+ <tr><th>State</th> <th>head 1</th> <th>head 2</th></tr>
+ <tr><td>OR</td> <td>A first row that's not a header</td> <td>Another col</td></tr>
+ <tr><td>OR</td> <td>A first row that's not a header</td> <td>Another col</td></tr>
+ </tbody></table>
+
+ <!-- expect 4 failures -->
+</body></html>