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

Easy support of calc expressions #1201

Merged
merged 25 commits into from
Aug 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
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
129 changes: 78 additions & 51 deletions docs/review/api/alfa-css.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { Hash } from '@siteimprove/alfa-hash';
import { Hashable } from '@siteimprove/alfa-hash';
import { Iterable as Iterable_2 } from '@siteimprove/alfa-iterable';
import * as json from '@siteimprove/alfa-json';
import { Mapper } from '@siteimprove/alfa-mapper';
import { Option } from '@siteimprove/alfa-option';
import { Parser } from '@siteimprove/alfa-parser';
import { Predicate } from '@siteimprove/alfa-predicate';
Expand All @@ -36,12 +35,8 @@ export class Angle<U extends Unit.Angle = Unit.Angle> extends Dimension<"angle",
// (undocumented)
scale(factor: number): Angle<U>;
// (undocumented)
toJSON(): Angle.JSON;
// (undocumented)
toString(): string;
// (undocumented)
get type(): "angle";
// (undocumented)
withUnit<U extends Unit.Angle>(unit: U): Angle<U>;
}

Expand All @@ -50,9 +45,7 @@ export namespace Angle {
// (undocumented)
export function isAngle(value: unknown): value is Angle;
// (undocumented)
export interface JSON extends Dimension.JSON<"angle"> {
// (undocumented)
unit: Unit.Angle;
export interface JSON<U extends Unit.Angle = Unit.Angle> extends Dimension.JSON<"angle", U> {
}
const // (undocumented)
parse: Parser<Slice<Token>, Angle, string>;
Expand Down Expand Up @@ -123,17 +116,28 @@ export namespace Box {
}

// @public (undocumented)
export class Calculation extends Value<"calculation"> {
export class Calculation<out D extends Calculation.Dimension = Calculation.Dimension> extends Value<"calculation"> {
// (undocumented)
equals(value: unknown): value is this;
// (undocumented)
get expression(): Calculation.Expression;
// (undocumented)
hash(hash: Hash): void;
// (undocumented)
isDimension<D extends Numeric.Dimension>(dimension: D): this is Calculation<D>;
// (undocumented)
isDimensionPercentage<D extends Numeric.Dimension>(dimension: D): this is Calculation<`${D}-percentage`>;
// (undocumented)
isNumber(): this is Calculation<"number">;
// (undocumented)
isPercentage(): this is Calculation<"percentage">;
// (undocumented)
static of(expression: Calculation.Expression): Calculation;
// (undocumented)
reduce(resolve: Mapper<Numeric>): Calculation;
reduce(resolver: Calculation.Resolver): Calculation;
resolve(this: Calculation<"length-percentage">, resolver: Calculation.Resolver<"px", Length<"px">>): Option<Length<"px">>;
// (undocumented)
resolve(this: Calculation<"number">, resolver: Calculation.Resolver<"px", Length<"px">>): Option<Number_2>;
// (undocumented)
toJSON(): Calculation.JSON;
// (undocumented)
Expand All @@ -144,19 +148,25 @@ export class Calculation extends Value<"calculation"> {

// @public (undocumented)
export namespace Calculation {
// @internal (undocumented)
export type Dimension = Kind.Base | `${Numeric.Dimension}-percentage` | "number";
// (undocumented)
export abstract class Expression implements Equatable, Serializable {
// (undocumented)
abstract equals(value: unknown): value is this;
// (undocumented)
abstract get kind(): Kind;
// Warning: (ae-incompatible-release-tags) The symbol "reduce" is marked as @public, but its signature references "Resolver" which is marked as @internal
//
// (undocumented)
abstract reduce(resolve: Mapper<Numeric>): Expression;
abstract reduce<L extends Unit.Length = "px", P extends Numeric = Numeric>(resolver: Resolver<L, P>): Expression;
// (undocumented)
toJSON(): Expression.JSON;
// (undocumented)
toLength(): Option<Length>;
// (undocumented)
toNumber(): Option<Number_2>;
// (undocumented)
toPercentage(): Option<Percentage>;
// (undocumented)
abstract toString(): string;
Expand All @@ -179,8 +189,10 @@ export namespace Calculation {
get kind(): Kind;
// (undocumented)
static of(operand: Expression): Invert;
// Warning: (ae-incompatible-release-tags) The symbol "reduce" is marked as @public, but its signature references "Resolver" which is marked as @internal
//
// (undocumented)
reduce(resolve: Mapper<Numeric>): Expression;
reduce<L extends Unit.Length = "px", P extends Numeric = Numeric>(resolver: Resolver<L, P>): Expression;
// (undocumented)
toString(): string;
// (undocumented)
Expand Down Expand Up @@ -237,7 +249,7 @@ export namespace Calculation {
// (undocumented)
export namespace Kind {
// (undocumented)
export type Base = "length" | "angle" | "time" | "frequency" | "resolution" | "percentage";
export type Base = Numeric.Dimension | "percentage";
// (undocumented)
export type Hint = Exclude<Kind.Base, "percentage">;
// (undocumented)
Expand All @@ -260,8 +272,10 @@ export namespace Calculation {
export class Negate extends Operation.Unary {
// (undocumented)
static of(operand: Expression): Negate;
// Warning: (ae-incompatible-release-tags) The symbol "reduce" is marked as @public, but its signature references "Resolver" which is marked as @internal
//
// (undocumented)
reduce(resolve: Mapper<Numeric>): Expression;
reduce<L extends Unit.Length = "px", P extends Numeric = Numeric>(resolver: Resolver<L, P>): Expression;
// (undocumented)
toString(): string;
// (undocumented)
Expand Down Expand Up @@ -305,19 +319,30 @@ export namespace Calculation {
export class Product extends Operation.Binary {
// (undocumented)
static of(...operands: [Expression, Expression]): Result<Product, string>;
// Warning: (ae-incompatible-release-tags) The symbol "reduce" is marked as @public, but its signature references "Resolver" which is marked as @internal
//
// (undocumented)
reduce(resolve: Mapper<Numeric>): Expression;
reduce<L extends Unit.Length = "px", P extends Numeric = Numeric>(resolver: Resolver<L, P>): Expression;
// (undocumented)
toString(): string;
// (undocumented)
get type(): "product";
}
// @internal
export interface Resolver<L extends Unit.Length = "px", P extends Numeric = Numeric> {
// (undocumented)
length(value: Length<Unit.Length.Relative>): Length<L>;
// (undocumented)
percentage(value: Percentage): P;
}
// (undocumented)
export class Sum extends Operation.Binary {
// (undocumented)
static of(...operands: [Expression, Expression]): Result<Sum, string>;
// Warning: (ae-incompatible-release-tags) The symbol "reduce" is marked as @public, but its signature references "Resolver" which is marked as @internal
//
// (undocumented)
reduce(resolve: Mapper<Numeric>): Expression;
reduce<L extends Unit.Length = "px", P extends Numeric = Numeric>(resolver: Resolver<L, P>): Expression;
// (undocumented)
toString(): string;
// (undocumented)
Expand All @@ -331,8 +356,10 @@ export namespace Calculation {
get kind(): Kind;
// (undocumented)
static of(value: Numeric): Value;
// Warning: (ae-incompatible-release-tags) The symbol "reduce" is marked as @public, but its signature references "Resolver" which is marked as @internal
//
// (undocumented)
reduce(resolve: Mapper<Numeric>): Value;
reduce<L extends Unit.Length = "px", P extends Numeric = Numeric>(resolver: Resolver<L, P>): Value;
// (undocumented)
toJSON(): Value.JSON;
// (undocumented)
Expand All @@ -352,8 +379,14 @@ export namespace Calculation {
value: Numeric.JSON;
}
}
const // Warning: (ae-incompatible-release-tags) The symbol "parse" is marked as @public, but its signature references "Dimension" which is marked as @internal
//
// (undocumented)
parse: Parser<Slice<Token>, Calculation<Dimension>, string, []>;
const // (undocumented)
parse: Parser<Slice<Token>, Calculation, string, []>;
parseLengthPercentage: Parser<Slice<Token>, Calculation<"length-percentage">, string, []>;
const // (undocumented)
parseLengthNumberPercentage: Parser<Slice<Token>, Calculation<"number"> | Calculation<"length-percentage">, string, []>;
}

// @public (undocumented)
Expand Down Expand Up @@ -522,8 +555,8 @@ export namespace Declaration {
}

// @public (undocumented)
export abstract class Dimension<T extends string = string, U extends Unit = Unit, V extends U = U> extends Numeric<T> implements Convertible<U>, Comparable<Dimension<T, U>> {
protected constructor(value: number, unit: V);
export abstract class Dimension<T extends Numeric.Dimension = Numeric.Dimension, U extends Unit = Unit, V extends U = U> extends Numeric<T> implements Convertible<U>, Comparable<Dimension<T, U>> {
protected constructor(value: number, unit: V, type: T);
// (undocumented)
abstract get canonicalUnit(): U;
// (undocumented)
Expand All @@ -533,6 +566,8 @@ export abstract class Dimension<T extends string = string, U extends Unit = Unit
// (undocumented)
hasUnit<V extends U>(unit: V): this is Dimension<T, U, V>;
// (undocumented)
toJSON(): Dimension.JSON<T, U>;
// (undocumented)
get unit(): V;
// (undocumented)
protected readonly _unit: V;
Expand All @@ -545,9 +580,9 @@ export namespace Dimension {
// (undocumented)
export function isDimension(value: unknown): value is Dimension;
// (undocumented)
export interface JSON<T extends string = string> extends Numeric.JSON<T> {
export interface JSON<T extends Numeric.Dimension = Numeric.Dimension, U extends Unit = Unit> extends Numeric.JSON<T> {
// (undocumented)
unit: Unit;
unit: U;
}
}

Expand Down Expand Up @@ -918,10 +953,6 @@ export class Integer extends Numeric<"integer"> {
static of(value: number): Integer;
// (undocumented)
scale(factor: number): Integer;
// (undocumented)
toJSON(): Integer.JSON;
// (undocumented)
get type(): "integer";
}

// @public (undocumented)
Expand All @@ -930,8 +961,6 @@ export namespace Integer {
export function isInteger(value: unknown): value is Integer;
// (undocumented)
export interface JSON extends Numeric.JSON<"integer"> {
// (undocumented)
value: number;
}
const // (undocumented)
parse: Parser<Slice<Token>, Integer, string>;
Expand Down Expand Up @@ -993,12 +1022,8 @@ export class Length<U extends Unit.Length = Unit.Length> extends Dimension<"leng
// (undocumented)
scale(factor: number): Length<U>;
// (undocumented)
toJSON(): Length.JSON<U>;
// (undocumented)
toString(): string;
// (undocumented)
get type(): "length";
// (undocumented)
withUnit<U extends Unit.Length>(unit: U): Length<U>;
}

Expand All @@ -1011,9 +1036,7 @@ export namespace Length {
const // (undocumented)
parse: Parser<Slice<Token>, Length, string>;
// (undocumented)
export interface JSON<U extends Unit.Length = Unit.Length> extends Dimension.JSON<"length"> {
// (undocumented)
unit: U;
export interface JSON<U extends Unit.Length = Unit.Length> extends Dimension.JSON<"length", U> {
}
}

Expand Down Expand Up @@ -1305,10 +1328,6 @@ class Number_2 extends Numeric<"number"> {
static of(value: number): Number_2;
// (undocumented)
scale(factor: number): Number_2;
// (undocumented)
toJSON(): Number_2.JSON;
// (undocumented)
get type(): "number";
}

// @public (undocumented)
Expand All @@ -1317,8 +1336,6 @@ namespace Number_2 {
function isNumber(value: unknown): value is Number_2;
// (undocumented)
interface JSON extends Numeric.JSON<"number"> {
// (undocumented)
value: number;
}
const // (undocumented)
parseZero: Parser<Slice<Token>, Number_2, string>;
Expand All @@ -1328,8 +1345,8 @@ namespace Number_2 {
export { Number_2 as Number }

// @public (undocumented)
export abstract class Numeric<T extends string = string> extends Value<T> implements Comparable<Numeric<T>> {
protected constructor(value: number);
export abstract class Numeric<T extends Numeric.Type = Numeric.Type> extends Value<T> implements Comparable<Numeric<T>> {
protected constructor(value: number, type: T);
// (undocumented)
compare(value: Numeric<T>): Comparison;
static readonly Decimals = 7;
Expand All @@ -1340,26 +1357,42 @@ export abstract class Numeric<T extends string = string> extends Value<T> implem
// (undocumented)
abstract scale(factor: number): Numeric<T>;
// (undocumented)
abstract toJSON(): Numeric.JSON<T>;
toJSON(): Numeric.JSON<T>;
// (undocumented)
toString(): string;
// (undocumented)
get type(): T;
// (undocumented)
protected readonly _type: T;
// (undocumented)
get value(): number;
// (undocumented)
protected readonly _value: number;
}

// @public (undocumented)
export namespace Numeric {
// (undocumented)
export type Dimension = "angle" | "length";
// (undocumented)
export function isNumeric(value: unknown): value is Numeric;
// Warning: (ae-incompatible-release-tags) The symbol "JSON" is marked as @public, but its signature references "Type" which is marked as @internal
//
// (undocumented)
export interface JSON<T extends string = string> extends Value.JSON<T> {
export interface JSON<T extends Type = Type> extends Value.JSON<T> {
// (undocumented)
[key: string]: json.JSON;
// (undocumented)
type: T;
// (undocumented)
value: number;
}
// (undocumented)
export type Ratio = "percentage";
// (undocumented)
export type Scalar = "integer" | "number";
// @internal (undocumented)
export type Type = Scalar | Ratio | Dimension;
}

// @public (undocumented)
Expand All @@ -1371,11 +1404,7 @@ export class Percentage extends Numeric<"percentage"> {
// (undocumented)
scale(factor: number): Percentage;
// (undocumented)
toJSON(): Percentage.JSON;
// (undocumented)
toString(): string;
// (undocumented)
get type(): "percentage";
}

// @public (undocumented)
Expand All @@ -1384,8 +1413,6 @@ export namespace Percentage {
export function isPercentage(value: unknown): value is Percentage;
// (undocumented)
export interface JSON extends Numeric.JSON<"percentage"> {
// (undocumented)
value: number;
}
const // (undocumented)
parse: Parser<Slice<Token>, Percentage, string>;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"execa": "^5.1.1",
"minimist": "^1.2.6",
"package-dependency-graph": "^1.14.3",
"prettier": "^2.4.1",
"prettier": "^2.7.1",
"typescript": "^4.7.3"
},
"packageManager": "yarn@3.0.2"
Expand Down
1 change: 1 addition & 0 deletions packages/alfa-css/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"@siteimprove/alfa-record": "workspace:^0.43.1",
"@siteimprove/alfa-refinement": "workspace:^0.43.1",
"@siteimprove/alfa-result": "workspace:^0.43.1",
"@siteimprove/alfa-selective": "workspace:^0.43.1",
"@siteimprove/alfa-slice": "workspace:^0.43.1",
"@siteimprove/alfa-thunk": "workspace:^0.43.1"
},
Expand Down
Loading