Refactored the coffeescript behavior so it is a bit more testable.

This commit is contained in:
Arthur Barrett
2013-02-04 18:25:09 -05:00
parent 0ca7131974
commit 435fd05ef4
3 changed files with 70 additions and 25 deletions

View File

@@ -60,4 +60,8 @@ span.annotatable {
right: 8px;
margin-top: 4px;
}
&.opaque {
opacity: 0.4;
}
}

View File

@@ -1,29 +1,72 @@
class @Annotatable
@_debug: true
wrapperSelector: '.annotatable-wrapper'
spanSelector: 'span.annotatable[data-span-id]'
discussionSelector: '.annotatable-discussion[data-discussion-id]'
constructor: (el) ->
console.log 'loaded Annotatable' if @_debug
@el = el
@spandata = $('.annotatable-wrapper', @el).data "spans"
@initSpans()
@init()
initSpans: () ->
selector = 'span.annotatable[data-span-id]'
$(@el).find(selector).on 'click', (e) =>
@onClickSpan.call this, e
init: () ->
@loadSpanData()
@initEvents()
onClickSpan: (e) ->
span_id = e.target.getAttribute('data-span-id')
discussion_id = @spandata[span_id]
selector = '.annotatable-discussion[data-discussion-id="'+discussion_id+'"]';
$discussion = $(selector, @el)
padding = 20
top = $discussion.offset().top - padding
highlighted = false
complete = () ->
if !highlighted
$discussion.effect('highlight', {}, 1000)
highlighted = true
initEvents: () ->
$(@wrapperSelector, @el).delegate(@spanSelector, {
'click': @_bind @onSpanEvent @onClickSpan
'mouseenter': @_bind @onSpanEvent @onEnterSpan
'mouseleave': @_bind @onSpanEvent @onLeaveSpan
})
$('html, body').animate({
scrollTop: top,
}, 1000, 'swing', complete)
loadSpanData: () ->
@spandata = $(@wrapperSelector, @el).data('spans')
getDiscussionId: (span_id) ->
@spandata[span_id]
getDiscussionEl: (discussion_id) ->
$(@discussionSelector, @el).filter('[data-discussion-id="'+discussion_id+'"]')
onSpanEvent: (fn) ->
(e) =>
span_id = e.target.getAttribute('data-span-id')
discussion_id = @getDiscussionId(span_id)
span = {
id: span_id,
el: e.target
}
discussion = {
id: discussion_id,
el: @getDiscussionEl(discussion_id)
}
fn.call this, span, discussion
onClickSpan: (span, discussion) ->
@scrollToDiscussion(discussion.el)
onEnterSpan: (span, discussion) ->
$(@discussionSelector, @el).not(discussion.el).toggleClass('opaque', true)
onLeaveSpan: (span, discussion) ->
$(@discussionSelector, @el).not(discussion.el).toggleClass('opaque', false)
scrollToDiscussion: (el) ->
complete = @makeHighlighter(el)
top = el.offset().top - 20 # with some padding
$('html, body').animate({ scrollTop: top }, 750, 'swing', complete)
makeHighlighter: (el) ->
return @_once -> el.effect('highlight', {}, 750)
_once: (fn) ->
done = false
return =>
fn.call this unless done
done = true
_bind: (fn) ->
return => fn.apply(this, arguments)

View File

@@ -1,4 +1,4 @@
<div class="annotatable-wrapper" id="${element_id}">
<div class="annotatable-wrapper" id="${element_id}-wrapper">
<div class="annotatable-header">
<div class="help-icon"></div>
@@ -14,9 +14,7 @@
<script>
$(function() {
// TODO pass spans to module directly
var el = $('#${element_id}.annotatable-wrapper');
el.data('spans', ${json_discussion_for});
$('#${element_id}-wrapper').data('spans', ${json_discussion_for});
});
</script>