Commit 271a8962 authored by Randall Leeds's avatar Randall Leeds

Take options parameter in anchoring methods

Rather than having each of the anchoring implementations have different
call signatures for their methods, use an options argument that varies
in content between the implementations, but probably shares some core
options like the root node.
parent e1b2a3b0
......@@ -228,7 +228,9 @@ module.exports = class Guest extends Annotator
# :rtype: Promise
####
anchorTarget: (target) ->
root = @element[0]
options =
ignoreSelector: '[class^="annotator-"]'
root: @element[0]
# Selectors
fragment = null
......@@ -253,9 +255,9 @@ module.exports = class Guest extends Annotator
if fragment?
promise = promise.catch =>
a = anchor.FragmentAnchor.fromSelector(fragment)
a = anchor.FragmentAnchor.fromSelector(fragment, options)
Promise.resolve(a).then (a) ->
Promise.resolve(a.toRange(root)).then (r) ->
Promise.resolve(a.toRange(options)).then (r) ->
if quote?.exact? and r.toString() != quote.exact
throw new Error('quote mismatch')
else
......@@ -263,9 +265,9 @@ module.exports = class Guest extends Annotator
if range?
promise = promise.catch =>
a = anchor.RangeAnchor.fromSelector(range, root)
a = anchor.RangeAnchor.fromSelector(range, options)
Promise.resolve(a).then (a) ->
Promise.resolve(a.toRange(root)).then (r) ->
Promise.resolve(a.toRange(options)).then (r) ->
if quote?.exact? and r.toString() != quote.exact
throw new Error('quote mismatch')
else
......@@ -273,9 +275,9 @@ module.exports = class Guest extends Annotator
if position?
promise = promise.catch =>
a = anchor.TextPositionAnchor.fromSelector(position)
a = anchor.TextPositionAnchor.fromSelector(position, options)
Promise.resolve(a).then (a) ->
Promise.resolve(a.toRange(root)).then (r) ->
Promise.resolve(a.toRange(options)).then (r) ->
if quote?.exact? and r.toString() != quote.exact
throw new Error('quote mismatch')
else
......@@ -284,9 +286,9 @@ module.exports = class Guest extends Annotator
if quote?
promise = promise.catch =>
# The quote is implicitly checked during range conversion.
a = anchor.TextQuoteAnchor.fromSelector(quote, position)
a = anchor.TextQuoteAnchor.fromSelector(quote, options)
Promise.resolve(a).then (a) ->
Promise.resolve(a.toRange(root))
Promise.resolve(a.toRange(options))
return promise
......@@ -328,17 +330,21 @@ module.exports = class Guest extends Annotator
return Promise.all(targets)
createSelectors: (range) ->
root = @element[0]
toSelector = (anchor) -> anchor.toSelector(root)
softFail = (reason) -> null
notNull = (selectors) -> (s for s in selectors when s?)
options =
ignoreSelector: '[class^="annotator-"]'
root: @element[0]
notNull = (selectors) ->
(s for s in selectors when s?)
selectors = ANCHOR_TYPES.map (type) =>
try
Promise.resolve(type.fromRange(range)).then (a) ->
Promise.resolve(a.toSelector(root))
, softFail
Promise.resolve(type.fromRange(range, options)).then (a) ->
Promise.resolve(a.toSelector(options))
, -> null
catch
Promise.resolve()
return Promise.all(selectors).then(notNull)
onSuccessfulSelection: (event, immediate) ->
......
......@@ -7,7 +7,7 @@ Annotator = require('annotator')
$ = Annotator.$
xpathRange = Annotator.Range
textWalker = require('./text-walker')
seek = require('dom-seek')
# Helper functions for throwing common errors
......@@ -82,7 +82,8 @@ class RangeAnchor extends Anchor
return new RangeAnchor(range)
# Create and anchor using the saved Range selector.
@fromSelector: (selector, root=document.body) ->
@fromSelector: (selector, options = {}) ->
root = options.root or document.body
data = {
start: selector.startContainer
startOffset: selector.startOffset
......@@ -95,7 +96,9 @@ class RangeAnchor extends Anchor
toRange: ->
return @range
toSelector: (root=document.body, ignoreSelector='[class^="annotator-"]') ->
toSelector: (options = {}) ->
root = options.root or document.body
ignoreSelector = options.ignoreSelector
range = new xpathRange.BrowserRange(@range).serialize(root, ignoreSelector)
return {
type: 'RangeSelector'
......@@ -120,7 +123,10 @@ class TextPositionAnchor extends Anchor
unless @start? then missingParameter('start')
unless @end? then missingParameter('end')
@fromRange: (range, root=document.body, filter=null) ->
@fromRange: (range, options = {}) ->
root = options.root or document.body
filter = options.filter or null
range = new xpathRange.BrowserRange(range).normalize(root)
walker = new textWalker.TextWalker(root, filter)
......@@ -135,7 +141,10 @@ class TextPositionAnchor extends Anchor
@fromSelector: (selector) ->
return new TextPositionAnchor(selector.start, selector.end)
toRange: (root=document.body, filter=null) ->
toRange: (options = {}) ->
root = options.root or document.body
filter = options.filter or null
walker = new textWalker.TextWalker(root, filter)
range = document.createRange()
......@@ -171,7 +180,10 @@ class TextQuoteAnchor extends Anchor
constructor: (@quote, @prefix='', @suffix='', @start, @end) ->
unless @quote? then missingParameter('quote')
@fromRange: (range, root=document.body, filter=null) ->
@fromRange: (range, options = {}) ->
root = options.root or document.body
filter = options.filter or null
range = new xpathRange.BrowserRange(range).normalize(root)
walker = new textWalker.TextWalker(root, filter)
......@@ -190,22 +202,22 @@ class TextQuoteAnchor extends Anchor
return new TextQuoteAnchor(exact, prefix, suffix, start, end)
@fromSelector: (selector, position) ->
@fromSelector: (selector, options = {}) ->
{start, end} = options.position ? {}
{exact, prefix, suffix} = selector
{start, end} = position ? {}
return new TextQuoteAnchor(exact, prefix, suffix, start, end)
toRange: (root=document.body) ->
toRange: (options = {}) ->
root = options.root or document.body
corpus = root.textContent
matcher = new DomTextMatcher(-> corpus)
options =
matchDistance: corpus.length * 2
contextMatchDistance: corpus.length * 2
contextMatchThreshold: 0.5
patternMatchThreshold: 0.5
flexContext: true
withFuzzyComparison: true
options.matchDistance ?= corpus.length * 2
options.contextMatchDistance ?= corpus.length * 2
options.contextMatchThreshold ?= 0.5
options.patternMatchThreshold ?= 0.5
options.flexContext ?= true
options.withFuzzyComparison ?= true
if @prefix.length and @suffix.length
result = matcher.searchFuzzyWithContext(
......
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