Skip to content

Commit

Permalink
chore(innate): add accessibility tree building
Browse files Browse the repository at this point in the history
  • Loading branch information
j-mendez committed Sep 29, 2023
1 parent d3aa4a3 commit ac5f765
Show file tree
Hide file tree
Showing 12 changed files with 1,041 additions and 81 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ✨ kayle

The futuristic web accessibility engine.
The blazing fast and accurate web accessibility engine.

## Getting Started

Expand Down Expand Up @@ -218,6 +218,10 @@ Run the following to install on ^node@18

Use the command `yarn build` to compile all the scripts for each locale.

## Rust Runner

We are building a rust based runner called [kayle_innate](./kayle_innate/) that can port to wasm that will take the audits into the nanoseconds - low milliseconds zone.

## Discord

If you want to chat about the project checkout our [Discord](https://discord.gg/ukmJcjQ5).
Expand Down
20 changes: 20 additions & 0 deletions kayle/lib/wasm/css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { RunnerConfig } from "../config";

// get all the css of the document to send to rust
export const getAllCss = async (config: RunnerConfig) => {
return await config.page.evaluate(() => {
return [...document.styleSheets]
.map((styleSheet) => {
try {
return [...styleSheet.cssRules].map((rule) => rule.cssText).join("");
} catch (e) {
console.log(
"Access to stylesheet %s is denied.",
styleSheet.href
);
}
})
.filter(Boolean)
.join("\n");
});
};
5 changes: 4 additions & 1 deletion kayle/lib/wasm/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@ import type { RunnerConfig } from "../config";
export async function extractLinks(config: RunnerConfig, target?: string) {
const htmlContent = await config.page.content();
const domain = typeof target === "string" ? target : config.page.url();
return get_document_links(htmlContent, domain !== "about:blank" ? domain : "");
return get_document_links(
htmlContent,
domain !== "about:blank" ? domain : ""
);
}
1 change: 1 addition & 0 deletions kayle/lib/wasm/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { extractLinks } from "./extract";
export { getAllCss } from "./css"
2 changes: 1 addition & 1 deletion kayle_innate/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ repository = "https://github.com/a11ywatch/kayle"
crate-type = ["cdylib", "rlib"]

[features]
default = ["console_error_panic_hook"]
default = ["console_error_panic_hook", "accessibility"]
accessibility = ["select"]

[dependencies]
Expand Down
6 changes: 6 additions & 0 deletions kayle_innate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,9 @@ In order to test the accessibility parser in Rust run.

1. Port expensive functions to wasm with preloading capabilities injection into browsers.
1. Reborn the accessibility testing in rust.

## Notes

For creating a rust based wasm accessibility runner we have a high surface level of getting 35ms audits [medium](./tests/mock.rs) case
from the fastesdt audits `fast_htmlcs` 200-300ms on a large run. This leads us to the possibility of porting this over
to get the drastic benefits from a re-write.
1 change: 1 addition & 0 deletions kayle_innate/src/engine/rules.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// accessibility rules todo:
1 change: 1 addition & 0 deletions kayle_innate/src/i18n/locales.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// support for based locales in readme
68 changes: 34 additions & 34 deletions kayle_innate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ extern crate lazy_static;
mod utils;
use case_insensitive_string::CaseInsensitiveString;
use std::collections::HashSet;
use utils::{convert_abs_path, convert_base_path, set_panic_hook, domain_name};
use utils::{convert_abs_path, convert_base_path, domain_name, set_panic_hook};
use wasm_bindgen::prelude::*;

#[cfg(feature = "wee_alloc")]
Expand Down Expand Up @@ -124,12 +124,14 @@ pub fn get_document_links(res: &str, domain: &str) -> Box<[JsValue]> {
links.into_boxed_slice()
}

#[wasm_bindgen]
// RUST_LOG=info wasm-pack test --firefox --headless --features accessibility --release
#[cfg(feature = "accessibility")]
/// try to fix all possible issues using a spec against the tree.
pub fn parse_accessibility_tree(html: &str) {
pub fn parse_accessibility_tree(
html: &str,
) -> std::collections::BTreeMap<String, Vec<scraper::node::Element>> {
set_panic_hook();
use std::collections::BTreeMap;

#[wasm_bindgen]
extern "C" {
Expand Down Expand Up @@ -158,60 +160,58 @@ pub fn parse_accessibility_tree(html: &str) {
// The chrome browser we can set to ignore all assets and fetch them here but, it would be re-doing the wheel.
// If we can send the Stylesheets from node to rust this could leverage the sheets attached since we just need the node references.

let mut n = 0;
let t = now();
let mut n = 0;
let mut accessibility_tree: BTreeMap<Option<&str>, Vec<_>> = BTreeMap::new();
let d = select::document::Document::from(html);

// measure select parsing doc 1:1 around 34ms - gets slower when using methods possibly due to clones
while let Some(node) = select::document::Document::from(html).nth(n) {
// measure select parsing doc 1:1 around 25ms
while let Some(node) = d.nth(n) {
let element_name = node.name();
console_log!("{:?}", element_name);
// console_log!("{:?}", element_name);
accessibility_tree
.entry(element_name)
.and_modify(|n| n.push(node))
.or_insert(Vec::from([node]));
n += 1;
}

console_log!("Select Parser duration {:?}ms", now() - t);
// console_log!("Tree {:?}", accessibility_tree);

let t = now();

// parse doc will start from html downwards
let h = scraper::Html::parse_document(html);
// accessibility tree for ordered element mappings
let mut accessibility_tree: BTreeMap<String, Vec<_>> = BTreeMap::new();
let mut hh = h.tree.nodes();

// measure select parsing doc 1:1 around 10ms
while let Some(node) = hh.next() {
if let Some(element) = node.value().as_element() {
let element_name = element.name();
console_log!("{:?}", element_name);
// console_log!("{:?}", element_name);
accessibility_tree
.entry(element_name.to_string())
.and_modify(|n| n.push(element.to_owned()))
.or_insert(Vec::from([element.to_owned()]));
}
}
// "html"
// "head"
// "title"
// "meta"
// "link"
// "style"
// "body"
// "header"
// "nav"
// "a"
// "a"
// "main"
// "h1"
// "p"
// "input"
// "footer"
// "ul"
// "li"

console_log!("Scraper Parser: duration {:?}ms", now() - t);
console_log!("Getting tree links {:?}", accessibility_tree.get("a"));

accessibility_tree
// console_log!("Tree {:?}", accessibility_tree);
}

#[wasm_bindgen]
/// use gpu to accelerate layout rendering or workers.
pub fn validate_node() {
todo!("It will validate a node whether accessibility checks should arise.")
/// audit a web page passing the html and css rules.
pub fn audit(html: &str, _css_rules: &str) {
let _tree = parse_accessibility_tree(&html);
}

#[wasm_bindgen]
/// Perform the a judgement against a page to determine effort, access, and more.
pub fn judge() {
todo!("Determine the score of the website after the tree was built.")
/// parse css tree to maps
pub fn parse_css(_css: &str) {
// parse the css to a list of nodes capable of o1 getting results
}
Loading

0 comments on commit ac5f765

Please sign in to comment.