Skip to content

Instantly share code, notes, and snippets.

@adjohu
Created October 15, 2011 21:44
Show Gist options
  • Save adjohu/1290196 to your computer and use it in GitHub Desktop.
Save adjohu/1290196 to your computer and use it in GitHub Desktop.
# Defaults
grid = [10,10]
container = "#container"
# Button types
buttons =
text :
html : '<div>
<div class="content">
Double click to edit me
</div>
</div>'
dblclick : ->
content_el = $(this).children('.content')
content = content_el.html()
# Make new instance of CKEditor -> remove current if exists.
editor = CKEDITOR.instances.editor
if editor?
editor.destroy()
$('#editor').ckeditor()
editor = CKEDITOR.instances.editor
# Add .edits content to ckeditor, add event handler to update .edit
editor.setData(content)
editor.on 'change', -> content_el.html editor.getData()
getValue : ->
$(this).children('.content').html()
layerTitle : ->
buttons.text.getValue.apply(@).substring(0,30)+"..."
image :
html : '<div>
<strong>Image will go here</strong>
</div>'
dblclick : ->
$("body").append('<div id="imageupload" style="display: none;"><input type="file" id="imageuploader" /></div>')
$.modal({
div: '#imageupload',
title: 'Image upload',
overlayClose: true
})
$("#imageupload").eq(0).remove()
$(this).children('strong, img').remove()
$.upload(this)
getValue : ->
'image'
layerTitle : ->
'Image'
background :
html: '<div></div>'
dblclick: ->
getValue : ->
layerTitle : ->
'Background'
# Edit object containing functions that will run on .edits
edit =
select : (el, calledByLayer = false) ->
#select the matching layer
layer.select( $(el).data('layer'), true ) if not calledByLayer
# This should be the only edit with class .current and only draggable .edit
$('.edit.current').removeClass('current').draggable 'disable'
$(el).addClass('current').draggable 'enable'
# Layer object containing functions to run on layers
layer =
select : (el, calledByEdit = false) ->
editEl = $(el).data 'el'
type = $(el).data 'type'
# Select matching .edit
edit.select(editEl, true) if not calledByEdit
# make this the selected layer
$('#layers .current').removeClass 'current'
$(el).addClass 'current'
# Display relevant properties panel
# also, populate it with the current properties
$('#properties input').each(->
$(this).val($(editEl).css $(this).attr('name'))
$(this).trigger('change')
)
$('#properties li').hide()
$('#properties_' + type).show()
# Updates the layer title
update : (el) ->
$this = $(el)
console.log $this.data()
title = buttons[$this.data 'type'].layerTitle.apply $this.data 'el'
$this.children('a').html(title)
setImageAttr = (el) ->
$(el).attr('alt')
# Arrange layers by z-index (highest at top)
orderLayers = ->
layers = $('#layers')
$('li', layers).sortElements (a,b) ->
$(b).data('z-index') - $(a).data('z-index')
###
Adds a layer to the layers panel and links the layer to the .edit and vice versa
@param htmlElement el - the .edit to link to the layer
###
addLayer = (el) ->
layers = $('#layers')
# Sort out z-index of edit
zIndex = parseInt( $(el).css('z-index') ,10)
zIndex = 0 if isNaN zIndex
# Add new layer
new_layer = $('<li />')
.data(
'el' : el
'type' : $(el).data 'type'
'z-index' : zIndex
)
.html('<a href="#">Layer</a>')
.click ->
layer.select(this)
layers.append new_layer
# Link this layer to the .edit
$(el).data(
'layer' : new_layer
)
layer.update new_layer
orderLayers()
observeEdits = ->
$('.edit:not(.ui-draggable)')
.append('<div class="gridline gridline_x"></div><div class="gridline gridline_y"></div>')
.mouseup ->
edit.select @
.dblclick ->
# get edit type (eg. text / img etc) and match against buttons to find dblclick function
buttons[$(@).data 'type'].dblclick.apply @
.draggable(
disabled : true
grid : grid
containment : container
# functions to run during drag events
start : (evt) ->
# show gridlines
$(this).children('.gridline').show()
drag : (evt, ui) ->
# Force draggable to stay on grid
ui.position.left -= ui.position.left % grid[0]
ui.position.top -= ui.position.top % grid[1]
stop : (evt) ->
# hide gridlines
$(this).children('.gridline').hide()
)
.resizable(
grid : grid
handles : 'n, e, s, w, ne, se, sw, nw '
containment : container
resize : (evt,ui) ->
# Force resize to stay on grid
ui.size.width -= ui.size.width % grid[0]
)
.each ->
type = @className.match(/edit_([^\s]*)/)[1]
$(@).data('type', type)
addLayer @
$ ->
observeEdits()
# key shortcuts
$(window).keyup (event) ->
current = $('.edit.current')
if event.keyCode is 46 and current.length > 0 # Delete key - delete current .edit
current.data('layer').remove()
current.remove()
# Button actions
$('.save').click ->
savePage()
return false
$('.newVar').click ->
variation(0)
return false
# Observe properties inputs to change css props on current selected .edit
$('#properties input')
.change ->
# Get property and value
prop = @.name
val = @.value
el = $('#layers .current').data('el')
$(el).css prop,val
.each ->
self = @
# make it a colorpicker
if this.name.indexOf 'color' > -1
$(this).ColorPicker(
onBeforeShow : ->
$(@).ColorPickerSetColor(@.value)
onChange : (hsb,hex,rgb) ->
console.log @
$(self).val("#" + hex).trigger 'change'
)
# Toolbox items can be dragged onto the container to create new
# text fields/ images / etc...
$('#toolbox a')
.draggable(
helper : 'clone'
)
# We will clone the 'helper' when we finish dragging
.bind 'dragstop', (event,ui) ->
# Find the position relative to the container
{left,top} = ui.position
left -= $(container).position().left
top -= $(container).position().top
# Find the button in the button object that matches this button
button_class = @className.match(/button_([^\s]*)/)[1]
button = buttons[button_class]
$(button.html)
.addClass('edit')
.addClass("edit_#{button_class}")
.appendTo(container)
.css
left : left
top : top
# Call observeEdits to make this act as one of the .edits
observeEdits()
# Make layers draggable and auto become draggable.
$('#layers').sortable(
axis : 'y'
update : (evt, ui) ->
# Order the edits by z-index consecutively.
layers = $('#layers > li')
layers.reverse()
layers.each (idx) ->
zidx = idx + 1
$(this).data 'z-index', zidx
$($(this).data 'el').css 'z-index', zidx
layer.update @
)
# Create a new variation
window.variation = (v) ->
editData = {
cid: id
vid: v
# Position data
width : $(container).width()
height : $(container).height()
}
$.post(
'/editor/ajax/variation/'
editData
(data) ->
window.vid = data
'text')
# Save action
window.savePage = ->
variation(vid)
$('.edit').each ->
$this = $(@)
pos = $this.position()
if $this.children('.content').length > 0
value = $this.children('.content').html()
else
value = $this.children('img')
randomcontainer = $('<div />')
value.clone().appendTo(randomcontainer)
value = randomcontainer.html()
editData = {
type: $this.data('type')
zindex: $this.attr('z-index')
id : $this.data('id')
vid : vid
# Position data
xPos : pos.left
yPos : pos.top
width : $this.width()
height : $this.height()
html : value
css : $this.attr('style')
}
$.post(
'/editor/ajax/save/'
editData
(data) ->
$this.data('id', data)
'text')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment