Fixed issue #2924 - Unable to paste from clipboard in note field in ticket zoom.
This commit is contained in:
parent
343415d6e8
commit
ddb4bb5150
3 changed files with 180 additions and 85 deletions
|
@ -73,6 +73,8 @@ class App.Utils
|
|||
ascii = @textCleanup(ascii)
|
||||
#ascii = @htmlEscape(ascii)
|
||||
ascii = @linkify(ascii)
|
||||
ascii = ascii.replace(/(\n\r|\r\n|\r)/g, "\n")
|
||||
ascii = ascii.replace(/ /g, ' ')
|
||||
ascii = '<div>' + ascii.replace(/\n/g, '</div><div>') + '</div>'
|
||||
ascii.replace(/<div><\/div>/g, '<div><br></div>')
|
||||
|
||||
|
@ -1269,3 +1271,42 @@ class App.Utils
|
|||
.filter (elem) ->
|
||||
elem?
|
||||
.join '/'
|
||||
|
||||
@clipboardHtmlIsWithText: (html) ->
|
||||
if !html
|
||||
return false
|
||||
|
||||
parsedHTML = jQuery(jQuery.parseHTML(html))
|
||||
|
||||
if !parsedHTML || !parsedHTML.text
|
||||
return false
|
||||
|
||||
if parsedHTML.text().trim().length is 0
|
||||
return false
|
||||
|
||||
true
|
||||
|
||||
@clipboardHtmlInsertPreperation: (htmlRaw, options) ->
|
||||
if options.mode is 'textonly'
|
||||
if !options.multiline
|
||||
html = App.Utils.htmlRemoveTags(htmlRaw)
|
||||
else
|
||||
html = App.Utils.htmlRemoveRichtext(htmlRaw)
|
||||
else
|
||||
html = App.Utils.htmlCleanup(htmlRaw)
|
||||
|
||||
htmlString = html.html()
|
||||
|
||||
if !htmlString && html && html.text && html.text()
|
||||
htmlString = App.Utils.text2html(html.text())
|
||||
|
||||
# as fallback, get text from htmlRaw
|
||||
if !htmlString || htmlString == ''
|
||||
parsedHTML = jQuery(jQuery.parseHTML(htmlRaw))
|
||||
if parsedHTML
|
||||
text = parsedHTML.text().trim()
|
||||
|
||||
if text
|
||||
htmlString = App.Utils.text2html(text)
|
||||
|
||||
htmlString
|
||||
|
|
|
@ -263,11 +263,32 @@
|
|||
}
|
||||
}
|
||||
|
||||
Plugin.prototype.onPaste = function (e) {
|
||||
e.preventDefault()
|
||||
this.log('paste')
|
||||
Plugin.prototype.getHtmlFromClipboard = function(clipboardData) {
|
||||
try {
|
||||
return clipboardData.getData('text/html')
|
||||
}
|
||||
catch (e) {
|
||||
console.log('Sorry, can\'t get html of clipboard because browser is not supporting it.')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// insert and in case, resize images
|
||||
Plugin.prototype.getTextFromClipboard = function(clipboardData) {
|
||||
var text
|
||||
try {
|
||||
text = clipboardData.getData('text/plain')
|
||||
if (!text || text.length === 0) {
|
||||
text = clipboardData.getData('text')
|
||||
}
|
||||
return text
|
||||
}
|
||||
catch (e) {
|
||||
console.log('Sorry, can\'t get text of clipboard because browser is not supporting it.')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
Plugin.prototype.getClipboardData = function(e) {
|
||||
var clipboardData
|
||||
if (e.clipboardData) { // ie
|
||||
clipboardData = e.clipboardData
|
||||
|
@ -281,30 +302,41 @@
|
|||
else {
|
||||
throw "No clipboardData support"
|
||||
}
|
||||
return clipboardData
|
||||
}
|
||||
|
||||
if (clipboardData && clipboardData.items && clipboardData.items[0]) {
|
||||
var imageInserted = false
|
||||
var item
|
||||
Plugin.prototype.getClipboardDataImage = function(clipboardData) {
|
||||
if (!clipboardData.items || !clipboardData.items[0]) {
|
||||
return
|
||||
}
|
||||
return $.grep(clipboardData.items, function(item){
|
||||
return item.kind == 'file' && (item.type == 'image/png' || item.type == 'image/jpeg')
|
||||
})[0]
|
||||
}
|
||||
|
||||
// look for image only if no HTML with textual content is available.
|
||||
// E.g. Excel provides images of the spreadsheet along with HTML.
|
||||
// While some browsers make images available in clipboard as HTML,
|
||||
// sometimes wrapped in multiple nodes.
|
||||
Plugin.prototype.onPaste = function (e) {
|
||||
e.preventDefault()
|
||||
var clipboardData, clipboardImage, text, htmlRaw, htmlString
|
||||
|
||||
var rawHTML = clipboardData.getData('text/html')
|
||||
var parsedHTML = jQuery(jQuery.parseHTML(rawHTML))
|
||||
this.log('paste')
|
||||
|
||||
if(parsedHTML.text().trim().length == 0) {
|
||||
item = jQuery.grep(clipboardData.items, function(item){
|
||||
return item.kind == 'file' && (item.type == 'image/png' || item.type == 'image/jpeg')
|
||||
})[0]
|
||||
}
|
||||
clipboardData = this.getClipboardData(e)
|
||||
|
||||
if (item) {
|
||||
this.log('paste image', item)
|
||||
console.log(item)
|
||||
// look for image only if no HTML with textual content is available.
|
||||
// E.g. Excel provides images of the spreadsheet along with HTML.
|
||||
// While some browsers make images available in clipboard as HTML,
|
||||
// sometimes wrapped in multiple nodes.
|
||||
htmlRaw = this.getHtmlFromClipboard(clipboardData)
|
||||
|
||||
var imageFile = item.getAsFile()
|
||||
if (!App.Utils.clipboardHtmlIsWithText(htmlRaw)) {
|
||||
|
||||
// insert and in case, resize images
|
||||
clipboardImage = this.getClipboardDataImage(clipboardData)
|
||||
if (clipboardImage) {
|
||||
|
||||
this.log('paste image', clipboardImage)
|
||||
|
||||
var imageFile = clipboardImage.getAsFile()
|
||||
var reader = new FileReader()
|
||||
|
||||
reader.onload = $.proxy(function (e) {
|
||||
|
@ -340,74 +372,35 @@
|
|||
}, this)
|
||||
|
||||
reader.readAsDataURL(imageFile)
|
||||
imageInserted = true
|
||||
} else {
|
||||
item = clipboardData.items[0]
|
||||
return true
|
||||
}
|
||||
}
|
||||
if (imageInserted) {
|
||||
|
||||
// insert html
|
||||
if (htmlRaw) {
|
||||
htmlString = App.Utils.clipboardHtmlInsertPreperation(htmlRaw, this.options)
|
||||
if (htmlString) {
|
||||
this.log('insert html from clipboard', htmlString)
|
||||
this.paste(htmlString)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// insert text
|
||||
text = this.getTextFromClipboard(clipboardData)
|
||||
if (!text) {
|
||||
return false
|
||||
}
|
||||
htmlString = App.Utils.text2html(text)
|
||||
|
||||
// check length limit
|
||||
if (!this.maxLengthOk(htmlString.length)) {
|
||||
return
|
||||
}
|
||||
|
||||
// check existing + paste text for limit
|
||||
var text, docType
|
||||
try {
|
||||
text = clipboardData.getData('text/html')
|
||||
docType = 'html'
|
||||
if (!text || text.length === 0) {
|
||||
docType = 'text'
|
||||
text = clipboardData.getData('text/plain')
|
||||
}
|
||||
if (!text || text.length === 0) {
|
||||
docType = 'text2'
|
||||
text = clipboardData.getData('text')
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.log('Sorry, can\'t insert markup because browser is not supporting it.')
|
||||
docType = 'text3'
|
||||
text = clipboardData.getData('text')
|
||||
}
|
||||
this.log('paste', docType, text)
|
||||
|
||||
if (docType == 'html') {
|
||||
if (this.options.mode === 'textonly') {
|
||||
if (!this.options.multiline) {
|
||||
text = App.Utils.htmlRemoveTags(text)
|
||||
this.log('htmlRemoveTags', text)
|
||||
}
|
||||
else {
|
||||
this.log('htmlRemoveRichtext', text)
|
||||
text = App.Utils.htmlRemoveRichtext(text)
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.log('htmlCleanup', text)
|
||||
text = App.Utils.htmlCleanup(text)
|
||||
}
|
||||
text = text.html()
|
||||
this.log('text.html()', text)
|
||||
|
||||
// as fallback, take text
|
||||
if (!text) {
|
||||
text = App.Utils.text2html(text.text())
|
||||
this.log('text2html', text)
|
||||
}
|
||||
}
|
||||
else {
|
||||
text = App.Utils.text2html(text)
|
||||
this.log('text2html', text)
|
||||
}
|
||||
|
||||
if (!this.maxLengthOk(text.length)) {
|
||||
return
|
||||
}
|
||||
|
||||
// cleanup
|
||||
text = App.Utils.removeEmptyLines(text)
|
||||
this.log('insert', text)
|
||||
|
||||
this.paste(text)
|
||||
htmlString = App.Utils.removeEmptyLines(htmlString)
|
||||
this.log('insert text from clipboard', htmlString)
|
||||
this.paste(htmlString)
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,35 @@ test("text2html", function() {
|
|||
result = App.Utils.text2html(source)
|
||||
equal(result, should, source)
|
||||
|
||||
source = "Some\nValue\n"
|
||||
should = "<div>Some</div><div>Value</div>"
|
||||
result = App.Utils.text2html(source)
|
||||
equal(result, should, source)
|
||||
|
||||
source = "Some\rValue\r"
|
||||
should = "<div>Some</div><div>Value</div>"
|
||||
result = App.Utils.text2html(source)
|
||||
equal(result, should, source)
|
||||
|
||||
source = "Some\n\rValue\n\r"
|
||||
should = "<div>Some</div><div>Value</div>"
|
||||
result = App.Utils.text2html(source)
|
||||
equal(result, should, source)
|
||||
|
||||
source = "Some\r\nValue\r\n"
|
||||
should = "<div>Some</div><div>Value</div>"
|
||||
result = App.Utils.text2html(source)
|
||||
equal(result, should, source)
|
||||
|
||||
source = "Some Value 123"
|
||||
should = "<div>Some Value 123</div>"
|
||||
result = App.Utils.text2html(source)
|
||||
equal(result, should, source)
|
||||
|
||||
source = "Some\n Value\n 123"
|
||||
should = "<div>Some</div><div> Value</div><div> 123</div>"
|
||||
result = App.Utils.text2html(source)
|
||||
equal(result, should, source)
|
||||
});
|
||||
|
||||
// htmlStrip
|
||||
|
@ -3306,3 +3335,35 @@ test('App.Utils.joinUrlComponents()', function() {
|
|||
// expect @joinUrlComponents() to filter them out of the results before joining the rest with slashes
|
||||
equal(App.Utils.joinUrlComponents('foo', undefined, 'bar', null, 'baz'), 'foo/bar/baz', 'with a list including null or undefined')
|
||||
});
|
||||
|
||||
test('App.Utils.clipboardHtmlIsWithText()', function() {
|
||||
|
||||
// no content with text
|
||||
equal(App.Utils.clipboardHtmlIsWithText('<div></div>'), false)
|
||||
equal(App.Utils.clipboardHtmlIsWithText('<div> </div>'), false)
|
||||
equal(App.Utils.clipboardHtmlIsWithText('<div><img src="test.jpg"/></div>'), false)
|
||||
equal(App.Utils.clipboardHtmlIsWithText('<div><!-- some comment --></div>'), false)
|
||||
equal(App.Utils.clipboardHtmlIsWithText('<div><!-- some comment --> </div>'), false)
|
||||
equal(App.Utils.clipboardHtmlIsWithText("<div><!-- some comment --> \n </div>"), false)
|
||||
|
||||
// content with text
|
||||
equal(App.Utils.clipboardHtmlIsWithText('test'), true)
|
||||
equal(App.Utils.clipboardHtmlIsWithText('<div>test</div>'), true)
|
||||
equal(App.Utils.clipboardHtmlIsWithText('<meta http-equiv="content-type" content="text/html; charset=utf-8">sometext'), true)
|
||||
});
|
||||
|
||||
test('App.Utils.clipboardHtmlInsertPreperation()', function() {
|
||||
equal(App.Utils.clipboardHtmlInsertPreperation('<div></div>', {}), '')
|
||||
equal(App.Utils.clipboardHtmlInsertPreperation('<div> </div>', {}), ' ')
|
||||
equal(App.Utils.clipboardHtmlInsertPreperation('<div><img src="test.jpg"/></div>', {}), '<img src="test.jpg">')
|
||||
equal(App.Utils.clipboardHtmlInsertPreperation('<div><!-- some comment --></div>', {}), '')
|
||||
equal(App.Utils.clipboardHtmlInsertPreperation('<div><!-- some comment --> </div>', {}), ' ')
|
||||
equal(App.Utils.clipboardHtmlInsertPreperation("<div><!-- some comment --> \n </div>", {}), " \n ")
|
||||
equal(App.Utils.clipboardHtmlInsertPreperation('test', {}), 'test')
|
||||
equal(App.Utils.clipboardHtmlInsertPreperation('<div>test</div>', {}), 'test')
|
||||
equal(App.Utils.clipboardHtmlInsertPreperation('<meta http-equiv="content-type" content="text/html; charset=utf-8">sometext', {}), '<div>sometext</div>')
|
||||
equal(App.Utils.clipboardHtmlInsertPreperation('<div><b>test</b> 123</div>', { mode: 'textonly' }), 'test 123')
|
||||
equal(App.Utils.clipboardHtmlInsertPreperation('<div><b>test</b><br> 123</div>', { mode: 'textonly' }), 'test 123')
|
||||
equal(App.Utils.clipboardHtmlInsertPreperation('<div><b>test</b><br> 123</div>', { mode: 'textonly', multiline: true }), 'test<br> 123')
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue