Commit 9dea86d3 authored by Randall Leeds's avatar Randall Leeds

Restore some asynchrony more beautifully

While transforming a selector to a range must occur synchronously,
the individual strategies can be attempted in separate animation
frames.

Also, make this more beautiful.
parent 47395f67
raf = require('raf')
{ {
FragmentAnchor FragmentAnchor
RangeAnchor RangeAnchor
...@@ -5,6 +7,18 @@ ...@@ -5,6 +7,18 @@
TextQuoteAnchor TextQuoteAnchor
} = require('./types') } = require('./types')
querySelector = (type, selector, options) ->
doQuery = (resolve, reject) ->
try
anchor = type.fromSelector(selector, options)
range = anchor.toRange(options)
resolve(range)
catch error
reject(error)
return new Promise(doQuery)
###* ###*
# Anchor a set of selectors. # Anchor a set of selectors.
# #
...@@ -36,41 +50,35 @@ exports.anchor = (selectors, options = {}) -> ...@@ -36,41 +50,35 @@ exports.anchor = (selectors, options = {}) ->
when 'RangeSelector' when 'RangeSelector'
range = selector range = selector
# Until we successfully anchor, we fail.
promise = Promise.reject('unable to anchor')
# Assert the quote matches the stored quote, if applicable # Assert the quote matches the stored quote, if applicable
assertQuote = (range) -> maybeAssertQuote = (range) ->
if quote?.exact? and range.toString() != quote.exact if quote?.exact? and range.toString() != quote.exact
throw new Error('quote mismatch') throw new Error('quote mismatch')
else else
return range return range
# Until we successfully anchor, we fail.
promise = Promise.reject('unable to anchor')
if fragment? if fragment?
promise = promise.catch -> promise = promise.catch ->
anchor = FragmentAnchor.fromSelector(fragment, options) return querySelector(FragmentAnchor, fragment, options)
range = anchor.toRange(options) .then(maybeAssertQuote)
assertQuote(range)
return range
if range? if range?
promise = promise.catch -> promise = promise.catch ->
anchor = RangeAnchor.fromSelector(range, options) return querySelector(RangeAnchor, range, options)
range = anchor.toRange(options) .then(maybeAssertQuote)
assertQuote(range)
return range
if position? if position?
promise = promise.catch -> promise = promise.catch ->
anchor = TextPositionAnchor.fromSelector(position, options) return querySelector(TextPositionAnchor, position, options)
range = anchor.toRange(options) .then(maybeAssertQuote)
assertQuote(range)
return range
if quote? if quote?
promise = promise.catch -> promise = promise.catch ->
anchor = TextQuoteAnchor.fromSelector(quote, options) # Note: similarity of the quote is implied.
return anchor.toRange(options) return querySelector(TextQuoteAnchor, quote, options)
return promise return promise
......
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