#http://www.kryogenix.org/code/browser/custom-drag-image.html #http://www.html5rocks.com/en/tutorials/dnd/basics/#toc-examples class window.Editor extends Backbone.View el: '#chaskiq-mail-editor' events: -> 'keyup .note-editable': 'copyToFocusedElement' 'drag .blocks li a' : 'drag' "click #editor-controls #save" : "saveAndClose" #propery changer "changeColor.colorpicker .colorpicker": "changeColor" "change .text-size-picker": "changeProperty" "change .font-picker": "changeProperty" "change .font-weight": "changeProperty" "change .font-spacing": "changeProperty" "change .font-align": "changeProperty" #"submit form" : "submitEditor" #get recursion! "click input.submit": "submitEditor" initialize: -> @textarea = $(@el).find('#campaign_html_content') @css = $(@el).find('#campaign_css') window.current_editor = @ @placeholder = null @files = [] setIframe: (iframe)-> @iframe = iframe copyToEditor: (ev)-> $this = $(ev.currentTarget); window.setTimeout ()=> $(@iframe.el).find('#mail-editor').html($this.val()); , 0 buildOptionsFromStyles: ()-> @renderBlockDesignSettings() copyToTextArea: ()-> $this = $(@iframe.el).find("#mail-editor") window.setTimeout ()=> $(@el).find('#campaign_html_content').val($this.html()); , 0 copyToFocusedElement: (ev)-> @currentFocused().find('.mcnTextContent').html($(ev.currentTarget).html()) @copyToTextArea() copyCssRulesToTextArea: ()-> rules = _.map @style().cssRules , (rule)-> rule.cssText $("#campaign_css").val(rules.join(" ")) submitEditor: (ev)-> @removeTplBlockControls() @copyToTextArea() @copyCssRulesToTextArea() setTimeout -> $(ev.currentTarget).submit() , 600 template: -> '

dsfsd

