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'], ''.$m[1].'>') > 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], ''.$n[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) + '
';
+ }
+
/**
*
*/