Improved App.Utils class.

This commit is contained in:
Martin Edenhofer 2015-12-27 23:29:04 +01:00
parent caa3e77997
commit 8b10b2accf
4 changed files with 217 additions and 62 deletions

View file

@ -1,24 +1,24 @@
# coffeelint: disable=no_unnecessary_double_quotes
class App.Utils
# textCleand = App.Utils.textCleanup( rawText )
@textCleanup: ( ascii ) ->
# textCleand = App.Utils.textCleanup(rawText)
@textCleanup: (ascii) ->
$.trim( ascii )
.replace(/(\r\n|\n\r)/g, "\n") # cleanup
.replace(/\r/g, "\n") # cleanup
.replace(/[ ]\n/g, "\n") # remove tailing spaces
.replace(/\n{3,20}/g, "\n\n") # remove multiple empty lines
# htmlEscapedAndLinkified = App.Utils.text2html( rawText )
@text2html: ( ascii ) ->
# htmlEscapedAndLinkified = App.Utils.text2html(rawText)
@text2html: (ascii) ->
ascii = @textCleanup(ascii)
#ascii = @htmlEscape(ascii)
ascii = @linkify(ascii)
ascii = '<div>' + ascii.replace(/\n/g, '</div><div>') + '</div>'
ascii.replace(/<div><\/div>/g, '<div><br></div>')
# rawText = App.Utils.html2text( html )
@html2text: ( html ) ->
# rawText = App.Utils.html2text(html)
@html2text: (html) ->
# remove not needed new lines
html = html.replace(/>\n/g, '>')
@ -37,11 +37,11 @@ class App.Utils
.replace(/\r/g, "\n") # cleanup
.replace(/\n{3,20}/g, "\n\n") # remove multiple empty lines
# htmlEscapedAndLinkified = App.Utils.linkify( rawText )
# htmlEscapedAndLinkified = App.Utils.linkify(rawText)
@linkify: (ascii) ->
window.linkify( ascii )
window.linkify(ascii)
# wrappedText = App.Utils.wrap( rawText, maxLineLength )
# wrappedText = App.Utils.wrap(rawText, maxLineLength)
@wrap: (ascii, max = 82) ->
result = ''
counter_lines = 0
@ -80,19 +80,19 @@ class App.Utils
result += "\n"
result
# quotedText = App.Utils.quote( rawText )
# quotedText = App.Utils.quote(rawText)
@quote: (ascii, max = 82) ->
ascii = @textCleanup(ascii)
ascii = @wrap(ascii, max)
$.trim( ascii )
$.trim(ascii)
.replace /^(.*)$/mg, (match) ->
if match
'> ' + match
else
'>'
# htmlEscaped = App.Utils.htmlEscape( rawText )
@htmlEscape: ( ascii ) ->
# htmlEscaped = App.Utils.htmlEscape(rawText)
@htmlEscape: (ascii) ->
return ascii if !ascii
return ascii if !ascii.replace
ascii.replace(/&/g, '&amp;')
@ -101,8 +101,9 @@ class App.Utils
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
# textWithoutTags = App.Utils.htmlRemoveTags( html )
# textWithoutTags = App.Utils.htmlRemoveTags(html)
@htmlRemoveTags: (html) ->
html = @_checkTypeOf(html)
# remove comments
@_removeComments(html)
@ -111,17 +112,18 @@ class App.Utils
@_removeWordMarkup(html)
# remove tags, keep content
html.find('div, span, p, li, ul, ol, a, b, u, i, label, small, strong, strike, pre, code, center, blockquote, form, textarea, font, address, table, thead, tbody, tr, td, h1, h2, h3, h4, h5, h6').replaceWith( ->
html.find('div, span, p, li, ul, ol, a, b, u, i, label, small, strong, strike, pre, code, center, blockquote, form, fieldset, textarea, font, address, table, thead, tbody, tr, td, h1, h2, h3, h4, h5, h6').replaceWith( ->
$(@).contents()
)
# remove tags & content
html.find('div, span, p, li, ul, ol, a, b, u, i, label, small, strong, strike, pre, code, center, blockquote, form, textarea, font, table, thead, tbody, tr, td, h1, h2, h3, h4, h5, h6, br, hr, img, svg, input, select, button, style, applet, embed, noframes, canvas, script, frame, iframe').remove()
html.find('div, span, p, li, ul, ol, a, b, u, i, label, small, strong, strike, pre, code, center, blockquote, form, fieldset, textarea, font, table, thead, tbody, tr, td, h1, h2, h3, h4, h5, h6, br, hr, img, svg, input, select, button, style, applet, embed, noframes, canvas, script, frame, iframe, meta, link, title, head').remove()
html
# htmlOnlyWithRichtext = App.Utils.htmlRemoveRichtext( html )
# htmlOnlyWithRichtext = App.Utils.htmlRemoveRichtext(html)
@htmlRemoveRichtext: (html) ->
html = @_checkTypeOf(html)
# remove comments
@_removeComments(html)
@ -133,17 +135,18 @@ class App.Utils
@_removeWordMarkup(html)
# remove tags, keep content
html.find('li, ul, ol, a, b, u, i, label, small, strong, strike, pre, code, center, blockquote, form, textarea, font, address, table, thead, tbody, tr, td, h1, h2, h3, h4, h5, h6').replaceWith( ->
html.find('li, ul, ol, a, b, u, i, label, small, strong, strike, pre, code, center, blockquote, form, fieldset, textarea, font, address, table, thead, tbody, tr, td, h1, h2, h3, h4, h5, h6').replaceWith( ->
$(@).contents()
)
# remove tags & content
html.find('li, ul, ol, a, b, u, i, label, small, strong, strike, pre, code, center, blockquote, form, textarea, font, address, table, thead, tbody, tr, td, h1, h2, h3, h4, h5, h6, hr, img, svg, input, select, button, style, applet, embed, noframes, canvas, script, frame, iframe').remove()
html.find('li, ul, ol, a, b, u, i, label, small, strong, strike, pre, code, center, blockquote, form, fieldset, textarea, font, address, table, thead, tbody, tr, td, h1, h2, h3, h4, h5, h6, hr, img, svg, input, select, button, style, applet, embed, noframes, canvas, script, frame, iframe, meta, link, title, head').remove()
html
# cleanHtmlWithRichText = App.Utils.htmlCleanup( html )
# cleanHtmlWithRichText = App.Utils.htmlCleanup(html)
@htmlCleanup: (html) ->
html = @_checkTypeOf(html)
# remove comments
@_removeComments(html)
@ -155,7 +158,7 @@ class App.Utils
@_removeWordMarkup(html)
# remove tags, keep content
html.find('a, font, small, time, form').replaceWith( ->
html.find('a, font, small, time, form, label').replaceWith( ->
$(@).contents()
)
@ -179,16 +182,22 @@ class App.Utils
)
# remove tags & content
html.find('font, hr, img, svg, input, select, button, style, applet, embed, noframes, canvas, script, frame, iframe').remove()
html.find('font, hr, img, svg, input, select, button, style, applet, embed, noframes, canvas, script, frame, iframe, meta, link, title, head, fieldset').remove()
html
@_checkTypeOf: (item) ->
return item if typeof item isnt 'string'
return $(item) if item.substr(0,9) isnt '<!DOCTYPE' && item.substr(0,5) isnt '<html'
$("<div>#{item}</div>")
@_removeAttributes: (html) ->
html.find('*')
.removeAttr( 'style' )
.removeAttr( 'class' )
.removeAttr( 'title' )
.removeAttr( 'lang' )
.removeAttr('style')
.removeAttr('class')
.removeAttr('title')
.removeAttr('lang')
.removeAttr('type')
html
@_removeComments: (html) ->
@ -201,37 +210,38 @@ class App.Utils
@_removeWordMarkup: (html) ->
match = false
htmlTmp = html.get(0).outerHTML
regex = new RegExp('<(/w|w)\:[A-Za-z]{3}>')
regex = new RegExp('<(/w|w)\:[A-Za-z]')
if htmlTmp.match(regex)
match = true
htmlTmp = htmlTmp.replace(regex, '')
regex = new RegExp('<(/o|o)\:[A-Za-z]{1}>')
regex = new RegExp('<(/o|o)\:[A-Za-z]')
if htmlTmp.match(regex)
match = true
htmlTmp = htmlTmp.replace(regex, '')
if match
html.html(htmlTmp)
return window.word_filter(html)
html
# signatureNeeded = App.Utils.signatureCheck( message, signature )
# signatureNeeded = App.Utils.signatureCheck(message, signature)
@signatureCheck: (message, signature) ->
messageText = $( '<div>' + message + '</div>' ).text().trim()
messageText = $('<div>' + message + '</div>').text().trim()
messageText = messageText.replace(/(\n|\r|\t)/g, '')
signatureText = $( '<div>' + signature + '</div>' ).text().trim()
signatureText = $('<div>' + signature + '</div>').text().trim()
signatureText = signatureText.replace(/(\n|\r|\t)/g, '')
quote = (str) ->
(str + '').replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&")
#console.log('SC', messageText, signatureText, quote(signatureText))
regex = new RegExp( quote(signatureText), 'mi' )
regex = new RegExp(quote(signatureText), 'mi')
if messageText.match(regex)
false
else
true
# messageWithMarker = App.Utils.signatureIdentify( message, false )
# messageWithMarker = App.Utils.signatureIdentify(message, false)
@signatureIdentify: (message, test = false) ->
textToSearch = @html2text( message )
textToSearch = @html2text(message)
# count lines, if we do have lower the 10, ignore this
textToSearchInLines = textToSearch.split("\n")
@ -450,19 +460,23 @@ class App.Utils
value
)
# true|false = App.Utils.lastLineEmpty( message )
# true|false = App.Utils.lastLineEmpty(message)
@lastLineEmpty: (message) ->
messageCleanup = message.replace(/>\s+</g, '><').replace(/(\n|\r|\t)/g, '').trim()
return true if messageCleanup.match(/<(br|\s+?|\/)>$/im)
return true if messageCleanup.match(/<div(|\s.+?)><\/div>$/im)
false
# cleanString = App.Utils.htmlAttributeCleanup( string )
# string = App.Utils.removeEmptyLines(stringWithEmptyLines)
@removeEmptyLines: (string) ->
string.replace(/^\s*[\r\n]/gm, '')
# cleanString = App.Utils.htmlAttributeCleanup(string)
@htmlAttributeCleanup: (string) ->
string.replace(/((?![-a-zA-Z0-9_]+).|\n|\r|\t)/gm, '')
# diff = App.Utils.formDiff( dataNow, dataLast )
@formDiff: ( dataNowRaw, dataLastRaw ) ->
# diff = App.Utils.formDiff(dataNow, dataLast)
@formDiff: (dataNowRaw, dataLastRaw) ->
dataNow = clone(dataNowRaw)
@_formDiffNormalizer(dataNow)
dataLast = clone(dataLastRaw)

View file

@ -96,41 +96,54 @@
// just paste text
this.$element.on('paste', function (e) {
e.preventDefault()
_this.log('paste')
// check existing + paste text for limit
var text
if (window.clipboardData) { // IE
text = window.clipboardData.getData('Text')
var text = e.originalEvent.clipboardData.getData('text/html')
var docType = 'html'
if (!text || text.length === 0) {
docType = 'text'
text = e.originalEvent.clipboardData.getData('text/plain')
}
else {
text = (e.originalEvent || e).clipboardData.getData('text/plain')
if (!text || text.length === 0) {
docType = 'text2'
text = e.originalEvent.clipboardData.getData('text')
}
_this.log('paste', docType, text)
if ( !_this.maxLengthOk( text.length) ) {
e.preventDefault()
if (!_this.maxLengthOk(text.length)) {
return
}
// use setTimeout() with 0 to execute it right after paste event
if ( _this.options.mode === 'textonly' ) {
if ( !_this.options.multiline ) {
setTimeout($.proxy(function(){
App.Utils.htmlRemoveTags(this.$element)
}, _this), 0)
if (docType == 'html') {
text = '<div>' + text + '</div>' // to prevent multible dom object. we need it at level 0
if (_this.options.mode === 'textonly') {
if (!_this.options.multiline) {
text = App.Utils.htmlRemoveTags(text)
}
else {
text = App.Utils.htmlRemoveRichtext(text)
}
}
else {
setTimeout($.proxy(function(){
App.Utils.htmlRemoveRichtext(this.$element)
}, _this), 0)
text = App.Utils.htmlCleanup(text)
}
text = text.html()
// as fallback, take text
if (!text) {
text = App.Utils.text2html(text.text())
}
}
else {
setTimeout($.proxy(function(){
App.Utils.htmlCleanup(this.$element)
}, _this), 0)
text = App.Utils.text2html(text)
}
// cleanup
text = App.Utils.removeEmptyLines(text)
_this.log('insert', test)
document.execCommand('insertHTML', false, text)
return true
})

View file

@ -0,0 +1,84 @@
// (C) sbrin - https://github.com/sbrin
// https://gist.github.com/sbrin/6801034
window.word_filter = function(editor){
var content = editor.html();
// Word comments like conditional comments etc
content = content.replace(/<!--[\s\S]+?-->/gi, '');
// Remove comments, scripts (e.g., msoShowComment), XML tag, VML content,
// MS Office namespaced tags, and a few other tags
content = content.replace(/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi, '');
// Convert <s> into <strike> for line-though
content = content.replace(/<(\/?)s>/gi, "<$1strike>");
// Replace nbsp entites to char since it's easier to handle
//content = content.replace(/&nbsp;/gi, "\u00a0");
content = content.replace(/&nbsp;/gi, ' ');
// Convert <span style="mso-spacerun:yes">___</span> to string of alternating
// breaking/non-breaking spaces of same length
content = content.replace(/<span\s+style\s*=\s*"\s*mso-spacerun\s*:\s*yes\s*;?\s*"\s*>([\s\u00a0]*)<\/span>/gi, function(str, spaces) {
return (spaces.length > 0) ? spaces.replace(/./, " ").slice(Math.floor(spaces.length/2)).split("").join("\u00a0") : '';
});
editor.html(content);
// Parse out list indent level for lists
$('p', editor).each(function(){
var str = $(this).attr('style');
var matches = /mso-list:\w+ \w+([0-9]+)/.exec(str);
if (matches) {
$(this).data('_listLevel', parseInt(matches[1], 10));
}
});
// Parse Lists
var last_level=0;
var pnt = null;
$('p', editor).each(function(){
var cur_level = $(this).data('_listLevel');
if(cur_level != undefined){
var txt = $(this).text();
var list_tag = '<ul></ul>';
if (/^\s*\w+\./.test(txt)) {
var matches = /([0-9])\./.exec(txt);
if (matches) {
var start = parseInt(matches[1], 10);
list_tag = start>1 ? '<ol start="' + start + '"></ol>' : '<ol></ol>';
}else{
list_tag = '<ol></ol>';
}
}
if(cur_level>last_level){
if(last_level==0){
$(this).before(list_tag);
pnt = $(this).prev();
}else{
pnt = $(list_tag).appendTo(pnt);
}
}
if(cur_level<last_level){
for(var i=0; i<last_level-cur_level; i++){
pnt = pnt.parent();
}
}
$('span:first', this).remove();
pnt.append('<li>' + $(this).html() + '</li>')
$(this).remove();
last_level = cur_level;
}else{
last_level = 0;
}
})
$('[style]', editor).removeAttr('style');
$('[align]', editor).removeAttr('align');
$('span', editor).replaceWith(function() {return $(this).contents();});
$('span:empty', editor).remove();
$("[class^='Mso']", editor).removeAttr('class');
$('p:empty', editor).remove();
return editor
}

File diff suppressed because one or more lines are too long