coffeescript-ui
Version:
Coffeescript User Interface System
291 lines (223 loc) • 6.95 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.Droppable extends CUI.DragDropSelect
= "droppable"
initOpts: ->
super()
accept:
check: Function
drop:
default: (ev, info) =>
pos = info.dropTargetPos or "on"
CUI.alert(
markdown: true,
text: "You dropped me **"+pos+"**: " + CUI.dom.getAttribute(info.dropTarget, "class")
)
check: Function
hoverClass:
default: "cui-droppable"
check: String
dropHelper:
mandatory: true
default: false
check: Boolean
targetHelper:
mandatory: true
default: false
check: Boolean
selector:
check: (v) =>
CUI.util.isString(v) or CUI.util.isFunction(v)
accept: (ev, info) ->
?(ev, info)
destroy: ->
super()
readOpts: ->
super()
if
CUI.util.assert(, "new CUI.Droppable", "opts.targetHelper needs opts.selector to be set.", opts: )
if
CUI.util.assert(not or , "new CUI.Droppable", "opts.dropHelper does only work without opts.selector or with opts.targetHelper and opts.selector. needs opts.selector to be set.", opts: )
= CUI.dom.element("DIV", class: "cui-droppable-drop-helper")
return
removeHelper: ->
if
CUI.dom.removeClass(, )
= null
if
CUI.dom.remove()
if
for el in CUI.dom.findElements(, )
el.classList.remove("cui-droppable-target-helper")
= undefined
= undefined
resetMargin: ->
if not
return
.classList.remove(.__target_helper_class)
delete(.__target_helper_class)
delete()
delete()
insideSaveZone: (coord) ->
if not
return false
buf = 5 # add extra pixels
for zone in
if (zone.viewportTopMargin - buf) <= coord.pageY <= (zone.viewportBottomMargin + buf) and
(zone.viewportLeftMargin - buf) <= coord.pageX <= (zone.viewportRightMargin + buf)
return true
return false
syncDropHelper: ->
# drop helper goes on top
dim = CUI.dom.getDimensions()
document.body.appendChild()
CUI.dom.setDimensions ,
contentBoxWidth: dim.borderBoxWidth
contentBoxHeight: dim.borderBoxHeight
drop_helper_dim = CUI.dom.getDimensions()
CUI.dom.setStyle ,
position: "absolute"
top: dim.viewportTop - drop_helper_dim.borderTopWidth - drop_helper_dim.marginTop
left: dim.viewportLeft - drop_helper_dim.borderLeftWidth - drop_helper_dim.marginLeft
syncTargetHelper: (ev, info) ->
target = ev.getTarget()
coord = CUI.util.getCoordinatesFromEvent(info.originalEvent)
if ev.getType() == "cui-dragleave"
new_target = info.originalEvent.getTarget()
if CUI.dom.closest(new_target, ".cui-drag-drop-select-droppable") !=
# outside us
return true
if or not
# ignore the event
return
acceptable = (dropTarget, dropTargetPos) =>
info.dropTarget = dropTarget
if
info.dropTargetPos = dropTargetPos
if == false
return false
else
return true
if not
# check axis
last_dim = null
= undefined
for el in CUI.dom.findElements(, )
if
el.classList.add("cui-droppable-target-helper")
# we only need to check the first two elements
# if we only have one we cannot determine the "axis" anyway
if != undefined
continue
dim = CUI.dom.getDimensions(el)
if last_dim
= null
if last_dim.viewportLeft == dim.viewportLeft
= "y"
if last_dim.viewportTop == dim.viewportTop
= "x"
last_dim = dim
if not
= "x"
= null
= null
= true
CUI.dom.removeClass(, )
if
= CUI.dom.closest(target, )
else
=
if not
if not acceptable()
if and not
# bubble
return true
return
=
= null
CUI.dom.addClass(, )
if
return
if not
if
console.info("Inside save zone...")
return
if
if not acceptable()
return
=
= null
else
console.info("No selected target, no dropHelper...")
# bubble
return true
return
CUI.dom.remove()
dim = CUI.dom.getDimensions()
if ( == "x" and coord.pageX > dim.viewportCenterLeft) or
( == "y" and coord.pageY > dim.viewportCenterTop)
dropTargetPos = "after"
else
dropTargetPos = "before"
dropTarget =
if not acceptable(dropTarget, dropTargetPos)
return
= dropTarget
= dropTargetPos
helper_cls = "cui-droppable-target-helper-"++"--"+
if == and .__target_helper_class == helper_cls
; # target helper is still ok
else
= [ CUI.dom.getDimensions() ]
.__target_helper_class = helper_cls
CUI.dom.addClass(, .__target_helper_class)
.push(CUI.dom.getDimensions())
=
return
init: ->
CUI.Events.listen
node:
type: "cui-dragend"
instance: @
call: (ev, info) =>
CUI.Events.listen
node:
type: "cui-drop"
instance: @
call: (ev, info) =>
if not
return
info.dropTarget =
if
info.dropTargetPos =
if != false
ev.stopPropagation()
CUI.setTimeout
call: =>
return
CUI.Events.listen
node:
type: ["cui-dragover", "cui-dragenter", "cui-dragleave"]
instance: @
call: (ev, info) =>
ev.stopPropagation()
return