From e0127c412ede5b3b9bbc51bbdfd18d7363a76bae Mon Sep 17 00:00:00 2001 From: Jean-Yves Moyen Date: Tue, 4 May 2021 10:41:15 +0200 Subject: [PATCH 1/4] Start adding test cases --- .../test/property/background-size.spec.tsx | 25 +++++++++++++++++++ packages/alfa-style/tsconfig.json | 1 + 2 files changed, 26 insertions(+) create mode 100644 packages/alfa-style/test/property/background-size.spec.tsx diff --git a/packages/alfa-style/test/property/background-size.spec.tsx b/packages/alfa-style/test/property/background-size.spec.tsx new file mode 100644 index 0000000000..198b4eef78 --- /dev/null +++ b/packages/alfa-style/test/property/background-size.spec.tsx @@ -0,0 +1,25 @@ +import { h } from "@siteimprove/alfa-dom"; +import { test } from "@siteimprove/alfa-test"; +import { Style } from "../../src"; + +const device = Device.standard(); + +test("#cascaded() parses `background-size: cover`", (t) => { + const element =
; + + const style = Style.from(element, device); + + t.deepEqual(style.cascaded("background-size").get().toJSON(), { + value: { + type: "list", + values: [ + { + type: "keyword", + value: "cover", + }, + ], + separator: ", ", + }, + source: h.declaration("background-size", "cover").toJSON(), + }); +}); diff --git a/packages/alfa-style/tsconfig.json b/packages/alfa-style/tsconfig.json index dcc9cccbda..dda9f4dc68 100644 --- a/packages/alfa-style/tsconfig.json +++ b/packages/alfa-style/tsconfig.json @@ -138,6 +138,7 @@ "test/property/background-color.spec.tsx", "test/property/background-image.spec.tsx", "test/property/background-position.spec.tsx", + "test/property/background-size.spec.tsx", "test/property/border.spec.tsx", "test/property/border-[block,inline].spec.tsx", "test/property/border-[block,inline]-[end,start].spec.tsx", From b6e4038f2db91df8128ae1ac5d9a9e278565e531 Mon Sep 17 00:00:00 2001 From: Jean-Yves Moyen Date: Tue, 4 May 2021 13:52:57 +0200 Subject: [PATCH 2/4] Add failing examples --- .../test/property/background-size.spec.tsx | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/packages/alfa-style/test/property/background-size.spec.tsx b/packages/alfa-style/test/property/background-size.spec.tsx index 198b4eef78..b7ed0a71b0 100644 --- a/packages/alfa-style/test/property/background-size.spec.tsx +++ b/packages/alfa-style/test/property/background-size.spec.tsx @@ -1,3 +1,4 @@ +import { Device } from "@siteimprove/alfa-device"; import { h } from "@siteimprove/alfa-dom"; import { test } from "@siteimprove/alfa-test"; import { Style } from "../../src"; @@ -23,3 +24,122 @@ test("#cascaded() parses `background-size: cover`", (t) => { source: h.declaration("background-size", "cover").toJSON(), }); }); + +test("#cascaded() parses `background-size: 10px`", (t) => { + const element =
; + + const style = Style.from(element, device); + + t.deepEqual(style.cascaded("background-size").get().toJSON(), { + value: { + type: "list", + values: [ + [ + { + type: "length", + value: 10, + unit: "px", + }, + { + type: "keyword", + value: "auto", + }, + ], + ], + separator: ", ", + }, + source: h.declaration("background-size", "10px").toJSON(), + }); +}); + +test("#cascaded() parses `background-size: 10%`", (t) => { + const element =
; + + const style = Style.from(element, device); + + t.deepEqual(style.cascaded("background-size").get().toJSON(), { + value: { + type: "list", + values: [ + [ + { + type: "percentage", + value: 0.1, + }, + { + type: "keyword", + value: "auto", + }, + ], + ], + separator: ", ", + }, + source: h.declaration("background-size", "10%").toJSON(), + }); +}); + +test("#cascaded() parses `background-size: 10px 20px`", (t) => { + const element =
; + + const style = Style.from(element, device); + + t.deepEqual(style.cascaded("background-size").get().toJSON(), { + value: { + type: "list", + values: [ + [ + { + type: "length", + value: 10, + unit: "px", + }, + { + type: "length", + value: 20, + unit: "px", + }, + ], + ], + separator: ", ", + }, + source: h.declaration("background-size", "10px 20px").toJSON(), + }); +}); + +test("#cascaded() parses `background-size: 10px, 20px`", (t) => { + const element =
; + + const style = Style.from(element, device); + + t.deepEqual(style.cascaded("background-size").get().toJSON(), { + value: { + type: "list", + values: [ + [ + { + type: "length", + value: 10, + unit: "px", + }, + { + type: "keyword", + value: "auto", + }, + ], + [ + { + type: "length", + value: 20, + unit: "px", + }, + { + type: "keyword", + value: "auto", + }, + ], + ], + separator: ", ", + }, + source: h.declaration("background-size", "10px, 20px").toJSON(), + }); +}); From 300cfe2ec6bdfbdd198d5e68e1b3286abaeae978 Mon Sep 17 00:00:00 2001 From: Jean-Yves Moyen Date: Tue, 4 May 2021 14:02:53 +0200 Subject: [PATCH 3/4] Accept percentages and two values for background-size --- .../src/property/background-size.ts | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/packages/alfa-style/src/property/background-size.ts b/packages/alfa-style/src/property/background-size.ts index c98306873c..e12604f8fd 100644 --- a/packages/alfa-style/src/property/background-size.ts +++ b/packages/alfa-style/src/property/background-size.ts @@ -1,13 +1,15 @@ import { Keyword, Length, Percentage, Token } from "@siteimprove/alfa-css"; import { Iterable } from "@siteimprove/alfa-iterable"; import { Parser } from "@siteimprove/alfa-parser"; +import { Slice } from "@siteimprove/alfa-slice"; import { Property } from "../property"; import { Resolver } from "../resolver"; import { List } from "./value/list"; +import parseWhitespace = Token.parseWhitespace; -const { map, either, delimited, option, pair, separatedList } = Parser; +const { map, either, delimited, option, pair, right, separatedList } = Parser; declare module "../property" { interface Longhands { @@ -24,11 +26,10 @@ export type Specified = List; * @internal */ export namespace Specified { + export type Dimension = Length | Percentage | Keyword<"auto">; + export type Item = - | [ - Length | Percentage | Keyword<"auto">, - Length | Percentage | Keyword<"auto"> - ] + | [Dimension, Dimension] | Keyword<"cover"> | Keyword<"contain">; } @@ -42,22 +43,30 @@ export type Computed = List; * @internal */ export namespace Computed { + export type Dimension = Length<"px"> | Percentage | Keyword<"auto">; + export type Item = - | [ - Length<"px"> | Percentage | Keyword<"auto">, - Length<"px"> | Percentage | Keyword<"auto"> - ] + | [Dimension, Dimension] | Keyword<"cover"> | Keyword<"contain">; } +/** + * @internal + */ +const parseDimension = either, Specified.Dimension, string>( + Length.parse, + Percentage.parse, + Keyword.parse("auto") +); + /** * @internal */ export const parse = either( pair( - either(Length.parse, Keyword.parse("auto")), - map(option(either(Length.parse, Keyword.parse("auto"))), (y) => + parseDimension, + map(option(right(parseWhitespace, parseDimension)), (y) => y.getOrElse(() => Keyword.of("auto")) ) ), From 499f3b26cfbd0282dc9689697282e875fd10b252 Mon Sep 17 00:00:00 2001 From: Jean-Yves Moyen Date: Tue, 4 May 2021 14:27:59 +0200 Subject: [PATCH 4/4] Use Tuple to store dimensions in background-size --- .../src/property/background-size.ts | 29 ++-- .../alfa-style/src/property/background.ts | 3 +- .../test/property/background-size.spec.tsx | 125 ++++++++++-------- 3 files changed, 88 insertions(+), 69 deletions(-) diff --git a/packages/alfa-style/src/property/background-size.ts b/packages/alfa-style/src/property/background-size.ts index e12604f8fd..516cd4cd9f 100644 --- a/packages/alfa-style/src/property/background-size.ts +++ b/packages/alfa-style/src/property/background-size.ts @@ -7,7 +7,7 @@ import { Property } from "../property"; import { Resolver } from "../resolver"; import { List } from "./value/list"; -import parseWhitespace = Token.parseWhitespace; +import { Tuple } from "./value/tuple"; const { map, either, delimited, option, pair, right, separatedList } = Parser; @@ -29,7 +29,7 @@ export namespace Specified { export type Dimension = Length | Percentage | Keyword<"auto">; export type Item = - | [Dimension, Dimension] + | Tuple<[Dimension, Dimension]> | Keyword<"cover"> | Keyword<"contain">; } @@ -46,7 +46,7 @@ export namespace Computed { export type Dimension = Length<"px"> | Percentage | Keyword<"auto">; export type Item = - | [Dimension, Dimension] + | Tuple<[Dimension, Dimension]> | Keyword<"cover"> | Keyword<"contain">; } @@ -64,11 +64,14 @@ const parseDimension = either, Specified.Dimension, string>( * @internal */ export const parse = either( - pair( - parseDimension, - map(option(right(parseWhitespace, parseDimension)), (y) => - y.getOrElse(() => Keyword.of("auto")) - ) + map( + pair( + parseDimension, + map(option(right(Token.parseWhitespace, parseDimension)), (y) => + y.getOrElse(() => Keyword.of("auto")) + ) + ), + ([x, y]) => Tuple.of(x, y) ), Keyword.parse("contain", "cover") ); @@ -91,7 +94,7 @@ export const parseList = map( export default Property.register( "background-size", Property.of( - List.of([[Keyword.of("auto"), Keyword.of("auto")]], ", "), + List.of([Tuple.of(Keyword.of("auto"), Keyword.of("auto"))], ", "), parseList, (value, style) => value.map((sizes) => @@ -101,12 +104,12 @@ export default Property.register( return size; } - const [x, y] = size; + const [x, y] = size.values; - return [ + return Tuple.of( x.type === "length" ? Resolver.length(x, style) : x, - y.type === "length" ? Resolver.length(y, style) : y, - ]; + y.type === "length" ? Resolver.length(y, style) : y + ); }), ", " ) diff --git a/packages/alfa-style/src/property/background.ts b/packages/alfa-style/src/property/background.ts index ec88e9f114..d8ac64e387 100644 --- a/packages/alfa-style/src/property/background.ts +++ b/packages/alfa-style/src/property/background.ts @@ -6,6 +6,7 @@ import { Slice } from "@siteimprove/alfa-slice"; import { Property } from "../property"; import { List } from "./value/list"; +import { Tuple } from "./value/tuple"; import * as Attachment from "./background-attachment"; import * as Clip from "./background-clip"; @@ -253,7 +254,7 @@ export default Property.registerShorthand( image.push(layer[1] ?? Keyword.of("none")); positionX.push(layer[2] ?? Percentage.of(0)); positionY.push(layer[3] ?? Percentage.of(0)); - size.push(layer[4] ?? [Keyword.of("auto"), Keyword.of("auto")]); + size.push(layer[4] ?? Tuple.of(Keyword.of("auto"), Keyword.of("auto"))); repeatX.push(layer[5] ?? Keyword.of("repeat")); repeatY.push(layer[6] ?? Keyword.of("repeat")); attachment.push(layer[7] ?? Keyword.of("scroll")); diff --git a/packages/alfa-style/test/property/background-size.spec.tsx b/packages/alfa-style/test/property/background-size.spec.tsx index b7ed0a71b0..5920772501 100644 --- a/packages/alfa-style/test/property/background-size.spec.tsx +++ b/packages/alfa-style/test/property/background-size.spec.tsx @@ -34,17 +34,20 @@ test("#cascaded() parses `background-size: 10px`", (t) => { value: { type: "list", values: [ - [ - { - type: "length", - value: 10, - unit: "px", - }, - { - type: "keyword", - value: "auto", - }, - ], + { + type: "tuple", + values: [ + { + type: "length", + value: 10, + unit: "px", + }, + { + type: "keyword", + value: "auto", + }, + ], + }, ], separator: ", ", }, @@ -61,16 +64,19 @@ test("#cascaded() parses `background-size: 10%`", (t) => { value: { type: "list", values: [ - [ - { - type: "percentage", - value: 0.1, - }, - { - type: "keyword", - value: "auto", - }, - ], + { + type: "tuple", + values: [ + { + type: "percentage", + value: 0.1, + }, + { + type: "keyword", + value: "auto", + }, + ], + }, ], separator: ", ", }, @@ -87,18 +93,21 @@ test("#cascaded() parses `background-size: 10px 20px`", (t) => { value: { type: "list", values: [ - [ - { - type: "length", - value: 10, - unit: "px", - }, - { - type: "length", - value: 20, - unit: "px", - }, - ], + { + type: "tuple", + values: [ + { + type: "length", + value: 10, + unit: "px", + }, + { + type: "length", + value: 20, + unit: "px", + }, + ], + }, ], separator: ", ", }, @@ -115,28 +124,34 @@ test("#cascaded() parses `background-size: 10px, 20px`", (t) => { value: { type: "list", values: [ - [ - { - type: "length", - value: 10, - unit: "px", - }, - { - type: "keyword", - value: "auto", - }, - ], - [ - { - type: "length", - value: 20, - unit: "px", - }, - { - type: "keyword", - value: "auto", - }, - ], + { + type: "tuple", + values: [ + { + type: "length", + value: 10, + unit: "px", + }, + { + type: "keyword", + value: "auto", + }, + ], + }, + { + type: "tuple", + values: [ + { + type: "length", + value: 20, + unit: "px", + }, + { + type: "keyword", + value: "auto", + }, + ], + }, ], separator: ", ", },