Commit 2273234653924b731f9ef01432e392481ee1d4e2

Authored by erbunao
1 parent 6bd114a7

Implements and refactors clipboard feature for markdown.

app/assets/javascripts/markdown_area.js.coffee
1   -formatLink = (str) ->
2   - "![" + str.alt + "](" + str.url + ")"
3   -
4 1 $(document).ready ->
5 2 alertClass = "alert alert-danger alert-dismissable div-dropzone-alert"
6 3 alertAttr = "class=\"close\" data-dismiss=\"alert\"" + "aria-hidden=\"true\""
... ... @@ -13,15 +10,12 @@ $(document).ready ->
13 10 project_image_path_upload = window.project_image_path_upload or null
14 11  
15 12 $("textarea.markdown-area").wrap "<div class=\"div-dropzone\"></div>"
16   -
17 13 $(".div-dropzone").parent().addClass "div-dropzone-wrapper"
18   -
19 14 $(".div-dropzone").append divHover
20 15 $(".div-dropzone-hover").append iconPicture
21 16 $(".div-dropzone").append divSpinner
22 17 $(".div-dropzone-spinner").append iconSpinner
23 18  
24   -
25 19 dropzone = $(".div-dropzone").dropzone(
26 20 url: project_image_path_upload
27 21 dictDefaultMessage: ""
... ... @@ -36,7 +30,7 @@ $(document).ready -&gt;
36 30 previewContainer: false
37 31  
38 32 processing: ->
39   - $(".div-dropzone-alert").alert "close"
  33 + closeAlertMessage()
40 34  
41 35 dragover: ->
42 36 $(".div-dropzone > textarea").addClass "div-dropzone-focus"
... ... @@ -55,31 +49,127 @@ $(document).ready -&gt;
55 49 return
56 50  
57 51 success: (header, response) ->
58   - child = $(dropzone[0]).children("textarea")
59   - $(child).val $(child).val() + formatLink(response.link) + "\n"
  52 + appendToTextArea(formatLink(response.link))
60 53 return
61 54  
62 55 error: (temp, errorMessage) ->
63   - checkIfMsgExists = $(".error-alert").children().length
64   - if checkIfMsgExists is 0
65   - $(".error-alert").append divAlert
66   - $(".div-dropzone-alert").append btnAlert + errorMessage
  56 + showError(errorMessage)
67 57 return
68 58  
69 59 sending: ->
70   - $(".div-dropzone-spinner").css "opacity", 0.7
  60 + showSpinner()
71 61 return
72 62  
73 63 complete: ->
74 64 $(".dz-preview").remove()
75 65 $(".markdown-area").trigger "input"
76   - $(".div-dropzone-spinner").css "opacity", 0
  66 + closeSpinner()
77 67 return
78 68 )
79 69  
  70 + child = $(dropzone[0]).children("textarea")
  71 +
  72 + formatLink = (str) ->
  73 + "![" + str.alt + "](" + str.url + ")"
  74 +
  75 + handlePaste = (e) ->
  76 + e.preventDefault()
  77 + my_event = e.originalEvent
  78 +
  79 + if my_event.clipboardData and my_event.clipboardData.items
  80 + i = 0
  81 + while i < my_event.clipboardData.items.length
  82 + item = my_event.clipboardData.items[i]
  83 + processItem(my_event, item)
  84 + i++
  85 +
  86 + processItem = (e, item) ->
  87 + if isImage(item)
  88 + filename = getFilename(e) or "image.png"
  89 + text = "{{" + filename + "}}"
  90 + pasteText(text)
  91 + uploadFile item.getAsFile(), filename
  92 + else if e.clipboardData.items.length == 1
  93 + text = e.clipboardData.getData("text/plain")
  94 + pasteText(text)
  95 +
  96 + isImage = (item) ->
  97 + if item
  98 + item.type.indexOf("image") isnt -1
  99 +
  100 + pasteText = (text) ->
  101 + caretStart = $(child)[0].selectionStart
  102 + caretEnd = $(child)[0].selectionEnd
  103 + textEnd = $(child).val().length
  104 +
  105 + beforeSelection = $(child).val().substring 0, caretStart
  106 + afterSelection = $(child).val().substring caretEnd, textEnd
  107 + $(child).val beforeSelection + text + afterSelection
  108 + $(".markdown-area").trigger "input"
  109 +
  110 + getFilename = (e) ->
  111 + if window.clipboardData and window.clipboardData.getData
  112 + value = window.clipboardData.getData("Text")
  113 + else if e.clipboardData and e.clipboardData.getData
  114 + value = e.clipboardData.getData("text/plain")
  115 +
  116 + value = value.split("\r")
  117 + value.first()
  118 +
  119 + uploadFile = (item, filename) ->
  120 + formData = new FormData()
  121 + formData.append "markdown_img", item, filename
  122 + $.ajax
  123 + url: project_image_path_upload
  124 + type: "POST"
  125 + data: formData
  126 + dataType: "json"
  127 + processData: false
  128 + contentType: false
  129 + headers:
  130 + "X-CSRF-Token": $("meta[name=\"csrf-token\"]").attr("content")
  131 +
  132 + beforeSend: ->
  133 + showSpinner()
  134 + closeAlertMessage()
  135 +
  136 + success: (e, textStatus, response) ->
  137 + insertToTextArea(filename, formatLink(response.responseJSON.link))
  138 +
  139 + error: (response) ->
  140 + showError(response.responseJSON.message)
  141 +
  142 + complete: ->
  143 + closeSpinner()
  144 +
  145 + insertToTextArea = (filename, url) ->
  146 + $(child).val (index, val) ->
  147 + val.replace("{{" + filename + "}}", url + "\n")
  148 +
  149 + appendToTextArea = (url) ->
  150 + $(child).val (index, val) ->
  151 + val + url + "\n"
  152 +
  153 + showSpinner = (e) ->
  154 + $(".div-dropzone-spinner").css "opacity", 0.7
  155 +
  156 + closeSpinner = ->
  157 + $(".div-dropzone-spinner").css "opacity", 0
  158 +
  159 + showError = (message) ->
  160 + checkIfMsgExists = $(".error-alert").children().length
  161 + if checkIfMsgExists is 0
  162 + $(".error-alert").append divAlert
  163 + $(".div-dropzone-alert").append btnAlert + message
  164 +
  165 + closeAlertMessage = ->
  166 + $(".div-dropzone-alert").alert "close"
  167 +
