Accessibility Validation Rule Codification Requirements

From MemberWiki

Jump to: navigation, search

Contents

Introduction

This document describes the requirements for the structure of a validation rule and of a ruleset, a container for validation rules. A validation rule is applied to web content as understood by the W3C Web Content Accessibility Guidelines 2.0 (WCAG2) by tools such as the Functional Accessibility Evaluator (FAE) or dedicated commercial web validation application. Validation rules may be applied to a specific Document Object Model (DOM) node or to a set of DOM nodes after a document is loaded into a user agent, to the original source of the rendered document, or based upon HTTP messages sent between the client-side component of an application and that application's host. Validation rules may also be applied at run-time within the context of a user agent to evaluate dynamic content when specific events are fired or other dynamic state-changes occur to nodes or sets of nodes. It is beyond the scope of this document to describe how or when rules are processed and applied by a given tool. The aim is to describe a way of expressing validation rules that will enable them to be readily consumable by accessibility tool venders and open-sorce or third-party components and applications and that these rules will be reusable among their various applications.

Also, although this document focuses upon validation rules that are derive from WCAG 2.0 and, inparticular, the accessibility of web content as understood by that specification, the aim is to permit these requirements to determine the codification of other types of rules. For instance, these requirements might be useful in describing rule formats for specifying privacy and security policies of corporate web sites, a company's branding strategy and legal policies via logos, templates, and page layouts and disclaimers and notices, or rules that are derived from other open standards, including other accessibility standards.

Components of a Validation Rule

The following is a list of basic components of any validation rule that will be described by the group:

rule properties
the properties that distinguish the rule from other rules in the set of rules and that aid the processing application in organizing these rules or presenting violations of these rules. Such properties include a unique id for the rule within the context of a set of rules, a human-readable name for the rule, a localized message to be generated when the rule is violated, a severity level for the rule, or a URL that gives more information about the rule and how to satisfy it
rule context
the environment or scope within which a given validation rule is to be applied. Possible contexts are described below and include the entire document, a single HTML element within a DOM, or an event within the DOM.
rule logic
the actual test that evaluates an accessibility requirement against a given rule context and returns a result. A result is an object that incapsulates whether or not a given rule passed or failed, the violating DOM node(s), and other information for generating validation reports.

Notice that, while all of these aspects of a validation rule might be expressed declaratively in a markup language such as XML or in a procedural language like Java, the group has agreed that JavaScript Object literals are most suitable for codifying rules. (We cannot use | JavaScript Object Notation (JSON) because of the desire to express rule logic and other aspects of a rule as JavaScript functions.)

Rule Properties

The properties associated with a validation rule are meant to support three purposes in any given validation tool or rules engine:

  • authoring/editing rules: providing the user the ability to create their own rules or edit or remove existing rules
  • rules selection: providing the user the ability to select the rules that are active (or inactive) during validation processes
  • rule execution and reporting violations: providing the user the ability to execute rules and receive notification that a rule has failed and information about that rule and the nodes that failed to satisfy that rule. This information might be used to display the violation in a UI, log a record of the violation to a storage medium (e.g. log file or database), file a defect about the violation in a defect tracking system, etc.

The following table lists the proposed properties that are associated with a rule. For each property, the table shows the following:

  1. the name of the property
  2. the suggested JavaScript type for that property
  3. whether or not the property is required
  4. the default value of the property to be assumed by validation engines when no value is given for it and the property is not required; validation engines or tools that consume rules should warn the user about missing required properties and refuse to process or consume rules that lack these properties
  5. whether the property is to be determined by the rule logic object itself (rule) or by the rule object as it is defined by a requirement object within a ruleset (requirement)
  6. a description of the property
