Skip to content

Commit

Permalink
Account for presentational role conflict resolution in ARIA feature m…
Browse files Browse the repository at this point in the history
…appings (#264)

* Add an options argument to Feature#role
  • Loading branch information
Jym77 authored Jun 17, 2020
1 parent 72106a6 commit 3ff77d1
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 11 deletions.
27 changes: 19 additions & 8 deletions packages/alfa-aria/src/feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,26 @@ import { Scope, Table } from "@siteimprove/alfa-table";
import { Role } from "./role";

const { hasName, isElement } = Element;
const { and, equals, test } = Predicate;
const { and } = Predicate;

export class Feature<N extends string = string> {
public static of<N extends string>(
name: N,
role: Feature.Aspect<Option<string>> = () => None,
role: Feature.Aspect<Option<string>, [Feature.RoleOptions]> = () => None,
attributes: Feature.Aspect<Map<string, string>> = () => Map.empty(),
status: Feature.Status = { obsolete: false }
): Feature<N> {
return new Feature(name, role, attributes, status);
}

private readonly _name: N;
private readonly _role: Feature.Aspect<Option<string>>;
private readonly _role: Feature.Aspect<Option<string>, [Feature.RoleOptions]>;
private readonly _attributes: Feature.Aspect<Map<string, string>>;
private readonly _status: Feature.Status;

private constructor(
name: N,
role: Feature.Aspect<Option<string>>,
role: Feature.Aspect<Option<string>, [Feature.RoleOptions]>,
attributes: Feature.Aspect<Map<string, string>>,
status: Feature.Status
) {
Expand All @@ -43,7 +43,7 @@ export class Feature<N extends string = string> {
return this._name;
}

public get role(): Feature.Aspect<Option<string>> {
public get role(): Feature.Aspect<Option<string>, [Feature.RoleOptions]> {
return this._role;
}

Expand All @@ -57,12 +57,23 @@ export class Feature<N extends string = string> {
}

export namespace Feature {
export type Aspect<T> = Mapper<Element, T>;
export type Aspect<T, A extends Array<unknown> = []> = Mapper<
Element,
T,
A
>;

export interface Status {
readonly obsolete: boolean;
}

export interface RoleOptions {
/**
* @internal
*/
readonly allowPresentational?: boolean;
}

const features = Cache.empty<Namespace, Cache<string, Feature>>();

export function register<N extends string>(
Expand Down Expand Up @@ -298,9 +309,9 @@ Feature.register(

Feature.register(
Namespace.HTML,
Feature.of("img", (element) =>
Feature.of("img", (element, { allowPresentational = true }) =>
Option.of(
element.attribute("alt").some((alt) => alt.value === "")
allowPresentational && element.attribute("alt").some((alt) => alt.value === "")
? "presentation"
: "img"
)
Expand Down
5 changes: 4 additions & 1 deletion packages/alfa-aria/src/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,10 @@ export namespace Node {
role.some(isPresentational) &&
!isAllowedPresentational(node)
) {
return Role.from(node, { explicit: false });
return Role.from(node, {
explicit: false,
allowPresentational: false,
});
}

return Branched.of(role);
Expand Down
8 changes: 6 additions & 2 deletions packages/alfa-aria/src/role.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,11 @@ export namespace Role {
const feature = Feature.lookup(namespace, element.name);

return feature.flatMap((feature) =>
feature.role(element).flatMap(Role.lookup)
feature
.role(element, {
allowPresentational: options.allowPresentational,
})
.flatMap(Role.lookup)
);
});
}
Expand All @@ -280,7 +284,7 @@ export namespace Role {
}

export namespace from {
export interface Options {
export interface Options extends Feature.RoleOptions {
readonly explicit?: boolean;
readonly implicit?: boolean;
}
Expand Down

0 comments on commit 3ff77d1

Please sign in to comment.