diff --git a/plugins/kolab_notes/kolab_notes.php b/plugins/kolab_notes/kolab_notes.php index 87a7a7e5..9a613f65 100644 --- a/plugins/kolab_notes/kolab_notes.php +++ b/plugins/kolab_notes/kolab_notes.php @@ -337,7 +337,7 @@ class kolab_notes extends rcube_plugin } // clean HTML contents - if (!empty($note['description']) && preg_match('/<(html|body|div|p|span)(\s+[a-z]|>)/', $note['description'])) { + if (!empty($note['description']) && preg_match('/<(html|body)(\s+[a-z]|>)/', $note['description'], $m) && strpos($note['description'], '') > 0) { $note['html'] = $this->_wash_html($note['description']); } @@ -426,7 +426,7 @@ class kolab_notes extends rcube_plugin } // generate new note object from input - $object = $this->_write_preprocess($note, $old); + $object = $this->_write_preprocess($note, $old);# return false; $saved = $folder->save($object, 'note', $note['uid']); if (!$saved) { @@ -483,10 +483,10 @@ class kolab_notes extends rcube_plugin // try to be smart and convert to plain-text if no real formatting is detected if (preg_match('!
(.*)
!ims', $object['description'], $m)) { - if (!preg_match('!<(a|b|i|strong|em|p|span|div|pre|li)(\s+[a-z]|>)!im', $m[1])) { + if (!preg_match('!<(a|b|i|strong|em|p|span|div|pre|li)(\s+[a-z]|>)!im', $m[1], $n) || !strpos($m[1], '')) { // $converter = new rcube_html2text($m[1], false, true, 0); // $object['description'] = rtrim($converter->get_text()); - $object['description'] = preg_replace('!!', "\n", $m[1]); + $object['description'] = html_entity_decode(preg_replace('!!', "\n", $m[1])); $is_html = false; } } @@ -529,8 +529,8 @@ class kolab_notes extends rcube_plugin // initialize HTML washer $washer = new rcube_washtml($wash_opts); - //$washer->add_callback('form', 'rcmail_washtml_callback'); - //$washer->add_callback('style', 'rcmail_washtml_callback'); + $washer->add_callback('form', array($this, '_washtml_callback')); + $washer->add_callback('a', array($this, '_washtml_callback')); // Remove non-UTF8 characters $html = rcube_charset::clean($html); @@ -543,5 +543,36 @@ class kolab_notes extends rcube_plugin return $html; } + /** + * Callback function for washtml cleaning class + */ + public function _washtml_callback($tagname, $attrib, $content, $washtml) + { + switch ($tagname) { + case 'form': + $out = html::div('form', $content); + break; + + case 'a': + // strip temporary link tags from plain-text markup + $attrib = html::parse_attrib_string($attrib); + if (!empty($attrib['class']) && strpos($attrib['class'], 'x-templink') !== false) { + // remove link entirely + if (strpos($attrib['href'], html_entity_decode($content)) !== false) { + $out = $content; + break; + } + $attrib['class'] = trim(str_replace('x-templink', '', $attrib['class'])); + } + $out = html::a($attrib, $content); + break; + + default: + $out = ''; + } + + return $out; + } + } diff --git a/plugins/kolab_notes/notes.js b/plugins/kolab_notes/notes.js index ff3aef88..7365ac98 100644 --- a/plugins/kolab_notes/notes.js +++ b/plugins/kolab_notes/notes.js @@ -151,7 +151,6 @@ function rcube_kolab_notes_ui(settings) theme_advanced_toolbar_align: 'left', theme_advanced_buttons3: '', theme_advanced_statusbar_location: 'none', -// extended_valid_elements: 'font[face|size|color|style],span[id|class|align|style]', relative_urls: false, remove_script_host: false, gecko_spellcheck: true, @@ -165,7 +164,8 @@ function rcube_kolab_notes_ui(settings) ed.onClick.add(function(ed, e) { var link = $(e.target).closest('a'); if (link.length && e.shiftKey) { - window.open(link.get(0).href, '_blank'); + if (!bw.mz) window.open(link.get(0).href, '_blank'); + return false; } }); } @@ -187,9 +187,9 @@ function rcube_kolab_notes_ui(settings) /** * Quote HTML entities */ - function Q(html) + function Q(str) { - return String(html).replace(/&/g, '"').replace(//g, '>'); + return String(str).replace(//g, '>').replace(/"/g, '"'); } /** @@ -223,6 +223,7 @@ function rcube_kolab_notes_ui(settings) function edit_note(uid, action) { if (!uid) { + noteslist.clear_selection(); me.selected_note = { list:me.selected_list, uid:null, title:rcmail.gettext('newnote','kolab_notes'), description:'', categories:[] } render_note(me.selected_note); } @@ -398,8 +399,11 @@ function rcube_kolab_notes_ui(settings) var html, node, editor = tinyMCE.get('notecontent'); if (editor) { html = data.html || data.description; - if (!html.match(/<(html|body|p|div|span)/)) - html = '
' + Q(html) + '
'; + + // convert plain text to HTML and make URLs clickable + if (!data.html || !html.match(/<(html|body)/)) { + html = text2html(html); + } editor.setContent(html); node = editor.getContentAreaContainer().childNodes[0]; @@ -411,6 +415,23 @@ function rcube_kolab_notes_ui(settings) $(window).resize(); } + /** + * Convert the given plain text to HTML contents to be displayed in editor + */ + function text2html(str) + { + // simple link parser (similar to rcube_string_replacer class in PHP) + var utf_domain = '[^?&@"\'/\\(\\)\\s\\r\\t\\n]+\\.([^\x00-\x2f\x3b-\x40\x5b-\x60\x7b-\x7f]{2,}|xn--[a-z0-9]{2,})', + url1 = '.:;,', url2 = 'a-z0-9%=#@+?&/_~\\[\\]-', + link_pattern = new RegExp('([hf]t+ps?://|www.)('+utf_domain+'(['+url1+']?['+url2+']+)*)?', 'ig'), + link_replace = function(matches, p1, p2) { + var url = (p1 == 'www.' ? 'http://' : '') + p1 + p2; + return '' + p1 + p2 + ''; + }; + + return '
' + Q(str).replace(link_pattern, link_replace) + '
'; + } + /** * */