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