overleaf/services/web/public/coffee/ide/directives/layout.coffee

203 lines
6.9 KiB
CoffeeScript
Raw Normal View History

2014-07-08 07:02:26 -04:00
define [
"base"
"libs/jquery-layout"
], (App) ->
App.directive "layout", ["$parse", "$compile", "ide", ($parse, $compile, ide) ->
2014-07-08 07:02:26 -04:00
return {
compile: () ->
pre: (scope, element, attrs) ->
name = attrs.layout
2018-03-22 08:10:34 -04:00
customTogglerPane = scope.$eval(attrs.customTogglerPane or "false")
customTogglerMsgWhenOpen = scope.$eval(attrs.customTogglerMsgWhenOpen or "false")
customTogglerMsgWhenClosed = scope.$eval(attrs.customTogglerMsgWhenClosed or "false")
hasCustomToggler = customTogglerPane != false and customTogglerMsgWhenOpen != false and customTogglerMsgWhenClosed != false
2014-07-08 07:02:26 -04:00
if attrs.spacingOpen?
spacingOpen = parseInt(attrs.spacingOpen, 10)
else
spacingOpen = window.uiConfig.defaultResizerSizeOpen
2014-07-08 07:02:26 -04:00
if attrs.spacingClosed?
spacingClosed = parseInt(attrs.spacingClosed, 10)
else
spacingClosed = window.uiConfig.defaultResizerSizeClosed
2014-07-08 07:02:26 -04:00
options =
spacing_open: spacingOpen
spacing_closed: spacingClosed
slidable: false
enableCursorHotkey: false
onopen: (pane) =>
onPaneOpen(pane)
onclose: (pane) =>
onPaneClose(pane)
2014-07-08 07:02:26 -04:00
onresize: () =>
onInternalResize()
maskIframesOnResize: scope.$eval(
attrs.maskIframesOnResize or "false"
)
east:
size: scope.$eval(attrs.initialSizeEast)
initClosed: scope.$eval(attrs.initClosedEast)
west:
size: scope.$eval(attrs.initialSizeEast)
initClosed: scope.$eval(attrs.initClosedWest)
# Restore previously recorded state
if (state = ide.localStorage("layout.#{name}"))?
if state.east?
if !attrs.minimumRestoreSizeEast? or (state.east.size >= attrs.minimumRestoreSizeEast and !state.east.initClosed)
options.east = state.east
if state.west?
if !attrs.minimumRestoreSizeWest? or (state.west.size >= attrs.minimumRestoreSizeWest and !state.west.initClosed)
options.west = state.west
2014-07-08 07:02:26 -04:00
2017-12-11 10:33:00 -05:00
if window.uiConfig.eastResizerCursor?
options.east.resizerCursor = window.uiConfig.eastResizerCursor
if window.uiConfig.westResizerCursor?
options.west.resizerCursor = window.uiConfig.westResizerCursor
repositionControls = () ->
state = element.layout().readState()
if state.east?
controls = element.find("> .ui-layout-resizer-controls")
if state.east.initClosed
controls.hide()
else
controls.show()
controls.css({
right: state.east.size
})
repositionCustomToggler = () ->
if !customTogglerEl?
return
state = element.layout().readState()
positionAnchor = if customTogglerPane == "east" then "right" else "left"
paneState = state[customTogglerPane]
if paneState?
customTogglerEl.css(positionAnchor, if paneState.initClosed then 0 else paneState.size)
resetOpenStates = () ->
state = element.layout().readState()
if attrs.openEast? and state.east?
openEast = $parse(attrs.openEast)
openEast.assign(scope, !state.east.initClosed)
2014-07-08 07:02:26 -04:00
# Someone moved the resizer
onInternalResize = () ->
state = element.layout().readState()
scope.$broadcast "layout:#{name}:resize", state
repositionControls()
if hasCustomToggler
repositionCustomToggler()
2014-07-08 07:02:26 -04:00
resetOpenStates()
2014-07-08 07:02:26 -04:00
oldWidth = element.width()
# Something resized our parent element
onExternalResize = () ->
if attrs.resizeProportionally? and scope.$eval(attrs.resizeProportionally)
eastState = element.layout().readState().east
if eastState?
newInternalWidth = eastState.size / oldWidth * element.width()
oldWidth = element.width()
element.layout().sizePane("east", newInternalWidth)
return
element.layout().resizeAll()
element.layout options
element.layout().resizeAll()
if attrs.resizeOn?
scope.$on attrs.resizeOn, () -> onExternalResize()
if hasCustomToggler
state = element.layout().readState()
customTogglerScope = scope.$new()
customTogglerScope.isOpen = true
customTogglerScope.isVisible = true
if state[customTogglerPane]?.initClosed == true
customTogglerScope.isOpen = false
2018-03-20 12:06:44 -04:00
customTogglerScope.tooltipMsgWhenOpen = customTogglerMsgWhenOpen
customTogglerScope.tooltipMsgWhenClosed = customTogglerMsgWhenClosed
customTogglerScope.tooltipPlacement = if customTogglerPane == "east" then "left" else "right"
customTogglerScope.handleClick = () ->
element.layout().toggle(customTogglerPane)
repositionCustomToggler()
customTogglerEl = $compile("
<a href
ng-show=\"isVisible\"
class=\"custom-toggler #{ 'custom-toggler-' + customTogglerPane }\"
ng-class=\"isOpen ? 'custom-toggler-open' : 'custom-toggler-closed'\"
2018-03-20 12:06:44 -04:00
tooltip=\"{{ isOpen ? tooltipMsgWhenOpen : tooltipMsgWhenClosed }}\"
tooltip-placement=\"{{ tooltipPlacement }}\"
ng-click=\"handleClick()\">
")(customTogglerScope)
element.append(customTogglerEl)
onPaneOpen = (pane) ->
if !hasCustomToggler and pane != customTogglerPane
return
customTogglerEl.scope().$applyAsync () ->
customTogglerEl.scope().isOpen = true
onPaneClose = (pane) ->
if !hasCustomToggler and pane != customTogglerPane
return
customTogglerEl.scope().$applyAsync () ->
customTogglerEl.scope().isOpen = false
2014-07-08 07:02:26 -04:00
# Save state when exiting
$(window).unload () ->
ide.localStorage("layout.#{name}", element.layout().readState())
2014-07-08 07:02:26 -04:00
if attrs.openEast?
scope.$watch attrs.openEast, (value, oldValue) ->
if value? and value != oldValue
if value
element.layout().open("east")
else
element.layout().close("east")
setTimeout () ->
scope.$digest()
, 0
if attrs.allowOverflowOn?
layoutObj = element.layout()
overflowPane = scope.$eval(attrs.allowOverflowOn)
overflowPaneEl = layoutObj.panes[overflowPane]
# Set the panel as overflowing (gives it higher z-index and sets overflow rules)
layoutObj.allowOverflow overflowPane
# Read the given z-index value and increment it, so that it's higher than synctex controls.
overflowPaneZVal = overflowPaneEl.zIndex()
overflowPaneEl.css "z-index", overflowPaneZVal + 1
2014-07-08 07:02:26 -04:00
resetOpenStates()
2014-07-10 09:36:04 -04:00
onInternalResize()
if attrs.layoutDisabled?
scope.$watch attrs.layoutDisabled, (value) ->
if value
element.layout().hide("east")
else
element.layout().show("east")
if hasCustomToggler
customTogglerEl.scope().$applyAsync () ->
customTogglerEl.scope().isOpen = !value
customTogglerEl.scope().isVisible = !value
post: (scope, element, attrs) ->
name = attrs.layout
state = element.layout().readState()
scope.$broadcast "layout:#{name}:linked", state
2014-07-08 07:02:26 -04:00
}
]