Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
gitlab-ce
Commits
1bba9700
Commit
1bba9700
authored
Oct 19, 2017
by
Filipa Lacerda
Committed by
Winnie Hellmann
Oct 21, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove dropzoneInput from global namespace
parent
0a7ca618
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
269 additions
and
309 deletions
+269
-309
app/assets/javascripts/blob/blob_file_dropzone.js
app/assets/javascripts/blob/blob_file_dropzone.js
+1
-2
app/assets/javascripts/dropzone_input.js
app/assets/javascripts/dropzone_input.js
+265
-297
app/assets/javascripts/gl_form.js
app/assets/javascripts/gl_form.js
+2
-2
app/assets/javascripts/notes.js
app/assets/javascripts/notes.js
+0
-3
app/assets/javascripts/zen_mode.js
app/assets/javascripts/zen_mode.js
+0
-2
spec/javascripts/blob/blob_file_dropzone_spec.js
spec/javascripts/blob/blob_file_dropzone_spec.js
+0
-1
spec/javascripts/zen_mode_spec.js
spec/javascripts/zen_mode_spec.js
+1
-2
No files found.
app/assets/javascripts/blob/blob_file_dropzone.js
View file @
1bba9700
/* eslint-disable func-names, object-shorthand, prefer-arrow-callback */
/* global Dropzone */
import
Dropzone
from
'
dropzone
'
;
import
'
../lib/utils/url_utility
'
;
import
{
HIDDEN_CLASS
}
from
'
../lib/utils/constants
'
;
import
csrf
from
'
../lib/utils/csrf
'
;
...
...
app/assets/javascripts/dropzone_input.js
View file @
1bba9700
/* eslint-disable func-names, space-before-function-paren, wrap-iife, max-len, one-var, no-var, one-var-declaration-per-line, no-unused-vars, camelcase, quotes, no-useless-concat, prefer-template, quote-props, comma-dangle, object-shorthand, consistent-return, prefer-arrow-callback */
/* global Dropzone */
import
Dropzone
from
'
dropzone
'
;
import
_
from
'
underscore
'
;
import
'
./preview_markdown
'
;
import
csrf
from
'
./lib/utils/csrf
'
;
window
.
DropzoneInput
=
(
function
()
{
function
DropzoneInput
(
form
)
{
const
divHover
=
'
<div class="div-dropzone-hover"></div>
'
;
const
iconPaperclip
=
'
<i class="fa fa-paperclip div-dropzone-icon"></i>
'
;
const
$attachButton
=
form
.
find
(
'
.button-attach-file
'
);
const
$attachingFileMessage
=
form
.
find
(
'
.attaching-file-message
'
);
const
$cancelButton
=
form
.
find
(
'
.button-cancel-uploading-files
'
);
const
$retryLink
=
form
.
find
(
'
.retry-uploading-link
'
);
const
$uploadProgress
=
form
.
find
(
'
.uploading-progress
'
);
const
$uploadingErrorContainer
=
form
.
find
(
'
.uploading-error-container
'
);
const
$uploadingErrorMessage
=
form
.
find
(
'
.uploading-error-message
'
);
const
$uploadingProgressContainer
=
form
.
find
(
'
.uploading-progress-container
'
);
const
uploadsPath
=
window
.
uploads_path
||
null
;
const
maxFileSize
=
gon
.
max_file_size
||
10
;
const
formTextarea
=
form
.
find
(
'
.js-gfm-input
'
);
let
handlePaste
;
let
pasteText
;
let
addFileToForm
;
let
updateAttachingMessage
;
let
isImage
;
let
getFilename
;
let
uploadFile
;
formTextarea
.
wrap
(
'
<div class="div-dropzone"></div>
'
);
formTextarea
.
on
(
'
paste
'
,
(
function
(
_this
)
{
return
function
(
event
)
{
return
handlePaste
(
event
);
};
})(
this
));
// Add dropzone area to the form.
const
$mdArea
=
formTextarea
.
closest
(
'
.md-area
'
);
form
.
setupMarkdownPreview
();
const
$formDropzone
=
form
.
find
(
'
.div-dropzone
'
);
$formDropzone
.
parent
().
addClass
(
'
div-dropzone-wrapper
'
);
$formDropzone
.
append
(
divHover
);
$formDropzone
.
find
(
'
.div-dropzone-hover
'
).
append
(
iconPaperclip
);
if
(
!
uploadsPath
)
return
;
const
dropzone
=
$formDropzone
.
dropzone
({
url
:
uploadsPath
,
dictDefaultMessage
:
''
,
clickable
:
true
,
paramName
:
'
file
'
,
maxFilesize
:
maxFileSize
,
uploadMultiple
:
false
,
headers
:
csrf
.
headers
,
previewContainer
:
false
,
processing
:
function
()
{
return
$
(
'
.div-dropzone-alert
'
).
alert
(
'
close
'
);
},
dragover
:
function
()
{
$mdArea
.
addClass
(
'
is-dropzone-hover
'
);
form
.
find
(
'
.div-dropzone-hover
'
).
css
(
'
opacity
'
,
0.7
);
},
dragleave
:
function
()
{
$mdArea
.
removeClass
(
'
is-dropzone-hover
'
);
form
.
find
(
'
.div-dropzone-hover
'
).
css
(
'
opacity
'
,
0
);
},
drop
:
function
()
{
$mdArea
.
removeClass
(
'
is-dropzone-hover
'
);
form
.
find
(
'
.div-dropzone-hover
'
).
css
(
'
opacity
'
,
0
);
formTextarea
.
focus
();
},
success
:
function
(
header
,
response
)
{
const
processingFileCount
=
this
.
getQueuedFiles
().
length
+
this
.
getUploadingFiles
().
length
;
const
shouldPad
=
processingFileCount
>=
1
;
pasteText
(
response
.
link
.
markdown
,
shouldPad
);
// Show 'Attach a file' link only when all files have been uploaded.
if
(
!
processingFileCount
)
$attachButton
.
removeClass
(
'
hide
'
);
addFileToForm
(
response
.
link
.
url
);
},
error
:
function
(
file
,
errorMessage
=
'
Attaching the file failed.
'
,
xhr
)
{
// If 'error' event is fired by dropzone, the second parameter is error message.
// If the 'errorMessage' parameter is empty, the default error message is set.
// If the 'error' event is fired by backend (xhr) error response, the third parameter is
// xhr object (xhr.responseText is error message).
// On error we hide the 'Attach' and 'Cancel' buttons
// and show an error.
// If there's xhr error message, let's show it instead of dropzone's one.
const
message
=
xhr
?
xhr
.
responseText
:
errorMessage
;
$uploadingErrorContainer
.
removeClass
(
'
hide
'
);
$uploadingErrorMessage
.
html
(
message
);
$attachButton
.
addClass
(
'
hide
'
);
$cancelButton
.
addClass
(
'
hide
'
);
},
totaluploadprogress
:
function
(
totalUploadProgress
)
{
updateAttachingMessage
(
this
.
files
,
$attachingFileMessage
);
$uploadProgress
.
text
(
Math
.
round
(
totalUploadProgress
)
+
'
%
'
);
},
sending
:
function
(
file
)
{
// DOM elements already exist.
// Instead of dynamically generating them,
// we just either hide or show them.
$attachButton
.
addClass
(
'
hide
'
);
$uploadingErrorContainer
.
addClass
(
'
hide
'
);
$uploadingProgressContainer
.
removeClass
(
'
hide
'
);
$cancelButton
.
removeClass
(
'
hide
'
);
},
removedfile
:
function
()
{
$attachButton
.
removeClass
(
'
hide
'
);
$cancelButton
.
addClass
(
'
hide
'
);
$uploadingProgressContainer
.
addClass
(
'
hide
'
);
$uploadingErrorContainer
.
addClass
(
'
hide
'
);
},
queuecomplete
:
function
()
{
$
(
'
.dz-preview
'
).
remove
();
$
(
'
.markdown-area
'
).
trigger
(
'
input
'
);
export
default
function
dropzoneInput
(
form
)
{
const
divHover
=
'
<div class="div-dropzone-hover"></div>
'
;
const
iconPaperclip
=
'
<i class="fa fa-paperclip div-dropzone-icon"></i>
'
;
const
$attachButton
=
form
.
find
(
'
.button-attach-file
'
);
const
$attachingFileMessage
=
form
.
find
(
'
.attaching-file-message
'
);
const
$cancelButton
=
form
.
find
(
'
.button-cancel-uploading-files
'
);
const
$retryLink
=
form
.
find
(
'
.retry-uploading-link
'
);
const
$uploadProgress
=
form
.
find
(
'
.uploading-progress
'
);
const
$uploadingErrorContainer
=
form
.
find
(
'
.uploading-error-container
'
);
const
$uploadingErrorMessage
=
form
.
find
(
'
.uploading-error-message
'
);
const
$uploadingProgressContainer
=
form
.
find
(
'
.uploading-progress-container
'
);
const
uploadsPath
=
window
.
uploads_path
||
null
;
const
maxFileSize
=
gon
.
max_file_size
||
10
;
const
formTextarea
=
form
.
find
(
'
.js-gfm-input
'
);
let
handlePaste
;
let
pasteText
;
let
addFileToForm
;
let
updateAttachingMessage
;
let
isImage
;
let
getFilename
;
let
uploadFile
;
formTextarea
.
wrap
(
'
<div class="div-dropzone"></div>
'
);
formTextarea
.
on
(
'
paste
'
,
event
=>
handlePaste
(
event
));
// Add dropzone area to the form.
const
$mdArea
=
formTextarea
.
closest
(
'
.md-area
'
);
form
.
setupMarkdownPreview
();
const
$formDropzone
=
form
.
find
(
'
.div-dropzone
'
);
$formDropzone
.
parent
().
addClass
(
'
div-dropzone-wrapper
'
);
$formDropzone
.
append
(
divHover
);
$formDropzone
.
find
(
'
.div-dropzone-hover
'
).
append
(
iconPaperclip
);
if
(
!
uploadsPath
)
return
;
const
dropzone
=
$formDropzone
.
dropzone
({
url
:
uploadsPath
,
dictDefaultMessage
:
''
,
clickable
:
true
,
paramName
:
'
file
'
,
maxFilesize
:
maxFileSize
,
uploadMultiple
:
false
,
headers
:
csrf
.
headers
,
previewContainer
:
false
,
processing
:
()
=>
$
(
'
.div-dropzone-alert
'
).
alert
(
'
close
'
),
dragover
:
()
=>
{
$mdArea
.
addClass
(
'
is-dropzone-hover
'
);
form
.
find
(
'
.div-dropzone-hover
'
).
css
(
'
opacity
'
,
0.7
);
},
dragleave
:
()
=>
{
$mdArea
.
removeClass
(
'
is-dropzone-hover
'
);
form
.
find
(
'
.div-dropzone-hover
'
).
css
(
'
opacity
'
,
0
);
},
drop
:
()
=>
{
$mdArea
.
removeClass
(
'
is-dropzone-hover
'
);
form
.
find
(
'
.div-dropzone-hover
'
).
css
(
'
opacity
'
,
0
);
formTextarea
.
focus
();
},
success
(
header
,
response
)
{
const
processingFileCount
=
this
.
getQueuedFiles
().
length
+
this
.
getUploadingFiles
().
length
;
const
shouldPad
=
processingFileCount
>=
1
;
pasteText
(
response
.
link
.
markdown
,
shouldPad
);
// Show 'Attach a file' link only when all files have been uploaded.
if
(
!
processingFileCount
)
$attachButton
.
removeClass
(
'
hide
'
);
addFileToForm
(
response
.
link
.
url
);
},
error
:
(
file
,
errorMessage
=
'
Attaching the file failed.
'
,
xhr
)
=>
{
// If 'error' event is fired by dropzone, the second parameter is error message.
// If the 'errorMessage' parameter is empty, the default error message is set.
// If the 'error' event is fired by backend (xhr) error response, the third parameter is
// xhr object (xhr.responseText is error message).
// On error we hide the 'Attach' and 'Cancel' buttons
// and show an error.
// If there's xhr error message, let's show it instead of dropzone's one.
const
message
=
xhr
?
xhr
.
responseText
:
errorMessage
;
$uploadingProgressContainer
.
addClass
(
'
hide
'
);
$cancelButton
.
addClass
(
'
hide
'
);
$uploadingErrorContainer
.
removeClass
(
'
hide
'
);
$uploadingErrorMessage
.
html
(
message
);
$attachButton
.
addClass
(
'
hide
'
);
$cancelButton
.
addClass
(
'
hide
'
);
},
totaluploadprogress
(
totalUploadProgress
)
{
updateAttachingMessage
(
this
.
files
,
$attachingFileMessage
);
$uploadProgress
.
text
(
`
${
Math
.
round
(
totalUploadProgress
)}
%`
);
},
sending
:
()
=>
{
// DOM elements already exist.
// Instead of dynamically generating them,
// we just either hide or show them.
$attachButton
.
addClass
(
'
hide
'
);
$uploadingErrorContainer
.
addClass
(
'
hide
'
);
$uploadingProgressContainer
.
removeClass
(
'
hide
'
);
$cancelButton
.
removeClass
(
'
hide
'
);
},
removedfile
:
()
=>
{
$attachButton
.
removeClass
(
'
hide
'
);
$cancelButton
.
addClass
(
'
hide
'
);
$uploadingProgressContainer
.
addClass
(
'
hide
'
);
$uploadingErrorContainer
.
addClass
(
'
hide
'
);
},
queuecomplete
:
()
=>
{
$
(
'
.dz-preview
'
).
remove
();
$
(
'
.markdown-area
'
).
trigger
(
'
input
'
);
$uploadingProgressContainer
.
addClass
(
'
hide
'
);
$cancelButton
.
addClass
(
'
hide
'
);
},
});
const
child
=
$
(
dropzone
[
0
]).
children
(
'
textarea
'
);
// removeAllFiles(true) stops uploading files (if any)
// and remove them from dropzone files queue.
$cancelButton
.
on
(
'
click
'
,
(
e
)
=>
{
const
target
=
e
.
target
.
closest
(
'
.js-main-target-form
'
).
querySelector
(
'
.div-dropzone
'
);
e
.
preventDefault
();
e
.
stopPropagation
();
Dropzone
.
forElement
(
target
).
removeAllFiles
(
true
);
});
// If 'error' event is fired, we store a failed files,
// clear dropzone files queue, change status of failed files to undefined,
// and add that files to the dropzone files queue again.
// addFile() adds file to dropzone files queue and upload it.
$retryLink
.
on
(
'
click
'
,
(
e
)
=>
{
const
dropzoneInstance
=
Dropzone
.
forElement
(
e
.
target
.
closest
(
'
.js-main-target-form
'
).
querySelector
(
'
.div-dropzone
'
));
const
failedFiles
=
dropzoneInstance
.
files
;
e
.
preventDefault
();
// 'true' parameter of removeAllFiles() cancels
// uploading of files that are being uploaded at the moment.
dropzoneInstance
.
removeAllFiles
(
true
);
failedFiles
.
map
((
failedFile
)
=>
{
const
file
=
failedFile
;
if
(
file
.
status
===
Dropzone
.
ERROR
)
{
file
.
status
=
undefined
;
file
.
accepted
=
undefined
;
}
});
const
child
=
$
(
dropzone
[
0
]).
children
(
'
textarea
'
);
// removeAllFiles(true) stops uploading files (if any)
// and remove them from dropzone files queue.
$cancelButton
.
on
(
'
click
'
,
(
e
)
=>
{
const
target
=
e
.
target
.
closest
(
'
.js-main-target-form
'
).
querySelector
(
'
.div-dropzone
'
);
e
.
preventDefault
();
e
.
stopPropagation
();
Dropzone
.
forElement
(
target
).
removeAllFiles
(
true
);
});
// If 'error' event is fired, we store a failed files,
// clear dropzone files queue, change status of failed files to undefined,
// and add that files to the dropzone files queue again.
// addFile() adds file to dropzone files queue and upload it.
$retryLink
.
on
(
'
click
'
,
(
e
)
=>
{
const
dropzoneInstance
=
Dropzone
.
forElement
(
e
.
target
.
closest
(
'
.js-main-target-form
'
).
querySelector
(
'
.div-dropzone
'
));
const
failedFiles
=
dropzoneInstance
.
files
;
e
.
preventDefault
();
// 'true' parameter of removeAllFiles() cancels uploading of files that are being uploaded at the moment.
dropzoneInstance
.
removeAllFiles
(
true
);
failedFiles
.
map
((
failedFile
,
i
)
=>
{
const
file
=
failedFile
;
if
(
file
.
status
===
Dropzone
.
ERROR
)
{
file
.
status
=
undefined
;
file
.
accepted
=
undefined
;
}
return
dropzoneInstance
.
addFile
(
file
);
});
return
dropzoneInstance
.
addFile
(
file
);
});
handlePaste
=
function
(
event
)
{
var
filename
,
image
,
pasteEvent
,
text
;
pasteEvent
=
event
.
originalEvent
;
if
(
pasteEvent
.
clipboardData
&&
pasteEvent
.
clipboardData
.
items
)
{
image
=
isImage
(
pasteEvent
);
if
(
image
)
{
event
.
preventDefault
();
filename
=
getFilename
(
pasteEvent
)
||
'
image.png
'
;
text
=
`{{
${
filename
}
}}`
;
pasteText
(
text
);
return
uploadFile
(
image
.
getAsFile
(),
filename
);
}
});
// eslint-disable-next-line consistent-return
handlePaste
=
(
event
)
=>
{
const
pasteEvent
=
event
.
originalEvent
;
if
(
pasteEvent
.
clipboardData
&&
pasteEvent
.
clipboardData
.
items
)
{
const
image
=
isImage
(
pasteEvent
);
if
(
image
)
{
event
.
preventDefault
();
const
filename
=
getFilename
(
pasteEvent
)
||
'
image.png
'
;
const
text
=
`{{
${
filename
}
}}`
;
pasteText
(
text
);
return
uploadFile
(
image
.
getAsFile
(),
filename
);
}
};
isImage
=
function
(
data
)
{
var
i
,
item
;
i
=
0
;
while
(
i
<
data
.
clipboardData
.
items
.
length
)
{
item
=
data
.
clipboardData
.
items
[
i
];
if
(
item
.
type
.
indexOf
(
'
image
'
)
!==
-
1
)
{
return
item
;
}
i
+=
1
;
}
return
false
;
};
pasteText
=
function
(
text
,
shouldPad
)
{
var
afterSelection
,
beforeSelection
,
caretEnd
,
caretStart
,
textEnd
;
var
formattedText
=
text
;
if
(
shouldPad
)
formattedText
+=
"
\n\n
"
;
const
textarea
=
child
.
get
(
0
);
caretStart
=
textarea
.
selectionStart
;
caretEnd
=
textarea
.
selectionEnd
;
textEnd
=
$
(
child
).
val
().
length
;
beforeSelection
=
$
(
child
).
val
().
substring
(
0
,
caretStart
);
afterSelection
=
$
(
child
).
val
().
substring
(
caretEnd
,
textEnd
);
$
(
child
).
val
(
beforeSelection
+
formattedText
+
afterSelection
);
textarea
.
setSelectionRange
(
caretStart
+
formattedText
.
length
,
caretEnd
+
formattedText
.
length
);
textarea
.
style
.
height
=
`
${
textarea
.
scrollHeight
}
px`
;
formTextarea
.
get
(
0
).
dispatchEvent
(
new
Event
(
'
input
'
));
return
formTextarea
.
trigger
(
'
input
'
);
};
addFileToForm
=
function
(
path
)
{
$
(
form
).
append
(
'
<input type="hidden" name="files[]" value="
'
+
_
.
escape
(
path
)
+
'
">
'
);
};
getFilename
=
function
(
e
)
{
var
value
;
if
(
window
.
clipboardData
&&
window
.
clipboardData
.
getData
)
{
value
=
window
.
clipboardData
.
getData
(
'
Text
'
);
}
else
if
(
e
.
clipboardData
&&
e
.
clipboardData
.
getData
)
{
value
=
e
.
clipboardData
.
getData
(
'
text/plain
'
);
}
value
=
value
.
split
(
"
\r
"
);
return
value
[
0
];
};
const
showSpinner
=
function
(
e
)
{
return
$uploadingProgressContainer
.
removeClass
(
'
hide
'
);
};
const
closeSpinner
=
function
()
{
return
$uploadingProgressContainer
.
addClass
(
'
hide
'
);
};
const
showError
=
function
(
message
)
{
$uploadingErrorContainer
.
removeClass
(
'
hide
'
);
$uploadingErrorMessage
.
html
(
message
);
};
const
closeAlertMessage
=
function
()
{
return
form
.
find
(
'
.div-dropzone-alert
'
).
alert
(
'
close
'
);
};
const
insertToTextArea
=
function
(
filename
,
url
)
{
const
$child
=
$
(
child
);
$child
.
val
(
function
(
index
,
val
)
{
return
val
.
replace
(
`{{
${
filename
}
}}`
,
url
);
});
$child
.
trigger
(
'
change
'
);
};
const
appendToTextArea
=
function
(
url
)
{
return
$
(
child
).
val
(
function
(
index
,
val
)
{
return
val
+
url
+
"
\n
"
;
});
};
uploadFile
=
function
(
item
,
filename
)
{
var
formData
;
formData
=
new
FormData
();
formData
.
append
(
'
file
'
,
item
,
filename
);
return
$
.
ajax
({
url
:
uploadsPath
,
type
:
'
POST
'
,
data
:
formData
,
dataType
:
'
json
'
,
processData
:
false
,
contentType
:
false
,
headers
:
csrf
.
headers
,
beforeSend
:
function
()
{
showSpinner
();
return
closeAlertMessage
();
},
success
:
function
(
e
,
textStatus
,
response
)
{
return
insertToTextArea
(
filename
,
response
.
responseJSON
.
link
.
markdown
);
},
error
:
function
(
response
)
{
return
showError
(
response
.
responseJSON
.
message
);
},
complete
:
function
()
{
return
closeSpinner
();
}
});
};
updateAttachingMessage
=
(
files
,
messageContainer
)
=>
{
let
attachingMessage
;
const
filesCount
=
files
.
filter
(
function
(
file
)
{
return
file
.
status
===
'
uploading
'
||
file
.
status
===
'
queued
'
;
}).
length
;
// Dinamycally change uploading files text depending on files number in
// dropzone files queue.
if
(
filesCount
>
1
)
{
attachingMessage
=
'
Attaching
'
+
filesCount
+
'
files -
'
;
}
else
{
attachingMessage
=
'
Attaching a file -
'
;
}
};
isImage
=
(
data
)
=>
{
let
i
=
0
;
while
(
i
<
data
.
clipboardData
.
items
.
length
)
{
const
item
=
data
.
clipboardData
.
items
[
i
];
if
(
item
.
type
.
indexOf
(
'
image
'
)
!==
-
1
)
{
return
item
;
}
messageContainer
.
text
(
attachingMessage
);
};
form
.
find
(
'
.markdown-selector
'
).
click
(
function
(
e
)
{
e
.
preventDefault
();
$
(
this
).
closest
(
'
.gfm-form
'
).
find
(
'
.div-dropzone
'
).
click
();
formTextarea
.
focus
();
i
+=
1
;
}
return
false
;
};
pasteText
=
(
text
,
shouldPad
)
=>
{
let
formattedText
=
text
;
if
(
shouldPad
)
{
formattedText
+=
'
\n\n
'
;
}
const
textarea
=
child
.
get
(
0
);
const
caretStart
=
textarea
.
selectionStart
;
const
caretEnd
=
textarea
.
selectionEnd
;
const
textEnd
=
$
(
child
).
val
().
length
;
const
beforeSelection
=
$
(
child
).
val
().
substring
(
0
,
caretStart
);
const
afterSelection
=
$
(
child
).
val
().
substring
(
caretEnd
,
textEnd
);
$
(
child
).
val
(
beforeSelection
+
formattedText
+
afterSelection
);
textarea
.
setSelectionRange
(
caretStart
+
formattedText
.
length
,
caretEnd
+
formattedText
.
length
);
textarea
.
style
.
height
=
`
${
textarea
.
scrollHeight
}
px`
;
formTextarea
.
get
(
0
).
dispatchEvent
(
new
Event
(
'
input
'
));
return
formTextarea
.
trigger
(
'
input
'
);
};
addFileToForm
=
(
path
)
=>
{
$
(
form
).
append
(
`<input type="hidden" name="files[]" value="
${
_
.
escape
(
path
)}
">`
);
};
getFilename
=
(
e
)
=>
{
let
value
;
if
(
window
.
clipboardData
&&
window
.
clipboardData
.
getData
)
{
value
=
window
.
clipboardData
.
getData
(
'
Text
'
);
}
else
if
(
e
.
clipboardData
&&
e
.
clipboardData
.
getData
)
{
value
=
e
.
clipboardData
.
getData
(
'
text/plain
'
);
}
value
=
value
.
split
(
'
\r
'
);
return
value
[
0
];
};
const
showSpinner
=
()
=>
$uploadingProgressContainer
.
removeClass
(
'
hide
'
);
const
closeSpinner
=
()
=>
$uploadingProgressContainer
.
addClass
(
'
hide
'
);
const
showError
=
(
message
)
=>
{
$uploadingErrorContainer
.
removeClass
(
'
hide
'
);
$uploadingErrorMessage
.
html
(
message
);
};
const
closeAlertMessage
=
()
=>
form
.
find
(
'
.div-dropzone-alert
'
).
alert
(
'
close
'
);
const
insertToTextArea
=
(
filename
,
url
)
=>
{
const
$child
=
$
(
child
);
$child
.
val
((
index
,
val
)
=>
val
.
replace
(
`{{
${
filename
}
}}`
,
url
));
$child
.
trigger
(
'
change
'
);
};
uploadFile
=
(
item
,
filename
)
=>
{
const
formData
=
new
FormData
();
formData
.
append
(
'
file
'
,
item
,
filename
);
return
$
.
ajax
({
url
:
uploadsPath
,
type
:
'
POST
'
,
data
:
formData
,
dataType
:
'
json
'
,
processData
:
false
,
contentType
:
false
,
headers
:
csrf
.
headers
,
beforeSend
:
()
=>
{
showSpinner
();
return
closeAlertMessage
();
},
success
:
(
e
,
text
,
response
)
=>
{
const
md
=
response
.
responseJSON
.
link
.
markdown
;
insertToTextArea
(
filename
,
md
);
},
error
:
response
=>
showError
(
response
.
responseJSON
.
message
),
complete
:
()
=>
closeSpinner
(),
});
}
return
DropzoneInput
;
})();
};
updateAttachingMessage
=
(
files
,
messageContainer
)
=>
{
let
attachingMessage
;
const
filesCount
=
files
.
filter
(
file
=>
file
.
status
===
'
uploading
'
||
file
.
status
===
'
queued
'
).
length
;
// Dinamycally change uploading files text depending on files number in
// dropzone files queue.
if
(
filesCount
>
1
)
{
attachingMessage
=
`Attaching
${
filesCount
}
files -`
;
}
else
{
attachingMessage
=
'
Attaching a file -
'
;
}
messageContainer
.
text
(
attachingMessage
);
};
form
.
find
(
'
.markdown-selector
'
).
click
(
function
onMarkdownClick
(
e
)
{
e
.
preventDefault
();
$
(
this
).
closest
(
'
.gfm-form
'
).
find
(
'
.div-dropzone
'
).
click
();
formTextarea
.
focus
();
});
}
app/assets/javascripts/gl_form.js
View file @
1bba9700
/* global DropzoneInput */
/* global autosize */
import
GfmAutoComplete
from
'
./gfm_auto_complete
'
;
import
dropzoneInput
from
'
./dropzone_input
'
;
export
default
class
GLForm
{
constructor
(
form
,
enableGFM
=
false
)
{
...
...
@@ -41,7 +41,7 @@ export default class GLForm {
mergeRequests
:
this
.
enableGFM
,
labels
:
this
.
enableGFM
,
});
new
DropzoneInput
(
this
.
form
);
// eslint-disable-line no-new
dropzoneInput
(
this
.
form
);
autosize
(
this
.
textarea
);
}
// form and textarea event listeners
...
...
app/assets/javascripts/notes.js
View file @
1bba9700
...
...
@@ -13,7 +13,6 @@ import $ from 'jquery';
import
_
from
'
underscore
'
;
import
Cookies
from
'
js-cookie
'
;
import
autosize
from
'
vendor/autosize
'
;
import
Dropzone
from
'
dropzone
'
;
import
'
vendor/jquery.caret
'
;
// required by jquery.atwho
import
'
vendor/jquery.atwho
'
;
import
AjaxCache
from
'
~/lib/utils/ajax_cache
'
;
...
...
@@ -22,13 +21,11 @@ import CommentTypeToggle from './comment_type_toggle';
import
GLForm
from
'
./gl_form
'
;
import
loadAwardsHandler
from
'
./awards_handler
'
;
import
'
./autosave
'
;
import
'
./dropzone_input
'
;
import
TaskList
from
'
./task_list
'
;
import
{
ajaxPost
,
isInViewport
,
getPagePath
,
scrollToElement
,
isMetaKey
}
from
'
./lib/utils/common_utils
'
;
import
imageDiffHelper
from
'
./image_diff/helpers/index
'
;
window
.
autosize
=
autosize
;
window
.
Dropzone
=
Dropzone
;
function
normalizeNewlines
(
str
)
{
return
str
.
replace
(
/
\r\n
/g
,
'
\n
'
);
...
...
app/assets/javascripts/zen_mode.js
View file @
1bba9700
...
...
@@ -11,8 +11,6 @@ import Dropzone from 'dropzone';
import
'
mousetrap
'
;
import
'
mousetrap/plugins/pause/mousetrap-pause
'
;
window
.
Dropzone
=
Dropzone
;
//
// ### Events
//
...
...
spec/javascripts/blob/blob_file_dropzone_spec.js
View file @
1bba9700
import
'
dropzone
'
;
import
BlobFileDropzone
from
'
~/blob/blob_file_dropzone
'
;
describe
(
'
BlobFileDropzone
'
,
()
=>
{
...
...
spec/javascripts/zen_mode_spec.js
View file @
1bba9700
/* eslint-disable space-before-function-paren, no-var, one-var, one-var-declaration-per-line, object-shorthand, comma-dangle, no-return-assign, new-cap, max-len */
/* global Dropzone */
/* global Mousetrap */
import
Dropzone
from
'
dropzone
'
;
import
ZenMode
from
'
~/zen_mode
'
;
(
function
()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment