You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@annotator.apache.org by ge...@apache.org on 2022/11/23 21:38:21 UTC

[incubator-annotator] 01/02: Tweak types

This is an automated email from the ASF dual-hosted git repository.

gerben pushed a commit to branch tweak-types
in repository https://gitbox.apache.org/repos/asf/incubator-annotator.git

commit 0ae18a75c97cde61abc37b2932d7e337f8882ea0
Author: Gerben <ge...@treora.com>
AuthorDate: Sun Nov 6 15:15:58 2022 +0100

    Tweak types
    
    Based on experience in Web Annotation Discovery webextension <https://code.treora.com/gerben/web-annotation-discovery-webextension/src/commit/52293bb25d72b1cd4c2ee18ae385acc7bd38f687/src/util/dom-selectors.ts#L133-L150>
---
 packages/dom/src/range/match.ts |  6 +++---
 packages/selector/src/index.ts  | 32 ++++++++++++++++++++++++++------
 packages/selector/src/types.ts  |  6 +++---
 3 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/packages/dom/src/range/match.ts b/packages/dom/src/range/match.ts
index 04222f0..27a1ad6 100644
--- a/packages/dom/src/range/match.ts
+++ b/packages/dom/src/range/match.ts
@@ -95,11 +95,11 @@ import { cartesian } from './cartesian.js';
  *
  * @public
  */
-export function makeCreateRangeSelectorMatcher(
-  createMatcher: <T extends Selector, TMatch extends Node | Range>(
+export function makeCreateRangeSelectorMatcher<T extends Selector>(
+  createMatcher: <TMatch extends Node | Range>(
     selector: T,
   ) => Matcher<Node | Range, TMatch>,
-): (selector: RangeSelector) => Matcher<Node | Range, Range> {
+): (selector: RangeSelector<T>) => Matcher<Node | Range, Range> {
   return function createRangeSelectorMatcher(selector) {
     const startMatcher = createMatcher(selector.startSelector);
     const endMatcher = createMatcher(selector.endSelector);
diff --git a/packages/selector/src/index.ts b/packages/selector/src/index.ts
index 48183a6..f75f6e1 100644
--- a/packages/selector/src/index.ts
+++ b/packages/selector/src/index.ts
@@ -32,6 +32,28 @@ export type {
 } from './types.js';
 export * from './text/index.js';
 
+/**
+ * A Refinable selector can have the `refinedBy` attribute, whose value must be
+ * of the same type (possibly again refined, recursively).
+ *
+ * See {@link https://www.w3.org/TR/2017/REC-annotation-model-20170223/#refinement-of-selection
+ * | §4.2.9 Refinement of Selection} in the Web Annotation Data Model.
+ *
+ * @example
+ * Example value of type `Refinable<CssSelector, TextQuoteSelector>`:
+ *
+ *     {
+ *       type: "CssSelector",
+ *       …,
+ *       refinedBy: {
+ *         type: "TextQuoteSelector",
+ *         …,
+ *         refinedBy: { … }, // again either a CssSelector or TextQuoteSelector
+ *       }
+ *     }
+ */
+export type Refinable<T extends Selector> = T & { refinedBy?: Refinable<T> };
+
 /**
  * Wrap a matcher creation function so that it supports refinement of selection.
  *
@@ -45,18 +67,16 @@ export * from './text/index.js';
  * @public
  */
 export function makeRefinable<
-  // Any subtype of Selector can be made refinable; but note we limit the value
-  // of refinedBy because it must also be accepted by matcherCreator.
-  TSelector extends Selector & { refinedBy?: TSelector },
+  TSelector extends Selector,
   TScope,
   // To enable refinement, the implementation’s Match object must be usable as a
   // Scope object itself.
   TMatch extends TScope
 >(
-  matcherCreator: (selector: TSelector) => Matcher<TScope, TMatch>,
-): (selector: TSelector) => Matcher<TScope, TMatch> {
+  matcherCreator: (selector: Refinable<TSelector>) => Matcher<TScope, TMatch>,
+): (selector: Refinable<TSelector>) => Matcher<TScope, TMatch> {
   return function createMatcherWithRefinement(
-    sourceSelector: TSelector,
+    sourceSelector: Refinable<TSelector>,
   ): Matcher<TScope, TMatch> {
     const matcher = matcherCreator(sourceSelector);
 
diff --git a/packages/selector/src/types.ts b/packages/selector/src/types.ts
index d3c227b..a93d168 100644
--- a/packages/selector/src/types.ts
+++ b/packages/selector/src/types.ts
@@ -91,10 +91,10 @@ export interface TextPositionSelector extends Selector {
  *
  * @public
  */
-export interface RangeSelector extends Selector {
+export interface RangeSelector<T extends Selector = Selector> extends Selector {
   type: 'RangeSelector';
-  startSelector: Selector;
-  endSelector: Selector;
+  startSelector: T;
+  endSelector: T;
 }
 
 /**