' render: -> document.getElementById("editor-frame").onload = ()=> #iframe loaded @iframe = $("#editor-frame")[0].contentWindow.iframe #@buildOptionsFromStyles() $("#tab-2").html(@baseStylesTemplate("accordeon", @definitionsForEditor())) $('.colorpicker').colorpicker(); if _.isEmpty(@textarea.val()) $(@iframe.el).find('#mail-editor').html(@baseTemplate()) else $(@iframe.el).find('#mail-editor').html(@textarea.val()); #init from saved content #$(@el).find('#mail-editor').html(@baseTemplate()) #init from base js tamplarte #$("#tab-2").html(@baseStylesTemplate("accordeon", @definitionsForEditor())) #@removeTplBlockControls() #for legacy already embeded tmp controls #@addTplBlockControls() removeTplBlockControls: -> $(".tpl-block-controls").remove() addTplBlockControls: -> _.each $(".chaskiqBlock.tpl-block"), (n)=> $(n).append(@templateBlockControls()) displaySections: (ev)-> #console.log($(ev.currentTarget)) #console.log($(ev.currentTarget).hasClass("tpl-container")) container = $(ev.currentTarget).parent(".tpl-container") #_.each $('.tpl-container'), (n)-> # return if $(n).find(".legend").length > 0 # #debugger # #$(n).append("
#{$(n).attr("mc:container")}
") container.append("
#{$(container).attr("mc:container")}
") container.addClass("default") if container.hasClass("tpl-container") container.addClass("over").removeClass("default") container.find(".legend").addClass("over").removeClass("default") ev.preventDefault() setDraggedEl: (e)-> @crt = $(e.currentTarget).parents(".tpl-block")[0].cloneNode(true) #.clone() @crt.style.backgroundColor = "white"; @crt.style.position = "absolute"; @crt.style.border = "1px solid #666"; @crt.style.boxShadow = "1px 2px 2px #adadad" @crt.style.top = "0px"; @crt.style.right = "0px"; @crt.style.opacity = 0.9; @crt.style.zIndex = -9999; document.body.appendChild(@crt); e.dataTransfer = e.originalEvent.dataTransfer; e.dataTransfer.setDragImage(@crt, 0, 0); removeDraggedEl: -> $(@crt).remove() displayItemOver: (ev)-> @displaySections(ev) $('.tpl-block').removeClass("chaskiqDndItemBefore") if $(ev.currentTarget).hasClass("tpl-block") $(ev.currentTarget).addClass("chaskiqDndItemBefore") ev.preventDefault() hideSections: ()-> $('.tpl-container').removeClass("default").removeClass("over") _.each $('.tpl-container'), (n)-> $(n).find(".legend").remove() drag: (ev)-> #console.log(ev.currentTarget) @dragged = $(ev.currentTarget) allowDrop: (ev)-> #console.log("allos drop") ev.preventDefault() displayEmptyBlocks: -> _.each $('.tpl-container'), (container)-> empty_message = $(container).find('.chaskiqContainerEmptyMessage') if $(container).find(".tpl-block").length > 0 empty_message.hide() else empty_message.show() dropBlock: (container, tmpl)-> #drop on before item or in tpl-container if $(".tpl-block.chaskiqDndItemBefore").length > 0 container.find(".tpl-block.chaskiqDndItemBefore").before(tmpl) container.find('.chaskiqContainerEmptyMessage').hide() else container.find(".tpl-container").append(tmpl) #container.find('.chaskiqContainerEmptyMessage').hide() releaseBeforeItem: ()-> $(".tpl-block").removeClass("chaskiqDndItemBefore") displayWysiwyg: -> $('.block-settings').show() $('.main-settings').hide() @initWysiwyg() false displayBlockButtons: -> $('.block-settings').hide() $('.main-settings').show() false saveAndClose: -> @copyToTextArea() @displayBlockButtons() false currentFocused: ()-> $(@.iframe.el).find(".tpl-block.focus") initWysiwyg: -> $('.summernote').destroy() InitSummernote() $('.summernote').code(@currentFocused().find('.mcnTextContent').html()); handleBlock: (block_type)-> html = "" switch block_type when "boxed" html = @boxedBlock() when "text" html = @textBlock() when "separator" html = @separatorBlock() when "image" html = @imageBlock() when "image_group" html = @imageGroupBlock() when "image_card" html = @imageCardBlock() else console.log "Nada" @wrapBlock(html) deleteBloc: (ev)-> target = $(ev.currentTarget) container = target.parents(".tpl-container") target.parents(".tpl-block").remove() if container.find(".tpl-block").length is 0 container.find(".chaskiqContainerEmptyMessage").show() false emptyContainerMessage: ()-> "
Drop Content Blocks Here
" wrapBlock: (content)-> "
#{content}
#{@templateBlockControls()}
" templateBlockControls: -> "
" baseTemplate: ()-> "
#{@emptyContainerMessage()}
#{@emptyContainerMessage()}
#{@emptyContainerMessage()}
#{@emptyContainerMessage()} #{@wrapBlock(@subscriptionBlock())}
" boxedBlock: ()-> "
This is a Text Block. Use this to provide text...
" textBlock: ()-> "
This is a Text Block. Use this to provide text...
" separatorBlock: ()-> "
" imageBlock: ()-> "
Drop an image here
or
" imageGroupBlock: ()-> "
Drop an image here
or
Drop an image here
or
" imageCardBlock: ()-> "
Drop an image here
or
Your text caption goes here
" subscriptionBlock: ()-> "
© {{campaign_description}}

Our mailing address is:
{{campaign_url}}

unsubscribe from this list    update subscription preferences 

