Commit 3f4de98f authored by gergely-ujvari's avatar gergely-ujvari

Merge pull request #2066 from hypothesis/separete-host-service

Separate the Host service
parents cd9e1db1 7f6ff5b8
......@@ -17,23 +17,8 @@ class AnnotationUISync
getAnnotationsByTags = (tags) ->
tags.map(annotationSync.getAnnotationForTag, annotationSync)
# Sends a message to the host frame only.
notifyHost = (message) ->
for {channel, window} in bridge.links when window is $window.parent
channel.notify(message)
break
# Send messages to host to hide/show sidebar iframe.
hide = notifyHost.bind(null, method: 'hideFrame')
show = notifyHost.bind(null, method: 'showFrame')
channelListeners =
back: hide
open: show
showEditor: show
showAnnotations: (ctx, tags=[]) ->
show()
annotations = getAnnotationsByTags(tags)
annotationUI.selectAnnotations(annotations)
focusAnnotations: (ctx, tags=[]) ->
......
......@@ -82,6 +82,7 @@ configureTemplates = ['$sceDelegateProvider', ($sceDelegateProvider) ->
setupCrossFrame = ['crossframe', (crossframe) -> crossframe.connect()]
setupHost = ['host', (host) -> ]
setupStreamer = [
'$http', '$window', 'streamer'
......@@ -101,6 +102,7 @@ module = angular.module('h', imports)
unless mocha? # Crude method of detecting test environment.
module.run(setupCrossFrame)
module.run(setupStreamer)
module.run(setupHost)
require('./vendor/annotator.auth.js')
require('./annotator/monkey')
......@@ -125,6 +127,7 @@ require('./annotation-mapper-service')
require('./annotation-ui-service')
require('./auth-service')
require('./cross-frame-service')
require('./host-service')
require('./flash-service')
require('./permissions-service')
require('./local-storage-service')
......
......@@ -258,11 +258,6 @@ module.exports = class Annotator.Guest extends Annotator
method: "updateAnnotations"
params: (a.$$tag for a in annotations)
showEditor: (annotation) =>
@crossframe?.notify
method: "showEditor"
params: annotation.$$tag
focusAnnotations: (annotations) =>
@crossframe?.notify
method: "focusAnnotations"
......@@ -327,6 +322,7 @@ module.exports = class Annotator.Guest extends Annotator
this.toggleAnnotationSelection annotations
else
# Tell sidebar to show the viewer for these annotations
this.triggerShowFrame()
this.showAnnotations annotations
# When Mousing over a highlight, tell the sidebar to focus the relevant annotations
......@@ -370,9 +366,9 @@ module.exports = class Annotator.Guest extends Annotator
# Might not be needed anymore. Perhaps should just use on adderclick or perhaps new note?
addComment: ->
@adder.hide()
annotation = this.setupAnnotation(this.createAnnotation())
this.setupAnnotation(this.createAnnotation())
Annotator.Util.getGlobal().getSelection().removeAllRanges()
this.showEditor(annotation)
this.triggerShowFrame()
# Open the sidebar
triggerShowFrame: ->
......@@ -400,8 +396,8 @@ module.exports = class Annotator.Guest extends Annotator
switch event.target.dataset.action
when 'highlight'
this.setVisibleHighlights true
annotation = this.setupAnnotation(this.createHighlight())
this.setupAnnotation(this.createHighlight())
when 'comment'
annotation = this.setupAnnotation(this.createAnnotation())
this.showEditor(annotation)
this.setupAnnotation(this.createAnnotation())
this.triggerShowFrame()
Annotator.Util.getGlobal().getSelection().removeAllRanges()
###*
# @ngdoc service
# @name host
#
# @description
# The `host` service relays the instructions the sidebar needs to send
# to the host document. (As opposed to all guests)
# It uses the bridge service to talk to the host.
###
class HostService
this.inject = ['$window', 'bridge']
constructor: ( $window, bridge ) ->
# Sends a message to the host frame
@_notifyHost = (message) ->
for {channel, window} in bridge.links when window is $window.parent
channel.notify(message)
break
channelListeners =
back: => @hideSidebar()
open: => @showSidebar()
for own channel, listener of channelListeners
bridge.on(channel, listener)
# Tell the host to show the sidebar
showSidebar: => @_notifyHost method: 'showFrame'
# Tell the host to hide the sidebar
hideSidebar: => @_notifyHost method: 'hideFrame'
angular.module('h').service('host', HostService)
......@@ -28,11 +28,7 @@ describe 'AnnotationSync', ->
call: sandbox.stub()
notify: sandbox.stub()
onConnect: sandbox.stub()
links: [
{window: PARENT_WINDOW, channel: createChannel()}
{window: 'ANOTHER_WINDOW', channel: createChannel()}
{window: 'THIRD_WINDOW', channel: createChannel()}
]
links: []
# TODO: Fix this hack to remove pre-existing bound listeners.
$rootScope.$$listeners = []
......
......@@ -71,56 +71,7 @@ describe 'AnnotationUISync', ->
createAnnotationUISync()
assert.notCalled(channel.notify)
describe 'on "back" event', ->
it 'sends the "hideFrame" message to the host only', ->
createAnnotationUISync()
publish({method: 'back'})
assert.calledWith(fakeBridge.links[0].channel.notify, method: 'hideFrame')
assert.notCalled(fakeBridge.links[1].channel.notify)
assert.notCalled(fakeBridge.links[2].channel.notify)
it 'triggers a digest', ->
createAnnotationUISync()
publish({method: 'back'})
assert.called($digest)
describe 'on "open" event', ->
it 'sends the "showFrame" message to the host only', ->
createAnnotationUISync()
publish({method: 'open'})
assert.calledWith(fakeBridge.links[0].channel.notify, method: 'showFrame')
assert.notCalled(fakeBridge.links[1].channel.notify)
assert.notCalled(fakeBridge.links[2].channel.notify)
it 'triggers a digest', ->
createAnnotationUISync()
publish({method: 'open'})
assert.called($digest)
describe 'on "showEditor" event', ->
it 'sends the "showFrame" message to the host only', ->
createAnnotationUISync()
publish({method: 'showEditor'})
assert.calledWith(fakeBridge.links[0].channel.notify, method: 'showFrame')
assert.notCalled(fakeBridge.links[1].channel.notify)
assert.notCalled(fakeBridge.links[2].channel.notify)
it 'triggers a digest', ->
createAnnotationUISync()
publish({method: 'showEditor'})
assert.called($digest)
describe 'on "showAnnotations" event', ->
it 'sends the "showFrame" message to the host only', ->
createAnnotationUISync()
publish({
method: 'showAnnotations',
params: ['tag1', 'tag2', 'tag3']
})
assert.calledWith(fakeBridge.links[0].channel.notify, method: 'showFrame')
assert.notCalled(fakeBridge.links[1].channel.notify)
assert.notCalled(fakeBridge.links[2].channel.notify)
it 'updates the annotationUI to include the shown annotations', ->
createAnnotationUISync()
publish({
......
{module, inject} = require('angular-mock')
assert = chai.assert
sinon.assert.expose assert, prefix: null
describe 'Host service', ->
sandbox = null
host = null
createChannel = -> notify: sandbox.stub()
fakeBridge = null
$digest = null
publish = null
PARENT_WINDOW = 'PARENT_WINDOW'
dumpListeners = null
before ->
require('../host-service')
beforeEach module('h')
beforeEach module ($provide) ->
sandbox = sinon.sandbox.create()
fakeWindow = parent: PARENT_WINDOW
listeners = {}
publish = ({method, params}) ->
listeners[method]('ctx', params)
fakeBridge =
ls: listeners
on: sandbox.spy (method, fn) -> listeners[method] = fn
notify: sandbox.stub()
onConnect: sandbox.stub()
links: [
{window: PARENT_WINDOW, channel: createChannel()}
{window: 'ANOTHER_WINDOW', channel: createChannel()}
{window: 'THIRD_WINDOW', channel: createChannel()}
]
$provide.value 'bridge', fakeBridge
$provide.value '$window', fakeWindow
return
afterEach ->
sandbox.restore()
beforeEach inject ($rootScope, _host_) ->
host = _host_
$digest = sandbox.stub($rootScope, '$digest')
describe 'the public API', ->
describe 'showSidebar()', ->
it 'sends the "showFrame" message to the host only', ->
host.showSidebar()
assert.calledWith(fakeBridge.links[0].channel.notify, method: 'showFrame')
assert.notCalled(fakeBridge.links[1].channel.notify)
assert.notCalled(fakeBridge.links[2].channel.notify)
describe 'hideSidebar()', ->
it 'sends the "hideFrame" message to the host only', ->
host.hideSidebar()
assert.calledWith(fakeBridge.links[0].channel.notify, method: 'hideFrame')
assert.notCalled(fakeBridge.links[1].channel.notify)
assert.notCalled(fakeBridge.links[2].channel.notify)
describe 'reacting to the bridge', ->
describe 'on "back" event', ->
it 'triggers the hideSidebar() API', ->
sandbox.spy host, "hideSidebar"
publish method: 'back'
assert.called host.hideSidebar
describe 'on "open" event', ->
it 'triggers the showSidebar() API', ->
sandbox.spy host, "showSidebar"
publish method: 'open'
assert.called host.showSidebar
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