diff --git a/app/assets/javascripts/app/lib/app_post/utils.coffee b/app/assets/javascripts/app/lib/app_post/utils.coffee
index 5a80d973c..956889672 100644
--- a/app/assets/javascripts/app/lib/app_post/utils.coffee
+++ b/app/assets/javascripts/app/lib/app_post/utils.coffee
@@ -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>/g, '
')
@@ -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
diff --git a/app/assets/javascripts/app/lib/base/jquery.contenteditable.js b/app/assets/javascripts/app/lib/base/jquery.contenteditable.js
index 09cf6532f..985d3d4ef 100644
--- a/app/assets/javascripts/app/lib/base/jquery.contenteditable.js
+++ b/app/assets/javascripts/app/lib/base/jquery.contenteditable.js
@@ -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
}
diff --git a/public/assets/tests/html_utils.js b/public/assets/tests/html_utils.js
index a409a1674..37234a117 100644
--- a/public/assets/tests/html_utils.js
+++ b/public/assets/tests/html_utils.js
@@ -63,6 +63,35 @@ test("text2html", function() {
result = App.Utils.text2html(source)
equal(result, should, source)
+ source = "Some\nValue\n"
+ should = "
Some
Value
"
+ result = App.Utils.text2html(source)
+ equal(result, should, source)
+
+ source = "Some\rValue\r"
+ should = "
Some
Value
"
+ result = App.Utils.text2html(source)
+ equal(result, should, source)
+
+ source = "Some\n\rValue\n\r"
+ should = "
Some
Value
"
+ result = App.Utils.text2html(source)
+ equal(result, should, source)
+
+ source = "Some\r\nValue\r\n"
+ should = "
Some
Value
"
+ result = App.Utils.text2html(source)
+ equal(result, should, source)
+
+ source = "Some Value 123"
+ should = "
Some Value 123
"
+ result = App.Utils.text2html(source)
+ equal(result, should, source)
+
+ source = "Some\n Value\n 123"
+ should = "
Some
Value
123
"
+ 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('
'), false)
+ equal(App.Utils.clipboardHtmlIsWithText('
'), false)
+ equal(App.Utils.clipboardHtmlIsWithText('
'), false)
+ equal(App.Utils.clipboardHtmlIsWithText('
'), false)
+ equal(App.Utils.clipboardHtmlIsWithText('
'), false)
+ equal(App.Utils.clipboardHtmlIsWithText("
\n
"), false)
+
+ // content with text
+ equal(App.Utils.clipboardHtmlIsWithText('test'), true)
+ equal(App.Utils.clipboardHtmlIsWithText('
test
'), true)
+ equal(App.Utils.clipboardHtmlIsWithText('
sometext'), true)
+});
+
+test('App.Utils.clipboardHtmlInsertPreperation()', function() {
+ equal(App.Utils.clipboardHtmlInsertPreperation('
', {}), '')
+ equal(App.Utils.clipboardHtmlInsertPreperation('
', {}), ' ')
+ equal(App.Utils.clipboardHtmlInsertPreperation('
', {}), '
')
+ equal(App.Utils.clipboardHtmlInsertPreperation('
', {}), '')
+ equal(App.Utils.clipboardHtmlInsertPreperation('
', {}), ' ')
+ equal(App.Utils.clipboardHtmlInsertPreperation("
\n
", {}), " \n ")
+ equal(App.Utils.clipboardHtmlInsertPreperation('test', {}), 'test')
+ equal(App.Utils.clipboardHtmlInsertPreperation('
test
', {}), 'test')
+ equal(App.Utils.clipboardHtmlInsertPreperation('
sometext', {}), '
sometext
')
+ equal(App.Utils.clipboardHtmlInsertPreperation('
test 123
', { mode: 'textonly' }), 'test 123')
+ equal(App.Utils.clipboardHtmlInsertPreperation('
test
123
', { mode: 'textonly' }), 'test 123')
+ equal(App.Utils.clipboardHtmlInsertPreperation('
test
123
', { mode: 'textonly', multiline: true }), 'test
123')
+});
+