PageSourceSearch

https://diveaai.com/js/jquery.rateyo.js

js diveaai.com collected 2026-09-29 19:50:55 UTC 29,648 bytes, 1,136 lines download raw bytes

1/*****
2* rateyo - v2.3.3
3* http://prrashi.github.io/rateyo/
4* Copyright (c) 2014 Prashanth Pamidi; Licensed MIT
5*****/
6
7;(function ($) {
8  "use strict";
9
10  // The basic svg string required to generate stars
11  var BASICSTAR = "<xml version=\"1.0\" encoding=\"utf-8\">"+
12                  "<svg version=\"1.1\""+
13                        "xmlns=\"http://www.w3.org/2000/svg\""+
14                        "viewBox=\"0 12.705 512 486.59\""+
15                        "x=\"0px\" y=\"0px\""+
16                        "xml:space=\"preserve\">"+
17                    "<polygon "+
18                              "points=\"256.814,12.705 317.205,198.566"+
19                                      " 512.631,198.566 354.529,313.435 "+
20                                      "414.918,499.295 256.814,384.427 "+
21                                      "98.713,499.295 159.102,313.435 "+
22                                      "1,198.566 196.426,198.566 \" style='stroke:black;stroke-width:30'/>"+
23                  "</svg>";
24
25  // The Default values of different options available in the Plugin
26  var DEFAULTS = {
27
28    starWidth : "32px",
29    normalFill: "gray",
30    ratedFill : "#f39c12",
31    numStars  : 5,
32    maxValue  : 5,
33    precision : 1,
34    rating    : 0,
35    fullStar  : false,
36    halfStar  : false,
37    readOnly  : false,
38    spacing   : "0px",
39    rtl       : false,
40    multiColor: null,
41    onInit    : null,
42    onChange  : null,
43    onSet     : null,
44    starSvg   : null
45  };
46
47  //Default colors for multi-color rating
48  var MULTICOLOR_OPTIONS = {
49
50    startColor: "#c0392b", //red
51    endColor  : "#f1c40f"  //yellow
52  };
53
54  // http://stackoverflow.com/questions/11381673/detecting-a-mobile-browser
55  function isMobileBrowser () {
56    var check = false;
57    /* jshint ignore:start */
58    (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera);
59    /* jshint ignore:end */
60    return check;
61  }
62
63  function checkPrecision (value, minValue, maxValue) {
64
65    /*
66     * This function removes the unnecessary precision, at Min and Max Values
67     */
68
69    // Its like comparing 0.0 with 0, which is true
70    if (value === minValue) {
71
72      value = minValue;
73    }
74    else if(value === maxValue) {
75
76      value = maxValue;
77    }
78
79    return value;
80  }
81
82  function checkBounds (value, minValue, maxValue) {
83
84    /*
85     * Check if the value is between min and max values, if not, throw an error
86     */
87
88    var isValid = value >= minValue && value <= maxValue;
89
90    if(!isValid){
91
92        throw Error("Invalid Rating, expected value between "+ minValue +
93                    " and " + maxValue);
94    }
95
96    return value;
97  }
98
99  function isDefined(value) {
100
101    // Better way to check if a variable is defined or not
102    return typeof value !== "undefined";
103  }
104
105  // Regex to match Colors in Hex Format like #FF00FF
106  var hexRegex = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i;
107
108  var hexToRGB = function (hex) {
109
110    /*
111     * Extracts and returns the Red, Blue, Green Channel values,
112     * in the form of decimals
113     */
114
115    if (!hexRegex.test(hex)) {
116
117      return null;
118    }
119
120    var hexValues = hexRegex.exec(hex),
121        r = parseInt(hexValues[1], 16),
122        g = parseInt(hexValues[2], 16),
123        b = parseInt(hexValues[3], 16);
124
125    return {r:r, g:g, b:b};
126  };
127
128  function getChannelValue(startVal, endVal, percent) {
129
130    /*
131     * Returns a value between `startVal` and `endVal` based on the percent
132     */
133
134    var newVal = (endVal - startVal)*(percent/100);
135
136    newVal = Math.round(startVal + newVal).toString(16);
137
138    if (newVal.length === 1) {
139
140        newVal = "0" + newVal;
141    }
142
143    return newVal;
144  }
145
146  function getColor (startColor, endColor, percent) {
147
148    /*
149     * Given the percentage( `percent` ) of `endColor` to be mixed
150     * with the `startColor`, returns the mixed color.
151     * Colors should be only in Hex Format
152     */
153
154    if (!startColor || !endColor) {
155
156      return null;
157    }
158
159    percent = isDefined(percent)? percent : 0;
160
161    startColor = hexToRGB(startColor);
162    endColor = hexToRGB(endColor);
163
164    var r = getChannelValue(startColor.r, endColor.r, percent),
165        b = getChannelValue(startColor.b, endColor.b, percent),
166        g = getChannelValue(startColor.g, endColor.g, percent);
167
168    return "#" + r + g + b;
169  }
170
171  function RateYo ($node, options) {
172
173    /*
174     * The Contructor, whose instances are used by plugin itself
175     */
176
177    // Storing the HTML element as a property, for future access
178    this.node = $node.get(0);
179
180    var that = this;
181
182    // Remove any stuff that is present inside the container, and add the plugin class
183    $node.empty().addClass("jq-ry-container");
184
185    /*
186     * Basically the plugin displays the rating using two rows of stars lying one above
187     * the other, the row that is on the top represents the actual rating, and the one
188     * behind acts just like a background.
189     *
190     * `$groupWrapper`: is an element that wraps both the rows
191     * `$normalGroup`: is the container for row of stars thats behind and
192     *                 acts as background
193     * `$ratedGroup`: is the container for row of stars that display the actual rating.
194     *
195     * The rating is displayed by adjusting the width of `$ratedGroup`
196     */
197    var $groupWrapper = $("<div/>").addClass("jq-ry-group-wrapper")
198                                   .appendTo($node);
199
200    var $normalGroup = $("<div/>").addClass("jq-ry-normal-group")
201                                  .addClass("jq-ry-group")
202                                  .appendTo($groupWrapper);
203
204    var $ratedGroup = $("<div/>").addClass("jq-ry-rated-group")
205                                 .addClass("jq-ry-group")
206                                 .appendTo($groupWrapper);
207
208    /*
209     * Variable `step`: store the value of the rating for each star
210     *                  eg: if `maxValue` is 5 and `numStars` is 5, value of each star
211     *                      is 1.
212     * Variable `starWidth`: stores the decimal value of width of star in units of px
213     * Variable `percentOfStar`: stores the percentage of width each star takes w.r.t
214     *                           the container
215     * Variable `spacing`: stores the decimal value of the spacing between stars
216     *                     in the units of px
217     * Variable `percentOfSpacing`: stores the percentage of width of the spacing
218     *                              between stars w.r.t the container
219     */
220    var step, starWidth, percentOfStar, spacing,
221        percentOfSpacing, containerWidth, minValue = 0;
222
223    /*
224     * `currentRating` contains rating that is being displayed at the latest point of
225     * time.
226     *
227     * When ever you hover over the plugin UI, the rating value changes
228     * according to the place where you point the cursor, currentRating contains
229     * the current value of rating that is being shown in the UI
230     */
231    var currentRating = options.rating;
232
233    // A flag to store if the plugin is already being displayed in the UI
234    var isInitialized = false;
235
236    function showRating (ratingVal) {
237
238      /*
239       * The function is responsible for displaying the rating by changing
240       * the width of `$ratedGroup`
241       */
242
243      if (!isDefined(ratingVal)) {
244
245        ratingVal = options.rating;
246      }
247
248      // Storing the value that is being shown in `currentRating`.
249      currentRating = ratingVal;
250
251      var numStarsToShow = ratingVal/step;
252
253      // calculating the percentage of width of $ratedGroup with respect to its parent
254      var percent = numStarsToShow*percentOfStar;
255
256      if (numStarsToShow > 1) {
257
258        // adding the percentage of space that is taken by the gap the stars
259        percent += (Math.ceil(numStarsToShow) - 1)*percentOfSpacing;
260      }
261
262      setRatedFill(options.ratedFill);
263
264      percent = options.rtl ? 100 - percent : percent;
265
266      if (percent < 0) {
267
268        percent = 0;
269      } else if (percent > 100) {
270
271        percent = 100;
272      }
273
274      $ratedGroup.css("width", percent + "%");
275    }
276
277    function setContainerWidth () {
278
279      /*
280       * Set the width of the `this.node` based on the width of each star and
281       * the space between them
282       */
283
284      containerWidth = starWidth*options.numStars + spacing*(options.numStars - 1);
285
286      percentOfStar = (starWidth/containerWidth)*100;
287
288      percentOfSpacing = (spacing/containerWidth)*100;
289
290      $node.width(containerWidth);
291
292      showRating();
293    }
294
295    function setStarWidth (newWidth) {
296
297      /*
298       * Set the width and height of each SVG star, called whenever one changes the
299       * `starWidth` option
300       */
301
302      // The width and height of the star should be the same
303      var starHeight = options.starWidth = newWidth;
304
305      starWidth = window.parseFloat(options.starWidth.replace("px", ""));
306
307      $normalGroup.find("svg")
308                  .attr({width : options.starWidth,
309                         height: starHeight});
310
311      $ratedGroup.find("svg")
312                 .attr({width : options.starWidth,
313                        height: starHeight});
314
315      setContainerWidth();
316
317      return $node;
318    }
319
320    function setSpacing (newSpacing) {
321
322      /*
323       * Set spacing between the SVG stars, called whenever one changes
324       * the `spacing` option
325       */
326
327      options.spacing = newSpacing;
328
329      spacing = parseFloat(options.spacing.replace("px", ""));
330
331      $normalGroup.find("svg:not(:first-child)")
332                  .css({"margin-left": newSpacing});
333
334      $ratedGroup.find("svg:not(:first-child)")
335                 .css({"margin-left": newSpacing});
336
337      setContainerWidth();
338
339      return $node;
340    }
341
342    function setNormalFill (newFill) {
343
344      /*
345       * Set the background fill of the Stars, called whenever one changes the
346       * `normalFill` option
347       */
348
349      options.normalFill = newFill;
350
351      var $svgs = (options.rtl ? $ratedGroup : $normalGroup).find("svg");
352
353      $svgs.attr({fill: options.normalFill});
354
355      return $node;
356    }
357
358    /*
359     * Store the recent `ratedFill` option in a variable
360     * so that if multiColor is unset, we can use the perviously set `ratedFill`
361     * from this variable
362     */
363    var ratedFill = options.ratedFill;
364
365    function setRatedFill (newFill) {
366
367      /*
368       * Set ratedFill of the stars, called when one changes the `ratedFill` option
369       */
370
371      /*
372       * If `multiColor` option is set, `newFill` variable is dynamically set
373       * based on the rating, what ever set as parameter will be discarded
374       */
375      if (options.multiColor) {
376
377        var ratingDiff = currentRating - minValue,
378            percentCovered = (ratingDiff/options.maxValue)*100;
379
380        var colorOpts  = options.multiColor || {},
381            startColor = colorOpts.startColor || MULTICOLOR_OPTIONS.startColor,
382            endColor   = colorOpts.endColor || MULTICOLOR_OPTIONS.endColor;
383
384        newFill = getColor(startColor, endColor, percentCovered);
385      } else {
386
387        ratedFill = newFill;
388      }
389
390      options.ratedFill = newFill;
391
392      var $svgs = (options.rtl ? $normalGroup : $ratedGroup).find("svg");
393
394      $svgs.attr({fill: options.ratedFill});
395
396      return $node;
397    }
398
399    function setRtl (newValue) {
400
401      newValue = !!newValue;
402
403      options.rtl = newValue;
404
405      setNormalFill(options.normalFill);
406      showRating();
407    }
408
409    function setMultiColor (colorOptions) {
410
411      /*
412       * called whenever one changes the `multiColor` option
413       */
414
415      options.multiColor = colorOptions;
416
417      // set the recently set `ratedFill` option, if multiColor Options are unset
418      setRatedFill(colorOptions ? colorOptions : ratedFill);
419    }
420
421    function setNumStars (newValue) {
422
423      /*
424       * Set the number of stars to use to display the rating, called whenever one
425       * changes the `numStars` option
426       */
427
428      options.numStars = newValue;
429
430      step = options.maxValue/options.numStars;
431
432      $normalGroup.empty();
433      $ratedGroup.empty();
434
435      for (var i=0; i<options.numStars; i++) {
436
437        $normalGroup.append($(options.starSvg || BASICSTAR));
438        $ratedGroup.append($(options.starSvg || BASICSTAR));
439      }
440
441      setStarWidth(options.starWidth);
442      setNormalFill(options.normalFill);
443      setSpacing(options.spacing);
444
445      showRating();
446
447      return $node;
448    }
449
450    function setMaxValue (newValue) {
451
452      /*
453       * set the Maximum Value of rating to be allowed, called whenever
454       * one changes the `maxValue` option
455       */
456
457      options.maxValue = newValue;
458
459      step = options.maxValue/options.numStars;
460
461      if (options.rating > newValue) {
462
463        setRating(newValue);
464      }
465
466      showRating();
467
468      return $node;
469    }
470
471    function setPrecision (newValue) {
472
473      /*
474       * Set the precision of the rating value, called if one changes the
475       * `precision` option
476       */
477
478      options.precision = newValue;
479
480      setRating(options.rating);
481
482      return $node;
483    }
484
485    function setHalfStar (newValue) {
486
487      /*
488       * This function will be called if one changes the `halfStar` option
489       */
490
491      options.halfStar = newValue;
492
493      return $node;
494    }
495
496    function setFullStar (newValue) {
497
498      /*
499       * This function will be called if one changes the `fullStar` option
500       */
501
502      options.fullStar = newValue;
503
504      return $node;
505    }
506
507    function round (value) {
508
509      /*
510       * Rounds the value of rating if `halfStar` or `fullStar` options are chosen
511       */
512
513      var remainder = value%step,
514          halfStep = step/2,
515          isHalfStar = options.halfStar,
516          isFullStar = options.fullStar;
517
518      if (!isFullStar && !isHalfStar) {
519
520        return value;
521      }
522
523      if (isFullStar || (isHalfStar && remainder > halfStep)) {
524
525        value += step - remainder;
526      } else {
527
528        value = value - remainder;
529
530        if (remainder > 0) {
531
532          value += halfStep;
533        }
534      }
535
536      return value;
537    }
538
539    function calculateRating (e) {
540
541      /*
542       * Calculates and returns the rating based on the position of cursor w.r.t the
543       * plugin container
544       */
545
546      var position = $normalGroup.offset(),
547          nodeStartX = position.left,
548          nodeEndX = nodeStartX + $normalGroup.width();
549
550      var maxValue = options.maxValue;
551
552      // The x-coordinate(position) of the mouse pointer w.r.t page
553      var pageX = e.pageX;
554
555      var calculatedRating = 0;
556
557      // If the mouse pointer is to the left of the container
558      if(pageX < nodeStartX) {
559
560        calculatedRating = minValue;
561      }else if (pageX > nodeEndX) { // If the mouse pointer is right of the container
562
563        calculatedRating = maxValue;
564      }else { // If the mouse pointer is inside the continer
565
566        /*
567         * The fraction of width covered by the pointer w.r.t to the total width
568         * of the container.
569         */
570        var calcPrcnt = ((pageX - nodeStartX)/(nodeEndX - nodeStartX));
571
572        if (spacing > 0) {
573
574          /*
575           * If there is spacing between stars, take the percentage of width covered
576           * and subtract the percentage of width covered by stars and spacing, to find
577           * how many stars are covered, the number of stars covered is the rating
578           *
579           * TODO: I strongly feel that this logic can be improved!, Please help!
580           */
581          calcPrcnt *= 100;
582
583          var remPrcnt = calcPrcnt;
584
585          while (remPrcnt > 0) {
586
587            if (remPrcnt > percentOfStar) {
588
589              calculatedRating += step;
590              remPrcnt -= (percentOfStar + percentOfSpacing);
591            } else {
592
593              calculatedRating += remPrcnt/percentOfStar*step;
594              remPrcnt = 0;
595            }
596          }
597        } else {
598
599          /*
600           * If there is not spacing between stars, the fraction of width covered per
601           * `maxValue` is the rating
602           */
603          calculatedRating = calcPrcnt * (options.maxValue);
604        }
605
606        // Round the rating if `halfStar` or `fullStar` options are chosen
607        calculatedRating = round(calculatedRating);
608      }
609
610      if (options.rtl) {
611
612        calculatedRating = maxValue - calculatedRating;
613      }
614
615      return parseFloat(calculatedRating);
616    }
617
618    function setReadOnly (newValue) {
619
620      /*
621       * UnBinds mouse event handlers, called when whenever one changes the
622       * `readOnly` option
623       */
624
625      options.readOnly = newValue;
626
627      $node.attr("readonly", true);
628
629      unbindEvents();
630
631      if (!newValue) {
632
633        $node.removeAttr("readonly");
634
635        bindEvents();
636      }
637
638      return $node;
639    }
640
641    function setRating (newValue) {
642
643      /*
644       * Sets the rating of the Plugin, Called when option `rating` is changed
645       * or, when `rating` method is called
646       */
647
648      var rating = newValue;
649
650      var maxValue = options.maxValue;
651
652      if (typeof rating === "string") {
653
654        // If rating is given in percentage, maxValue should be 100
655        if (rating[rating.length - 1] === "%") {
656
657          rating = rating.substr(0, rating.length - 1);
658          maxValue = 100;
659
660          setMaxValue(maxValue);
661        }
662
663        rating = parseFloat(rating);
664      }
665
666      checkBounds(rating, minValue, maxValue);
667
668      rating = parseFloat(rating.toFixed(options.precision));
669
670      checkPrecision(parseFloat(rating), minValue, maxValue);
671
672      options.rating = rating;
673
674      showRating();
675
676      if (isInitialized) {
677
678        $node.trigger("rateyo.set", {rating: rating});
679      }
680
681      return $node;
682    }
683
684    function setOnInit (method) {
685
686      /*
687       * set what method to be called on Initialization
688       */
689
690      options.onInit = method;
691
692      return $node;
693    }
694
695    function setOnSet (method) {
696
697      /*
698       * set what method to be called when rating is set
699       */
700
701      options.onSet = method;
702
703      return $node;
704    }
705
706    function setOnChange (method) {
707
708      /*
709       * set what method to be called rating in the UI is changed
710       */
711
712      options.onChange = method;
713
714      return $node;
715    }
716
717    this.rating = function (newValue) {
718
719      /*
720       * rating getter/setter
721       */
722
723      if (!isDefined(newValue)) {
724
725        return options.rating;
726      }
727
728      setRating(newValue);
729
730      return $node;
731    };
732
733    this.destroy = function () {
734
735      /*
736       * Removes the Rating UI by clearing the content, and removing the custom classes
737       */
738
739      if (!options.readOnly) {
740
741        unbindEvents();
742      }
743
744      RateYo.prototype.collection = deleteInstance($node.get(0),
745                                                   this.collection);
746
747      $node.removeClass("jq-ry-container").children().remove();
748
749      return $node;
750    };
751
752    this.method = function (methodName) {
753
754      /*
755       * Method to call the methods of RateYo Instance
756       */
757
758      if (!methodName) {
759
760        throw Error("Method name not specified!");
761      }
762
763      if (!isDefined(this[methodName])) {
764
765        throw Error("Method " + methodName + " doesn't exist!");
766      }
767
768      var args = Array.prototype.slice.apply(arguments, []),
769          params = args.slice(1),
770          method = this[methodName];
771
772      return method.apply(this, params);
773    };
774
775    this.option = function (optionName, param) {
776
777      /*
778       * Method to get/set Options
779       */
780
781      if (!isDefined(optionName)) {
782
783        return options;
784      }
785
786      var method;
787
788      switch (optionName) {
789
790        case "starWidth":
791
792          method = setStarWidth;
793          break;
794        case "numStars":
795
796          method = setNumStars;
797          break;
798        case "normalFill":
799
800          method = setNormalFill;
801          break;
802        case "ratedFill":
803
804          method = setRatedFill;
805          break;
806        case "multiColor":
807
808          method = setMultiColor;
809          break;
810        case "maxValue":
811
812          method = setMaxValue;
813          break;
814        case "precision":
815
816          method = setPrecision;
817          break;
818        case "rating":
819
820          method = setRating;
821          break;
822        case "halfStar":
823
824          method = setHalfStar;
825          break;
826        case "fullStar":
827
828          method = setFullStar;
829          break;
830        case "readOnly":
831
832          method = setReadOnly;
833          break;
834        case "spacing":
835
836          method = setSpacing;
837          break;
838        case "rtl":
839
840          method = setRtl;
841          break;
842        case "onInit":
843
844          method = setOnInit;
845          break;
846        case "onSet":
847
848          method = setOnSet;
849          break;
850        case "onChange":
851
852          method = setOnChange;
853          break;
854        default:
855
856          throw Error("No such option as " + optionName);
857      }
858
859      return isDefined(param) ? method(param) : options[optionName];
860    };
861
862    function onMouseEnter (e) {
863
864      /*
865       * If the Mouse Pointer is inside the container, calculate and show the rating
866       * in UI
867       */
868
869      var rating = calculateRating(e).toFixed(options.precision);
870
871      var maxValue = options.maxValue;
872
873      rating = checkPrecision(parseFloat(rating), minValue, maxValue);
874
875      showRating(rating);
876
877      $node.trigger("rateyo.change", {rating: rating});
878    }
879
880    function onMouseLeave () {
881      if (isMobileBrowser()) {
882        return;
883      }
884
885      /*
886       * If mouse leaves, revert the rating in UI to previously set rating,
887       * when empty value is passed to showRating, it will take the previously set
888       * rating
889       */
890
891      showRating();
892
893      $node.trigger("rateyo.change", {rating: options.rating});
894    }
895
896    function onMouseClick (e) {
897
898      /*
899       * On clicking the mouse inside the container, calculate and set the rating
900       */
901
902      var resultantRating = calculateRating(e).toFixed(options.precision);
903      resultantRating = parseFloat(resultantRating);
904
905      that.rating(resultantRating);
906    }
907
908    function onInit(e, data) {
909
910      if(options.onInit && typeof options.onInit === "function") {
911
912        /* jshint validthis:true */
913        options.onInit.apply(this, [data.rating, that]);
914      }
915    }
916
917    function onChange (e, data) {
918
919      if(options.onChange && typeof options.onChange === "function") {
920
921        /* jshint validthis:true */
922        options.onChange.apply(this, [data.rating, that]);
923      }
924    }
925
926    function onSet (e, data) {
927
928      if(options.onSet && typeof options.onSet === "function") {
929
930        /* jshint validthis:true */
931        options.onSet.apply(this, [data.rating, that]);
932      }
933    }
934
935    function bindEvents () {
936
937      $node.on("mousemove", onMouseEnter)
938           .on("mouseenter", onMouseEnter)
939           .on("mouseleave", onMouseLeave)
940           .on("click", onMouseClick)
941           .on("rateyo.init", onInit)
942           .on("rateyo.change", onChange)
943           .on("rateyo.set", onSet);
944    }
945
946    function unbindEvents () {
947
948      $node.off("mousemove", onMouseEnter)
949           .off("mouseenter", onMouseEnter)
950           .off("mouseleave", onMouseLeave)
951           .off("click", onMouseClick)
952           .off("rateyo.init", onInit)
953           .off("rateyo.change", onChange)
954           .off("rateyo.set", onSet);
955    }
956
957    setNumStars(options.numStars);
958    setReadOnly(options.readOnly);
959
960    if (options.rtl) {
961
962      setRtl(options.rtl);
963    }
964
965    this.collection.push(this);
966    this.rating(options.rating, true);
967
968    isInitialized = true;
969    $node.trigger("rateyo.init", {rating: options.rating});
970  }
971
972  RateYo.prototype.collection = [];
973
974  function getInstance (node, collection) {
975
976    /*
977     * Given a HTML element (node) and a collection of RateYo instances,
978     * this function will search through the collection and return the matched
979     * instance having the node
980     */
981
982    var instance;
983
984    $.each(collection, function () {
985
986      if(node === this.node){
987
988        instance = this;
989        return false;
990      }
991    });
992
993    return instance;
994  }
995
996  function deleteInstance (node, collection) {
997
998    /*
999     * Given a HTML element (node) and a collection of RateYo instances,
1000     * this function will search through the collection and delete the
1001     * instance having the node, and return the modified collection
1002     */
1003
1004    $.each(collection, function (index) {
1005
1006      if (node === this.node) {
1007
1008        var firstPart = collection.slice(0, index),
1009            secondPart = collection.slice(index+1, collection.length);
1010
1011        collection = firstPart.concat(secondPart);
1012
1013        return false;
1014      }
1015    });
1016
1017    return collection;
1018  }
1019
1020  function _rateYo (options) {
1021
1022    var rateYoInstances = RateYo.prototype.collection;
1023
1024    /* jshint validthis:true */
1025    var $nodes = $(this);
1026
1027    if($nodes.length === 0) {
1028
1029      return $nodes;
1030    }
1031
1032    var args = Array.prototype.slice.apply(arguments, []);
1033
1034    if (args.length === 0) {
1035
1036      //If args length is 0, Initialize the UI with default settings
1037      options = args[0] = {};
1038    }else if (args.length === 1 && typeof args[0] === "object") {
1039
1040      //If an Object is specified as first argument, it is considered as options
1041      options = args[0];
1042    }else if (args.length >= 1 && typeof args[0] === "string") {
1043
1044      /*
1045       * if there is only one argument, and if its a string, it is supposed to be a
1046       * method name, if more than one argument is specified, the remaining arguments
1047       * except the first argument, will be passed as a params to the specified method
1048       */
1049
1050      var methodName = args[0],
1051          params = args.slice(1);
1052
1053      var result = [];
1054
1055      $.each($nodes, function (i, node) {
1056
1057        var existingInstance = getInstance(node, rateYoInstances);
1058
1059        if(!existingInstance) {
1060
1061          throw Error("Trying to set options before even initialization");
1062        }
1063
1064        var method = existingInstance[methodName];
1065
1066        if (!method) {
1067
1068          throw Error("Method " + methodName + " does not exist!");
1069        }
1070
1071        var returnVal = method.apply(existingInstance, params);
1072
1073        result.push(returnVal);
1074      });
1075
1076      /*
1077       * If the plugin in being called on only one jQuery Element, return only the
1078       * first value, to support chaining.
1079       */
1080      result = result.length === 1? result[0]: result;
1081
1082      return result;
1083    }else {
1084
1085      throw Error("Invalid Arguments");
1086    }
1087
1088    /*
1089     * if only options are passed, extend default options, and if the plugin is not
1090     * initialized on a particular jQuery element, initalize RateYo on it
1091     */
1092    options = $.extend({}, DEFAULTS, options);
1093
1094    return $.each($nodes, function () {
1095
1096               var existingInstance = getInstance(this, rateYoInstances);
1097
1098               if (existingInstance) {
1099
1100                 return existingInstance;
1101               }
1102
1103               var $node = $(this),
1104                   dataAttrs = {},
1105                   optionsCopy = $.extend({}, options);
1106
1107               $.each($node.data(), function (key, value) {
1108
1109                 if (key.indexOf("rateyo") !== 0) {
1110
1111                   return;
1112                 }
1113
1114                 var optionName = key.replace(/^rateyo/, "");
1115
1116                 optionName = optionName[0].toLowerCase() + optionName.slice(1);
1117
1118                 dataAttrs[optionName] = value;
1119
1120                 delete optionsCopy[optionName];
1121               });
1122
1123               return new RateYo($(this), $.extend({}, dataAttrs, optionsCopy));
1124           });
1125  }
1126
1127  function rateYo () {
1128
1129    /* jshint validthis:true */
1130    return _rateYo.apply(this, Array.prototype.slice.apply(arguments, []));
1131  }
1132
1133  window.RateYo = RateYo;
1134  $.fn.rateYo = rateYo;
1135
1136}(window.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.