Name Type Required Default Source Description
id String Yes rule a unique token that can be used to pick out a particular rule from the collection of rules
label String No id rule a human-readable and localizable name or label for the rule, which should also probably be unique in the collection of rules
message String No null requirement a localizable description of the problem that is to be repaired when a rule fails
severity String Yes requirement a localizable token describing the impact to the application or content that results when failing this rule
priority String No null requirement a localizable token describing the priority of the impact
dependencies Array No null rule, requirement a list of ids of rules that must have been executed and have passed prior to this rule's execution
requirementUrl String No null requirement a relative or absolute URL at which the rule is defined and where more information about the rule and how to satisfy it is available
enable Boolean No true requirement whether or not the rule is active (i.e. to be executed in an appropriate context)
criterionNumber String No null requirement the identifying number, index, tag, or other distinguishing identifier within a given checklist, specification, or set of guidelines for the rule (e.g. "1.1.1" in WCAG20 or "1194.21d" of U.S. Section 508
criterionDesc String No null requirement localizable description as taken from the original set of guidelines that corresponds to the value of a given criterionNumber property
criterionLevel String No null requirement localizable compliance or stringency level as taken from the original set of guidelines that corresponds to the value of a given 'criterionNumber' property
context String, Function Yes rule context expression or function describing the criteria under which the rule is applicable (see below)
validateParams Object No null rule parameters specific to the validation function for this rule (see below)
validate Function Yes rule function incapsulating the logic for a given rule (see below)

Rule ids

Rule ids are 5-digit numeric values represented as strings in the rule object. Rule ids are assigned from a range of numeric values from 10000 through 99999. Furthermore, each actively contributing organization of this task force is assigned a range of ids according to the table below from which ids for new rules should be chosen. This enables each participating organization to keep track of its own contributions and the ids that are already in use and prevents rule ids from being reused and from having to determine available ids across organizations. New organizations who wish to contribute rules should send a message to the task force mailing list at accessibility@openajax.org to be assigned a range of rule id values to be associated with the rules they contribute.

Organization Rule Id Range
Deque Systems 10000 - 19999
IBM 20000 - 29999
Parasoft 30000 - 39999
University of Illinois 40000 - 49999

Rule ids should be used consistently throughout documents related to the work of this group and in the code repository in which rule objects and related code artifacts are maintained.

Rule Contexts

A 'rule context' is a JavaScript object that represents key features of the environment that are required to execute a given rule. This environment might include the document object, a single node or set of nodes, an element with a given attribute (possibly with a particular value), a dispatched event and its associated target and type, and related configuration or state information as well as other tool-dependent properties.

The purpose of the rule context is to make rule execution more efficient, permitting the evaluation or validation tool to invoke only those rules that are appropriate given the conditions or characteristics of the environment at hand. Rule contexts also minimize rewriting conditions under which rules are to be executed, thus decoupling the rule logic of a rule from its environment and encouraging good coding practices and code reuse.

The group has defined the following rule contexts:

document
the rule is to be applied at the document-level, requiring the context of the entire document to be successfully executed. Such rules would, for instance, include checks for unique element ids or for appropriate heading hierarchies.
frame/iframe
the rule applies to the content of a frame or iframe. (This may turn out to be collapsable into the document context.)
element
the rule applies to a DOM node with nodeType = ELEMENT_NODE regardless of attributes or event handlers. In HTML validations, for example, tags for element-oriented contexts might include 'img' or 'input', which would specify that rules with that tag only be executed in the context of elements with that tag name.
element with attribute (possibly with a specific value)
rule applies to an element with a particular attribute or set of attributes (e.g. elements with tabindex attribute ) or with attributes with a particular value (e.g. tabindex = -1).
element pattern
the rule applies to a set of elements with certain child/parent relationships (e.g. header nesting, fieldset/legend, list elements and widgets)
element text
the rule applies to the text nodes of a given element
browser or W3C DOM events
rules to be applied when a particular browser event (e.g. onfocus) or DOM event (DOMNodeInserted) is fired by the user agent.

In addition to the above contexts, two special 'exclusionary' context are defined:

exclusive of element
the rule applies to all but an element with a given node name. For example, in HTML, a rule might apply to all elements except <img> elements.
exclusive of attribute
the rule applies to all elements except to those with the specified attributes. For example, in HTML, a rule might apply to all elements except <img> elements that have an alt attribute.

Specifying Rule Contexts

Since we have defined several types of rule contexts, we need a notation for expressing those contexts somewhere in the rule or ruleset objects. The following proposed notation is used to specify rule contexts in a rule or ruleset. The item on the left is the rule context as defined above and the expression on the right represents the syntax for expressing that context. This expression is called a 'rule context expression', a predefined notation for expressing the rule contexts to be used in rule or ruleset objects to associate rule logic with the context in which that logic is to be executed.

In the following grammar, whitespace is optional and present only for readability. Any context expression parsing apparatus should ignore whitespace in places where it appears in the grammar:

contextExpr ::= document

   | frame
   | element ("|" element)*
   | element_attrs_present ("|" element_attrs_present)*
   | element_attrs_values ("|" element_attrs_values)*
   | element_hierarchy_pattern
   | events
   | exclusionary_context_expr
  1. document ::= "document"
  2. frame ::= "frame" | "iframe"
  3. element ::= elemName( "|" elemName)*
  4. element_attrs_present ::= elemName "[@" attrName "]"("[@" attrName "]")*
  5. element_attrs_values ::= elemName "[@" attrName op attrValue "]"("[@" attrName op attrValue "]")*
  6. exclusionary_context_expr ::= exclusionary_element_context | (exclusionary_attr_context (| exclusionary_attr_context)*
  7. exclusionary_element_context ::= "!(" element ")"
  8. exclusionary_attr_context ::= elemName "[!(@" attrName ("|@" attrName )* ")]"
  9. op ::= "==" | "!="
  10. events ::= eventType (| eventType)*
  11. element_hierarchy_pattern ::= >not yet defined>

Note: eventTypes are: DOMFocusIn, DOMMutation, DOMNodeInserted, DOMNodeDeleted, User

In this simple grammar, both 'elemName' and 'attrName' are qualified names as described in Namespaces in XML 1.0. The 'elemName' may also be the wildcard character '*' (which represents all elements with nodeType == ELEMENT_NODE). The identifier 'eventType' can be an event type taken from either the DOM Level 2 Events or HTML 4.01 specifications.

Some Examples

Following are some examples of context expressions that might be used in a rule object:

"document"
the ruleContext handed to the validate function must be the document object (i.e. window.document or window.content.document in FF)
"img"
the ruleContext handed to the validate function must be an <img> element
"img | input"
the ruleContext handed to the validate function must be either an <img> or <input> element
"*"
the ruleContext handed to the validate function can be any element (i.e. ruleContext.nodeType == Node.ELEMENT_NODE)
"img[@alt]"
the ruleContext handed to the validate function must be an <img> element with an alt attribute (which may be empty)
"img[@alt][@title]"
the ruleContext handed to the validate function must be an <img> element with both an alt and title attribute
"img[@alt=='foo']"
the ruleContext handed to the validate function must be an <img> element with an alt attribute with a value of exactly 'foo'
"img[@alt!='foo']"
the ruleContext handed to the validate function must be an <img> element with either a missing alt attribute or an alt attribute that does not have the value 'foo'
"*[@alt]"
the ruleContext handed to the validate function can be any element with an alt attribute
"!(img)"
the ruleContext handed to the validate function must not be an <img> element
"!(img | input)"
the ruleContext handed to the validate function must be neither an <img> nor <input> element
"img[!(@alt)]"
the ruleContext handed to the validate function must be an <img> element that does not have an alt attribute
"img[!(@alt | @title)]"
the ruleContext handed to the validate function must be an <img> element that has neither an alt nor a title attribute
"*[!(@alt)]"
the ruleContext handed to the validate function can be any element that does not have an alt attribute

Note that these examples could be combined using the disjunct operator '|' to form compound context expressions. However, exclusionary contexts may not be combined with non-exclusionary contexts.

Rule Logic

The rule logic for a given rule is always expressed as a JavaScript function and associated with the 'validate' property of the object representing a rule. The definition of this function is as follows:

validate : function (ruleContext)

where 'ruleContext' is one of the predetermined context objects discussed earlier (e.g. document object, particular element, etc.). The body of the function must contain standard JavaScript code to be executed upon the rule being invoked by a validation or rules engine responsible for consuming and processing the rule objects in a given ruleset. This code can include:

  1. standard variable declarations
  2. standard control-flow structures
  3. calls to other JavaScript functions
  4. references to predefined constants or variables

With regard to items (3) and (4), constants, variables, functions, and other JavaScript artifacts upon which the validate function depends must be found in modules that are loaded and interpreted by the same JavaScript engine responsible for processing rule and ruleset objects and in the same execution context as these objects. The mechanism for ensuring that all appropriate JavaScript modules are loaded and for the evaluation of such constants, variables, and functions is left to tool developers.

The object that contains the definition of the validate function must also contain the rule id as described earlier and any dependencies and a context expression. All other properties are optional or may be specified in the ruleset requirement that leverages this rule object. To mitigate confusion, this object, the rule object that incapsulates the actual rule logic, will be refered to as the rule logic object.

Predefined Constants for Rule Logic

The logic of some validation rules will depend upon parameters that are determined by the ruleset in which the rule is placed or by the native language of the content. The group will offer suggested values for such parameters but tool developers may expose ways to overwrite the properties or values of these parameters.

The 'validateParams' property of a rule logic object serves to define such parameters. The validateParams object is a JavaScript object, the keys of which are the names of the variables (i.e. the identifiers) to be referenced in the validate function for that rule. Each identifier/key is associated with an object that contains additional information about the parameter, including the only required property, its value.

For example, the range within which the length of an alt text attribute value might fall will likely depend upon the native language of the content being validated and by the specification embodied by a given ruleset. Hence, this range could be expressed as two parameters, 'min_alt_text_length' and 'max_alt_text_length'. A rule that wishes to utilize these parameters might look as follows:

{

   id : 'imgAltAttrLength',
   context : 'img',
   validateParams : {
       min_alt_text_length : {value:10, type:"integer"},
       max_alt_text_length : {value:150, type:"integer"}
   },
   validate : function (ruleContext) {
       var params = this.validateParams;

var length = ruleContext.alt.length ;

       var passed = length >= params.min_alt_text_length.value && length <= params.min_alt_text_length.value;
       :
   },
   :

}

Of course, the 'type' property is optional and many other properties could be defined, depending upon application requirements.

Returned Result

The validate function must return a JavaScript object of type OValidationResult with the following properties:

Name Type Required Description
result boolean Yes whether or not the rule was executed successfully; a result of 'true' means that the rule was executed successfully or that the criterion that the rule embodies was satisfied, a value of 'false' means that that criterion was not satisfied
nodes Array No the list of offending nodes, which may be empty or null if the rule was executed successfully (i.e. the 'result' property is 'true')
attrs Array No the list of offending node attributes, which may be empty or null if the rule was executed successfully (i.e. the 'result' property is 'true') or if the element had no attributes
textContent String No the offending text content of an element, which may be empty or null if the rule was executed successfully (i.e. the 'result' property is 'true') or if the element had no text nodes
msgArgs Array No a list of parameters for the resulting message, which will be null if the rule was executed successfully (i.e. the 'result' property is 'true')

Message arguments given in the 'msgArgs' property are used when a rule fails (i.e. its 'result' property is 'false') and additional information is necessary to complete the message reported to the user. The additional information is only available during execution time or once the rule is executed. The processing of message parameters and the tokens that indicate the placement and ordering of the values of these parameters is tool-dependent but it is expected that such tokens would appear in the localized strings indicated by the 'messageCode' property.

Rulesets

A ruleset is a collection of rules, usually meant to embody a specific set of guidelines, a policy, or set of compliance requirements. For example, a ruleset might represent the accessibility standards defined by | WCAG20 or the by | U.S. Section 508.

Rulesets have their own unique properties (discussed in the next section) and subgroups of rules called 'requirements'. A 'requirement' represents a colection of rules that corresponds to a given checklist item, guideline, or criterion within a standard, specification, or checklist. For instance, a requirement object could be defined for each of the success criteria of WCAG2 or for each item in U.S. Section 508. Requirement objects might also be defined with respect to different compliance levels within a given standard or with respect to some other grouping mechanism.

Attributes of a Ruleset

Rulesets can be defined in JSON and have the following properties:

Name Type Required Default Description
id String Yes a unique identifier that can be used to pick out a particular ruleset from the collection of rulesets
nameCode String Yes the ID of a localizable, human-readable name of or label for the ruleset
descriptionCode String No null a localizable, human-readable description for the ruleset
rulesetUrl String No null the URL defining the specification or guidelines embodied by this ruleset
baseReqUrl String No null the base URL for resolving any relative URLs given as the value of the 'requirementUrl' property of rule objects
requirements Array Yes an array of requirements objects as defined below

Requirements Objects

Each object in the requirements array has a set of common rule properties taken from the enumerated rule properties above. In addition, each requirements object has a 'rules' property, which maps a rule id to an object containing properties and values specific to that rule. (This is the ruleset.rule object identified in the rule properties table above.) All other properties for that rule are obtained from the requirements object or from the rule logic object (the object containing the definition of the validate function). Thus, the value of a given rule property can be obtained from the following sources, in the following order:

  1. the rule logic object itself in which the validate function is defined
  2. the rule object within the requirements object (ruleset.rule) that defines properties specific to a given rule
  3. the requirements object in which a rule is included

Note that the behavior for retrieving the value of a property for a particular rule that is included in multiple requirements objects without defining its own specific properties within its definition in the requirements object or within the rule logic object itself is undetermined.

For example, consider the following abbreviated WCAG2 ruleset definition:

{
 id : "WCAG_2_0",
 nameCode : "WCAG20.name",
 descriptionCode : "WCAG20.description",
 rulesetUrl : "http://www.w3.org/TR/WCAG20/",
 baseReqUrl : "http://www.w3.org/TR/WCAG20/",

 requirements : [
   {
   criterionNumber : '1.1.1',
   criterionLevel : 'WCAG20.level.A',
   criterionDesc : 'WCAG20.description.1_1_1',
   requirementUrl: '#text-equiv',
   rules : {
           'imgAltAttrMissing' : {severityCode:'level.violation', messageCode:'images.warnings.altmissing'},
           'imgAltAttrLength' : {severityCode:'level.potentialViolation', messageCode:'images.msg.altbadlen'},
          'imgAltLongdescInvalid' : {severityCode:'level.potentialViolation', messageCode:'images.msg.invalidLongdesc},
           'imgAltAttrEmptyTitleAttrPresent' : {severityCode:'level.recommendation', messageCode:'images.warnings.altother'},
}
   }, // 1.1.1

   {
   criterionNumber : '2.4.2',
   criterionLevel : 'WCAG20.level.A',
   criterionDesc : 'WCAG20.description.2_4_2',
   requirementUrl: '#navigation-mechanisms',
   rules : {
       'titleMissingOrEmpty' : {severityCode:'level.Violation', messageCode:'titles.warnings.missingOrEmptyTitle'},
       'titleMissingH1Words' : {severityCode:'level.PotentialViolation', messageCode:'titles.msg.titlemissingh1words'},
}
   }, // 2.4.2 

 {
   criterionNumber : '2.4.6',
   criterionLevel : 'WCAG20.level.AA',
   criterionDesc : 'WCAG20.description.2_4_6',
   requirementUrl: '#navigation-mechanisms',
   rules : {
       'headingTextMissing' : {severityCode:'level.Violation', messageCode:'headers.msg.emptyheader'},
       'headingTextLength' : {severityCode:'level.Recommendation', messageCode:'headers.msg.toolong'},
       'headingImproperNesting' : {severityCode:'level.Violation', messageCode:'headers.warnings.impropernesting'},
}
   }, // 2.4.6 

 ]
}

Here, we are defining three requirements objects corresponding to success criteria 1.1.1, 2.4.2, and 2.4.6 of WCAG2. Each requirements object contains several rules for verifying to what extent that criterion is met. Notice that, in each case, the criterionNumber, criterionDesc, and criterionLevel as well as the requirementUrl for the rule is defined within the requirements object but that the severity and messageCode are defined in the specific rule object as it is defined within that requirement. Thus, a rules engine looking for the value of the 'severity' attribute of the 'imgAltAttrMissing' rule would first look in the rule logic object, then in the requirements object corresponding to success criterion 1.1.1, and, finally, in the the specific rule object defined by a requirement to find the desired value.

Other groupings are possible. For instance, all of the level A success criteria could be placed into a single requirements object or all rules concerning only <img> elements could be placed in their own requirements object. (Keep in mind, however, that the latter scenario would be problematic given rule definitions from this group, as these definitions already contain context property values so that these would override any context property values in the requirements object.)

Rule Test Cases

When a rule is submitted to the task force in the format given above, the contributor is also responsible for submitting a test case for that rule. The test case is an HTML document that can demonstrate that the rule, when executed, returns a passing result on those nodes that satisfy the context of the rule and the rule logic and returns a failing result for those that satisfy the rule context but fail the rule logic. Thus, nodes that do not satisfy the rule context should be ignored.

TODO: Directory structure and naming convention for test cases in the repository

As part of the test case, authors should include a <script> element that specifies how the rule(s) being tested by this test case behaves with regard to this HTML document. This information is encoded in JSON using a rulesCoverage object that looks like the following:

<script language="JavaScript">
  //<![CDATA[
    var OpenAjax = OpenAjax || {} ;
    OpenAjax.a11y = OpenAjax.a11y || {} ;
    OpenAjax.a11y.ruleCoverage = [
{
      ruleId: "imgAltAttrWithForebiddenFileExt",
      failedXpaths: [
        "//img[@id='fail-one']",
        "//img[@id='fail-two']",
        "//img[@id='fail-three']",
        "//img[@id='fail-four']",
       "//img[@id='fail-five']"
      ],
      passedXpaths: [
        "//img[@id='pass-one']",
        "//img[@id='pass-two']",
        "//img[@id='pass-three']"
      ]
    },
    {
      ruleId: "imgAltAttrWithForebiddenWord",
      failedXpaths: [
        "//img[@id='fail-six']",
        "//img[@id='fail-seven']"
      ],
      passedXpaths: [
        "//img[@id='pass-one']",
        "//img[@id='pass-two']",
        "//img[@id='pass-three']"
    ]}] ;
  //]]>
</script>

The ruleCoverage object should be defined in the OpenAjax.a11y namespace for clarity and interoperability of tooling and is an array of objects. Each object in this array consists of three properties:

  1. a 'ruleId' that specifies the rule for which test results are being given
  2. the 'passedXpaths' property for identifying the nodes within this document by XPath that pass when the given rule is applied to them
  3. the 'failedXpaths' property for identifying the nodes within this document by XPath that fail when the given rule is applied to them

No test harness is maintained by this group at this time for verifying the correctness of the test case or of its validity with regard to the rule(s) that it purports to test.

Personal tools