Commit 37b3c617 authored by Juan Corona's avatar Juan Corona Committed by Juan Corona

Implement functionality for external container config

- Set a new `externalFrame` property when the external container config is provided.
- Use the new instance var is over the existing `frame` var.
	- This was done to isolate the new usage from the existing usage of `frame`
	- The existing usage of `frame` applies control over the sidebar frame, which works against what we want with `externalFrame`
- Make the uses of `frame` conditional.
	- These are the statements that are not invoked when the external container is specified.
	- The one case where we do want to use either frame is when emitting `onLayoutChange`
- Refactor the Sidebar tests to test for the added implementation and usage
parent 9c3fb515
......@@ -41,22 +41,31 @@ module.exports = class Host extends Guest
.attr('src', sidebarAppSrc)
.addClass('h-sidebar-iframe')
@frame = $('<div></div>')
.css('display', 'none')
.addClass('annotator-frame annotator-outer')
externalContainer = null
if config.theme == 'clean'
@frame.addClass('annotator-frame--drop-shadow-enabled')
if config.externalContainerSelector
# Use the native method to also validate the input
externalContainer = document.querySelector(config.externalContainerSelector)
@frame.appendTo(element)
if externalContainer
@externalFrame = $(externalContainer)
else
@frame = $('<div></div>')
.css('display', 'none')
.addClass('annotator-frame annotator-outer')
if config.theme == 'clean'
@frame.addClass('annotator-frame--drop-shadow-enabled')
@frame.appendTo(element)
super
app.appendTo(@frame)
app.appendTo(@frame || @externalFrame)
this.on 'panelReady', =>
# Show the UI
@frame.css('display', '')
@frame?.css('display', '')
this.on 'beforeAnnotationCreated', (annotation) ->
# When a new non-highlight annotation is created, focus
......@@ -66,5 +75,5 @@ module.exports = class Host extends Guest
app[0].contentWindow.focus()
destroy: ->
@frame.remove()
@frame?.remove()
super
......@@ -162,8 +162,9 @@ module.exports = class Sidebar extends Host
# container.
if @onLayoutChange
rect = @frame[0].getBoundingClientRect()
computedStyle = window.getComputedStyle(@frame[0])
frame = @frame || @externalFrame
rect = frame[0].getBoundingClientRect()
computedStyle = window.getComputedStyle(frame[0])
width = parseInt(computedStyle.width)
leftMargin = parseInt(computedStyle.marginLeft)
......@@ -198,6 +199,8 @@ module.exports = class Sidebar extends Host
})
onPan: (event) =>
return unless @frame
switch event.type
when 'panstart'
# Initialize the gesture state
......@@ -241,8 +244,9 @@ module.exports = class Sidebar extends Host
show: ->
@crossframe.call('sidebarOpened')
@frame.css 'margin-left': "#{-1 * @frame.width()}px"
@frame.removeClass 'annotator-collapsed'
if @frame
@frame.css 'margin-left': "#{-1 * @frame.width()}px"
@frame.removeClass 'annotator-collapsed'
if @plugins.Toolbar?
@plugins.Toolbar.showCollapseSidebarBtn();
......@@ -255,9 +259,9 @@ module.exports = class Sidebar extends Host
this._notifyOfLayoutChange(true)
hide: ->
@frame.css 'margin-left': ''
@frame.addClass 'annotator-collapsed'
if @frame
@frame.css 'margin-left': ''
@frame.addClass 'annotator-collapsed'
if @plugins.Toolbar?
@plugins.Toolbar.hideCloseBtn();
......@@ -269,7 +273,11 @@ module.exports = class Sidebar extends Host
this._notifyOfLayoutChange(false)
isOpen: ->
!@frame.hasClass('annotator-collapsed')
if @frame
return !@frame.hasClass('annotator-collapsed')
else
# Assume it will always be open for an external frame
return true
setAllVisibleHighlights: (shouldShowHighlights) ->
@crossframe.call('setVisibleHighlights', shouldShowHighlights)
......
......@@ -7,6 +7,8 @@ rafStub = (fn) ->
Sidebar = proxyquire('../sidebar', { raf: rafStub })
DEFAULT_WIDTH = 350
DEFAULT_HEIGHT = 600
EXTERNAL_CONTAINER_SELECTOR = 'test-external-container'
describe 'Sidebar', ->
......@@ -20,6 +22,11 @@ describe 'Sidebar', ->
element = document.createElement('div')
return new Sidebar(element, config)
createExternalContainer = ->
externalFrame = $('<div class="' + EXTERNAL_CONTAINER_SELECTOR + '"></div>')
externalFrame.width(DEFAULT_WIDTH).height(DEFAULT_HEIGHT)
return externalFrame[0]
beforeEach ->
sandbox.stub(Sidebar.prototype, '_setupGestures')
......@@ -307,10 +314,6 @@ describe 'Sidebar', ->
describe 'layout change notifier', ->
layoutChangeHandlerSpy = null
sidebar = null
frame = null
DEFAULT_WIDTH = 350
DEFAULT_HEIGHT = 600
assertLayoutValues = (args, expectations) ->
expected = Object.assign {
......@@ -321,53 +324,117 @@ describe 'Sidebar', ->
assert.deepEqual args, expected
beforeEach ->
layoutChangeHandlerSpy = sandbox.spy()
sidebar = createSidebar { onLayoutChange: layoutChangeHandlerSpy, sidebarAppUrl: '/' }
# remove info about call that happens on creation of sidebar
layoutChangeHandlerSpy.reset()
frame = sidebar.frame[0]
Object.assign frame.style, {
display: 'block',
width: DEFAULT_WIDTH + 'px',
height: DEFAULT_HEIGHT + 'px',
describe 'with the frame set up as default', ->
sidebar = null
frame = null
beforeEach ->
layoutChangeHandlerSpy = sandbox.spy()
sidebar = createSidebar { onLayoutChange: layoutChangeHandlerSpy, sidebarAppUrl: '/' }
# remove info about call that happens on creation of sidebar
layoutChangeHandlerSpy.reset()
frame = sidebar.frame[0]
Object.assign frame.style, {
display: 'block',
width: DEFAULT_WIDTH + 'px',
height: DEFAULT_HEIGHT + 'px',
# width is based on left position of the window,
# we need to apply the css that puts the frame in the
# correct position
position: 'fixed',
top: 0,
left: '100%',
}
document.body.appendChild frame
afterEach ->
frame.remove()
it 'notifies when sidebar changes expanded state', ->
sidebar.show()
assert.calledOnce layoutChangeHandlerSpy
assertLayoutValues layoutChangeHandlerSpy.lastCall.args[0], {expanded: true}
sidebar.hide()
assert.calledTwice layoutChangeHandlerSpy
assertLayoutValues layoutChangeHandlerSpy.lastCall.args[0], {
expanded: false,
width: 0,
}
it 'notifies when sidebar is panned left', ->
sidebar.gestureState = { initial: -DEFAULT_WIDTH }
sidebar.onPan({type: 'panleft', deltaX: -50})
assertLayoutValues layoutChangeHandlerSpy.lastCall.args[0], { width: 400 }
it 'notifies when sidebar is panned right', ->
sidebar.gestureState = { initial: -DEFAULT_WIDTH }
sidebar.onPan({type: 'panright', deltaX: 50})
assertLayoutValues layoutChangeHandlerSpy.lastCall.args[0], { width: 300 }
describe 'with the frame in an external container', ->
sidebar = null
externalFrame = null
beforeEach ->
externalFrame = createExternalContainer()
Object.assign externalFrame.style, {
display: 'block',
width: DEFAULT_WIDTH + 'px',
height: DEFAULT_HEIGHT + 'px',
position: 'fixed',
top: 0,
left: 0,
}
document.body.appendChild externalFrame
layoutChangeHandlerSpy = sandbox.spy()
layoutChangeExternalConfig = {
onLayoutChange: layoutChangeHandlerSpy,
sidebarAppUrl: '/',
externalContainerSelector: '.' + EXTERNAL_CONTAINER_SELECTOR,
}
sidebar = createSidebar layoutChangeExternalConfig
# remove info about call that happens on creation of sidebar
layoutChangeHandlerSpy.reset()
afterEach ->
externalFrame.remove()
it 'notifies when sidebar changes expanded state', ->
sidebar.show()
assert.calledOnce layoutChangeHandlerSpy
assertLayoutValues layoutChangeHandlerSpy.lastCall.args[0], {expanded: true}
sidebar.hide()
assert.calledTwice layoutChangeHandlerSpy
assertLayoutValues layoutChangeHandlerSpy.lastCall.args[0], {
expanded: false,
width: 0,
}
describe 'sidebar frame in an external container', ->
sidebar = null
externalFrame = null
# width is based on left position of the window,
# we need to apply the css that puts the frame in the
# correct position
position: 'fixed',
top: 0,
left: '100%',
}
beforeEach ->
externalFrame = createExternalContainer()
document.body.appendChild externalFrame
document.body.appendChild frame
sidebar = createSidebar { externalContainerSelector: '.' + EXTERNAL_CONTAINER_SELECTOR }
afterEach ->
frame.remove()
externalFrame.remove()
it 'notifies when sidebar changes expanded state', ->
sidebar.show()
assert.calledOnce layoutChangeHandlerSpy
assertLayoutValues layoutChangeHandlerSpy.lastCall.args[0], {expanded: true}
sidebar.hide()
assert.calledTwice layoutChangeHandlerSpy
assertLayoutValues layoutChangeHandlerSpy.lastCall.args[0], {
expanded: false,
width: 0,
}
it 'notifies when sidebar is panned left', ->
sidebar.gestureState = { initial: -DEFAULT_WIDTH }
sidebar.onPan({type: 'panleft', deltaX: -50})
assertLayoutValues layoutChangeHandlerSpy.lastCall.args[0], { width: 400 }
it 'notifies when sidebar is panned right', ->
sidebar.gestureState = { initial: -DEFAULT_WIDTH }
sidebar.onPan({type: 'panright', deltaX: 50})
assertLayoutValues layoutChangeHandlerSpy.lastCall.args[0], { width: 300 }
it 'uses the configured external container as the frame', ->
assert.equal(sidebar.frame, undefined)
assert.isDefined(sidebar.externalFrame)
assert.equal(sidebar.externalFrame[0], externalFrame)
assert.equal(externalFrame.childNodes.length, 1)
describe 'config', ->
it 'does not have the BucketBar plugin if the clean theme is enabled', ->
......
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