Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
coopwire-hypothesis
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
孙灵跃 Leon Sun
coopwire-hypothesis
Commits
143d7ba1
Commit
143d7ba1
authored
May 12, 2015
by
Randall Leeds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move anchoring into its own module
parent
484688a7
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
132 additions
and
154 deletions
+132
-154
html.coffee
h/static/scripts/annotator/anchoring/html.coffee
+89
-0
types.coffee
h/static/scripts/annotator/anchoring/types.coffee
+0
-0
guest.coffee
h/static/scripts/annotator/guest.coffee
+43
-154
No files found.
h/static/scripts/annotator/anchoring/html.coffee
0 → 100644
View file @
143d7ba1
{
FragmentAnchor
RangeAnchor
TextPositionAnchor
TextQuoteAnchor
}
=
require
(
'./types'
)
###*
# Anchor a set of selectors.
#
# This function converts a set of selectors into a document range using.
# It encapsulates the core anchoring algorithm, using the selectors alone or
# in combination to establish the best anchor within the document.
#
# :param Array selectors: The selectors to try.
# :return: A Promise that resolves to a Range on success.
# :rtype: Promise
####
exports
.
anchor
=
(
selectors
,
options
)
->
# Selectors
fragment
=
null
position
=
null
quote
=
null
range
=
null
# Collect all the selectors
for
selector
in
selectors
?
[]
switch
selector
.
type
when
'FragmentSelector'
fragment
=
selector
when
'TextPositionSelector'
position
=
selector
when
'TextQuoteSelector'
quote
=
selector
when
'RangeSelector'
range
=
selector
# Until we successfully anchor, we fail.
promise
=
Promise
.
reject
(
'unable to anchor'
)
# Assert the quote matches the stored quote, if applicable
assertQuote
=
(
range
)
->
if
quote
?
.
exact
?
and
range
.
toString
()
!=
quote
.
exact
throw
new
Error
(
'quote mismatch'
)
else
return
range
if
fragment
?
promise
=
promise
.
catch
=>
Promise
.
resolve
(
FragmentAnchor
.
fromSelector
(
fragment
,
options
))
.
then
((
a
)
->
Promise
.
resolve
(
a
.
toRange
(
options
)))
.
then
(
assertQuote
)
if
range
?
promise
=
promise
.
catch
=>
Promise
.
resolve
(
RangeAnchor
.
fromSelector
(
range
,
options
))
.
then
((
a
)
->
Promise
.
resolve
(
a
.
toRange
(
options
)))
.
then
(
assertQuote
)
if
position
?
promise
=
promise
.
catch
=>
Promise
.
resolve
(
TextPositionAnchor
.
fromSelector
(
position
,
options
))
.
then
((
a
)
->
Promise
.
resolve
(
a
.
toRange
(
options
)))
.
then
(
assertQuote
)
if
quote
?
promise
=
promise
.
catch
=>
Promise
.
resolve
(
TextQuoteAnchor
.
fromSelector
(
quote
,
options
))
.
then
((
a
)
->
Promise
.
resolve
(
a
.
toRange
(
options
)))
return
promise
exports
.
describe
=
(
range
,
options
)
->
maybeDescribeWith
=
(
type
)
->
return
Promise
.
resolve
(
type
)
.
then
((
t
)
->
Promise
.
resolve
(
t
.
fromRange
(
range
,
options
)))
.
then
((
a
)
->
Promise
.
resolve
(
a
.
toSelector
(
options
)))
.
catch
(
->
null
)
selectors
=
(
maybeDescribeWith
(
type
)
for
type
in
[
FragmentAnchor
RangeAnchor
TextPositionAnchor
TextQuoteAnchor
])
return
Promise
.
all
(
selectors
)
.
then
((
selectors
)
->
(
s
for
s
in
selectors
when
s
?
))
h/static/scripts/annotator/
lib/anchor
.coffee
→
h/static/scripts/annotator/
anchoring/types
.coffee
View file @
143d7ba1
File moved
h/static/scripts/annotator/guest.coffee
View file @
143d7ba1
...
...
@@ -2,16 +2,9 @@ Promise = global.Promise or require('es6-promise').Promise
Annotator
=
require
(
'annotator'
)
$
=
Annotator
.
$
anchor
=
require
(
'./lib/anchor
'
)
anchor
ing
=
require
(
'./anchoring/html
'
)
highlight
=
require
(
'./lib/highlight'
)
ANCHOR_TYPES
=
[
anchor
.
FragmentAnchor
anchor
.
RangeAnchor
anchor
.
TextPositionAnchor
anchor
.
TextQuoteAnchor
]
module
.
exports
=
class
Guest
extends
Annotator
SHOW_HIGHLIGHTS_CLASS
=
'annotator-highlights-always-on'
...
...
@@ -145,57 +138,61 @@ module.exports = class Guest extends Annotator
this
.
removeEvents
()
setupAnnotation
:
(
annotation
)
->
# Factories to close over the loop variable, below.
succeed
=
(
target
)
->
(
highlights
)
->
{
annotation
,
target
,
highlights
}
{
anchored
,
unanchored
,
plugins
}
=
this
root
=
@
element
[
0
]
ignoreSelector
=
'[class^="annotator-"]'
maybeAnchor
=
(
target
)
->
anchoring
.
anchor
(
target
.
selector
,
{
root
,
ignoreSelector
})
.
then
(
highlightRange
)
.
then
((
highlights
)
->
{
annotation
,
target
,
highlights
})
.
catch
((
reason
)
->
{
annotation
,
target
,
reason
})
fail
=
(
target
)
->
(
reason
)
->
{
annotation
,
target
}
highlightRange
=
(
range
)
->
normedRange
=
Annotator
.
Range
.
sniff
(
range
).
normalize
(
root
)
return
highlight
.
highlightRange
(
normedRange
)
# Function to collect anchoring promises
finish
=
(
results
)
=>
anchored
=
false
storeAndSync
=
(
results
)
->
highlighted
=
false
for
result
in
results
if
result
.
highlights
?
anchor
ed
=
true
@
anchored
.
push
(
result
)
highlight
ed
=
true
anchored
.
push
(
result
)
else
@
unanchored
.
push
(
result
)
if
results
.
length
and
not
anchored
annotation
.
$orphan
=
true
# Sync the results
this
.
plugins
.
CrossFrame
.
sync
([
annotation
])
# Create a TextHighlight for a range.
highlightRange
=
(
range
)
=>
normedRange
=
Annotator
.
Range
.
sniff
(
range
).
normalize
(
@
element
[
0
])
return
highlight
.
highlightRange
(
normedRange
)
unanchored
.
push
(
result
)
# Try to anchor all the targets
anchorTargets
=
(
targets
=
[])
=>
for
target
in
targets
when
target
.
selector
Promise
.
resolve
()
.
then
(
=>
this
.
anchorTarget
(
target
))
.
then
(
highlightRange
)
.
then
(
succeed
(
target
),
fail
(
target
))
annotation
.
$orphan
=
(
results
.
length
and
not
highlighted
)
plugins
.
CrossFrame
.
sync
([
annotation
])
# Start anchoring in the background
Promise
.
all
(
anchorTargets
(
annotation
.
target
)).
then
(
finish
)
targets
=
(
maybeAnchor
(
target
)
for
target
in
annotation
.
target
?
[])
Promise
.
all
(
targets
).
then
(
storeAndSync
)
annotation
createAnnotation
:
(
annotation
=
{})
->
root
=
@
element
[
0
]
ignoreSelector
=
'[class^="annotator-"]'
options
=
{
root
,
ignoreSelector
}
ranges
=
@
selectedRanges
@
selectedRanges
=
null
return
this
.
getDocumentInfo
().
then
(
info
)
=>
annotation
.
uri
=
info
.
uri
this
.
createTargets
(
ranges
).
then
(
targets
)
=>
annotation
.
target
=
targets
this
.
publish
(
'beforeAnnotationCreated'
,
[
annotation
])
return
this
.
setupAnnotation
(
annotation
)
info
=
this
.
getDocumentInfo
()
Promise
.
all
(
ranges
.
map
((
r
)
->
anchoring
.
describe
(
r
,
options
)))
.
then
((
targets
)
->
info
.
then
((
info
)
->
if
info
.
metadata
?
annotation
.
document
=
info
.
metadata
annotation
.
uri
=
source
=
info
.
uri
annotation
.
target
=
({
source
,
selector
}
for
selector
in
targets
)
)
)
.
then
(
=>
this
.
publish
(
'beforeAnnotationCreated'
,
[
annotation
]))
.
then
(
=>
this
.
setupAnnotation
(
annotation
))
annotation
createHighlight
:
->
return
this
.
createAnnotation
({
$highlight
:
true
})
...
...
@@ -212,83 +209,6 @@ module.exports = class Guest extends Annotator
this
.
publish
(
'annotationDeleted'
,
[
annotation
])
annotation
###*
# Anchor a target.
#
# This function converts an annotation target into a document range using
# its selectors. It encapsulates the core anchoring algorithm that uses the
# selectors alone or in combination to establish an anchor within the document.
#
# :root Node target: The root Node of the anchoring context.
# :param Object target: The target to anchor.
# :return: A Promise that resolves to a Range on success.
# :rtype: Promise
####
anchorTarget
:
(
target
)
->
options
=
ignoreSelector
:
'[class^="annotator-"]'
root
:
@
element
[
0
]
# Selectors
fragment
=
null
position
=
null
quote
=
null
range
=
null
# Collect all the selectors
for
selector
in
target
.
selector
?
[]
switch
selector
.
type
when
'FragmentSelector'
fragment
=
selector
when
'TextPositionSelector'
position
=
selector
when
'TextQuoteSelector'
quote
=
selector
when
'RangeSelector'
range
=
selector
# Until we successfully anchor, we fail.
promise
=
Promise
.
reject
(
'unable to anchor'
)
if
fragment
?
promise
=
promise
.
catch
=>
a
=
anchor
.
FragmentAnchor
.
fromSelector
(
fragment
,
options
)
Promise
.
resolve
(
a
).
then
(
a
)
->
Promise
.
resolve
(
a
.
toRange
(
options
)).
then
(
r
)
->
if
quote
?
.
exact
?
and
r
.
toString
()
!=
quote
.
exact
throw
new
Error
(
'quote mismatch'
)
else
return
r
if
range
?
promise
=
promise
.
catch
=>
a
=
anchor
.
RangeAnchor
.
fromSelector
(
range
,
options
)
Promise
.
resolve
(
a
).
then
(
a
)
->
Promise
.
resolve
(
a
.
toRange
(
options
)).
then
(
r
)
->
if
quote
?
.
exact
?
and
r
.
toString
()
!=
quote
.
exact
throw
new
Error
(
'quote mismatch'
)
else
return
r
if
position
?
promise
=
promise
.
catch
=>
a
=
anchor
.
TextPositionAnchor
.
fromSelector
(
position
,
options
)
Promise
.
resolve
(
a
).
then
(
a
)
->
Promise
.
resolve
(
a
.
toRange
(
options
)).
then
(
r
)
->
if
quote
?
.
exact
?
and
r
.
toString
()
!=
quote
.
exact
throw
new
Error
(
'quote mismatch'
)
else
return
r
if
quote
?
promise
=
promise
.
catch
=>
# The quote is implicitly checked during range conversion.
a
=
anchor
.
TextQuoteAnchor
.
fromSelector
(
quote
,
options
)
Promise
.
resolve
(
a
).
then
(
a
)
->
Promise
.
resolve
(
a
.
toRange
(
options
))
return
promise
showAnnotations
:
(
annotations
)
=>
@
crossframe
?
.
notify
method
:
"showAnnotations"
...
...
@@ -311,37 +231,6 @@ module.exports = class Guest extends Annotator
onAnchorMousedown
:
->
createTargets
:
(
ranges
)
->
info
=
this
.
getDocumentInfo
()
if
ranges
?
targets
=
ranges
.
map
(
range
)
=>
this
.
createSelectors
(
range
).
then
(
selectors
)
=>
info
.
then
(
info
)
=>
return
{
source
:
info
.
uri
selector
:
selectors
}
else
targets
=
[
info
.
then
(({
uri
})
->
{
source
:
uri
})]
return
Promise
.
all
(
targets
)
createSelectors
:
(
range
)
->
options
=
ignoreSelector
:
'[class^="annotator-"]'
root
:
@
element
[
0
]
notNull
=
(
selectors
)
->
(
s
for
s
in
selectors
when
s
?
)
selectors
=
for
type
in
ANCHOR_TYPES
promise
=
Promise
.
resolve
(
type
).
then
(
t
)
->
Promise
.
resolve
(
t
.
fromRange
(
range
,
options
)).
then
(
a
)
->
Promise
.
resolve
(
a
.
toSelector
(
options
))
promise
.
catch
(
->
null
)
return
Promise
.
all
(
selectors
).
then
(
notNull
)
onSuccessfulSelection
:
(
event
,
immediate
)
->
unless
event
?
throw
"Called onSuccessfulSelection without an event!"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment