Valerii Vasin (valerii) wrote in changelog,
Valerii Vasin
valerii
changelog

[livejournal] r22389: LJSUP-12798: Implement selection operati...

Committer: vvasin
LJSUP-12798: Implement selection operations in LJ.DOM namespace
U   trunk/htdocs/js/basic.js
U   trunk/htdocs/js/jquery_fn.js
Modified: trunk/htdocs/js/basic.js
===================================================================
--- trunk/htdocs/js/basic.js	2012-07-04 12:12:35 UTC (rev 22388)
+++ trunk/htdocs/js/basic.js	2012-07-04 12:56:43 UTC (rev 22389)
@@ -282,11 +282,11 @@
 		if (timer) { return; }
 
 		return callFunc();
-	}
+	};
 };
 
 LJ.console = function() {
-	var consoleExists = function() { return 'console' in window },
+	var consoleExists = function() { return 'console' in window; },
 		runIfExists = function(method, args) {
 			if (consoleExists() && console[method]) {
 				console[method].apply(console, args);
@@ -331,7 +331,7 @@
 		if (!runIfExists('time', arguments) && !timers[label]) {
 			timers[label] = +new Date();
 		}
-	}
+	};
 
 	consoleShim.timeEnd = function(label) {
 		if (!runIfExists('timeEnd', arguments) && timers[label]) {
@@ -339,7 +339,7 @@
 			consoleShim.log(label + ': ' + (now - timers[label]) + 'ms');
 			delete timers[label];
 		}
-	}
+	};
 
 	return consoleShim;
 }();
@@ -361,9 +361,8 @@
 	} else {
 		LJ._const[name] = value;
 	}
+};
 
-}
-
 /**
  * Get the value of the constant.
  *
@@ -374,7 +373,7 @@
 	name = name.toUpperCase().replace(/\s+/g, '_');
 
 	return (LJ._const.hasOwnProperty(name) ? LJ._const[name] : void 0);
-}
+};
 
 /**
  * @namespace LJ.Util.Journal Utility functions connected with journal
@@ -581,7 +580,7 @@
 	 * @return {string} A string representation of timezone, eg +0400
 	 */
 	LJ.Util.Date.timezone = function() {
-		var offset = (-(new Date).getTimezoneOffset() / 0.6),
+		var offset = (-(new Date()).getTimezoneOffset() / 0.6),
 			str = '';
 
 		if (offset > 0) {
@@ -594,7 +593,7 @@
 		str += ('' + offset).pad(4, '0');
 
 		return str;
-	}
+	};
 
 }());
 
