Skip to content

Commit

Permalink
Merge pull request #1710 from IBMa/issue-1670
Browse files Browse the repository at this point in the history
feature(engine): Add better guideline controls to the core engine
  • Loading branch information
ErickRenteria authored Oct 11, 2023
2 parents e124556 + a8076e3 commit 44cac71
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 29 deletions.
8 changes: 4 additions & 4 deletions accessibility-checker-engine/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
"description": "IBM Equal Access Accessibility Checker Engine",
"private": false,
"scripts": {
"build-node": "npm run prebuild && npx webpack --config webpack-node.config.js",
"build-node-debug": "npm run prebuild && npx webpack --config webpack-node-debug.config.js",
"build": "npm run prebuild && npx webpack --config webpack.config.js",
"build-debug": "npm run prebuild && npx webpack --config webpack-debug.config.js",
"build-node": "npm run prebuild && npx webpack --config webpack-node.config.js && shx cp dist/index.d.ts dist/ace-node.d.ts",
"build-node-debug": "npm run prebuild && npx webpack --config webpack-node-debug.config.js && shx cp dist/index.d.ts dist/ace-node-debug.d.ts",
"build": "npm run prebuild && npx webpack --config webpack.config.js && shx cp dist/index.d.ts dist/ace.d.ts",
"build-debug": "npm run prebuild && npx webpack --config webpack-debug.config.js && shx cp dist/index.d.ts dist/ace-debug.d.ts",
"prebuild": "ts-node src/genRuleIndex.ts",
"test": "npm run prebuild && karma start",
"serve": "serve .",
Expand Down
3 changes: 2 additions & 1 deletion accessibility-checker-engine/src/v4/api/IGuideline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ export type Checkpoint = {
// or all if not specified
reasonCodes?: string[],
level: eRulePolicy,
toolkitLevel: eToolkitLevel
toolkitLevel: eToolkitLevel,
enabled?: boolean
}>
}

Expand Down
131 changes: 109 additions & 22 deletions accessibility-checker-engine/src/v4/checker/Checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
limitations under the License.
*****************************************************************************/

import { Issue, Rule as RuleV4, eRulePolicy } from "../api/IRule";
import { Rule as RuleV4, eRulePolicy } from "../api/IRule";
import { Engine } from "../../v2/common/Engine";
import { ARIAMapper } from "../../v2/aria/ARIAMapper";
import { StyleMapper } from "../../v2/style/StyleMapper";
import { a11yRulesets } from "../rulesets";
import * as checkRulesV4 from "../rules";
import { Checkpoint, Guideline, eGuidelineCategory } from "../api/IGuideline";
import { Guideline, eGuidelineCategory } from "../api/IGuideline";
import { IEngine } from "../api/IEngine";
import { Report } from "../api/IReport";
import { IChecker } from "../api/IChecker";
Expand Down Expand Up @@ -84,14 +84,22 @@ _initialize();
export type Ruleset = Guideline;

