1/*! 2 * bootstrap-star-rating v4.0.3 3 * http://plugins.krajee.com/star-rating 4 * 5 * Author: Kartik Visweswaran 6 * Copyright: 2013 - 2017, Kartik Visweswaran, Krajee.com 7 * 8 * Licensed under the BSD 3-Clause 9 * https://github.com/kartik-v/bootstrap-star-rating/blob/master/LICENSE.md 10 */ 11(function (factory) { 12 "use strict"; 13 //noinspection JSUnresolvedVariable 14 if (typeof define === 'function' && define.amd) { // jshint ignore:line 15 // AMD. Register as an anonymous module. 16 define(['jquery'], factory); // jshint ignore:line 17 } else { // noinspection JSUnresolvedVariable 18 if (typeof module === 'object' && module.exports) { // jshint ignore:line 19 // Node/CommonJS 20 // noinspection JSUnresolvedVariable 21 module.exports = factory(require('jquery')); // jshint ignore:line 22 } else { 23 // Browser globals 24 factory(window.jQuery); 25 } 26 } 27}(function ($) { 28 "use strict"; 29 30 $.fn.ratingLocales = {}; 31 $.fn.ratingThemes = {}; 32 33 var $h, Rating; 34 35 // global helper methods and constants 36 $h = { 37 NAMESPACE: '.rating', 38 DEFAULT_MIN: 0, 39 DEFAULT_MAX: 5, 40 DEFAULT_STEP: 0.5, 41 isEmpty: function (value, trim) { 42 return value === null || value === undefined || value.length === 0 || (trim && $.trim(value) === ''); 43 }, 44 getCss: function (condition, css) { 45 return condition ? ' ' + css : ''; 46 }, 47 addCss: function ($el, css) { 48 $el.removeClass(css).addClass(css); 49 }, 50 getDecimalPlaces: function (num) { 51 var m = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/); 52 return !m ? 0 : Math.max(0, (m[1] ? m[1].length : 0) - (m[2] ? +m[2] : 0)); 53 }, 54 applyPrecision: function (val, precision) { 55 return parseFloat(val.toFixed(precision)); 56 }, 57 handler: function ($el, event, callback, skipOff, skipNS) { 58 var ev = skipNS ? event : event.split(' ').join($h.NAMESPACE + ' ') + $h.NAMESPACE; 59 if (!skipOff) { 60 $el.off(ev); 61 } 62 $el.on(ev, callback); 63 } 64 }; 65 66 // rating constructor 67 Rating = function (element, options) { 68 var self = this; 69 self.$element = $(element); 70 self._init(options); 71 }; 72 Rating.prototype = { 73 constructor: Rating, 74 _parseAttr: function (vattr, options) { 75 var self = this, $el = self.$element, elType = $el.attr('type'), finalVal, val, chk, out; 76 if (elType === 'range' || elType === 'number') { 77 val = options[vattr] || $el.data(vattr) || $el.attr(vattr); 78 switch (vattr) { 79 case 'min': 80 chk = $h.DEFAULT_MIN; 81 break; 82 case 'max': 83 chk = $h.DEFAULT_MAX; 84 break; 85 default: 86 chk = $h.DEFAULT_STEP; 87 } 88 finalVal = $h.isEmpty(val) ? chk : val; 89 out = parseFloat(finalVal); 90 } else { 91 out = parseFloat(options[vattr]); 92 } 93 return isNaN(out) ? chk : out; 94 }, 95 _parseValue: function (val) { 96 var self = this, v = parseFloat(val); 97 if (isNaN(v)) { 98 v = self.clearValue; 99 } 100 return (self.zeroAsNull && (v === 0 || v === '0') ? null : v); 101 }, 102 _setDefault: function (key, val) { 103 var self = this; 104 if ($h.isEmpty(self[key])) { 105 self[key] = val; 106 } 107 }, 108 _initSlider: function (options) { 109 var self = this, v = self.$element.val(); 110 self.initialValue = $h.isEmpty(v) ? 0 : v; 111 self._setDefault('min', self._parseAttr('min', options)); 112 self._setDefault('max', self._parseAttr('max', options)); 113 self._setDefault('step', self._parseAttr('step', options)); 114 if (isNaN(self.min) || $h.isEmpty(self.min)) { 115 self.min = $h.DEFAULT_MIN; 116 } 117 if (isNaN(self.max) || $h.isEmpty(self.max)) { 118 self.max = $h.DEFAULT_MAX; 119 } 120 if (isNaN(self.step) || $h.isEmpty(self.step) || self.step === 0) { 121 self.step = $h.DEFAULT_STEP; 122 } 123 self.diff = self.max - self.min; 124 }, 125 _initHighlight: function (v) { 126 var self = this, w, cap = self._getCaption(); 127 if (!v) { 128 v = self.$element.val(); 129 } 130 w = self.getWidthFromValue(v) + '%'; 131 self.$filledStars.width(w); 132 self.cache = {caption: cap, width: w, val: v}; 133 }, 134 _getContainerCss: function () { 135 var self = this; 136 return 'rating-container' + 137 $h.getCss(self.theme, 'theme-' + self.theme) + 138 $h.getCss(self.rtl, 'rating-rtl') + 139 $h.getCss(self.size, 'rating-' + self.size) + 140 $h.getCss(self.animate, 'rating-animate') + 141 $h.getCss(self.disabled || self.readonly, 'rating-disabled') + 142 $h.getCss(self.containerClass, self.containerClass); 143 }, 144 _checkDisabled: function () { 145 var self = this, $el = self.$element, opts = self.options; 146 self.disabled = opts.disabled === undefined ? $el.attr('disabled') || false : opts.disabled; 147 self.readonly = opts.readonly === undefined ? $el.attr('readonly') || false : opts.readonly; 148 self.inactive = (self.disabled || self.readonly); 149 $el.attr({disabled: self.disabled, readonly: self.readonly}); 150 }, 151 _addContent: function (type, content) { 152 var self = this, $container = self.$container, isClear = type === 'clear'; 153 if (self.rtl) { 154 return isClear ? $container.append(content) : $container.prepend(content); 155 } else { 156 return isClear ? $container.prepend(content) : $container.append(content); 157 } 158 }, 159 _generateRating: function () { 160 var self = this, $el = self.$element, $rating, $container, w; 161 $container = self.$container = $(document.createElement("div")).insertBefore($el); 162 $h.addCss($container, self._getContainerCss()); 163 self.$rating = $rating = $(document.createElement("div")).attr('class', 'rating-stars').appendTo($container) 164 .append(self._getStars('empty')).append(self._getStars('filled')); 165 self.$emptyStars = $rating.find('.empty-stars'); 166 self.$filledStars = $rating.find('.filled-stars'); 167 self._renderCaption(); 168 self._renderClear(); 169 self._initHighlight(); 170 $container.append($el); 171 if (self.rtl) { 172 w = Math.max(self.$emptyStars.outerWidth(), self.$filledStars.outerWidth()); 173 self.$emptyStars.width(w); 174 } 175 $el.appendTo($rating); 176 }, 177 _getCaption: function () { 178 var self = this; 179 return self.$caption && self.$caption.length ? self.$caption.html() : self.defaultCaption; 180 }, 181 _setCaption: function (content) { 182 var self = this; 183 if (self.$caption && self.$caption.length) { 184 self.$caption.html(content); 185 } 186 }, 187 _renderCaption: function () { 188 var self = this, val = self.$element.val(), html, $cap = self.captionElement ? $(self.captionElement) : ''; 189 if (!self.showCaption) { 190 return; 191 } 192 html = self.fetchCaption(val); 193 if ($cap && $cap.length) { 194 $h.addCss($cap, 'caption'); 195 $cap.html(html); 196 self.$caption = $cap; 197 return; 198 } 199 self._addContent('caption', '<div class="caption">' + html + '</div>'); 200 self.$caption = self.$container.find(".caption"); 201 }, 202 _renderClear: function () { 203 var self = this, css, $clr = self.clearElement ? $(self.clearElement) : ''; 204 if (!self.showClear) { 205 return; 206 } 207 css = self._getClearClass(); 208 if ($clr.length) { 209 $h.addCss($clr, css); 210 $clr.attr({"title": self.clearButtonTitle}).html(self.clearButton); 211 self.$clear = $clr; 212 return; 213 } 214 self._addContent('clear', 215 '<div class="' + css + '" title="' + self.clearButtonTitle + '">' + self.clearButton + '</div>'); 216 self.$clear = self.$container.find('.' + self.clearButtonBaseClass); 217 }, 218 _getClearClass: function () { 219 var self = this; 220 return self.clearButtonBaseClass + ' ' + (self.inactive ? '' : self.clearButtonActiveClass); 221 }, 222 _toggleHover: function (out) { 223 var self = this, w, width, caption; 224 if (!out) { 225 return; 226 } 227 if (self.hoverChangeStars) { 228 w = self.getWidthFromValue(self.clearValue); 229 width = out.val <= self.clearValue ? w + '%' : out.width; 230 self.$filledStars.css('width', width); 231 } 232 if (self.hoverChangeCaption) { 233 caption = out.val <= self.clearValue ? self.fetchCaption(self.clearValue) : out.caption; 234 if (caption) { 235 self._setCaption(caption + ''); 236 } 237 } 238 }, 239 _init: function (options) { 240 var self = this, $el = self.$element.addClass('rating-input'), v; 241 self.options = options; 242 $.each(options, function (key, value) { 243 self[key] = value; 244 }); 245 if (self.rtl || $el.attr('dir') === 'rtl') { 246 self.rtl = true; 247 $el.attr('dir', 'rtl'); 248 } 249 self.starClicked = false;
250 self.clearClicked = false; 251 self._initSlider(options); 252 self._checkDisabled(); 253 if (self.displayOnly) { 254 self.inactive = true; 255 self.showClear = false; 256 self.showCaption = false; 257 } 258 self._generateRating(); 259 self._initEvents(); 260 self._listen(); 261 v = self._parseValue($el.val()); 262 $el.val(v); 263 return $el.removeClass('rating-loading'); 264 }, 265 _initEvents: function () { 266 var self = this; 267 self.events = { 268 _getTouchPosition: function (e) { 269 var pageX = $h.isEmpty(e.pageX) ? e.originalEvent.touches[0].pageX : e.pageX; 270 return pageX - self.$rating.offset().left; 271 }, 272 _listenClick: function (e, callback) { 273 e.stopPropagation(); 274 e.preventDefault(); 275 if (e.handled !== true) { 276 callback(e); 277 e.handled = true; 278 } else { 279 return false; 280 } 281 }, 282 _noMouseAction: function (e) { 283 return !self.hoverEnabled || self.inactive || (e && e.isDefaultPrevented()); 284 }, 285 initTouch: function (e) { 286 //noinspection JSUnresolvedVariable 287 var ev, touches, pos, out, caption, w, width, params, clrVal = self.clearValue || 0, 288 isTouchCapable = 'ontouchstart' in window || 289 (window.DocumentTouch && document instanceof window.DocumentTouch); 290 if (!isTouchCapable || self.inactive) { 291 return; 292 } 293 ev = e.originalEvent; 294 //noinspection JSUnresolvedVariable 295 touches = !$h.isEmpty(ev.touches) ? ev.touches : ev.changedTouches; 296 pos = self.events._getTouchPosition(touches[0]); 297 if (e.type === "touchend") { 298 self._setStars(pos); 299 params = [self.$element.val(), self._getCaption()]; 300 self.$element.trigger('change').trigger('rating:change', params); 301 self.starClicked = true; 302 } else { 303 out = self.calculate(pos); 304 caption = out.val <= clrVal ? self.fetchCaption(clrVal) : out.caption; 305 w = self.getWidthFromValue(clrVal); 306 width = out.val <= clrVal ? w + '%' : out.width; 307 self._setCaption(caption); 308 self.$filledStars.css('width', width); 309 } 310 }, 311 starClick: function (e) { 312 var pos, params; 313 self.events._listenClick(e, function (ev) { 314 if (self.inactive) { 315 return false; 316 } 317 pos = self.events._getTouchPosition(ev); 318 self._setStars(pos); 319 params = [self.$element.val(), self._getCaption()]; 320 self.$element.trigger('change').trigger('rating:change', params); 321 self.starClicked = true; 322 }); 323 }, 324 clearClick: function (e) { 325 self.events._listenClick(e, function () { 326 if (!self.inactive) { 327 self.clear(); 328 self.clearClicked = true; 329 } 330 }); 331 }, 332 starMouseMove: function (e) { 333 var pos, out; 334 if (self.events._noMouseAction(e)) { 335 return; 336 } 337 self.starClicked = false; 338 pos = self.events._getTouchPosition(e); 339 out = self.calculate(pos); 340 self._toggleHover(out); 341 self.$element.trigger('rating:hover', [out.val, out.caption, 'stars']); 342 }, 343 starMouseLeave: function (e) { 344 var out; 345 if (self.events._noMouseAction(e) || self.starClicked) { 346 return; 347 } 348 out = self.cache; 349 self._toggleHover(out); 350 self.$element.trigger('rating:hoverleave', ['stars']); 351 }, 352 clearMouseMove: function (e) { 353 var caption, val, width, out; 354 if (self.events._noMouseAction(e) || !self.hoverOnClear) { 355 return; 356 } 357 self.clearClicked = false;
358 caption = '<span class="' + self.clearCaptionClass + '">' + self.clearCaption + '</span>'; 359 val = self.clearValue; 360 width = self.getWidthFromValue(val) || 0; 361 out = {caption: caption, width: width, val: val}; 362 self._toggleHover(out); 363 self.$element.trigger('rating:hover', [val, caption, 'clear']); 364 }, 365 clearMouseLeave: function (e) { 366 var out; 367 if (self.events._noMouseAction(e) || self.clearClicked || !self.hoverOnClear) { 368 return; 369 } 370 out = self.cache; 371 self._toggleHover(out); 372 self.$element.trigger('rating:hoverleave', ['clear']); 373 }, 374 resetForm: function (e) { 375 if (e && e.isDefaultPrevented()) { 376 return; 377 } 378 if (!self.inactive) { 379 self.reset(); 380 } 381 } 382 }; 383 }, 384 _listen: function () { 385 var self = this, $el = self.$element, $form = $el.closest('form'), $rating = self.$rating, 386 $clear = self.$clear, events = self.events; 387 $h.handler($rating, 'touchstart touchmove touchend', $.proxy(events.initTouch, self)); 388 $h.handler($rating, 'click touchstart', $.proxy(events.starClick, self)); 389 $h.handler($rating, 'mousemove', $.proxy(events.starMouseMove, self)); 390 $h.handler($rating, 'mouseleave', $.proxy(events.starMouseLeave, self)); 391 if (self.showClear && $clear.length) { 392 $h.handler($clear, 'click touchstart', $.proxy(events.clearClick, self)); 393 $h.handler($clear, 'mousemove', $.proxy(events.clearMouseMove, self)); 394 $h.handler($clear, 'mouseleave', $.proxy(events.clearMouseLeave, self)); 395 } 396 if ($form.length) { 397 $h.handler($form, 'reset', $.proxy(events.resetForm, self), true); 398 } 399 return $el; 400 }, 401 _getStars: function (type) { 402 var self = this, stars = '<span class="' + type + '-stars">', i; 403 for (i = 1; i <= self.stars; i++) { 404 stars += '<span class="star">' + self[type + 'Star'] + '</span>'; 405 } 406 return stars + '</span>'; 407 }, 408 _setStars: function (pos) { 409 var self = this, out = arguments.length ? self.calculate(pos) : self.calculate(), $el = self.$element, 410 v = self._parseValue(out.val); 411 $el.val(v); 412 self.$filledStars.css('width', out.width); 413 self._setCaption(out.caption); 414 self.cache = out; 415 return $el; 416 }, 417 showStars: function (val) { 418 var self = this, v = self._parseValue(val); 419 self.$element.val(v); 420 return self._setStars(); 421 }, 422 calculate: function (pos) { 423 var self = this, defaultVal = $h.isEmpty(self.$element.val()) ? 0 : self.$element.val(), 424 val = arguments.length ? self.getValueFromPosition(pos) : defaultVal, 425 caption = self.fetchCaption(val), width = self.getWidthFromValue(val); 426 width += '%'; 427 return {caption: caption, width: width, val: val}; 428 }, 429 getValueFromPosition: function (pos) { 430 var self = this, precision = $h.getDecimalPlaces(self.step), val, factor, maxWidth = self.$rating.width(); 431 factor = (self.diff * pos) / (maxWidth * self.step); 432 factor = self.rtl ? Math.floor(factor) : Math.ceil(factor); 433 val = $h.applyPrecision(parseFloat(self.min + factor * self.step), precision); 434 val = Math.max(Math.min(val, self.max), self.min); 435 return self.rtl ? (self.max - val) : val; 436 }, 437 getWidthFromValue: function (val) { 438 var self = this, min = self.min, max = self.max, factor, $r = self.$emptyStars, w; 439 if (!val || val <= min || min === max) { 440 return 0; 441 } 442 w = $r.outerWidth(); 443 factor = w ? $r.width() / w : 1; 444 if (val >= max) { 445 return 100; 446 } 447 return (val - min) * factor * 100 / (max - min); 448 }, 449 fetchCaption: function (rating) { 450 var self = this, val = parseFloat(rating) || self.clearValue, css, cap, capVal, cssVal, caption, 451 vCap = self.starCaptions, vCss = self.starCaptionClasses; 452 if (val && val !== self.clearValue) { 453 val = $h.applyPrecision(val, $h.getDecimalPlaces(self.step)); 454 } 455 cssVal = typeof vCss === "function" ? vCss(val) : vCss[val]; 456 capVal = typeof vCap === "function" ? vCap(val) : vCap[val]; 457 cap = $h.isEmpty(capVal) ? self.defaultCaption.replace(/\{rating}/g, val) : capVal; 458 css = $h.isEmpty(cssVal) ? self.clearCaptionClass : cssVal; 459 caption = (val === self.clearValue) ? self.clearCaption : cap; 460 return '<span class="' + css + '">' + caption + '</span>'; 461 }, 462 destroy: function () { 463 var self = this, $el = self.$element; 464 if (!$h.isEmpty(self.$container)) { 465 self.$container.before($el).remove(); 466 } 467 $.removeData($el.get(0)); 468 return $el.off('rating').removeClass('rating rating-input'); 469 }, 470 create: function (options) { 471 var self = this, opts = options || self.options || {}; 472 return self.destroy().rating(opts); 473 }, 474 clear: function () { 475 var self = this, title = '<span class="' + self.clearCaptionClass + '">' + self.clearCaption + '</span>'; 476 if (!self.inactive) { 477 self._setCaption(title); 478 } 479 return self.showStars(self.clearValue).trigger('change').trigger('rating:clear'); 480 }, 481 reset: function () { 482 var self = this; 483 return self.showStars(self.initialValue).trigger('rating:reset'); 484 }, 485 update: function (val) { 486 var self = this; 487 return arguments.length ? self.showStars(val) : self.$element; 488 }, 489 refresh: function (options) { 490 var self = this, $el = self.$element; 491 if (!options) { 492 return $el; 493 } 494 return self.destroy().rating($.extend(true, self.options, options)).trigger('rating:refresh'); 495 } 496 }; 497 498 $.fn.rating = function (option) { 499 var args = Array.apply(null, arguments), retvals = []; 500 args.shift(); 501 this.each(function () { 502 var self = $(this), data = self.data('rating'), options = typeof option === 'object' && option, 503 theme = options.theme || self.data('theme'), lang = options.language || self.data('language') || 'en', 504 thm = {}, loc = {}, opts; 505 if (!data) { 506 if (theme) { 507 thm = $.fn.ratingThemes[theme] || {}; 508 } 509 if (lang !== 'en' && !$h.isEmpty($.fn.ratingLocales[lang])) { 510 loc = $.fn.ratingLocales[lang]; 511 } 512 opts = $.extend(true, {}, $.fn.rating.defaults, thm, $.fn.ratingLocales.en, loc, options, self.data()); 513 data = new Rating(this, opts); 514 self.data('rating', data); 515 } 516 517 if (typeof option === 'string') { 518 retvals.push(data[option].apply(data, args)); 519 } 520 }); 521 switch (retvals.length) { 522 case 0: 523 return this; 524 case 1:
525 return retvals[0] === undefined ? this : retvals[0]; 526 default: 527 return retvals; 528 } 529 }; 530 531 $.fn.rating.defaults = { 532 theme: '', 533 language: 'en', 534 stars: 5, 535 filledStar: '<i class="glyphicon glyphicon-star"></i>', 536 emptyStar: '<i class="glyphicon glyphicon-star-empty"></i>', 537 containerClass: '', 538 size: 'md', 539 animate: true, 540 displayOnly: false, 541 rtl: false, 542 showClear: true, 543 showCaption: true, 544 starCaptionClasses: { 545 0.5: 'label label-danger badge-danger', 546 1: 'label label-danger badge-danger', 547 1.5: 'label label-warning badge-warning', 548 2: 'label label-warning badge-warning', 549 2.5: 'label label-info badge-info', 550 3: 'label label-info badge-info', 551 3.5: 'label label-primary badge-primary', 552 4: 'label label-primary badge-primary', 553 4.5: 'label label-success badge-success', 554 5: 'label label-success badge-success' 555 }, 556 clearButton: '<i class="glyphicon glyphicon-minus-sign"></i>', 557 clearButtonBaseClass: 'clear-rating', 558 clearButtonActiveClass: 'clear-rating-active', 559 clearCaptionClass: 'label label-default', 560 clearValue: null, 561 captionElement: null, 562 clearElement: null, 563 hoverEnabled: true, 564 hoverChangeCaption: true, 565 hoverChangeStars: true, 566 hoverOnClear: true, 567 zeroAsNull: true 568 }; 569 570 $.fn.ratingLocales.en = { 571 defaultCaption: '{rating} Stars', 572 starCaptions: { 573 0.5: 'Half Star', 574 1: 'One Star', 575 1.5: 'One & Half Star', 576 2: 'Two Stars', 577 2.5: 'Two & Half Stars', 578 3: 'Three Stars', 579 3.5: 'Three & Half Stars', 580 4: 'Four Stars', 581 4.5: 'Four & Half Stars', 582 5: 'Five Stars' 583 }, 584 clearButtonTitle: 'Clear', 585 clearCaption: 'Not Rated' 586 }; 587 588 $.fn.rating.Constructor = Rating; 589 590 /** 591 * Convert automatically inputs with class 'rating' into Krajee's star rating control. 592 */ 593 $(document).ready(function () { 594 var $input = $('input.rating'); 595 if ($input.length) { 596 $input.removeClass('rating-loading').addClass('rating-loading').rating(); 597 } 598 }); 599}));
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.