Ext.namespace("Zarafa.core"); /** * @class Zarafa.core.HTMLParser * * Class for performing operations on HTML content. * * @singleton */ Zarafa.core.HTMLParser = (function() { // regular expression to strip all style tags with its content var stripStylesRe = /<style[^>]*>[\s\S]*?<\/style[^>]*>/gim; // regular expression to strip all style tags with its content var stripScriptsRe = /<script[^>]*>[\s\S]*?<\/script[^>]*>/gim; // regular expression to convert <br /> tags to newlines var br2nlRe = /<br\s*?\/*?>/gim; // regular expression to convert \r\n, \n or \r tags to <br /> var nl2brRe = /\r\n|\n|\r/gim; // regular expression to convert outlook style inline image urls to url which can request image using download_attachment.php var cidToUrlRe = /(src\s*=\s*[\"\']?)cid:([^ \"\']*)([\"\']?)/igm; // regular expression to convert url for inline images to outlook style url var urlToCidRe = /(src\s*=\s*[\"\']?)\S*attachCid=([^ &\"\']*)[^ \"\']*([\"\']?)/igm; return { /** * Strips all style tags, and also remove its contents * @param {Mixed} value The text from which to strip style tags * @return {String} The stripped text */ stripStyles : function(v) { return !v ? v : String(v).replace(stripStylesRe, ''); }, /** * Strips all script tags, and also remove its contents * @param {Mixed} value The text from which to strip script tags * @return {String} The stripped text */ stripScripts : function(v) { return !v ? v : String(v).replace(stripScriptsRe, ''); }, /** * Converts HTML tag <br /> to newline characters * @param {String} The string value to format. * @return {String} The string with embedded \n tags in place of <br />. */ br2nl : function(v) { return Ext.isEmpty(v) ? '' : v.replace(br2nlRe, '\n'); }, /** * Converts newline characters to HTML tag <br /> * @param {String} The string value to format. * @return {String} The string with embedded <br /> tags in place of \n. */ nl2br : function(v) { return Ext.isEmpty(v) ? '' : v.replace(nl2brRe, '<br>'); }, /** * Converts newline(\r\n, \r) characters to \n * @param {String} The string value to format. * @return {String} The string with embedded \n in place of \r\n or \r. */ rlnl2nl : function(v) { return Ext.isEmpty(v) ? '' : v.replace(/\r\n|\r/gim, '\n'); }, /** * Format string with plain-text contents into a HTML formatted string. * * This will convert new-line characters into <br /> elements. * * @param {String} content The plain-text contents to be formatted * @return {String} The HTML representation of the content */ convertPlainToHTML : function(content) { if(Ext.isEmpty(content)) { return content; } // convert all html entities to their html equivalents content = Zarafa.core.HTMLParser.entityEncode(content, 'ENT_NOQUOTES'); // We should wrap the content in <pre> tag to maintain // text indentation/spacing when we convert it to HTML. content = '<div><pre wrap style=\"white-space: pre-wrap; word-wrap: break-word;\">' + content + '</pre></div>'; // convert all breaklines content = Zarafa.core.HTMLParser.nl2br(content); return content; }, /** * Format string with HTML contents into a plain-text string. * * This will convert <br /> characters into \n elements. * * @param {String} content The HTML contents to be formatted * @return {String} The plain-text representation of the content */ convertHTMLToPlain : function(content) { if(Ext.isEmpty(content)) { return content; } //----- remove tags but preserve the content ---- // remove all select / options tags content = content.replace( /<[\/]?(?:select)[^>]*>/gim, '\n'); content = content.replace(/<[\/]?(?:option)[^>]*>/gim, '\t'); // replace all tags with their text equivalents content = content.replace(/<(?:hr)[^>]*>/gim, '\n-----------\n'); content = content.replace(/<[\/]?(?:h[123456]|div|p|pre|title)[^>]*>/gim, '\n\n'); content = content.replace(/<[\/]?(?:ul|ol|dl|dt|textarea|img)[^>]*>/gim, '\n'); content = content.replace(/<[\/]?(?:dd|li)[^>]*>/gim, '\t'); // tags related to table content = content.replace(/<[\/]?(?:table)[^>]*>/gim, '\n\n'); content = content.replace(/<[\/]?(?:caption|tr)[^>]*>/gim, '\n'); content = content.replace(/<[^\/]?(?:th|td)[^>]*>/gim, '<br />'); // remove anchor tag by preserving the links, links will be added after content of anchor tag in between <> signs content = content.replace(/<a[^>]* href=[\'\"]?([^\s\'\">]*)[^>]*>([\s\S]*?)<\/a[^>]*>/gim, '$2 <$1>'); //------ remove tags without preserving the contents ----- // remove style tags content = Zarafa.core.HTMLParser.stripStyles(content); // remove script tags content = Zarafa.core.HTMLParser.stripScripts(content); // remove comments content = content.replace(/<!--[\s\S]*?-->/gim, ''); // we have processed tags which are usefull for plain text conversion so now remove all remaining tags content = Zarafa.core.HTMLParser.stripUnwantedTags(content, ['br']); // decode html entities content = Zarafa.core.HTMLParser.entityDecode(content); // remove unnecessary space content = content.replace(/^\s*$/gm, ''); // add <br> in line which hasn't <br> at end of line content = content.replace(/(.*[^<>\n]$)/gm, '$1<br />'); // remove extra line breaks content = content.replace(/\n/gm, ''); // convert all breaklines content = Zarafa.core.HTMLParser.br2nl(content); // remove remaining html entities content = content.replace(/[&][#0-9a-z]*[;]/gim, ''); // remove breaklines from the end of the lines content = content.replace(/\n(?!\n)$/gm, ''); return content; }, /** * Function which strips unwanted tags, This function is whitelisting based so you need * to pass tags that are allowed in the text, all other tags will be removed. This function will * only remove tags and will not remove content in between tags. * @param {String} content html content * @param {Array} allowedTags tags that should not be removed from the content. * @return {String} content after removing unwanted tags. */ stripUnwantedTags : function (content, allowedTags) { // Match all HTML tags var matches = content.match(/(<\/?[^>]+>)/gi); var html = ''; var allowedTag = ''; var i = -1; var allowed = false; if(!allowedTags) { allowedTags = []; } // Go through all HTML tags if(matches && matches.length > 0) { for(var index1 = 0, len1 = matches.length; index1 < len1; index1++) { // Save HTML tag html = matches[index1].toString(); // flag to indicate that tag should be removed or not allowed = false; // Go through all allowed tags for(var index2 = 0, len2 = allowedTags.length; index2 < len2; index2++) { allowedTag = allowedTags[index2].toLowerCase(); i = -1; if (i !== 0) { i = html.toLowerCase().indexOf('<'+allowedTag+'>'); } if (i !== 0) { i = html.toLowerCase().indexOf('<'+allowedTag+' '); } if (i !== 0) { i = html.toLowerCase().indexOf('</'+allowedTag); } // Determine if (i === 0) { allowed = true; break; } } if (allowed !== true) { content = content.split(html).join(''); // Custom replace. No regexing } } } return content; }, /** * Function will check if data contains external contents in any html tag (img, audio, video), * and will also check for external stylesheets. * @param {String} data data that should be checked for external content. * @return {Boolean} true if data contains external content else false. */ hasExternalContent : function(data) { if(Ext.isEmpty(data)) { return false; } // @TODO more work needs for these regular expressions or else a dom based html parser // check tags whose attributes are src or background if(data.search(/(src|background)\s*=\s*([\'\"])*?\s*(https*:[^ \'\"]*)([\'\"])*/igm) !== -1) { return true; } // check tags whose attributes contains style attribute with external url if(data.search(/(style)\s*=(\S*)(url)\(([\'\"]*?)\s*(https*:.*[^\'\"])([\'\"]*?)\)/igm) !== -1) { return true; } return false; }, /** * Function will replace external content links with blank strings, so external content would not be loaded. * @param {String} data raw data. * @return {String} filtered data. */ blockExternalContent : function(data) { if(Ext.isEmpty(data)) { return data; } if (!Zarafa.core.HTMLParser.hasExternalContent(data)) { return data; } // @TODO more work needs for these regular expressions or else a dom based html parser data = data.replace(/(src|background)\s*=\s*([\'\"])*?\s*(https*:[^ \'\"]*)\s*([\'\"])*/igm, "$1=$2$4"); data = data.replace(/(style)\s*=(\S*)(url)\(([\'\"]*?)\s*(https*:.*[^\'\"])([\'\"]*?)\)/igm, "$1=$2$3($4$6)"); return data; }, /** * Function will return translation table for HTML entities which can be used to * encode/decode HTML entities. * @param {String} tableType type of table to get, options are HTML_SPECIALCHARS or HTML_ENTITIES. * @param {String} quoteStyle options are ENT_COMPAT, ENT_NOQUOTES or ENT_QUOTES. * @return {Object} table for translation of HTML entities */ getHTMLTranslationTable : function(tableType, quoteStyle) { if(!tableType) { tableType = 'HTML_SPECIALCHARS'; } if(!quoteStyle) { quoteStyle = 'ENT_COMPAT'; } var entities = {}; entities['38'] = '&'; if (tableType === 'HTML_ENTITIES') { entities['94'] = 'ˆ'; entities['126'] = '˜'; entities['130'] = '‚'; // Single Low-9 Quotation Mark entities['131'] = 'ƒ'; // Latin Small Letter F With Hook entities['132'] = '„'; // Double Low-9 Quotation Mark entities['133'] = '…'; // Horizontal Ellipsis entities['134'] = '†'; // Dagger entities['135'] = '‡'; // Double Dagger entities['136'] = 'ˆ'; // Modifier Letter Circumflex Accent entities['137'] = '‰'; // Per Mille Sign entities['138'] = 'Š'; // Latin Capital Letter S With Caron entities['139'] = '‹'; // Single Left-Pointing Angle Quotation Mark entities['140'] = 'Œ'; // Latin Capital Ligature OE entities['145'] = '‘'; // Left Single Quotation Mark entities['146'] = '’'; // Right Single Quotation Mark entities['147'] = '“'; // Left Double Quotation Mark entities['148'] = '”'; // Right Double Quotation Mark entities['149'] = '•'; // Bullet entities['150'] = '–'; // En Dash entities['151'] = '—'; // Em Dash entities['152'] = '˜'; // Small Tilde entities['153'] = '™'; // Trade Mark Sign entities['154'] = 'š'; // Latin Small Letter S With Caron entities['155'] = '›'; // Single Right-Pointing Angle Quotation Mark entities['156'] = 'œ'; // Latin Small Ligature OE entities['159'] = 'Ÿ'; // Latin Capital Letter Y With Diaeresis entities['160'] = ' '; // Non-breaking space entities['161'] = '¡'; // Inverted exclamation mark entities['162'] = '¢'; // Cent sign entities['163'] = '£'; // Pound sign entities['164'] = '¤'; // Currency sign entities['165'] = '¥'; // Yen sign entities['166'] = '¦'; // Broken vertical bar entities['167'] = '§'; // Section sign entities['168'] = '¨'; // Diaeresis entities['169'] = '©'; // Copyright sign entities['170'] = 'ª'; // Feminine ordinal indicator entities['171'] = '«'; // Left-pointing double angle quotation mark entities['172'] = '¬'; // Not sign entities['173'] = '­'; // Soft hyphen entities['174'] = '®'; // Registered sign entities['175'] = '¯'; // Macron entities['176'] = '°'; // Degree sign entities['177'] = '±'; // Plus-minus sign entities['178'] = '²'; // Superscript two entities['179'] = '³'; // Superscript three entities['180'] = '´'; // Acute accent entities['181'] = 'µ'; // Micro sign entities['182'] = '¶'; // Pilcrow sign entities['183'] = '·'; // Middle dot entities['184'] = '¸'; // Cedilla entities['185'] = '¹'; // Superscript one entities['186'] = 'º'; // Masculine ordinal indicator entities['187'] = '»'; // Right-pointing double angle quotation mark entities['188'] = '¼'; // Vulgar fraction one-quarter entities['189'] = '½'; // Vulgar fraction one-half entities['190'] = '¾'; // Vulgar fraction three-quarters entities['191'] = '¿'; // Inverted question mark entities['192'] = 'À'; // A with grave entities['193'] = 'Á'; // A with acute entities['194'] = 'Â'; // A with circumflex entities['195'] = 'Ã'; // A with tilde entities['196'] = 'Ä'; // A with diaeresis entities['197'] = 'Å'; // A with ring above entities['198'] = 'Æ'; // AE entities['199'] = 'Ç'; // C with cedilla entities['200'] = 'È'; // E with grave entities['201'] = 'É'; // E with acute entities['202'] = 'Ê'; // E with circumflex entities['203'] = 'Ë'; // E with diaeresis entities['204'] = 'Ì'; // I with grave entities['205'] = 'Í'; // I with acute entities['206'] = 'Î'; // I with circumflex entities['207'] = 'Ï'; // I with diaeresis entities['208'] = 'Ð'; // Eth entities['209'] = 'Ñ'; // N with tilde entities['210'] = 'Ò'; // O with grave entities['211'] = 'Ó'; // O with acute entities['212'] = 'Ô'; // O with circumflex entities['213'] = 'Õ'; // O with tilde entities['214'] = 'Ö'; // O with diaeresis entities['215'] = '×'; // Multiplication sign entities['216'] = 'Ø'; // O with stroke entities['217'] = 'Ù'; // U with grave entities['218'] = 'Ú'; // U with acute entities['219'] = 'Û'; // U with circumflex entities['220'] = 'Ü'; // U with diaeresis entities['221'] = 'Ý'; // Y with acute entities['222'] = 'Þ'; // Thorn entities['223'] = 'ß'; // Sharp s. Also known as ess-zed entities['224'] = 'à'; // a with grave entities['225'] = 'á'; // a with acute entities['226'] = 'â'; // a with circumflex entities['227'] = 'ã'; // a with tilde entities['228'] = 'ä'; // a with diaeresis entities['229'] = 'å'; // a with ring above entities['230'] = 'æ'; // ae. Also known as ligature ae entities['231'] = 'ç'; // c with cedilla entities['232'] = 'è'; // e with grave entities['233'] = 'é'; // e with acute entities['234'] = 'ê'; // e with circumflex entities['235'] = 'ë'; // e with diaeresis entities['236'] = 'ì'; // i with grave entities['237'] = 'í'; // i with acute entities['238'] = 'î'; // i with circumflex entities['239'] = 'ï'; // i with diaeresis entities['240'] = 'ð'; // eth entities['241'] = 'ñ'; // n with tilde entities['242'] = 'ò'; // o with grave entities['243'] = 'ó'; // o with acute entities['244'] = 'ô'; // o with circumflex entities['245'] = 'õ'; // o with tilde entities['246'] = 'ö'; // o with diaeresis entities['247'] = '÷'; // Division sign entities['248'] = 'ø'; // o with stroke. Also known as o with slash entities['249'] = 'ù'; // u with grave entities['250'] = 'ú'; // u with acute entities['251'] = 'û'; // u with circumflex entities['252'] = 'ü'; // u with diaeresis entities['253'] = 'ý'; // y with acute entities['254'] = 'þ'; // thorn entities['255'] = 'ÿ'; // y with diaeresis entities['264'] = 'Ĉ'; // Latin capital letter C with circumflex entities['265'] = 'ĉ'; // Latin small letter c with circumflex entities['338'] = 'Œ'; // Latin capital ligature OE entities['339'] = 'œ'; // Latin small ligature oe entities['352'] = 'Š'; // Latin capital letter S with caron entities['353'] = 'š'; // Latin small letter s with caron entities['372'] = 'Ŵ'; // Latin capital letter W with circumflex entities['373'] = 'ŵ'; // Latin small letter w with circumflex entities['374'] = 'Ŷ'; // Latin capital letter Y with circumflex entities['375'] = 'ŷ'; // Latin small letter y with circumflex entities['376'] = 'Ÿ'; // Latin capital letter Y with diaeresis entities['402'] = 'ƒ'; // Latin small f with hook, function, florin entities['710'] = 'ˆ'; // Modifier letter circumflex accent entities['732'] = '˜'; // Small tilde entities['913'] = 'Α'; // Alpha entities['914'] = 'Β'; // Beta entities['915'] = 'Γ'; // Gamma entities['916'] = 'Δ'; // Delta entities['917'] = 'Ε'; // Epsilon entities['918'] = 'Ζ'; // Zeta entities['919'] = 'Η'; // Eta entities['920'] = 'Θ'; // Theta entities['921'] = 'Ι'; // Iota entities['922'] = 'Κ'; // Kappa entities['923'] = 'Λ'; // Lambda entities['924'] = 'Μ'; // Mu entities['925'] = 'Ν'; // Nu entities['926'] = 'Ξ'; // Xi entities['927'] = 'Ο'; // Omicron entities['928'] = 'Π'; // Pi entities['929'] = 'Ρ'; // Rho entities['931'] = 'Σ'; // Sigma entities['932'] = 'Τ'; // Tau entities['933'] = 'Υ'; // Upsilon entities['934'] = 'Φ'; // Phi entities['935'] = 'Χ'; // Chi entities['936'] = 'Ψ'; // Psi entities['937'] = 'Ω'; // Omega entities['945'] = 'α'; // alpha entities['946'] = 'β'; // beta entities['947'] = 'γ'; // gamma entities['948'] = 'δ'; // delta entities['949'] = 'ε'; // epsilon entities['950'] = 'ζ'; // zeta entities['951'] = 'η'; // eta entities['952'] = 'θ'; // theta entities['953'] = 'ι'; // iota entities['954'] = 'κ'; // kappa entities['955'] = 'λ'; // lambda entities['956'] = 'μ'; // mu entities['957'] = 'ν'; // nu entities['958'] = 'ξ'; // xi entities['959'] = 'ο'; // omicron entities['960'] = 'π'; // pi entities['961'] = 'ρ'; // rho entities['962'] = 'ς'; // sigmaf entities['963'] = 'σ'; // sigma entities['964'] = 'τ'; // tau entities['965'] = 'υ'; // upsilon entities['966'] = 'φ'; // phi entities['967'] = 'χ'; // chi entities['968'] = 'ψ'; // psi entities['969'] = 'ω'; // omega entities['977'] = 'ϑ'; // Theta symbol entities['978'] = 'ϒ'; // Greek upsilon with hook symbol entities['982'] = 'ϖ'; // Pi symbol entities['8194'] = ' '; // En space entities['8195'] = ' '; // Em space entities['8201'] = ' '; // Thin space entities['8204'] = '‌'; // Zero width non-joiner entities['8205'] = '‍'; // Zero width joiner entities['8206'] = '‎'; // Left-to-right mark entities['8207'] = '‏'; // Right-to-left mark entities['8211'] = '–'; // En dash entities['8212'] = '—'; // Em dash entities['8216'] = '‘'; // Left single quotation mark entities['8217'] = '’'; // Right single quotation mark entities['8218'] = '‚'; // Single low-9 quotation mark entities['8220'] = '“'; // Left double quotation mark entities['8221'] = '”'; // Right double quotation mark entities['8222'] = '„'; // Double low-9 quotation mark entities['8224'] = '†'; // Dagger entities['8225'] = '‡'; // Double dagger entities['8226'] = '•'; // Bullet entities['8230'] = '…'; // Horizontal ellipsis entities['8240'] = '‰'; // Per mille sign entities['8242'] = '′'; // Prime entities['8243'] = '″'; // Double Prime entities['8249'] = '‹'; // Single left-pointing angle quotation entities['8250'] = '›'; // Single right-pointing angle quotation entities['8254'] = '‾'; // Overline entities['8260'] = '⁄'; // Fraction Slash entities['8364'] = '€'; // Euro sign entities['8472'] = '℘'; // Script capital entities['8465'] = 'ℑ'; // Blackletter capital I entities['8476'] = 'ℜ'; // Blackletter capital R entities['8482'] = '™'; // Trade mark sign entities['8501'] = 'ℵ'; // Alef symbol entities['8592'] = '←'; // Leftward arrow entities['8593'] = '↑'; // Upward arrow entities['8594'] = '→'; // Rightward arrow entities['8595'] = '↓'; // Downward arrow entities['8596'] = '↔'; // Left right arrow entities['8629'] = '↵'; // Downward arrow with corner leftward. Also known as carriage return entities['8656'] = '⇐'; // Leftward double arrow. ISO 10646 does not say that lArr is the same as the 'is implied by' arrow but also does not have any other character for that function. So ? lArr can be used for 'is implied by' as ISOtech suggests entities['8657'] = '⇑'; // Upward double arrow entities['8658'] = '⇒'; // Rightward double arrow. ISO 10646 does not say this is the 'implies' character but does not have another character with this function so ? rArr can be used for 'implies' as ISOtech suggests entities['8659'] = '⇓'; // Downward double arrow entities['8660'] = '⇔'; // Left-right double arrow // Mathematical Operators entities['8704'] = '∀'; // For all entities['8706'] = '∂'; // Partial differential entities['8707'] = '∃'; // There exists entities['8709'] = '∅'; // Empty set. Also known as null set and diameter entities['8711'] = '∇'; // Nabla. Also known as backward difference entities['8712'] = '∈'; // Element of entities['8713'] = '∉'; // Not an element of entities['8715'] = '∋'; // Contains as member entities['8719'] = '∏'; // N-ary product. Also known as product sign. Prod is not the same character as U+03A0 'greek capital letter pi' though the same glyph might be used for both entities['8721'] = '∑'; // N-ary summation. Sum is not the same character as U+03A3 'greek capital letter sigma' though the same glyph might be used for both entities['8722'] = '−'; // Minus sign entities['8727'] = '∗'; // Asterisk operator entities['8729'] = '∙'; // Bullet operator entities['8730'] = '√'; // Square root. Also known as radical sign entities['8733'] = '∝'; // Proportional to entities['8734'] = '∞'; // Infinity entities['8736'] = '∠'; // Angle entities['8743'] = '∧'; // Logical and. Also known as wedge entities['8744'] = '∨'; // Logical or. Also known as vee entities['8745'] = '∩'; // Intersection. Also known as cap entities['8746'] = '∪'; // Union. Also known as cup entities['8747'] = '∫'; // Integral entities['8756'] = '∴'; // Therefore entities['8764'] = '∼'; // tilde operator. Also known as varies with and similar to. The tilde operator is not the same character as the tilde, U+007E, although the same glyph might be used to represent both entities['8773'] = '≅'; // Approximately equal to entities['8776'] = '≈'; // Almost equal to. Also known as asymptotic to entities['8800'] = '≠'; // Not equal to entities['8801'] = '≡'; // Identical to entities['8804'] = '≤'; // Less-than or equal to entities['8805'] = '≥'; // Greater-than or equal to entities['8834'] = '⊂'; // Subset of entities['8835'] = '⊃'; // Superset of. Note that nsup, 'not a superset of, U+2283' is not covered by the Symbol font encoding and is not included. entities['8836'] = '⊄'; // Not a subset of entities['8838'] = '⊆'; // Subset of or equal to entities['8839'] = '⊇'; // Superset of or equal to entities['8853'] = '⊕'; // Circled plus. Also known as direct sum entities['8855'] = '⊗'; // Circled times. Also known as vector product entities['8869'] = '⊥'; // Up tack. Also known as orthogonal to and perpendicular entities['8901'] = '⋅'; // Dot operator. The dot operator is not the same character as U+00B7 middle dot // Miscellaneous Technical entities['8968'] = '⌈'; // Left ceiling. Also known as an APL upstile entities['8969'] = '⌉'; // Right ceiling entities['8970'] = '⌊'; // left floor. Also known as APL downstile entities['8971'] = '⌋'; // Right floor entities['9001'] = '⟨'; // Left-pointing angle bracket. Also known as bra. Lang is not the same character as U+003C 'less than'or U+2039 'single left-pointing angle quotation mark' entities['9002'] = '⟩'; // Right-pointing angle bracket. Also known as ket. Rang is not the same character as U+003E 'greater than' or U+203A 'single right-pointing angle quotation mark' // Geometric Shapes entities['9642'] = '▪'; // Black small square entities['9643'] = '▫'; // White small square entities['9674'] = '◊'; // Lozenge // Miscellaneous Symbols entities['9702'] = '◦'; // White bullet entities['9824'] = '♠'; // Black (filled) spade suit entities['9827'] = '♣'; // Black (filled) club suit. Also known as shamrock entities['9829'] = '♥'; // Black (filled) heart suit. Also known as shamrock entities['9830'] = '♦'; // Black (filled) diamond suit } if (quoteStyle !== 'ENT_NOQUOTES') { entities['34'] = '"'; } if (quoteStyle === 'ENT_QUOTES') { entities['39'] = '''; } entities['60'] = '<'; entities['62'] = '>'; // ascii decimals to real symbols var decimal; var hashMap = {}; for (decimal in entities) { hashMap[String.fromCharCode(decimal)] = entities[decimal]; } return hashMap; }, /** * Function will decode HTML entities in the string. * @param {String} content string that should be decoded. * @param {String} quoteStyle options are ENT_COMPAT, ENT_NOQUOTES or ENT_QUOTES. * @return {String} decoded string. */ entityDecode : function(content, quoteStyle) { var hashMap = Zarafa.core.HTMLParser.getHTMLTranslationTable('HTML_ENTITIES', quoteStyle); var symbol = ''; var entity = ''; for (symbol in hashMap) { entity = hashMap[symbol]; content = content.split(entity).join(symbol); } content = content.split(''').join('\''); return content; }, /** * Function will encode HTML entities in the string. * @param {String} content string that should be encoded. * @param {String} quoteStyle options are ENT_COMPAT, ENT_NOQUOTES or ENT_QUOTES. * @return {String} decoded string. */ entityEncode : function(content, quoteStyle) { var hashMap = Zarafa.core.HTMLParser.getHTMLTranslationTable('HTML_ENTITIES', quoteStyle); var symbol = ''; var entity = ''; for (symbol in hashMap) { entity = hashMap[symbol]; content = content.split(symbol).join(entity); } content = content.split('\'').join('''); return content; }, /** * Function to convert from Outlook inline attachment format (src="cid:...") to img tag * that will display the image (by querying download_attachment.php) * Builds up the query string for asking the image, using store and record entryid, and content id * @param {String} body The message body to be modified * @param {String} storeEntryId The store entryid * @param {String} entryId The message entryid * @param {Array} attachNum Attachment number of the attachment that should be downloaded. * When accessing embedded messages this array can contain multiple elements indicating * attachment numbers at each level, So value [0, 1] will indicate we want to download * second attachment of first embedded message. * @return {String} the modified HTML body */ inlineImgOutlookToZarafa : function(body, storeEntryId, entryId, attachNum) { var cidToUrl = function(match, srcStart, imgCid, srcEnd, offset, str) { if(imgCid) { var url = container.getBaseURL(); url = Ext.urlAppend(url, 'load=download_attachment'); url = Ext.urlAppend(url, 'attachCid=' + imgCid); url = Ext.urlAppend(url, 'store=' + storeEntryId); url = Ext.urlAppend(url, 'entryid=' + entryId); url = Ext.urlAppend(url, 'contentDispositionType=inline'); if(!Ext.isEmpty(attachNum)) { for (var i = 0; i< attachNum.length; i++) { url = Ext.urlAppend(url, 'attachNum[]=' + attachNum[i]); } } // return our own url for getting inline attachments return srcStart + url + srcEnd; } // return match as it is but in a real world this is not going to happen return match; }; // replace cid: with our own url to get inline attachment return body.replace(cidToUrlRe, cidToUrl); }, /** * Function to convert from Zarafa inline img format to Outlook format (src="cid:...") * Grabs the cid from the img tag (src="...attachCid=...") * @param {String} body the message body to be modified * @return {String} the modified html body */ inlineImgZarafaToOutlook : function(body) { if(!Ext.isDefined(body)){ return; } var urlToCid = function(match, srcStart, imgCid, srcEnd, offset, str) { if(imgCid) { // return img src with just cid: tag return srcStart + 'cid:' + imgCid + srcEnd; } // return match as it is but in a real world this is not going to happen return match; }; // replace our own url with cid: return body.replace(urlToCidRe, urlToCid); } }; })();