Skip to content

Commit

Permalink
Store original device layout was scraped with (#1474)
Browse files Browse the repository at this point in the history
* Add device parameter to element constructor

* Replace `box` property by `boxes: Cache<Device, Rectangle>`

* Add dependency alfa-dom -> alfa-device to package.json

* Add device to tests using box

* Extract API

* Add unlisted dependency

* Add dependency in tsconfig too

* Add `OPTIONS` type parameter to `Serializable` interface

* Add serialization options

* Extract API

* Clean up

* Add changesets

* Update .changeset/chilled-laws-hammer.md

Co-authored-by: Jean-Yves Moyen <[email protected]>

* Update packages/alfa-dom/src/node.ts

Co-authored-by: Jean-Yves Moyen <[email protected]>

* Remove placeholder function

* Removed unused imports and dependencies

* Remove package the right way

* Extract API

* Update yarn.lock

* Revert yarn.lock update

* Revert all changes to *.api.md as something seems to have gone wrong

* Extract API

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jean-Yves Moyen <[email protected]>
  • Loading branch information
3 people authored Oct 19, 2023
1 parent 831e7ff commit 6231b55
Show file tree
Hide file tree
Showing 38 changed files with 346 additions and 216 deletions.
7 changes: 7 additions & 0 deletions .changeset/beige-colts-chew.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@siteimprove/alfa-style": minor
---

**Breaking:** Function `getBoundingBox` was removed.

Use `Element#getBoundingBox` instead.
7 changes: 7 additions & 0 deletions .changeset/brave-dolphins-smash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@siteimprove/alfa-json": minor
---

**Added:** `Serializable` interface now optionally accepts serialization options.

When implementing the interface a type parameter can be supplied and `toJSON` can optionally take an object of that type that can be used for changing the serialization behavior.
7 changes: 7 additions & 0 deletions .changeset/chilled-laws-hammer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@siteimprove/alfa-dom": minor
---

**Breaking:** `Element#of` now requires the device used when scraping a page in order to store a box.

This ensures that the boxes of the elements will be stored with and only be accessible for the same device instance. If no device is provided, no box is stored with the element.
7 changes: 7 additions & 0 deletions .changeset/metal-planets-hammer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@siteimprove/alfa-tree": minor
---

**Added:** Optional serialization options type parameter added to abstract `Node` class.

This is passed to the `Serializable` interface to allow implementers to supply the serialization options type.
7 changes: 7 additions & 0 deletions .changeset/slow-moles-thank.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@siteimprove/alfa-dom": minor
---

**Added:** `Document#toJSON` now optionally accepts serialization options containing device.

The options will be passed down to all children of the document and used by `Element` to serialize the box corresponding to the device.
50 changes: 28 additions & 22 deletions docs/review/api/alfa-dom.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
```ts

import { Array as Array_2 } from '@siteimprove/alfa-array';
import { Device } from '@siteimprove/alfa-device';
import * as earl from '@siteimprove/alfa-earl';
import { Equatable } from '@siteimprove/alfa-equatable';
import { Flags } from '@siteimprove/alfa-flags';
Expand Down Expand Up @@ -227,15 +228,15 @@ export class Document extends Node<"document"> {
// (undocumented)
get style(): Iterable<Sheet>;
// (undocumented)
toJSON(): Document.JSON;
toJSON(options?: Node.SerializationOptions): Document.JSON;
// (undocumented)
toString(): string;
}

// @public (undocumented)
export namespace Document {
// @internal (undocumented)
export function fromDocument(json: JSON): Trampoline<Document>;
export function fromDocument(json: JSON, device?: Device): Trampoline<Document>;
// (undocumented)
export function isDocument(value: unknown): value is Document;
// (undocumented)
Expand All @@ -262,14 +263,14 @@ export class Element<N extends string = string> extends Node<"element"> implemen
// (undocumented)
get attributes(): Sequence<Attribute>;
// (undocumented)
get box(): Option<Rectangle>;
// (undocumented)
children(options?: Node.Traversal): Sequence<Node>;
// (undocumented)
get classes(): Sequence<string>;
// (undocumented)
get content(): Option<Document>;
// (undocumented)
getBoundingBox(device: Device): Option<Rectangle>;
// (undocumented)
get id(): Option<string>;
// @internal (undocumented)
protected _internalPath(options?: Node.Traversal): string;
Expand All @@ -280,7 +281,7 @@ export class Element<N extends string = string> extends Node<"element"> implemen
// (undocumented)
get namespace(): Option<Namespace>;
// (undocumented)
static of<N extends string = string>(namespace: Option<Namespace>, prefix: Option<string>, name: N, attributes?: Iterable_2<Attribute>, children?: Iterable_2<Node>, style?: Option<Block>, box?: Option<Rectangle>): Element<N>;
static of<N extends string = string>(namespace: Option<Namespace>, prefix: Option<string>, name: N, attributes?: Iterable_2<Attribute>, children?: Iterable_2<Node>, style?: Option<Block>, box?: Option<Rectangle>, device?: Option<Device>): Element<N>;
// (undocumented)
parent(options?: Node.Traversal): Option<Node>;
// (undocumented)
Expand All @@ -294,15 +295,15 @@ export class Element<N extends string = string> extends Node<"element"> implemen
// (undocumented)
tabIndex(): Option<number>;
// (undocumented)
toJSON(): Element.JSON<N>;
toJSON(options?: Node.SerializationOptions): Element.JSON<N>;
// (undocumented)
toString(): string;
}

// @public (undocumented)
export namespace Element {
// @internal (undocumented)
export function fromElement<N extends string = string>(json: JSON<N>): Trampoline<Element<N>>;
export function fromElement<N extends string = string>(json: JSON<N>, device?: Device): Trampoline<Element<N>>;
// (undocumented)
export function isElement(value: unknown): value is Element;
// (undocumented)
Expand Down Expand Up @@ -398,7 +399,7 @@ export class Fragment extends Node<"fragment"> {
// @public (undocumented)
export namespace Fragment {
// @internal (undocumented)
export function fromFragment(json: JSON): Trampoline<Fragment>;
export function fromFragment(json: JSON, device?: Device): Trampoline<Fragment>;
// (undocumented)
export function isFragment(value: unknown): value is Fragment;
// (undocumented)
Expand Down Expand Up @@ -431,7 +432,7 @@ export namespace GroupingRule {
}

// @public (undocumented)
export function h<N extends string = string>(name: N, attributes?: Array<Attribute> | Record<string, string | boolean>, children?: Array<Node | string>, style?: Array<Declaration> | Record<string, string>, box?: Rectangle): Element<N>;
export function h<N extends string = string>(name: N, attributes?: Array<Attribute> | Record<string, string | boolean>, children?: Array<Node | string>, style?: Array<Declaration> | Record<string, string>, box?: Rectangle, device?: Device): Element<N>;

// @public (undocumented)
export namespace h {
Expand All @@ -444,7 +445,7 @@ export namespace h {
// (undocumented)
export function document(children: Array<Node | string>, style?: Array<Sheet>): Document;
// (undocumented)
export function element<N extends string = string>(name: N, attributes?: Array<Attribute> | Record<string, string | boolean>, children?: Array<Node | string>, style?: Array<Declaration> | Record<string, string>, namespace?: Namespace, box?: Rectangle): Element<N>;
export function element<N extends string = string>(name: N, attributes?: Array<Attribute> | Record<string, string | boolean>, children?: Array<Node | string>, style?: Array<Declaration> | Record<string, string>, namespace?: Namespace, box?: Rectangle, device?: Device): Element<N>;
// (undocumented)
export function fragment(children: Array<Node | string>): Fragment;
// (undocumented)
Expand Down Expand Up @@ -675,7 +676,7 @@ export namespace NamespaceRule {
}

// @public (undocumented)
export abstract class Node<T extends string = string> extends tree.Node<Node.Traversal.Flag, T> implements earl.Serializable<Node.EARL>, json.Serializable<tree.Node.JSON<T>>, sarif.Serializable<sarif.Location> {
export abstract class Node<T extends string = string> extends tree.Node<Node.Traversal.Flag, T> implements earl.Serializable<Node.EARL>, json.Serializable<tree.Node.JSON<T>, Node.SerializationOptions>, sarif.Serializable<sarif.Location> {
protected constructor(children: Array<Node>, type: T);
// (undocumented)
equals(value: Node): boolean;
Expand Down Expand Up @@ -774,32 +775,37 @@ export namespace Node {
};
}
// (undocumented)
export function from(json: Element.JSON): Element;
export function from(json: Element.JSON, device?: Device): Element;
// (undocumented)
export function from(json: Attribute.JSON): Attribute;
export function from(json: Attribute.JSON, device?: Device): Attribute;
// (undocumented)
export function from(json: Text.JSON): Text;
export function from(json: Text.JSON, device?: Device): Text;
// (undocumented)
export function from(json: Comment.JSON): Comment;
export function from(json: Comment.JSON, device?: Device): Comment;
// (undocumented)
export function from(json: Document.JSON, device?: Device): Document;
const flatTree: Traversal;
const fullTree: Traversal;
const composedNested: Traversal;
// (undocumented)
export function from(json: Document.JSON): Document;
// (undocumented)
export function from(json: Type.JSON): Document;
export function from(json: Type.JSON, device?: Device): Document;
// (undocumented)
export function from(json: Fragment.JSON): Fragment;
export function from(json: Fragment.JSON, device?: Device): Fragment;
// (undocumented)
export function from(json: JSON): Node;
export function from(json: JSON, device?: Device): Node;
// @internal (undocumented)
export function fromNode(json: JSON): Trampoline<Node>;
export function fromNode(json: JSON, device?: Device): Trampoline<Node>;
// (undocumented)
export function isNode(value: unknown): value is Node;
// (undocumented)
export interface JSON<T extends string = string> extends tree.Node.JSON<T> {
}
// (undocumented)
export interface SerializationOptions {
// (undocumented)
device: Device;
}
// (undocumented)
export class Traversal extends Flags<Traversal.Flag> {
// (undocumented)
static of(...flags: Array<Traversal.Flag>): Traversal;
Expand Down Expand Up @@ -964,7 +970,7 @@ export class Shadow extends Node<"shadow"> {
// @public (undocumented)
export namespace Shadow {
// @internal (undocumented)
export function fromShadow(json: JSON): Trampoline<Shadow>;
export function fromShadow(json: JSON, device?: Device): Trampoline<Shadow>;
// (undocumented)
export function isShadow(value: unknown): value is Shadow;
// (undocumented)
Expand Down
8 changes: 4 additions & 4 deletions docs/review/api/alfa-json.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ namespace JSON_2 {
export { JSON_2 as JSON }

// @public (undocumented)
export interface Serializable<T extends JSON_2 = JSON_2> {
export interface Serializable<T extends JSON_2 = JSON_2, OPTIONS extends unknown = unknown> {
// (undocumented)
toJSON(): T;
toJSON(options?: OPTIONS): T;
}

// @public (undocumented)
Expand All @@ -36,9 +36,9 @@ export namespace Serializable {
// (undocumented)
export type ToJSON<T> = T extends Serializable<infer U> ? U : T extends JSON_2 ? T : JSON_2;
// (undocumented)
export function toJSON<T extends JSON_2>(value: Serializable<T>): T;
export function toJSON<T extends JSON_2, OPTIONS extends unknown = unknown>(value: Serializable<T>, options?: OPTIONS): T;
// (undocumented)
export function toJSON<T>(value: T): ToJSON<T>;
export function toJSON<T, OPTIONS extends unknown = unknown>(value: T, options?: OPTIONS): ToJSON<T>;
}

// (No @packageDocumentation comment for this package)
Expand Down
2 changes: 0 additions & 2 deletions docs/review/api/alfa-style.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import { Percentage } from '@siteimprove/alfa-css';
import { Position } from '@siteimprove/alfa-css';
import { Predicate } from '@siteimprove/alfa-predicate';
import { Rectangle } from '@siteimprove/alfa-css';
import { Rectangle as Rectangle_2 } from '@siteimprove/alfa-rectangle';
import { Rotate } from '@siteimprove/alfa-css';
import { Serializable } from '@siteimprove/alfa-json';
import { Shadow } from '@siteimprove/alfa-css';
Expand Down Expand Up @@ -373,7 +372,6 @@ export namespace Style {
const // Warning: (ae-forgotten-export) The symbol "element" needs to be exported by the entry point index.d.ts
//
// (undocumented)
getBoundingBox: typeof element.getBoundingBox, // (undocumented)
getOffsetParent: typeof element.getOffsetParent, // (undocumented)
getPositioningParent: typeof element.getPositioningParent, // (undocumented)
hasBorder: typeof element.hasBorder, // (undocumented)
Expand Down
4 changes: 2 additions & 2 deletions docs/review/api/alfa-tree.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { Refinement } from '@siteimprove/alfa-refinement';
import { Sequence } from '@siteimprove/alfa-sequence';

// @public
export abstract class Node<F extends Flags.allFlags, T extends string = string> implements Iterable<Node<F>>, Equatable, Hashable, json.Serializable<Node.JSON<T>> {
export abstract class Node<F extends Flags.allFlags, T extends string = string, S extends unknown = unknown> implements Iterable<Node<F>>, Equatable, Hashable, json.Serializable<Node.JSON<T>, S> {
// (undocumented)
[Symbol.iterator](): Iterator<Node<F>>;
protected constructor(children: Array<Node<F>>, type: T);
Expand Down Expand Up @@ -90,7 +90,7 @@ export abstract class Node<F extends Flags.allFlags, T extends string = string>
// (undocumented)
siblings(options?: Flags<F>): Sequence<Node<F>>;
// (undocumented)
toJSON(): Node.JSON<T>;
toJSON(options?: S): Node.JSON<T>;
// (undocumented)
get type(): T;
// (undocumented)
Expand Down
1 change: 1 addition & 0 deletions packages/alfa-dom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"@siteimprove/alfa-array": "workspace:^0.67.0",
"@siteimprove/alfa-cache": "workspace:^0.67.0",
"@siteimprove/alfa-css": "workspace:^0.67.0",
"@siteimprove/alfa-device": "workspace:^0.67.0",
"@siteimprove/alfa-earl": "workspace:^0.67.0",
"@siteimprove/alfa-equatable": "workspace:^0.67.0",
"@siteimprove/alfa-flags": "workspace:^0.67.0",
Expand Down
12 changes: 8 additions & 4 deletions packages/alfa-dom/src/h.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { None, Option } from "@siteimprove/alfa-option";
import { Predicate } from "@siteimprove/alfa-predicate";

import { Device } from "@siteimprove/alfa-device";
import { Rectangle } from "@siteimprove/alfa-rectangle";
import {
Attribute,
Expand Down Expand Up @@ -37,9 +38,10 @@ export function h<N extends string = string>(
attributes?: Array<Attribute> | Record<string, string | boolean>,
children?: Array<Node | string>,
style?: Array<Declaration> | Record<string, string>,
box?: Rectangle
box?: Rectangle,
device: Device = Device.standard()
): Element<N> {
return h.element(name, attributes, children, style, undefined, box);
return h.element(name, attributes, children, style, undefined, box, device);
}

/**
Expand All @@ -52,7 +54,8 @@ export namespace h {
children: Array<Node | string> = [],
style: Array<Declaration> | Record<string, string> = [],
namespace?: Namespace,
box?: Rectangle
box?: Rectangle,
device?: Device
): Element<N> {
attributes = Array.isArray(attributes)
? attributes
Expand Down Expand Up @@ -95,7 +98,8 @@ export namespace h {
.filter(nor(Document.isDocument, Shadow.isShadow))
.map((child) => (typeof child === "string" ? h.text(child) : child)),
style.length === 0 ? None : Option.of(block),
Option.from(box)
Option.from(box),
Option.from(device)
);

if (content !== undefined) {
Expand Down
11 changes: 9 additions & 2 deletions packages/alfa-dom/src/jsx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { h } from "./h";

import { Element, Node } from ".";

import { Device } from "@siteimprove/alfa-device";
import { Rectangle } from "@siteimprove/alfa-rectangle";
import * as dom from ".";

Expand All @@ -18,6 +19,7 @@ export function jsx<N extends string = string>(
const attributes: Record<string, string | boolean> = {};
const style: Record<string, string> = {};
let box: Rectangle | undefined = undefined;
let device: Device | undefined = undefined;

for (const [name, value] of entries(properties ?? {})) {
if (value === null || value === undefined) {
Expand All @@ -33,7 +35,11 @@ export function jsx<N extends string = string>(
continue;

case "box":
box = Rectangle.from(value as Rectangle.JSON);
const deviceAndBox = value as { device: Device } & Rectangle.JSON;

box = Rectangle.from(deviceAndBox);
device = deviceAndBox.device;

continue;

default:
Expand All @@ -46,7 +52,8 @@ export function jsx<N extends string = string>(
attributes,
(children as Array<jsx.Child>).flat(Infinity),
style,
box
box,
device
);
}

Expand Down
Loading

0 comments on commit 6231b55

Please sign in to comment.