diff --git a/app/assets/javascripts/app/controllers/_application_controller.js.coffee b/app/assets/javascripts/app/controllers/_application_controller.js.coffee index 19edb08df..e28c581a5 100644 --- a/app/assets/javascripts/app/controllers/_application_controller.js.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller.js.coffee @@ -229,7 +229,7 @@ class App.Controller extends Spine.Controller title: -> ticket_id = $(@).data('id') ticket = App.Ticket.fullLocal( ticket_id ) - HTMLEscape( ticket.title ) + App.Utils.htmlEscape( ticket.title ) content: -> ticket_id = $(@).data('id') ticket = App.Ticket.fullLocal( ticket_id ) @@ -264,7 +264,7 @@ class App.Controller extends Spine.Controller title: -> user_id = $(@).data('id') user = App.User.fullLocal( user_id ) - HTMLEscape( user.displayName() ) + App.Utils.htmlEscape( user.displayName() ) content: -> user_id = $(@).data('id') user = App.User.fullLocal( user_id ) @@ -311,7 +311,7 @@ class App.Controller extends Spine.Controller title: -> organization_id = $(@).data('id') organization = App.Organization.fullLocal( organization_id ) - HTMLEscape( organization.name ) + App.Utils.htmlEscape( organization.name ) content: -> organization_id = $(@).data('id') organization = App.Organization.fullLocal( organization_id ) diff --git a/app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee b/app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee index a231cf2a7..c49f3897b 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee @@ -442,12 +442,12 @@ class App.GenericHistory extends App.ControllerModal if item.value_from if item.value_to content += " #{ @T( 'from' ) }" - content += " '#{ HTMLEscape(item.value_from) }'" + content += " '#{ App.Utils.htmlEscape(item.value_from) }'" if item.value_to if item.value_from content += " #{ @T( 'to' ) }" - content += " '#{ HTMLEscape(item.value_to) }'" + content += " '#{ App.Utils.htmlEscape(item.value_to) }'" newItem.records.push content diff --git a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee index 76cfec859..10e0b2fb2 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee @@ -145,7 +145,6 @@ class App.TicketZoom extends App.Controller # get data @ticket = App.Ticket.fullLocal( @ticket_id ) @ticket.article = undefined - console.log('KLKL',@ticket) # render page @render(force) @@ -849,7 +848,7 @@ class Edit extends App.Controller @open_textarea(null, true) for key, value of data.article if key is 'body' - @$('[data-name="' + key + '"]').text(value) + @$('[data-name="' + key + '"]').html(value) else @$('[name="' + key + '"]').val(value) ) @@ -1384,17 +1383,20 @@ class ArticleView extends App.Controller false checkIfSignatureIsNeeded: (type) => - + console.log('checkIfSignatureIsNeeded', type, @ui.signature) # add signature if @ui.signature && @ui.signature.body && type.name is 'email' - body = @ui.el.find('[name="body"]').val() || '' - regexp = new RegExp( escapeRegExp( @ui.signature.body ) , 'i') - if !body.match(regexp) - body = body + "\n" + @ui.signature.body - @ui.el.find('[name="body"]').val( body ) + body = @ui.el.find('[data-name="body"]').html() || '' - # update textarea size - @ui.el.find('[name="body"]').trigger('change') + # convert to html + signature = @ui.signature.body + #signature = signature.replace(//g, " ") + signature = '

' + signature.replace(/\n/g, '

') + '

' + regexp = new RegExp( escapeRegExp( signature ) , 'im') + #console.log('aaa', body, regexp) + if !body || !body.match(regexp) + body = body + signature + @ui.el.find('[data-name="body"]').html( body ) replyAll: (e) => @reply(e, true) @@ -1483,13 +1485,18 @@ class ArticleView extends App.Controller # add quoted text if needed selectedText = App.ClipBoard.getSelected() - console.log('selectedText', selectedText) + if selectedText - body = @ui.el.find('[data-name="body"]').text() || '' + body = @ui.el.find('[data-name="body"]').html() || '' + + # quote text selectedText = selectedText.replace /^(.*)$/mg, (match) => '> ' + match - body = selectedText + "\n" + body - articleNew.body = body + + # convert to html + selectedText = '

' + selectedText.replace(/\n/g, "

") + '

