coffeescript-ui
Version:
Coffeescript User Interface System
175 lines (135 loc) • 4.29 kB
text/coffeescript
###
* coffeescript-ui - Coffeescript User Interface System (CUI)
* Copyright (c) 2013 - 2016 Programmfabrik GmbH
* MIT Licence
* https://github.com/programmfabrik/coffeescript-ui, http://www.coffeescript-ui.org
###
class CUI.StickyHeaderControl extends CUI.Element
constructor: (opts) ->
super(opts)
# destroy old instances, in case we are re-initialized
# on an .empty()ied element
CUI.dom.data(, "stickyHeaderControl")?.destroy()
CUI.dom.data(, "stickyHeaderControl", @)
= CUI.dom.div("cui-sticky-header-control")
CUI.Events.listen
instance: @
type: "viewport-resize"
node:
call: =>
CUI.dom.append(, )
= []
= []
= []
= false
CUI.Events.listen
node:
type: "scroll"
instance: @
call: (ev) =>
# console.time "scroll"
# console.timeEnd "scroll"
return
initOpts: ->
super()
element:
mandatory: true
check: (v) ->
CUI.util.isElement(v)
__positionControl: ->
dim = CUI.dom.getDimensions()
CUI.dom.setStyle ,
left: dim.clientBoundingRect.left
top: dim.clientBoundingRect.top
CUI.dom.setDimension(, "marginBoxWidth", dim.clientWidth)
# console.error "__positionControl", ,
return
isInDOM: ->
and CUI.dom.isInDOM()
addStickyHeader: (stickyHeader) ->
CUI.util.assert(not or CUI.dom.isInDOM(), "#{@__cls}.addStickyHeader", "StickyHeaderControl is not in DOM tree anymore. Cannot add a new CUI.StickyHeader.")
CUI.util.assert(stickyHeader instanceof CUI.StickyHeader, "#{@__cls}.addStickyHeader", "Needs to be instance of StickyHeader but is #{CUI.util.getObjectClass(stickyHeader)}", stickyHeader: stickyHeader)
.push(stickyHeader)
initNewStickyHeaders: ->
measure_headers = []
for nsh in
dom = nsh.DOM
header =
stickyHeader: nsh
level: nsh.getLevel()
node: dom.cloneNode(true)
.push(header)
measure_headers.push(header)
header.node.style.visiblity = "hidden"
CUI.dom.prepend(, header.node)
.splice(0)
for header in measure_headers
header.dimInControl = CUI.dom.getDimensions(header.node)
.removeChild(header.node)
header.node.style.visiblity = ""
@
destroy: ->
# console.warn "destroying sticky header control"
CUI.dom.removeData(, "stickyHeaderControl")
CUI.Events.ignore
instance: @
CUI.dom.remove()
= null
= null
position: ->
if not
return
= true
scrollTop = .scrollTop
slots = []
extraTop = 0
for header, idx in
extraTop = 0
for i in [0...header.level] by 1
slot = slots[i]
if slot == null
break
extraTop += slots[i].dimInControl.marginBoxHeight
if header.stickyHeader.DOM.offsetTop < scrollTop + extraTop + header.dimInControl.marginTop
slots[header.level] = header
for i in [header.level+1...slots.length] by 1
slots[i] = null
else
next_header = header
top_space = 0
for slot in slots
if slot == null
break
top_space += slot.dimInControl.marginBoxHeight
break
if next_header
cut = next_header.stickyHeader.DOM.offsetTop - scrollTop - top_space
cut = cut - next_header.dimInControl.marginTop
# console.debug cut, next_header.stickyHeader.DOM[0], next_header.stickyHeader.DOM[0].offsetTop, scrollTop, top_space
else
cut = 0
for hiddenHeader in
hiddenHeader.style.visibility = ""
.splice(0)
CUI.dom.empty()
top = 0
for slot, idx in slots
if slot == null
break
CUI.dom.prepend(, slot.node)
if cut < 0 and slot.level == next_header.level
top += cut
hideHeader = slot.stickyHeader.DOM
hideHeader.style.visibility = "hidden"
.push(hideHeader)
slot.node.style.top = top+"px"
top += slot.dimInControl.marginBoxHeight
CUI.dom.setStyle(,
height: top
)
@