Skip to content

Commit

Permalink
Covert html.coffee to js
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyle Keating authored and robertknight committed Oct 8, 2020
1 parent c9cdea1 commit 6710182
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 92 deletions.
89 changes: 0 additions & 89 deletions src/annotator/anchoring/html.coffee

This file was deleted.

107 changes: 107 additions & 0 deletions src/annotator/anchoring/html.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { RangeAnchor, TextPositionAnchor, TextQuoteAnchor } from './types';

/**
* @typedef {import("./types").AnyRangeType} AnyRangeType
* @typedef {import('../../types/api').Selector} Selector
*/

/**
* @param {RangeAnchor|TextPositionAnchor|TextQuoteAnchor} anchor
* @param {Object} [options]
* @param {number} [options.hint]
*/
async function querySelector(anchor, options = {}) {
return anchor.toRange(options);
}

/**
* Anchor a set of selectors.
*
* This function converts a set of selectors into a document range.
* It encapsulates the core anchoring algorithm, using the selectors alone or
* in combination to establish the best anchor within the document.
*
* @param {Node} root - The root element of the anchoring context.
* @param {Selector[]} selectors - The selectors to try.
* @param {Object} [options]
* @param {number} [options.hint]
*/
export function anchor(root, selectors, options = {}) {
let position = null;
let quote = null;
let range = null;

// Collect all the selectors
for (let selector of selectors) {
switch (selector.type) {
case 'TextPositionSelector':
position = selector;
options.hint = position.start; // TextQuoteAnchor hint
break;
case 'TextQuoteSelector':
quote = selector;
break;
case 'RangeSelector':
range = selector;
break;
}
}

/**
* Assert the quote matches the stored quote, if applicable
* @param {Range} range
*/
const maybeAssertQuote = range => {
if (quote?.exact && range.toString() !== quote.exact) {
throw new Error('quote mismatch');
} else {
return range;
}
};

// From a default of failure, we build up catch clauses to try selectors in
// order, from simple to complex.
/** @type {Promise<Range>} */
let promise = Promise.reject('unable to anchor');

if (range) {
promise = promise.catch(() => {
let anchor = RangeAnchor.fromSelector(root, range);
return querySelector(anchor, options).then(maybeAssertQuote);
});
}

if (position) {
promise = promise.catch(() => {
let anchor = TextPositionAnchor.fromSelector(root, position);
return querySelector(anchor, options).then(maybeAssertQuote);
});
}

if (quote) {
promise = promise.catch(() => {
let anchor = TextQuoteAnchor.fromSelector(root, quote);
return querySelector(anchor, options);
});
}

return promise;
}

/**
* @param {Node} root
* @param {Range} range
*/
export function describe(root, range) {
const types = [RangeAnchor, TextPositionAnchor, TextQuoteAnchor];
const result = [];
for (let type of types) {
try {
const anchor = type.fromRange(root, range);
result.push(anchor.toSelector());
} catch (error) {
continue;
}
}
return result;
}
2 changes: 1 addition & 1 deletion src/annotator/anchoring/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export class TextPositionAnchor {
}

/**
* Converts between TextQuoteSelector selectors and Range objects.
* Converts between `TextQuoteSelector` selectors and `Range` objects.
*/
export class TextQuoteAnchor {
/**
Expand Down
2 changes: 0 additions & 2 deletions src/annotator/guest.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import scrollIntoView from 'scroll-into-view';
import Delegator from './delegator';
import { Adder } from './adder';

// @ts-expect-error - Module is CoffeeScript
import * as htmlAnchoring from './anchoring/html';

import { sniff } from './anchoring/range';
import {
getHighlightsContainingNode,
Expand Down

0 comments on commit 6710182

Please sign in to comment.