function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function (obj) { return typeof obj; }; } else { _typeof = function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } // The basic svg string required to generate stars var BASICSTAR = "" + "" + "" + ""; // The Default values of different options available in the Plugin var DEFAULTS = { starWidth: "32px", normalFill: "gray", ratedFill: "#f39c12", numStars: 5, maxValue: 5, precision: 1, rating: 0, fullStar: false, halfStar: false, hover: true, readOnly: false, spacing: "0px", rtl: false, multiColor: null, onInit: null, onChange: null, onSet: null, starSvg: null }; //Default colors for multi-color rating var MULTICOLOR_OPTIONS = { startColor: "#c0392b", //red endColor: "#f1c40f" //yellow }; // http://stackoverflow.com/questions/11381673/detecting-a-mobile-browser function isMobileBrowser() { var check = false; (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); return check; } function checkPrecision(value, minValue, maxValue) { /* * This function removes the unnecessary precision, at Min and Max Values */ // Its like comparing 0.0 with 0, which is true if (value === minValue) { value = minValue; } else if (value === maxValue) { value = maxValue; } return value; } function checkBounds(value, minValue, maxValue) { /* * Check if the value is between min and max values, if not, throw an error */ var isValid = value >= minValue && value <= maxValue; if (!isValid) { throw Error("Invalid Rating, expected value between " + minValue + " and " + maxValue); } return value; } function isType(value, type) { return _typeof(value) === type; } function isDefined(value) { // Better way to check if a variable is defined or not return typeof value !== "undefined"; } var isNumber = function isNumber(input) { return isType(input, "number"); }; var isString = function isString(input) { return isType(input, "string"); }; var isFunction = function isFunction(input) { return isType(input, "function"); }; var hexRegex = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i; function hexToRGB(hex) { /* * Extracts and returns the Red, Blue, Green Channel values, * in the form of decimals */ if (!hexRegex.test(hex)) { return null; } var hexValues = hexRegex.exec(hex), r = parseInt(hexValues[1], 16), g = parseInt(hexValues[2], 16), b = parseInt(hexValues[3], 16); return { r: r, g: g, b: b }; } function getChannelValue(startVal, endVal, percent) { /* * Returns a value between `startVal` and `endVal` based on the percent */ var newVal = (endVal - startVal) * (percent / 100); newVal = Math.round(startVal + newVal).toString(16); if (newVal.length === 1) { newVal = "0" + newVal; } return newVal; } function getColor(startColor, endColor, percent) { /* * Given the percentage( `percent` ) of `endColor` to be mixed * with the `startColor`, returns the mixed color. * Colors should be only in Hex Format */ if (!startColor || !endColor) { return null; } percent = isDefined(percent) ? percent : 0; startColor = hexToRGB(startColor); endColor = hexToRGB(endColor); var r = getChannelValue(startColor.r, endColor.r, percent), b = getChannelValue(startColor.b, endColor.b, percent), g = getChannelValue(startColor.g, endColor.g, percent); return "#" + r + g + b; } var eventObjectMap = {}; function getEventObject(event) { return eventObjectMap[event] || (eventObjectMap[event] = new String(event)); } var handlerProxyMap = new WeakMap(); function proxy(node, fn, event) { event = getEventObject(event); var eventHandlerMap = handlerProxyMap.get(node); if (!eventHandlerMap) { handlerProxyMap.set(node, eventHandlerMap = new WeakMap()); } var handlerMap = eventHandlerMap.get(event); if (!handlerMap) { eventHandlerMap.set(event, handlerMap = new Map()); } var handler = handlerMap.get(fn); if (handler) { return handler; } function proxy(e) { var data = e.detail; fn.call(node, e, data); } handlerMap.set(fn, proxy); return proxy; } proxy.get = function getOriginalFunction(node, fn, event) { event = getEventObject(event); var eventHandlerMap = handlerProxyMap.get(node); if (!eventHandlerMap) { return fn; } var handlerMap = eventHandlerMap.get(event); if (!handlerMap) { return fn; } return handlerMap.get(fn) || fn; }; var Event = isFunction(window.Event) ? window.Event : function Event(event) { var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var _params$bubbles = params.bubbles, bubbles = _params$bubbles === void 0 ? false : _params$bubbles, _params$cancelable = params.cancelable, cancelable = _params$cancelable === void 0 ? false : _params$cancelable; var evt = document.createEvent("Event"); evt.initEvent(event, bubbles, cancelable); return evt; }; var CustomEvent = isFunction(window.CustomEvent) ? window.CustomEvent : (CustomEvent.prototype = Object.create(Event.prototype), CustomEvent); var events = { trigger: function trigger(event, detail) { var eventProps = { bubbles: true }; if (!isDefined(detail)) { this.node.dispatchEvent(new Event(event, eventProps)); } else { this.node.dispatchEvent(new CustomEvent(event, _objectSpread2({ detail: detail }, eventProps))); } return this; }, on: function on(event, handler) { this.node.addEventListener(event, proxy(this.node, handler, event)); return this; }, off: function off(event, handler) { this.node.removeEventListener(event, proxy.get(this.node, handler, event)); return this; } }; var rateyoAttrRegex = /^rateyo(.+)$/; function classList(node, operation, input) { var className = node.className.trim(); var classes = className && className.split(/\s/) || [], classMap = {}; classes = classes.reduce(function (result, item, index) { if (!classMap.hasOwnProperty(item)) { result.push(item); classMap[item] = index; } return result; }, []); if (operation === classList.add) { if (classMap.hasOwnProperty(input)) { return; } classes.push(input); } else if (operation === classList.remove) { if (!classMap.hasOwnProperty(input)) { return; } classes.splice(classMap[input], 1); } node.className = classes.join(" "); } classList.add = "add"; classList.remove = "remove"; function El(node) { this.node = node; } El.prototype = { empty: function empty() { this.node.innerHTML = ""; return this; }, addClass: function addClass(className) { classList(this.node, classList.add, className); return this; }, removeClass: function removeClass(className) { classList(this.node, classList.remove, className); return this; }, appendTo: function appendTo(parent) { (El.isEl(parent) ? parent.node : parent).appendChild(this.node); return this; }, css: function css(styleAttribute, value) { this.node.style[styleAttribute] = value; return this; }, width: function width(_width) { if (!isDefined(_width)) { return this.node.getBoundingClientRect().width; } this.css("width", _width + (isNumber(_width) ? "px" : "")); }, find: function find(selector) { return $(this.node.querySelectorAll(selector)); }, attr: function attr(attrObj) { for (var attrName in attrObj) { if (attrObj.hasOwnProperty(attrName)) { this.node.setAttribute(attrName, attrObj[attrName]); } } return this; }, removeAttr: function removeAttr(attributeName) { this.node.removeAttribute(attributeName); return this; }, children: function children() { return $(this.node.childNodes); }, remove: function remove() { return this.node.remove(); }, offset: function offset() { var _this$node$getBoundin = this.node.getBoundingClientRect(), top = _this$node$getBoundin.top, left = _this$node$getBoundin.left, bottom = _this$node$getBoundin.bottom, right = _this$node$getBoundin.right; return { top: top, left: left, bottom: bottom, right: right }; }, dataAttrOptions: function dataAttrOptions() { var dataset = this.node.dataset; return Object.keys(dataset).reduce(function (options, attr) { var match = attr.match(rateyoAttrRegex); if (!match) { return options; } var rateyoAttr = match[1], option = rateyoAttr[0].toLowerCase() + rateyoAttr.slice(1); options[option] = dataset[attr]; return options; }, {}); } }; El.prototype = _objectSpread2(_objectSpread2({}, El.prototype), events); El.isEl = function (node) { return node instanceof El; }; function Collection(nodeList) { var _this = this; this.collection = []; Array.prototype.forEach.call(nodeList, function (node) { _this.collection.push(new El(node)); }); } Collection.isCollection = function (input) { return input instanceof Collection; }; Collection.prototype = {}; var _loop = function _loop(method) { if (!El.prototype.hasOwnProperty(method)) { return "continue"; } function proxy() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } this.collection.forEach(function (el) { return El.isEl(el) && el[method].apply(el, args); }); return this; } Collection.prototype[method] = proxy; }; for (var method in El.prototype) { var _ret = _loop(method); if (_ret === "continue") continue; } var parser = new DOMParser(); function parseHTML(html) { return parser.parseFromString(html.trim(), "text/html").body.childNodes; } function $(node) { node = isString(node) && parseHTML(node) || node; if (El.isEl(node) || Collection.isCollection(node)) { return node; } if (node instanceof NodeList) { return new Collection(node); } return new El(node); } $.El = El; var instanceMap = new WeakMap(); function RateYo(node) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (!(this instanceof RateYo)) { return new RateYo(node, options); } if (instanceMap.has(node)) { return instanceMap.get(node); } var that = this; this.node = node; var $node = $(node); options = _objectSpread2(_objectSpread2(_objectSpread2({}, DEFAULTS), options), $node.dataAttrOptions()); // Remove any stuff that is present inside the container, and add the plugin class $node.empty().addClass("jq-ry-container"); /* * Basically the plugin displays the rating using two rows of stars lying one above * the other, the row that is on the top represents the actual rating, and the one * behind acts just like a background. * * `$groupWrapper`: is an element that wraps both the rows * `$normalGroup`: is the container for row of stars thats behind and * acts as background * `$ratedGroup`: is the container for row of stars that display the actual rating. * * The rating is displayed by adjusting the width of `$ratedGroup` */ var $groupWrapper = $(document.createElement("div")).addClass("jq-ry-group-wrapper").appendTo($node); var $normalGroup = $(document.createElement("div")).addClass("jq-ry-normal-group").addClass("jq-ry-group").appendTo($groupWrapper); var $ratedGroup = $(document.createElement("div")).addClass("jq-ry-rated-group").addClass("jq-ry-group").appendTo($groupWrapper); /* * Variable `step`: store the value of the rating for each star * eg: if `maxValue` is 5 and `numStars` is 5, value of each star * is 1. * Variable `starWidth`: stores the decimal value of width of star in units of px * Variable `percentOfStar`: stores the percentage of width each star takes w.r.t * the container * Variable `spacing`: stores the decimal value of the spacing between stars * in the units of px * Variable `percentOfSpacing`: stores the percentage of width of the spacing * between stars w.r.t the container */ var step, starWidth, percentOfStar, spacing, percentOfSpacing, containerWidth, minValue = 0; /* * `currentRating` contains rating that is being displayed at the latest point of * time. * * When ever you hover over the plugin UI, the rating value changes * according to the place where you point the cursor, currentRating contains * the current value of rating that is being shown in the UI */ var currentRating = options.rating; // A flag to store if the plugin is already being displayed in the UI var isInitialized = false; function showRating(ratingVal) { /* * The function is responsible for displaying the rating by changing * the width of `$ratedGroup` */ if (!isDefined(ratingVal)) { ratingVal = options.rating; } // Storing the value that is being shown in `currentRating`. currentRating = ratingVal; var numStarsToShow = ratingVal / step; // calculating the percentage of width of $ratedGroup with respect to its parent var percent = numStarsToShow * percentOfStar; if (numStarsToShow > 1) { // adding the percentage of space that is taken by the gap the stars percent += (Math.ceil(numStarsToShow) - 1) * percentOfSpacing; } setRatedFill(options.ratedFill); percent = options.rtl ? 100 - percent : percent; if (percent < 0) { percent = 0; } else if (percent > 100) { percent = 100; } $ratedGroup.css("width", percent + "%"); } function setContainerWidth() { /* * Set the width of the `this.node` based on the width of each star and * the space between them */ containerWidth = starWidth * options.numStars + spacing * (options.numStars - 1); percentOfStar = starWidth / containerWidth * 100; percentOfSpacing = spacing / containerWidth * 100; $node.width(containerWidth); showRating(); } function setStarWidth(newWidth) { /* * Set the width and height of each SVG star, called whenever one changes the * `starWidth` option */ // The width and height of the star should be the same var starHeight = options.starWidth = newWidth; starWidth = window.parseFloat(options.starWidth.replace("px", "")); $normalGroup.find("svg").attr({ width: options.starWidth, height: starHeight }); $ratedGroup.find("svg").attr({ width: options.starWidth, height: starHeight }); setContainerWidth(); return $node; } function setSpacing(newSpacing) { /* * Set spacing between the SVG stars, called whenever one changes * the `spacing` option */ options.spacing = newSpacing; spacing = parseFloat(options.spacing.replace("px", "")); $normalGroup.find("svg:not(:first-child)").css("margin-left", newSpacing); $ratedGroup.find("svg:not(:first-child)").css("margin-left", newSpacing); setContainerWidth(); return $node; } function setNormalFill(newFill) { /* * Set the background fill of the Stars, called whenever one changes the * `normalFill` option */ options.normalFill = newFill; var $svgs = (options.rtl ? $ratedGroup : $normalGroup).find("svg"); $svgs.attr({ fill: options.normalFill }); return $node; } /* * Store the recent `ratedFill` option in a variable * so that if multiColor is unset, we can use the perviously set `ratedFill` * from this variable */ var ratedFill = options.ratedFill; function setRatedFill(newFill) { /* * Set ratedFill of the stars, called when one changes the `ratedFill` option */ /* * If `multiColor` option is set, `newFill` variable is dynamically set * based on the rating, what ever set as parameter will be discarded */ if (options.multiColor) { var ratingDiff = currentRating - minValue, percentCovered = ratingDiff / options.maxValue * 100; var colorOpts = options.multiColor || {}, startColor = colorOpts.startColor || MULTICOLOR_OPTIONS.startColor, endColor = colorOpts.endColor || MULTICOLOR_OPTIONS.endColor; newFill = getColor(startColor, endColor, percentCovered); } else { ratedFill = newFill; } options.ratedFill = newFill; var $svgs = (options.rtl ? $normalGroup : $ratedGroup).find("svg"); $svgs.attr({ fill: options.ratedFill }); return $node; } function setRtl(newValue) { newValue = !!newValue; options.rtl = newValue; setNormalFill(options.normalFill); showRating(); } function setMultiColor(colorOptions) { /* * called whenever one changes the `multiColor` option */ options.multiColor = colorOptions; // set the recently set `ratedFill` option, if multiColor Options are unset setRatedFill(colorOptions ? colorOptions : ratedFill); } function setNumStars(newValue) { /* * Set the number of stars to use to display the rating, called whenever one * changes the `numStars` option */ options.numStars = newValue; step = options.maxValue / options.numStars; $normalGroup.empty(); $ratedGroup.empty(); for (var i = 0; i < options.numStars; i++) { $(options.starSvg || BASICSTAR).appendTo($normalGroup); $(options.starSvg || BASICSTAR).appendTo($ratedGroup); } setStarWidth(options.starWidth); setNormalFill(options.normalFill); setSpacing(options.spacing); showRating(); return $node; } function setMaxValue(newValue) { /* * set the Maximum Value of rating to be allowed, called whenever * one changes the `maxValue` option */ options.maxValue = newValue; step = options.maxValue / options.numStars; if (options.rating > newValue) { setRating(newValue); } showRating(); return $node; } function setPrecision(newValue) { /* * Set the precision of the rating value, called if one changes the * `precision` option */ options.precision = newValue; setRating(options.rating); return $node; } function setHalfStar(newValue) { /* * This function will be called if one changes the `halfStar` option */ options.halfStar = newValue; return $node; } function setFullStar(newValue) { /* * This function will be called if one changes the `fullStar` option */ options.fullStar = newValue; return $node; } function round(value) { /* * Rounds the value of rating if `halfStar` or `fullStar` options are chosen */ var remainder = value % step, halfStep = step / 2, isHalfStar = options.halfStar, isFullStar = options.fullStar; if (!isFullStar && !isHalfStar) { return value; } if (isFullStar || isHalfStar && remainder > halfStep) { value += step - remainder; } else { value = value - remainder; if (remainder > 0) { value += halfStep; } } return value; } function calculateRating(e) { /* * Calculates and returns the rating based on the position of cursor w.r.t the * plugin container */ var position = $normalGroup.offset(), nodeStartX = position.left, nodeEndX = nodeStartX + $normalGroup.width(); var maxValue = options.maxValue; // The x-coordinate(position) of the mouse pointer w.r.t page var pageX = e.pageX; var calculatedRating = 0; // If the mouse pointer is to the left of the container if (pageX < nodeStartX) { calculatedRating = minValue; } else if (pageX > nodeEndX) { // If the mouse pointer is right of the container calculatedRating = maxValue; } else { // If the mouse pointer is inside the continer /* * The fraction of width covered by the pointer w.r.t to the total width * of the container. */ var calcPrcnt = (pageX - nodeStartX) / (nodeEndX - nodeStartX); if (spacing > 0) { /* * If there is spacing between stars, take the percentage of width covered * and subtract the percentage of width covered by stars and spacing, to find * how many stars are covered, the number of stars covered is the rating * * TODO: I strongly feel that this logic can be improved!, Please help! */ calcPrcnt *= 100; var remPrcnt = calcPrcnt; while (remPrcnt > 0) { if (remPrcnt > percentOfStar) { calculatedRating += step; remPrcnt -= percentOfStar + percentOfSpacing; } else { calculatedRating += remPrcnt / percentOfStar * step; remPrcnt = 0; } } } else { /* * If there is not spacing between stars, the fraction of width covered per * `maxValue` is the rating */ calculatedRating = calcPrcnt * options.maxValue; } // Round the rating if `halfStar` or `fullStar` options are chosen calculatedRating = round(calculatedRating); } if (options.rtl) { calculatedRating = maxValue - calculatedRating; } return parseFloat(calculatedRating); } function setReadOnly(newValue) { /* * UnBinds mouse event handlers, called when whenever one changes the * `readOnly` option */ options.readOnly = newValue; $node.attr({ "readonly": true }); unbindEvents(); if (!newValue) { $node.removeAttr("readonly"); bindEvents(); } return $node; } function setRating(newValue) { /* * Sets the rating of the Plugin, Called when option `rating` is changed * or, when `rating` method is called */ var rating = newValue; var maxValue = options.maxValue; if (typeof rating === "string") { // If rating is given in percentage, maxValue should be 100 if (rating[rating.length - 1] === "%") { rating = rating.substr(0, rating.length - 1); maxValue = 100; setMaxValue(maxValue); } rating = parseFloat(rating); } checkBounds(rating, minValue, maxValue); rating = parseFloat(rating.toFixed(options.precision)); checkPrecision(parseFloat(rating), minValue, maxValue); options.rating = rating; showRating(); if (isInitialized) { $node.trigger("rateyo.set", { rating: rating }); } return $node; } function setOnInit(method) { /* * set what method to be called on Initialization */ options.onInit = method; return $node; } function setOnSet(method) { /* * set what method to be called when rating is set */ options.onSet = method; return $node; } function setOnChange(method) { /* * set what method to be called rating in the UI is changed */ options.onChange = method; return $node; } this.rating = function (newValue) { /* * rating getter/setter */ if (!isDefined(newValue)) { return options.rating; } setRating(newValue); return $node; }; this.destroy = function () { /* * Removes the Rating UI by clearing the content, and removing the custom classes */ if (!options.readOnly) { unbindEvents(); } instanceMap["delete"](node); $node.removeClass("jq-ry-container").children().remove(); return $node; }; this.method = function (methodName) { /* * Method to call the methods of RateYo Instance */ if (!methodName) { throw Error("Method name not specified!"); } if (!isDefined(this[methodName])) { throw Error("Method " + methodName + " doesn't exist!"); } var args = Array.prototype.slice.apply(arguments, []), params = args.slice(1), method = this[methodName]; return method.apply(this, params); }; this.option = function (optionName, param) { /* * Method to get/set Options */ if (!isDefined(optionName)) { return options; } var method; switch (optionName) { case "starWidth": method = setStarWidth; break; case "numStars": method = setNumStars; break; case "normalFill": method = setNormalFill; break; case "ratedFill": method = setRatedFill; break; case "multiColor": method = setMultiColor; break; case "maxValue": method = setMaxValue; break; case "precision": method = setPrecision; break; case "rating": method = setRating; break; case "halfStar": method = setHalfStar; break; case "fullStar": method = setFullStar; break; case "readOnly": method = setReadOnly; break; case "spacing": method = setSpacing; break; case "rtl": method = setRtl; break; case "onInit": method = setOnInit; break; case "onSet": method = setOnSet; break; case "onChange": method = setOnChange; break; default: throw Error("No such option as " + optionName); } return isDefined(param) ? method(param) : options[optionName]; }; function onMouseEnter(e) { if (!options.hover) { return; } /* * If the Mouse Pointer is inside the container, calculate and show the rating * in UI */ var rating = calculateRating(e).toFixed(options.precision); var maxValue = options.maxValue; rating = checkPrecision(parseFloat(rating), minValue, maxValue); showRating(rating); $node.trigger("rateyo.change", { rating: rating }); } function onMouseLeave() { if (isMobileBrowser() || !options.hover) { return; } /* * If mouse leaves, revert the rating in UI to previously set rating, * when empty value is passed to showRating, it will take the previously set * rating */ showRating(); $node.trigger("rateyo.change", { rating: options.rating }); } function onMouseClick(e) { /* * On clicking the mouse inside the container, calculate and set the rating */ var resultantRating = calculateRating(e).toFixed(options.precision); resultantRating = parseFloat(resultantRating); that.rating(resultantRating); } function onInit(e, data) { if (options.onInit && typeof options.onInit === "function") { options.onInit.apply(this, [data.rating, that]); } } function onChange(e, data) { if (options.onChange && typeof options.onChange === "function") { options.onChange.apply(this, [data.rating, that]); } } function onSet(e, data) { if (options.onSet && typeof options.onSet === "function") { options.onSet.apply(this, [data.rating, that]); } } function bindEvents() { $node.on("mousemove", onMouseEnter).on("mouseenter", onMouseEnter).on("mouseleave", onMouseLeave).on("click", onMouseClick).on("rateyo.init", onInit).on("rateyo.change", onChange).on("rateyo.set", onSet); } function unbindEvents() { $node.off("mousemove", onMouseEnter).off("mouseenter", onMouseEnter).off("mouseleave", onMouseLeave).off("click", onMouseClick).off("rateyo.init", onInit).off("rateyo.change", onChange).off("rateyo.set", onSet); } setNumStars(options.numStars); setReadOnly(options.readOnly); if (options.rtl) { setRtl(options.rtl); } instanceMap.set(node, this); this.rating(options.rating, true); isInitialized = true; $node.trigger("rateyo.init", { rating: options.rating }); } Object.defineProperty(RateYo.prototype, "on", { value: function on(eventName, handler) { $(this.node).on(eventName, handler); return this; } }); Object.defineProperty(RateYo.prototype, "off", { value: function off(eventName, handler) { $(this.node).off(eventName, handler); return this; } }); Object.defineProperty(RateYo, "has", { value: function has(node) { return instanceMap.has(node); } }); Object.defineProperty(RateYo, "get", { value: function get(node) { return instanceMap.get(node); } }); Object.defineProperty(RateYo, "_$", { get: function get() { return $; } }); export default RateYo;