Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider element with height or width of 0 as invisible unless the text overflows #827

Merged
merged 47 commits into from
Jun 16, 2021
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
a2c09e0
Add basic tests for R11 (#770)
Jym77 Apr 20, 2021
b3b3d06
Remove second expectation from R62 (#772)
Jym77 Apr 21, 2021
53089a6
Implement pseudo classes equality (#773)
Jym77 Apr 21, 2021
6aac6f4
Name computation: skip step 1 when descending (#778)
Jym77 Apr 27, 2021
e6fb3bb
SIA R62: accept different font weight (#779)
Jym77 Apr 29, 2021
39be660
Extended diagnostic for R14 (#786)
Jym77 May 4, 2021
597c2a1
Fix background size (#788)
Jym77 May 4, 2021
8b586a4
Assume no background on size (#789)
Jym77 May 4, 2021
62d1132
SIA R17: add test (#791)
elenamongelli May 7, 2021
a78c527
SIA R4: test added (#793)
elenamongelli May 7, 2021
69ea3cd
SIA R3: add test (#792)
elenamongelli May 7, 2021
4f5fddd
R6 test added (#795)
elenamongelli May 7, 2021
b5f2dd6
Run prettier
Jym77 May 7, 2021
0c2977c
Add --immutable flag to install instruction, add intructions for runn…
Jym77 May 7, 2021
f66b35e
Simplify double negative
Jym77 May 11, 2021
6bc0448
SIA R5: add test (#794)
elenamongelli May 11, 2021
96f6a4c
SIA R12: Add Test (#800)
elenamongelli May 17, 2021
46eed6f
Fix hasRole to pick the role from the accessible node (#805)
Jym77 May 17, 2021
39fbaad
Merge branch 'main' into develop
Jym77 May 17, 2021
71d5482
Clean up
Jym77 May 17, 2021
3129b13
R18 add test (#803)
elenamongelli May 17, 2021
1a8b05b
SIA-R19: Add test (#807)
elenamongelli May 18, 2021
0378d6f
SIA-R8: Added tests (#806)
elenamongelli May 18, 2021
98237ce
R16 extended diagnostic (#804)
elenamongelli May 19, 2021
6ec7b83
Clean up test descriptions a bit
Jym77 May 19, 2021
e5950db
Use n-ary and to streamline code
Jym77 May 21, 2021
0b0d863
R62 extended diagnostic (#801)
elenamongelli May 26, 2021
c2333b8
Send shorthands for border
Jym77 May 26, 2021
1d39a93
Avoid sending styles that are equals to initial
Jym77 May 26, 2021
456d060
Avoid sending styles that are equals to initial
Jym77 May 26, 2021
e1b4cf0
Send shorthands for outline
Jym77 May 28, 2021
314a272
Send shorthand for text-decoration
Jym77 May 28, 2021
4a8bc76
Support text-decoration-thickness (#817)
Jym77 May 28, 2021
24fa3fb
Merge branch 'main' into develop
Jym77 May 28, 2021
afd1c50
Remove unused imports
Jym77 May 28, 2021
8f0338d
Increase Nodejs heap size (#818)
Jym77 May 28, 2021
3b282b6
SIA R65: accept different border as focus indicator (#819)
Jym77 Jun 1, 2021
dcecc1f
Remove 'found' which is not used by frontend
Jym77 Jun 1, 2021
a087aa5
Fix serialisation of outline
Jym77 Jun 2, 2021
da6a10f
Heap size problem and investigation. (#822)
Jym77 Jun 2, 2021
da99401
Support `font-variant` CSS property (#821)
Jym77 Jun 2, 2021
452bc78
Test for SIA-R20 added
elenamongelli Jun 8, 2021
de8a225
Checks for overflow auto, scroll added in both rules and tests
elenamongelli Jun 8, 2021
daf6b5f
Comments have been integrated
elenamongelli Jun 9, 2021
b6380d3
Merge branch 'main' into is-clipped-update
Jym77 Jun 14, 2021
322ed4f
Clean up
Jym77 Jun 14, 2021
d7be9b4
Merge branch 'main' into is-clipped-update
Jym77 Jun 16, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/integrate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ jobs:
name: Build
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
os: [ ubuntu-latest, windows-latest ]
node: [12, 14]
runs-on: ${{ matrix.os }}
env:
NODE_OPTIONS: "--max-old-space-size=4096"
steps:
- uses: actions/[email protected]
- uses: actions/[email protected]
Expand Down
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ Alfa will run in any [ECMAScript 2018](https://www.ecma-international.org/ecma-2
In order to build Alfa, a recent version (>= 12) of [Node.js](https://nodejs.org/) is required in addition to the [Yarn](https://yarnpkg.com/) package manager. Once Node.js and Yarn are installed, go ahead and install the Alfa development dependencies:

```console
$ yarn install
$ yarn install --immutable
```

When done, you can start a watcher that watches source files for changes and kicks off the associated build steps when they change:
Expand All @@ -148,6 +148,18 @@ As new code is pulled from the repository, changes to dependencies and code may
$ yarn build
```

If you want to run tests and make sure everything is working, use:

```console
$ yarn test
```

When working on a specific package, you can run only these tests:

```console
$ yarn test packages/alfa-<package-name>
```

If you would like to contribute to Alfa, make sure to check out the [contribution guidelines](docs/contributing.md). If you have any questions, you are also welcome to [open an issue][].

## Architecture
Expand Down
8 changes: 7 additions & 1 deletion packages/alfa-aria/src/name.ts
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,13 @@ export namespace Name {
// https://w3c.github.io/accname/#step1
// Step 1 is skipped when referencing due to step 2B.ii.b
// https://w3c.github.io/accname/#step2B.ii.b
if (!state.isReferencing && role.some((role) => role.isNameProhibited())) {
// Step 1 is skipped when descending due to step 2F.iii.b
// https://w3c.github.io/accname/#step2B.iii.b
if (
!state.isReferencing &&
!state.isDescending &&
role.some((role) => role.isNameProhibited())
) {
return None;
}

Expand Down
1 change: 0 additions & 1 deletion packages/alfa-aria/src/role.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,6 @@ export class Role<N extends Role.Name = Role.Name>

return false;
}

/**
* Get the implicit value of the specified attribute, if any.
*/
Expand Down
80 changes: 80 additions & 0 deletions packages/alfa-aria/test/name.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,86 @@ test(`.from() determines the name of an <a> element with text in its subtree,
});
});

test(`.from() determines the name of an <a> element with text in its subtree,
when the source is nested and doesn't itself allow naming`, (t) => {
const a = (
<a href="#" title="Content">
<p>Hello world</p>
</a>
);

t.deepEqual(Name.from(a, device).toJSON(), {
type: "some",
value: {
value: "Hello world",
sources: [
{
type: "descendant",
element: "/a[1]",
name: {
value: "Hello world",
sources: [
{
type: "descendant",
element: "/a[1]/p[1]",
name: {
value: "Hello world",
sources: [
{
type: "data",
text: "/a[1]/p[1]/text()[1]",
},
],
},
},
],
},
},
],
},
});
});

test(`.from() determines the name of an <a> element with text in its subtree,
when the source is nested and presentational`, (t) => {
const a = (
<a href="#" title="Content">
<span role="none">Hello world</span>
</a>
);

t.deepEqual(Name.from(a, device).toJSON(), {
type: "some",
value: {
value: "Hello world",
sources: [
{
type: "descendant",
element: "/a[1]",
name: {
value: "Hello world",
sources: [
{
type: "descendant",
element: "/a[1]/span[1]",
name: {
value: "Hello world",
sources: [
{
type: "data",
text: "/a[1]/span[1]/text()[1]",
},
],
},
},
],
},
},
],
},
});
});

test(`.from() determines the name of an <a> element with text in its subtree,
when there are multiple nested sources`, (t) => {
const a = (
Expand Down
6 changes: 6 additions & 0 deletions packages/alfa-css/src/syntax/nth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ export class Nth implements Iterable<Token>, Equatable, Serializable {
offset: this._offset,
};
}

public toString(): string {
return this._step === 0
? `${this._offset}`
: `${this._step}n+${this._offset};`;
}
}

/**
Expand Down
11 changes: 11 additions & 0 deletions packages/alfa-rules/src/common/expectation/get-colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,17 @@ function getLayers(
return None;
}

// If there is a background-size, we currently have no way of guessing
// whether it is large enough to go under the text or not.
// So we simply bail out.
if (
!style
.computed("background-size")
.value.equals(style.initial("background-size").value)
) {
return None;
}

// For each gradient, we extract all color stops into a background layer of
// their own. As gradients need a start and an end point, there will always
// be at least two color stops.
Expand Down
3 changes: 0 additions & 3 deletions packages/alfa-rules/src/common/predicate/has-border.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ export function hasBorder(
return sides.some(
(side) =>
style.computed(`border-${side}-width` as const).none(Length.isZero) &&
style
.computed(`border-${side}-style` as const)
.none((style) => style.value === "none") &&
style
.computed(`border-${side}-color` as const)
.none((color) => color.type === "color" && Color.isTransparent(color))
Expand Down
12 changes: 9 additions & 3 deletions packages/alfa-rules/src/common/predicate/has-role.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { Role } from "@siteimprove/alfa-aria";
import { Node, Role } from "@siteimprove/alfa-aria";
import { Device } from "@siteimprove/alfa-device";
import { Element } from "@siteimprove/alfa-dom";
import { Predicate } from "@siteimprove/alfa-predicate";

export function hasRole(predicate?: Predicate<Role>): Predicate<Element>;
export function hasRole(
device: Device,
predicate?: Predicate<Role>
): Predicate<Element>;

export function hasRole<N extends Role.Name>(
device: Device,
name: N,
...rest: Array<N>
): Predicate<Element>;

export function hasRole(
device: Device,
nameOrPredicate: Predicate<Role> | Role.Name = () => true,
...names: Array<Role.Name>
): Predicate<Element> {
Expand All @@ -21,5 +27,5 @@ export function hasRole(
predicate = Role.hasName(nameOrPredicate, ...names);
}

return (element) => Role.from(element).some(predicate);
return (element) => Node.from(element, device).role.some(predicate);
}
46 changes: 46 additions & 0 deletions packages/alfa-rules/src/common/predicate/is-clipped.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,52 @@ function isClippedBySize(
}
}
}

if (x.value === "auto" || y.value === "auto") {
const { value: height } = style.computed("height");
const { value: width } = style.computed("width");

for (const dimension of [height, width]) {
switch (dimension.type) {
case "percentage":
if (dimension.value <= 0) {
return true;
} else {
break;
}

case "length":
if (dimension.value <= 1) {
Jym77 marked this conversation as resolved.
Show resolved Hide resolved
return true;
} else {
break;
}
}
}
}

if (x.value === "scroll" || y.value === "scroll") {
const { value: height } = style.computed("height");
const { value: width } = style.computed("width");
Jym77 marked this conversation as resolved.
Show resolved Hide resolved

for (const dimension of [height, width]) {
switch (dimension.type) {
case "percentage":
if (dimension.value <= 0) {
return true;
} else {
break;
}

case "length":
if (dimension.value <= 1) {
return true;
} else {
break;
}
}
}
}
Jym77 marked this conversation as resolved.
Show resolved Hide resolved
}

for (const parent of node.parent({ flattened: true })) {
Expand Down
8 changes: 4 additions & 4 deletions packages/alfa-rules/src/common/predicate/is-tabbable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ const { and, not } = Predicate;
export function isTabbable(device: Device): Predicate<Element> {
return and(
hasTabIndex((tabIndex) => tabIndex >= 0),
and(
not(redirectsFocus),
and(not(isDisabled), not(isInert(device)), isRendered(device))
)
not(redirectsFocus),
not(isDisabled),
not(isInert(device)),
isRendered(device)
);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/alfa-rules/src/sia-r10/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default Rule.Atomic.of<Page, Attribute>({
hasAttribute("autocomplete", hasTokens),
or(
isTabbable(device),
hasRole((role) => role.isWidget())
hasRole(device, (role) => role.isWidget())
),
isPerceivable(device),
(element) =>
Expand Down
2 changes: 1 addition & 1 deletion packages/alfa-rules/src/sia-r11/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default Rule.Atomic.of<Page, Element>({
.filter(
and(
hasNamespace(Namespace.HTML),
hasRole("link"),
hasRole(device, "link"),
not(isIgnored(device))
)
);
Expand Down
2 changes: 1 addition & 1 deletion packages/alfa-rules/src/sia-r12/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default Rule.Atomic.of<Page, Element>({
and(
not(hasInputType("image")),
hasNamespace(Namespace.HTML),
hasRole("button"),
hasRole(device, "button"),
not(isIgnored(device))
)
);
Expand Down
Loading