diff --git a/README.md b/README.md index bf62c1f..709f80d 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ let audit = accessibility_rs::audit(&html, &css_rules, false); 2. Re-creating layout trees to get element positions. 3. Ideal shapes for audits that scale. 4. Amazingly fast audits. +5. Internationalization support for translations. ## Roadmap diff --git a/RULES.md b/RULES.md index 89416d5..ac4b307 100644 --- a/RULES.md +++ b/RULES.md @@ -6,13 +6,14 @@ List of techniques we want to have and whether we have it handled or not for WCA ### WCAGA -| Technique | Description | Type | Complete | -| -------------------------------------------------- | -------------------------------------------- | ----- | -------- | -| [H25](https://www.w3.org/TR/WCAG20-TECHS/H25.html) | empty titles | error | ✅ | -| [H32](https://www.w3.org/TR/WCAG20-TECHS/H32.html) | missing form submit button | error | ✅ | -| [H57](https://www.w3.org/TR/WCAG20-TECHS/H57.html) | html contains valid lang | error | ✅ | -| [F40](https://www.w3.org/TR/WCAG20-TECHS/F40.html) | using meta redirect with a time limit | error | ✅ | -| [F40](https://www.w3.org/TR/WCAG20-TECHS/F41.html) | due to using meta refresh to reload the page | error | ✅ | +| Technique | Description | Type | Complete | +| -------------------------------------------------- | ------------------------------------ | ----- | -------- | +| [H25](https://www.w3.org/TR/WCAG20-TECHS/H25.html) | empty titles | error | ✅ | +| [H32](https://www.w3.org/TR/WCAG20-TECHS/H32.html) | missing form submit button | error | ✅ | +| [H57](https://www.w3.org/TR/WCAG20-TECHS/H57.html) | html contains valid lang | error | ✅ | +| [F40](https://www.w3.org/TR/WCAG20-TECHS/F40.html) | meta redirect used with a time limit | error | ✅ | +| [F40](https://www.w3.org/TR/WCAG20-TECHS/F41.html) | meta refresh used to reload the page | error | ✅ | +| [F47](https://www.w3.org/TR/WCAG20-TECHS/F41.html) | blink element used for attention | error | ✅ | ### WCAGAA diff --git a/accessibility-rs/src/engine/rules/ids.rs b/accessibility-rs/src/engine/rules/ids.rs index ba74bda..485e1fe 100644 --- a/accessibility-rs/src/engine/rules/ids.rs +++ b/accessibility-rs/src/engine/rules/ids.rs @@ -14,6 +14,8 @@ pub enum Techniques { F40, /// F41, + /// + F47, } impl Techniques { @@ -29,7 +31,7 @@ impl Techniques { Techniques::H57 => vec!["H57.2", "H57.3.Lang", "H57.3.XmlLang"], Techniques::F40 => vec!["F40.2"], Techniques::F41 => vec!["F41.2"], - _ => vec![""], + Techniques::F47 => vec!["F47"], } } } diff --git a/accessibility-rs/src/engine/rules/wcag_base.rs b/accessibility-rs/src/engine/rules/wcag_base.rs index 69c59ea..2c7a050 100644 --- a/accessibility-rs/src/engine/rules/wcag_base.rs +++ b/accessibility-rs/src/engine/rules/wcag_base.rs @@ -52,7 +52,7 @@ pub enum Guideline { /// Make Web pages appear and operate in predictable ways. Predictable, /// Provide users enough time to read and use content. - EnoughTime + EnoughTime, } impl Guideline { diff --git a/accessibility-rs/src/engine/rules/wcag_rule_map.rs b/accessibility-rs/src/engine/rules/wcag_rule_map.rs index 7ea3173..8e95376 100644 --- a/accessibility-rs/src/engine/rules/wcag_rule_map.rs +++ b/accessibility-rs/src/engine/rules/wcag_rule_map.rs @@ -19,7 +19,6 @@ lazy_static! { (lang.chars().all(|x| x.is_alphanumeric()) && !lang.contains("_") && lang.len() < 12, "3.Lang", Default::default()) }), ])), - // empty titles ("meta", Vec::from([ Rule::new(Techniques::F40, Criteria::Error, Principle::Operable, Guideline::EnoughTime, |_rule, nodes| { let mut valid = true; @@ -54,7 +53,6 @@ lazy_static! { (valid, "2", Default::default()) }), ])), - // empty titles ("title", Vec::from([ Rule::new(Techniques::H25, Criteria::Error, Principle::Operable, Guideline::Navigable, |_rule, nodes| { (!nodes.is_empty(), "1.NoTitleEl", Default::default()) @@ -63,7 +61,11 @@ lazy_static! { (nodes.is_empty() || nodes[0].0.html().is_empty(), "1.EmptyTitle", Default::default()) }), ])), - // missing form submit + ("blink", Vec::from([ + Rule::new(Techniques::F47, Criteria::Error, Principle::Operable, Guideline::EnoughTime, |_rule, nodes| { + (nodes.is_empty(), "", Default::default()) + }), + ])), ("form", Vec::from([ Rule::new(Techniques::H32, Criteria::Error, Principle::Operable, Guideline::Predictable, |_rule, nodes| { // check the first element for now diff --git a/accessibility-rs/src/i18n/locales.rs b/accessibility-rs/src/i18n/locales.rs index b864196..3be636f 100644 --- a/accessibility-rs/src/i18n/locales.rs +++ b/accessibility-rs/src/i18n/locales.rs @@ -82,8 +82,12 @@ impl Messages { /// parse pub fn get_message(rule_id: &Techniques, section: &str, lang: &str) -> &'static str { - let k = &[rule_id.as_str(), section].join("."); - let message = LOCALES.get(&k.as_str()); + let rule_id = rule_id.as_str(); + let message = if section.is_empty() { + LOCALES.get(&rule_id) + } else { + LOCALES.get([rule_id, section].join(".").as_str()) + }; match message { Some(m) => match lang { @@ -107,6 +111,7 @@ lazy_static! { (Techniques::H57.pairs()[2], Messages::new(&"The language specified in the xml:lang attribute of the document element does not appear to be well-formed.", "", "")), (Techniques::F40.pairs()[0], Messages::new(&"Meta refresh tag used to redirect to another page, with a time limit that is not zero. Users cannot control this time limit.", "", "")), (Techniques::F41.pairs()[0], Messages::new(&"Meta refresh tag used to refresh the current page. Users cannot control the time limit for this refresh.", "", "")), + (Techniques::F47.pairs()[0], Messages::new(&"Blink elements cannot satisfy the requirement that blinking information can be stopped within five seconds.", "", "")), ]) }; } diff --git a/accessibility-rs/tests/unit/meta.rs b/accessibility-rs/tests/unit/meta.rs index 8b21ff0..9b971de 100644 --- a/accessibility-rs/tests/unit/meta.rs +++ b/accessibility-rs/tests/unit/meta.rs @@ -18,11 +18,11 @@ fn _audit_missing_headers() { assert_eq!(valid, false) } - #[test] /// meta refresh redirect fn _audit_meta_refresh() { - let audit = accessibility_rs::audit(r###" + let audit = accessibility_rs::audit( + r###" Do not use this! - "###, &"", false); + "###, + &"", + false, + ); let mut valid = true; for x in &audit { @@ -48,14 +51,18 @@ fn _audit_meta_refresh() { assert_eq!(valid, false); - let audit = accessibility_rs::audit(r###" + let audit = accessibility_rs::audit( + r###" HTML Techniques for WCAG 2.0 - "###, &"", false); + "###, + &"", + false, + ); let mut valid = true; for x in &audit { @@ -68,3 +75,29 @@ fn _audit_meta_refresh() { assert_eq!(valid, false); } +#[test] +/// no blink elements +fn _audit_blink_found() { + let audit = accessibility_rs::audit( + r###" + + Do not use this! + + +

My Great Product Sale! $44,995!

+ + "###, + &"", + false, + ); + let mut valid = true; + + for x in &audit { + if x.code == "WCAGAAA.Principle2.Guideline2_2.F47" { + valid = false; + break; + } + } + + assert_eq!(valid, false); +}