Commit 21ae258e authored by Alejandro Celaya's avatar Alejandro Celaya Committed by Alejandro Celaya

Migrate buckets module to TS

parent 5dfad22f
import type { Anchor, AnchorPosition } from '../../types/annotator';
import { getBoundingClientRect } from '../highlighter'; import { getBoundingClientRect } from '../highlighter';
/** export type Bucket = {
* @typedef {import('../../types/annotator').Anchor} Anchor /** The annotation tags in this bucket */
* @typedef {import('../../types/annotator').AnchorPosition} AnchorPosition tags: Set<string>;
*/ /** The vertical pixel offset where this bucket should appear in the bucket bar */
position: number;
};
/** export type BucketSet = {
* @typedef Bucket /**
* @prop {Set<string>} tags - The annotation tags in this bucket * A single bucket containing all the annotation tags whose anchors are
* @prop {number} position - The vertical pixel offset where this bucket should * offscreen upwards
* appear in the bucket bar */
*/ above: Bucket;
/** /**
* @typedef BucketSet * A single bucket containing all the annotation tags which anchors are
* @prop {Bucket} above - A single bucket containing all the annotation * offscreen downwards
* tags whose anchors are offscreen upwards */
* @prop {Bucket} below - A single bucket containing all the annotation below: Bucket;
* tags which anchors are offscreen downwards
* @prop {Bucket[]} buckets - On-screen buckets
*/
/** /** On-screen buckets */
* @typedef WorkingBucket buckets: Bucket[];
* @prop {Set<string>} tags - The annotation tags in this bucket };
* @prop {number} position - The computed position (offset) for this bucket,
* based on the current anchors. This is centered between `top` and `bottom` export type WorkingBucket = {
* @prop {number} top - The uppermost (lowest) vertical offset for the anchors /** The annotation tags in this bucket */
* in this bucket — the lowest `top` position value, akin to the top offset of tags: Set<string>;
* a theoretical box drawn around all of the anchor highlights in this bucket
* @prop {number} bottom - The bottommost (highest) vertical offset for the /**
* anchors in this bucket — the highest `top` position value, akin to the * The computed position (offset) for this bucket, based on the current anchors.
* bottom of a theoretical box drawn around all of the anchor highlights in * This is centered between `top` and `bottom`
* this bucket */
*/ position: number;
/**
* The uppermost (lowest) vertical offset for the anchors in this bucket —
* the lowest `top` position value, akin to the top offset of a theoretical
* box drawn around all the anchor highlights in this bucket
*/
top: number;
/**
* he bottommost (highest) vertical offset for the anchors in this bucket —
* the highest `top` position value, akin to the bottom of a theoretical box
* drawn around all the anchor highlights in this bucket
*/
bottom: number;
};
// Only anchors with top offsets between `BUCKET_TOP_THRESHOLD` and // Only anchors with top offsets between `BUCKET_TOP_THRESHOLD` and
// `window.innerHeight - BUCKET_BOTTOM_THRESHOLD` are considered "on-screen" // `window.innerHeight - BUCKET_BOTTOM_THRESHOLD` are considered "on-screen"
...@@ -49,15 +64,16 @@ const BUCKET_GAP_SIZE = 60; ...@@ -49,15 +64,16 @@ const BUCKET_GAP_SIZE = 60;
* Find the closest valid anchor in `anchors` that is offscreen in the direction * Find the closest valid anchor in `anchors` that is offscreen in the direction
* indicated. * indicated.
* *
* @param {Anchor[]} anchors * @return The closest anchor or `null` if no valid anchor found
* @param {'up'|'down'} direction
* @return {Anchor|null} - The closest anchor or `null` if no valid anchor found
*/ */
export function findClosestOffscreenAnchor(anchors, direction) { export function findClosestOffscreenAnchor(
anchors: Anchor[],
direction: 'up' | 'down'
): Anchor | null {
let closestAnchor = null; let closestAnchor = null;
let closestTop = 0; let closestTop = 0;
for (let anchor of anchors) { for (const anchor of anchors) {
if (!anchor.highlights?.length) { if (!anchor.highlights?.length) {
continue; continue;
} }
...@@ -98,13 +114,9 @@ export function findClosestOffscreenAnchor(anchors, direction) { ...@@ -98,13 +114,9 @@ export function findClosestOffscreenAnchor(anchors, direction) {
/** /**
* Compute the top and bottom positions for the set of anchors' highlights, sorted * Compute the top and bottom positions for the set of anchors' highlights, sorted
* vertically, from top to bottom. * vertically, from top to bottom.
*
* @param {Anchor[]} anchors
* @return {AnchorPosition[]}
*/ */
export function computeAnchorPositions(anchors) { export function computeAnchorPositions(anchors: Anchor[]): AnchorPosition[] {
/** @type {AnchorPosition[]} */ const positions: AnchorPosition[] = [];
const positions = [];
anchors.forEach(({ annotation, highlights }) => { anchors.forEach(({ annotation, highlights }) => {
if (!highlights?.length) { if (!highlights?.length) {
...@@ -131,31 +143,18 @@ export function computeAnchorPositions(anchors) { ...@@ -131,31 +143,18 @@ export function computeAnchorPositions(anchors) {
return positions; return positions;
} }
/** export function computeBuckets(anchorPositions: AnchorPosition[]): BucketSet {
* Compute buckets const aboveTags = new Set<string>();
* const belowTags = new Set<string>();
* @param {AnchorPosition[]} anchorPositions const buckets: Bucket[] = [];
* @return {BucketSet}
*/
export function computeBuckets(anchorPositions) {
/** @type {Set<string>} */
const aboveTags = new Set();
/** @type {Set<string>} */
const belowTags = new Set();
/** @type {Bucket[]} */
const buckets = [];
// Hold current working anchors and positions as we build each bucket // Hold current working anchors and positions as we build each bucket
/** @type {WorkingBucket|null} */ let currentBucket: WorkingBucket | null = null;
let currentBucket = null;
/** /**
* Create a new working bucket based on the provided `AnchorPosition` * Create a new working bucket based on the provided `AnchorPosition`
*
* @param {AnchorPosition} anchorPosition
* @return {WorkingBucket}
*/ */
function newBucket({ bottom, tag, top }) { function newBucket({ bottom, tag, top }: AnchorPosition): WorkingBucket {
const anchorHeight = bottom - top; const anchorHeight = bottom - top;
const bucketPosition = top + anchorHeight / 2; const bucketPosition = top + anchorHeight / 2;
return { return {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment