1/*! 2 * jQuery Raty - A Star Rating Plugin 3 * 4 * The MIT License 5 * 6 * author: Washington Botelho 7 * github: wbotelhos/raty 8 * version: 2.8.0 9 * 10 */ 11 12(function($) { 13 'use strict'; 14 15 var methods = { 16 init: function(options) { 17 return this.each(function() { 18 this.self = $(this); 19 20 methods.destroy.call(this.self); 21 22 this.opt = $.extend(true, {}, $.fn.raty.defaults, options, this.self.data()); 23 24 methods._adjustCallback.call(this); 25 methods._adjustNumber.call(this); 26 methods._adjustHints.call(this); 27 28 this.opt.score = methods._adjustedScore.call(this, this.opt.score); 29 30 if (this.opt.starType !== 'img') { 31 methods._adjustStarType.call(this); 32 } 33 34 methods._adjustPath.call(this); 35 methods._createStars.call(this); 36 37 if (this.opt.cancel) { 38 methods._createCancel.call(this); 39 } 40 41 if (this.opt.precision) { 42 methods._adjustPrecision.call(this); 43 } 44 45 methods._createScore.call(this); 46 methods._apply.call(this, this.opt.score); 47 methods._setTitle.call(this, this.opt.score); 48 methods._target.call(this, this.opt.score); 49 50 if (this.opt.readOnly) { 51 methods._lock.call(this); 52 } else { 53 this.style.cursor = 'pointer'; 54 55 methods._binds.call(this); 56 } 57 }); 58 }, 59 60 _adjustCallback: function() { 61 var options = ['number', 'readOnly', 'score', 'scoreName', 'target', 'path']; 62 63 for (var i = 0; i < options.length; i++) { 64 if (typeof this.opt[options[i]] === 'function') { 65 this.opt[options[i]] = this.opt[options[i]].call(this); 66 } 67 } 68 }, 69 70 _adjustedScore: function(score) { 71 if (!score) { 72 return score; 73 } 74 75 return methods._between(score, 0, this.opt.number); 76 }, 77 78 _adjustHints: function() { 79 if (!this.opt.hints) { 80 this.opt.hints = []; 81 } 82 83 if (!this.opt.halfShow && !this.opt.half) { 84 return; 85 } 86 87 var steps = this.opt.precision ? 10 : 2; 88 89 for (var i = 0; i < this.opt.number; i++) { 90 var group = this.opt.hints[i]; 91 92 if (Object.prototype.toString.call(group) !== '[object Array]') { 93 group = [group]; 94 } 95 96 this.opt.hints[i] = []; 97 98 for (var j = 0; j < steps; j++) { 99 var 100 hint = group[j], 101 last = group[group.length - 1]; 102 103 if (last === undefined) { 104 last = null; 105 } 106 107 this.opt.hints[i][j] = hint === undefined ? last : hint; 108 } 109 } 110 }, 111 112 _adjustNumber: function() { 113 this.opt.number = methods._between(this.opt.number, 1, this.opt.numberMax); 114 }, 115 116 _adjustPath: function() { 117 this.opt.path = this.opt.path || ''; 118 119 if (this.opt.path && this.opt.path.charAt(this.opt.path.length - 1) !== '/') { 120 this.opt.path += '/'; 121 } 122 }, 123 124 _adjustPrecision: function() { 125 this.opt.half = true; 126 }, 127 128 _adjustStarType: function() { 129 var replaces = ['cancelOff', 'cancelOn', 'starHalf', 'starOff', 'starOn']; 130 131 this.opt.path = ''; 132 133 for (var i = 0; i < replaces.length; i++) { 134 this.opt[replaces[i]] = this.opt[replaces[i]].replace('.', '-'); 135 } 136 }, 137 138 _apply: function(score) { 139 methods._fill.call(this, score); 140 141 if (score) { 142 if (score > 0) { 143 this.score.val(score); 144 } 145 146 methods._roundStars.call(this, score); 147 } 148 }, 149 150 _between: function(value, min, max) { 151 return Math.min(Math.max(parseFloat(value), min), max); 152 }, 153 154 _binds: function() { 155 if (this.cancel) { 156 methods._bindOverCancel.call(this); 157 methods._bindClickCancel.call(this); 158 methods._bindOutCancel.call(this); 159 } 160 161 methods._bindOver.call(this); 162 methods._bindClick.call(this); 163 methods._bindOut.call(this); 164 }, 165 166 _bindClick: function() { 167 var that = this; 168 169 that.stars.on('click.raty', function(evt) { 170 var 171 execute = true, 172 score = (that.opt.half || that.opt.precision) ? that.self.data('score') : (this.alt || $(this).data('alt')); 173 174 if (that.opt.click) { 175 execute = that.opt.click.call(that, +score, evt); 176 } 177 178 if (execute || execute === undefined) { 179 if (that.opt.half && !that.opt.precision) {
180 score = methods._roundHalfScore.call(that, score); 181 } 182 183 methods._apply.call(that, score); 184 } 185 }); 186 }, 187 188 _bindClickCancel: function() { 189 var that = this; 190 191 that.cancel.on('click.raty', function(evt) { 192 that.score.removeAttr('value'); 193 194 if (that.opt.click) { 195 that.opt.click.call(that, null, evt); 196 } 197 }); 198 }, 199 200 _bindOut: function() { 201 var that = this; 202 203 that.self.on('mouseleave.raty', function(evt) { 204 var score = +that.score.val() || undefined; 205 206 methods._apply.call(that, score); 207 methods._target.call(that, score, evt); 208 methods._resetTitle.call(that); 209 210 if (that.opt.mouseout) { 211 that.opt.mouseout.call(that, score, evt); 212 } 213 }); 214 }, 215 216 _bindOutCancel: function() { 217 var that = this; 218 219 that.cancel.on('mouseleave.raty', function(evt) { 220 var icon = that.opt.cancelOff; 221 222 if (that.opt.starType !== 'img') { 223 icon = that.opt.cancelClass + ' ' + icon; 224 } 225 226 methods._setIcon.call(that, this, icon); 227 228 if (that.opt.mouseout) { 229 var score = +that.score.val() || undefined; 230 231 that.opt.mouseout.call(that, score, evt); 232 } 233 }); 234 }, 235 236 _bindOver: function() { 237 var 238 that = this, 239 action = that.opt.half ? 'mousemove.raty' : 'mouseover.raty'; 240 241 that.stars.on(action, function(evt) { 242 var score = methods._getScoreByPosition.call(that, evt, this); 243 244 methods._fill.call(that, score); 245 246 if (that.opt.half) { 247 methods._roundStars.call(that, score, evt); 248 methods._setTitle.call(that, score, evt); 249 250 that.self.data('score', score); 251 } 252 253 methods._target.call(that, score, evt); 254 255 if (that.opt.mouseover) { 256 that.opt.mouseover.call(that, score, evt); 257 } 258 }); 259 }, 260 261 _bindOverCancel: function() { 262 var that = this; 263 264 that.cancel.on('mouseover.raty', function(evt) { 265 var 266 starOff = that.opt.path + that.opt.starOff, 267 icon = that.opt.cancelOn; 268 269 if (that.opt.starType === 'img') { 270 that.stars.attr('src', starOff); 271 } else { 272 icon = that.opt.cancelClass + ' ' + icon; 273 274 that.stars.attr('class', starOff); 275 } 276 277 methods._setIcon.call(that, this, icon); 278 methods._target.call(that, null, evt); 279 280 if (that.opt.mouseover) { 281 that.opt.mouseover.call(that, null); 282 } 283 }); 284 }, 285 286 _buildScoreField: function() { 287 return $('<input />', { name: this.opt.scoreName, type: 'hidden' }).appendTo(this); 288 }, 289 290 _createCancel: function() { 291 var 292 icon = this.opt.path + this.opt.cancelOff, 293 cancel = $('<' + this.opt.starType + ' />', { title: this.opt.cancelHint, 'class': this.opt.cancelClass }); 294 295 if (this.opt.starType === 'img') { 296 cancel.attr({ src: icon, alt: 'x' }); 297 } else { 298 // TODO: use $.data 299 cancel.attr('data-alt', 'x').addClass(icon); 300 } 301 302 if (this.opt.cancelPlace === 'left') { 303 this.self.prepend(' ').prepend(cancel); 304 } else { 305 this.self.append(' ').append(cancel); 306 } 307 308 this.cancel = cancel; 309 }, 310 311 _createScore: function() { 312 var score = $(this.opt.targetScore); 313 314 this.score = score.length ? score : methods._buildScoreField.call(this); 315 }, 316 317 _createStars: function() { 318 for (var i = 1; i <= this.opt.number; i++) { 319 var 320 name = methods._nameForIndex.call(this, i), 321 attrs = { alt: i, src: this.opt.path + this.opt[name] }; 322 323 if (this.opt.starType !== 'img') { 324 attrs = { 'data-alt': i, 'class': attrs.src }; // TODO: use $.data. 325 } 326 327 attrs.title = methods._getHint.call(this, i); 328 329 $('<' + this.opt.starType + ' />', attrs).appendTo(this); 330 331 if (this.opt.space) { 332 this.self.append(i < this.opt.number ? ' ' : ''); 333 } 334 } 335 336 this.stars = this.self.children(this.opt.starType); 337 }, 338 339 _error: function(message) { 340 $(this).text(message); 341 342 $.error(message); 343 }, 344 345 _fill: function(score) { 346 var hash = 0; 347 348 for (var i = 1; i <= this.stars.length; i++) { 349 var 350 icon, 351 star = this.stars[i - 1], 352 turnOn = methods._turnOn.call(this, i, score); 353 354 if (this.opt.iconRange && this.opt.iconRange.length > hash) { 355 var irange = this.opt.iconRange[hash]; 356 357 icon = methods._getRangeIcon.call(this, irange, turnOn); 358 359 if (i <= irange.range) { 360 methods._setIcon.call(this, star, icon); 361 } 362 363 if (i === irange.range) { 364 hash++; 365 } 366 } else { 367 icon = this.opt[turnOn ? 'starOn' : 'starOff']; 368 369 methods._setIcon.call(this, star, icon); 370 } 371 } 372 }, 373
374 _getFirstDecimal: function(number) { 375 var 376 decimal = number.toString().split('.')[1], 377 result = 0; 378 379 if (decimal) { 380 result = parseInt(decimal.charAt(0), 10); 381 382 if (decimal.slice(1, 5) === '9999') { 383 result++; 384 } 385 } 386 387 return result; 388 }, 389 390 _getRangeIcon: function(irange, turnOn) { 391 return turnOn ? irange.on || this.opt.starOn : irange.off || this.opt.starOff; 392 }, 393 394 _getScoreByPosition: function(evt, icon) { 395 var score = parseInt(icon.alt || icon.getAttribute('data-alt'), 10); 396 397 if (this.opt.half) { 398 var 399 size = methods._getWidth.call(this), 400 percent = parseFloat((evt.pageX - $(icon).offset().left) / size); 401 402 score = score - 1 + percent; 403 } 404 405 return score; 406 }, 407 408 _getHint: function(score, evt) { 409 if (score !== 0 && !score) { 410 return this.opt.noRatedMsg; 411 } 412 413 var 414 decimal = methods._getFirstDecimal.call(this, score), 415 integer = Math.ceil(score), 416 group = this.opt.hints[(integer || 1) - 1], 417 hint = group, 418 set = !evt || this.move; 419 420 if (this.opt.precision) { 421 if (set) { 422 decimal = decimal === 0 ? 9 : decimal - 1; 423 } 424 425 hint = group[decimal]; 426 } else if (this.opt.halfShow || this.opt.half) { 427 decimal = set && decimal === 0 ? 1 : decimal > 5 ? 1 : 0; 428 429 hint = group[decimal]; 430 } 431 432 return hint === '' ? '' : hint || score; 433 }, 434 435 _getWidth: function() { 436 var width = this.stars[0].width || parseFloat(this.stars.eq(0).css('font-size')); 437 438 if (!width) { 439 methods._error.call(this, 'Could not get the icon width!'); 440 } 441 442 return width; 443 }, 444 445 _lock: function() { 446 var hint = methods._getHint.call(this, this.score.val()); 447 448 this.style.cursor = ''; 449 this.title = hint; 450 451 this.score.prop('readonly', true); 452 this.stars.prop('title', hint); 453 454 if (this.cancel) { 455 this.cancel.hide(); 456 } 457 458 this.self.data('readonly', true); 459 }, 460 461 _nameForIndex: function(i) { 462 return this.opt.score && this.opt.score >= i ? 'starOn' : 'starOff'; 463 }, 464 465 _resetTitle: function() { 466 for (var i = 0; i < this.opt.number; i++) { 467 this.stars[i].title = methods._getHint.call(this, i + 1); 468 } 469 }, 470 471 _roundHalfScore: function(score) { 472 var 473 integer = parseInt(score, 10), 474 decimal = methods._getFirstDecimal.call(this, score); 475 476 if (decimal !== 0) { 477 decimal = decimal > 5 ? 1 : 0.5; 478 } 479 480 return integer + decimal; 481 }, 482 483 _roundStars: function(score, evt) { 484 var 485 decimal = (score % 1).toFixed(2), 486 name ; 487 488 if (evt || this.move) { 489 name = decimal > 0.5 ? 'starOn' : 'starHalf'; 490 } else if (decimal > this.opt.round.down) { // Up: [x.76 .. x.99] 491 name = 'starOn'; 492 493 if (this.opt.halfShow && decimal < this.opt.round.up) { // Half: [x.26 .. x.75] 494 name = 'starHalf'; 495 } else if (decimal < this.opt.round.full) { // Down: [x.00 .. x.5] 496 name = 'starOff'; 497 } 498 } 499 500 if (name) { 501 var 502 icon = this.opt[name], 503 star = this.stars[Math.ceil(score) - 1]; 504 505 methods._setIcon.call(this, star, icon); 506 } // Full down: [x.00 .. x.25] 507 }, 508 509 _setIcon: function(star, icon) { 510 star[this.opt.starType === 'img' ? 'src' : 'className'] = this.opt.path + icon; 511 }, 512 513 _setTarget: function(target, score) { 514 if (score) { 515 score = this.opt.targetFormat.toString().replace('{score}', score); 516 } 517 518 if (target.is(':input')) { 519 target.val(score); 520 } else { 521 target.html(score); 522 } 523 }, 524 525 _setTitle: function(score, evt) { 526 if (score) { 527 var 528 integer = parseInt(Math.ceil(score), 10), 529 star = this.stars[integer - 1]; 530 531 star.title = methods._getHint.call(this, score, evt); 532 } 533 }, 534 535 _target: function(score, evt) { 536 if (this.opt.target) { 537 var target = $(this.opt.target); 538 539 if (!target.length) { 540 methods._error.call(this, 'Target selector invalid or missing!'); 541 } 542 543 var mouseover = evt && evt.type === 'mouseover'; 544 545 if (score === undefined) { 546 score = this.opt.targetText; 547 } else if (score === null) { 548 score = mouseover ? this.opt.cancelHint : this.opt.targetText; 549 } else { 550 if (this.opt.targetType === 'hint') { 551 score = methods._getHint.call(this, score, evt); 552 } else if (this.opt.precision) { 553 score = parseFloat(score).toFixed(1); 554 } 555 556 var mousemove = evt && evt.type === 'mousemove'; 557 558 if (!mouseover && !mousemove && !this.opt.targetKeep) { 559 score = this.opt.targetText; 560 } 561 } 562 563 methods._setTarget.call(this, target, score); 564 } 565 }, 566 567 _turnOn: function(i, score) { 568 return this.opt.single ? (i === score) : (i <= score); 569 }, 570 571 _unlock: function() { 572 this.style.cursor = 'pointer'; 573 this.removeAttribute('title'); 574 575 this.score.removeAttr('readonly'); 576 577 this.self.data('readonly', false); 578 579 for (var i = 0; i < this.opt.number; i++) { 580 this.stars[i].title = methods._getHint.call(this, i + 1); 581 } 582 583 if (this.cancel) { 584 this.cancel.css('display', ''); 585 } 586 }, 587 588 cancel: function(click) { 589 return this.each(function() { 590 var self = $(this); 591 592 if (self.data('readonly') !== true) { 593 methods[click ? 'click' : 'score'].call(self, null); 594 595 this.score.removeAttr('value'); 596 } 597 }); 598 }, 599 600 click: function(score) { 601 return this.each(function() { 602 if ($(this).data('readonly') !== true) {
603 score = methods._adjustedScore.call(this, score); 604 605 methods._apply.call(this, score); 606 607 if (this.opt.click) { 608 this.opt.click.call(this, score, $.Event('click')); 609 } 610 611 methods._target.call(this, score); 612 } 613 }); 614 }, 615 616 destroy: function() { 617 return this.each(function() { 618 var 619 self = $(this), 620 raw = self.data('raw'); 621 622 if (raw) { 623 self.off('.raty').empty().css({ cursor: raw.style.cursor }).removeData('readonly'); 624 } else { 625 self.data('raw', self.clone()[0]); 626 } 627 }); 628 }, 629 630 getScore: function() { 631 var 632 score = [], 633 value ; 634 635 this.each(function() { 636 value = this.score.val(); 637 638 score.push(value ? +value : undefined); 639 }); 640 641 return (score.length > 1) ? score : score[0]; 642 }, 643 644 move: function(score) { 645 return this.each(function() { 646 var 647 integer = parseInt(score, 10), 648 decimal = methods._getFirstDecimal.call(this, score); 649 650 if (integer >= this.opt.number) { 651 integer = this.opt.number - 1; 652 decimal = 10; 653 } 654 655 var 656 width = methods._getWidth.call(this), 657 steps = width / 10, 658 star = $(this.stars[integer]), 659 percent = star.offset().left + steps * decimal, 660 evt = $.Event('mousemove', { pageX: percent }); 661 662 this.move = true; 663 664 star.trigger(evt); 665 666 this.move = false; 667 }); 668 }, 669 670 readOnly: function(readonly) { 671 return this.each(function() { 672 var self = $(this); 673 674 if (self.data('readonly') !== readonly) { 675 if (readonly) { 676 self.off('.raty').children(this.opt.starType).off('.raty'); 677 678 methods._lock.call(this); 679 } else { 680 methods._binds.call(this); 681 methods._unlock.call(this); 682 } 683 684 self.data('readonly', readonly); 685 } 686 }); 687 }, 688 689 reload: function() { 690 return methods.set.call(this, {}); 691 }, 692 693 score: function() { 694 var self = $(this); 695 696 return arguments.length ? methods.setScore.apply(self, arguments) : methods.getScore.call(self); 697 }, 698 699 set: function(options) { 700 return this.each(function() { 701 $(this).raty($.extend({}, this.opt, options)); 702 }); 703 }, 704 705 setScore: function(score) { 706 return this.each(function() { 707 if ($(this).data('readonly') !== true) { 708 score = methods._adjustedScore.call(this, score); 709 710 methods._apply.call(this, score); 711 methods._target.call(this, score); 712 } 713 }); 714 } 715 }; 716 717 $.fn.raty = function(method) { 718 if (methods[method]) { 719 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 720 } else if (typeof method === 'object' || !method) { 721 return methods.init.apply(this, arguments); 722 } else { 723 $.error('Method ' + method + ' does not exist!'); 724 } 725 }; 726 727 $.fn.raty.defaults = { 728 cancel: false, 729 cancelClass: 'raty-cancel', 730 cancelHint: 'Cancel this rating!', 731 cancelOff: 'cancel-off.png', 732 cancelOn: 'cancel-on.png', 733 cancelPlace: 'left', 734 click: undefined, 735 half: false, 736 halfShow: true, 737 hints: ['bad', 'poor', 'regular', 'good', 'gorgeous'], 738 iconRange: undefined, 739 mouseout: undefined, 740 mouseover: undefined, 741 noRatedMsg: 'Not rated yet!', 742 number: 5, 743 numberMax: 20, 744 path: undefined, 745 precision: false, 746 readOnly: false, 747 round: { down: 0.25, full: 0.6, up: 0.76 }, 748 score: undefined, 749 scoreName: 'score', 750 single: false, 751 space: true, 752 starHalf: 'star-half.png', 753 starOff: 'star-off.png', 754 starOn: 'star-on.png', 755 starType: 'img', 756 target: undefined, 757 targetFormat: '{score}', 758 targetKeep: false, 759 targetScore: undefined, 760 targetText: '', 761 targetType: 'hint' 762 }; 763})(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.