Skip to content

Commit

Permalink
Add mask-border-source
Browse files Browse the repository at this point in the history
  • Loading branch information
rcj-siteimprove committed Dec 10, 2024
1 parent fb39e55 commit e5af28b
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 0 deletions.
2 changes: 2 additions & 0 deletions packages/alfa-style/src/longhands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ import MarginBottom from "./property/margin-bottom.js";
import MarginLeft from "./property/margin-left.js";
import MarginRight from "./property/margin-right.js";
import MarginTop from "./property/margin-top.js";
import MaskBorderSource from "./property/mask-border-source.js";
import MinHeight from "./property/min-height.js";
import MinWidth from "./property/min-width.js";
import MixBlendMode from "./property/mix-blend-mode.js";
Expand Down Expand Up @@ -268,6 +269,7 @@ export namespace Longhands {
"margin-left": MarginLeft,
"margin-right": MarginRight,
"margin-top": MarginTop,
"mask-border-source": MaskBorderSource,
"min-height": MinHeight,
"min-width": MinWidth,
"mix-blend-mode": MixBlendMode,
Expand Down
45 changes: 45 additions & 0 deletions packages/alfa-style/src/property/mask-border-source.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
Image,
Keyword,
URL,
type Parser as CSSParser,
} from "@siteimprove/alfa-css";
import { Parser } from "@siteimprove/alfa-parser";
import { Selective } from "@siteimprove/alfa-selective";

import { Longhand } from "../longhand.js";
import { Resolver } from "../resolver.js";

const { either } = Parser;

export type MaskBorderSource = Keyword<"none"> | Image | URL;

export namespace MaskBorderSource {
export const parse: CSSParser<MaskBorderSource> = either(
Keyword.parse("none"),
either(Image.parse, URL.parse),
);

export const initialItem = Keyword.of("none");
}

type Specified = MaskBorderSource;
type Computed = Specified;

/**
* {@link https://developer.mozilla.org/en-US/docs/Web/CSS/mask-border-source}
*
* @internal
*/
export default Longhand.of<Specified, Computed>(
MaskBorderSource.initialItem,
MaskBorderSource.parse,
(value, style) =>
value.map((image) =>
Selective.of(image)
.if(Image.isImage, (image) =>
image.partiallyResolve(Resolver.length(style)),
)
.get(),
),
);
1 change: 1 addition & 0 deletions packages/alfa-style/src/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@
"./property/margin-left.ts",
"./property/margin-right.ts",
"./property/margin-top.ts",
"./property/mask-border-source.ts",
"./property/min-height.ts",
"./property/min-width.ts",
"./property/mix-blend-mode.ts",
Expand Down
11 changes: 11 additions & 0 deletions packages/alfa-style/test/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ export function specified<N extends Longhands.Name>(
return Style.from(element, device, context).specified(name).toJSON();
}

/**
* @internal
*/
export function computed<N extends Longhands.Name>(
element: Element,
name: N,
context: Context = Context.empty(),
): Value.JSON<Style.Specified<N>> {
return Style.from(element, device, context).computed(name).toJSON();
}

/**
* @internal
*/
Expand Down
109 changes: 109 additions & 0 deletions packages/alfa-style/test/property/mask-border-source.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { test } from "@siteimprove/alfa-test";
import { h } from "@siteimprove/alfa-dom";

import { computed } from "../common.js";

test("initial value is none", (t) => {
t.deepEqual(computed(<div></div>, "mask-border-source"), {
value: {
type: "keyword",
value: "none",
},
source: null,
});
});

test("#computed parses url value", (t) => {
t.deepEqual(
computed(
<div style={{ maskBorderSource: "url(foo.svg)" }}></div>,
"mask-border-source",
),
{
value: {
type: "image",
image: {
type: "url",
url: "foo.svg",
},
},
source: h.declaration("mask-border-source", "url(foo.svg)").toJSON(),
},
);
});

test("#computed parses linear-gradient value", (t) => {
t.deepEqual(
computed(
<div style={{ maskBorderSource: "linear-gradient(red, blue)" }}></div>,
"mask-border-source",
),
{
value: {
type: "image",
image: {
type: "gradient",
kind: "linear",
direction: {
type: "side",
side: "bottom",
},
items: [
{
color: {
type: "color",
format: "rgb",
alpha: {
type: "percentage",
value: 1,
},
red: {
type: "percentage",
value: 1,
},
green: {
type: "percentage",
value: 0,
},
blue: {
type: "percentage",
value: 0,
},
},
position: null,
type: "stop",
},
{
color: {
type: "color",
format: "rgb",
alpha: {
type: "percentage",
value: 1,
},
red: {
type: "percentage",
value: 0,
},
green: {
type: "percentage",
value: 0,
},
blue: {
type: "percentage",
value: 1,
},
},
position: null,
type: "stop",
},
],
repeats: false,
},
},
source: h
.declaration("mask-border-source", "linear-gradient(red, blue)")
.toJSON(),
},
);
});
1 change: 1 addition & 0 deletions packages/alfa-style/test/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"./property/isolation.spec.tsx",
"./property/line-height.spec.tsx",
"./property/margin.spec.tsx",
"./property/mask-border-source.spec.tsx",
"./property/mix-blend-mode.spec.tsx",
"./property/opacity.spec.tsx",
"./property/outline.spec.tsx",
Expand Down

0 comments on commit e5af28b

Please sign in to comment.