Commit c817fa70 authored by csillag's avatar csillag

Simplify the bridge service

 - Remove unused support for options
 - Simplify the handling of scope
 - Make it a simpleton, and register the class as the constructor function.

Also updated all tests.

Kudos to @tilgovi for the feedback and ideas.
parent 719f2284
......@@ -20,8 +20,7 @@ CrossFrame = class Annotator.Plugin.CrossFrame extends Annotator.Plugin
opts = extract(options, 'server')
discovery = new CrossFrame.Discovery(window, opts)
opts = extract(options, 'scope')
bridge = new CrossFrame.Bridge(opts)
bridge = new CrossFrame.Bridge()
opts = extract(options, 'on', 'emit', 'formatter', 'parser')
annotationSync = new CrossFrame.AnnotationSync(bridge, opts)
......
......@@ -51,10 +51,6 @@ describe 'Annotator.Plugin.CrossFrame', ->
createCrossFrame()
assert.calledWith(cf.CrossFrame.Discovery)
it 'passes the options along to the bridge', ->
createCrossFrame(scope: 'myscope')
assert.calledWith(cf.CrossFrame.Bridge, scope: 'myscope')
it 'instantiates the AnnotationSync component', ->
createCrossFrame()
assert.called(cf.CrossFrame.AnnotationSync)
......
$ = require('jquery')
Channel = require('jschannel')
# The Bridge service sets up a channel between frames
# and provides an events API on top of it.
class Bridge
options:
# Scope identifier to distinguish this channel from any others
scope: 'bridge'
# Callback to invoke when a connection is established. The function is
# passed:
# - the newly created channel object
# - the window just connected to
onConnect: null
# Any callbacks for messages on the channel. Max one callback per method.
channelListeners: null
# Connected links to other frames
links: null
channelListeners: null
onConnectListeners: null
constructor: (options) ->
@options = $.extend(true, {}, @options, options)
constructor: ->
@links = []
@channelListeners = @options.channelListeners || {}
@channelListeners = {}
@onConnectListeners = []
if typeof @options.onConnect == 'function'
@onConnectListeners.push(@options.onConnect)
createChannel: (source, origin, token) ->
createChannel: (source, origin, scope) ->
# Set up a channel
scope = @options.scope + ':' + token
channelOptions =
window: source
origin: origin
......@@ -119,6 +104,6 @@ class Bridge
channel = Channel.build(options)
if angular?
angular.module('h').value('Bridge', Bridge)
angular.module('h').service 'bridge', Bridge
else
Annotator.Plugin.CrossFrame.Bridge = Bridge
......@@ -4,12 +4,12 @@ class CrossFrameService
this.inject = [
'$rootScope', '$document', '$window', 'store', 'annotationUI'
'Discovery', 'Bridge',
'Discovery', 'bridge',
'AnnotationSync', 'AnnotationUISync'
]
constructor: (
$rootScope, $document, $window, store, annotationUI
Discovery, Bridge,
Discovery, bridge,
AnnotationSync, AnnotationUISync
) ->
@providers = []
......@@ -19,13 +19,6 @@ class CrossFrameService
server: true
new Discovery($window, options)
# Set up the bridge plugin, which bridges the main annotation methods
# between the host page and the panel widget.
createBridge = ->
options =
scope: 'annotator:bridge'
new Bridge(options)
createAnnotationSync = (bridge) ->
whitelist = ['target', 'document', 'uri']
options =
......@@ -63,7 +56,6 @@ class CrossFrameService
this.connect = ->
discovery = createDiscovery()
bridge = createBridge()
bridge.onConnect(addProvider)
annotationSync = createAnnotationSync(bridge)
......
......@@ -60,7 +60,6 @@ module.exports = class Annotator.Guest extends Annotator
delete @options.app
cfOptions =
scope: 'annotator:bridge'
on: (event, handler) =>
this.subscribe(event, handler)
emit: (event, args...) =>
......
......@@ -7,7 +7,7 @@ sinon.assert.expose assert, prefix: null
describe 'Bridge', ->
sandbox = sinon.sandbox.create()
createBridge = null
bridge = null
createChannel = null
before ->
......@@ -15,9 +15,8 @@ describe 'Bridge', ->
require('../bridge')
beforeEach module('h')
beforeEach inject (Bridge) ->
createBridge = (options) ->
new Bridge(options)
beforeEach inject (_bridge_) ->
bridge = _bridge_
createChannel = ->
call: sandbox.stub()
......@@ -34,21 +33,19 @@ describe 'Bridge', ->
describe '.createChannel', ->
it 'creates a new channel with the provided options', ->
Channel.build.returns(createChannel())
bridge = createBridge()
bridge.createChannel('WINDOW', 'ORIGIN', 'TOKEN')
assert.called(Channel.build)
assert.calledWith(Channel.build, {
window: 'WINDOW'
origin: 'ORIGIN'
scope: 'bridge:TOKEN'
scope: 'TOKEN'
onReady: sinon.match.func
})
it 'adds the channel to the .links property', ->
channel = createChannel()
Channel.build.returns(channel)
bridge = createBridge()
bridge.createChannel('WINDOW', 'ORIGIN', 'TOKEN')
assert.include(bridge.links, {channel: channel, window: 'WINDOW'})
......@@ -57,7 +54,6 @@ describe 'Bridge', ->
channel = createChannel()
Channel.build.returns(channel)
bridge = createBridge()
bridge.on('message1', sinon.spy())
bridge.on('message2', sinon.spy())
bridge.createChannel('WINDOW', 'ORIGIN', 'TOKEN')
......@@ -70,7 +66,6 @@ describe 'Bridge', ->
channel = createChannel()
Channel.build.returns(channel)
bridge = createBridge()
ret = bridge.createChannel('WINDOW', 'ORIGIN', 'TOKEN')
assert.equal(ret, channel)
......@@ -80,7 +75,6 @@ describe 'Bridge', ->
channel = createChannel()
Channel.build.returns(channel)
bridge = createBridge()
bridge.createChannel('WINDOW', 'ORIGIN', 'TOKEN')
bridge.call({method: 'method1', params: 'params1'})
......@@ -93,7 +87,6 @@ describe 'Bridge', ->
channel = createChannel()
Channel.build.returns(channel)
bridge = createBridge()
bridge.createChannel('WINDOW', 'ORIGIN', 'TOKEN')
bridge.call({method: 'method1', params: 'params1'})
......@@ -108,7 +101,6 @@ describe 'Bridge', ->
callback = sandbox.stub()
bridge = createBridge()
Channel.build.returns(channel1)
bridge.createChannel('WINDOW', 'ORIGIN', 'TOKEN')
Channel.build.returns(channel2)
......@@ -127,7 +119,6 @@ describe 'Bridge', ->
channel2.call.yieldsTo('success', 'result2')
callback = sandbox.stub()
bridge = createBridge()
Channel.build.returns(channel1)
bridge.createChannel('WINDOW', 'ORIGIN', 'TOKEN')
......@@ -144,7 +135,6 @@ describe 'Bridge', ->
channel.call.yieldsTo('error', new Error(''), 'A reason for the error')
Channel.build.returns(channel)
bridge = createBridge()
bridge.createChannel('WINDOW', 'ORIGIN', 'TOKEN')
bridge.call({method: 'method1', params: 'params1', callback: sandbox.stub()})
......@@ -155,7 +145,6 @@ describe 'Bridge', ->
channel.call.yieldsTo('error', new Error(''), 'A reason for the error')
Channel.build.returns(channel)
bridge = createBridge()
bridge.createChannel('WINDOW', 'ORIGIN', 'TOKEN')
bridge.call({method: 'method1', params: 'params1', callback: sandbox.stub()})
bridge.call({method: 'method1', params: 'params1', callback: sandbox.stub()})
......@@ -168,7 +157,6 @@ describe 'Bridge', ->
Channel.build.returns(channel)
callback = sandbox.stub()
bridge = createBridge()
bridge.createChannel('WINDOW', 'ORIGIN', 'TOKEN')
bridge.call({method: 'method1', params: 'params1', callback: callback})
......@@ -180,7 +168,6 @@ describe 'Bridge', ->
channel.call.yieldsTo('error', 'timeout_error', 'timeout')
Channel.build.returns(channel)
bridge = createBridge()
ret = bridge.call({method: 'method1', params: 'params1'})
assert.isFunction(ret.then)
......@@ -190,7 +177,6 @@ describe 'Bridge', ->
message = {method: 'message1', params: 'params'}
Channel.build.returns(channel)
bridge = createBridge()
bridge.createChannel('WINDOW', 'ORIGIN', 'TOKEN')
bridge.notify(message)
......@@ -202,7 +188,6 @@ describe 'Bridge', ->
channel = createChannel()
Channel.build.returns(channel)
bridge = createBridge()
bridge.createChannel('WINDOW', 'ORIGIN', 'TOKEN')
bridge.on('message1', sandbox.spy())
......@@ -210,7 +195,6 @@ describe 'Bridge', ->
assert.calledWith(channel.bind, 'message1', sinon.match.func)
it 'only allows one message to be registered per method', ->
bridge = createBridge()
bridge.on('message1', sandbox.spy())
assert.throws ->
bridge.on('message1', sandbox.spy())
......@@ -220,7 +204,6 @@ describe 'Bridge', ->
channel = createChannel()
Channel.build.returns(channel)
bridge = createBridge()
bridge.createChannel('WINDOW', 'ORIGIN', 'TOKEN')
bridge.off('message1', sandbox.spy())
......@@ -229,7 +212,6 @@ describe 'Bridge', ->
channel2 = createChannel()
Channel.build.returns(channel1)
bridge = createBridge()
bridge.createChannel('WINDOW', 'ORIGIN', 'TOKEN')
bridge.off('message1', sandbox.spy())
......@@ -243,7 +225,6 @@ describe 'Bridge', ->
Channel.build.yieldsTo('onReady', channel)
callback = sandbox.stub()
bridge = createBridge()
bridge.onConnect(callback)
bridge.createChannel('WINDOW', 'ORIGIN', 'TOKEN')
......@@ -258,7 +239,6 @@ describe 'Bridge', ->
callback1 = sandbox.stub()
callback2 = sandbox.stub()
bridge = createBridge()
bridge.onConnect(callback1)
bridge.onConnect(callback2)
......
......@@ -42,8 +42,7 @@ describe 'CrossFrameService', ->
$provide.value('annotationUI', fakeAnnotationUI)
$provide.value('Discovery',
sandbox.stub().returns(fakeDiscovery))
$provide.value('Bridge',
sandbox.stub().returns(fakeBridge))
$provide.value('bridge', fakeBridge)
$provide.value('AnnotationSync',
sandbox.stub().returns(fakeAnnotationSync))
$provide.value('AnnotationUISync',
......
......@@ -39,10 +39,6 @@ describe 'Annotator.Guest', ->
sandbox.restore()
describe 'setting up the bridge', ->
it 'sets the scope for the cross frame bridge', ->
guest = createGuest()
options = Annotator.Plugin.CrossFrame.lastCall.args[1]
assert.equal(options.scope, 'annotator:bridge')
it 'provides an event bus for the annotation sync module', ->
guest = createGuest()
......
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