Skip to content

Commit

Permalink
chore(locales): add translation extracting in rules map
Browse files Browse the repository at this point in the history
  • Loading branch information
j-mendez committed Oct 15, 2023
1 parent 9246f3f commit e5a5543
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 50 deletions.
2 changes: 1 addition & 1 deletion accessibility-rs/src/engine/audit/wcag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ impl WCAG3AA {
match rules {
Some(rules) => {
for rule in rules {
let validation = (rule.validate)(&node.0, &node.1);
let validation = (rule.validate)(&node.1, &auditor.locale);
let message = validation.message;

if !validation.valid {
Expand Down
8 changes: 4 additions & 4 deletions accessibility-rs/src/engine/rules/rule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub struct Validation {
/// elements that match the issue
pub elements: Vec<String>,
/// the message of the error
pub message: &'static str,
pub message: String,
}

impl Validation {
Expand All @@ -23,7 +23,7 @@ impl Validation {
valid: bool,
id: &'static str,
elements: Vec<String>,
message: &'static str,
message: String,
) -> Self {
Self {
valid,
Expand All @@ -50,7 +50,7 @@ pub struct Rule {
/// the type of rule
pub issue_type: IssueType,
/// validate a test returns (valid, rule, selectors)
pub validate: fn(&str, &Vec<(ElementRef<'_>, Option<DefaultKey>)>) -> Validation,
pub validate: fn(&Vec<(ElementRef<'_>, Option<DefaultKey>)>, &str) -> Validation,
/// the principle type
pub principle: Principle,
/// the guideline to follow
Expand All @@ -67,7 +67,7 @@ impl Rule {
principle: Principle,
guideline: Guideline,
success_criteria: &'static str,
validate: fn(&str, &Vec<(ElementRef<'_>, Option<DefaultKey>)>) -> Validation,
validate: fn(&Vec<(ElementRef<'_>, Option<DefaultKey>)>, &str) -> Validation,
) -> Rule {
Rule {
rule_id,
Expand Down
6 changes: 3 additions & 3 deletions accessibility-rs/src/engine/rules/utils/nodes.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::engine::rules::rule::Validation;
use crate::ElementRef;
use accessibility_scraper::{node, Selector};
use accessibility_scraper::Selector;
use selectors::Element;
use slotmap::DefaultKey;

Expand Down Expand Up @@ -44,7 +44,7 @@ pub fn is_empty(nodes: &ElementNodes) -> (bool, Vec<String>) {
/// elements empty with validation
pub fn validate_empty_nodes(nodes: &ElementNodes, id: &'static str) -> Validation {
let (valid, elements) = is_empty(&nodes);
Validation::new(valid, id, elements, "")
Validation::new(valid, id, elements, Default::default())
}

/// check if the selector only exist for one element
Expand Down Expand Up @@ -143,5 +143,5 @@ pub fn validate_missing_attr(
}
});

Validation::new(valid, id, elements, "")
Validation::new(valid, id, elements, Default::default())
}
66 changes: 34 additions & 32 deletions accessibility-rs/src/engine/rules/wcag_rule_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::engine::rules::utils::nodes::{
get_unique_selector, has_alt, validate_empty_nodes, validate_missing_attr,
};
use crate::engine::rules::wcag_base::{Guideline, IssueType, Principle};
use crate::i18n::locales::get_message_i18n_str_raw;
use accessibility_scraper::{ElementRef, Selector};
use selectors::Element;
use std::collections::BTreeMap;
Expand All @@ -16,11 +17,11 @@ lazy_static! {
pub static ref RULES_A: BTreeMap<&'static str, Vec<Rule>> =
vec![
("html", Vec::from([
Rule::new(Techniques::H57, IssueType::Error, Principle::Understandable, Guideline::Readable, "1", |_rule, nodes| {
Rule::new(Techniques::H57, IssueType::Error, Principle::Understandable, Guideline::Readable, "1", |nodes, _lang| {
let n = nodes[0].0;
Validation::new_issue(!n.attr("lang").unwrap_or_default().is_empty() || !n.attr("xml:lang").unwrap_or_default().is_empty(), "2")
}),
Rule::new(Techniques::H57, IssueType::Error, Principle::Understandable, Guideline::Readable, "1", |_rule, nodes| {
Rule::new(Techniques::H57, IssueType::Error, Principle::Understandable, Guideline::Readable, "1", |nodes, _lang| {
let lang = nodes[0].0.attr("lang").unwrap_or_default();
let alphabetic = lang.chars().all(|x| x.is_alphabetic());
// <https://www.rfc-editor.org/rfc/bcp/bcp47.txt>
Expand All @@ -32,7 +33,7 @@ lazy_static! {
alphabetic && lang.len() < 12
}, "3.Lang")
}),
Rule::new(Techniques::H57, IssueType::Error, Principle::Understandable, Guideline::Readable, "1", |_rule, nodes| {
Rule::new(Techniques::H57, IssueType::Error, Principle::Understandable, Guideline::Readable, "1", |nodes, _lang| {
let lang = nodes[0].0.attr("xml:lang").unwrap_or_default();
let alphabetic = lang.chars().all(|x| x == '_' || x.is_alphabetic());
// <https://www.rfc-editor.org/rfc/bcp/bcp47.txt>
Expand All @@ -44,7 +45,7 @@ lazy_static! {
alphabetic && lang.len() < 12
}, "3.XmlLang")
}),
Rule::new(Techniques::F77, IssueType::Error, Principle::Robust, Guideline::Compatible, "1", |_rule, nodes| {
Rule::new(Techniques::F77, IssueType::Error, Principle::Robust, Guideline::Compatible, "1", |nodes, lang| {
let mut id_map: HashMap<&str, u8> = HashMap::new();
let mut valid = true;

Expand Down Expand Up @@ -77,15 +78,16 @@ lazy_static! {
}
}

let duplicate_ids = id_map.into_iter().filter_map(|(id, size)| if size >= 1 { Some(id.to_string()) } else { None }).collect();
let duplicate_ids: Vec<_> = id_map.into_iter().filter_map(|(id, size)| if size >= 1 { Some(id.to_string()) } else { None }).collect();
let message = t!(&get_message_i18n_str_raw( &Guideline::Compatible, Techniques::F77.as_str(), "1", ""), locale = lang, id = duplicate_ids.join(","));

// let message = t!(&crate::i18n::locales::get_message_i18n_str(_rule, ""));
println!("{:?}", message);

Validation::new(valid, "", duplicate_ids, "")
Validation::new(valid, "", duplicate_ids, message)
}),
])),
("meta", Vec::from([
Rule::new(Techniques::F40, IssueType::Error, Principle::Operable, Guideline::EnoughTime, "1", |_rule, nodes| {
Rule::new(Techniques::F40, IssueType::Error, Principle::Operable, Guideline::EnoughTime, "1", |nodes, _lang| {
let mut valid = true;

for node in nodes {
Expand All @@ -101,7 +103,7 @@ lazy_static! {

Validation::new_issue(valid, "2")
}),
Rule::new(Techniques::F41, IssueType::Error, Principle::Understandable, Guideline::EnoughTime, "1", |_rule, nodes| {
Rule::new(Techniques::F41, IssueType::Error, Principle::Understandable, Guideline::EnoughTime, "1", |nodes, _lang| {
let mut valid = true;

for node in nodes {
Expand All @@ -119,30 +121,30 @@ lazy_static! {
}),
])),
("title", Vec::from([
Rule::new(Techniques::H25, IssueType::Error, Principle::Operable, Guideline::Navigable, "1", |_rule, nodes| {
Rule::new(Techniques::H25, IssueType::Error, Principle::Operable, Guideline::Navigable, "1", |nodes, _lang| {
Validation::new_issue(!nodes.is_empty(), "1.NoTitleEl")
}),
Rule::new(Techniques::H25, IssueType::Error, Principle::Operable, Guideline::Navigable, "1", |_rule, nodes| {
Rule::new(Techniques::H25, IssueType::Error, Principle::Operable, Guideline::Navigable, "1", |nodes, _lang| {
Validation::new_issue(nodes.is_empty() || nodes[0].0.html().is_empty(), "1.EmptyTitle")
}),
])),
("blink", Vec::from([
Rule::new(Techniques::F47, IssueType::Error, Principle::Operable, Guideline::EnoughTime, "2", |_rule, nodes| {
Rule::new(Techniques::F47, IssueType::Error, Principle::Operable, Guideline::EnoughTime, "2", |nodes, _lang| {
Validation::new_issue(nodes.is_empty(), "")
}),
])),
("iframe", Vec::from([
Rule::new(Techniques::H64, IssueType::Error, Principle::Operable, Guideline::Navigable, "1", |_rule, nodes| {
Rule::new(Techniques::H64, IssueType::Error, Principle::Operable, Guideline::Navigable, "1", |nodes, _lang| {
validate_missing_attr(nodes, "title", "1")
}),
])),
("frame", Vec::from([
Rule::new(Techniques::H64, IssueType::Error, Principle::Operable, Guideline::Navigable, "1", |_rule, nodes| {
Rule::new(Techniques::H64, IssueType::Error, Principle::Operable, Guideline::Navigable, "1", |nodes, _lang| {
validate_missing_attr(nodes, "title", "1")
}),
])),
("form", Vec::from([
Rule::new(Techniques::H32, IssueType::Error, Principle::Operable, Guideline::Predictable, "2", |_rule, nodes| {
Rule::new(Techniques::H32, IssueType::Error, Principle::Operable, Guideline::Predictable, "2", |nodes, _lang| {
let mut valid = false;
let mut elements = Vec::new();
let selector = unsafe { Selector::parse("button[type=submit]").unwrap_unchecked() };
Expand All @@ -160,9 +162,9 @@ lazy_static! {
}
}

Validation::new(valid, "2", elements, "")
Validation::new(valid, "2", elements, Default::default())
}),
Rule::new(Techniques::H36, IssueType::Error, Principle::Perceivable, Guideline::TextAlternatives, "1", |_rule, nodes| {
Rule::new(Techniques::H36, IssueType::Error, Principle::Perceivable, Guideline::TextAlternatives, "1", |nodes, _lang| {
let mut valid = false;
let mut elements = Vec::new();
let selector = unsafe { Selector::parse("input[type=image][name=submit]").unwrap_unchecked() };
Expand All @@ -180,11 +182,11 @@ lazy_static! {
}
}

Validation::new(valid, "", elements, "")
Validation::new(valid, "", elements, Default::default())
}),
])),
("a", Vec::from([
Rule::new(Techniques::H30, IssueType::Error, Principle::Perceivable, Guideline::TextAlternatives, "1", |_rule, nodes| {
Rule::new(Techniques::H30, IssueType::Error, Principle::Perceivable, Guideline::TextAlternatives, "1", |nodes, _lang| {
let mut valid = true;
let selector = unsafe { Selector::parse("img").unwrap_unchecked() };
let mut elements = Vec::new();
Expand All @@ -202,9 +204,9 @@ lazy_static! {
}
}

Validation::new(valid, "2", elements, "")
Validation::new(valid, "2", elements, Default::default())
}),
Rule::new(Techniques::H91, IssueType::Error, Principle::Robust, Guideline::Compatible, "2", |_rule, nodes| {
Rule::new(Techniques::H91, IssueType::Error, Principle::Robust, Guideline::Compatible, "2", |nodes, _lang| {
let mut valid = true;
let mut elements = Vec::new();

Expand All @@ -221,9 +223,9 @@ lazy_static! {
_ => ()
}
}
Validation::new(valid, "A.NoContent", elements, "")
Validation::new(valid, "A.NoContent", elements, Default::default())
}),
Rule::new(Techniques::H91, IssueType::Error, Principle::Robust, Guideline::Compatible, "2", |_rule, nodes| {
Rule::new(Techniques::H91, IssueType::Error, Principle::Robust, Guideline::Compatible, "2", |nodes, _lang| {
let mut valid = true;
let mut elements = Vec::new();
for ele in nodes {
Expand All @@ -234,11 +236,11 @@ lazy_static! {
}
valid = v;
}
Validation::new(valid, "A.EmptyNoId", elements, "")
Validation::new(valid, "A.EmptyNoId", elements, Default::default())
}),
])),
("img", Vec::from([
Rule::new(Techniques::H37, IssueType::Error, Principle::Perceivable, Guideline::TextAlternatives, "1", |_rule, nodes| {
Rule::new(Techniques::H37, IssueType::Error, Principle::Perceivable, Guideline::TextAlternatives, "1", |nodes, _lang| {
let mut valid = true;
let mut elements = Vec::new();

Expand All @@ -251,36 +253,36 @@ lazy_static! {
valid = alt;
}

Validation::new(valid, "", elements, "")
Validation::new(valid, "", elements, Default::default())
}),
])),
("h1", Vec::from([
Rule::new(Techniques::H42, IssueType::Error, Principle::Perceivable, Guideline::Adaptable, "1", |_rule, nodes| {
Rule::new(Techniques::H42, IssueType::Error, Principle::Perceivable, Guideline::Adaptable, "1", |nodes, _lang| {
validate_empty_nodes(nodes, "2")
}),
])),
("h2", Vec::from([
Rule::new(Techniques::H42, IssueType::Error, Principle::Perceivable, Guideline::Adaptable, "1", |_rule, nodes| {
Rule::new(Techniques::H42, IssueType::Error, Principle::Perceivable, Guideline::Adaptable, "1", |nodes, _lang| {
validate_empty_nodes(nodes, "2")
}),
])),
("h3", Vec::from([
Rule::new(Techniques::H42, IssueType::Error, Principle::Perceivable, Guideline::Adaptable, "1", |_rule, nodes| {
Rule::new(Techniques::H42, IssueType::Error, Principle::Perceivable, Guideline::Adaptable, "1", |nodes, _lang| {
validate_empty_nodes(nodes, "2")
}),
])),
("h4", Vec::from([
Rule::new(Techniques::H42, IssueType::Error, Principle::Perceivable, Guideline::Adaptable, "1", |_rule, nodes| {
Rule::new(Techniques::H42, IssueType::Error, Principle::Perceivable, Guideline::Adaptable, "1", |nodes, _lang| {
validate_empty_nodes(nodes, "2")
}),
])),
("h5", Vec::from([
Rule::new(Techniques::H42, IssueType::Error, Principle::Perceivable, Guideline::Adaptable, "1", |_rule, nodes| {
Rule::new(Techniques::H42, IssueType::Error, Principle::Perceivable, Guideline::Adaptable, "1", |nodes, _lang| {
validate_empty_nodes(nodes, "2")
}),
])),
("h6", Vec::from([
Rule::new(Techniques::H42, IssueType::Error, Principle::Perceivable, Guideline::Adaptable, "1", |_rule, nodes| {
Rule::new(Techniques::H42, IssueType::Error, Principle::Perceivable, Guideline::Adaptable, "1", |nodes, _lang| {
validate_empty_nodes(nodes, "2")
}),
])),
Expand Down
22 changes: 12 additions & 10 deletions accessibility-rs/src/i18n/locales.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::engine::rules::rule::Rule;
use crate::engine::rules::{rule::Rule, wcag_base::Guideline};

type M = &'static str;

Expand Down Expand Up @@ -63,21 +63,23 @@ impl Langs {
}
}

/// get message config type
pub fn get_message_i18n_str(rule: &Rule, section: &str) -> String {
// todo: add criteria handling fix
let base = [rule.guideline.as_index(), rule.success_criteria].join("_") + "_";
/// get message config type raw
pub fn get_message_i18n_str_raw(guideline: &Guideline, rule_id: &str, success_criteria: &str, section: &str) -> String {
let base = [guideline.as_index(), success_criteria].join("_") + "_";
let message = if section.is_empty() {
[rule.rule_id.as_str()].join(".").to_string()
[rule_id].join(".").to_string()
} else {
[rule.rule_id.as_str(), section].join(".").to_string()
[rule_id, section].join(".").to_string()
};
let message = [base.as_str(), message.as_str()].join("").to_string();

message
[base.as_str(), message.as_str()].join("").to_string()
}

/// get message config type
pub fn get_message_i18n_str(rule: &Rule, section: &str) -> String {
get_message_i18n_str_raw(&rule.guideline, rule.rule_id.as_str(), rule.success_criteria, section)
}

/// get message
pub fn get_message_i18n(rule: &Rule, section: &str, lang: &str) -> String {
let message = get_message_i18n_str(rule, section);

Expand Down
1 change: 1 addition & 0 deletions accessibility-rs/tests/unit/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ fn _audit_duplicate_element_id() {
let mut valid = true;

for x in &audit {
println!("{:?}", x);
if x.code == "WCAGAAA.Principle4.Guideline4_1.F77" {
valid = false;
break;
Expand Down

0 comments on commit e5a5543

Please sign in to comment.