Skip to content

Commit

Permalink
chore(audit): add auditor base
Browse files Browse the repository at this point in the history
  • Loading branch information
j-mendez committed Oct 6, 2023
1 parent 11ac777 commit 0874bfe
Show file tree
Hide file tree
Showing 11 changed files with 319 additions and 271 deletions.
4 changes: 2 additions & 2 deletions kayle_innate/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion kayle_innate/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ js-sys = "0.3.64"
selectors = "=0.21.0"
smallvec = "0.6"
ego-tree = "0.6.2"
victor_tree = { version = "0.0.5" }
victor_tree = { version = "0.0.7" }
markup5ever = "0.11.0"

[dependencies.cssparser]
Expand Down
65 changes: 65 additions & 0 deletions kayle_innate/src/engine/audit/auditor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use scraper_forky::ElementRef;
use scraper_forky::Html;
use victor_tree::style::StyleSet;

use super::tree::parse_accessibility_tree;

/// the intro to an audit
pub struct Auditor<'a> {
/// the html document
pub document: &'a Html,
/// the tree to map to nodes
pub tree: std::collections::BTreeMap<&'a str, Vec<ElementRef<'a>>>,
/// styles for the audit
pub author: StyleSet,
// /// the matching context for css selectors
pub match_context: selectors::matching::MatchingContext<'a, scraper_forky::selector::Simple>,
}

impl<'a> Auditor<'a> {
pub fn new(
document: &'a Html,
css_rules: &str,
match_context: selectors::matching::MatchingContext<'a, scraper_forky::selector::Simple>,
) -> Auditor<'a> {
use crate::{console_log, now};
let t = now();
let tree = parse_accessibility_tree(&document);
console_log!("Tree Build Time {:?}", now() - t);
let tt = now();

// TODO: make stylesheet building optional and only on first requirement
let author = {
let mut author = victor_tree::style::StyleSetBuilder::new();
if !css_rules.is_empty() {
author.add_stylesheet(css_rules);
} else {
use markup5ever::local_name;
match tree.get("style") {
Some(styles) => {
for node in styles {
// https://html.spec.whatwg.org/multipage/semantics.html#update-a-style-block
if let Some(type_attr) = node.attr(&local_name!("type")) {
if !type_attr.eq_ignore_ascii_case("text/css") {
continue;
}
author.add_stylesheet(&node.inner_html())
}
}
}
_ => (),
}
}
author.finish()
};

console_log!("StyleSheets Build Time {:?}", now() - tt);

Auditor {
document,
tree,
author,
match_context,
}
}
}
4 changes: 4 additions & 0 deletions kayle_innate/src/engine/audit/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
/// the auditor
pub mod auditor;
/// the node tree
pub mod tree;
/// WCAG audit
pub mod wcag;
74 changes: 74 additions & 0 deletions kayle_innate/src/engine/audit/tree.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use scraper_forky::ElementRef;
use std::collections::BTreeMap;

/// try to fix all possible issues using a spec against the tree.
pub fn parse_accessibility_tree(
html: &scraper_forky::Html,
// todo: return the nodes with a tuple of the layout node and the element node
) -> std::collections::BTreeMap<&str, Vec<ElementRef<'_>>> {
// use taffy::prelude::*;
// // todo: use optional variable for clips or layout creation
// let mut taffy = Taffy::new();

// let header_node = taffy
// .new_leaf(Style {
// size: Size {
// width: points(800.0),
// height: points(100.0),
// },
// ..Default::default()
// })
// .unwrap();

// let body_node = taffy
// .new_leaf(Style {
// size: Size {
// width: points(800.0),
// height: auto(),
// },
// flex_grow: 1.0,
// ..Default::default()
// })
// .unwrap();

// let root_node = taffy
// .new_with_children(
// Style {
// flex_direction: FlexDirection::Column,
// size: Size {
// width: points(800.0),
// height: points(600.0),
// },
// ..Default::default()
// },
// &[header_node, body_node],
// )
// .unwrap();

