Skip to content

Commit 1fba83c

Browse files
feat: initial source code (#1)
1 parent 74c357c commit 1fba83c

File tree

19 files changed

+802
-29
lines changed

19 files changed

+802
-29
lines changed

.github/workflows/publish.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
name: Publish
22

33
on:
4-
# push:
5-
# branches:
6-
# - main
4+
push:
5+
branches:
6+
- main
77
workflow_dispatch:
88

99
jobs:

LIBRARY.md

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
1-
# @example/package
1+
# @nc/css-color-value
22

3-
A description of this library.
4-
5-
## Usage
6-
```ts
7-
import { add } from '@example/package'
8-
9-
add(2, 2)
10-
```
3+
A work-in-progress polyfill for `CSSColorValue` and related types, from the CSS Typed OM Level 1 API.
114

125
## License
136

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2024 {{author}}
3+
Copyright (c) 2024 Samantha Nguyen
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ First, create a new repository. Choose your method:
1717
```
1818

1919
Then, make sure to update the following:
20-
- [`./LICENSE`](./LICENSE): change `{{author}}` to your username
21-
or real name, whichever you prefer.
20+
- [`./LICENSE`](./LICENSE): change `{{author}}` to your username or real name, whichever you prefer.
2221
- [`./deno.json`](./deno.json): change the package name to your own.
2322
- [`./.github/workflows/publish.yml`](./.github/workflows/publish.yml): Uncomment out the top so that the workflow will publish your package every time there's a commit pushed to `main` branch.
2423
- Delete this `README.md` file, rename `LIBRARY.md` to `README.md`, and update with your own information.

deno.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "@example/package",
2+
"name": "@nc/css-color-value",
33
"version": "0.1.0",
44
"license": "MIT",
55
"tasks": {
@@ -14,6 +14,14 @@
1414
"LICENSE"
1515
]
1616
},
17+
"compilerOptions": {
18+
"lib": [
19+
"deno.ns",
20+
"DOM",
21+
"DOM.Iterable",
22+
"ESNext"
23+
]
24+
},
1725
"exports": {
1826
".": "./src/mod.ts"
1927
},

deno.lock

Lines changed: 6 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/matches.ts

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/**
2+
* @see {@link https://drafts.css-houdini.org/css-typed-om/#cssnumericvalue-match}
3+
*/
4+
const matchesSingleType = (
5+
value: CSSNumericValue,
6+
productionKey: keyof CSSNumericType,
7+
expected: number = 1,
8+
): boolean => {
9+
const type = value.type()
10+
for (const key in type) {
11+
const typedKey = key as keyof CSSNumericType
12+
if (typedKey === productionKey) {
13+
if (type[typedKey] !== expected) return false
14+
} else {
15+
if (type[typedKey] !== 0) return false
16+
}
17+
}
18+
return true
19+
}
20+
21+
/**
22+
* A CSSNumericValue matches for `<number>`
23+
* when all entries of `CSSNumericType` are non-zero
24+
*/
25+
export const matchesNumber = (value: CSSNumericValue): boolean => {
26+
const type = value.type()
27+
return type.length !== 0 &&
28+
type.angle !== 0 &&
29+
type.time !== 0 &&
30+
type.frequency !== 0 &&
31+
type.resolution !== 0 &&
32+
type.flex !== 0 &&
33+
type.percent !== 0
34+
}
35+
36+
/**
37+
* A CSSNumericValue matches for `<length>`
38+
* when the only non-zero entry of `CSSNumericType` is length of 1
39+
*
40+
* @see {@link https://drafts.csswg.org/css-values-4/#length-value}
41+
*/
42+
export const matchesLength = (value: CSSNumericValue): boolean =>
43+
matchesSingleType(value, 'length', 1)
44+
45+
/**
46+
* A CSSNumericValue matches for `<angle>`
47+
* when the only non-zero entry of `CSSNumericType` is angle of 1
48+
*
49+
* @see {@link https://drafts.csswg.org/css-values-4/#angle-value}
50+
*/
51+
export const matchesAngle = (value: CSSNumericValue): boolean =>
52+
matchesSingleType(value, 'angle', 1)
53+
54+
/**
55+
* A CSSNumericValue matches for `<time>`
56+
* when the only non-zero entry of `CSSNumericType` is time of 1
57+
*
58+
* @see {@link https://drafts.csswg.org/css-values-4/#time-value}
59+
*/
60+
export const matchesTime = (value: CSSNumericValue): boolean =>
61+
matchesSingleType(value, 'time', 1)
62+
63+
/**
64+
* A CSSNumericValue matches for `<frequency>`
65+
* when the only non-zero entry of `CSSNumericType` is frequency of 1
66+
*
67+
* @see {@link https://drafts.csswg.org/css-values-4/#frequency-value}
68+
*/
69+
export const matchesFrequency = (value: CSSNumericValue): boolean =>
70+
matchesSingleType(value, 'frequency', 1)
71+
72+
/**
73+
* A CSSNumericValue matches for `<resolution>`
74+
* when the only non-zero entry of `CSSNumericType` is resolution of 1
75+
*
76+
* @see {@link https://drafts.csswg.org/css-values-4/#resolution-value}
77+
*/
78+
export const matchesResolution = (value: CSSNumericValue): boolean =>
79+
matchesSingleType(value, 'resolution', 1)
80+
81+
/**
82+
* A CSSNumericValue matches for `<flex>`
83+
* when the only non-zero entry of `CSSNumericType` is flex of 1
84+
*
85+
* @see {@link https://drafts.csswg.org/css-values-4/#flex-value}
86+
*/
87+
export const matchesFlex = (value: CSSNumericValue): boolean =>
88+
matchesSingleType(value, 'flex', 1)
89+
90+
/**
91+
* A CSSNumericValue matches for `<percent>`
92+
* when the only non-zero entry of `CSSNumericType` is percent of 1
93+
*
94+
* @see {@link https://drafts.csswg.org/css-values-4/#percent-value}
95+
*/
96+
export const matchesPercent = (value: CSSNumericValue): boolean =>
97+
matchesSingleType(value, 'percent', 1)
98+
99+
/**
100+
* A CSSNumericValue matches for `<length-percentage>`
101+
*
102+
* @see {@link https://drafts.csswg.org/css-values-4/#typedef-length-percentage}
103+
*/
104+
export const matchesLengthPercentage = (value: CSSNumericValue): boolean =>
105+
matchesLength(value) || matchesPercent(value)
106+
107+
/**
108+
* A CSSNumericValue matches for `<frequency-percentage>`
109+
*
110+
* @see {@link https://drafts.csswg.org/css-values-4/#typedef-frequency-percentage}
111+
*/
112+
export const matchesFrequencyPercentage = (value: CSSNumericValue): boolean =>
113+
matchesFrequency(value) || matchesPercent(value)
114+
115+
/**
116+
* A CSSNumericValue matches for `<angle-percentage>`
117+
*
118+
* @see {@link https://drafts.csswg.org/css-values-4/#typedef-angle-percentage}
119+
*/
120+
export const matchesAnglePercentage = (value: CSSNumericValue): boolean =>
121+
matchesAngle(value) || matchesPercent(value)
122+
123+
/**
124+
* A CSSNumericValue matches for `<time-percentage>`
125+
*
126+
* @see {@link https://drafts.csswg.org/css-values-4/#typedef-time-percentage}
127+
*/
128+
export const matchesTimePercentage = (value: CSSNumericValue): boolean =>
129+
matchesTime(value) || matchesPercent(value)

src/mod.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
/**
2-
* Adds x and y.
3-
* @param {number} x
4-
* @param {number} y
5-
* @returns {number} Sum of x and y
2+
* A CSS Typed OM value which represents a `<color>`.
3+
*
4+
* @see {@link https://drafts.css-houdini.org/css-typed-om/#colorvalue-objects}
65
*/
7-
export function add(x: number, y: number): number {
8-
return x + y
6+
export class CssColorValue extends CSSStyleValue {
7+
/**
8+
* Parse a string into a `CssColorValue`
9+
*
10+
* @see {@link https://drafts.css-houdini.org/css-typed-om/#dom-csscolorvalue-parse}
11+
*/
12+
static override parse(_value: string): CssColorValue | CSSStyleValue {
13+
throw new Error()
14+
}
915
}

src/mod_test.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/reify.ts

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import { matchesAngle, matchesNumber, matchesPercent } from './matches.ts'
2+
import type {
3+
CSSColorAngle,
4+
CSSColorNumber,
5+
CSSColorPercent,
6+
CSSColorRGBComp,
7+
} from './types.ts'
8+
9+
/**
10+
* A method that turns an `<ident>` into a CSSKeywordValue.
11+
*
12+
* @see {@link https://drafts.css-houdini.org/css-typed-om/#reify-an-identifier}
13+
*/
14+
export function reifyIdent(ident: string): CSSKeywordValue {
15+
return new CSSKeywordValue(ident)
16+
}
17+
18+
/**
19+
* A method that turns a CSSKeywordish into a CSSKeywordValue.
20+
*
21+
* @see {@link https://drafts.css-houdini.org/css-typed-om/#rectify-a-keywordish-value}
22+
*/
23+
export function rectifyKeywordish(val: CSSKeywordish): CSSKeywordValue {
24+
return val instanceof CSSKeywordValue ? val : new CSSKeywordValue(val)
25+
}
26+
27+
/**
28+
* A method that turns a CSSColorRGBComp into a Typed OM value.
29+
*
30+
* @see {@link https://drafts.css-houdini.org/css-typed-om/#rectify-a-csscolorrgbcomp}
31+
*/
32+
export function rectifyColorRGBComp(
33+
val: CSSColorRGBComp,
34+
): CSSUnitValue | CSSKeywordValue | CSSNumericValue {
35+
if (typeof val === 'number') {
36+
return new CSSUnitValue(val * 100, 'percent')
37+
}
38+
if (typeof val === 'string') {
39+
return rectifyKeywordish(val)
40+
}
41+
if (
42+
val instanceof CSSNumericValue &&
43+
(matchesNumber(val) || matchesPercent(val))
44+
) {
45+
return val
46+
}
47+
if (val instanceof CSSKeywordValue && val.value.toLowerCase() === 'none') {
48+
return val
49+
}
50+
throw new SyntaxError()
51+
}
52+
53+
/**
54+
* A method that turns a CSSColorPercent into a Typed OM value.
55+
*
56+
* @see {@link https://drafts.css-houdini.org/css-typed-om/#rectify-a-csscolorpercent}
57+
*/
58+
export function rectifyColorPercent(
59+
val: CSSColorPercent,
60+
): CSSUnitValue | CSSKeywordValue | CSSNumericValue {
61+
if (typeof val === 'number') {
62+
return new CSSUnitValue(val * 100, 'percent')
63+
}
64+
if (typeof val === 'string') {
65+
return rectifyKeywordish(val)
66+
}
67+
if (val instanceof CSSNumericValue && matchesPercent(val)) {
68+
return val
69+
}
70+
if (val instanceof CSSKeywordValue && val.value.toLowerCase() === 'none') {
71+
return val
72+
}
73+
throw new SyntaxError()
74+
}
75+
76+
/**
77+
* A method that turns a CSSColorNumber into a Typed OM value.
78+
*
79+
* @see {@link https://drafts.css-houdini.org/css-typed-om/#rectify-a-csscolornumber}
80+
*/
81+
export function rectifyColorNumber(
82+
val: CSSColorNumber,
83+
): CSSUnitValue | CSSKeywordValue | CSSNumericValue {
84+
if (typeof val === 'number') {
85+
return new CSSUnitValue(val, 'number')
86+
}
87+
if (typeof val === 'string') {
88+
return rectifyKeywordish(val)
89+
}
90+
if (val instanceof CSSNumericValue && matchesNumber(val)) {
91+
return val
92+
}
93+
if (val instanceof CSSKeywordValue && val.value.toLowerCase() === 'none') {
94+
return val
95+
}
96+
throw new SyntaxError()
97+
}
98+
99+
/**
100+
* A method that turns a CSSColorAngle into a Typed OM value.
101+
*
102+
* @see {@link https://drafts.css-houdini.org/css-typed-om/#rectify-a-csscolorangle}
103+
*/
104+
export function rectifyColorAngle(
105+
val: CSSColorAngle,
106+
): CSSUnitValue | CSSKeywordValue | CSSNumericValue {
107+
if (typeof val === 'number') {
108+
return new CSSUnitValue(val, 'deg')
109+
}
110+
if (typeof val === 'string') {
111+
return rectifyKeywordish(val)
112+
}
113+
if (val instanceof CSSNumericValue && matchesAngle(val)) {
114+
return val
115+
}
116+
if (val instanceof CSSKeywordValue && val.value.toLowerCase() === 'none') {
117+
return val
118+
}
119+
throw new SyntaxError()
120+
}

0 commit comments

Comments
 (0)