Improved App.Utils class.
This commit is contained in:
parent
caa3e77997
commit
8b10b2accf
4 changed files with 217 additions and 62 deletions
|
@ -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, '&')
|
||||
|
@ -101,8 +101,9 @@ class App.Utils
|
|||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
|
||||
# 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)
|
||||
|
|
|
@ -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
|
||||
})
|
||||
|
||||
|
|
84
app/assets/javascripts/app/lib/base/word_filter.js
Normal file
84
app/assets/javascripts/app/lib/base/word_filter.js
Normal 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(/ /gi, "\u00a0");
|
||||
content = content.replace(/ /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
Loading…
Reference in a new issue