' + + articleNew.body = selectedText + body App.Event.trigger('ui::ticket::setArticleType', { ticket: @ticket, type: type, article: articleNew } ) @@ -1514,12 +1521,7 @@ class Article extends App.Controller return # build html body - # cleanup body -# @article['html'] = @article.body.trim() - @article['html'] = $.trim( @article.body ) - @article['html'].replace( /\n\r/g, "\n" ) - @article['html'].replace( /\r/g, "\n" ) - @article['html'].replace( /\n\n/g, "\n" ) + @article['html'] = App.Utils.textCleanup( @article.body ) # if body has more then x lines / else search for signature preview = 10 @@ -1532,7 +1534,7 @@ class Article extends App.Controller else article_lines.splice( preview - 1, 0, '-----SEEMORE-----' ) @article['html'] = article_lines.join("\n") - @article['html'] = window.linkify( @article['html'] ) + @article['html'] = App.Utils.linkify( @article['html'] ) notify = '' + App.i18n.translateContent('See more') + '' # preview mode @@ -1553,7 +1555,7 @@ class Article extends App.Controller if @article_changed @article['html'] = @article['html'] + '' - @article['html'] = @article['html'].replace( /\n/g, '
' ) + @article['html'] = App.Utils.text2html( @article.body ) actionRow: -> if @isRole('Customer') diff --git a/app/assets/javascripts/app/index.js.coffee b/app/assets/javascripts/app/index.js.coffee index 564af0268..f628c4e61 100644 --- a/app/assets/javascripts/app/index.js.coffee +++ b/app/assets/javascripts/app/index.js.coffee @@ -92,7 +92,7 @@ class App extends Spine.Controller # define linkify helper params.L = ( item ) -> if item && typeof item is 'string' - return window.linkify( item ) + return App.Utils.linkify( item ) item # define config helper @@ -118,9 +118,9 @@ class App extends Spine.Controller if result result = result + ', ' if item.name - result = result + HTMLEscape(item.name) + ' ' + result = result + App.Utils.htmlEscape(item.name) + ' ' if item.address - result = result + " <#{HTMLEscape(item.address)}>" + result = result + " <#{App.Utils.htmlEscape(item.address)}>" result diff --git a/app/assets/javascripts/app/lib/app_post/i18n.js.coffee b/app/assets/javascripts/app/lib/app_post/i18n.js.coffee index d9b0f3325..ca5997031 100644 --- a/app/assets/javascripts/app/lib/app_post/i18n.js.coffee +++ b/app/assets/javascripts/app/lib/app_post/i18n.js.coffee @@ -130,13 +130,13 @@ class _i18nSingleton extends Spine.Module ) translateInline: ( string, args... ) => - HTMLEscape( @translate( string, args... ) ) + App.Utils.htmlEscape( @translate( string, args... ) ) translateContent: ( string, args... ) => - translated = HTMLEscape( @translate( string, args... ) ) -# replace = '' + translated + '' + translated = App.Utils.htmlEscape( @translate( string, args... ) ) +# replace = '' + translated + '' if App.Config.get( 'Translation' ) - replace = '' + translated + '' + replace = '' + translated + '' # if !@_translated # replace += 'XX' replace += '' diff --git a/app/assets/javascripts/app/lib/app_post/utils.js.coffee b/app/assets/javascripts/app/lib/app_post/utils.js.coffee new file mode 100644 index 000000000..084b7cf76 --- /dev/null +++ b/app/assets/javascripts/app/lib/app_post/utils.js.coffee @@ -0,0 +1,32 @@ +class App.Utils + + # textCleand = App.Utils.textCleanup( rawText ) + + @textCleanup: ( ascii ) -> + $.trim( ascii ) + .replace(/(\r\n|\n\r)/g, "\n") # cleanup + .replace(/\r/g, "\n") # cleanup + .replace(/\s+$/gm, "\n") # remove tailing spaces + .replace(/\n{2,9}/gm, "\n\n") # remove multible empty lines + + # htmlEscapedAndLinkified = App.Utils.text2html( rawText ) + + @text2html: ( ascii ) -> + ascii = @textCleanup(ascii) + #ascii = @htmlEscape(ascii) + ascii = @linkify(ascii) + ascii.replace( /\n/g, '
' ) + + # htmlEscaped = App.Utils.htmlEscape( rawText ) + + @htmlEscape: ( ascii ) -> + ascii.replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, ''') + + # htmlEscapedAndLinkified = App.Utils.linkify( rawText ) + + @linkify: (ascii) -> + window.linkify( ascii ) \ No newline at end of file diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index ca3b26b8d..d2ba680d8 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -76,15 +76,6 @@ function clone(object) { return JSON.parse(JSON.stringify(object)); } -function HTMLEscape(string) { - return ( '' + string ) - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, ''') -} - jQuery.event.special.remove = { remove: function(e) { if (e.handler) e.handler(); diff --git a/app/controllers/tests_controller.rb b/app/controllers/tests_controller.rb index e5368af33..0d17c6e06 100644 --- a/app/controllers/tests_controller.rb +++ b/app/controllers/tests_controller.rb @@ -37,6 +37,13 @@ class TestsController < ApplicationController end end + # GET /tests/html_utils + def html_utils + respond_to do |format| + format.html # index.html.erb + end + end + # GET /test/wait def wait sleep params[:sec].to_i diff --git a/app/views/tests/html_utils.html.erb b/app/views/tests/html_utils.html.erb new file mode 100644 index 000000000..05b5d23bf --- /dev/null +++ b/app/views/tests/html_utils.html.erb @@ -0,0 +1,15 @@ + + + + + + + + + +
\ No newline at end of file diff --git a/config/routes/test.rb b/config/routes/test.rb index a3b084654..8faf95f01 100644 --- a/config/routes/test.rb +++ b/config/routes/test.rb @@ -6,6 +6,7 @@ Zammad::Application.routes.draw do match '/tests-form', :to => 'tests#form', :via => :get match '/tests-form-extended', :to => 'tests#form_extended', :via => :get match '/tests-table', :to => 'tests#table', :via => :get + match '/tests-html-utils', :to => 'tests#html_utils', :via => :get match '/tests/wait/:sec', :to => 'tests#wait', :via => :get end \ No newline at end of file diff --git a/public/assets/tests/html-utils.js b/public/assets/tests/html-utils.js new file mode 100644 index 000000000..f23c39b5b --- /dev/null +++ b/public/assets/tests/html-utils.js @@ -0,0 +1,152 @@ +window.onload = function() { + +// textCleanup +test( "textCleanup", function() { + + var source = "Some\nValue\n\n\nTest" + var should = "Some\nValue\n\nTest" + var result = App.Utils.textCleanup( source ) + equal( result, should, source ) + + source = "Some\nValue\n\n \n\n\nTest" + should = "Some\nValue\n\nTest" + result = App.Utils.textCleanup( source ) + equal( result, should, source ) + + source = "Some\n\rValue\n\r\n\r\n\rTest" + should = "Some\nValue\n\nTest" + result = App.Utils.textCleanup( source ) + equal( result, should, source ) + + source = "Some\n\rValue\n\r\n\r\n\rTest\r" + should = "Some\nValue\n\nTest" + result = App.Utils.textCleanup( source ) + equal( result, should, source ) + + source = "Some\r\nValue\r\n\r\n\r\nTest\r\n" + should = "Some\nValue\n\nTest" + result = App.Utils.textCleanup( source ) + equal( result, should, source ) + + source = "Some\r\nValue\r\n\r\n\r\n\r\n\r\n\r\nTest\r\n" + should = "Some\nValue\n\nTest" + result = App.Utils.textCleanup( source ) + equal( result, should, source ) + +}); + +// htmlEscape +test( "htmlEscape", function() { + + var source = "<" + var should = "<" + var result = App.Utils.htmlEscape( source ) + equal( result, should, source ) + + source = ">" + should = ">" + result = App.Utils.htmlEscape( source ) + equal( result, should, source ) + + source = "&" + should = "&" + result = App.Utils.htmlEscape( source ) + equal( result, should, source ) + + source = "&" + should = "&amp;" + result = App.Utils.htmlEscape( source ) + equal( result, should, source ) + + source = "& ;" + should = "&amp ;" + result = App.Utils.htmlEscape( source ) + equal( result, should, source ) + + source = "& amp;" + should = "& amp;" + result = App.Utils.htmlEscape( source ) + equal( result, should, source ) + + source = "'test'" + should = "'test'" + result = App.Utils.htmlEscape( source ) + equal( result, should, source ) + + source = '"test"' + should = ""test"" + result = App.Utils.htmlEscape( source ) + equal( result, should, source ) + + source = "<>" + should = "<>" + result = App.Utils.htmlEscape( source ) + equal( result, should, source ) + + source = "<<>" + should = "<&lt;>" + result = App.Utils.htmlEscape( source ) + equal( result, should, source ) + + +}); + +// text2html +test( "text2html", function() { + + var source = "Some\nValue\n\n\nTest" + var should = "Some
Value

Test" + var 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\nValue\n" + should = "Some
<b>Value</b>" + result = App.Utils.text2html( source ) + equal( result, should, source ) + +}); + +// linkify +test( "linkify", function() { + + var source = "http://example.com" + var should = 'http://example.com' + var result = App.Utils.linkify( source ) + equal( result, should, source ) + + source = "http://example.com?some_param=lalala" + should = 'http://example.com?some_param=lalala' + result = App.Utils.linkify( source ) + equal( result, should, source ) + + source = "example.com" + should = 'example.com' + result = App.Utils.linkify( source ) + equal( result, should, source ) + + source = "some text example.com" + should = 'some text example.com' + result = App.Utils.linkify( source ) + equal( result, should, source ) + + source = "example.com some text" + should = 'example.com some text' + result = App.Utils.linkify( source ) + equal( result, should, source ) + + + /* + source = "example.com" + should = 'http://example.com' + result = App.Utils.linkify( source ) + equal( result, should, source ) + */ + +}); + +} \ No newline at end of file diff --git a/test/browser/aab_unit_test.rb b/test/browser/aab_unit_test.rb index 78587e06b..a702c571a 100644 --- a/test/browser/aab_unit_test.rb +++ b/test/browser/aab_unit_test.rb @@ -134,4 +134,26 @@ class AAbUnitTest < TestCase ] browser_single_test(tests) end + def test_html_utils + tests = [ + { + :name => 'start', + :instance => browser_instance, + :url => browser_url + '/tests-html-utils', + :action => [ + { + :execute => 'wait', + :value => 8, + }, + { + :execute => 'match', + :css => '.result .failed', + :value => '0', + :match_result => true, + }, + ], + }, + ] + browser_single_test(tests) + end end \ No newline at end of file