1/* 2 * jQuery Input Limiter plugin 1.3.1 3 * http://rustyjeans.com/jquery-plugins/input-limiter/ 4 * 5 * Copyright (c) 2009 Russel Fones <[email protected]> 6 * 7 * Permission is hereby granted, free of charge, to any person 8 * obtaining a copy of this software and associated documentation 9 * files (the "Software"), to deal in the Software without 10 * restriction, including without limitation the rights to use, 11 * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following 14 * conditions: 15 * 16 * The above copyright notice and this permission notice shall be 17 * included in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 * OTHER DEALINGS IN THE SOFTWARE. 27 */ 28 29(function ($) { 30 $.fn.inputlimiter = function (options) { 31 var opts = $.extend({}, $.fn.inputlimiter.defaults, options), 32 $elements = $(this); 33 if (opts.boxAttach && !$('#' + opts.boxId).length) { 34 $('<div/>').appendTo("body").attr({id: opts.boxId, 'class': opts.boxClass}).css({'position': 'absolute'}).hide(); 35 // apply bgiframe if available 36 if ($.fn.bgiframe) { 37 $('#' + opts.boxId).bgiframe(); 38 } 39 } 40 41 var inputlimiterKeyup = function (e) { 42 var $this = $(this), 43 count = counter($this.val()); 44 if (!opts.allowExceed && count > opts.limit) { 45 $this.val(truncater($this.val())); 46 } 47 if (opts.boxAttach) { 48 $('#' + opts.boxId).css({ 49 'width': $this.outerWidth() - ($('#' + opts.boxId).outerWidth() - $('#' + opts.boxId).width()) + 'px', 50 'left': $this.offset().left + 'px', 51 'top': ($this.offset().top + $this.outerHeight()) - 1 + 'px', 52 'z-index': 2000 53 }); 54 } 55 var charsRemaining = (opts.limit - count > 0 ? opts.limit - count : 0), 56 remText = opts.remTextFilter(opts, charsRemaining), 57 limitText = opts.limitTextFilter(opts); 58 59 if (opts.limitTextShow) { 60 $('#' + opts.boxId).html(remText + ' ' + limitText); 61 // Check to see if the text is wrapping in the box 62 // If it is lets break it between the remaining test and the limit test 63 var textWidth = $("<span/>").appendTo("body").attr({id: '19cc9195583bfae1fad88e19d443be7a', 'class': opts.boxClass}).html(remText + ' ' + limitText).innerWidth(); 64 $("#19cc9195583bfae1fad88e19d443be7a").remove(); 65 if (textWidth > $('#' + opts.boxId).innerWidth()) { 66 $('#' + opts.boxId).html(remText + '<br />' + limitText); 67 } 68 // Show the limiter box 69 $('#' + opts.boxId).show(); 70 } else { 71 $('#' + opts.boxId).html(remText).show(); 72 } 73 }, 74 75 inputlimiterKeypress = function (e) { 76 var count = counter($(this).val()); 77 if (!opts.allowExceed && count > opts.limit) { 78 var modifierKeyPressed = e.ctrlKey || e.altKey || e.metaKey; 79 if (!modifierKeyPressed && (e.which >= 32 && e.which <= 122) && this.selectionStart === this.selectionEnd) { 80 return false; 81 } 82 } 83 }, 84 85 inputlimiterBlur = function () { 86 var $this = $(this); 87 count = counter($this.val()); 88 if (!opts.allowExceed && count > opts.limit) { 89 $this.val(truncater($this.val())); 90 } 91 if (opts.boxAttach) { 92 $('#' + opts.boxId).fadeOut('fast'); 93 } else if (opts.remTextHideOnBlur) { 94 var limitText = opts.limitText; 95 limitText = limitText.replace(/\%n/g, opts.limit); 96 limitText = limitText.replace(/\%s/g, (opts.limit === 1 ? '' : 's')); 97 $('#' + opts.boxId).html(limitText); 98 } 99 }, 100 101 counter = function (value) { 102 if (opts.limitBy.toLowerCase() === "words") { 103 return (value.length > 0 ? $.trim(value).replace(/\ +(?= )/g, '').split(' ').length : 0); 104 } 105 var count = value.length, 106 newlines = value.match(/\n/g); 107 if (newlines && opts.lineReturnCount > 1) { 108 count += newlines.length * (opts.lineReturnCount - 1); 109 } 110 return count; 111 }, 112 113 truncater = function (value) { 114 if (opts.limitBy.toLowerCase() === "words") { 115 return $.trim(value).replace(/\ +(?= )/g, '').split(' ').splice(0, opts.limit).join(' ') + ' '; 116 } 117 return value.substring(0, opts.limit); 118 }; 119 120 $(this).each(function (i) { 121 var $this = $(this); 122 if ((!options || !options.limit) && opts.useMaxlength && parseInt($this.attr('maxlength')) > 0 && parseInt($this.attr('maxlength')) != opts.limit) { 123 $this.inputlimiter($.extend({}, opts, { limit: parseInt($this.attr('maxlength')) })); 124 } else { 125 if (!opts.allowExceed && opts.useMaxlength && opts.limitBy.toLowerCase() === "characters") { 126 $this.attr('maxlength', opts.limit); 127 } 128 $this.unbind('.inputlimiter'); 129 $this.bind('keyup.inputlimiter', inputlimiterKeyup); 130 $this.bind('keypress.inputlimiter', inputlimiterKeypress); 131 $this.bind('blur.inputlimiter', inputlimiterBlur); 132 } 133 }); 134 }; 135 136 $.fn.inputlimiter.remtextfilter = function (opts, charsRemaining) { 137 var remText = opts.remText; 138 if (charsRemaining === 0 && opts.remFullText !== null) { 139 remText = opts.remFullText; 140 } 141 remText = remText.replace(/\%n/g, charsRemaining); 142 remText = remText.replace(/\%s/g, (opts.zeroPlural ? (charsRemaining === 1 ? '' : 's') : (charsRemaining <= 1 ? '' : 's'))); 143 return remText; 144 }; 145 146 $.fn.inputlimiter.limittextfilter = function (opts) { 147 var limitText = opts.limitText; 148 limitText = limitText.replace(/\%n/g, opts.limit); 149 limitText = limitText.replace(/\%s/g, (opts.limit <= 1 ? '' : 's')); 150 return limitText; 151 }; 152 153 $.fn.inputlimiter.defaults = { 154 limit: 255, 155 boxAttach: true, 156 boxId: 'limiterBox', 157 boxClass: 'limiterBox', 158 remText: '%n character%s remaining.', 159 remTextFilter: $.fn.inputlimiter.remtextfilter, 160 remTextHideOnBlur: true, 161 remFullText: null, 162 limitTextShow: true, 163 limitText: 'Field limited to %n character%s.', 164 limitTextFilter: $.fn.inputlimiter.limittextfilter, 165 zeroPlural: true, 166 allowExceed: false, 167 useMaxlength: true, 168 limitBy: 'characters', 169 lineReturnCount: 1 170 }; 171 172})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.