Merge pull request #7032 from erbunao/markdown_clipboard
Implements clipboard feature for markdown areas.
This commit is contained in:
commit
64b1956b0b
|
@ -1,6 +1,3 @@
|
|||
formatLink = (str) ->
|
||||
"![" + str.alt + "](" + str.url + ")"
|
||||
|
||||
$(document).ready ->
|
||||
alertClass = "alert alert-danger alert-dismissable div-dropzone-alert"
|
||||
alertAttr = "class=\"close\" data-dismiss=\"alert\"" + "aria-hidden=\"true\""
|
||||
|
@ -13,15 +10,12 @@ $(document).ready ->
|
|||
project_image_path_upload = window.project_image_path_upload or null
|
||||
|
||||
$("textarea.markdown-area").wrap "<div class=\"div-dropzone\"></div>"
|
||||
|
||||
$(".div-dropzone").parent().addClass "div-dropzone-wrapper"
|
||||
|
||||
$(".div-dropzone").append divHover
|
||||
$(".div-dropzone-hover").append iconPicture
|
||||
$(".div-dropzone").append divSpinner
|
||||
$(".div-dropzone-spinner").append iconSpinner
|
||||
|
||||
|
||||
dropzone = $(".div-dropzone").dropzone(
|
||||
url: project_image_path_upload
|
||||
dictDefaultMessage: ""
|
||||
|
@ -36,7 +30,7 @@ $(document).ready ->
|
|||
previewContainer: false
|
||||
|
||||
processing: ->
|
||||
$(".div-dropzone-alert").alert "close"
|
||||
closeAlertMessage()
|
||||
|
||||
dragover: ->
|
||||
$(".div-dropzone > textarea").addClass "div-dropzone-focus"
|
||||
|
@ -55,31 +49,127 @@ $(document).ready ->
|
|||
return
|
||||
|
||||
success: (header, response) ->
|
||||
child = $(dropzone[0]).children("textarea")
|
||||
$(child).val $(child).val() + formatLink(response.link) + "\n"
|
||||
appendToTextArea(formatLink(response.link))
|
||||
return
|
||||
|
||||
error: (temp, errorMessage) ->
|
||||
checkIfMsgExists = $(".error-alert").children().length
|
||||
if checkIfMsgExists is 0
|
||||
$(".error-alert").append divAlert
|
||||
$(".div-dropzone-alert").append btnAlert + errorMessage
|
||||
showError(errorMessage)
|
||||
return
|
||||
|
||||
sending: ->
|
||||
$(".div-dropzone-spinner").css "opacity", 0.7
|
||||
showSpinner()
|
||||
return
|
||||
|
||||
complete: ->
|
||||
$(".dz-preview").remove()
|
||||
$(".markdown-area").trigger "input"
|
||||
$(".div-dropzone-spinner").css "opacity", 0
|
||||
closeSpinner()
|
||||
return
|
||||
)
|
||||
|
||||
child = $(dropzone[0]).children("textarea")
|
||||
|
||||
formatLink = (str) ->
|
||||
"![" + str.alt + "](" + str.url + ")"
|
||||
|
||||
handlePaste = (e) ->
|
||||
e.preventDefault()
|
||||
my_event = e.originalEvent
|
||||
|
||||
if my_event.clipboardData and my_event.clipboardData.items
|
||||
i = 0
|
||||
while i < my_event.clipboardData.items.length
|
||||
item = my_event.clipboardData.items[i]
|
||||
processItem(my_event, item)
|
||||
i++
|
||||
|
||||
processItem = (e, item) ->
|
||||
if isImage(item)
|
||||
filename = getFilename(e) or "image.png"
|
||||
text = "{{" + filename + "}}"
|
||||
pasteText(text)
|
||||
uploadFile item.getAsFile(), filename
|
||||
else if e.clipboardData.items.length == 1
|
||||
text = e.clipboardData.getData("text/plain")
|
||||
pasteText(text)
|
||||
|
||||
isImage = (item) ->
|
||||
if item
|
||||
item.type.indexOf("image") isnt -1
|
||||
|
||||
pasteText = (text) ->
|
||||
caretStart = $(child)[0].selectionStart
|
||||
caretEnd = $(child)[0].selectionEnd
|
||||
textEnd = $(child).val().length
|
||||
|
||||
beforeSelection = $(child).val().substring 0, caretStart
|
||||
afterSelection = $(child).val().substring caretEnd, textEnd
|
||||
$(child).val beforeSelection + text + afterSelection
|
||||
$(".markdown-area").trigger "input"
|
||||
|
||||
getFilename = (e) ->
|
||||
if window.clipboardData and window.clipboardData.getData
|
||||
value = window.clipboardData.getData("Text")
|
||||
else if e.clipboardData and e.clipboardData.getData
|
||||
value = e.clipboardData.getData("text/plain")
|
||||
|
||||
value = value.split("\r")
|
||||
value.first()
|
||||
|
||||
uploadFile = (item, filename) ->
|
||||
formData = new FormData()
|
||||
formData.append "markdown_img", item, filename
|
||||
$.ajax
|
||||
url: project_image_path_upload
|
||||
type: "POST"
|
||||
data: formData
|
||||
dataType: "json"
|
||||
processData: false
|
||||
contentType: false
|
||||
headers:
|
||||
"X-CSRF-Token": $("meta[name=\"csrf-token\"]").attr("content")
|
||||
|
||||
beforeSend: ->
|
||||
showSpinner()
|
||||
closeAlertMessage()
|
||||
|
||||
success: (e, textStatus, response) ->
|
||||
insertToTextArea(filename, formatLink(response.responseJSON.link))
|
||||
|
||||
error: (response) ->
|
||||
showError(response.responseJSON.message)
|
||||
|
||||
complete: ->
|
||||
closeSpinner()
|
||||
|
||||
insertToTextArea = (filename, url) ->
|
||||
$(child).val (index, val) ->
|
||||
val.replace("{{" + filename + "}}", url + "\n")
|
||||
|
||||
appendToTextArea = (url) ->
|
||||
$(child).val (index, val) ->
|
||||
val + url + "\n"
|
||||
|
||||
showSpinner = (e) ->
|
||||
$(".div-dropzone-spinner").css "opacity", 0.7
|
||||
|
||||
closeSpinner = ->
|
||||
$(".div-dropzone-spinner").css "opacity", 0
|
||||
|
||||
showError = (message) ->
|
||||
checkIfMsgExists = $(".error-alert").children().length
|
||||
if checkIfMsgExists is 0
|
||||
$(".error-alert").append divAlert
|
||||
$(".div-dropzone-alert").append btnAlert + message
|
||||
|
||||
closeAlertMessage = ->
|
||||
$(".div-dropzone-alert").alert "close"
|
||||
|
||||
$(".markdown-selector").click (e) ->
|
||||
e.preventDefault()
|
||||
$(".div-dropzone").click()
|
||||
return
|
||||
|
||||
$(".div-dropzone").on "paste", handlePaste
|
||||
|
||||
return
|
|
@ -43,6 +43,11 @@
|
|||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.hint {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.div-dropzone-alert {
|
||||
|
|
|
@ -11,6 +11,8 @@ class ProjectsController < ApplicationController
|
|||
layout 'navless', only: [:new, :create, :fork]
|
||||
before_filter :set_title, only: [:new, :create]
|
||||
|
||||
rescue_from CarrierWave::IntegrityError, with: :invalid_file
|
||||
|
||||
def new
|
||||
@project = Project.new
|
||||
end
|
||||
|
@ -185,6 +187,10 @@ class ProjectsController < ApplicationController
|
|||
%w(png jpg jpeg gif)
|
||||
end
|
||||
|
||||
def invalid_file(error)
|
||||
render json: { message: error.message }, status: :internal_server_error
|
||||
end
|
||||
|
||||
def set_title
|
||||
@title = 'New Project'
|
||||
end
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
= f.text_area :description, class: 'form-control js-gfm-input markdown-area', rows: 14
|
||||
.col-sm-12.hint
|
||||
.pull-left Issues are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
|
||||
.pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
|
||||
.pull-right Attach images (JPG, PNG, GIF) by dragging & dropping, #{link_to "selecting them", '#', class: 'markdown-selector' } or pasting from the clipboard.
|
||||
.clearfix
|
||||
.error-alert
|
||||
%hr
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
= f.text_area :description, class: "form-control js-gfm-input markdown-area", rows: 14
|
||||
.col-sm-12.hint
|
||||
.pull-left Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
|
||||
.pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
|
||||
.pull-right Attach images (JPG, PNG, GIF) by dragging & dropping, #{link_to "selecting them", '#', class: 'markdown-selector' } or pasting from the clipboard.
|
||||
|
||||
.clearfix
|
||||
.error-alert
|
||||
%hr
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
= f.text_area :description, class: "form-control js-gfm-input markdown-area", rows: 10
|
||||
.col-sm-12.hint
|
||||
.pull-left Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
|
||||
.pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
|
||||
.pull-right Attach images (JPG, PNG, GIF) by dragging & dropping, #{link_to "selecting them", '#', class: 'markdown-selector' } or pasting from the clipboard.
|
||||
|
||||
.clearfix
|
||||
.error-alert
|
||||
.form-group
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
= f.text_area :description, maxlength: 2000, class: "form-control markdown-area", rows: 10
|
||||
.hint
|
||||
.pull-left Milestones are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
|
||||
.pull-left Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
|
||||
.pull-left Attach images (JPG, PNG, GIF) by dragging & dropping, #{link_to "selecting them", '#', class: 'markdown-selector' } or pasting from the clipboard.
|
||||
.clearfix
|
||||
.error-alert
|
||||
.col-md-6
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
.note-write-holder
|
||||
= f.text_area :note, size: 255, class: 'note_text js-note-text js-gfm-input markdown-area'
|
||||
|
||||
.light.clearfix
|
||||
.light.clearfix.hint
|
||||
.pull-left Comments are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
|
||||
.pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
|
||||
|
||||
.pull-right Attach images (JPG, PNG, GIF) by dragging & dropping, #{link_to "selecting them", '#', class: 'markdown-selector' } or pasting from the clipboard.
|
||||
.error-alert
|
||||
.note-preview-holder.hide
|
||||
.js-note-preview
|
||||
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
= f.text_area :content, class: 'form-control js-gfm-input markdown-area', rows: 18
|
||||
.col-sm-12.hint
|
||||
.pull-left Wiki content is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
|
||||
.pull-right Attach images (JPG, PNG, GIF) by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }.
|
||||
.pull-right Attach images (JPG, PNG, GIF) by dragging & dropping, #{link_to "selecting them", '#', class: 'markdown-selector' } or pasting from the clipboard.
|
||||
|
||||
.clearfix
|
||||
.error-alert
|
||||
.form-group
|
||||
|
|
Loading…
Reference in New Issue