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

Support text-decoration-thickness #817

Merged
merged 2 commits into from
May 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 6 additions & 3 deletions packages/alfa-rules/src/sia-r62/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,11 +360,14 @@ export namespace ComputedStyles {
"outline-style"
)} ${longhand("outline-style")}`.trim();

// While text-decoration-style is not important for deciding if there is one,
// it is important for rendering the link with the correct styling.
// While text-decoration-style and text-decoration-thickness are not
// important for deciding if there is one, but they are important for
// rendering the link with the correct styling.
const textDecoration = `${longhand("text-decoration-line")} ${longhand(
"text-decoration-color"
)} ${longhand("text-decoration-style")}`.trim();
)} ${longhand("text-decoration-style")} ${longhand(
"text-decoration-thickness"
)}`.trim();

const longhands = ([
"background-color",
Expand Down
1 change: 1 addition & 0 deletions packages/alfa-style/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ import "./property/text-decoration";
import "./property/text-decoration-color";
import "./property/text-decoration-line";
import "./property/text-decoration-style";
import "./property/text-decoration-thickness";
import "./property/text-indent";
import "./property/text-overflow";
import "./property/text-transform";
Expand Down
64 changes: 64 additions & 0 deletions packages/alfa-style/src/property/text-decoration-thickness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Keyword, Length, Percentage, Token } from "@siteimprove/alfa-css";
import { Parser } from "@siteimprove/alfa-parser";
import { Slice } from "@siteimprove/alfa-slice";

import { Property } from "../property";
import { Resolver } from "../resolver";
import { Value } from "../value";

const { either } = Parser;

declare module "../property" {
interface Longhands {
"text-decoration-thickness": Property<Specified, Computed>;
}
}

/**
* @internal
*/
export type Specified =
| Length
| Percentage
| Keyword<"auto">
| Keyword<"from-font">;

/**
* @internal
*/
export type Computed = Length<"px"> | Keyword<"auto"> | Keyword<"from-font">;

/**
* @internal
*/
export const parse = either<Slice<Token>, Specified, string>(
Keyword.parse("auto", "from-font"),
Length.parse,
Percentage.parse
);

/**
* {@link https://developer.mozilla.org/en-US/docs/Web/CSS/outline-width}
* @internal
*/
export default Property.register(
"text-decoration-thickness",
Property.of<Specified, Computed>(
Keyword.of("auto"),
parse,
(thickness, style) =>
thickness.map((value) => {
switch (value.type) {
case "keyword":
return value;
case "length":
return Resolver.length(value, style);
case "percentage":
return Length.of(
style.computed("font-size").value.value * value.value,
"px"
);
}
})
)
);
33 changes: 29 additions & 4 deletions packages/alfa-style/src/property/text-decoration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ import { Property } from "../property";
import * as Color from "./text-decoration-color";
import * as Line from "./text-decoration-line";
import * as Style from "./text-decoration-style";
import * as Thickness from "./text-decoration-thickness";

declare module "../property" {
interface Shorthands {
"text-decoration": Property.Shorthand<
"text-decoration-line" | "text-decoration-style" | "text-decoration-color"
| "text-decoration-line"
| "text-decoration-style"
| "text-decoration-color"
| "text-decoration-thickness"
>;
}
}
Expand All @@ -22,11 +26,17 @@ declare module "../property" {
export default Property.registerShorthand(
"text-decoration",
Property.shorthand(
["text-decoration-line", "text-decoration-style", "text-decoration-color"],
[
"text-decoration-line",
"text-decoration-style",
"text-decoration-color",
"text-decoration-thickness",
],
(input) => {
let line: Line.Specified | undefined;
let style: Style.Specified | undefined;
let color: Color.Specified | undefined;
let thickness: Thickness.Specified | undefined;

while (true) {
for (const [remainder] of Token.parseWhitespace(input)) {
Expand Down Expand Up @@ -60,11 +70,25 @@ export default Property.registerShorthand(
}
}

if (thickness === undefined) {
const result = Thickness.parse(input);

if (result.isOk()) {
[input, thickness] = result.get();
continue;
}
}

break;
}

if (line === undefined && style === undefined && color === undefined) {
return Err.of(`Expected one of line, style, or color`);
if (
line === undefined &&
style === undefined &&
color === undefined &&
thickness === undefined
) {
return Err.of(`Expected one of line, style, color, or thickness`);
}

return Result.of([
Expand All @@ -73,6 +97,7 @@ export default Property.registerShorthand(
["text-decoration-line", line ?? Keyword.of("initial")],
["text-decoration-style", style ?? Keyword.of("initial")],
["text-decoration-color", color ?? Keyword.of("initial")],
["text-decoration-thickness", thickness ?? Keyword.of("initial")],
],
]);
}
Expand Down
51 changes: 51 additions & 0 deletions packages/alfa-style/test/property/text-decoration.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,54 @@ test("#cascaded() parses `text-decoration: underline solid red`", (t) => {
source: h.declaration("text-decoration", "underline solid red").toJSON(),
});
});

test("#cascaded() parses `text-decoration: underline solid red 2px`", (t) => {
const element = <div style={{ textDecoration: "underline solid red 2px" }} />;

const declaration = h.declaration(
"text-decoration",
"underline solid red 2px"
);

const style = Style.from(element, device);

t.deepEqual(style.cascaded("text-decoration-line").get().toJSON(), {
value: {
type: "list",
values: [
{
type: "keyword",
value: "underline",
},
],
separator: " ",
},
source: declaration.toJSON(),
});

t.deepEqual(style.cascaded("text-decoration-style").get().toJSON(), {
value: {
type: "keyword",
value: "solid",
},
source: declaration.toJSON(),
});

t.deepEqual(style.cascaded("text-decoration-color").get().toJSON(), {
value: {
type: "color",
format: "named",
color: "red",
},
source: declaration.toJSON(),
});

t.deepEqual(style.cascaded("text-decoration-thickness").get().toJSON(), {
value: {
type: "length",
value: 2,
unit: "px",
},
source: declaration.toJSON(),
});
});
1 change: 1 addition & 0 deletions packages/alfa-style/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
"src/property/text-decoration-color.ts",
"src/property/text-decoration-line.ts",
"src/property/text-decoration-style.ts",
"src/property/text-decoration-thickness.ts",
"src/property/text-indent.ts",
"src/property/text-overflow.ts",
"src/property/text-transform.ts",
Expand Down