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 ...@@ -41,22 +41,31 @@ module.exports = class Host extends Guest
.attr('src', sidebarAppSrc) .attr('src', sidebarAppSrc)
.addClass('h-sidebar-iframe') .addClass('h-sidebar-iframe')
@frame = $('<div></div>') externalContainer = null
.css('display', 'none')
.addClass('annotator-frame annotator-outer')
if config.theme == 'clean' if config.externalContainerSelector
@frame.addClass('annotator-frame--drop-shadow-enabled') # 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 super
app.appendTo(@frame) app.appendTo(@frame || @externalFrame)
this.on 'panelReady', => this.on 'panelReady', =>
# Show the UI # Show the UI
@frame.css('display', '') @frame?.css('display', '')
this.on 'beforeAnnotationCreated', (annotation) -> this.on 'beforeAnnotationCreated', (annotation) ->
# When a new non-highlight annotation is created, focus # When a new non-highlight annotation is created, focus
...@@ -66,5 +75,5 @@ module.exports = class Host extends Guest ...@@ -66,5 +75,5 @@ module.exports = class Host extends Guest
app[0].contentWindow.focus() app[0].contentWindow.focus()
destroy: -> destroy: ->
@frame.remove() @frame?.remove()
super super
...@@ -162,8 +162,9 @@ module.exports = class Sidebar extends Host ...@@ -162,8 +162,9 @@ module.exports = class Sidebar extends Host
# container. # container.
if @onLayoutChange if @onLayoutChange
rect = @frame[0].getBoundingClientRect() frame = @frame || @externalFrame
computedStyle = window.getComputedStyle(@frame[0]) rect = frame[0].getBoundingClientRect()
computedStyle = window.getComputedStyle(frame[0])
width = parseInt(computedStyle.width) width = parseInt(computedStyle.width)
leftMargin = parseInt(computedStyle.marginLeft) leftMargin = parseInt(computedStyle.marginLeft)
...@@ -198,6 +199,8 @@ module.exports = class Sidebar extends Host ...@@ -198,6 +199,8 @@ module.exports = class Sidebar extends Host
}) })
onPan: (event) => onPan: (event) =>
return unless @frame
switch event.type switch event.type
when 'panstart' when 'panstart'
# Initialize the gesture state # Initialize the gesture state
...@@ -241,8 +244,9 @@ module.exports = class Sidebar extends Host ...@@ -241,8 +244,9 @@ module.exports = class Sidebar extends Host
show: -> show: ->
@crossframe.call('sidebarOpened') @crossframe.call('sidebarOpened')
@frame.css 'margin-left': "#{-1 * @frame.width()}px" if @frame
@frame.removeClass 'annotator-collapsed' @frame.css 'margin-left': "#{-1 * @frame.width()}px"
@frame.removeClass 'annotator-collapsed'
if @plugins.Toolbar? if @plugins.Toolbar?
@plugins.Toolbar.showCollapseSidebarBtn(); @plugins.Toolbar.showCollapseSidebarBtn();
...@@ -255,9 +259,9 @@ module.exports = class Sidebar extends Host ...@@ -255,9 +259,9 @@ module.exports = class Sidebar extends Host
this._notifyOfLayoutChange(true) this._notifyOfLayoutChange(true)
hide: -> hide: ->
@frame.css 'margin-left': '' if @frame
@frame.addClass 'annotator-collapsed' @frame.css 'margin-left': ''
@frame.addClass 'annotator-collapsed'
if @plugins.Toolbar? if @plugins.Toolbar?
@plugins.Toolbar.hideCloseBtn(); @plugins.Toolbar.hideCloseBtn();
...@@ -269,7 +273,11 @@ module.exports = class Sidebar extends Host ...@@ -269,7 +273,11 @@ module.exports = class Sidebar extends Host
this._notifyOfLayoutChange(false) this._notifyOfLayoutChange(false)
isOpen: -> 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) -> setAllVisibleHighlights: (shouldShowHighlights) ->
@crossframe.call('setVisibleHighlights', shouldShowHighlights) @crossframe.call('setVisibleHighlights', shouldShowHighlights)
......
...@@ -7,6 +7,8 @@ rafStub = (fn) -> ...@@ -7,6 +7,8 @@ rafStub = (fn) ->
Sidebar = proxyquire('../sidebar', { raf: rafStub }) Sidebar = proxyquire('../sidebar', { raf: rafStub })
DEFAULT_WIDTH = 350
DEFAULT_HEIGHT = 600
EXTERNAL_CONTAINER_SELECTOR = 'test-external-container' EXTERNAL_CONTAINER_SELECTOR = 'test-external-container'
describe 'Sidebar', -> describe 'Sidebar', ->
...@@ -20,6 +22,11 @@ describe 'Sidebar', -> ...@@ -20,6 +22,11 @@ describe 'Sidebar', ->
element = document.createElement('div') element = document.createElement('div')
return new Sidebar(element, config) return new Sidebar(element, config)
createExternalContainer = ->
externalFrame = $('<div class="' + EXTERNAL_CONTAINER_SELECTOR + '"></div>')
externalFrame.width(DEFAULT_WIDTH).height(DEFAULT_HEIGHT)
return externalFrame[0]
beforeEach -> beforeEach ->
sandbox.stub(Sidebar.prototype, '_setupGestures') sandbox.stub(Sidebar.prototype, '_setupGestures')
...@@ -307,10 +314,6 @@ describe 'Sidebar', -> ...@@ -307,10 +314,6 @@ describe 'Sidebar', ->
describe 'layout change notifier', -> describe 'layout change notifier', ->
layoutChangeHandlerSpy = null layoutChangeHandlerSpy = null
sidebar = null
frame = null
DEFAULT_WIDTH = 350
DEFAULT_HEIGHT = 600
assertLayoutValues = (args, expectations) -> assertLayoutValues = (args, expectations) ->
expected = Object.assign { expected = Object.assign {
...@@ -321,53 +324,117 @@ describe 'Sidebar', -> ...@@ -321,53 +324,117 @@ describe 'Sidebar', ->
assert.deepEqual args, expected assert.deepEqual args, expected
beforeEach -> describe 'with the frame set up as default', ->
layoutChangeHandlerSpy = sandbox.spy() sidebar = null
sidebar = createSidebar { onLayoutChange: layoutChangeHandlerSpy, sidebarAppUrl: '/' } frame = null
beforeEach ->
# remove info about call that happens on creation of sidebar layoutChangeHandlerSpy = sandbox.spy()
layoutChangeHandlerSpy.reset() sidebar = createSidebar { onLayoutChange: layoutChangeHandlerSpy, sidebarAppUrl: '/' }
frame = sidebar.frame[0] # remove info about call that happens on creation of sidebar
Object.assign frame.style, { layoutChangeHandlerSpy.reset()
display: 'block',
width: DEFAULT_WIDTH + 'px', frame = sidebar.frame[0]
height: DEFAULT_HEIGHT + 'px', 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, beforeEach ->
# we need to apply the css that puts the frame in the externalFrame = createExternalContainer()
# correct position document.body.appendChild externalFrame
position: 'fixed',
top: 0,
left: '100%',
}
document.body.appendChild frame sidebar = createSidebar { externalContainerSelector: '.' + EXTERNAL_CONTAINER_SELECTOR }
afterEach -> afterEach ->
frame.remove() externalFrame.remove()
it 'notifies when sidebar changes expanded state', -> it 'uses the configured external container as the frame', ->
sidebar.show() assert.equal(sidebar.frame, undefined)
assert.calledOnce layoutChangeHandlerSpy assert.isDefined(sidebar.externalFrame)
assertLayoutValues layoutChangeHandlerSpy.lastCall.args[0], {expanded: true} assert.equal(sidebar.externalFrame[0], externalFrame)
assert.equal(externalFrame.childNodes.length, 1)
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 'config', -> describe 'config', ->
it 'does not have the BucketBar plugin if the clean theme is enabled', -> 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