Commits

benoitc  committed 40338d8

fix opera. for now disable the tab feature on enter key.

  • Participants
  • Parent commits a9d8129
  • Tags 0.1.3

Comments (0)

Files changed (1)

File jquery.textarea.js

     }
   }
 
+  Function.prototype.ebind = function() {
+    var __method = this, args = $A(arguments), object = args.shift();
+    return function() {
+      return __method.apply(object, args.concat($A(arguments)));
+    }
+  }
+  
   Function.prototype.bindAsEventListener = function() {
     var __method = this,
     args = $A(arguments),
         textarea: this
       });
 
-      this.bindMethodsToObj("handleKey");
-
       // detection of browser for webkit
       var ua = navigator.userAgent.toLowerCase();
       this.isWebkit = (ua.indexOf('webkit') >= 0);
       this.isOpera = (ua.indexOf('opera') >= 0);
 
       if (this.options.resizeable && !this.isWebkit) {
-
         resizeHandle = $('<div class="' + this.options.resizeClassName + '"></div>')
         .insertAfter(this.el)
         .bind("mousedown", function(e) {
 
       // we need to add one character for webkit
       if (this.isWebkit)
-      this.options.tab_char += 1;
+        this.options.tab_char += 1;
 
       if (this.options.tab_spacing) {
         this.tabulation = "";
         for (var i=0; i<this.options.tab_char; i++)
-        this.tabulation += " ";
+          this.tabulation += " ";
       } else {
         this.tabulation = "\t";
       }
       this.tab_detected = false;
 
       // init selection for ie
-      if (typeof this.element.selectionStart == 'undefined')
-      this.element.selectionStart = this.element.selectionEnd = 0;
+      if (!!document.selection)
+        this.element.selectionStart = this.element.selectionEnd = 0;
 
-      this.el.keydown(this.handleKey);
+      this.el.keydown(this.handleKey.ebind(this));
 
-      var self = this
+      var self = this;
       this.doOnChange = function(e) {
         if (self._change_callback) {
           self._change_callback(self.element.value);
         } 
         return;
       }
-
+      
       this.el.keyup(this.doOnChange);
       this.el.bind('paste', this.doOnChange);
       this.el.bind('input', this.doOnChange);
+      
+      if(!!document.selection){
+  			this.el.bind('mouseup',this.saveRange.bindAsEventListener(this));  
+  			this.el.bind('keyup',this.saveRange.bindAsEventListener(this));
+  		}
+  		
+  		if (this.isOpera) {
+  		  this.el.bind('blur', function(e) {
+  		    if (self.lastKey && self.lastKey == 9)
+  		      self.el.focus();
+  		  });
+  		}
 
     },
 
 
     getSelection: function(){
       if(!!document.selection)
-      return document.selection.createRange().text;
+        return document.selection.createRange().text;
       else if(!!this.element.setSelectionRange)
-      return this.element.value.substring(this.element.selectionStart,this.element.selectionEnd);
+        return this.element.value.substring(this.element.selectionStart,this.element.selectionEnd);
       else
       return false;
     },
 
     handleKey: function(e) {
       c = e.charCode || e.keyCode;
+      this.lastKey = c;
       if (c == 9) {
+        this.tab_selection();
+        if( window.event ){
+          e.returnValue = false;
+        }
         e.preventDefault();
-        this.tab_selection();
-        e.returnValue = false;
         e.stopPropagation();
         return false;
-      } else if (c == 13) {
+      } else if ((c == 13 || c == 10) && (!this.isOpera)) {
+        //FIXME: opera disabled for now 
         if (this.do_enter()) {
+          if( window.event ){
+            e.returnValue = false;
+          }
           e.preventDefault();
-          e.returnValue = false;
           e.stopPropagation();
           return false;
-        }
+        }        
       }
       return true;
     }, 
 
     tab_selection: function() {
       if (this._is_tabbing)
-      return
-
+        return;
+      
       this._is_tabbing = true;
-
-      if ( !! document.selection)
-      this._getIESelection();
+      if (!!document.selection && !this.isOpera)
+        this._getIESelection();
 
       if (!this._tab_detected)
-      this._detect_tab();
+        this._detect_tab();
 
       var start = this.element.selectionStart;
       var end = this.element.selectionEnd;
       if (insText.length == 0) {
         // if only one line selected
         this.element.value = this.element.value.substr(0, start) +
-        this.tabulation + this.element.value.substr(end);
+          this.tabulation + this.element.value.substr(end);
         pos_start = start + this.tabulation.length;
         pos_end = pos_start;
       } else {
         pos_start = start;
         pos_end = this.element.value.indexOf("\n", startText.length + insText.length);
         if (pos_end == -1)
-        pos_end = this.element.value.length;
+          pos_end = this.element.value.length;
       }
       this.element.selectionStart = pos_start;
       this.element.selectionEnd = pos_end;
 
-      if ( !! document.selection) {
+      if (!!document.selection && !this.isOpera) {
         this._setIESelection();
         setTimeout(function() {
           self._is_tabbing = false;
-        },
-        100);
+        }, 100);
         this._is_tabbing = false;
       } else {
         this._is_tabbing = false;
     },
 
     do_enter: function() {
-      if ( !! document.selection)
-      this._getIESelection();
+      if (!!document.selection && !this.isOpera)
+        this._getIESelection();
 
       var scrollTop = this.el.scrollTop();
       var scrollLeft = this.el.scrollLeft();
-
       var start = this.element.selectionStart;
       var end = this.element.selectionEnd;
-
-      var start_last_line = Math.max(0, 
-        this.element.value.substring(0, start).lastIndexOf("\n") + 1);
-
-      var latest_line = this.element.value.substring(start_last_line,
-        start)
-
+      
+      var start_last_line = Math.max(0, this.element.value.substring(0, start).lastIndexOf("\n") + 1);
+      var latest_line = this.element.value.substring(start_last_line, start)
       if (latest_line.match(/^[ \t]+$/mg, ""))
         return false;
-
+      
       var begin_line = latest_line.replace(/^([ \t]*).*/gm, "$1");
-      if (begin_line == "\n" || begin_line == "\r")
+      if (begin_line == "\n" || begin_line == "\r\n")
         return false;
-
-      if ( !! document.selection || this.isOpera) {
-        begin_line = "\rn" + begin_line;
+        
+      begin_line = begin_line.replace(/\r?\n/g, '') 
+      if ( !!document.selection) {
+        begin_line = "\r\n" + begin_line;
       } else {
         begin_line = "\n" + begin_line;
       }
       this.element.value = this.element.value.substring(0, start) +
-      begin_line + this.element.value.substring(end);
+        begin_line + this.element.value.substring(end);
 
       this.area_select(start + begin_line.length, 0);
-
       this.el.scrollTop(scrollTop);
       this.el.scrollLeft(scrollLeft);
-
       return true;
     },
 
     area_select: function(start, length) {
-      var value = this.el.val();
+      value = this.el.val();
       start = Math.max(0, Math.min(value.length, start));
       end = Math.max(start, Math.min(value.length, start + length));
-
-      if ( !! document.selection) {
+      if (!!document.selection && !this.isOpera) {
         this.element.selectionStart = start;
-        this.element;
-        selectionEnd = end;
+        this.element.selectionEnd = end;
         this._setIESelection();
       } else {
         if (this.isOpera) {
           this.element.setSelectionRange(0, 0);
+          this.element.setSelectionRange(end, end);
+        } else {
+          this.element.setSelectionRange(start, end);
         }
-        this.element.setSelectionRange(start, end);
+        
       }
     },
 
       } else {
         this.tabulation = "";
         for (var i = 0; i < this.options.tab_char; i++)
-        this.tabulation += " ";
+          this.tabulation += " ";
       }
       this._tab_detected = true;
     },
       end_range.moveStart('character', -this.element.value.length);
       this.el.selectionEnd = end_range.text.length;
       if (this.element.selectionEnd < this.element.selectionStart)
-      this.element.selectionEnd = this.element.selectionStart;
+        this.element.selectionEnd = this.element.selectionStart;
 
     },
 
       range.setEndPoint('EndToStart', range);
       range.collapse(true);
       range.moveStart('character', this.element.selectionStart - nbLineStart);
-      range.moveEnd('character',
-      this.element.selectionEnd - nbLineEnd -
-      (this.element.selectionStart - nbLineStart));
+      range.moveEnd('character', this.element.selectionEnd - nbLineEnd -
+        (this.element.selectionStart - nbLineStart));
 
       range.select();
-    },
-
-    bindToObj: function(fn) {
-      var self = this;
-      return function() {
-        return fn.apply(self, arguments)
-      };
-    },
-
-    bindMethodsToObj: function() {
-      for (var i = 0; i < arguments.length; i++) {
-        this[arguments[i]] = this.bindToObj(this[arguments[i]]);
-      };
     }
 
 });