+function ($) {
  'use strict';

  var sentinelChar = '吶';

  function IETextarea(element, completer, option) {
    this.initialize(element, completer, option);
    $('<span>' + sentinelChar + '</span>').css({
      position: 'absolute',
      top: -9999,
      left: -9999
    }).insertBefore(element);
  }

  $.extend(IETextarea.prototype, $.fn.textcomplete.Textarea.prototype, {
    // Public methods
    // --------------

    select: function (value, strategy, e) {
      var pre = this.getTextFromHeadToCaret();
      var post = this.el.value.substring(pre.length);
      var newSubstr = strategy.replace(value, e);
      var regExp;
      if (typeof newSubstr !== 'undefined') {
        if ($.isArray(newSubstr)) {
          post = newSubstr[1] + post;
          newSubstr = newSubstr[0];
        }
        regExp = $.isFunction(strategy.match) ? strategy.match(pre) : strategy.match;
        pre = pre.replace(regExp, newSubstr);
        this.$el.val(pre + post);
        this.el.focus();
        var range = this.el.createTextRange();
        range.collapse(true);
        range.moveEnd('character', pre.length);
        range.moveStart('character', pre.length);
        range.select();
      }
    },

    getTextFromHeadToCaret: function () {
      this.el.focus();
      var range = document.selection.createRange();
      range.moveStart('character', -this.el.value.length);
      var arr = range.text.split(sentinelChar)
      return arr.length === 1 ? arr[0] : arr[1];
    }
  });

  $.fn.textcomplete.IETextarea = IETextarea;
}(jQuery);
