inital commit
This commit is contained in:
362
public/plugins/simpleStar/src/star-rating.js
Normal file
362
public/plugins/simpleStar/src/star-rating.js
Normal file
@@ -0,0 +1,362 @@
|
||||
/*!
|
||||
* Star Rating
|
||||
* @version: 3.4.0
|
||||
* @author: Paul Ryley (http://geminilabs.io)
|
||||
* @url: https://github.com/pryley/star-rating.js
|
||||
* @license: MIT
|
||||
*/
|
||||
/** global: define, Event */
|
||||
;(function (window, document, undefined) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var handle = 'star-rating';
|
||||
|
||||
/** @return object */
|
||||
var Plugin = function (selector, options) { // string|object|NodeList, object
|
||||
var selectorType = {}.toString.call(selector);
|
||||
if ('[object String]' === selectorType) {
|
||||
this.selects = document.querySelectorAll(selector);
|
||||
} else if ('[object NodeList]' === selectorType) {
|
||||
this.selects = selector;
|
||||
} else {
|
||||
this.selects = [selector];
|
||||
}
|
||||
this.destroy = function () {
|
||||
this.widgets.forEach(function (widget) {
|
||||
widget.destroy_();
|
||||
});
|
||||
};
|
||||
this.rebuild = function () {
|
||||
this.widgets.forEach(function (widget) {
|
||||
widget.rebuild_();
|
||||
});
|
||||
};
|
||||
this.widgets = [];
|
||||
for (var i = 0; i < this.selects.length; i++) {
|
||||
if (this.selects[i].tagName !== 'SELECT' || this.selects[i][handle]) continue;
|
||||
var widget = new Widget(this.selects[i], options);
|
||||
if (widget.direction === undefined) continue;
|
||||
this.widgets.push(widget);
|
||||
}
|
||||
};
|
||||
|
||||
/** @return void */
|
||||
var Widget = function (el, options) { // HTMLElement, object|null
|
||||
this.el = el;
|
||||
this.options_ = this.extend_({}, this.defaults_, options || {}, JSON.parse(el.getAttribute('data-options')));
|
||||
this.setStarCount_();
|
||||
if (this.stars < 1 || this.stars > this.options_.maxStars) return;
|
||||
this.rebuild_();
|
||||
};
|
||||
|
||||
Widget.prototype = {
|
||||
|
||||
defaults_: {
|
||||
classname: 'gl-star-rating',
|
||||
clearable: true,
|
||||
initialText: 'Select a Rating',
|
||||
maxStars: 10,
|
||||
showText: true,
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
init_: function () {
|
||||
this.initEvents_();
|
||||
this.current = this.selected = this.getSelectedValue_();
|
||||
this.wrapEl_();
|
||||
this.buildWidgetEl_();
|
||||
this.setDirection_();
|
||||
this.setValue_(this.current);
|
||||
this.handleEvents_('add');
|
||||
this.el[handle] = true;
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
buildLabelEl_: function () {
|
||||
if (!this.options_.showText) return;
|
||||
this.textEl = this.insertSpanEl_(this.widgetEl, {
|
||||
class: this.options_.classname + '-text',
|
||||
}, true);
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
buildWidgetEl_: function () {
|
||||
var values = this.getOptionValues_();
|
||||
var widgetEl = this.insertSpanEl_(this.el, {
|
||||
class: this.options_.classname + '-stars',
|
||||
}, true);
|
||||
for (var key in values) {
|
||||
var newEl = this.createSpanEl_({
|
||||
'data-value': key,
|
||||
'data-text': values[key],
|
||||
});
|
||||
widgetEl.innerHTML += newEl.outerHTML;
|
||||
}
|
||||
this.widgetEl = widgetEl;
|
||||
this.buildLabelEl_();
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
changeTo_: function (index) { // int
|
||||
if (index < 0 || isNaN(index)) {
|
||||
index = 0;
|
||||
}
|
||||
if (index > this.stars) {
|
||||
index = this.stars;
|
||||
}
|
||||
this.widgetEl.classList.remove('s' + (10 * this.current));
|
||||
this.widgetEl.classList.add('s' + (10 * index));
|
||||
if (this.options_.showText) {
|
||||
this.textEl.textContent = index < 1 ? this.options_.initialText : this.widgetEl.childNodes[index - 1].dataset.text;
|
||||
}
|
||||
this.current = index;
|
||||
},
|
||||
|
||||
/** @return HTMLElement */
|
||||
createSpanEl_: function (attributes) { // object
|
||||
var el = document.createElement('span');
|
||||
attributes = attributes || {};
|
||||
for (var key in attributes) {
|
||||
el.setAttribute(key, attributes[key]);
|
||||
}
|
||||
return el;
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
destroy_: function () {
|
||||
this.handleEvents_('remove');
|
||||
var wrapEl = this.el.parentNode;
|
||||
wrapEl.parentNode.replaceChild(this.el, wrapEl);
|
||||
delete this.el[handle];
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
eventListener_: function (el, action, events, options) { // HTMLElement, string, array
|
||||
options = options || false;
|
||||
events.forEach(function (event) {
|
||||
if (this.events) {
|
||||
el[action + 'EventListener'](event, this.events[event], options);
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/** @return object */
|
||||
extend_: function () { // ...object
|
||||
var args = [].slice.call(arguments);
|
||||
var result = args[0];
|
||||
var extenders = args.slice(1);
|
||||
Object.keys(extenders).forEach(function (i) {
|
||||
for (var key in extenders[i]) {
|
||||
if (!extenders[i].hasOwnProperty(key)) continue;
|
||||
result[key] = extenders[i][key];
|
||||
}
|
||||
});
|
||||
return result;
|
||||
},
|
||||
|
||||
/** @return false|object */
|
||||
getEventOptions_: function () { // string
|
||||
var eventOptions = false;
|
||||
try {
|
||||
var opts = Object.defineProperty({}, 'passive', {
|
||||
get: function () {
|
||||
eventOptions = { passive: false };
|
||||
}
|
||||
});
|
||||
window.addEventListener('test', null, opts);
|
||||
} catch (e) {}
|
||||
return eventOptions;
|
||||
},
|
||||
|
||||
/** @return int */
|
||||
getIndexFromEvent_: function (ev) { // MouseEvent|TouchEvent
|
||||
var direction = {};
|
||||
var pageX = ev.pageX || ev.changedTouches[0].pageX;
|
||||
var widgetWidth = this.widgetEl.offsetWidth;
|
||||
direction.ltr = Math.max(pageX - this.offsetLeft, 1);
|
||||
direction.rtl = widgetWidth - direction.ltr;
|
||||
return Math.min(
|
||||
Math.ceil(direction[this.direction] / Math.round(widgetWidth / this.stars)),
|
||||
this.stars
|
||||
);
|
||||
},
|
||||
|
||||
/** @return object */
|
||||
getOptionValues_: function () {
|
||||
var el = this.el;
|
||||
var unorderedValues = {};
|
||||
var orderedValues = {};
|
||||
for (var i = 0; i < el.length; i++) {
|
||||
if (this.isValueEmpty_(el[i])) continue;
|
||||
unorderedValues[el[i].value] = el[i].text;
|
||||
}
|
||||
Object.keys(unorderedValues).sort().forEach(function (key) {
|
||||
orderedValues[key] = unorderedValues[key];
|
||||
});
|
||||
return orderedValues;
|
||||
},
|
||||
|
||||
/** @return int */
|
||||
getSelectedValue_: function () {
|
||||
return parseInt(this.el.options[Math.max(this.el.selectedIndex, 0)].value) || 0;
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
handleEvents_: function (action) { // string
|
||||
var formEl = this.el.closest('form');
|
||||
if (formEl && formEl.tagName === 'FORM') {
|
||||
this.eventListener_(formEl, action, ['reset']);
|
||||
}
|
||||
if ('add' === action && this.el.disabled) return;
|
||||
this.eventListener_(this.el, action, ['change', 'keydown']);
|
||||
this.eventListener_(this.widgetEl, action, [
|
||||
'mousedown', 'mouseleave', 'mousemove', 'mouseover',
|
||||
'touchend', 'touchmove', 'touchstart',
|
||||
], this.getEventOptions_());
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
initEvents_: function () {
|
||||
this.events = {
|
||||
change: this.onChange_.bind(this),
|
||||
keydown: this.onKeydown_.bind(this),
|
||||
mousedown: this.onPointerdown_.bind(this),
|
||||
mouseleave: this.onPointerleave_.bind(this),
|
||||
mousemove: this.onPointermove_.bind(this),
|
||||
mouseover: this.onPointerover_.bind(this),
|
||||
reset: this.onReset_.bind(this),
|
||||
touchend: this.onPointerdown_.bind(this),
|
||||
touchmove: this.onPointermove_.bind(this),
|
||||
touchstart: this.onPointerover_.bind(this),
|
||||
};
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
insertSpanEl_: function (el, attributes, after) { // HTMLElement, object, bool
|
||||
var newEl = this.createSpanEl_(attributes);
|
||||
el.parentNode.insertBefore(newEl, after === true ? el.nextSibling : el);
|
||||
return newEl;
|
||||
},
|
||||
|
||||
/** @return bool */
|
||||
isValueEmpty_: function (el) { // HTMLElement
|
||||
return el.getAttribute('value') === null || el.value === '';
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
onChange_: function () {
|
||||
this.changeTo_(this.getSelectedValue_());
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
onKeydown_: function (ev) { // KeyboardEvent
|
||||
if (!~['ArrowLeft', 'ArrowRight'].indexOf(ev.key)) return;
|
||||
var increment = ev.key === 'ArrowLeft' ? -1 : 1;
|
||||
if (this.direction === 'rtl') {
|
||||
increment *= -1;
|
||||
}
|
||||
this.setValue_(Math.min(Math.max(this.getSelectedValue_() + increment, 0), this.stars));
|
||||
this.triggerChangeEvent_();
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
onPointerdown_: function (ev) { // MouseEvent|TouchEvent
|
||||
ev.preventDefault();
|
||||
var index = this.getIndexFromEvent_(ev);
|
||||
if (this.current !== 0 && parseFloat(this.selected) === index && this.options_.clearable) {
|
||||
index = 0;
|
||||
}
|
||||
this.setValue_(index);
|
||||
this.triggerChangeEvent_();
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
onPointerleave_: function (ev) { // MouseEvent
|
||||
ev.preventDefault();
|
||||
this.changeTo_(this.selected);
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
onPointermove_: function (ev) { // MouseEvent|TouchEvent
|
||||
ev.preventDefault();
|
||||
this.changeTo_(this.getIndexFromEvent_(ev));
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
onPointerover_: function (ev) { // MouseEvent|TouchEvent
|
||||
ev.preventDefault();
|
||||
var rect = this.widgetEl.getBoundingClientRect();
|
||||
this.offsetLeft = rect.left + document.body.scrollLeft;
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
onReset_: function () {
|
||||
var originallySelected = this.el.querySelector('[selected]');
|
||||
var value = originallySelected ? originallySelected.value : '';
|
||||
this.el.value = value;
|
||||
this.selected = parseInt(value) || 0;
|
||||
this.changeTo_(value);
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
rebuild_: function () {
|
||||
if (this.el.parentNode.classList.contains(this.options_.classname)) {
|
||||
this.destroy_();
|
||||
}
|
||||
this.init_();
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
setDirection_: function () {
|
||||
var wrapEl = this.el.parentNode;
|
||||
this.direction = window.getComputedStyle(wrapEl, null).getPropertyValue('direction');
|
||||
wrapEl.classList.add(this.options_.classname + '-' + this.direction);
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
setValue_: function (index) {
|
||||
this.el.value = this.selected = index;
|
||||
this.changeTo_(index);
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
setStarCount_: function () {
|
||||
var el = this.el;
|
||||
this.stars = 0;
|
||||
for (var i = 0; i < el.length; i++) {
|
||||
if (this.isValueEmpty_(el[i])) continue;
|
||||
if (isNaN(parseFloat(el[i].value)) || !isFinite(el[i].value)) {
|
||||
this.stars = 0;
|
||||
return;
|
||||
}
|
||||
this.stars++;
|
||||
}
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
triggerChangeEvent_: function () {
|
||||
this.el.dispatchEvent(new Event('change'));
|
||||
},
|
||||
|
||||
/** @return void */
|
||||
wrapEl_: function () {
|
||||
var wrapEl = this.insertSpanEl_(this.el, {
|
||||
class: this.options_.classname,
|
||||
'data-star-rating': '',
|
||||
});
|
||||
wrapEl.appendChild(this.el);
|
||||
},
|
||||
};
|
||||
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define([], function () { return Plugin; });
|
||||
}
|
||||
else if (typeof module === 'object' && module.exports) {
|
||||
module.exports = Plugin;
|
||||
}
|
||||
else {
|
||||
window.StarRating = Plugin;
|
||||
}
|
||||
|
||||
})(window, document);
|
||||
153
public/plugins/simpleStar/src/star-rating.scss
Normal file
153
public/plugins/simpleStar/src/star-rating.scss
Normal file
@@ -0,0 +1,153 @@
|
||||
/*!
|
||||
* Star Rating
|
||||
* @version: 3.4.0
|
||||
* @author: Paul Ryley (http://geminilabs.io)
|
||||
* @url: https://github.com/pryley/star-rating.js
|
||||
* @license: MIT
|
||||
*/
|
||||
|
||||
$star-rating: () !default;
|
||||
|
||||
$star-rating-defaults: (
|
||||
base-classname : 'gl-star-rating',
|
||||
base-display : block,
|
||||
base-height : 26px,
|
||||
font-size : 0.8em,
|
||||
font-weight : 600,
|
||||
parent : '',
|
||||
star-empty : url(../img/star-empty.svg),
|
||||
star-full : url(../img/star-full.svg),
|
||||
star-half : url(../img/star-half.svg),
|
||||
star-size : 24px,
|
||||
text-background: #1a1a1a,
|
||||
text-color : #fff,
|
||||
);
|
||||
|
||||
@function sr($value) {
|
||||
@return map-get(map-merge($star-rating-defaults, $star-rating), $value);
|
||||
}
|
||||
|
||||
#{sr(parent)} .#{sr(base-classname)}[data-star-rating] {
|
||||
position: relative;
|
||||
display: sr(base-display);
|
||||
}
|
||||
|
||||
#{sr(parent)} .#{sr(base-classname)}[data-star-rating] > select {
|
||||
overflow: hidden;
|
||||
visibility: visible !important;
|
||||
position: absolute !important;
|
||||
top: 0;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
clip: rect(1px, 1px, 1px, 1px); // IE/Edge
|
||||
clip-path: circle(1px at 0 0); // Modern
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#{sr(parent)} .#{sr(base-classname)}[data-star-rating] > select::before,
|
||||
#{sr(parent)} .#{sr(base-classname)}[data-star-rating] > select::after {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#{sr(parent)} .#{sr(base-classname)}-ltr[data-star-rating] > select {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#{sr(parent)} .#{sr(base-classname)}-rtl[data-star-rating] > select {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
#{sr(parent)} .#{sr(base-classname)}[data-star-rating] > select:focus + .#{sr(base-classname)}-stars::before {
|
||||
opacity: 0.5;
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
content: '';
|
||||
outline: dotted 1px currentColor;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#{sr(parent)} .#{sr(base-classname)}-stars {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
height: sr(base-height);
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#{sr(parent)} select[disabled] + .#{sr(base-classname)}-stars {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
#{sr(parent)} .#{sr(base-classname)}-stars > span {
|
||||
display: inline-block;
|
||||
width: sr(star-size);
|
||||
height: sr(star-size);
|
||||
background-size: sr(star-size);
|
||||
background-repeat: no-repeat;
|
||||
background-image: sr(star-empty);
|
||||
margin: 0 sr(star-size)/6 0 0;
|
||||
&:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
#{sr(parent)} .#{sr(base-classname)}-rtl[data-star-rating] .#{sr(base-classname)}-stars > span {
|
||||
margin: 0 0 0 sr(star-size)/6;
|
||||
&:last-of-type {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
#{sr(parent)} .#{sr(base-classname)}-stars.s10 > span:nth-child(1),
|
||||
#{sr(parent)} .#{sr(base-classname)}-stars.s20 > span:nth-child(-1n+2),
|
||||
#{sr(parent)} .#{sr(base-classname)}-stars.s30 > span:nth-child(-1n+3),
|
||||
#{sr(parent)} .#{sr(base-classname)}-stars.s40 > span:nth-child(-1n+4),
|
||||
#{sr(parent)} .#{sr(base-classname)}-stars.s50 > span:nth-child(-1n+5),
|
||||
#{sr(parent)} .#{sr(base-classname)}-stars.s60 > span:nth-child(-1n+6),
|
||||
#{sr(parent)} .#{sr(base-classname)}-stars.s70 > span:nth-child(-1n+7),
|
||||
#{sr(parent)} .#{sr(base-classname)}-stars.s80 > span:nth-child(-1n+8),
|
||||
#{sr(parent)} .#{sr(base-classname)}-stars.s90 > span:nth-child(-1n+9),
|
||||
#{sr(parent)} .#{sr(base-classname)}-stars.s100 > span {
|
||||
background-image: sr(star-full);
|
||||
}
|
||||
|
||||
#{sr(parent)} .#{sr(base-classname)}-text {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
height: sr(base-height);
|
||||
line-height: sr(base-height);
|
||||
font-size: sr(font-size);
|
||||
font-weight: sr(font-weight);
|
||||
color: sr(text-color);
|
||||
background-color: sr(text-background);
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
padding: 0 sr(star-size)/2 0 sr(star-size)/4;
|
||||
margin: 0 0 0 sr(star-size)/2;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -(sr(star-size)/2);
|
||||
width: 0;
|
||||
height: 0;
|
||||
content: "";
|
||||
border-style: solid;
|
||||
border-width: sr(base-height)/2 sr(star-size)/2 sr(base-height)/2 0;
|
||||
border-color: transparent sr(text-background) transparent transparent;
|
||||
}
|
||||
}
|
||||
|
||||
#{sr(parent)} .#{sr(base-classname)}-rtl[data-star-rating] .#{sr(base-classname)}-text {
|
||||
padding: 0 sr(star-size)/4 0 sr(star-size)/2;
|
||||
margin: 0 sr(star-size)/2 0 0;
|
||||
|
||||
&::before {
|
||||
left: unset;
|
||||
right: -(sr(star-size)/2);
|
||||
border-width: sr(base-height)/2 0 sr(base-height)/2 sr(star-size)/2;
|
||||
border-color: transparent transparent transparent sr(text-background);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user