export class Checker implements IChecker {
private guidelines: Guideline[] = [];

engine: IEngine;
rulesets: Guideline[] = [];
/**
* @deprecated Use getGuidelines().
*/
rulesets: Guideline[] = this.guidelines;
/**
* @deprecated Use getGuidelineIds().
*/
rulesetIds: string[] = [];
rulesetRules: { [rsId: string]: string[] } = {};
ruleLevels : { [ruleId: string]: { [rsId: string] : eRulePolicy }} = {};
ruleCategory : { [ruleId: string]: { [rsId: string] : eGuidelineCategory }} = {};

constructor() {
public constructor() {
let engine = this.engine = new Engine();

engine.addMapper(new ARIAMapper());
Expand All @@ -106,29 +114,102 @@ export class Checker implements IChecker {
}
}

/**
* Adds a guideline to the engine. If the id already exists, the previous guideline will be replaced.
* @param guideline
*/
addGuideline(guideline: Guideline) {
this.rulesets.push(guideline);
if (guideline.id in this.rulesetRules) {
this.removeGuideline(guideline.id);
}
this.guidelines.push(guideline);
this.rulesetIds.push(guideline.id);
const ruleIds = [];
for (const cp of guideline.checkpoints) {
cp.rules = cp.rules || [];
for (const rule of cp.rules) {
ruleIds.push(rule.id);
this.ruleLevels[rule.id] = this.ruleLevels[rule.id] || {};
this.ruleLevels[rule.id][guideline.id] = rule.level;
this.ruleCategory[rule.id] = this.ruleCategory[rule.id] || {};
this.ruleCategory[rule.id][guideline.id] = guideline.category;
if (rule.enabled !== false) {
ruleIds.push(rule.id);
this.ruleLevels[rule.id] = this.ruleLevels[rule.id] || {};
this.ruleLevels[rule.id][guideline.id] = rule.level;
this.ruleCategory[rule.id] = this.ruleCategory[rule.id] || {};
this.ruleCategory[rule.id][guideline.id] = guideline.category;
}
}
}
this.rulesetRules[guideline.id] = ruleIds;
}

getGuidelines() {
return this.rulesets;
/**
* Enable a rule for all guidelines
* @param ruleId
*/
enableRule(ruleId: string) {
for (const guideline of this.getGuidelines()) {
let updated = false;
for (const cp of guideline.checkpoints) {
for (const rule of cp.rules) {
if (rule.enabled === false) {
updated = true;
delete rule.enabled;
}
}
}
if (updated) {
this.addGuideline(guideline);
}
}
}

getGuidelineIds() {
return this.rulesetIds;
/**
* Disable a rule for all guidelines
* @param ruleId
*/
disableRule(ruleId: string) {
for (const guideline of this.getGuidelines()) {
let updated = false;
for (const cp of guideline.checkpoints) {
for (const rule of cp.rules) {
if (rule.enabled !== false) {
updated = true;
rule.enabled = false;
}
}
}
if (updated) {
this.addGuideline(guideline);
}
}
}

/**
* Remove a guideline from the engine
*
* Generally, there isn't a good reason to do this. Users should just not select the guideline as an option in check
* @param guidelineId
*/
private removeGuideline(guidelineId: string) {
if (guidelineId in this.rulesetRules) {
delete this.rulesetRules[guidelineId];
this.rulesets = this.guidelines = this.guidelines.filter(guideline => guideline.id !== guidelineId);
this.rulesetIds = this.getGuidelineIds();
}
}

/**
* Get the guidelines available in the engine
* @returns
*/
getGuidelines() : Guideline[] {
return JSON.parse(JSON.stringify(this.guidelines));
}

/**
* Get the ids of the guidelines available in the engine
* @returns
*/
getGuidelineIds() : string[] {
return this.guidelines.map(guideline => guideline.id);
}

/**
Expand All @@ -139,19 +220,25 @@ export class Checker implements IChecker {
this.addGuideline(rs);
}

check(node: Node | Document, rsIds?: string | string[]) : Promise<Report> {
/**
* Perform a check of the specified node/document
* @param node DOMNode or Document on which to run the check
* @param guidelineIds Guideline ids to check with to specify which rules to run
* @returns
*/
check(node: Node | Document, guidelineIds?: string | string[]) : Promise<Report> {
// Determine which rules to run
let ruleIds : string[] = [];

// Fix the input
if (!rsIds) {
if (!guidelineIds) {
ruleIds = this.engine.getRulesIds();
} else{
if (typeof rsIds === "string") {
rsIds = [rsIds];
if (typeof guidelineIds === "string") {
guidelineIds = [guidelineIds];
}

for (const rsId of rsIds) {
for (const rsId of guidelineIds) {
if (rsId in this.rulesetRules) {
ruleIds = ruleIds.concat(this.rulesetRules[rsId]);
}
Expand All @@ -175,8 +262,8 @@ export class Checker implements IChecker {
report.nls[result.ruleId][result.reasonId] = checkNls[result.ruleId][result.reasonId];
}
}
result.value[0] = myThis.getLevel(rsIds as string[], result.ruleId);
result.category = myThis.getCategory(rsIds as string[], result.ruleId);
result.value[0] = myThis.getLevel(guidelineIds as string[], result.ruleId);
result.category = myThis.getCategory(guidelineIds as string[], result.ruleId);
delete result.path.css;
}
return report;
Expand Down Expand Up @@ -217,7 +304,7 @@ export class Checker implements IChecker {
return eGuidelineCategory.OTHER;
}
if (!rsIds) {
rsIds = this.rulesetIds;
rsIds = this.getGuidelineIds();
}
for (const rsId of rsIds) {
if (rsId in rsInfo) {
Expand Down
1 change: 1 addition & 0 deletions accessibility-checker-engine/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"compilerOptions": {
"declaration": true,
"allowJs": false,
"target": "ES5",
"removeComments": false,
Expand Down
3 changes: 2 additions & 1 deletion common/module/src/engine/IGuideline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ export type Checkpoint = {
// or all if not specified
reasonCodes?: string[],
level: eRulePolicy,
toolkitLevel: eToolkitLevel
toolkitLevel: eToolkitLevel,
enabled?: boolean
}>
}

Expand Down
3 changes: 2 additions & 1 deletion report-react/src/IReport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ export interface ICheckpoint {
// or all if not specified
reasonCodes?: string[],
level: string,
toolkitLevel: string
toolkitLevel: string,
enabled?: boolean
}>
}

Expand Down

0 comments on commit 44cac71

Please sign in to comment.