80 168 $(".markdown-selector").click (e) ->
81 169 e.preventDefault()
82 170 $(".div-dropzone").click()
83 171 return
84 172  
  173 + $(".div-dropzone").on "paste", handlePaste
  174 +
85 175 return
86 176 \ No newline at end of file
... ...
app/assets/stylesheets/generic/markdown_area.scss
... ... @@ -43,6 +43,11 @@
43 43 display: none;
44 44 }
45 45 }
  46 +
  47 + .hint {
  48 + padding: 0;
  49 + margin: 0;
  50 + }
46 51 }
47 52  
48 53 .div-dropzone-alert {
... ...
app/controllers/projects_controller.rb
... ... @@ -11,6 +11,8 @@ class ProjectsController &lt; ApplicationController
11 11 layout 'navless', only: [:new, :create, :fork]
12 12 before_filter :set_title, only: [:new, :create]
13 13  
  14 + rescue_from CarrierWave::IntegrityError, with: :invalid_file
  15 +
14 16 def new
15 17 @project = Project.new
16 18 end
... ... @@ -185,6 +187,10 @@ class ProjectsController &lt; ApplicationController
185 187 %w(png jpg jpeg gif)
186 188 end
187 189  
  190 + def invalid_file(error)
  191 + render json: { message: error.message }, status: :internal_server_error
  192 + end
  193 +
188 194 def set_title
189 195 @title = 'New Project'
190 196 end
... ...
app/views/projects/issues/_form.html.haml
... ... @@ -23,7 +23,7 @@
23 23 = f.text_area :description, class: 'form-control js-gfm-input markdown-area', rows: 14
24 24 .col-sm-12.hint
25 25 .pull-left Issues are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
26   - .pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
  26 + .pull-right Attach images (JPG, PNG, GIF) by dragging & dropping, #{link_to "selecting them", '#', class: 'markdown-selector' } or pasting from the clipboard.
27 27 .clearfix
28 28 .error-alert
29 29 %hr
... ...
app/views/projects/merge_requests/_form.html.haml
... ... @@ -25,7 +25,8 @@
25 25 = f.text_area :description, class: "form-control js-gfm-input markdown-area", rows: 14
26 26 .col-sm-12.hint
27 27 .pull-left Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
28   - .pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
  28 + .pull-right Attach images (JPG, PNG, GIF) by dragging & dropping, #{link_to "selecting them", '#', class: 'markdown-selector' } or pasting from the clipboard.
  29 +
29 30 .clearfix
30 31 .error-alert
31 32 %hr
... ...
app/views/projects/merge_requests/_new_submit.html.haml
... ... @@ -26,7 +26,8 @@
26 26 = f.text_area :description, class: "form-control js-gfm-input markdown-area", rows: 10
27 27 .col-sm-12.hint
28 28 .pull-left Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
29   - .pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
  29 + .pull-right Attach images (JPG, PNG, GIF) by dragging & dropping, #{link_to "selecting them", '#', class: 'markdown-selector' } or pasting from the clipboard.
  30 +
30 31 .clearfix
31 32 .error-alert
32 33 .form-group
... ...
app/views/projects/milestones/_form.html.haml
... ... @@ -24,7 +24,7 @@
24 24 = f.text_area :description, maxlength: 2000, class: "form-control markdown-area", rows: 10
25 25 .hint
26 26 .pull-left Milestones are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
27   - .pull-left Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
  27 + .pull-left Attach images (JPG, PNG, GIF) by dragging & dropping, #{link_to "selecting them", '#', class: 'markdown-selector' } or pasting from the clipboard.
28 28 .clearfix
29 29 .error-alert
30 30 .col-md-6
... ...
app/views/projects/notes/_form.html.haml
... ... @@ -16,10 +16,10 @@
16 16 .note-write-holder
17 17 = f.text_area :note, size: 255, class: 'note_text js-note-text js-gfm-input markdown-area'
18 18  
19   - .light.clearfix
  19 + .light.clearfix.hint
20 20 .pull-left Comments are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
21   - .pull-right Attach images (JPG, PNG, GIF) by dragging &amp; dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
22   -
  21 + .pull-right Attach images (JPG, PNG, GIF) by dragging & dropping, #{link_to "selecting them", '#', class: 'markdown-selector' } or pasting from the clipboard.
  22 + .error-alert
23 23 .note-preview-holder.hide
24 24 .js-note-preview
25 25  
... ...
app/views/projects/wikis/_form.html.haml
... ... @@ -25,7 +25,8 @@
25 25 = f.text_area :content, class: 'form-control js-gfm-input markdown-area', rows: 18
26 26 .col-sm-12.hint
27 27 .pull-left Wiki content is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
28   - .pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
  28 + .pull-right Attach images (JPG, PNG, GIF) by dragging & dropping, #{link_to "selecting them", '#', class: 'markdown-selector' } or pasting from the clipboard.
  29 +
29 30 .clearfix
30 31 .error-alert
31 32 .form-group
... ...