Added some new tests for html handling.
This commit is contained in:
parent
8bf6a28781
commit
2880ff3baf
9 changed files with 141 additions and 26 deletions
|
@ -1390,8 +1390,7 @@ class ArticleView extends App.Controller
|
||||||
|
|
||||||
# convert to html
|
# convert to html
|
||||||
signature = @ui.signature.body
|
signature = @ui.signature.body
|
||||||
#signature = signature.replace(//g, " ")
|
signature = App.Utils.text2html( signature )
|
||||||
signature = '<p>' + signature.replace(/\n/g, '</p><p>') + '</p>'
|
|
||||||
regexp = new RegExp( escapeRegExp( signature ) , 'im')
|
regexp = new RegExp( escapeRegExp( signature ) , 'im')
|
||||||
#console.log('aaa', body, regexp)
|
#console.log('aaa', body, regexp)
|
||||||
if !body || !body.match(regexp)
|
if !body || !body.match(regexp)
|
||||||
|
@ -1490,11 +1489,11 @@ class ArticleView extends App.Controller
|
||||||
body = @ui.el.find('[data-name="body"]').html() || ''
|
body = @ui.el.find('[data-name="body"]').html() || ''
|
||||||
|
|
||||||
# quote text
|
# quote text
|
||||||
selectedText = selectedText.replace /^(.*)$/mg, (match) =>
|
selectedText = App.Utils.textCleanup( selectedText )
|
||||||
'> ' + match
|
selectedText = App.Utils.quote( selectedText )
|
||||||
|
|
||||||
# convert to html
|
# convert to html
|
||||||
selectedText = '<p>' + selectedText.replace(/\n/g, "</p><p>") + '</p>'
|
selectedText = App.Utils.text2html( selectedText )
|
||||||
|
|
||||||
articleNew.body = selectedText + body
|
articleNew.body = selectedText + body
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,26 @@
|
||||||
class App.Utils
|
class App.Utils
|
||||||
|
|
||||||
# textCleand = App.Utils.textCleanup( rawText )
|
# textCleand = App.Utils.textCleanup( rawText )
|
||||||
|
|
||||||
@textCleanup: ( ascii ) ->
|
@textCleanup: ( ascii ) ->
|
||||||
$.trim( ascii )
|
$.trim( ascii )
|
||||||
.replace(/(\r\n|\n\r)/g, "\n") # cleanup
|
.replace(/(\r\n|\n\r)/g, "\n") # cleanup
|
||||||
.replace(/\r/g, "\n") # cleanup
|
.replace(/\r/g, "\n") # cleanup
|
||||||
.replace(/\s+$/gm, "\n") # remove tailing spaces
|
.replace(/[ ]\n/g, "\n") # remove tailing spaces
|
||||||
.replace(/\n{2,9}/gm, "\n\n") # remove multible empty lines
|
.replace(/\n{3,9}/g, "\n\n") # remove multible empty lines
|
||||||
|
|
||||||
# htmlEscapedAndLinkified = App.Utils.text2html( rawText )
|
# htmlEscapedAndLinkified = App.Utils.text2html( rawText )
|
||||||
|
|
||||||
@text2html: ( ascii ) ->
|
@text2html: ( ascii ) ->
|
||||||
|
console.log('AA0', ascii)
|
||||||
ascii = @textCleanup(ascii)
|
ascii = @textCleanup(ascii)
|
||||||
#ascii = @htmlEscape(ascii)
|
#ascii = @htmlEscape(ascii)
|
||||||
|
console.log('AA1', ascii)
|
||||||
ascii = @linkify(ascii)
|
ascii = @linkify(ascii)
|
||||||
ascii.replace( /\n/g, '<br>' )
|
#ascii.replace( /\n/g, '<br>' )
|
||||||
|
console.log('AA', ascii)
|
||||||
|
ascii = '<div>' + ascii.replace(/\n/g, '</div><div>') + '</div>'
|
||||||
|
ascii.replace(/<div><\/div>/g, '<div><br></div>')
|
||||||
|
|
||||||
# htmlEscaped = App.Utils.htmlEscape( rawText )
|
# htmlEscaped = App.Utils.htmlEscape( rawText )
|
||||||
|
|
||||||
@htmlEscape: ( ascii ) ->
|
@htmlEscape: ( ascii ) ->
|
||||||
ascii.replace(/&/g, '&')
|
ascii.replace(/&/g, '&')
|
||||||
.replace(/</g, '<')
|
.replace(/</g, '<')
|
||||||
|
@ -27,6 +29,15 @@ class App.Utils
|
||||||
.replace(/'/g, ''')
|
.replace(/'/g, ''')
|
||||||
|
|
||||||
# htmlEscapedAndLinkified = App.Utils.linkify( rawText )
|
# htmlEscapedAndLinkified = App.Utils.linkify( rawText )
|
||||||
|
|
||||||
@linkify: (ascii) ->
|
@linkify: (ascii) ->
|
||||||
window.linkify( ascii )
|
window.linkify( ascii )
|
||||||
|
|
||||||
|
# quotedText = App.Utils.quote( rawText )
|
||||||
|
@quote: (ascii) ->
|
||||||
|
ascii = @textCleanup(ascii)
|
||||||
|
$.trim( ascii )
|
||||||
|
.replace /^(.*)$/mg, (match) =>
|
||||||
|
if match
|
||||||
|
'> ' + match
|
||||||
|
else
|
||||||
|
'>'
|
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
// max length validation
|
// max length validation
|
||||||
var validation = function(element) {
|
var validation = function(element) {
|
||||||
console.log('pp', element, $(element))
|
|
||||||
// try to set error on framework form
|
// try to set error on framework form
|
||||||
var parent = $(element).parent().parent()
|
var parent = $(element).parent().parent()
|
||||||
if ( parent.hasClass('controls') ) {
|
if ( parent.hasClass('controls') ) {
|
||||||
|
@ -76,6 +76,13 @@
|
||||||
mode: editorMode,
|
mode: editorMode,
|
||||||
maxLength: this.options.maxlength || -1,
|
maxLength: this.options.maxlength || -1,
|
||||||
maxLengthReached: validation,
|
maxLengthReached: validation,
|
||||||
|
tags: {
|
||||||
|
'break': 'br',
|
||||||
|
'horizontalRule': 'hr',
|
||||||
|
'paragraph': 'div',
|
||||||
|
'outerLevel': ['pre', 'blockquote', 'figure'],
|
||||||
|
'innerLevel': ['a', 'b', 'u', 'i', 'img', 'strong']
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ module Channel::EmailBuild
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def build(attr, notification = false)
|
def self.build(attr, notification = false)
|
||||||
mail = Mail.new
|
mail = Mail.new
|
||||||
|
|
||||||
# set organization
|
# set organization
|
||||||
|
@ -48,7 +48,7 @@ module Channel::EmailBuild
|
||||||
content_type 'text/html; charset=UTF-8'
|
content_type 'text/html; charset=UTF-8'
|
||||||
|
|
||||||
# complete check
|
# complete check
|
||||||
attr[:body] = html_complete_check( attr[:body] )
|
attr[:body] = Channel::EmailBuild.html_complete_check( attr[:body] )
|
||||||
|
|
||||||
body attr[:body]
|
body attr[:body]
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class Channel::Sendmail
|
class Channel::Sendmail
|
||||||
include Channel::EmailBuild
|
|
||||||
def send(attr, channel, notification = false)
|
def send(attr, channel, notification = false)
|
||||||
|
|
||||||
# return if we run import mode
|
# return if we run import mode
|
||||||
return if Setting.get('import_mode')
|
return if Setting.get('import_mode')
|
||||||
|
|
||||||
mail = build(attr, notification)
|
mail = Channel::EmailBuild.build(attr, notification)
|
||||||
mail.delivery_method :sendmail
|
mail.delivery_method :sendmail
|
||||||
mail.deliver
|
mail.deliver
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class Channel::SMTP
|
class Channel::SMTP
|
||||||
include Channel::EmailBuild
|
|
||||||
def send(attr, channel, notification = false)
|
def send(attr, channel, notification = false)
|
||||||
|
|
||||||
# return if we run import mode
|
# return if we run import mode
|
||||||
return if Setting.get('import_mode')
|
return if Setting.get('import_mode')
|
||||||
|
|
||||||
mail = self.build(attr, notification)
|
mail = Channel::EmailBuild.build(attr, notification)
|
||||||
mail.delivery_method :smtp, {
|
mail.delivery_method :smtp, {
|
||||||
:openssl_verify_mode => 'none',
|
:openssl_verify_mode => 'none',
|
||||||
:address => channel[:options][:host],
|
:address => channel[:options][:host],
|
||||||
|
|
|
@ -45,7 +45,7 @@ class String
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
# from https://gist.github.com/petrblaho/657856
|
# base from https://gist.github.com/petrblaho/657856
|
||||||
def html2text
|
def html2text
|
||||||
text = self.
|
text = self.
|
||||||
gsub(/( |\n|\s)+/im, ' ').squeeze(' ').strip.
|
gsub(/( |\n|\s)+/im, ' ').squeeze(' ').strip.
|
||||||
|
@ -65,7 +65,8 @@ class String
|
||||||
gsub(/<hr(| [^>]*)>/i, "___\n").
|
gsub(/<hr(| [^>]*)>/i, "___\n").
|
||||||
gsub(/<li(| [^>]*)>/i, "\n* ").
|
gsub(/<li(| [^>]*)>/i, "\n* ").
|
||||||
gsub(/<blockquote(| [^>]*)>/i, '> ').
|
gsub(/<blockquote(| [^>]*)>/i, '> ').
|
||||||
gsub(/<(br)(| [^>]*)>/i, "\n").
|
gsub(/<(br)(|\/| [^>]*)>/i, "\n").
|
||||||
|
gsub(/<\/div(| [^>]*)>/i, "\n").
|
||||||
gsub(/<(\/h[\d]+|p)(| [^>]*)>/i, "\n\n").
|
gsub(/<(\/h[\d]+|p)(| [^>]*)>/i, "\n\n").
|
||||||
gsub(/<[^>]*>/, '')
|
gsub(/<[^>]*>/, '')
|
||||||
).lstrip.gsub(/\n[ ]+/, "\n") + "\n"
|
).lstrip.gsub(/\n[ ]+/, "\n") + "\n"
|
||||||
|
@ -74,6 +75,6 @@ class String
|
||||||
text = text + "\n [#{i+1}] <#{CGI.unescapeHTML(links[i])}>" unless links[i].nil?
|
text = text + "\n [#{i+1}] <#{CGI.unescapeHTML(links[i])}>" unless links[i].nil?
|
||||||
end
|
end
|
||||||
links = nil
|
links = nil
|
||||||
text
|
text.chomp
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -33,6 +33,12 @@ test( "textCleanup", function() {
|
||||||
result = App.Utils.textCleanup( source )
|
result = App.Utils.textCleanup( source )
|
||||||
equal( result, should, source )
|
equal( result, should, source )
|
||||||
|
|
||||||
|
source = "> Welcome!\n> \n> Thank you for installing Zammad.\n> \n> You will find ..."
|
||||||
|
should = "> Welcome!\n>\n> Thank you for installing Zammad.\n>\n> You will find ..."
|
||||||
|
result = App.Utils.textCleanup( source )
|
||||||
|
equal( result, should, source )
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// htmlEscape
|
// htmlEscape
|
||||||
|
@ -95,17 +101,22 @@ test( "htmlEscape", function() {
|
||||||
test( "text2html", function() {
|
test( "text2html", function() {
|
||||||
|
|
||||||
var source = "Some\nValue\n\n\nTest"
|
var source = "Some\nValue\n\n\nTest"
|
||||||
var should = "Some<br>Value<br><br>Test"
|
var should = "<div>Some</div><div>Value</div><div><br></div><div>Test</div>"
|
||||||
var result = App.Utils.text2html( source )
|
var result = App.Utils.text2html( source )
|
||||||
equal( result, should, source )
|
equal( result, should, source )
|
||||||
|
|
||||||
source = "Some\nValue\n"
|
source = "Some\nValue\n"
|
||||||
should = "Some<br>Value"
|
should = "<div>Some</div><div>Value</div>"
|
||||||
result = App.Utils.text2html( source )
|
result = App.Utils.text2html( source )
|
||||||
equal( result, should, source )
|
equal( result, should, source )
|
||||||
|
|
||||||
source = "Some\n<b>Value</b>\n"
|
source = "Some\n<b>Value</b>\n"
|
||||||
should = "Some<br><b>Value</b>"
|
should = "<div>Some</div><div><b>Value</b></div>"
|
||||||
|
result = App.Utils.text2html( source )
|
||||||
|
equal( result, should, source )
|
||||||
|
|
||||||
|
source = "> Welcome!\n> \n> Thank you for installing Zammad.\n> \n> You will find ..."
|
||||||
|
should = "<div>> Welcome!</div><div>></div><div>> Thank you for installing Zammad.</div><div>></div><div>> You will find ...</div>"
|
||||||
result = App.Utils.text2html( source )
|
result = App.Utils.text2html( source )
|
||||||
equal( result, should, source )
|
equal( result, should, source )
|
||||||
|
|
||||||
|
@ -149,4 +160,29 @@ test( "linkify", function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// quote
|
||||||
|
test( "quote", function() {
|
||||||
|
|
||||||
|
var source = "some text"
|
||||||
|
var should = '> some text'
|
||||||
|
var result = App.Utils.quote( source )
|
||||||
|
equal( result, should, source )
|
||||||
|
|
||||||
|
source = "some text\nsome other text\n"
|
||||||
|
should = "> some text\n> some other text"
|
||||||
|
result = App.Utils.quote( source )
|
||||||
|
equal( result, should, source )
|
||||||
|
|
||||||
|
source = "\n\nsome text\nsome other text\n \n"
|
||||||
|
should = "> some text\n> some other text"
|
||||||
|
result = App.Utils.quote( source )
|
||||||
|
equal( result, should, source )
|
||||||
|
|
||||||
|
source = "Welcome!\n\nThank you for installing Zammad.\n\nYou will find ..."
|
||||||
|
should = "> Welcome!\n>\n> Thank you for installing Zammad.\n>\n> You will find ..."
|
||||||
|
result = App.Utils.quote( source )
|
||||||
|
equal( result, should, source )
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
|
@ -24,4 +24,67 @@ class EmailBuildTest < ActiveSupport::TestCase
|
||||||
assert( result =~ /<b>test<\/b>/, 'test 2')
|
assert( result =~ /<b>test<\/b>/, 'test 2')
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test 'html email check' do
|
||||||
|
html = '<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||||
|
<head>
|
||||||
|
<body style="font-family:Geneva,Helvetica,Arial,sans-serif; font-size: 12px;">
|
||||||
|
<div>> Welcome!</div><div>></div><div>> Thank you for installing Zammad.</div><div>></div>
|
||||||
|
</body>
|
||||||
|
</html>'
|
||||||
|
mail = Channel::EmailBuild.build(
|
||||||
|
:from => 'sender@example.com',
|
||||||
|
:to => 'recipient@example.com',
|
||||||
|
:body => html,
|
||||||
|
:content_type => 'text/html',
|
||||||
|
)
|
||||||
|
|
||||||
|
should = '> Welcome!
|
||||||
|
>
|
||||||
|
> Thank you for installing Zammad.
|
||||||
|
>
|
||||||
|
'
|
||||||
|
assert_equal( should, mail.text_part.body.to_s )
|
||||||
|
assert_equal( html, mail.html_part.body.to_s )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
test 'html2text' do
|
||||||
|
html = '<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||||
|
<head>
|
||||||
|
<body style="font-family:Geneva,Helvetica,Arial,sans-serif; font-size: 12px;">
|
||||||
|
<div>> Welcome!</div><div>></div><div>> Thank you for installing Zammad.</div><div>></div>
|
||||||
|
</body>
|
||||||
|
</html>'
|
||||||
|
should = '> Welcome!
|
||||||
|
>
|
||||||
|
> Thank you for installing Zammad.
|
||||||
|
>
|
||||||
|
'
|
||||||
|
assert_equal( should, html.html2text )
|
||||||
|
|
||||||
|
|
||||||
|
html = ' line 1<br>
|
||||||
|
you<br/>
|
||||||
|
-----&'
|
||||||
|
should = 'line 1
|
||||||
|
you
|
||||||
|
-----&'
|
||||||
|
assert_equal( should, html.html2text )
|
||||||
|
|
||||||
|
|
||||||
|
html = ' <ul><li>#1</li><li>#2</li></ul>'
|
||||||
|
should = '* #1
|
||||||
|
* #2'
|
||||||
|
assert_equal( should, html.html2text )
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
Loading…
Reference in a new issue