// // Call compute_layout on the root of your tree to run the layout algorithm
// taffy.compute_layout(root_node, Size::MAX_CONTENT).unwrap();
// console_log!("Header Layout {:?}", taffy.layout(header_node).unwrap());
// We can get the x,y, and height, width of the element on proper tree insert

// parse doc will start from html downwards
// accessibility tree for ordered element mappings
let mut accessibility_tree: BTreeMap<&str, Vec<ElementRef<'_>>> =
BTreeMap::from([("title".into(), Default::default())]);

for node in html.tree.nodes() {
match scraper_forky::element_ref::ElementRef::wrap(node) {
Some(element) => {
accessibility_tree
.entry(element.value().name())
.and_modify(|n| n.push(element))
.or_insert(Vec::from([element]));
}
_ => (),
};
}

// console_log!("Getting tree links {:?}", accessibility_tree.get("a"));
// console_log!("Tree {:?}", accessibility_tree);

accessibility_tree
}
7 changes: 3 additions & 4 deletions kayle_innate/src/engine/audit/wcag.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::engine::rules::wcag_rule_map::RULES_A;
use crate::i18n::locales::{get_message, Langs};
use crate::Auditor;
use crate::{console_log, engine::issue::Issue};
use scraper_forky::ElementRef;

/// baseline for all rules
#[derive(Default)]
Expand All @@ -12,14 +12,13 @@ impl WCAG3AA {
/// init the rules
pub fn audit(
// allow tree mutation until threads or setup the tree with initial elements.
tree: &std::collections::BTreeMap<&str, Vec<ElementRef<'_>>>,
// _css: cssparser::Parser<'_, '_>,
auditor: &Auditor<'_>,
// todo: get configs like viewport
) -> Vec<Issue> {
let mut issues: Vec<Issue> = Vec::new();

// go through nodes and map to validation rules
for node in tree {
for node in &auditor.tree {
if RULES_A.contains_key(&*node.0) {
let rules = RULES_A.get(&*node.0);
match rules {
Expand Down
11 changes: 11 additions & 0 deletions kayle_innate/src/engine/styles/css_cache.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/// build matching context
pub fn build_matching_context<'a>(
nth_index_cache: &'a mut selectors::NthIndexCache,
) -> selectors::matching::MatchingContext<'a, scraper_forky::selector::Simple> {
selectors::matching::MatchingContext::new(
selectors::matching::MatchingMode::Normal,
None,
Some(nth_index_cache),
selectors::matching::QuirksMode::NoQuirks,
)
}
12 changes: 6 additions & 6 deletions kayle_innate/src/engine/styles/errors.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use cssparser::{CowRcStr, ParseError};
// use cssparser::{CowRcStr, ParseError};
use selectors::parser::SelectorParseErrorKind;

pub type PropertyParseError<'i> = ParseError<'i, PropertyParseErrorKind<'i>>;
// pub type PropertyParseError<'i> = ParseError<'i, PropertyParseErrorKind<'i>>;

pub enum PropertyParseErrorKind<'i> {
UnknownProperty(CowRcStr<'i>),
UnknownUnit(CowRcStr<'i>),
}
// pub enum PropertyParseErrorKind<'i> {
// UnknownProperty(CowRcStr<'i>),
// UnknownUnit(CowRcStr<'i>),
// }

pub enum RuleParseErrorKind<'i> {
Selector(SelectorParseErrorKind<'i>),
Expand Down
2 changes: 2 additions & 0 deletions kayle_innate/src/engine/styles/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
pub mod css_cache;
pub mod errors;
pub mod rules;

use crate::console_log;
use cssparser::{Parser, ParserInput};
use markup5ever::local_name;
Expand Down
Loading

0 comments on commit 0874bfe

Please sign in to comment.