Commit 880dbd63 authored by Randall Leeds's avatar Randall Leeds

Split host / sidebar and clean up plugin loading

parent d997c071
......@@ -5,8 +5,6 @@ raf = require('raf')
scrollIntoView = require('scroll-into-view')
Annotator = require('annotator')
Annotator.Plugin.BucketBar = BucketBar = require('./plugin/bucket-bar')
Annotator.Plugin.CrossFrame = CrossFrame = require('./plugin/cross-frame')
$ = Annotator.$
highlighter = require('./highlighter')
......@@ -33,11 +31,9 @@ module.exports = class Guest extends Annotator
".annotator-hl mouseover": "onHighlightMouseover"
".annotator-hl mouseout": "onHighlightMouseout"
# Plugin / Options configuration
options:
TextHighlights: {}
Document: {}
TextSelection: {}
clickToClose: true
# Anchoring module
anchoring: require('./anchoring/html')
......@@ -131,24 +127,20 @@ module.exports = class Guest extends Annotator
_setupWrapper: ->
@wrapper = @element
if @options.clickToClose
@wrapper.on 'click', (event) =>
if !@selectedTargets?.length
this.hideFrame()
return this
this
# These methods aren't used in the iframe-hosted configuration of Annotator.
_setupDynamicStyle: -> this
_setupViewer: -> this
_setupEditor: -> this
_setupDocumentEvents: -> this
_setupDynamicStyle: -> this
destroy: ->
$('#annotator-dynamic-style').remove()
@adder.remove()
@wrapper.find('.annotator-hl').each ->
@element.find('.annotator-hl').each ->
$(this).contents().insertBefore(this)
$(this).remove()
......@@ -331,7 +323,7 @@ module.exports = class Guest extends Annotator
else
# Show the adder button
@adder
.css(Annotator.Util.mousePosition(event, @wrapper[0]))
.css(Annotator.Util.mousePosition(event, @element[0]))
.show()
true
......@@ -388,14 +380,6 @@ module.exports = class Guest extends Annotator
@visibleHighlights = shouldShowHighlights
# Open the sidebar
showFrame: ->
@crossframe?.call('open')
# Close the sidebar
hideFrame: ->
@crossframe?.call('back')
onAdderMouseup: (event) ->
event.preventDefault()
event.stopPropagation()
......@@ -412,5 +396,4 @@ module.exports = class Guest extends Annotator
this.createHighlight()
when 'comment'
this.createAnnotation()
this.showFrame()
Annotator.Util.getGlobal().getSelection().removeAllRanges()
raf = require('raf')
Annotator = require('annotator')
$ = Annotator.$
Hammer = require('hammerjs')
Guest = require('./guest')
# Minimum width to which the frame can be resized.
MIN_RESIZE = 280
module.exports = class Host extends Guest
renderFrame: null
gestureState: null
constructor: (element, options) ->
src = options.app
if options.firstRun
# Allow options.app to contain query string params.
src = src + (if '?' in src then '&' else '?') + 'firstrun'
options.app += (if '?' in options.app then '&' else '?') + 'firstrun'
# Create the iframe
app = $('<iframe></iframe>')
.attr('name', 'hyp_sidebar_frame')
.attr('seamless', '')
.attr('src', src)
.attr('src', options.app)
@frame = $('<div></div>')
.css('display', 'none')
.addClass('annotator-frame annotator-outer annotator-collapsed')
.addClass('annotator-frame annotator-outer')
.appendTo(element)
super
this._addCrossFrameListeners()
app.appendTo(@frame)
if options.firstRun
this.on 'panelReady', => this.showFrame(transition: false)
# Host frame dictates the toolbar options.
this.on 'panelReady', =>
# Initialize tool state.
this.setVisibleHighlights(!!options.showHighlights)
# Time to actually show the UI
# Show the UI
@frame.css('display', '')
if @plugins.BucketBar?
this._setupGestures()
@plugins.BucketBar.element.on 'click', (event) =>
if @frame.hasClass 'annotator-collapsed'
this.showFrame()
destroy: ->
@frame.remove()
super
showFrame: (options={transition: true}) ->
if options.transition
@frame.removeClass 'annotator-no-transition'
else
@frame.addClass 'annotator-no-transition'
@frame.css 'margin-left': "#{-1 * @frame.width()}px"
@frame.removeClass 'annotator-collapsed'
if @toolbar?
@toolbar.find('[name=sidebar-toggle]')
.removeClass('h-icon-chevron-left')
.addClass('h-icon-chevron-right')
hideFrame: ->
@frame.css 'margin-left': ''
@frame.removeClass 'annotator-no-transition'
@frame.addClass 'annotator-collapsed'
if @toolbar?
@toolbar.find('[name=sidebar-toggle]')
.removeClass('h-icon-chevron-right')
.addClass('h-icon-chevron-left')
_addCrossFrameListeners: ->
@crossframe.on('showFrame', this.showFrame.bind(this, null))
@crossframe.on('hideFrame', this.hideFrame.bind(this, null))
_initializeGestureState: ->
@gestureState =
initial: null
final: null
onPan: (event) =>
switch event.type
when 'panstart'
# Initialize the gesture state
this._initializeGestureState()
# Immadiate response
@frame.addClass 'annotator-no-transition'
# Escape iframe capture
@frame.css('pointer-events', 'none')
# Set origin margin
@gestureState.initial = parseInt(getComputedStyle(@frame[0]).marginLeft)
when 'panend'
# Re-enable transitions
@frame.removeClass 'annotator-no-transition'
# Re-enable iframe events
@frame.css('pointer-events', '')
# Snap open or closed
if @gestureState.final <= -MIN_RESIZE
this.showFrame()
else
this.hideFrame()
# Reset the gesture state
this._initializeGestureState()
when 'panleft', 'panright'
return unless @gestureState.initial?
# Compute new margin from delta and initial conditions
m = @gestureState.initial
d = event.deltaX
@gestureState.final = Math.min(Math.round(m + d), 0)
# Start updating
this._updateLayout()
onSwipe: (event) =>
switch event.type
when 'swipeleft'
this.showFrame()
when 'swiperight'
this.hideFrame()
_setupGestures: ->
$toggle = @toolbar.find('[name=sidebar-toggle]')
# Prevent any default gestures on the handle
$toggle.on('touchmove', (event) -> event.preventDefault())
# Set up the Hammer instance and handlers
mgr = new Hammer.Manager($toggle[0])
.on('panstart panend panleft panright', this.onPan)
.on('swipeleft swiperight', this.onSwipe)
# Set up the gesture recognition
pan = mgr.add(new Hammer.Pan({direction: Hammer.DIRECTION_HORIZONTAL}))
swipe = mgr.add(new Hammer.Swipe({direction: Hammer.DIRECTION_HORIZONTAL}))
swipe.recognizeWith(pan)
# Set up the initial state
this._initializeGestureState()
# Return this for chaining
this
# Schedule any changes needed to update the layout of the widget or page
# in response to interface changes.
_updateLayout: ->
# Only schedule one frame at a time
return if @renderFrame
# Schedule a frame
@renderFrame = raf =>
@renderFrame = null # Clear the schedule
# Process the resize gesture
if @gestureState.final isnt @gestureState.initial
m = @gestureState.final
w = -m
@frame.css('margin-left', "#{m}px")
if w >= MIN_RESIZE then @frame.css('width', "#{w}px")
......@@ -10,39 +10,31 @@ if (g.wgxpath) {
// Applications
Annotator.Guest = require('./guest');
Annotator.Host = require('./host');
Annotator.Sidebar = require('./sidebar');
Annotator.PdfSidebar = require('./pdf-sidebar');
// UI plugins
Annotator.Plugin.BucketBar = require('./plugin/bucket-bar');
Annotator.Plugin.Toolbar = require('./plugin/toolbar');
// Document type plugins
Annotator.Plugin.Pdf = require('./plugin/pdf');
require('../vendor/annotator.document'); // Does not export the plugin :(
// Selection plugins
Annotator.Plugin.TextSelection = require('./plugin/textselection');
// Cross-frame communication
Annotator.Plugin.CrossFrame = require('./plugin/cross-frame');
Annotator.Plugin.CrossFrame.Bridge = require('../bridge');
Annotator.Plugin.CrossFrame.AnnotationSync = require('../annotation-sync');
Annotator.Plugin.CrossFrame.Bridge = require('../bridge');
Annotator.Plugin.CrossFrame.Discovery = require('../discovery');
// Bucket bar
require('./plugin/bucket-bar');
// Toolbar
require('./plugin/toolbar');
// Creating selections
require('./plugin/textselection');
var docs = 'https://h.readthedocs.org/en/latest/hacking/customized-embedding.html';
var options = {
app: jQuery('link[type="application/annotator+html"]').attr('href'),
BucketBar: {container: '.annotator-frame', scrollables: ['body']},
Toolbar: {container: '.annotator-frame'}
app: jQuery('link[type="application/annotator+html"]').attr('href')
};
// Document metadata plugins
if (window.PDFViewerApplication) {
require('./plugin/pdf');
options.BucketBar.scrollables = ['#viewerContainer'];
options.PDF = {};
} else {
require('../vendor/annotator.document');
options.Document = {};
}
if (window.hasOwnProperty('hypothesisConfig')) {
if (typeof window.hypothesisConfig === 'function') {
extend(options, window.hypothesisConfig());
......@@ -53,7 +45,9 @@ if (window.hasOwnProperty('hypothesisConfig')) {
Annotator.noConflict().$.noConflict(true)(function() {
'use strict';
var Klass = Annotator.Host;
var Klass = window.PDFViewerApplication ?
Annotator.PdfSidebar :
Annotator.Sidebar;
if (options.hasOwnProperty('constructor')) {
Klass = options.constructor;
delete options.constructor;
......
Sidebar = require('./sidebar')
module.exports = class PdfSidebar extends Sidebar
options:
TextSelection: {}
Pdf: {}
BucketBar:
container: '.annotator-frame'
scrollables: ['#viewerContainer']
Toolbar:
container: '.annotator-frame'
......@@ -42,7 +42,7 @@ scrollToClosest = (anchors, direction) ->
scrollIntoView(next.highlights[0])
class BucketBar extends Annotator.Plugin
module.exports = class BucketBar extends Annotator.Plugin
# svg skeleton
html: """
<div class="annotator-bucket-bar">
......@@ -57,7 +57,7 @@ class BucketBar extends Annotator.Plugin
gapSize: 60
# Selectors for the scrollable elements on the page
scrollables: null
scrollables: ['body']
# buckets of annotations that overlap
buckets: []
......@@ -293,6 +293,3 @@ class BucketBar extends Annotator.Plugin
BucketBar.BUCKET_SIZE = BUCKET_SIZE
BucketBar.BUCKET_NAV_SIZE = BUCKET_NAV_SIZE
BucketBar.BUCKET_TOP_THRESHOLD = BUCKET_TOP_THRESHOLD
# Export as a module
module.exports = BucketBar
......@@ -2,7 +2,7 @@ extend = require('extend')
Annotator = require('annotator')
class PDF extends Annotator.Plugin
module.exports = class Pdf extends Annotator.Plugin
documentLoaded: null
observer: null
pdfViewer: null
......@@ -105,7 +105,3 @@ class PDF extends Annotator.Plugin
for annotation in refreshAnnotations
annotator.anchor(annotation)
Annotator.Plugin.PDF = PDF
module.exports = PDF
......@@ -3,7 +3,7 @@ $ = Annotator.$
# This plugin implements the UI code for creating text annotations
class Annotator.Plugin.TextSelection extends Annotator.Plugin
module.exports = class TextSelection extends Annotator.Plugin
pluginInit: ->
# Register the event handlers required for creating a selection
......
Annotator = require('annotator')
$ = Annotator.$
makeButton = (item) ->
......@@ -10,7 +11,7 @@ makeButton = (item) ->
button = $('<li></li>').append(anchor)
return button[0]
class Annotator.Plugin.Toolbar extends Annotator.Plugin
module.exports = class Toolbar extends Annotator.Plugin
HIDE_CLASS = 'annotator-hide'
events:
......@@ -35,9 +36,9 @@ class Annotator.Plugin.Toolbar extends Annotator.Plugin
event.stopPropagation()
collapsed = @annotator.frame.hasClass('annotator-collapsed')
if collapsed
@annotator.showFrame()
@annotator.show()
else
@annotator.hideFrame()
@annotator.hide()
,
"title": "Hide Highlights"
"class": "h-icon-visibility"
......@@ -57,7 +58,7 @@ class Annotator.Plugin.Toolbar extends Annotator.Plugin
event.preventDefault()
event.stopPropagation()
@annotator.createAnnotation()
@annotator.showFrame()
@annotator.show()
]
@buttons = $(makeButton(item) for item in items)
......
extend = require('extend')
raf = require('raf')
Hammer = require('hammerjs')
Host = require('./host')
# Minimum width to which the frame can be resized.
MIN_RESIZE = 280
module.exports = class Sidebar extends Host
options:
Document: {}
TextSelection: {}
BucketBar:
container: '.annotator-frame'
Toolbar:
container: '.annotator-frame'
renderFrame: null
gestureState: null
constructor: (element, options) ->
super
this.hide()
if options.firstRun
this.on 'panelReady', => this.show()
if @plugins.BucketBar?
@plugins.BucketBar.element.on 'click', (event) => this.show()
if @plugins.Toolbar?
this._setupGestures()
this._setupSidebarEvents()
_setupDocumentEvents: ->
@element.on 'click', (event) =>
if !@selectedTargets?.length
this.hide()
return this
_setupSidebarEvents: ->
@crossframe.on('show', this.show.bind(this))
@crossframe.on('hide', this.hide.bind(this))
# Return this for chaining
this
_setupGestures: ->
$toggle = @toolbar.find('[name=sidebar-toggle]')
# Prevent any default gestures on the handle
$toggle.on('touchmove', (event) -> event.preventDefault())
# Set up the Hammer instance and handlers
mgr = new Hammer.Manager($toggle[0])
.on('panstart panend panleft panright', this.onPan)
.on('swipeleft swiperight', this.onSwipe)
# Set up the gesture recognition
pan = mgr.add(new Hammer.Pan({direction: Hammer.DIRECTION_HORIZONTAL}))
swipe = mgr.add(new Hammer.Swipe({direction: Hammer.DIRECTION_HORIZONTAL}))
swipe.recognizeWith(pan)
# Set up the initial state
this._initializeGestureState()
# Return this for chaining
this
_initializeGestureState: ->
@gestureState =
initial: null
final: null
# Schedule any changes needed to update the sidebar layout.
_updateLayout: ->
# Only schedule one frame at a time
return if @renderFrame
# Schedule a frame
@renderFrame = raf =>
@renderFrame = null # Clear the schedule
# Process the resize gesture
if @gestureState.final isnt @gestureState.initial
m = @gestureState.final
w = -m
@frame.css('margin-left', "#{m}px")
if w >= MIN_RESIZE then @frame.css('width', "#{w}px")
onPan: (event) =>
switch event.type
when 'panstart'
# Initialize the gesture state
this._initializeGestureState()
# Immadiate response
@frame.addClass 'annotator-no-transition'
# Escape iframe capture
@frame.css('pointer-events', 'none')
# Set origin margin
@gestureState.initial = parseInt(getComputedStyle(@frame[0]).marginLeft)
when 'panend'
# Re-enable transitions
@frame.removeClass 'annotator-no-transition'
# Re-enable iframe events
@frame.css('pointer-events', '')
# Snap open or closed
if @gestureState.final <= -MIN_RESIZE
this.show()
else
this.hide()
# Reset the gesture state
this._initializeGestureState()
when 'panleft', 'panright'
return unless @gestureState.initial?
# Compute new margin from delta and initial conditions
m = @gestureState.initial
d = event.deltaX
@gestureState.final = Math.min(Math.round(m + d), 0)
# Start updating
this._updateLayout()
onSwipe: (event) =>
switch event.type
when 'swipeleft'
this.show()
when 'swiperight'
this.hide()
show: ->
@frame.css 'margin-left': "#{-1 * @frame.width()}px"
@frame.removeClass 'annotator-collapsed'
if @toolbar?
@toolbar.find('[name=sidebar-toggle]')
.removeClass('h-icon-chevron-left')
.addClass('h-icon-chevron-right')
hide: ->
@frame.css 'margin-left': ''
@frame.addClass 'annotator-collapsed'
if @toolbar?
@toolbar.find('[name=sidebar-toggle]')
.removeClass('h-icon-chevron-right')
.addClass('h-icon-chevron-left')
createAnnotation: (annotation = {}) ->
super
this.show() unless annotation.$highlight
showAnnotations: (annotations) ->
super
this.show()
Annotator = require('annotator')
$ = Annotator.$
highlighter = {}
anchoring = {}
CrossFrame = sinon.stub()
CrossFrame['@noCallThru'] = true
raf = sinon.stub().yields()
raf['@noCallThru'] = true
......@@ -14,15 +14,14 @@ proxyquire = require('proxyquire')
Guest = proxyquire('../guest', {
'./highlighter': highlighter,
'./anchoring/html': anchoring,
'./plugin/cross-frame': CrossFrame,
'raf': raf
'annotator': Annotator,
'raf': raf,
'scroll-into-view': scrollIntoView,
})
$ = require('jquery')
describe 'Guest', ->
sandbox = null
sandbox = sinon.sandbox.create()
CrossFrame = null
fakeCrossFrame = null
createGuest = (options) ->
......@@ -30,18 +29,19 @@ describe 'Guest', ->
return new Guest(element, options || {})
beforeEach ->
sandbox = sinon.sandbox.create()
fakeCrossFrame = {
onConnect: sinon.stub()
on: sinon.stub()
sync: sinon.stub()
}
CrossFrame.reset()
CrossFrame = sandbox.stub()
CrossFrame.returns(fakeCrossFrame)
Annotator.Plugin.CrossFrame = CrossFrame
afterEach ->
sandbox.restore()
delete Annotator.Plugin.CrossFrame
describe 'cross frame', ->
......
raf = sinon.stub().yields()
raf['@noCallThru'] = true
CrossFrame = sinon.stub()
CrossFrame['@noCallThru'] = true
Annotator = require('annotator')
proxyquire = require('proxyquire')
Host = proxyquire('../host', {
'./plugin/cross-frame': CrossFrame,
'raf': raf
'annotator': Annotator,
})
describe 'Host', ->
sandbox = sinon.sandbox.create()
CrossFrame = null
fakeCrossFrame = null
createHost = (options={}) ->
......@@ -27,10 +23,13 @@ describe 'Host', ->
fakeCrossFrame.on = sandbox.stub().returns(fakeCrossFrame)
fakeCrossFrame.call = sandbox.spy()
CrossFrame.reset()
CrossFrame = sandbox.stub()
CrossFrame.returns(fakeCrossFrame)
Annotator.Plugin.CrossFrame = CrossFrame
afterEach -> sandbox.restore()
afterEach ->
sandbox.restore()
delete Annotator.Plugin.CrossFrame
describe 'widget visibility', ->
it 'starts hidden', ->
......@@ -56,84 +55,3 @@ describe 'Host', ->
assert.isFalse(host.visibleHighlights)
done()
host.publish('panelReady')
describe 'crossframe listeners', ->
emitHostEvent = (event, args...) ->
fn(args...) for [evt, fn] in fakeCrossFrame.on.args when event == evt
describe 'on "showFrame" event', ->
it 'shows the frame', ->
target = sandbox.stub(Host.prototype, 'showFrame')
host = createHost()
emitHostEvent('showFrame')
assert.called(target)
describe 'on "hideFrame" event', ->
it 'hides the frame', ->
target = sandbox.stub(Host.prototype, 'hideFrame')
host = createHost()
emitHostEvent('hideFrame')
assert.called(target)
describe 'pan gestures', ->
host = null
beforeEach ->
host = createHost({})
describe 'panstart event', ->
beforeEach ->
sandbox.stub(window, 'getComputedStyle').returns({marginLeft: '100px'})
host.onPan({type: 'panstart'})
it 'disables pointer events and transitions on the widget', ->
assert.isTrue(host.frame.hasClass('annotator-no-transition'))
assert.equal(host.frame.css('pointer-events'), 'none')
it 'captures the left margin as the gesture initial state', ->
assert.equal(host.gestureState.initial, '100')
describe 'panend event', ->
it 'enables pointer events and transitions on the widget', ->
host.gestureState = {final: 0}
host.onPan({type: 'panend'})
assert.isFalse(host.frame.hasClass('annotator-no-transition'))
assert.equal(host.frame.css('pointer-events'), '')
it 'calls `showFrame` if the widget is fully visible', ->
host.gestureState = {final: -500}
showFrame = sandbox.stub(host, 'showFrame')
host.onPan({type: 'panend'})
assert.calledOnce(showFrame)
it 'calls `hideFrame` if the widget is not fully visible', ->
host.gestureState = {final: -100}
hideFrame = sandbox.stub(host, 'hideFrame')
host.onPan({type: 'panend'})
assert.calledOnce(hideFrame)
describe 'panleft and panright events', ->
it 'shrinks or grows the widget to match the delta', ->
host.gestureState = {initial: -100}
host.onPan({type: 'panleft', deltaX: -50})
assert.equal(host.gestureState.final, -150)
host.onPan({type: 'panright', deltaX: 100})
assert.equal(host.gestureState.final, 0)
describe 'swipe gestures', ->
host = null
beforeEach ->
host = createHost({})
it 'opens the sidebar on swipeleft', ->
showFrame = sandbox.stub(host, 'showFrame')
host.onSwipe({type: 'swipeleft'})
assert.calledOnce(showFrame)
it 'closes the sidebar on swiperight', ->
hideFrame = sandbox.stub(host, 'hideFrame')
host.onSwipe({type: 'swiperight'})
assert.calledOnce(hideFrame)
Annotator = require('annotator')
proxyquire = require('proxyquire')
Sidebar = proxyquire('../sidebar', {
'annotator': Annotator,
})
describe 'Sidebar', ->
sandbox = sinon.sandbox.create()
CrossFrame = null
fakeCrossFrame = null
createSidebar = (options={}) ->
element = document.createElement('div')
return new Sidebar(element, options)
beforeEach ->
fakeCrossFrame = {}
fakeCrossFrame.onConnect = sandbox.stub().returns(fakeCrossFrame)
fakeCrossFrame.on = sandbox.stub().returns(fakeCrossFrame)
fakeCrossFrame.call = sandbox.spy()
CrossFrame = sandbox.stub()
CrossFrame.returns(fakeCrossFrame)
Annotator.Plugin.CrossFrame = CrossFrame
afterEach ->
sandbox.restore()
delete Annotator.Plugin.CrossFrame
describe 'crossframe listeners', ->
emitEvent = (event, args...) ->
fn(args...) for [evt, fn] in fakeCrossFrame.on.args when event == evt
describe 'on "show" event', ->
it 'shows the frame', ->
target = sandbox.stub(Sidebar.prototype, 'show')
sidebar = createSidebar()
emitEvent('show')
assert.called(target)
describe 'on "hide" event', ->
it 'hides the frame', ->
target = sandbox.stub(Sidebar.prototype, 'hide')
sidebar = createSidebar()
emitEvent('hide')
assert.called(target)
describe 'pan gestures', ->
sidebar = null
beforeEach ->
sidebar = createSidebar({})
describe 'panstart event', ->
beforeEach ->
sandbox.stub(window, 'getComputedStyle').returns({marginLeft: '100px'})
sidebar.onPan({type: 'panstart'})
it 'disables pointer events and transitions on the widget', ->
assert.isTrue(sidebar.frame.hasClass('annotator-no-transition'))
assert.equal(sidebar.frame.css('pointer-events'), 'none')
it 'captures the left margin as the gesture initial state', ->
assert.equal(sidebar.gestureState.initial, '100')
describe 'panend event', ->
it 'enables pointer events and transitions on the widget', ->
sidebar.gestureState = {final: 0}
sidebar.onPan({type: 'panend'})
assert.isFalse(sidebar.frame.hasClass('annotator-no-transition'))
assert.equal(sidebar.frame.css('pointer-events'), '')
it 'calls `show` if the widget is fully visible', ->
sidebar.gestureState = {final: -500}
show = sandbox.stub(sidebar, 'show')
sidebar.onPan({type: 'panend'})
assert.calledOnce(show)
it 'calls `hide` if the widget is not fully visible', ->
sidebar.gestureState = {final: -100}
hide = sandbox.stub(sidebar, 'hide')
sidebar.onPan({type: 'panend'})
assert.calledOnce(hide)
describe 'panleft and panright events', ->
it 'shrinks or grows the widget to match the delta', ->
sidebar.gestureState = {initial: -100}
sidebar.onPan({type: 'panleft', deltaX: -50})
assert.equal(sidebar.gestureState.final, -150)
sidebar.onPan({type: 'panright', deltaX: 100})
assert.equal(sidebar.gestureState.final, 0)
describe 'swipe gestures', ->
sidebar = null
beforeEach ->
sidebar = createSidebar({})
it 'opens the sidebar on swipeleft', ->
show = sandbox.stub(sidebar, 'show')
sidebar.onSwipe({type: 'swipeleft'})
assert.calledOnce(show)
it 'closes the sidebar on swiperight', ->
hide = sandbox.stub(sidebar, 'hide')
sidebar.onSwipe({type: 'swiperight'})
assert.calledOnce(hide)
......@@ -11,8 +11,8 @@ module.exports = [
'$window', 'bridge'
($window, bridge) ->
host =
showSidebar: -> callHost('showFrame')
hideSidebar: -> callHost('hideFrame')
showSidebar: -> callHost('show')
hideSidebar: -> callHost('hide')
# Sends a message to the host frame
callHost = (method) ->
......
......@@ -53,14 +53,14 @@ describe 'host', ->
describe 'showSidebar()', ->
it 'sends the "showFrame" message to the host only', ->
host.showSidebar()
assert.calledWith(fakeBridge.links[0].channel.call, 'showFrame')
assert.calledWith(fakeBridge.links[0].channel.call, 'show')
assert.notCalled(fakeBridge.links[1].channel.call)
assert.notCalled(fakeBridge.links[2].channel.call)
describe 'hideSidebar()', ->
it 'sends the "hideFrame" message to the host only', ->
host.hideSidebar()
assert.calledWith(fakeBridge.links[0].channel.call, 'hideFrame')
assert.calledWith(fakeBridge.links[0].channel.call, 'hide')
assert.notCalled(fakeBridge.links[1].channel.call)
assert.notCalled(fakeBridge.links[2].channel.call)
......
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