Index: /trunk/src/bp-core/js/jquery.atwho.js
===================================================================
--- /trunk/src/bp-core/js/jquery.atwho.js	(revision 9245)
+++ /trunk/src/bp-core/js/jquery.atwho.js	(revision 9246)
@@ -1,16 +1,22 @@
-/*! jquery.atwho - v0.5.1 - 2014-09-21
-* Copyright (c) 2014 chord.luo <chord.luo@gmail.com>; 
-* homepage: http://ichord.github.com/At.js 
+/*! jquery.atwho - v0.5.2 %>
+* Copyright (c) 2014 chord.luo <chord.luo@gmail.com>;
+* homepage: http://ichord.github.com/At.js
 * Licensed MIT
 */
-
-(function() {
-  (function(factory) {
-    if (typeof define === 'function' && define.amd) {
-      return define(['jquery'], factory);
-    } else {
-      return factory(window.jQuery);
-    }
-  })(function($) {
+(function (root, factory) {
+  if (typeof define === 'function' && define.amd) {
+    // AMD. Register as an anonymous module.
+    define(["jquery"], function ($) {
+      return (root.returnExportsGlobal = factory($));
+    });
+  } else if (typeof exports === 'object') {
+    // Node. Does not work with strict CommonJS, but
+    // only CommonJS-like enviroments that support module.exports,
+    // like Node.
+    module.exports = factory(require("jquery"));
+  } else {
+    factory(jQuery);
+  }
+}(this, function ($) {
 
 var Api, App, Controller, DEFAULT_CALLBACKS, KEY_CODE, Model, View,
@@ -116,6 +122,5 @@
     })(this)).on('click.atwhoInner', (function(_this) {
       return function(e) {
-        var _ref;
-        return (_ref = _this.controller()) != null ? _ref.view.hide(e) : void 0;
+        return _this.dispatch();
       };
     })(this));
@@ -301,8 +306,12 @@
 
   Controller.prototype.content = function() {
+    var range;
     if (this.$inputor.is('textarea, input')) {
       return this.$inputor.val();
     } else {
-      return this.$inputor.text();
+      if (!(range = this.mark_range())) {
+        return;
+      }
+      return (range.startContainer.textContent || "").slice(0, range.startOffset);
     }
   };
@@ -389,13 +398,13 @@
 
   Controller.prototype.insert = function(content, $li) {
-    var $inputor, content_node, pos, range, sel, source, start_str, text, wrapped_content;
+    var $inputor, node, pos, range, sel, source, start_str, text, wrapped_contents, _i, _len, _ref;
     $inputor = this.$inputor;
-    wrapped_content = this.callbacks('inserting_wrapper').call(this, $inputor, content, this.get_opt("suffix"));
+    wrapped_contents = this.callbacks('inserting_wrapper').call(this, $inputor, content, this.get_opt("suffix"));
     if ($inputor.is('textarea, input')) {
       source = $inputor.val();
       start_str = source.slice(0, Math.max(this.query.head_pos - this.at.length, 0));
-      text = "" + start_str + wrapped_content + (source.slice(this.query['end_pos'] || 0));
+      text = "" + start_str + wrapped_contents + (source.slice(this.query['end_pos'] || 0));
       $inputor.val(text);
-      $inputor.caret('pos', start_str.length + wrapped_content.length, {
+      $inputor.caret('pos', start_str.length + wrapped_contents.length, {
         iframe: this.app.iframe
       });
@@ -405,8 +414,11 @@
       range.setEnd(range.endContainer, range.endOffset);
       range.deleteContents();
-      content_node = $(wrapped_content, this.app.document)[0];
-      range.insertNode(content_node);
-      range.setEndAfter(content_node);
-      range.collapse(false);
+      _ref = $(wrapped_contents, this.app.document);
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        node = _ref[_i];
+        range.insertNode(node);
+        range.setEndAfter(node);
+        range.collapse(false);
+      }
       sel = this.app.window.getSelection();
       sel.removeAllRanges();
@@ -414,5 +426,5 @@
     } else if (range = this.ie8_range) {
       range.moveStart('character', this.query.end_pos - this.query.head_pos - this.at.length);
-      range.pasteHTML(wrapped_content);
+      range.pasteHTML(wrapped_contents);
       range.collapse(false);
       range.select();
@@ -542,6 +554,8 @@
       $menu.find('.cur').removeClass('cur');
       return $(e.currentTarget).addClass('cur');
-    }).on('click', (function(_this) {
+    }).on('click.atwho-view', 'li', (function(_this) {
       return function(e) {
+        $menu.find('.cur').removeClass('cur');
+        $(e.currentTarget).addClass('cur');
         _this.choose(e);
         return e.preventDefault();
@@ -594,5 +608,8 @@
       next = this.$el.find('li:first');
     }
-    return next.addClass('cur');
+    next.addClass('cur');
+    return this.$el.animate({
+      scrollTop: Math.max(0, cur.innerHeight() * (next.index() + 2) - this.$el.height())
+    }, 150);
   };
 
@@ -604,5 +621,8 @@
       prev = this.$el.find('li:last');
     }
-    return prev.addClass('cur');
+    prev.addClass('cur');
+    return this.$el.animate({
+      scrollTop: Math.max(0, cur.innerHeight() * (prev.index() + 2) - this.$el.height())
+    }, 150);
   };
 
@@ -616,4 +636,5 @@
     if (!this.visible()) {
       this.$el.show();
+      this.$el.scrollTop(0);
       this.context.trigger('shown');
     }
@@ -703,10 +724,12 @@
   },
   matcher: function(flag, subtext, should_start_with_space) {
-    var match, regexp;
+    var match, regexp, _a, _y;
     flag = flag.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
     if (should_start_with_space) {
       flag = '(?:^|\\s)' + flag;
     }
-    regexp = new RegExp(flag + '([A-Za-zÀ-ÿ0-9_\+\-]*)$|' + flag + '([^\\x00-\\xff]*)$', 'gi');
+    _a = decodeURI("%C3%80");
+    _y = decodeURI("%C3%BF");
+    regexp = new RegExp("" + flag + "([A-Za-z" + _a + "-" + _y + "0-9_\+\-]*)$|" + flag + "([^\\x00-\\xff]*)$", 'gi');
     match = regexp.exec(subtext);
     if (match) {
@@ -770,14 +793,14 @@
   },
   inserting_wrapper: function($inputor, content, suffix) {
-    var new_suffix, wrapped_content;
-    new_suffix = suffix === "" ? suffix : suffix || " ";
+    var wrapped_content;
+    suffix = suffix === "" ? suffix : suffix || " ";
     if ($inputor.is('textarea, input')) {
-      return '' + content + new_suffix;
+      return '' + content + suffix;
     } else if ($inputor.attr('contentEditable') === 'true') {
-      new_suffix = suffix === "" ? suffix : suffix || "&nbsp;";
+      suffix = suffix === " " ? "&nbsp;" : suffix;
       if (/firefox/i.test(navigator.userAgent)) {
-        wrapped_content = "<span>" + content + new_suffix + "</span>";
+        wrapped_content = "<span>" + content + suffix + "</span>";
       } else {
-        suffix = "<span contenteditable='false'>" + new_suffix + "<span>";
+        suffix = "<span contenteditable='false'>" + suffix + "</span>";
         wrapped_content = "<span contenteditable='false'>" + content + suffix + "</span>";
       }
@@ -785,5 +808,5 @@
         wrapped_content = "<span contenteditable='true'>" + content + "</span>";
       }
-      return wrapped_content;
+      return wrapped_content + "<span></span>";
     }
   }
@@ -848,4 +871,5 @@
 };
 
-  });
-}).call(this);
+
+
+}));
Index: /trunk/src/bp-core/js/jquery.caret.js
===================================================================
--- /trunk/src/bp-core/js/jquery.caret.js	(revision 9245)
+++ /trunk/src/bp-core/js/jquery.caret.js	(revision 9246)
@@ -85,19 +85,32 @@
 
       EditableCaret.prototype.getOffset = function(pos) {
-        var clonedRange, offset, range, rect;
+        var clonedRange, offset, range, rect, shadowCaret;
         if (oWindow.getSelection && (range = this.range())) {
-          if (range.endOffset - 1 < 0) {
-            return null;
+          if (range.endOffset - 1 > 0 && range.endContainer === !this.domInputor) {
+            clonedRange = range.cloneRange();
+            clonedRange.setStart(range.endContainer, range.endOffset - 1);
+            clonedRange.setEnd(range.endContainer, range.endOffset);
+            rect = clonedRange.getBoundingClientRect();
+            offset = {
+              height: rect.height,
+              left: rect.left + rect.width,
+              top: rect.top
+            };
+            clonedRange.detach();
           }
-          clonedRange = range.cloneRange();
-          clonedRange.setStart(range.endContainer, range.endOffset - 1);
-          clonedRange.setEnd(range.endContainer, range.endOffset);
-          rect = clonedRange.getBoundingClientRect();
-          offset = {
-            height: rect.height,
-            left: rect.left + rect.width,
-            top: rect.top
-          };
-          clonedRange.detach();
+          if (!offset || (offset != null ? offset.height : void 0) === 0) {
+            clonedRange = range.cloneRange();
+            shadowCaret = $(oDocument.createTextNode("|"));
+            clonedRange.insertNode(shadowCaret[0]);
+            clonedRange.selectNode(shadowCaret[0]);
+            rect = clonedRange.getBoundingClientRect();
+            offset = {
+              height: rect.height,
+              left: rect.left,
+              top: rect.top
+            };
+            shadowCaret.remove();
+            clonedRange.detach();
+          }
         } else if (oDocument.selection) {
           offset = this.getOldIEOffset();
@@ -212,5 +225,5 @@
         $inputor = this.$inputor;
         format = function(value) {
-          return $('<div></div>').text(value).html();
+          return $('<div></div>').text(value).html().replace(/\r\n|\r|\n/g, "<br/>").replace(/\s/g, "&nbsp;");
         };
         if (pos === void 0) {