" listenerForImagesReplace: ()-> $('.image-selector').on "click", ()-> html = current_editor.placeholder.parents(".mcpreview-image-uploader") url = $(this).data('image-url') current_editor.replaceImagePreview(html, url ) false checkExistentImages: (placeholder)-> #@targetForUpload = $(ev.currentTarget) $.ajax url: $("#editor-container").data("attachments-path") dataType: "json" success: (data)=> Chaskiq.Helpers.showModal(@templateForAttachments(data), "dsdsda") @placeholder = placeholder @listenerForImagesReplace() $('#myModal input[type=file]').on 'change', @prepareUpload $('#myModal #upload-form').on 'submit', @uploadFiles error: (err)-> alert("error retrieving files") replaceImagePreview: (html_to_replace, url)-> html_to_replace.replaceWith( "" ); Chaskiq.Helpers.hideModal() @copyToTextArea() templateforUploader: -> "
" templateForAttachments: (data)-> html = @templateforUploader() html += "" appendImageToAttachmentList: (data)-> $("#myModal .attachments-modal-list").prepend("
  • Select
  • ") @listenerForImagesReplace() fileUploader: -> # Catch the form submit and upload the files prepareUpload: (event) -> window.current_editor.files = event.target.files return uploadFiles: (event) -> console.log("upload upload!") event.stopPropagation() # Stop stuff happening event.preventDefault() # Totally stop stuff happening # START A LOADING SPINNER HERE # Create a formdata object and add the files data = new FormData $.each window.current_editor.files, (key, value) -> #data.append key, value data.append "attachment[image]", value return $.ajax url: $("#editor-container").data("attachments-path") type: 'POST' data: data cache: false dataType: 'json' processData: false contentType: false success: (data, textStatus, jqXHR) -> if typeof data.error == 'undefined' # Success so call function to process the form # submitForm event, data current_editor.appendImageToAttachmentList(data) else # Handle errors here console.log 'ERRORS: ' + data.error return error: (jqXHR, textStatus, errorThrown) -> # Handle errors here console.log 'ERRORS: ' + textStatus # STOP LOADING SPINNER return return defaultStyleSheet: -> @iframe.findStyleSheet() style: -> @defaultStyleSheet() definitionsForEditor: -> [ {name: "Page", targets: [ {name: "Background", selector: "#bodyTable", template: "background", namespace: "Content"}, {name: "Text", selector: "#bodyTable", template: "typography", namespace: "Content"} ] } {name: "Preheader", targets: [{name: "background", selector: "#templatePreheader", template: "background", namespace: "Content"}, {name: "Text", selector: "#templatePreHeader", template: "typography", namespace: "Content"}, {name: "h1", selector: "#templatePreHeader h1", template: "typography", namespace: "Content"}, {name: "h2", selector: "#templatePreHeader h2", template: "typography", namespace: "Content"}]} {name: "Header", targets: [{name: "Header background", selector: "#templateHeader", template: "background"} ]} {name: "Body", targets: [{name: "body background", selector: "#templateBody", template: "background", namespace: "Content"} , {name: "font", selector: ".bodyContainer .mcnTextContent", template: "typography", namespace: "Content"} {name: "links", selector: ".bodyContainer .mcnTextContent a", template: "typography", namespace: "Content"} ]} {name: "Footer", targets: [{name: "background",selector: "#templateFooter", template: "background", namespace: "Content"}, {name: "font", selector: ".footerContainer .mcnTextContent, .footerContainer .mcnTextContent p", template: "typography", namespace: "Content"} ]} {name: "Columns", targets: []} ] definitionsForBlocks: -> [ {name: "mcnBaseTemplate", targets: []} {name: "mcnBoxedText", targets: [ {name: "background", selector: ".mcnTextContentContainer", template: "background", namespace: "Content"}, {name: "font", selector: ".mcnTextContentContainer", template: "typography", namespace: "Content"} ]} {name: "mcnText", targets: [ {name: "background", selector: "", template: "background", namespace: "Content"}, {name: "font", selector: "", template: "typography", namespace: "Content"}, {name: "heading 1", selector: "h1", template: "typography", namespace: "Content"} , {name: "heading 2", selector: "h2", template: "typography", namespace: "Content"} , {name: "page links", selector: "a", template: "typography", namespace: "Content"} ]} {name: "mcnDivider", targets: []} {name: "mcnImage", targets: []} {name: "mcnImageGroup", targets: [ {name: "background", selector: "", template: "background", namespace: "BlockInner"}, ]} {name: "mcnImageCard", targets: [ {name: "background", selector: "", template: "background" , namespace: "BottomContent"}, {name: "font", selector: "", template: "typography", namespace: "BottomContent"} ]} {name: "mcnSubscription", targets: []} ] renderBlockDesignSettings: -> try $('.colorpicker').colorpicker('destroy') catch e console.log(e) focused = @currentFocused().find("table:first").attr("class") section = _.find editor.definitionsForBlocks(), (n)=> "#{n.name}Block" == focused console.log("section #{focused}" ) if section console.log("display for #{focused}") @current_section = section html = @buildDesignToolForTarget(section) $("#tab-4").html(html) $('.colorpicker').colorpicker(); #$('.colorpicker').colorpicker('destroy') #size, align, fonttype, color, weight, line heigh, letter spacing baseStylesTemplate: (id, definitions)-> "
    #{@colapsiblePanelsFor( id, definitions )}
    " colapsiblePanelsFor: (id, style_types)-> tpl = _.map style_types, (n)=> "

    #{n.name}

    #{@buildDesignToolForTarget(n)}

    " tpl.join(" ") buildDesignToolForTarget: (section)-> tpl = _.map section.targets, (n)=> @templateToolsFor(n , section.name) "
    #{tpl.join(" ")}
    " templateToolsFor: (n, parent_name)-> title = "

    #{n.name}

    " tools = "" switch n.template when "background" tools = @backgroundFieldsFor(n, parent_name) when "typography" tools = @typoFieldsFor(n, parent_name) [title, tools].join(" ") rgb2hex: (rgb)-> return if _.isUndefined(rgb) rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i); return if (rgb && rgb.length is 4) "#" + ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) + ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) + ("0" + parseInt(rgb[3],10).toString(16)).slice(-2) else '' #dry this changeColor: (ev)-> target = $(ev.currentTarget) css = target.data('css') property = target.data('css-property') value = @rgb2hex(ev.color.toString()) console.log "changing from #{css}, #{property} #{value}" if css.length > 0 @iframe.modifyRule(css, property, value) else @currentFocused() .find("table:first") .find(".#{@current_section.name}#{target.data('namespace')}") .css(property, value) changeProperty: (ev)-> target = $(ev.currentTarget) css = target.data('css') property = target.data('css-property') value = target.val() console.log "changing from #{css}, #{property} #{value}" if css.length > 0 @iframe.modifyRule(css, property, value) else editor.currentFocused() .find("table:first") .find(".#{@current_section.name}#{target.data('namespace')}") .css(property, value) arrayGen: (n)-> Array.apply(null, length: n).map Number.call, Number styleforSelector: (target, style_selector, parent_name)-> val = if !target.selector then @currentFocused().find(".#{parent_name}#{target.namespace}") else @.iframe.$el.find(target.selector) o = val.css(style_selector) #console.log o o backgroundFieldsFor: (target, parent_name)-> style_selector = "background-color" val = @styleforSelector(target, style_selector, parent_name) val = @rgb2hex(val) [""].join(" ") #border style, width, color typoFieldsFor: (target, parent_name)-> c = @styleforSelector(target, 'color', parent_name) color = "
    " sizeFont = "
    " ff = @styleforSelector(target, 'font-family', parent_name) familyFont = "
    " weight = "
    " #styleFont #weightline #heightletter spacingtext = "
    " align = "
    " [color, sizeFont, familyFont, weight, spacingtext, align].join(" ")