├── .gitignore ├── rust-toolchain.toml ├── src ├── lib.rs ├── role │ ├── snapshots │ │ ├── aria_query__role__test__snapshot_values.snap │ │ └── aria_query__role__test__snapshot_for_entries.snap │ ├── mod.rs │ └── aria_abstract_roles.rs ├── dom │ ├── snapshots │ │ ├── dom__test__snapshot_for_entries.snap │ │ ├── aria_query__dom__test__snapshot_for_entries.snap │ │ └── aria_query__dom__test__snapshot_for_entries_with_enum_dom_elements.snap │ └── mod.rs ├── aria │ ├── snapshots │ │ └── aria_query__aria__test__snapshot_for_entries.snap │ └── mod.rs └── definition │ └── mod.rs ├── README.md ├── .github ├── renovate.json └── workflows │ └── ci.yml ├── .cargo └── config.toml ├── Cargo.toml ├── LICENSE ├── Cargo.lock └── deny.toml /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "1.84.0" 3 | profile = "default" 4 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod aria; 2 | pub mod definition; 3 | pub mod dom; 4 | pub mod role; 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # aria-query 2 | 3 | Rust alternative [aria-query](https://github.com/A11yance/aria-query). This package is under the construction. -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["github>Boshen/renovate"] 4 | } 5 | -------------------------------------------------------------------------------- /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [alias] 2 | # Do not append `--` or it will break IDEs 3 | ck = "check --workspace --all-targets --locked" 4 | lint = "clippy --workspace --all-targets --all-features" 5 | codecov = "llvm-cov --workspace --ignore-filename-regex tasks" 6 | coverage = "run -p oxc_coverage --release --" 7 | benchmark = "run -p oxc_benchmark --release --" 8 | minsize = "run -p oxc_minsize --release --" 9 | rule = "run -p rulegen" 10 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "aria_query" 3 | version = "0.1.0" 4 | authors = ["Shinobu Hayashi "] 5 | categories = ["development-tools", "web-programming", "accessibility"] 6 | description = "Rust alternative aria-query" 7 | edition = "2021" 8 | keywords = ["JavaScript", "TypeScript", "accessibility"] 9 | license = "MIT" 10 | repository = "https://github.com/oxc-project/aria-query" 11 | rust-version = "1.60" 12 | 13 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 14 | 15 | [dependencies] 16 | phf = { version = "0.11", features = ["macros"] } 17 | 18 | [dev-dependencies] 19 | insta = { version = "1.34.0", features = ["json"] } 20 | serde = { version = "1.0.195", features = ["derive"] } 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023-present Boshen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /src/role/snapshots/aria_query__role__test__snapshot_values.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/role/mod.rs 3 | expression: roles_values 4 | --- 5 | [ 6 | { 7 | "name_from": [ 8 | "Author" 9 | ] 10 | }, 11 | { 12 | "name_from": [ 13 | "Author" 14 | ] 15 | }, 16 | { 17 | "name_from": [ 18 | "Author" 19 | ], 20 | "related_concepts": [ 21 | { 22 | "module": "XForms", 23 | "concept": {} 24 | } 25 | ] 26 | }, 27 | { 28 | "name_from": [ 29 | "Author" 30 | ] 31 | }, 32 | { 33 | "name_from": [ 34 | "Author" 35 | ] 36 | }, 37 | { 38 | "related_concepts": [ 39 | { 40 | "module": "XHTML", 41 | "concept": {} 42 | }, 43 | { 44 | "module": "Dublin Core", 45 | "concept": {} 46 | } 47 | ] 48 | }, 49 | { 50 | "related_concepts": [ 51 | { 52 | "module": "DTB", 53 | "concept": {} 54 | }, 55 | { 56 | "module": "DTB", 57 | "concept": {} 58 | }, 59 | { 60 | "module": "SMIL", 61 | "concept": {} 62 | } 63 | ] 64 | }, 65 | { 66 | "name_from": [ 67 | "Author", 68 | "Contents" 69 | ] 70 | }, 71 | { 72 | "name_from": [ 73 | "Author" 74 | ] 75 | }, 76 | {}, 77 | {}, 78 | { 79 | "name_from": [ 80 | "Author" 81 | ] 82 | } 83 | ] 84 | -------------------------------------------------------------------------------- /src/role/snapshots/aria_query__role__test__snapshot_for_entries.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/role/mod.rs 3 | expression: roles_entries 4 | --- 5 | { 6 | "command": { 7 | "name_from": [ 8 | "Author" 9 | ] 10 | }, 11 | "composite": { 12 | "name_from": [ 13 | "Author" 14 | ] 15 | }, 16 | "input": { 17 | "name_from": [ 18 | "Author" 19 | ], 20 | "related_concepts": [ 21 | { 22 | "module": "XForms", 23 | "concept": {} 24 | } 25 | ] 26 | }, 27 | "landmark": { 28 | "name_from": [ 29 | "Author" 30 | ] 31 | }, 32 | "range": { 33 | "name_from": [ 34 | "Author" 35 | ] 36 | }, 37 | "roletype": { 38 | "related_concepts": [ 39 | { 40 | "module": "XHTML", 41 | "concept": {} 42 | }, 43 | { 44 | "module": "Dublin Core", 45 | "concept": {} 46 | } 47 | ] 48 | }, 49 | "section": { 50 | "related_concepts": [ 51 | { 52 | "module": "DTB", 53 | "concept": {} 54 | }, 55 | { 56 | "module": "DTB", 57 | "concept": {} 58 | }, 59 | { 60 | "module": "SMIL", 61 | "concept": {} 62 | } 63 | ] 64 | }, 65 | "sectionhead": { 66 | "name_from": [ 67 | "Author", 68 | "Contents" 69 | ] 70 | }, 71 | "select": { 72 | "name_from": [ 73 | "Author" 74 | ] 75 | }, 76 | "structure": {}, 77 | "widget": {}, 78 | "window": { 79 | "name_from": [ 80 | "Author" 81 | ] 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/role/mod.rs: -------------------------------------------------------------------------------- 1 | mod aria_abstract_roles; 2 | use crate::definition::ARIARoleDefinition; 3 | use std::collections::HashMap; 4 | 5 | pub fn entries() -> HashMap<&'static str, &'static ARIARoleDefinition> { 6 | aria_abstract_roles::ARIA_ABSTRACT_ROLES 7 | .entries() 8 | .map(|(k, v)| (*k, *v)) 9 | .collect() 10 | } 11 | 12 | pub fn for_each(mut callback: impl FnMut(&'static str, &'static ARIARoleDefinition)) { 13 | aria_abstract_roles::ARIA_ABSTRACT_ROLES 14 | .into_iter() 15 | .for_each(|(k, v)| callback(k, v)); 16 | } 17 | 18 | pub fn get(name: &str) -> Option<&'static ARIARoleDefinition> { 19 | match aria_abstract_roles::ARIA_ABSTRACT_ROLES.get(name) { 20 | Some(v) => Some(v), 21 | None => None, 22 | } 23 | } 24 | 25 | pub fn has(name: &str) -> bool { 26 | aria_abstract_roles::ARIA_ABSTRACT_ROLES.contains_key(name) 27 | } 28 | 29 | pub fn keys() -> impl Iterator { 30 | aria_abstract_roles::ARIA_ABSTRACT_ROLES.keys().copied() 31 | } 32 | 33 | pub fn values() -> impl Iterator { 34 | aria_abstract_roles::ARIA_ABSTRACT_ROLES.values().copied() 35 | } 36 | 37 | #[cfg(test)] 38 | mod test { 39 | use crate::definition::ARIARoleDefinition; 40 | use crate::role; 41 | use insta::{assert_json_snapshot, Settings}; 42 | 43 | #[test] 44 | fn snapshot_for_entries() { 45 | let roles_entries = role::entries(); 46 | 47 | let mut settings = Settings::clone_current(); 48 | settings.set_sort_maps(true); 49 | settings.bind(|| { 50 | assert_json_snapshot!(roles_entries); 51 | }); 52 | } 53 | 54 | #[test] 55 | fn test_for_each() { 56 | let mut el_count = 0; 57 | role::for_each(|_, _| el_count += 1); 58 | assert_eq!(el_count, 12); 59 | let mut elements_list = Vec::new(); 60 | role::for_each(|k, _| { 61 | elements_list.push(k); 62 | }); 63 | assert_eq!(elements_list, role::keys().collect::>()); 64 | } 65 | 66 | #[test] 67 | fn test_get() { 68 | assert!(role::get("command").is_some()); 69 | assert!(role::get("unknown").is_none()); 70 | } 71 | 72 | #[test] 73 | fn test_has() { 74 | assert!(role::has("command")); 75 | assert!(!role::has("unknown")); 76 | } 77 | 78 | #[test] 79 | fn test_keys() { 80 | let keys = role::keys().collect::>(); 81 | for key in keys { 82 | assert!(role::entries().contains_key(key)); 83 | } 84 | } 85 | 86 | #[test] 87 | fn snapshot_values() { 88 | let roles_values = role::values(); 89 | let roles_values = roles_values.collect::>(); 90 | let mut settings = Settings::clone_current(); 91 | settings.set_sort_maps(true); 92 | settings.bind(|| { 93 | assert_json_snapshot!(roles_values); 94 | }); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/dom/snapshots/dom__test__snapshot_for_entries.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: crates/dom/src/lib.rs 3 | expression: dom_entries 4 | --- 5 | { 6 | "a": false, 7 | "abbr": false, 8 | "acronym": false, 9 | "address": false, 10 | "applet": false, 11 | "area": false, 12 | "article": false, 13 | "aside": false, 14 | "audio": false, 15 | "b": false, 16 | "base": true, 17 | "bdi": false, 18 | "bdo": false, 19 | "big": false, 20 | "blink": false, 21 | "blockquote": false, 22 | "body": false, 23 | "br": false, 24 | "button": false, 25 | "canvas": false, 26 | "caption": false, 27 | "center": false, 28 | "cite": false, 29 | "code": false, 30 | "col": true, 31 | "colgroup": true, 32 | "content": false, 33 | "data": false, 34 | "datalist": false, 35 | "dd": false, 36 | "del": false, 37 | "details": false, 38 | "dfn": false, 39 | "dialog": false, 40 | "dir": false, 41 | "div": false, 42 | "dl": false, 43 | "dt": false, 44 | "em": false, 45 | "embed": false, 46 | "fieldset": false, 47 | "figcaption": false, 48 | "figure": false, 49 | "font": false, 50 | "footer": false, 51 | "form": false, 52 | "frame": false, 53 | "frameset": false, 54 | "h1": false, 55 | "h2": false, 56 | "h3": false, 57 | "h4": false, 58 | "h5": false, 59 | "h6": false, 60 | "head": true, 61 | "header": false, 62 | "hgroup": false, 63 | "hr": false, 64 | "html": true, 65 | "i": false, 66 | "iframe": false, 67 | "img": false, 68 | "input": false, 69 | "ins": false, 70 | "kbd": false, 71 | "keygen": false, 72 | "label": false, 73 | "legend": false, 74 | "li": false, 75 | "link": true, 76 | "main": false, 77 | "map": false, 78 | "mark": false, 79 | "marquee": false, 80 | "menu": false, 81 | "menuitem": false, 82 | "meta": true, 83 | "meter": false, 84 | "nav": false, 85 | "noembed": true, 86 | "noscript": true, 87 | "object": false, 88 | "ol": false, 89 | "optgroup": false, 90 | "option": false, 91 | "output": false, 92 | "p": false, 93 | "param": true, 94 | "picture": true, 95 | "pre": false, 96 | "progress": false, 97 | "q": false, 98 | "rp": false, 99 | "rt": false, 100 | "rtc": false, 101 | "ruby": false, 102 | "s": false, 103 | "samp": false, 104 | "script": true, 105 | "section": false, 106 | "select": false, 107 | "small": false, 108 | "source": true, 109 | "spacer": false, 110 | "span": false, 111 | "strike": false, 112 | "strong": false, 113 | "style": true, 114 | "sub": false, 115 | "summary": false, 116 | "sup": false, 117 | "table": false, 118 | "tbody": false, 119 | "td": false, 120 | "textarea": false, 121 | "tfoot": false, 122 | "th": false, 123 | "thead": false, 124 | "time": false, 125 | "title": true, 126 | "tr": false, 127 | "track": true, 128 | "tt": false, 129 | "u": false, 130 | "ul": false, 131 | "var": false, 132 | "video": false, 133 | "wbr": false, 134 | "xmp": false 135 | } 136 | -------------------------------------------------------------------------------- /src/dom/snapshots/aria_query__dom__test__snapshot_for_entries.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/dom/mod.rs 3 | expression: dom_entries 4 | --- 5 | { 6 | "a": false, 7 | "abbr": false, 8 | "acronym": false, 9 | "address": false, 10 | "applet": false, 11 | "area": false, 12 | "article": false, 13 | "aside": false, 14 | "audio": false, 15 | "b": false, 16 | "base": true, 17 | "bdi": false, 18 | "bdo": false, 19 | "big": false, 20 | "blink": false, 21 | "blockquote": false, 22 | "body": false, 23 | "br": false, 24 | "button": false, 25 | "canvas": false, 26 | "caption": false, 27 | "center": false, 28 | "cite": false, 29 | "code": false, 30 | "col": true, 31 | "colgroup": true, 32 | "content": false, 33 | "data": false, 34 | "datalist": false, 35 | "dd": false, 36 | "del": false, 37 | "details": false, 38 | "dfn": false, 39 | "dialog": false, 40 | "dir": false, 41 | "div": false, 42 | "dl": false, 43 | "dt": false, 44 | "em": false, 45 | "embed": false, 46 | "fieldset": false, 47 | "figcaption": false, 48 | "figure": false, 49 | "font": false, 50 | "footer": false, 51 | "form": false, 52 | "frame": false, 53 | "frameset": false, 54 | "h1": false, 55 | "h2": false, 56 | "h3": false, 57 | "h4": false, 58 | "h5": false, 59 | "h6": false, 60 | "head": true, 61 | "header": false, 62 | "hgroup": false, 63 | "hr": false, 64 | "html": true, 65 | "i": false, 66 | "iframe": false, 67 | "img": false, 68 | "input": false, 69 | "ins": false, 70 | "kbd": false, 71 | "keygen": false, 72 | "label": false, 73 | "legend": false, 74 | "li": false, 75 | "link": true, 76 | "main": false, 77 | "map": false, 78 | "mark": false, 79 | "marquee": false, 80 | "menu": false, 81 | "menuitem": false, 82 | "meta": true, 83 | "meter": false, 84 | "nav": false, 85 | "noembed": true, 86 | "noscript": true, 87 | "object": false, 88 | "ol": false, 89 | "optgroup": false, 90 | "option": false, 91 | "output": false, 92 | "p": false, 93 | "param": true, 94 | "picture": true, 95 | "pre": false, 96 | "progress": false, 97 | "q": false, 98 | "rp": false, 99 | "rt": false, 100 | "rtc": false, 101 | "ruby": false, 102 | "s": false, 103 | "samp": false, 104 | "script": true, 105 | "section": false, 106 | "select": false, 107 | "small": false, 108 | "source": true, 109 | "spacer": false, 110 | "span": false, 111 | "strike": false, 112 | "strong": false, 113 | "style": true, 114 | "sub": false, 115 | "summary": false, 116 | "sup": false, 117 | "table": false, 118 | "tbody": false, 119 | "td": false, 120 | "textarea": false, 121 | "tfoot": false, 122 | "th": false, 123 | "thead": false, 124 | "time": false, 125 | "title": true, 126 | "tr": false, 127 | "track": true, 128 | "tt": false, 129 | "u": false, 130 | "ul": false, 131 | "var": false, 132 | "video": false, 133 | "wbr": false, 134 | "xmp": false 135 | } 136 | -------------------------------------------------------------------------------- /src/dom/snapshots/aria_query__dom__test__snapshot_for_entries_with_enum_dom_elements.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/dom/mod.rs 3 | expression: dom_entries 4 | --- 5 | { 6 | "a": false, 7 | "abbr": false, 8 | "acronym": false, 9 | "address": false, 10 | "applet": false, 11 | "area": false, 12 | "article": false, 13 | "aside": false, 14 | "audio": false, 15 | "b": false, 16 | "base": true, 17 | "bdi": false, 18 | "bdo": false, 19 | "big": false, 20 | "blink": false, 21 | "blockquote": false, 22 | "body": false, 23 | "br": false, 24 | "button": false, 25 | "canvas": false, 26 | "caption": false, 27 | "center": false, 28 | "cite": false, 29 | "code": false, 30 | "col": true, 31 | "colgroup": true, 32 | "content": false, 33 | "data": false, 34 | "datalist": false, 35 | "dd": false, 36 | "del": false, 37 | "details": false, 38 | "dfn": false, 39 | "dialog": false, 40 | "dir": false, 41 | "div": false, 42 | "dl": false, 43 | "dt": false, 44 | "em": false, 45 | "embed": false, 46 | "fieldset": false, 47 | "figcaption": false, 48 | "figure": false, 49 | "font": false, 50 | "footer": false, 51 | "form": false, 52 | "frame": false, 53 | "frameset": false, 54 | "h1": false, 55 | "h2": false, 56 | "h3": false, 57 | "h4": false, 58 | "h5": false, 59 | "h6": false, 60 | "head": true, 61 | "header": false, 62 | "hgroup": false, 63 | "hr": false, 64 | "html": true, 65 | "i": false, 66 | "iframe": false, 67 | "img": false, 68 | "input": false, 69 | "ins": false, 70 | "kbd": false, 71 | "keygen": false, 72 | "label": false, 73 | "legend": false, 74 | "li": false, 75 | "link": true, 76 | "main": false, 77 | "map": false, 78 | "mark": false, 79 | "marquee": false, 80 | "menu": false, 81 | "menuitem": false, 82 | "meta": true, 83 | "meter": false, 84 | "nav": false, 85 | "noembed": true, 86 | "noscript": true, 87 | "object": false, 88 | "ol": false, 89 | "optgroup": false, 90 | "option": false, 91 | "output": false, 92 | "p": false, 93 | "param": true, 94 | "picture": true, 95 | "pre": false, 96 | "progress": false, 97 | "q": false, 98 | "rp": false, 99 | "rt": false, 100 | "rtc": false, 101 | "ruby": false, 102 | "s": false, 103 | "samp": false, 104 | "script": true, 105 | "section": false, 106 | "select": false, 107 | "small": false, 108 | "source": true, 109 | "spacer": false, 110 | "span": false, 111 | "strike": false, 112 | "strong": false, 113 | "style": true, 114 | "sub": false, 115 | "summary": false, 116 | "sup": false, 117 | "table": false, 118 | "tbody": false, 119 | "td": false, 120 | "textarea": false, 121 | "tfoot": false, 122 | "th": false, 123 | "thead": false, 124 | "time": false, 125 | "title": true, 126 | "tr": false, 127 | "track": true, 128 | "tt": false, 129 | "u": false, 130 | "ul": false, 131 | "var": false, 132 | "video": false, 133 | "wbr": false, 134 | "xmp": false 135 | } 136 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | types: [opened, synchronize] 7 | paths-ignore: 8 | - '**/*.md' 9 | - '**/*.yml' 10 | - '!.github/workflows/ci.yml' 11 | push: 12 | branches: 13 | - main 14 | - "renovate/**" 15 | paths-ignore: 16 | - '**/*.md' 17 | - '**/*.yml' 18 | - '!.github/workflows/ci.yml' 19 | 20 | concurrency: 21 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} 22 | cancel-in-progress: ${{ github.ref_name != 'main' }} 23 | 24 | jobs: 25 | cache: 26 | name: Check and Build 27 | strategy: 28 | fail-fast: false 29 | matrix: 30 | include: 31 | - os: windows-latest 32 | - os: ubuntu-latest 33 | - os: macos-latest 34 | runs-on: ${{ matrix.os }} 35 | steps: 36 | - uses: taiki-e/checkout-action@v1 37 | - uses: Boshen/setup-rust@main 38 | with: 39 | save-cache: ${{ github.ref_name == 'main' }} 40 | - run: cargo ck 41 | - run: cargo test --no-run 42 | - run: cargo test 43 | 44 | wasm: 45 | name: Check Wasm 46 | runs-on: ubuntu-latest 47 | steps: 48 | - uses: taiki-e/checkout-action@v1 49 | - uses: Boshen/setup-rust@main 50 | with: 51 | save-cache: ${{ github.ref_name == 'main' }} 52 | cache-key: wasm 53 | - name: Check 54 | run: | 55 | rustup target add wasm32-unknown-unknown 56 | cargo check -p aria_query --target wasm32-unknown-unknown 57 | 58 | typos: 59 | name: Spell Check 60 | runs-on: ubuntu-latest 61 | steps: 62 | - uses: taiki-e/checkout-action@v1 63 | - uses: crate-ci/typos@master 64 | with: 65 | files: . 66 | 67 | deny: 68 | name: Cargo Deny 69 | runs-on: ubuntu-latest 70 | steps: 71 | - uses: taiki-e/checkout-action@v1 72 | - uses: dorny/paths-filter@v3 73 | id: filter 74 | with: 75 | filters: | 76 | src: 77 | - 'Cargo.lock' 78 | - name: Install cargo-deny 79 | if: steps.filter.outputs.src == 'true' 80 | uses: taiki-e/install-action@cargo-deny 81 | - uses: Boshen/setup-rust@main 82 | - if: steps.filter.outputs.src == 'true' 83 | run: cargo deny check 84 | 85 | unused-deps: 86 | name: Check Unused Dependencies 87 | runs-on: ubuntu-latest 88 | steps: 89 | - uses: taiki-e/checkout-action@v1 90 | - uses: dorny/paths-filter@v3 91 | id: filter 92 | with: 93 | filters: | 94 | src: 95 | - '**/*.rs' 96 | - '**/Cargo.toml' 97 | - 'Cargo.lock' 98 | - uses: Boshen/setup-rust@main 99 | with: 100 | restore-cache: false 101 | if: steps.filter.outputs.src == 'true' 102 | - uses: cargo-bins/cargo-binstall@v1.10.19 103 | if: steps.filter.outputs.src == 'true' 104 | - run: cargo binstall --no-confirm cargo-shear@1 105 | if: steps.filter.outputs.src == 'true' 106 | - run: cargo shear 107 | if: steps.filter.outputs.src == 'true' 108 | 109 | format: 110 | name: Format 111 | runs-on: ubuntu-latest 112 | steps: 113 | - uses: actions/checkout@v4 114 | - uses: Boshen/setup-rust@main 115 | with: 116 | components: rustfmt 117 | restore-cache: false 118 | - run: cargo fmt --all -- --check 119 | 120 | lint: 121 | name: Clippy 122 | runs-on: ubuntu-latest 123 | steps: 124 | - uses: taiki-e/checkout-action@v1 125 | - uses: Boshen/setup-rust@main 126 | with: 127 | cache-key: warm 128 | components: clippy 129 | - run: cargo lint -- -D warnings 130 | 131 | doc: 132 | name: Doc 133 | runs-on: ubuntu-latest 134 | steps: 135 | - uses: taiki-e/checkout-action@v1 136 | - uses: Boshen/setup-rust@main 137 | with: 138 | cache-key: warm 139 | components: rust-docs 140 | - run: RUSTDOCFLAGS='-D warnings' cargo doc -p aria_query 141 | -------------------------------------------------------------------------------- /src/aria/snapshots/aria_query__aria__test__snapshot_for_entries.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/aria/mod.rs 3 | expression: aria_entries 4 | --- 5 | { 6 | "aria-activedescendant": { 7 | "key": "aria-activedescendant", 8 | "type": "id" 9 | }, 10 | "aria-atomic": { 11 | "key": "aria-atomic", 12 | "type": "boolean" 13 | }, 14 | "aria-autocomplete": { 15 | "key": "aria-autocomplete", 16 | "type": "token", 17 | "values": [ 18 | "inline", 19 | "list", 20 | "both", 21 | "none" 22 | ] 23 | }, 24 | "aria-braillelabel": { 25 | "key": "aria-braillelabel", 26 | "type": "string" 27 | }, 28 | "aria-brailleroledescription": { 29 | "key": "aria-brailleroledescription", 30 | "type": "string" 31 | }, 32 | "aria-busy": { 33 | "key": "aria-busy", 34 | "type": "boolean" 35 | }, 36 | "aria-checked": { 37 | "key": "aria-checked", 38 | "type": "tristate" 39 | }, 40 | "aria-colcount": { 41 | "key": "aria-colcount", 42 | "type": "integer" 43 | }, 44 | "aria-colspan": { 45 | "key": "aria-colspan", 46 | "type": "integer" 47 | }, 48 | "aria-controls": { 49 | "key": "aria-controls", 50 | "type": "idlist" 51 | }, 52 | "aria-current": { 53 | "key": "aria-current", 54 | "type": "token", 55 | "values": [ 56 | "page", 57 | "step", 58 | "location", 59 | "date", 60 | "time", 61 | "true", 62 | "false" 63 | ] 64 | }, 65 | "aria-describedby": { 66 | "key": "aria-describedby", 67 | "type": "idlist" 68 | }, 69 | "aria-description": { 70 | "key": "aria-description", 71 | "type": "string" 72 | }, 73 | "aria-details": { 74 | "key": "aria-details", 75 | "type": "id" 76 | }, 77 | "aria-disabled": { 78 | "key": "aria-disabled", 79 | "type": "boolean" 80 | }, 81 | "aria-dropeffect": { 82 | "key": "aria-dropeffect", 83 | "type": "tokenlist", 84 | "values": [ 85 | "copy", 86 | "execute", 87 | "link", 88 | "move", 89 | "none", 90 | "popup" 91 | ] 92 | }, 93 | "aria-errormessage": { 94 | "key": "aria-errormessage", 95 | "type": "id" 96 | }, 97 | "aria-expanded": { 98 | "key": "aria-expanded", 99 | "type": "boolean", 100 | "allow_undefined": true 101 | }, 102 | "aria-flowto": { 103 | "key": "aria-flowto", 104 | "type": "idlist" 105 | }, 106 | "aria-grabbed": { 107 | "key": "aria-grabbed", 108 | "type": "boolean", 109 | "allow_undefined": true 110 | }, 111 | "aria-haspopup": { 112 | "key": "aria-haspopup", 113 | "type": "token", 114 | "values": [ 115 | "false", 116 | "true", 117 | "menu", 118 | "listbox", 119 | "tree", 120 | "grid", 121 | "dialog" 122 | ] 123 | }, 124 | "aria-hidden": { 125 | "key": "aria-hidden", 126 | "type": "boolean", 127 | "allow_undefined": true 128 | }, 129 | "aria-invalid": { 130 | "key": "aria-invalid", 131 | "type": "token", 132 | "values": [ 133 | "grammar", 134 | "false", 135 | "spelling", 136 | "true" 137 | ] 138 | }, 139 | "aria-keyshortcuts": { 140 | "key": "aria-keyshortcuts", 141 | "type": "string" 142 | }, 143 | "aria-label": { 144 | "key": "aria-label", 145 | "type": "string" 146 | }, 147 | "aria-labelledby": { 148 | "key": "aria-labelledby", 149 | "type": "idlist" 150 | }, 151 | "aria-level": { 152 | "key": "aria-level", 153 | "type": "integer" 154 | }, 155 | "aria-live": { 156 | "key": "aria-live", 157 | "type": "token", 158 | "values": [ 159 | "off", 160 | "polite", 161 | "assertive" 162 | ] 163 | }, 164 | "aria-modal": { 165 | "key": "aria-modal", 166 | "type": "boolean" 167 | }, 168 | "aria-multiline": { 169 | "key": "aria-multiline", 170 | "type": "boolean" 171 | }, 172 | "aria-multiselectable": { 173 | "key": "aria-multiselectable", 174 | "type": "boolean" 175 | }, 176 | "aria-orientation": { 177 | "key": "aria-orientation", 178 | "type": "token", 179 | "values": [ 180 | "horizontal", 181 | "vertical", 182 | "undefined" 183 | ] 184 | }, 185 | "aria-owns": { 186 | "key": "aria-owns", 187 | "type": "idlist" 188 | }, 189 | "aria-placeholder": { 190 | "key": "aria-placeholder", 191 | "type": "string" 192 | }, 193 | "aria-posinset": { 194 | "key": "aria-posinset", 195 | "type": "integer" 196 | }, 197 | "aria-pressed": { 198 | "key": "aria-pressed", 199 | "type": "tristate" 200 | }, 201 | "aria-readonly": { 202 | "key": "aria-readonly", 203 | "type": "boolean" 204 | }, 205 | "aria-relevant": { 206 | "key": "aria-relevant", 207 | "type": "tokenlist", 208 | "values": [ 209 | "additions", 210 | "removals", 211 | "text", 212 | "all" 213 | ] 214 | }, 215 | "aria-required": { 216 | "key": "aria-required", 217 | "type": "boolean" 218 | }, 219 | "aria-roledescription": { 220 | "key": "aria-roledescription", 221 | "type": "string" 222 | }, 223 | "aria-rowcount": { 224 | "key": "aria-rowcount", 225 | "type": "integer" 226 | }, 227 | "aria-rowindex": { 228 | "key": "aria-rowindex", 229 | "type": "integer" 230 | }, 231 | "aria-rowspan": { 232 | "key": "aria-rowspan", 233 | "type": "integer" 234 | }, 235 | "aria-selected": { 236 | "key": "aria-selected", 237 | "type": "boolean", 238 | "allow_undefined": true 239 | }, 240 | "aria-setsize": { 241 | "key": "aria-setsize", 242 | "type": "integer" 243 | }, 244 | "aria-sort": { 245 | "key": "aria-sort", 246 | "type": "token", 247 | "values": [ 248 | "ascending", 249 | "descending", 250 | "none", 251 | "other" 252 | ] 253 | }, 254 | "aria-valuemax": { 255 | "key": "aria-valuemax", 256 | "type": "number" 257 | }, 258 | "aria-valuemin": { 259 | "key": "aria-valuemin", 260 | "type": "number" 261 | }, 262 | "aria-valuenow": { 263 | "key": "aria-valuenow", 264 | "type": "number" 265 | }, 266 | "aria-valuetext": { 267 | "key": "aria-valuetext", 268 | "type": "string" 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "aria_query" 7 | version = "0.1.0" 8 | dependencies = [ 9 | "insta", 10 | "phf", 11 | "serde", 12 | ] 13 | 14 | [[package]] 15 | name = "console" 16 | version = "0.15.7" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" 19 | dependencies = [ 20 | "encode_unicode", 21 | "lazy_static", 22 | "libc", 23 | "windows-sys", 24 | ] 25 | 26 | [[package]] 27 | name = "encode_unicode" 28 | version = "0.3.6" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" 31 | 32 | [[package]] 33 | name = "insta" 34 | version = "1.42.0" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "6513e4067e16e69ed1db5ab56048ed65db32d10ba5fc1217f5393f8f17d8b5a5" 37 | dependencies = [ 38 | "console", 39 | "linked-hash-map", 40 | "once_cell", 41 | "serde", 42 | "similar", 43 | ] 44 | 45 | [[package]] 46 | name = "lazy_static" 47 | version = "1.4.0" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 50 | 51 | [[package]] 52 | name = "libc" 53 | version = "0.2.152" 54 | source = "registry+https://github.com/rust-lang/crates.io-index" 55 | checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" 56 | 57 | [[package]] 58 | name = "linked-hash-map" 59 | version = "0.5.6" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" 62 | 63 | [[package]] 64 | name = "once_cell" 65 | version = "1.20.2" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 68 | 69 | [[package]] 70 | name = "phf" 71 | version = "0.11.2" 72 | source = "registry+https://github.com/rust-lang/crates.io-index" 73 | checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" 74 | dependencies = [ 75 | "phf_macros", 76 | "phf_shared", 77 | ] 78 | 79 | [[package]] 80 | name = "phf_generator" 81 | version = "0.11.2" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" 84 | dependencies = [ 85 | "phf_shared", 86 | "rand", 87 | ] 88 | 89 | [[package]] 90 | name = "phf_macros" 91 | version = "0.11.2" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" 94 | dependencies = [ 95 | "phf_generator", 96 | "phf_shared", 97 | "proc-macro2", 98 | "quote", 99 | "syn", 100 | ] 101 | 102 | [[package]] 103 | name = "phf_shared" 104 | version = "0.11.2" 105 | source = "registry+https://github.com/rust-lang/crates.io-index" 106 | checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" 107 | dependencies = [ 108 | "siphasher", 109 | ] 110 | 111 | [[package]] 112 | name = "proc-macro2" 113 | version = "1.0.89" 114 | source = "registry+https://github.com/rust-lang/crates.io-index" 115 | checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" 116 | dependencies = [ 117 | "unicode-ident", 118 | ] 119 | 120 | [[package]] 121 | name = "quote" 122 | version = "1.0.35" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" 125 | dependencies = [ 126 | "proc-macro2", 127 | ] 128 | 129 | [[package]] 130 | name = "rand" 131 | version = "0.8.5" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 134 | dependencies = [ 135 | "rand_core", 136 | ] 137 | 138 | [[package]] 139 | name = "rand_core" 140 | version = "0.6.4" 141 | source = "registry+https://github.com/rust-lang/crates.io-index" 142 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 143 | 144 | [[package]] 145 | name = "serde" 146 | version = "1.0.217" 147 | source = "registry+https://github.com/rust-lang/crates.io-index" 148 | checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" 149 | dependencies = [ 150 | "serde_derive", 151 | ] 152 | 153 | [[package]] 154 | name = "serde_derive" 155 | version = "1.0.217" 156 | source = "registry+https://github.com/rust-lang/crates.io-index" 157 | checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" 158 | dependencies = [ 159 | "proc-macro2", 160 | "quote", 161 | "syn", 162 | ] 163 | 164 | [[package]] 165 | name = "similar" 166 | version = "2.4.0" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "32fea41aca09ee824cc9724996433064c89f7777e60762749a4170a14abbfa21" 169 | 170 | [[package]] 171 | name = "siphasher" 172 | version = "0.3.11" 173 | source = "registry+https://github.com/rust-lang/crates.io-index" 174 | checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" 175 | 176 | [[package]] 177 | name = "syn" 178 | version = "2.0.85" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" 181 | dependencies = [ 182 | "proc-macro2", 183 | "quote", 184 | "unicode-ident", 185 | ] 186 | 187 | [[package]] 188 | name = "unicode-ident" 189 | version = "1.0.12" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 192 | 193 | [[package]] 194 | name = "windows-sys" 195 | version = "0.45.0" 196 | source = "registry+https://github.com/rust-lang/crates.io-index" 197 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 198 | dependencies = [ 199 | "windows-targets", 200 | ] 201 | 202 | [[package]] 203 | name = "windows-targets" 204 | version = "0.42.2" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 207 | dependencies = [ 208 | "windows_aarch64_gnullvm", 209 | "windows_aarch64_msvc", 210 | "windows_i686_gnu", 211 | "windows_i686_msvc", 212 | "windows_x86_64_gnu", 213 | "windows_x86_64_gnullvm", 214 | "windows_x86_64_msvc", 215 | ] 216 | 217 | [[package]] 218 | name = "windows_aarch64_gnullvm" 219 | version = "0.42.2" 220 | source = "registry+https://github.com/rust-lang/crates.io-index" 221 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 222 | 223 | [[package]] 224 | name = "windows_aarch64_msvc" 225 | version = "0.42.2" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 228 | 229 | [[package]] 230 | name = "windows_i686_gnu" 231 | version = "0.42.2" 232 | source = "registry+https://github.com/rust-lang/crates.io-index" 233 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 234 | 235 | [[package]] 236 | name = "windows_i686_msvc" 237 | version = "0.42.2" 238 | source = "registry+https://github.com/rust-lang/crates.io-index" 239 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 240 | 241 | [[package]] 242 | name = "windows_x86_64_gnu" 243 | version = "0.42.2" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 246 | 247 | [[package]] 248 | name = "windows_x86_64_gnullvm" 249 | version = "0.42.2" 250 | source = "registry+https://github.com/rust-lang/crates.io-index" 251 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 252 | 253 | [[package]] 254 | name = "windows_x86_64_msvc" 255 | version = "0.42.2" 256 | source = "registry+https://github.com/rust-lang/crates.io-index" 257 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 258 | -------------------------------------------------------------------------------- /src/role/aria_abstract_roles.rs: -------------------------------------------------------------------------------- 1 | use crate::definition::{ 2 | ARIAAbstractRole, ARIADocumentStructureRole, ARIANameFromSources, ARIARole, ARIARoleDefinition, 3 | ARIARoleDefinitionKey, ARIARoleRelation, ARIARoleRelationConcept, RoleDefinitions, 4 | }; 5 | use phf::phf_ordered_map; 6 | 7 | pub static ARIA_ABSTRACT_ROLES: RoleDefinitions = phf_ordered_map! { 8 | "command" => &ARIARoleDefinition { 9 | is_abstract: true, 10 | accessible_name_required: false, 11 | base_concepts: None, 12 | children_presentational: false, 13 | name_from: Some(&[&ARIANameFromSources::Author]), 14 | prohibited_props: None, 15 | props: None, 16 | related_concepts: None, 17 | require_context_role: None, 18 | required_context_role: None, 19 | required_owned_elements: None, 20 | required_props: None, 21 | super_class: Some(&[&[&ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::RoleType), &ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::Widget)]]), 22 | }, 23 | "composite" => &ARIARoleDefinition { 24 | is_abstract: true, 25 | accessible_name_required: false, 26 | base_concepts: None, 27 | children_presentational: false, 28 | name_from: Some(&[&ARIANameFromSources::Author]), 29 | prohibited_props: None, 30 | props: Some(&phf_ordered_map! { 31 | "aria-activedescendant" => &None, 32 | "aria-disabled" => &None, 33 | }), 34 | related_concepts: None, 35 | require_context_role: None, 36 | required_context_role: None, 37 | required_owned_elements: None, 38 | required_props: None, 39 | super_class: Some(&[&[&ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::RoleType), &ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::Widget)]]) 40 | }, 41 | "input" => &ARIARoleDefinition { 42 | is_abstract: true, 43 | accessible_name_required: false, 44 | base_concepts: None, 45 | children_presentational: false, 46 | name_from: Some(&[&ARIANameFromSources::Author]), 47 | prohibited_props: None, 48 | props: Some(&phf_ordered_map! { 49 | "aria-disabled" => &None, 50 | }), 51 | related_concepts: Some(&[ 52 | ARIARoleRelation { 53 | concept: Some(ARIARoleRelationConcept { 54 | name: "input", 55 | attributes: None, 56 | constraints: None 57 | }), 58 | module: Some("XForms"), 59 | } 60 | ]), 61 | require_context_role: None, 62 | required_context_role: None, 63 | required_owned_elements: None, 64 | required_props: None, 65 | super_class: Some(&[&[&ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::RoleType), &ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::Widget)]]) 66 | }, 67 | "landmark" => &ARIARoleDefinition { 68 | is_abstract: true, 69 | accessible_name_required: false, 70 | base_concepts: None, 71 | children_presentational: false, 72 | name_from: Some(&[&ARIANameFromSources::Author]), 73 | prohibited_props: None, 74 | props: None, 75 | related_concepts: None, 76 | require_context_role: None, 77 | required_context_role: None, 78 | required_owned_elements: None, 79 | required_props: None, 80 | super_class: Some(&[&[&ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::RoleType), &ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::Structure), &ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::Section)]]) 81 | }, 82 | "range" => &ARIARoleDefinition { 83 | is_abstract: true, 84 | accessible_name_required: false, 85 | base_concepts: None, 86 | children_presentational: false, 87 | name_from: Some(&[&ARIANameFromSources::Author]), 88 | prohibited_props: None, 89 | props: Some(&phf_ordered_map! { 90 | "aria-valuemax" => &None, 91 | "aria-valuemin" => &None, 92 | "aria-valuenow" => &None, 93 | }), 94 | related_concepts: None, 95 | require_context_role: None, 96 | required_context_role: None, 97 | required_owned_elements: None, 98 | required_props: None, 99 | super_class: Some(&[&[&ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::RoleType), &ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::Structure)]]) 100 | }, 101 | "roletype" => &ARIARoleDefinition { 102 | is_abstract: true, 103 | accessible_name_required: false, 104 | base_concepts: None, 105 | children_presentational: false, 106 | name_from: None, 107 | prohibited_props: None, 108 | props: Some(&phf_ordered_map! { 109 | "aria-atomic" => &None, 110 | "aria-busy" => &None, 111 | "aria-controls" => &None, 112 | "aria-describedby" => &None, 113 | "aria-details" => &None, 114 | "aria-dropeffect" => &None, 115 | "aria-flowto" => &None, 116 | "aria-grabbed" => &None, 117 | "aria-hidden" => &None, 118 | "aria-keyshortcuts" => &None, 119 | "aria-label" => &None, 120 | "aria-labelledby" => &None, 121 | "aria-live" => &None, 122 | "aria-owns" => &None, 123 | "aria-relevant" => &None, 124 | "aria-roledescription" => &None, 125 | }), 126 | related_concepts: Some(&[ 127 | ARIARoleRelation { 128 | concept: Some(ARIARoleRelationConcept { 129 | name: "role", 130 | attributes: None, 131 | constraints: None 132 | }), 133 | module: Some("XHTML"), 134 | }, 135 | ARIARoleRelation { 136 | concept: Some(ARIARoleRelationConcept { 137 | name: "type", 138 | attributes: None, 139 | constraints: None 140 | }), 141 | module: Some("Dublin Core"), 142 | } 143 | ]), 144 | require_context_role: None, 145 | required_context_role: None, 146 | required_owned_elements: None, 147 | required_props: None, 148 | super_class: None 149 | }, 150 | "section" => &ARIARoleDefinition { 151 | is_abstract: true, 152 | accessible_name_required: false, 153 | base_concepts: None, 154 | children_presentational: false, 155 | name_from: None, 156 | prohibited_props: None, 157 | props: None, 158 | related_concepts: Some(&[ 159 | ARIARoleRelation { 160 | concept: Some(ARIARoleRelationConcept { 161 | name: "frontmatter", 162 | attributes: None, 163 | constraints: None 164 | }), 165 | module: Some("DTB"), 166 | }, 167 | ARIARoleRelation { 168 | concept: Some(ARIARoleRelationConcept { 169 | name: "level", 170 | attributes: None, 171 | constraints: None 172 | }), 173 | module: Some("DTB"), 174 | }, 175 | ARIARoleRelation { 176 | concept: Some(ARIARoleRelationConcept { 177 | name: "level", 178 | attributes: None, 179 | constraints: None 180 | }), 181 | module: Some("SMIL"), 182 | }, 183 | ]), 184 | require_context_role: None, 185 | required_context_role: None, 186 | required_owned_elements: None, 187 | required_props: None, 188 | super_class: Some(&[&[&ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::RoleType), &ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::Structure)]]) 189 | }, 190 | "sectionhead" => &ARIARoleDefinition { 191 | is_abstract: true, 192 | accessible_name_required: false, 193 | base_concepts: None, 194 | children_presentational: false, 195 | name_from: Some(&[&ARIANameFromSources::Author, &ARIANameFromSources::Contents]), 196 | prohibited_props: None, 197 | props: None, 198 | related_concepts: None, 199 | require_context_role: None, 200 | required_context_role: None, 201 | required_owned_elements: None, 202 | required_props: None, 203 | super_class: Some(&[&[&ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::RoleType), &ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::Structure)]]) 204 | }, 205 | "select" => &ARIARoleDefinition { 206 | is_abstract: true, 207 | accessible_name_required: false, 208 | base_concepts: None, 209 | children_presentational: false, 210 | name_from: Some(&[&ARIANameFromSources::Author]), 211 | prohibited_props: None, 212 | props: Some(&phf_ordered_map! { 213 | "aria-orientation" => &None, 214 | }), 215 | related_concepts: None, 216 | require_context_role: None, 217 | required_context_role: None, 218 | required_owned_elements: None, 219 | required_props: None, 220 | super_class: Some(&[&[&ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::RoleType), &ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::Widget), &ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::Composite)], 221 | &[&ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::RoleType), &ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::Structure), &ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::Section), &ARIARoleDefinitionKey::ARIARole(ARIARole::ARIADocumentStructureRole(ARIADocumentStructureRole::Group))]]) 222 | }, 223 | "structure" => &ARIARoleDefinition { 224 | is_abstract: true, 225 | accessible_name_required: false, 226 | base_concepts: None, 227 | children_presentational: false, 228 | name_from: None, 229 | prohibited_props: None, 230 | props: None, 231 | related_concepts: None, 232 | require_context_role: None, 233 | required_context_role: None, 234 | required_owned_elements: None, 235 | required_props: None, 236 | super_class: Some(&[&[&ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::RoleType)]]) 237 | }, 238 | "widget" => &ARIARoleDefinition { 239 | is_abstract: true, 240 | accessible_name_required: false, 241 | base_concepts: None, 242 | children_presentational: false, 243 | name_from: None, 244 | prohibited_props: None, 245 | props: None, 246 | related_concepts: None, 247 | require_context_role: None, 248 | required_context_role: None, 249 | required_owned_elements: None, 250 | required_props: None, 251 | super_class: Some(&[&[&ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::RoleType)]]) 252 | }, 253 | "window" => &ARIARoleDefinition { 254 | is_abstract: true, 255 | accessible_name_required: false, 256 | base_concepts: None, 257 | children_presentational: false, 258 | name_from: Some(&[&ARIANameFromSources::Author]), 259 | prohibited_props: None, 260 | props: Some(&phf_ordered_map! { 261 | "aria-modal" => &None, 262 | }), 263 | related_concepts: None, 264 | require_context_role: None, 265 | required_context_role: None, 266 | required_owned_elements: None, 267 | required_props: None, 268 | super_class: Some(&[&[&ARIARoleDefinitionKey::ARIAAbstractRole(ARIAAbstractRole::RoleType)]]) 269 | }, 270 | }; 271 | -------------------------------------------------------------------------------- /deny.toml: -------------------------------------------------------------------------------- 1 | # This template contains all of the possible sections and their default values 2 | 3 | # Note that all fields that take a lint level have these possible values: 4 | # * deny - An error will be produced and the check will fail 5 | # * warn - A warning will be produced, but the check will not fail 6 | # * allow - No warning or error will be produced, though in some cases a note 7 | # will be 8 | 9 | # The values provided in this template are the default values that will be used 10 | # when any section or field is not specified in your own configuration 11 | 12 | # Root options 13 | 14 | # The graph table configures how the dependency graph is constructed and thus 15 | # which crates the checks are performed against 16 | [graph] 17 | # If 1 or more target triples (and optionally, target_features) are specified, 18 | # only the specified targets will be checked when running `cargo deny check`. 19 | # This means, if a particular package is only ever used as a target specific 20 | # dependency, such as, for example, the `nix` crate only being used via the 21 | # `target_family = "unix"` configuration, that only having windows targets in 22 | # this list would mean the nix crate, as well as any of its exclusive 23 | # dependencies not shared by any other crates, would be ignored, as the target 24 | # list here is effectively saying which targets you are building for. 25 | targets = [ 26 | # The triple can be any string, but only the target triples built in to 27 | # rustc (as of 1.40) can be checked against actual config expressions 28 | #"x86_64-unknown-linux-musl", 29 | # You can also specify which target_features you promise are enabled for a 30 | # particular target. target_features are currently not validated against 31 | # the actual valid features supported by the target architecture. 32 | #{ triple = "wasm32-unknown-unknown", features = ["atomics"] }, 33 | ] 34 | # When creating the dependency graph used as the source of truth when checks are 35 | # executed, this field can be used to prune crates from the graph, removing them 36 | # from the view of cargo-deny. This is an extremely heavy hammer, as if a crate 37 | # is pruned from the graph, all of its dependencies will also be pruned unless 38 | # they are connected to another crate in the graph that hasn't been pruned, 39 | # so it should be used with care. The identifiers are [Package ID Specifications] 40 | # (https://doc.rust-lang.org/cargo/reference/pkgid-spec.html) 41 | #exclude = [] 42 | # If true, metadata will be collected with `--all-features`. Note that this can't 43 | # be toggled off if true, if you want to conditionally enable `--all-features` it 44 | # is recommended to pass `--all-features` on the cmd line instead 45 | all-features = false 46 | # If true, metadata will be collected with `--no-default-features`. The same 47 | # caveat with `all-features` applies 48 | no-default-features = false 49 | # If set, these feature will be enabled when collecting metadata. If `--features` 50 | # is specified on the cmd line they will take precedence over this option. 51 | #features = [] 52 | 53 | # The output table provides options for how/if diagnostics are outputted 54 | [output] 55 | # When outputting inclusion graphs in diagnostics that include features, this 56 | # option can be used to specify the depth at which feature edges will be added. 57 | # This option is included since the graphs can be quite large and the addition 58 | # of features from the crate(s) to all of the graph roots can be far too verbose. 59 | # This option can be overridden via `--feature-depth` on the cmd line 60 | feature-depth = 1 61 | 62 | # This section is considered when running `cargo deny check advisories` 63 | # More documentation for the advisories section can be found here: 64 | # https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html 65 | [advisories] 66 | # The path where the advisory databases are cloned/fetched into 67 | #db-path = "$CARGO_HOME/advisory-dbs" 68 | # The url(s) of the advisory databases to use 69 | #db-urls = ["https://github.com/rustsec/advisory-db"] 70 | # A list of advisory IDs to ignore. Note that ignored advisories will still 71 | # output a note when they are encountered. 72 | ignore = [ 73 | #"RUSTSEC-0000-0000", 74 | #{ id = "RUSTSEC-0000-0000", reason = "you can specify a reason the advisory is ignored" }, 75 | #"a-crate-that-is-yanked@0.1.1", # you can also ignore yanked crate versions if you wish 76 | #{ crate = "a-crate-that-is-yanked@0.1.1", reason = "you can specify why you are ignoring the yanked crate" }, 77 | ] 78 | # If this is true, then cargo deny will use the git executable to fetch advisory database. 79 | # If this is false, then it uses a built-in git library. 80 | # Setting this to true can be helpful if you have special authentication requirements that cargo-deny does not support. 81 | # See Git Authentication for more information about setting up git authentication. 82 | #git-fetch-with-cli = true 83 | 84 | # This section is considered when running `cargo deny check licenses` 85 | # More documentation for the licenses section can be found here: 86 | # https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html 87 | [licenses] 88 | # List of explicitly allowed licenses 89 | # See https://spdx.org/licenses/ for list of possible licenses 90 | # [possible values: any SPDX 3.11 short identifier (+ optional exception)]. 91 | allow = [ 92 | "MIT", 93 | "Apache-2.0", 94 | "Unicode-DFS-2016" 95 | #"Apache-2.0 WITH LLVM-exception", 96 | ] 97 | # The confidence threshold for detecting a license from license text. 98 | # The higher the value, the more closely the license text must be to the 99 | # canonical license text of a valid SPDX license file. 100 | # [possible values: any between 0.0 and 1.0]. 101 | confidence-threshold = 0.8 102 | # Allow 1 or more licenses on a per-crate basis, so that particular licenses 103 | # aren't accepted for every possible crate as with the normal allow list 104 | exceptions = [ 105 | # Each entry is the crate and version constraint, and its specific allow 106 | # list 107 | #{ allow = ["Zlib"], crate = "adler32" }, 108 | ] 109 | 110 | # Some crates don't have (easily) machine readable licensing information, 111 | # adding a clarification entry for it allows you to manually specify the 112 | # licensing information 113 | #[[licenses.clarify]] 114 | # The package spec the clarification applies to 115 | #crate = "ring" 116 | # The SPDX expression for the license requirements of the crate 117 | #expression = "MIT AND ISC AND OpenSSL" 118 | # One or more files in the crate's source used as the "source of truth" for 119 | # the license expression. If the contents match, the clarification will be used 120 | # when running the license check, otherwise the clarification will be ignored 121 | # and the crate will be checked normally, which may produce warnings or errors 122 | # depending on the rest of your configuration 123 | #license-files = [ 124 | # Each entry is a crate relative path, and the (opaque) hash of its contents 125 | #{ path = "LICENSE", hash = 0xbd0eed23 } 126 | #] 127 | 128 | [licenses.private] 129 | # If true, ignores workspace crates that aren't published, or are only 130 | # published to private registries. 131 | # To see how to mark a crate as unpublished (to the official registry), 132 | # visit https://doc.rust-lang.org/cargo/reference/manifest.html#the-publish-field. 133 | ignore = false 134 | # One or more private registries that you might publish crates to, if a crate 135 | # is only published to private registries, and ignore is true, the crate will 136 | # not have its license(s) checked 137 | registries = [ 138 | #"https://sekretz.com/registry 139 | ] 140 | 141 | # This section is considered when running `cargo deny check bans`. 142 | # More documentation about the 'bans' section can be found here: 143 | # https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html 144 | [bans] 145 | # Lint level for when multiple versions of the same crate are detected 146 | multiple-versions = "warn" 147 | # Lint level for when a crate version requirement is `*` 148 | wildcards = "allow" 149 | # The graph highlighting used when creating dotgraphs for crates 150 | # with multiple versions 151 | # * lowest-version - The path to the lowest versioned duplicate is highlighted 152 | # * simplest-path - The path to the version with the fewest edges is highlighted 153 | # * all - Both lowest-version and simplest-path are used 154 | highlight = "all" 155 | # The default lint level for `default` features for crates that are members of 156 | # the workspace that is being checked. This can be overridden by allowing/denying 157 | # `default` on a crate-by-crate basis if desired. 158 | workspace-default-features = "allow" 159 | # The default lint level for `default` features for external crates that are not 160 | # members of the workspace. This can be overridden by allowing/denying `default` 161 | # on a crate-by-crate basis if desired. 162 | external-default-features = "allow" 163 | # List of crates that are allowed. Use with care! 164 | allow = [ 165 | #"ansi_term@0.11.0", 166 | #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason it is allowed" }, 167 | ] 168 | # List of crates to deny 169 | deny = [ 170 | #"ansi_term@0.11.0", 171 | #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason it is banned" }, 172 | # Wrapper crates can optionally be specified to allow the crate when it 173 | # is a direct dependency of the otherwise banned crate 174 | #{ crate = "ansi_term@0.11.0", wrappers = ["this-crate-directly-depends-on-ansi_term"] }, 175 | ] 176 | 177 | # List of features to allow/deny 178 | # Each entry the name of a crate and a version range. If version is 179 | # not specified, all versions will be matched. 180 | #[[bans.features]] 181 | #crate = "reqwest" 182 | # Features to not allow 183 | #deny = ["json"] 184 | # Features to allow 185 | #allow = [ 186 | # "rustls", 187 | # "__rustls", 188 | # "__tls", 189 | # "hyper-rustls", 190 | # "rustls", 191 | # "rustls-pemfile", 192 | # "rustls-tls-webpki-roots", 193 | # "tokio-rustls", 194 | # "webpki-roots", 195 | #] 196 | # If true, the allowed features must exactly match the enabled feature set. If 197 | # this is set there is no point setting `deny` 198 | #exact = true 199 | 200 | # Certain crates/versions that will be skipped when doing duplicate detection. 201 | skip = [ 202 | #"ansi_term@0.11.0", 203 | #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason why it can't be updated/removed" }, 204 | ] 205 | # Similarly to `skip` allows you to skip certain crates during duplicate 206 | # detection. Unlike skip, it also includes the entire tree of transitive 207 | # dependencies starting at the specified crate, up to a certain depth, which is 208 | # by default infinite. 209 | skip-tree = [ 210 | #"ansi_term@0.11.0", # will be skipped along with _all_ of its direct and transitive dependencies 211 | #{ crate = "ansi_term@0.11.0", depth = 20 }, 212 | ] 213 | 214 | # This section is considered when running `cargo deny check sources`. 215 | # More documentation about the 'sources' section can be found here: 216 | # https://embarkstudios.github.io/cargo-deny/checks/sources/cfg.html 217 | [sources] 218 | # Lint level for what to happen when a crate from a crate registry that is not 219 | # in the allow list is encountered 220 | unknown-registry = "warn" 221 | # Lint level for what to happen when a crate from a git repository that is not 222 | # in the allow list is encountered 223 | unknown-git = "warn" 224 | # List of URLs for allowed crate registries. Defaults to the crates.io index 225 | # if not specified. If it is specified but empty, no registries are allowed. 226 | allow-registry = ["https://github.com/rust-lang/crates.io-index"] 227 | # List of URLs for allowed Git repositories 228 | allow-git = [] 229 | 230 | [sources.allow-org] 231 | # 1 or more github.com organizations to allow git sources for 232 | #github = [""] 233 | # 1 or more gitlab.com organizations to allow git sources for 234 | #gitlab = [""] 235 | # 1 or more bitbucket.org organizations to allow git sources for 236 | #bitbucket = [""] 237 | -------------------------------------------------------------------------------- /src/aria/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::definition::{ 2 | ARIAProperty, ARIAPropertyDefinition, ARIAPropertyDefinitionType, ARIAState, 3 | }; 4 | use phf::{phf_ordered_map, OrderedMap}; 5 | use std::collections::HashMap; 6 | 7 | static ARIA_PROPS_MAP: OrderedMap<&'static str, &'static ARIAPropertyDefinition> = phf_ordered_map! { 8 | "aria-activedescendant" => &ARIAPropertyDefinition { 9 | key: ARIAProperty::AriaActivedescendant, 10 | type_: ARIAPropertyDefinitionType::Id, 11 | values: None, 12 | allow_undefined: None, 13 | }, 14 | "aria-atomic" => &ARIAPropertyDefinition { 15 | key: ARIAProperty::AriaAtomic, 16 | type_: ARIAPropertyDefinitionType::Boolean, 17 | values: None, 18 | allow_undefined: None, 19 | }, 20 | "aria-autocomplete" => &ARIAPropertyDefinition { 21 | key: ARIAProperty::AriaAutocomplete, 22 | type_: ARIAPropertyDefinitionType::Token, 23 | values: Some(&["inline", "list", "both", "none"]), 24 | allow_undefined: None, 25 | }, 26 | "aria-braillelabel" => &ARIAPropertyDefinition { 27 | key: ARIAProperty::AriaBraillelabel, 28 | type_: ARIAPropertyDefinitionType::String, 29 | values: None, 30 | allow_undefined: None, 31 | }, 32 | "aria-brailleroledescription" => &ARIAPropertyDefinition { 33 | key: ARIAProperty::AriaBrailleroledescription, 34 | type_: ARIAPropertyDefinitionType::String, 35 | values: None, 36 | allow_undefined: None, 37 | }, 38 | "aria-busy" => &ARIAPropertyDefinition { 39 | key: ARIAProperty::ARIAState(ARIAState::AriaBusy), 40 | type_: ARIAPropertyDefinitionType::Boolean, 41 | values: None, 42 | allow_undefined: None, 43 | }, 44 | "aria-checked" => &ARIAPropertyDefinition { 45 | key: ARIAProperty::ARIAState(ARIAState::AriaChecked), 46 | type_: ARIAPropertyDefinitionType::Tristate, 47 | values: None, 48 | allow_undefined: None, 49 | }, 50 | "aria-colcount" => &ARIAPropertyDefinition { 51 | key: ARIAProperty::AriaColcount, 52 | type_: ARIAPropertyDefinitionType::Integer, 53 | values: None, 54 | allow_undefined: None, 55 | }, 56 | "aria-colspan" => &ARIAPropertyDefinition { 57 | key: ARIAProperty::AriaColspan, 58 | type_: ARIAPropertyDefinitionType::Integer, 59 | values: None, 60 | allow_undefined: None, 61 | }, 62 | "aria-controls" => &ARIAPropertyDefinition { 63 | key: ARIAProperty::AriaControls, 64 | type_: ARIAPropertyDefinitionType::IdList, 65 | values: None, 66 | allow_undefined: None, 67 | }, 68 | "aria-current" => &ARIAPropertyDefinition { 69 | key: ARIAProperty::AriaCurrent, 70 | type_: ARIAPropertyDefinitionType::Token, 71 | values: Some(&["page", "step", "location", "date", "time", "true", "false"]), 72 | allow_undefined: None, 73 | }, 74 | "aria-describedby" => &ARIAPropertyDefinition { 75 | key: ARIAProperty::AriaDescribedby, 76 | type_: ARIAPropertyDefinitionType::IdList, 77 | values: None, 78 | allow_undefined: None, 79 | }, 80 | "aria-description" => &ARIAPropertyDefinition { 81 | key: ARIAProperty::AriaDescription, 82 | type_: ARIAPropertyDefinitionType::String, 83 | values: None, 84 | allow_undefined: None, 85 | }, 86 | "aria-details" => &ARIAPropertyDefinition { 87 | key: ARIAProperty::AriaDetails, 88 | type_: ARIAPropertyDefinitionType::Id, 89 | values: None, 90 | allow_undefined: None, 91 | }, 92 | "aria-disabled" => &ARIAPropertyDefinition { 93 | key: ARIAProperty::ARIAState(ARIAState::AriaDisabled), 94 | type_: ARIAPropertyDefinitionType::Boolean, 95 | values: None, 96 | allow_undefined: None, 97 | }, 98 | "aria-dropeffect" => &ARIAPropertyDefinition { 99 | key: ARIAProperty::AriaDropeffect, 100 | type_: ARIAPropertyDefinitionType::TokenList, 101 | values: Some(&["copy", "execute", "link", "move", "none", "popup"]), 102 | allow_undefined: None, 103 | }, 104 | "aria-errormessage" => &ARIAPropertyDefinition { 105 | key: ARIAProperty::AriaErrormessage, 106 | type_: ARIAPropertyDefinitionType::Id, 107 | values: None, 108 | allow_undefined: None, 109 | }, 110 | "aria-expanded" => &ARIAPropertyDefinition { 111 | key: ARIAProperty::ARIAState(ARIAState::AriaExpanded), 112 | type_: ARIAPropertyDefinitionType::Boolean, 113 | values: None, 114 | allow_undefined: Some(true), 115 | }, 116 | "aria-flowto" => &ARIAPropertyDefinition { 117 | key: ARIAProperty::AriaFlowto, 118 | type_: ARIAPropertyDefinitionType::IdList, 119 | values: None, 120 | allow_undefined: None, 121 | }, 122 | "aria-grabbed" => &ARIAPropertyDefinition { 123 | key: ARIAProperty::ARIAState(ARIAState::AriaGrabbed), 124 | type_: ARIAPropertyDefinitionType::Boolean, 125 | values: None, 126 | allow_undefined: Some(true), 127 | }, 128 | "aria-haspopup" => &ARIAPropertyDefinition { 129 | key: ARIAProperty::AriaHaspopup, 130 | type_: ARIAPropertyDefinitionType::Token, 131 | values: Some(&["false", "true", "menu", "listbox", "tree", "grid", "dialog"]), 132 | allow_undefined: None, 133 | }, 134 | "aria-hidden" => &ARIAPropertyDefinition { 135 | key: ARIAProperty::ARIAState(ARIAState::AriaHidden), 136 | type_: ARIAPropertyDefinitionType::Boolean, 137 | values: None, 138 | allow_undefined: Some(true), 139 | }, 140 | "aria-invalid" => &ARIAPropertyDefinition { 141 | key: ARIAProperty::ARIAState(ARIAState::AriaInvalid), 142 | type_: ARIAPropertyDefinitionType::Token, 143 | values: Some(&["grammar", "false", "spelling", "true"]), 144 | allow_undefined: None, 145 | }, 146 | "aria-keyshortcuts" => &ARIAPropertyDefinition { 147 | key: ARIAProperty::AriaKeyshortcuts, 148 | type_: ARIAPropertyDefinitionType::String, 149 | values: None, 150 | allow_undefined: None, 151 | }, 152 | "aria-label" => &ARIAPropertyDefinition { 153 | key: ARIAProperty::AriaLabel, 154 | type_: ARIAPropertyDefinitionType::String, 155 | values: None, 156 | allow_undefined: None, 157 | }, 158 | "aria-labelledby" => &ARIAPropertyDefinition { 159 | key: ARIAProperty::AriaLabelledby, 160 | type_: ARIAPropertyDefinitionType::IdList, 161 | values: None, 162 | allow_undefined: None, 163 | }, 164 | "aria-level" => &ARIAPropertyDefinition { 165 | key: ARIAProperty::AriaLevel, 166 | type_: ARIAPropertyDefinitionType::Integer, 167 | values: None, 168 | allow_undefined: None, 169 | }, 170 | "aria-live" => &ARIAPropertyDefinition { 171 | key: ARIAProperty::AriaLive, 172 | type_: ARIAPropertyDefinitionType::Token, 173 | values: Some(&["off", "polite", "assertive"]), 174 | allow_undefined: None, 175 | }, 176 | "aria-modal" => &ARIAPropertyDefinition { 177 | key: ARIAProperty::AriaModal, 178 | type_: ARIAPropertyDefinitionType::Boolean, 179 | values: None, 180 | allow_undefined: None, 181 | }, 182 | "aria-multiline" => &ARIAPropertyDefinition { 183 | key: ARIAProperty::AriaMultiline, 184 | type_: ARIAPropertyDefinitionType::Boolean, 185 | values: None, 186 | allow_undefined: None, 187 | }, 188 | "aria-multiselectable" => &ARIAPropertyDefinition { 189 | key: ARIAProperty::AriaMultiselectable, 190 | type_: ARIAPropertyDefinitionType::Boolean, 191 | values: None, 192 | allow_undefined: None, 193 | }, 194 | "aria-orientation" => &ARIAPropertyDefinition { 195 | key: ARIAProperty::AriaOrientation, 196 | type_: ARIAPropertyDefinitionType::Token, 197 | values: Some(&["horizontal", "vertical", "undefined"]), 198 | allow_undefined: None, 199 | }, 200 | "aria-owns" => &ARIAPropertyDefinition { 201 | key: ARIAProperty::AriaOwns, 202 | type_: ARIAPropertyDefinitionType::IdList, 203 | values: None, 204 | allow_undefined: None, 205 | }, 206 | "aria-placeholder" => &ARIAPropertyDefinition { 207 | key: ARIAProperty::AriaPlaceholder, 208 | type_: ARIAPropertyDefinitionType::String, 209 | values: None, 210 | allow_undefined: None, 211 | }, 212 | "aria-posinset" => &ARIAPropertyDefinition { 213 | key: ARIAProperty::AriaPosinset, 214 | type_: ARIAPropertyDefinitionType::Integer, 215 | values: None, 216 | allow_undefined: None, 217 | }, 218 | "aria-pressed" => &ARIAPropertyDefinition { 219 | key: ARIAProperty::ARIAState(ARIAState::AriaPressed), 220 | type_: ARIAPropertyDefinitionType::Tristate, 221 | values: None, 222 | allow_undefined: None, 223 | }, 224 | "aria-readonly" => &ARIAPropertyDefinition { 225 | key: ARIAProperty::AriaReadonly, 226 | type_: ARIAPropertyDefinitionType::Boolean, 227 | values: None, 228 | allow_undefined: None, 229 | }, 230 | "aria-relevant" => &ARIAPropertyDefinition { 231 | key: ARIAProperty::AriaRelevant, 232 | type_: ARIAPropertyDefinitionType::TokenList, 233 | values: Some(&["additions", "removals", "text", "all"]), 234 | allow_undefined: None, 235 | }, 236 | "aria-required" => &ARIAPropertyDefinition { 237 | key: ARIAProperty::AriaRequired, 238 | type_: ARIAPropertyDefinitionType::Boolean, 239 | values: None, 240 | allow_undefined: None, 241 | }, 242 | "aria-roledescription" => &ARIAPropertyDefinition { 243 | key: ARIAProperty::AriaRoledescription, 244 | type_: ARIAPropertyDefinitionType::String, 245 | values: None, 246 | allow_undefined: None, 247 | }, 248 | "aria-rowcount" => &ARIAPropertyDefinition { 249 | key: ARIAProperty::AriaRowcount, 250 | type_: ARIAPropertyDefinitionType::Integer, 251 | values: None, 252 | allow_undefined: None, 253 | }, 254 | "aria-rowindex" => &ARIAPropertyDefinition { 255 | key: ARIAProperty::AriaRowindex, 256 | type_: ARIAPropertyDefinitionType::Integer, 257 | values: None, 258 | allow_undefined: None, 259 | }, 260 | "aria-rowspan" => &ARIAPropertyDefinition { 261 | key: ARIAProperty::AriaRowspan, 262 | type_: ARIAPropertyDefinitionType::Integer, 263 | values: None, 264 | allow_undefined: None, 265 | }, 266 | "aria-selected" => &ARIAPropertyDefinition { 267 | key: ARIAProperty::ARIAState(ARIAState::AriaSelected), 268 | type_: ARIAPropertyDefinitionType::Boolean, 269 | values: None, 270 | allow_undefined: Some(true), 271 | }, 272 | "aria-setsize" => &ARIAPropertyDefinition { 273 | key: ARIAProperty::AriaSetsize, 274 | type_: ARIAPropertyDefinitionType::Integer, 275 | values: None, 276 | allow_undefined: None, 277 | }, 278 | "aria-sort" => &ARIAPropertyDefinition { 279 | key: ARIAProperty::AriaSort, 280 | type_: ARIAPropertyDefinitionType::Token, 281 | values: Some(&["ascending", "descending", "none", "other"]), 282 | allow_undefined: None, 283 | }, 284 | "aria-valuemax" => &ARIAPropertyDefinition { 285 | key: ARIAProperty::AriaValuemax, 286 | type_: ARIAPropertyDefinitionType::Number, 287 | values: None, 288 | allow_undefined: None, 289 | }, 290 | "aria-valuemin" => &ARIAPropertyDefinition { 291 | key: ARIAProperty::AriaValuemin, 292 | type_: ARIAPropertyDefinitionType::Number, 293 | values: None, 294 | allow_undefined: None, 295 | }, 296 | "aria-valuenow" => &ARIAPropertyDefinition { 297 | key: ARIAProperty::AriaValuenow, 298 | type_: ARIAPropertyDefinitionType::Number, 299 | values: None, 300 | allow_undefined: None, 301 | }, 302 | "aria-valuetext" => &ARIAPropertyDefinition { 303 | key: ARIAProperty::AriaValuetext, 304 | type_: ARIAPropertyDefinitionType::String, 305 | values: None, 306 | allow_undefined: None, 307 | }, 308 | }; 309 | 310 | pub fn entries() -> HashMap<&'static str, &'static ARIAPropertyDefinition> { 311 | ARIA_PROPS_MAP.entries().map(|(k, v)| (*k, *v)).collect() 312 | } 313 | 314 | pub fn for_each(mut callback: impl FnMut(&'static str, &'static ARIAPropertyDefinition)) { 315 | ARIA_PROPS_MAP.into_iter().for_each(|(k, v)| callback(k, v)); 316 | } 317 | 318 | pub fn get(name: &str) -> Option<&'static ARIAPropertyDefinition> { 319 | match ARIA_PROPS_MAP.get(name) { 320 | Some(v) => Some(v), 321 | None => None, 322 | } 323 | } 324 | 325 | pub fn has(name: &str) -> bool { 326 | ARIA_PROPS_MAP.contains_key(name) 327 | } 328 | 329 | pub fn keys() -> impl Iterator { 330 | ARIA_PROPS_MAP.keys().copied() 331 | } 332 | 333 | pub fn values() -> impl Iterator { 334 | ARIA_PROPS_MAP.values().copied() 335 | } 336 | 337 | #[cfg(test)] 338 | mod test { 339 | use crate::aria; 340 | use insta::{assert_json_snapshot, Settings}; 341 | 342 | #[test] 343 | fn snapshot_for_entries() { 344 | let aria_entries = aria::entries(); 345 | 346 | let mut settings = Settings::clone_current(); 347 | settings.set_sort_maps(true); 348 | settings.bind(|| { 349 | assert_json_snapshot!(aria_entries); 350 | }); 351 | } 352 | 353 | #[test] 354 | fn test_for_each() { 355 | let mut el_count = 0; 356 | aria::for_each(|_, _| el_count += 1); 357 | assert_eq!(el_count, 50); 358 | let mut elements_list = Vec::new(); 359 | aria::for_each(|k, _| { 360 | elements_list.push(k); 361 | }); 362 | assert_eq!(elements_list, aria::keys().collect::>()); 363 | } 364 | 365 | #[test] 366 | fn test_get() { 367 | assert!(aria::get("aria-activedescendant").is_some()); 368 | assert!(aria::get("aria-unknown").is_none()); 369 | } 370 | 371 | #[test] 372 | fn test_has() { 373 | assert!(aria::has("aria-activedescendant")); 374 | assert!(!aria::has("aria-unknown")); 375 | } 376 | 377 | #[test] 378 | fn test_keys() { 379 | let keys = aria::keys().collect::>(); 380 | for key in keys { 381 | assert!(aria::entries().contains_key(key)); 382 | } 383 | } 384 | } 385 | -------------------------------------------------------------------------------- /src/definition/mod.rs: -------------------------------------------------------------------------------- 1 | use phf::OrderedMap; 2 | #[cfg(test)] 3 | use serde::{ser::SerializeStruct, Serialize}; 4 | 5 | #[cfg_attr(test, derive(Serialize))] 6 | pub enum ARIAAbstractRole { 7 | Command, 8 | Composite, 9 | Input, 10 | Landmark, 11 | Range, 12 | RoleType, 13 | Section, 14 | SectionHead, 15 | Select, 16 | Structure, 17 | Widget, 18 | Window, 19 | } 20 | 21 | #[cfg_attr(test, derive(Serialize))] 22 | pub enum ARIAWidgetRole { 23 | Button, 24 | CheckBox, 25 | GridCell, 26 | Link, 27 | MenuItem, 28 | MenuItemCheckBox, 29 | MenuItemRadio, 30 | Option, 31 | ProgressBar, 32 | Radio, 33 | ScrollBar, 34 | SearchBox, 35 | Slider, 36 | SpinButton, 37 | Switch, 38 | Tab, 39 | TabPanel, 40 | TextBox, 41 | TreeItem, 42 | } 43 | 44 | #[cfg_attr(test, derive(Serialize))] 45 | pub enum ARIACompositeWidgetRole { 46 | ComboBox, 47 | Grid, 48 | ListBox, 49 | Menu, 50 | MenuBar, 51 | RadioGroup, 52 | TabList, 53 | Tree, 54 | TreeGrid, 55 | } 56 | 57 | #[cfg_attr(test, derive(Serialize))] 58 | pub enum ARIADocumentStructureRole { 59 | Application, 60 | Article, 61 | BlockQuote, 62 | Caption, 63 | Cell, 64 | ColumnHeader, 65 | Definition, 66 | Deletion, 67 | Directory, 68 | Document, 69 | Emphasis, 70 | Feed, 71 | Figure, 72 | Generic, 73 | Group, 74 | Heading, 75 | Img, 76 | Insertion, 77 | List, 78 | ListItem, 79 | Mark, 80 | Math, 81 | Meter, 82 | None, 83 | Note, 84 | Paragraph, 85 | Presentation, 86 | Row, 87 | RowGroup, 88 | RowHeader, 89 | Separator, 90 | Strong, 91 | Subscript, 92 | Superscript, 93 | Table, 94 | Term, 95 | Time, 96 | ToolBar, 97 | ToolTip, 98 | } 99 | 100 | #[cfg_attr(test, derive(Serialize))] 101 | pub enum ARIALandmarkRole { 102 | Banner, 103 | Complementary, 104 | ContentInfo, 105 | Form, 106 | Main, 107 | Navigation, 108 | Region, 109 | Search, 110 | } 111 | 112 | #[cfg_attr(test, derive(Serialize))] 113 | pub enum ARIALiveRegionRole { 114 | Alert, 115 | Log, 116 | Marquee, 117 | Status, 118 | Timer, 119 | } 120 | 121 | #[cfg_attr(test, derive(Serialize))] 122 | pub enum ARIAWindowRole { 123 | AlertDialog, 124 | Dialog, 125 | } 126 | 127 | #[cfg_attr(test, derive(Serialize))] 128 | pub enum ARIAUncategorizedRole { 129 | Code, 130 | } 131 | 132 | // please define enum equal to the above flow type 133 | #[cfg_attr(test, derive(Serialize))] 134 | pub enum ARIADPubRole { 135 | DocAbstract, 136 | DocAcknowledgments, 137 | DocAfterword, 138 | DocAppendix, 139 | DocBacklink, 140 | DocBiblioentry, 141 | DocBibliography, 142 | DocBiblioref, 143 | DocChapter, 144 | DocColophon, 145 | DocConclusion, 146 | DocCover, 147 | DocCredit, 148 | DocCredits, 149 | DocDedication, 150 | DocEndnote, 151 | DocEndnotes, 152 | DocEpigraph, 153 | DocEpilogue, 154 | DocErrata, 155 | DocExample, 156 | DocFootnote, 157 | DocForeword, 158 | DocGlossary, 159 | DocGlossref, 160 | DocIndex, 161 | DocIntroduction, 162 | DocNoteref, 163 | DocNotice, 164 | DocPagebreak, 165 | DocPagelist, 166 | DocPart, 167 | DocPreface, 168 | DocPrologue, 169 | DocPullquote, 170 | DocQna, 171 | DocSubtitle, 172 | DocTip, 173 | DocToc, 174 | } 175 | 176 | #[cfg_attr(test, derive(Serialize))] 177 | pub enum ARIAGraphicsRole { 178 | GraphicsDocument, 179 | GraphicsObject, 180 | GraphicsSymbol, 181 | } 182 | 183 | #[cfg_attr(test, derive(Serialize))] 184 | pub enum ARIARole { 185 | ARIAWidgetRole(ARIAWidgetRole), 186 | ARIACompositeWidgetRole(ARIACompositeWidgetRole), 187 | ARIADocumentStructureRole(ARIADocumentStructureRole), 188 | ARIALandmarkRole(ARIALandmarkRole), 189 | ARIALiveRegionRole(ARIALiveRegionRole), 190 | ARIAWindowRole(ARIAWindowRole), 191 | ARIAUncategorizedRole(ARIAUncategorizedRole), 192 | ARIADPubRole(ARIADPubRole), 193 | ARIAGraphicsRole(ARIAGraphicsRole), 194 | } 195 | 196 | #[cfg_attr(test, derive(Serialize))] 197 | pub enum ARIARoleDefinitionKey { 198 | ARIAAbstractRole(ARIAAbstractRole), 199 | ARIARole(ARIARole), 200 | ARIADPubRole(ARIADPubRole), 201 | ARIAGraphicsRole(ARIAGraphicsRole), 202 | } 203 | 204 | #[cfg_attr(test, derive(Serialize))] 205 | pub enum ARIANameFromSources { 206 | Author, 207 | Contents, 208 | Prohibited, 209 | } 210 | 211 | #[cfg_attr(test, derive(Serialize))] 212 | pub enum ARIAState { 213 | AriaBusy, 214 | AriaChecked, 215 | AriaDisabled, 216 | AriaExpanded, 217 | AriaGrabbed, 218 | AriaHidden, 219 | AriaInvalid, 220 | AriaPressed, 221 | AriaSelected, 222 | } 223 | 224 | #[cfg_attr(test, derive(Serialize))] 225 | pub enum ARIAProperty { 226 | AriaActivedescendant, 227 | AriaAtomic, 228 | AriaAutocomplete, 229 | AriaBraillelabel, 230 | AriaBrailleroledescription, 231 | AriaColcount, 232 | AriaColindex, 233 | AriaColspan, 234 | AriaControls, 235 | AriaCurrent, 236 | AriaDescribedby, 237 | AriaDescription, 238 | AriaDetails, 239 | AriaDropeffect, 240 | AriaErrormessage, 241 | AriaFlowto, 242 | AriaHaspopup, 243 | AriaKeyshortcuts, 244 | AriaLabel, 245 | AriaLabelledby, 246 | AriaLevel, 247 | AriaLive, 248 | AriaModal, 249 | AriaMultiline, 250 | AriaMultiselectable, 251 | AriaOrientation, 252 | AriaOwns, 253 | AriaPlaceholder, 254 | AriaPosinset, 255 | AriaReadonly, 256 | AriaRelevant, 257 | AriaRequired, 258 | AriaRoledescription, 259 | AriaRowcount, 260 | AriaRowindex, 261 | AriaRowspan, 262 | AriaSetsize, 263 | AriaSort, 264 | AriaValuemax, 265 | AriaValuemin, 266 | AriaValuenow, 267 | AriaValuetext, 268 | ARIAState(ARIAState), 269 | } 270 | 271 | pub enum ARIAPropertyDefinitionType { 272 | String, 273 | Id, 274 | IdList, 275 | Integer, 276 | Number, 277 | Boolean, 278 | Token, 279 | TokenList, 280 | Tristate, 281 | } 282 | 283 | pub struct ARIAPropertyDefinition { 284 | pub key: ARIAProperty, 285 | pub type_: ARIAPropertyDefinitionType, 286 | pub values: Option<&'static [&'static str]>, 287 | pub allow_undefined: Option, 288 | } 289 | 290 | #[cfg(test)] 291 | impl Serialize for ARIAPropertyDefinition { 292 | fn serialize(&self, serializer: S) -> Result 293 | where 294 | S: serde::Serializer, 295 | { 296 | let mut state = serializer.serialize_struct("ARIAProperty", 4)?; 297 | state.serialize_field( 298 | "key", 299 | match self.key { 300 | ARIAProperty::AriaActivedescendant => "aria-activedescendant", 301 | ARIAProperty::AriaAtomic => "aria-atomic", 302 | ARIAProperty::AriaAutocomplete => "aria-autocomplete", 303 | ARIAProperty::AriaBraillelabel => "aria-braillelabel", 304 | ARIAProperty::AriaBrailleroledescription => "aria-brailleroledescription", 305 | ARIAProperty::AriaColcount => "aria-colcount", 306 | ARIAProperty::AriaColindex => "aria-colindex", 307 | ARIAProperty::AriaColspan => "aria-colspan", 308 | ARIAProperty::AriaControls => "aria-controls", 309 | ARIAProperty::AriaCurrent => "aria-current", 310 | ARIAProperty::AriaDescribedby => "aria-describedby", 311 | ARIAProperty::AriaDescription => "aria-description", 312 | ARIAProperty::AriaDetails => "aria-details", 313 | ARIAProperty::AriaDropeffect => "aria-dropeffect", 314 | ARIAProperty::AriaErrormessage => "aria-errormessage", 315 | ARIAProperty::AriaFlowto => "aria-flowto", 316 | ARIAProperty::AriaHaspopup => "aria-haspopup", 317 | ARIAProperty::AriaKeyshortcuts => "aria-keyshortcuts", 318 | ARIAProperty::AriaLabel => "aria-label", 319 | ARIAProperty::AriaLabelledby => "aria-labelledby", 320 | ARIAProperty::AriaLevel => "aria-level", 321 | ARIAProperty::AriaLive => "aria-live", 322 | ARIAProperty::AriaModal => "aria-modal", 323 | ARIAProperty::AriaMultiline => "aria-multiline", 324 | ARIAProperty::AriaMultiselectable => "aria-multiselectable", 325 | ARIAProperty::AriaOrientation => "aria-orientation", 326 | ARIAProperty::AriaOwns => "aria-owns", 327 | ARIAProperty::AriaPlaceholder => "aria-placeholder", 328 | ARIAProperty::AriaPosinset => "aria-posinset", 329 | ARIAProperty::AriaReadonly => "aria-readonly", 330 | ARIAProperty::AriaRelevant => "aria-relevant", 331 | ARIAProperty::AriaRequired => "aria-required", 332 | ARIAProperty::AriaRoledescription => "aria-roledescription", 333 | ARIAProperty::AriaRowcount => "aria-rowcount", 334 | ARIAProperty::AriaRowindex => "aria-rowindex", 335 | ARIAProperty::AriaRowspan => "aria-rowspan", 336 | ARIAProperty::AriaSetsize => "aria-setsize", 337 | ARIAProperty::AriaSort => "aria-sort", 338 | ARIAProperty::AriaValuemax => "aria-valuemax", 339 | ARIAProperty::AriaValuemin => "aria-valuemin", 340 | ARIAProperty::AriaValuenow => "aria-valuenow", 341 | ARIAProperty::AriaValuetext => "aria-valuetext", 342 | ARIAProperty::ARIAState(ARIAState::AriaBusy) => "aria-busy", 343 | ARIAProperty::ARIAState(ARIAState::AriaChecked) => "aria-checked", 344 | ARIAProperty::ARIAState(ARIAState::AriaDisabled) => "aria-disabled", 345 | ARIAProperty::ARIAState(ARIAState::AriaExpanded) => "aria-expanded", 346 | ARIAProperty::ARIAState(ARIAState::AriaGrabbed) => "aria-grabbed", 347 | ARIAProperty::ARIAState(ARIAState::AriaHidden) => "aria-hidden", 348 | ARIAProperty::ARIAState(ARIAState::AriaInvalid) => "aria-invalid", 349 | ARIAProperty::ARIAState(ARIAState::AriaPressed) => "aria-pressed", 350 | ARIAProperty::ARIAState(ARIAState::AriaSelected) => "aria-selected", 351 | }, 352 | )?; 353 | state.serialize_field( 354 | "type", 355 | match self.type_ { 356 | ARIAPropertyDefinitionType::String => "string", 357 | ARIAPropertyDefinitionType::Id => "id", 358 | ARIAPropertyDefinitionType::IdList => "idlist", 359 | ARIAPropertyDefinitionType::Integer => "integer", 360 | ARIAPropertyDefinitionType::Number => "number", 361 | ARIAPropertyDefinitionType::Boolean => "boolean", 362 | ARIAPropertyDefinitionType::Token => "token", 363 | ARIAPropertyDefinitionType::TokenList => "tokenlist", 364 | ARIAPropertyDefinitionType::Tristate => "tristate", 365 | }, 366 | )?; 367 | match &self.values { 368 | Some(values) => { 369 | state.serialize_field("values", &values)?; 370 | } 371 | None => { 372 | state.skip_field("values")?; 373 | } 374 | }; 375 | match self.allow_undefined { 376 | Some(allow_undefined) => { 377 | state.serialize_field("allow_undefined", &allow_undefined)?; 378 | } 379 | None => { 380 | state.skip_field("allow_undefined")?; 381 | } 382 | }; 383 | 384 | state.end() 385 | } 386 | } 387 | 388 | #[cfg_attr(test, derive(Serialize))] 389 | pub enum ARIAPropertyCurrent { 390 | Page, 391 | Step, 392 | Location, 393 | Date, 394 | Time, 395 | True, 396 | False, 397 | } 398 | 399 | // These constraints are drawn from the mapping between ARIA and HTML: 400 | // https://www.w3.org/TR/html-aria 401 | #[cfg_attr(test, derive(Serialize))] 402 | pub struct ARIARoleRelationConceptAttributeConstraints { 403 | // The attribute does not exist on the node: 404 | pub undefined: bool, 405 | // The attribute has a value: 406 | pub set: bool, 407 | pub gt1: bool, 408 | } 409 | 410 | #[cfg_attr(test, derive(Serialize))] 411 | pub struct ARIARoleRelationConceptAttribute { 412 | pub name: String, 413 | pub value: Option, 414 | pub constraints: Option, 415 | } 416 | 417 | // These constraints are drawn from the mapping between ARIA and HTML: 418 | // https://www.w3.org/TR/html-aria 419 | #[cfg_attr(test, derive(Serialize))] 420 | pub struct ARIARoleRelationConceptConstraints { 421 | pub scoped_to_the_body_element: bool, 422 | pub scoped_to_the_main_element: bool, 423 | pub scoped_to_a_sectioning_root_element_other_than_body: bool, 424 | pub scoped_to_a_sectioning_content_element: bool, 425 | pub direct_descendant_of_document: bool, 426 | pub direct_descendant_of_ol: bool, 427 | pub direct_descendant_of_ul: bool, 428 | pub direct_descendant_of_menu: bool, 429 | pub direct_descendant_of_details_element_with_the_open_attribute_defined: bool, 430 | pub ancestor_table_element_has_table_role: bool, 431 | pub ancestor_table_element_has_grid_role: bool, 432 | pub ancestor_table_element_has_treegrid_role: bool, 433 | pub the_size_attribute_value_is_greater_than_1: bool, 434 | pub the_multiple_attribute_is_not_set_and_the_size_attribute_does_not_have_a_value_greater_than_1: 435 | bool, 436 | pub the_list_attribute_is_not_set: bool, 437 | } 438 | 439 | /* The concept in a related domain that informs behavior mappings. 440 | ** Related domains include: HTML, "Device Independence Delivery Unit", XForms, 441 | ** and ARIA to name a few. 442 | **/ 443 | pub struct ARIARoleRelationConcept { 444 | pub name: &'static str, 445 | pub attributes: Option>, 446 | pub constraints: Option, 447 | } 448 | 449 | #[cfg(test)] 450 | impl Serialize for ARIARoleRelationConcept { 451 | fn serialize(&self, serializer: S) -> Result 452 | where 453 | S: serde::Serializer, 454 | { 455 | let mut state = serializer.serialize_struct("ARIARoleRelation", 4)?; 456 | 457 | match &self.attributes { 458 | Some(values) => { 459 | state.serialize_field("attributes", &values)?; 460 | } 461 | None => { 462 | state.skip_field("attributes")?; 463 | } 464 | }; 465 | 466 | match &self.constraints { 467 | Some(values) => { 468 | state.serialize_field("constraints", &values)?; 469 | } 470 | None => { 471 | state.skip_field("constraints")?; 472 | } 473 | }; 474 | 475 | state.end() 476 | } 477 | } 478 | 479 | #[cfg_attr(test, derive(Serialize))] 480 | pub struct ARIARoleRelation { 481 | pub module: Option<&'static str>, 482 | pub concept: Option, 483 | } 484 | 485 | pub type ARIAProps = OrderedMap<&'static str, &'static Option>; 486 | 487 | pub struct ARIARoleDefinition { 488 | /* Abstract roles may not be used in HTML. */ 489 | pub is_abstract: bool, 490 | pub accessible_name_required: bool, 491 | /* The concepts in related domains that inform behavior mappings. */ 492 | pub base_concepts: Option<&'static [&'static ARIARoleRelation]>, 493 | /* Child presentational roles strip child nodes of roles and flatten the content to text. */ 494 | pub children_presentational: bool, 495 | pub name_from: Option<&'static [&'static ARIANameFromSources]>, 496 | /* aria-* properties and states disallowed on this role. */ 497 | pub prohibited_props: Option<&'static [&'static ARIAProperty]>, 498 | /* aria-* properties and states allowed on this role. */ 499 | pub props: Option<&'static ARIAProps>, 500 | /* The concepts in related domains that inform behavior mappings. */ 501 | pub related_concepts: Option<&'static [ARIARoleRelation]>, 502 | pub require_context_role: Option<&'static [&'static ARIARole]>, 503 | pub required_context_role: Option<&'static [&'static ARIARole]>, 504 | pub required_owned_elements: Option<&'static [&'static [&'static ARIARole]]>, 505 | /* aria-* properties and states required on this role. */ 506 | pub required_props: Option<&'static ARIAProps>, 507 | /* An array or super class "stacks." Each stack contains a LIFO list of 508 | ** strings correspond to a super class in the inheritance chain of this 509 | ** role. Roles may have more than one inheritance chain, which is why 510 | ** this property is an array of arrays and not a single array. */ 511 | pub super_class: Option<&'static [&'static [&'static ARIARoleDefinitionKey]]>, 512 | } 513 | 514 | #[cfg(test)] 515 | impl Serialize for ARIARoleDefinition { 516 | fn serialize(&self, serializer: S) -> Result 517 | where 518 | S: serde::Serializer, 519 | { 520 | let mut state = serializer.serialize_struct("ARIARoleDefinition", 4)?; 521 | 522 | match &self.base_concepts { 523 | Some(values) => { 524 | state.serialize_field("base_concepts", &values)?; 525 | } 526 | None => { 527 | state.skip_field("base_concepts")?; 528 | } 529 | }; 530 | 531 | match &self.name_from { 532 | Some(values) => { 533 | state.serialize_field("name_from", &values)?; 534 | } 535 | None => { 536 | state.skip_field("name_from")?; 537 | } 538 | }; 539 | 540 | match &self.prohibited_props { 541 | Some(values) => { 542 | state.serialize_field("prohibited_props", &values)?; 543 | } 544 | None => { 545 | state.skip_field("prohibited_props")?; 546 | } 547 | }; 548 | 549 | match &self.related_concepts { 550 | Some(values) => { 551 | state.serialize_field("related_concepts", &values)?; 552 | } 553 | None => { 554 | state.skip_field("related_concepts")?; 555 | } 556 | }; 557 | 558 | state.end() 559 | } 560 | } 561 | 562 | pub type RoleDefinitions = OrderedMap<&'static str, &'static ARIARoleDefinition>; 563 | -------------------------------------------------------------------------------- /src/dom/mod.rs: -------------------------------------------------------------------------------- 1 | use phf::{phf_ordered_map, OrderedMap}; 2 | #[cfg(test)] 3 | use serde::Serialize; 4 | use std::collections::HashMap; 5 | 6 | #[derive(Debug, PartialEq, Eq, Hash)] 7 | pub enum DOMElements { 8 | A, 9 | Abbr, 10 | Acronym, 11 | Address, 12 | Applet, 13 | Area, 14 | Article, 15 | Aside, 16 | Audio, 17 | B, 18 | Base, 19 | Bdi, 20 | Bdo, 21 | Big, 22 | Blink, 23 | Blockquote, 24 | Body, 25 | Br, 26 | Button, 27 | Canvas, 28 | Caption, 29 | Center, 30 | Cite, 31 | Code, 32 | Col, 33 | Colgroup, 34 | Content, 35 | Data, 36 | Datalist, 37 | Dd, 38 | Del, 39 | Details, 40 | Dfn, 41 | Dialog, 42 | Dir, 43 | Div, 44 | Dl, 45 | Dt, 46 | Em, 47 | Embed, 48 | Fieldset, 49 | Figcaption, 50 | Figure, 51 | Font, 52 | Footer, 53 | Form, 54 | Frame, 55 | Frameset, 56 | H1, 57 | H2, 58 | H3, 59 | H4, 60 | H5, 61 | H6, 62 | Head, 63 | Header, 64 | Hgroup, 65 | Hr, 66 | Html, 67 | I, 68 | Iframe, 69 | Img, 70 | Input, 71 | Ins, 72 | Kbd, 73 | Keygen, 74 | Label, 75 | Legend, 76 | Li, 77 | Link, 78 | Main, 79 | Map, 80 | Mark, 81 | Marquee, 82 | Menu, 83 | MenuItem, 84 | Meta, 85 | Meter, 86 | Nav, 87 | Noembed, 88 | Noscript, 89 | Object, 90 | Ol, 91 | Optgroup, 92 | Option, 93 | Output, 94 | P, 95 | Param, 96 | Picture, 97 | Pre, 98 | Progress, 99 | Q, 100 | Rp, 101 | Rt, 102 | Rtc, 103 | Ruby, 104 | S, 105 | Samp, 106 | Script, 107 | Section, 108 | Select, 109 | Small, 110 | Source, 111 | Spacer, 112 | Span, 113 | Strike, 114 | Strong, 115 | Style, 116 | Sub, 117 | Summary, 118 | Sup, 119 | Table, 120 | Tbody, 121 | Td, 122 | Textarea, 123 | Tfoot, 124 | Th, 125 | Thead, 126 | Time, 127 | Title, 128 | Tr, 129 | Track, 130 | Tt, 131 | U, 132 | Ul, 133 | Var, 134 | Video, 135 | Wbr, 136 | Xmp, 137 | } 138 | 139 | #[cfg(test)] 140 | impl Serialize for DOMElements { 141 | fn serialize(&self, serializer: S) -> Result 142 | where 143 | S: serde::ser::Serializer, 144 | { 145 | let raw_dom_element = map_enum_dom_element_to_raw(self); 146 | raw_dom_element.serialize(serializer) 147 | } 148 | } 149 | 150 | static DOM_ELEMENTS: OrderedMap<&'static str, bool> = phf_ordered_map! { 151 | "a" => false, 152 | "abbr" => false, 153 | "acronym" => false, 154 | "address" => false, 155 | "applet" => false, 156 | "area" => false, 157 | "article" => false, 158 | "aside" => false, 159 | "audio" => false, 160 | "b" => false, 161 | "base" => true, 162 | "bdi" => false, 163 | "bdo" => false, 164 | "big" => false, 165 | "blink" => false, 166 | "blockquote" => false, 167 | "body" => false, 168 | "br" => false, 169 | "button" => false, 170 | "canvas" => false, 171 | "caption" => false, 172 | "center" => false, 173 | "cite" => false, 174 | "code" => false, 175 | "col" => true, 176 | "colgroup" => true, 177 | "content" => false, 178 | "data" => false, 179 | "datalist" => false, 180 | "dd" => false, 181 | "del" => false, 182 | "details" => false, 183 | "dfn" => false, 184 | "dialog" => false, 185 | "dir" => false, 186 | "div" => false, 187 | "dl" => false, 188 | "dt" => false, 189 | "em" => false, 190 | "embed" => false, 191 | "fieldset" => false, 192 | "figcaption" => false, 193 | "figure" => false, 194 | "font" => false, 195 | "footer" => false, 196 | "form" => false, 197 | "frame" => false, 198 | "frameset" => false, 199 | "h1" => false, 200 | "h2" => false, 201 | "h3" => false, 202 | "h4" => false, 203 | "h5" => false, 204 | "h6" => false, 205 | "head" => true, 206 | "header" => false, 207 | "hgroup" => false, 208 | "hr" => false, 209 | "html" => true, 210 | "i" => false, 211 | "iframe" => false, 212 | "img" => false, 213 | "input" => false, 214 | "ins" => false, 215 | "kbd" => false, 216 | "keygen" => false, 217 | "label" => false, 218 | "legend" => false, 219 | "li" => false, 220 | "link" => true, 221 | "main" => false, 222 | "map" => false, 223 | "mark" => false, 224 | "marquee" => false, 225 | "menu" => false, 226 | "menuitem" => false, 227 | "meta" => true, 228 | "meter" => false, 229 | "nav" => false, 230 | "noembed" => true, 231 | "noscript" => true, 232 | "object" => false, 233 | "ol" => false, 234 | "optgroup" => false, 235 | "option" => false, 236 | "output" => false, 237 | "p" => false, 238 | "param" => true, 239 | "picture" => true, 240 | "pre" => false, 241 | "progress" => false, 242 | "q" => false, 243 | "rp" => false, 244 | "rt" => false, 245 | "rtc" => false, 246 | "ruby" => false, 247 | "s" => false, 248 | "samp" => false, 249 | "script" => true, 250 | "section" => false, 251 | "select" => false, 252 | "small" => false, 253 | "source" => true, 254 | "spacer" => false, 255 | "span" => false, 256 | "strike" => false, 257 | "strong" => false, 258 | "style" => true, 259 | "sub" => false, 260 | "summary" => false, 261 | "sup" => false, 262 | "table" => false, 263 | "tbody" => false, 264 | "td" => false, 265 | "textarea" => false, 266 | "tfoot" => false, 267 | "th" => false, 268 | "thead" => false, 269 | "time" => false, 270 | "title" => true, 271 | "tr" => false, 272 | "track" => true, 273 | "tt" => false, 274 | "u" => false, 275 | "ul" => false, 276 | "var" => false, 277 | "video" => false, 278 | "wbr" => false, 279 | "xmp" => false, 280 | }; 281 | 282 | fn map_raw_dom_element_to_enum(raw_dom_element: &'static str) -> DOMElements { 283 | match raw_dom_element { 284 | "a" => DOMElements::A, 285 | "abbr" => DOMElements::Abbr, 286 | "acronym" => DOMElements::Acronym, 287 | "address" => DOMElements::Address, 288 | "applet" => DOMElements::Applet, 289 | "area" => DOMElements::Area, 290 | "article" => DOMElements::Article, 291 | "aside" => DOMElements::Aside, 292 | "audio" => DOMElements::Audio, 293 | "b" => DOMElements::B, 294 | "base" => DOMElements::Base, 295 | "bdi" => DOMElements::Bdi, 296 | "bdo" => DOMElements::Bdo, 297 | "big" => DOMElements::Big, 298 | "blink" => DOMElements::Blink, 299 | "blockquote" => DOMElements::Blockquote, 300 | "body" => DOMElements::Body, 301 | "br" => DOMElements::Br, 302 | "button" => DOMElements::Button, 303 | "canvas" => DOMElements::Canvas, 304 | "caption" => DOMElements::Caption, 305 | "center" => DOMElements::Center, 306 | "cite" => DOMElements::Cite, 307 | "code" => DOMElements::Code, 308 | "col" => DOMElements::Col, 309 | "colgroup" => DOMElements::Colgroup, 310 | "content" => DOMElements::Content, 311 | "data" => DOMElements::Data, 312 | "datalist" => DOMElements::Datalist, 313 | "dd" => DOMElements::Dd, 314 | "del" => DOMElements::Del, 315 | "details" => DOMElements::Details, 316 | "dfn" => DOMElements::Dfn, 317 | "dialog" => DOMElements::Dialog, 318 | "dir" => DOMElements::Dir, 319 | "div" => DOMElements::Div, 320 | "dl" => DOMElements::Dl, 321 | "dt" => DOMElements::Dt, 322 | "em" => DOMElements::Em, 323 | "embed" => DOMElements::Embed, 324 | "fieldset" => DOMElements::Fieldset, 325 | "figcaption" => DOMElements::Figcaption, 326 | "figure" => DOMElements::Figure, 327 | "font" => DOMElements::Font, 328 | "footer" => DOMElements::Footer, 329 | "form" => DOMElements::Form, 330 | "frame" => DOMElements::Frame, 331 | "frameset" => DOMElements::Frameset, 332 | "h1" => DOMElements::H1, 333 | "h2" => DOMElements::H2, 334 | "h3" => DOMElements::H3, 335 | "h4" => DOMElements::H4, 336 | "h5" => DOMElements::H5, 337 | "h6" => DOMElements::H6, 338 | "head" => DOMElements::Head, 339 | "header" => DOMElements::Header, 340 | "hgroup" => DOMElements::Hgroup, 341 | "hr" => DOMElements::Hr, 342 | "html" => DOMElements::Html, 343 | "i" => DOMElements::I, 344 | "iframe" => DOMElements::Iframe, 345 | "img" => DOMElements::Img, 346 | "input" => DOMElements::Input, 347 | "ins" => DOMElements::Ins, 348 | "kbd" => DOMElements::Kbd, 349 | "keygen" => DOMElements::Keygen, 350 | "label" => DOMElements::Label, 351 | "legend" => DOMElements::Legend, 352 | "li" => DOMElements::Li, 353 | "link" => DOMElements::Link, 354 | "main" => DOMElements::Main, 355 | "map" => DOMElements::Map, 356 | "mark" => DOMElements::Mark, 357 | "marquee" => DOMElements::Marquee, 358 | "menu" => DOMElements::Menu, 359 | "menuitem" => DOMElements::MenuItem, 360 | "meta" => DOMElements::Meta, 361 | "meter" => DOMElements::Meter, 362 | "nav" => DOMElements::Nav, 363 | "noembed" => DOMElements::Noembed, 364 | "noscript" => DOMElements::Noscript, 365 | "object" => DOMElements::Object, 366 | "ol" => DOMElements::Ol, 367 | "optgroup" => DOMElements::Optgroup, 368 | "option" => DOMElements::Option, 369 | "output" => DOMElements::Output, 370 | "p" => DOMElements::P, 371 | "param" => DOMElements::Param, 372 | "picture" => DOMElements::Picture, 373 | "pre" => DOMElements::Pre, 374 | "progress" => DOMElements::Progress, 375 | "q" => DOMElements::Q, 376 | "rp" => DOMElements::Rp, 377 | "rt" => DOMElements::Rt, 378 | "rtc" => DOMElements::Rtc, 379 | "ruby" => DOMElements::Ruby, 380 | "s" => DOMElements::S, 381 | "samp" => DOMElements::Samp, 382 | "script" => DOMElements::Script, 383 | "section" => DOMElements::Section, 384 | "select" => DOMElements::Select, 385 | "small" => DOMElements::Small, 386 | "source" => DOMElements::Source, 387 | "spacer" => DOMElements::Spacer, 388 | "span" => DOMElements::Span, 389 | "strike" => DOMElements::Strike, 390 | "strong" => DOMElements::Strong, 391 | "style" => DOMElements::Style, 392 | "sub" => DOMElements::Sub, 393 | "summary" => DOMElements::Summary, 394 | "sup" => DOMElements::Sup, 395 | "table" => DOMElements::Table, 396 | "tbody" => DOMElements::Tbody, 397 | "td" => DOMElements::Td, 398 | "textarea" => DOMElements::Textarea, 399 | "tfoot" => DOMElements::Tfoot, 400 | "th" => DOMElements::Th, 401 | "thead" => DOMElements::Thead, 402 | "time" => DOMElements::Time, 403 | "title" => DOMElements::Title, 404 | "tr" => DOMElements::Tr, 405 | "track" => DOMElements::Track, 406 | "tt" => DOMElements::Tt, 407 | "u" => DOMElements::U, 408 | "ul" => DOMElements::Ul, 409 | "var" => DOMElements::Var, 410 | "video" => DOMElements::Video, 411 | "wbr" => DOMElements::Wbr, 412 | "xmp" => DOMElements::Xmp, 413 | _ => unreachable!("Unknown DOM element: {}", raw_dom_element), 414 | } 415 | } 416 | 417 | fn map_enum_dom_element_to_raw(dom_element: &DOMElements) -> &'static str { 418 | match dom_element { 419 | DOMElements::A => "a", 420 | DOMElements::Abbr => "abbr", 421 | DOMElements::Acronym => "acronym", 422 | DOMElements::Address => "address", 423 | DOMElements::Applet => "applet", 424 | DOMElements::Area => "area", 425 | DOMElements::Article => "article", 426 | DOMElements::Aside => "aside", 427 | DOMElements::Audio => "audio", 428 | DOMElements::B => "b", 429 | DOMElements::Base => "base", 430 | DOMElements::Bdi => "bdi", 431 | DOMElements::Bdo => "bdo", 432 | DOMElements::Big => "big", 433 | DOMElements::Blink => "blink", 434 | DOMElements::Blockquote => "blockquote", 435 | DOMElements::Body => "body", 436 | DOMElements::Br => "br", 437 | DOMElements::Button => "button", 438 | DOMElements::Canvas => "canvas", 439 | DOMElements::Caption => "caption", 440 | DOMElements::Center => "center", 441 | DOMElements::Cite => "cite", 442 | DOMElements::Code => "code", 443 | DOMElements::Col => "col", 444 | DOMElements::Colgroup => "colgroup", 445 | DOMElements::Content => "content", 446 | DOMElements::Data => "data", 447 | DOMElements::Datalist => "datalist", 448 | DOMElements::Dd => "dd", 449 | DOMElements::Del => "del", 450 | DOMElements::Details => "details", 451 | DOMElements::Dfn => "dfn", 452 | DOMElements::Dialog => "dialog", 453 | DOMElements::Dir => "dir", 454 | DOMElements::Div => "div", 455 | DOMElements::Dl => "dl", 456 | DOMElements::Dt => "dt", 457 | DOMElements::Em => "em", 458 | DOMElements::Embed => "embed", 459 | DOMElements::Fieldset => "fieldset", 460 | DOMElements::Figcaption => "figcaption", 461 | DOMElements::Figure => "figure", 462 | DOMElements::Font => "font", 463 | DOMElements::Footer => "footer", 464 | DOMElements::Form => "form", 465 | DOMElements::Frame => "frame", 466 | DOMElements::Frameset => "frameset", 467 | DOMElements::H1 => "h1", 468 | DOMElements::H2 => "h2", 469 | DOMElements::H3 => "h3", 470 | DOMElements::H4 => "h4", 471 | DOMElements::H5 => "h5", 472 | DOMElements::H6 => "h6", 473 | DOMElements::Head => "head", 474 | DOMElements::Header => "header", 475 | DOMElements::Hgroup => "hgroup", 476 | DOMElements::Hr => "hr", 477 | DOMElements::Html => "html", 478 | DOMElements::I => "i", 479 | DOMElements::Iframe => "iframe", 480 | DOMElements::Img => "img", 481 | DOMElements::Input => "input", 482 | DOMElements::Ins => "ins", 483 | DOMElements::Kbd => "kbd", 484 | DOMElements::Keygen => "keygen", 485 | DOMElements::Label => "label", 486 | DOMElements::Legend => "legend", 487 | DOMElements::Li => "li", 488 | DOMElements::Link => "link", 489 | DOMElements::Main => "main", 490 | DOMElements::Map => "map", 491 | DOMElements::Mark => "mark", 492 | DOMElements::Marquee => "marquee", 493 | DOMElements::Menu => "menu", 494 | DOMElements::MenuItem => "menuitem", 495 | DOMElements::Meta => "meta", 496 | DOMElements::Meter => "meter", 497 | DOMElements::Nav => "nav", 498 | DOMElements::Noembed => "noembed", 499 | DOMElements::Noscript => "noscript", 500 | DOMElements::Object => "object", 501 | DOMElements::Ol => "ol", 502 | DOMElements::Optgroup => "optgroup", 503 | DOMElements::Option => "option", 504 | DOMElements::Output => "output", 505 | DOMElements::P => "p", 506 | DOMElements::Param => "param", 507 | DOMElements::Picture => "picture", 508 | DOMElements::Pre => "pre", 509 | DOMElements::Progress => "progress", 510 | DOMElements::Q => "q", 511 | DOMElements::Rp => "rp", 512 | DOMElements::Rt => "rt", 513 | DOMElements::Rtc => "rtc", 514 | DOMElements::Ruby => "ruby", 515 | DOMElements::S => "s", 516 | DOMElements::Samp => "samp", 517 | DOMElements::Script => "script", 518 | DOMElements::Section => "section", 519 | DOMElements::Select => "select", 520 | DOMElements::Small => "small", 521 | DOMElements::Source => "source", 522 | DOMElements::Spacer => "spacer", 523 | DOMElements::Span => "span", 524 | DOMElements::Strike => "strike", 525 | DOMElements::Strong => "strong", 526 | DOMElements::Style => "style", 527 | DOMElements::Sub => "sub", 528 | DOMElements::Summary => "summary", 529 | DOMElements::Sup => "sup", 530 | DOMElements::Table => "table", 531 | DOMElements::Tbody => "tbody", 532 | DOMElements::Td => "td", 533 | DOMElements::Textarea => "textarea", 534 | DOMElements::Tfoot => "tfoot", 535 | DOMElements::Th => "th", 536 | DOMElements::Thead => "thead", 537 | DOMElements::Time => "time", 538 | DOMElements::Title => "title", 539 | DOMElements::Tr => "tr", 540 | DOMElements::Track => "track", 541 | DOMElements::Tt => "tt", 542 | DOMElements::U => "u", 543 | DOMElements::Ul => "ul", 544 | DOMElements::Var => "var", 545 | DOMElements::Video => "video", 546 | DOMElements::Wbr => "wbr", 547 | DOMElements::Xmp => "xmp", 548 | } 549 | } 550 | 551 | pub fn entries() -> HashMap<&'static str, bool> { 552 | DOM_ELEMENTS.entries().map(|(k, v)| (*k, *v)).collect() 553 | } 554 | 555 | pub fn entries_with_enum_dom_elements() -> HashMap { 556 | DOM_ELEMENTS 557 | .entries() 558 | .map(|(k, v)| (map_raw_dom_element_to_enum(k), *v)) 559 | .collect() 560 | } 561 | 562 | pub fn for_each(mut callback: impl FnMut(&'static str, bool)) { 563 | DOM_ELEMENTS.into_iter().for_each(|(k, v)| callback(k, *v)); 564 | } 565 | 566 | pub fn for_each_with_enum_dom_elements(mut callback: impl FnMut(DOMElements, bool)) { 567 | DOM_ELEMENTS 568 | .into_iter() 569 | .for_each(|(k, v)| callback(map_raw_dom_element_to_enum(k), *v)); 570 | } 571 | 572 | pub fn get(name: &str) -> Option { 573 | DOM_ELEMENTS.get(name).copied() 574 | } 575 | 576 | pub fn get_with_enum_dom_elements(dom_element: DOMElements) -> Option { 577 | let raw_dom_element = map_enum_dom_element_to_raw(&dom_element); 578 | DOM_ELEMENTS.get(raw_dom_element).copied() 579 | } 580 | 581 | pub fn has(name: &str) -> bool { 582 | DOM_ELEMENTS.contains_key(name) 583 | } 584 | 585 | pub fn keys() -> impl Iterator { 586 | DOM_ELEMENTS.keys().copied() 587 | } 588 | 589 | pub fn values() -> impl Iterator { 590 | DOM_ELEMENTS.values().copied() 591 | } 592 | 593 | #[cfg(test)] 594 | mod test { 595 | use crate::dom; 596 | use insta::{assert_json_snapshot, Settings}; 597 | 598 | #[test] 599 | fn snapshot_for_entries() { 600 | let dom_entries = dom::entries(); 601 | 602 | let mut settings = Settings::clone_current(); 603 | settings.set_sort_maps(true); 604 | settings.bind(|| { 605 | assert_json_snapshot!(dom_entries); 606 | }); 607 | } 608 | 609 | #[test] 610 | fn snapshot_for_entries_with_enum_dom_elements() { 611 | let dom_entries = dom::entries_with_enum_dom_elements(); 612 | 613 | let mut settings = Settings::clone_current(); 614 | settings.set_sort_maps(true); 615 | settings.bind(|| { 616 | assert_json_snapshot!(dom_entries); 617 | }); 618 | } 619 | 620 | #[test] 621 | fn test_for_each() { 622 | let mut el_count = 0; 623 | dom::for_each(|_, _| el_count += 1); 624 | assert_eq!(el_count, 129); 625 | let mut reserved_count = 0; 626 | dom::for_each(|_, v| { 627 | if v { 628 | reserved_count += 1 629 | } 630 | }); 631 | assert_eq!(reserved_count, 16); 632 | let mut elements_list = Vec::new(); 633 | dom::for_each(|k, _| { 634 | elements_list.push(k); 635 | }); 636 | assert_eq!(elements_list, dom::keys().collect::>()); 637 | } 638 | 639 | #[test] 640 | fn test_for_each_with_enum_dom_elements() { 641 | let mut el_count = 0; 642 | dom::for_each_with_enum_dom_elements(|_, _| el_count += 1); 643 | assert_eq!(el_count, 129); 644 | let mut reserved_count = 0; 645 | dom::for_each_with_enum_dom_elements(|_, v| { 646 | if v { 647 | reserved_count += 1 648 | } 649 | }); 650 | assert_eq!(reserved_count, 16); 651 | let mut elements_list = Vec::new(); 652 | dom::for_each_with_enum_dom_elements(|k, _| { 653 | elements_list.push(k); 654 | }); 655 | assert_eq!( 656 | elements_list, 657 | dom::keys() 658 | .map(dom::map_raw_dom_element_to_enum) 659 | .collect::>() 660 | ); 661 | } 662 | 663 | #[test] 664 | fn test_get() { 665 | assert_eq!(dom::get("a"), Some(false)); 666 | assert_eq!(dom::get("html"), Some(true)); 667 | assert_eq!(dom::get("unknown"), None); 668 | } 669 | 670 | #[test] 671 | fn test_get_with_enum_dom_elements() { 672 | assert_eq!( 673 | dom::get_with_enum_dom_elements(dom::DOMElements::A), 674 | Some(false) 675 | ); 676 | assert_eq!( 677 | dom::get_with_enum_dom_elements(dom::DOMElements::Html), 678 | Some(true) 679 | ); 680 | } 681 | 682 | #[test] 683 | fn test_has() { 684 | assert!(dom::has("a")); 685 | assert!(dom::has("html")); 686 | assert!(!dom::has("unknown")); 687 | } 688 | 689 | #[test] 690 | fn test_keys() { 691 | let keys = dom::keys().collect::>(); 692 | for key in keys { 693 | assert!(dom::entries().contains_key(key)); 694 | } 695 | } 696 | } 697 | --------------------------------------------------------------------------------