@@ -620,6 +619,124 @@
 };
 
 /**
+ * Get field's selection
+ * @param  {jQuery/DOM} node jQuery or DOM node
+ * @return {Object}      Object, contains { start, end } coordinates of selection
+ */
+LJ.DOM.getSelection = function (node) {
+	var start = 0,
+		end = 0,
+		range,
+		dup,
+		regexp = null;
+
+	if (!node.nodeName) {
+		node = node.get(0);
+	}
+
+	if ( 'selectionStart' in node ) {
+		return {
+			start: node.selectionStart,
+			end: node.selectionEnd
+		};
+	}
+
+	if ( 'createTextRange' in node ) {
+		range = document.selection.createRange();
+		if ( range.parentElement() == node ) {
+			dup = range.duplicate();
+			if ( node.type === 'text' ) {
+				node.focus();
+				start = -dup.moveStart('character', -node.value.length);
+				end = start + range.text.length;
+			} else {
+				// textarea
+				regexp = /\r/g;
+				dup.moveToElementText(node);
+				dup.setEndPoint('EndToStart', range);
+				start = dup.text.replace(regexp, '').length;
+				dup.setEndPoint('EndToEnd', range);
+				end = dup.text.replace(regexp, '').length;
+				dup = document.selection.createRange();
+				dup.moveToElementText(node);
+				dup.moveStart('character', start);
+				while (dup.move('character', -dup.compareEndPoints('StartToStart', range))) {
+					start += 1;
+				}
+				dup.moveStart('character', end - start);
+				while (dup.move('character', -dup.compareEndPoints('StartToEnd', range))) {
+					end += 1;
+				}
+			}
+		}
+	}
+
+	return {
+		start: start,
+		end: end
+	};
+};
+
+/**
+ * Set selection for node
+ * @param {jQuery/DOM} node jQuery or native DOM node
+ * @param {number} start Selection start position
+ * @param {number} end   Selection end position
+ */
+LJ.DOM.setSelection = function (node, start, end) {
+	var range;
+	if (!node.nodeName) {
+		node = node.get(0);
+	}
+	// see https://bugzilla.mozilla.org/show_bug.cgi?id=265159
+	node.focus();
+	if( node.setSelectionRange ){
+		node.setSelectionRange(start, end);
+	}
+	// IE, "else" for opera 10
+	else if (document.selection && document.selection.createRange){
+		range = node.createTextRange();
+		range.collapse(true);
+		range.moveEnd('character', end);
+		range.moveStart('character', start);
+		range.select();
+	}
+};
+
+/**
+ * Set cursor position inside of input/textarea element
+ * @param {jQuery/DOM} node     jQuery or DOM node
+ * @param {[type]} position Cursor position
+ */
+LJ.DOM.setCursor = function (node, position) {
+	var text, length, absPosition;
+	if (!node.nodeName) {
+		node = node.get(0);
+	}
+	
+	text = ( 'value' in node ? node.value : node.text ).replace(/\r/, ''),
+	length = text.length;
+
+	// convenient positions
+	if (position === 'end') {
+		return LJ.DOM.setSelection(node, length, length);
+	}
+	if (position === 'start') {
+		return LJ.DOM.setSelection(node, 0, 0);
+	}
+	// calculation of correct caret position
+	if (position > 0) {
+		if (position > length) {
+			position = length;
+		}
+	} else if (position !== 0) {
+		absPosition = Math.abs(position);
+		position = absPosition > length ? 0 : length - absPosition;
+	}
+	LJ.DOM.setSelection(node, position, position);
+};
+
+/**
  * @namespace LJ.UI Namespace should contain utility functions that are connected with widgets.
  */
 LJ.UI = LJ.UI || {};
@@ -651,11 +768,11 @@
 
 	LJ.UI._templates[name] = {
 		type: type
-	}
+	};
 
 	var tmplObject = LJ.UI._templates[name];
 
-	switch(type) {
+	switch (type) {
 		case 'JQuery':
 			jQuery.template(name, template);
 			break;
@@ -1015,13 +1132,13 @@
 if (!Object.extend)
 	Object.extend = function (d, s){
 		if(d) for(var p in s) if(!d[p]) d[p] = s[p];
-		return d
+		return d;
 	};
 
 if (!Object.override)
 	Object.override = function (d, s){
 		if(d) for(var p in s) d[p] = s[p];
-		return d
+		return d;
 	};
 
 /* function extensions */
@@ -1073,7 +1190,7 @@
 				);
 
 			}
-		}
+		};
 
 		return bound;
 	},
@@ -1089,7 +1206,7 @@
 
 Object.extend(Function, {
 	defer: function(func, args/*, more than one*/) {
-		var args = [].slice.call(arguments, 1);
+		args = Array.prototype.slice.call(arguments, 1);
 
 		setTimeout(function() {
 			func.apply(null, args);
@@ -1114,14 +1231,14 @@
 	superClass = superClass || function(){
 	};
 	superClassFunc = function(){
-	}
-	Object.extend(superClassFunc.prototype, superClass.prototype)
+	};
+	Object.extend(superClassFunc.prototype, superClass.prototype);
 	Object.extend(superClassFunc.prototype, {
 		init: function(){
 		},
 		destroy: function(){
 		}
-	})
+	});
 	Object.override(constructor, superClass); // inherit static methods from the superClass
 	constructor.superClass = superClassFunc.prototype;
 
@@ -1273,7 +1390,7 @@
 	 * @return {Number} A Timestamp.
 	 */
 	now: function() {
-		return +new Date;
+		return new Date().valueOf();
 	}
 });
 
