Commit 67101824 authored by Kyle Keating's avatar Kyle Keating Committed by Robert Knight

Covert html.coffee to js

parent c9cdea1e
{
RangeAnchor
TextPositionAnchor
TextQuoteAnchor
} = require('./types')
querySelector = (type, root, selector, options) ->
doQuery = (resolve, reject) ->
try
anchor = type.fromSelector(root, selector, options)
range = anchor.toRange(options)
resolve(range)
catch error
reject(error)
return new Promise(doQuery)
###*
# 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 Element root: The root element of the anchoring context.
# :param Array selectors: The selectors to try.
# :param Object options: Options to pass to the anchor implementations.
# :return: A Promise that resolves to a Range on success.
# :rtype: Promise
####
exports.anchor = (root, selectors, options = {}) ->
# Selectors
fragment = null
position = null
quote = null
range = null
# Collect all the selectors
for selector in selectors ? []
switch selector.type
when 'TextPositionSelector'
position = selector
options.hint = position.start # TextQuoteAnchor hint
when 'TextQuoteSelector'
quote = selector
when 'RangeSelector'
range = selector
# Assert the quote matches the stored quote, if applicable
maybeAssertQuote = (range) ->
if quote?.exact? and 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.
promise = Promise.reject('unable to anchor')
if range?
promise = promise.catch ->
return querySelector(RangeAnchor, root, range, options)
.then(maybeAssertQuote)
if position?
promise = promise.catch ->
return querySelector(TextPositionAnchor, root, position, options)
.then(maybeAssertQuote)
if quote?
promise = promise.catch ->
# Note: similarity of the quote is implied.
return querySelector(TextQuoteAnchor, root, quote, options)
return promise
exports.describe = (root, range, options = {}) ->
types = [RangeAnchor, TextPositionAnchor, TextQuoteAnchor]
selectors = for type in types
try
anchor = type.fromRange(root, range, options)
selector = anchor.toSelector(options)
catch
continue
return selectors
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;
}
......@@ -137,7 +137,7 @@ export class TextPositionAnchor {
}
/**
* Converts between TextQuoteSelector selectors and Range objects.
* Converts between `TextQuoteSelector` selectors and `Range` objects.
*/
export class TextQuoteAnchor {
/**
......
......@@ -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,
......
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