@@ -1828,7 +1945,7 @@
 		var s = {
 			left: 0,
 			top: 0
-		}
+		};
 
 		if(!w) w = window;
 		var d = w.document;
@@ -2001,64 +2118,9 @@
 		return r;
 	},
 
-	getSelectedRange: function(node){
-		var start = 0,
-			end = 0;
-		if('selectionStart' in node){
-			start = node.selectionStart;
-			end = node.selectionEnd;
-		} else if(node.createTextRange){
-			var range = document.selection.createRange();
-			if(range.parentElement() == node){
-				var dup = range.duplicate();
-
-				if(node.type == 'text'){
-					node.focus();
-					start = -dup.moveStart('character', -node.value.length);
-					end = start + range.text.length;
-				} else {// textarea
-					var rex = /\r/g;
-					dup.moveToElementText(node);
-					dup.setEndPoint('EndToStart', range);
-					start = dup.text.replace(rex, '').length;
-					dup.setEndPoint('EndToEnd', range);
-					end = dup.text.replace(rex, '').length;
-					dup = document.selection.createRange();
-					dup.moveToElementText(node);
-					dup.moveStart('character', start);
-					while(dup.move('character', -dup.compareEndPoints('StartToStart', range))){
-						start++;
-					}
-					dup.moveStart('character', end - start);
-					while(dup.move('character', -dup.compareEndPoints('StartToEnd', range))){
-						end++;
-					}
-				}
-
-			}
-		}
-
-		return {
-			start: start,
-			end: end
-		}
-	},
-
-	setSelectedRange: function(node, start, end){
-		// see https://bugzilla.mozilla.org/show_bug.cgi?id=265159
-		node.focus();
-		if(node.setSelectionRange){
-			node.setSelectionRange(start, end);
-		}
-		// IE, "else" for opera 10
-		else if(document.selection && document.selection.createRange){
-			var range = node.createTextRange();
-			range.collapse(true);
-			range.moveEnd('character', end);
-			range.moveStart('character', start);
-			range.select();
-		}
-	}
+	// deprecated: use LJ.DOM.* instead
+	getSelectedRange: LJ.DOM.getSelection,
+	setSelectedRange: LJ.DOM.setSelection
 };
 
 $ = DOM.getElement;

Modified: trunk/htdocs/js/jquery_fn.js
===================================================================
--- trunk/htdocs/js/jquery_fn.js	2012-07-04 12:12:35 UTC (rev 22388)
+++ trunk/htdocs/js/jquery_fn.js	2012-07-04 12:56:43 UTC (rev 22389)
@@ -12,6 +12,30 @@
 	});
 };
 
+/**
+ * jQuery plugin that works with caret (it uses LJ.DOM.* methods and added for convenience only)
+ * - if two arguments have been provided: setting selection from startPos to endPos
+ * - if one argument: set cursor to startPos
+ * - if no arguments: get selection of field
+ * 
+ * @param  {number} startPos Start caret position
+ * @param  {number} endPos   End caret position.
+ */
+jQuery.fn.caret = function (startPos, endPos) {
+	var $el = this.length > 1 ? this.first() : this;
+
+	if (typeof startPos === 'number') {
+		if (typeof endPos !== 'number') {
+			LJ.DOM.setCursor($el, startPos);
+		} else {
+			LJ.DOM.setSelection($el, startPos, endPos);
+		}
+		return this;
+	} else {
+		return LJ.DOM.getSelection($el);
+	}
+};
+
 jQuery.fn.hourglass = function(xhr){
 	var hourglasses = [];
 	this.each(function(){

Tags: invis89, js, livejournal, vvasin
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments