Files
b2b.redline.com.pl/modules/privateshoplite/views/js/jquery.uniform.js
Jacek Pyziak 4d2561ce4e Add PrivateShop module templates and initial setup files
- Created restricted.tpl for displaying restricted access messages with customizable background options.
- Added index.php files in hook and main template directories to prevent direct access and ensure proper redirection.
- Implemented info.tpl to provide module information and support links, enhancing user experience with promotional content.
- Included necessary CSS styles for the new templates to ensure proper layout and responsiveness.
2025-07-04 01:27:12 +02:00

1039 lines
36 KiB
JavaScript

/**
* Uniform
* A jQuery plugin to make your form controls look how you want them to.
*
* @author Josh Pyles <joshpyles@gmail.com>
* @author Tyler Akins <fidian@rumkin.com>
* @author Shahriyar Imanov <shehi@imanov.me>
*
* @license MIT
*
* @see http://opensource.audith.org/uniform
*/
(function (wind, $, undef) {
"use strict";
/**
* Use .prop() if jQuery supports it, otherwise fall back to .attr()
* @usage All other parameters are passed to jQuery's function
*
* @param {jQuery} $el jQuery'd element on which we're calling attr/prop
* @return {*} The result from jQuery
*/
function attrOrProp($el /* , args */) {
var args = Array.prototype.slice.call(arguments, 1);
if ($el.prop) {
// jQuery 1.6+
return $el.prop.apply($el, args);
}
// jQuery 1.5 and below
return $el.attr.apply($el, args);
}
/**
* For backwards compatibility with older jQuery libraries, only bind
* one thing at a time. Also, this function adds our namespace to
* events in one consistent location, shrinking the minified code.
*
* The properties on the events object are the names of the events
* that we are supposed to add to. It can be a space separated list.
* The namespace will be added automatically.
*
* @param {jQuery} $el
* @param {Object} options Uniform options for this element
* @param {Object} events Events to bind, properties are event names
*/
function bindMany($el, options, events) {
var name, namespaced;
for (name in events) {
if (events.hasOwnProperty(name)) {
namespaced = name.replace(/ |$/g, options.eventNamespace);
$el.bind(namespaced, events[name]);
}
}
}
/**
* Bind the hover, active, focus, and blur UI updates
*
* @param {jQuery} $el Original element
* @param {jQuery} $target Target for the events (our div/span)
* @param {Object} options Uniform options for the element $target
*/
function bindUi($el, $target, options) {
bindMany($el, options, {
focus: function () {
$target.addClass(options.focusClass);
},
blur: function () {
$target.removeClass(options.focusClass);
$target.removeClass(options.activeClass);
},
mouseenter: function () {
$target.addClass(options.hoverClass);
},
mouseleave: function () {
$target.removeClass(options.hoverClass);
$target.removeClass(options.activeClass);
},
"mousedown touchbegin": function () {
if (!$el.is(":disabled")) {
$target.addClass(options.activeClass);
}
},
"mouseup touchend": function () {
$target.removeClass(options.activeClass);
}
});
}
/**
* Remove the hover, focus, active classes.
*
* @param {jQuery} $el Element with classes
* @param {Object} options Uniform options for the element
*/
function classClearStandard($el, options) {
$el.removeClass(options.hoverClass + " " + options.focusClass + " " + options.activeClass);
}
/**
* Add or remove a class, depending on if it's "enabled"
*
* @param {jQuery} $el Element that has the class added/removed
* @param {String} className Class or classes to add/remove
* @param {Boolean} enabled True to add the class, false to remove
*/
function classUpdate($el, className, enabled) {
if (enabled) {
$el.addClass(className);
} else {
$el.removeClass(className);
}
}
/**
* Updating the "checked" property can be a little tricky. This
* changed in jQuery 1.6 and now we can pass booleans to .prop().
* Prior to that, one either adds an attribute ("checked=checked") or
* removes the attribute.
*
* @param {jQuery} $tag Our Uniform span/div
* @param {jQuery} $el Original form element
* @param {Object} options Uniform options for this element
*/
function classUpdateChecked($tag, $el, options) {
// setTimeout() introduced by #357
setTimeout(function () {
var c = "checked",
isChecked = $el.is(":" + c);
if(!$el.attr("readonly")) {
if ($el.prop) {
// jQuery 1.6+
$el.prop(c, isChecked);
} else {
// jQuery 1.5 and below
if (isChecked) {
$el.attr(c, c);
} else {
$el.removeAttr(c);
}
}
}
classUpdate($tag, options.checkedClass, isChecked);
}, 1);
}
/**
* Set or remove the "disabled" class for disabled elements, based on
* if the element is detected to be disabled.
*
* @param {jQuery} $tag Our Uniform span/div
* @param {jQuery} $el Original form element
* @param {Object} options Uniform options for this element
*/
function classUpdateDisabled($tag, $el, options) {
classUpdate($tag, options.disabledClass, $el.is(":disabled"));
}
/**
* Wrap an element inside of a container or put the container next
* to the element. See the code for examples of the different methods.
*
* Returns the container that was added to the HTML.
*
* @param {jQuery} $el Element to wrap
* @param {jQuery} $container Add this new container around/near $el
* @param {String} method One of "after", "before" or "wrap"
* @return {jQuery} $container after it has been cloned for adding to $el
*/
function divSpanWrap($el, $container, method) {
switch (method) {
case "after":
// Result: <element /> <container />
$el.after($container);
return $el.next();
case "before":
// Result: <container /> <element />
$el.before($container);
return $el.prev();
case "wrap":
// Result: <container> <element /> </container>
$el.wrap($container);
return $el.parent();
}
return null;
}
/**
* Create a div/span combo for uniforming an element
*
* @param {jQuery} $el Element to wrap
* @param {Object} options Options for the element, set by the user
* @param {Object} divSpanConfig Options for how we wrap the div/span
* @return {Object} Contains the div and span as properties
*/
function divSpan($el, options, divSpanConfig) {
var $div, $span, id;
if (!divSpanConfig) {
divSpanConfig = {};
}
divSpanConfig = $.extend({
bind: {},
divClass: null,
divWrap: "wrap",
spanClass: null,
spanHtml: null,
spanWrap: "wrap"
}, divSpanConfig);
$div = $('<div />');
$span = $('<span />');
// Automatically hide this div/span if the element is hidden.
// Do not hide if the element is hidden because a parent is hidden.
if (options.autoHide && $el.is(':hidden') && $el.css('display') === 'none') {
$div.hide();
}
if (divSpanConfig.divClass) {
$div.addClass(divSpanConfig.divClass);
}
if (options.wrapperClass) {
$div.addClass(options.wrapperClass);
}
if (divSpanConfig.spanClass) {
$span.addClass(divSpanConfig.spanClass);
}
id = attrOrProp($el, 'id');
if (options.useID && id) {
attrOrProp($div, 'id', options.idPrefix + '-' + id);
}
if (divSpanConfig.spanHtml) {
$span.html(divSpanConfig.spanHtml);
}
$div = divSpanWrap($el, $div, divSpanConfig.divWrap);
$span = divSpanWrap($el, $span, divSpanConfig.spanWrap);
classUpdateDisabled($div, $el, options);
return {
div: $div,
span: $span
};
}
/**
* Wrap an element with a span to apply a global wrapper class
*
* @param {jQuery} $el Element to wrap
* @param {Object} options
* @return {jQuery} jQuery Wrapper element
*/
function wrapWithWrapperClass($el, options) {
var $span;
if (!options.wrapperClass) {
return null;
}
$span = $('<span />').addClass(options.wrapperClass);
$span = divSpanWrap($el, $span, "wrap");
return $span;
}
/**
* Test if high contrast mode is enabled.
*
* In high contrast mode, background images can not be set and
* they are always returned as 'none'.
*
* @return {Boolean} True if in high contrast mode
*/
function highContrast() {
var c, $div, el, rgb;
// High contrast mode deals with white and black
rgb = 'rgb(120,2,153)';
$div = $('<div style="width:0;height:0;color:' + rgb + '">');
$('body').append($div);
el = $div.get(0);
// $div.css() will get the style definition, not
// the actually displaying style
if (wind.getComputedStyle) {
c = wind.getComputedStyle(el, '').color;
} else {
c = (el.currentStyle || el.style || {}).color;
}
$div.remove();
return c.replace(/ /g, '') !== rgb;
}
/**
* Change text into safe HTML
*
* @param {String} text
* @return {String} HTML version
*/
function htmlify(text) {
if (!text) {
return "";
}
return $('<span />').text(text).html();
}
/**
* If not MSIE, return false.
* If it is, return the version number.
*
* @return {Boolean}|{Number}
*/
function isMsie() {
return navigator.cpuClass && !navigator.product;
}
/**
* Return true if this version of IE allows styling
*
* @return {Boolean}
*/
function isMsieSevenOrNewer() {
return wind.XMLHttpRequest !== undefined;
}
/**
* Check if the element is a multiselect
*
* @param {jQuery} $el Element
* @return {Boolean} true/false
*/
function isMultiselect($el) {
var elSize;
if ($el[0].multiple) {
return true;
}
elSize = attrOrProp($el, "size");
return !(!elSize || elSize <= 1);
}
/**
* Meaningless utility function. Used mostly for improving minification.
*
* @return {Boolean}
*/
function returnFalse() {
return false;
}
/**
* noSelect plugin, very slightly modified
* http://mths.be/noselect v1.0.3
*
* @param {jQuery} $elem Element that we don't want to select
* @param {Object} options Uniform options for the element
*/
function noSelect($elem, options) {
var none = 'none';
bindMany($elem, options, {
'selectstart dragstart mousedown': returnFalse
});
$elem.css({
MozUserSelect: none,
msUserSelect: none,
webkitUserSelect: none,
userSelect: none
});
}
/**
* Updates the filename tag based on the value of the real input
* element.
*
* @param {jQuery} $el Actual form element
* @param {jQuery} $filenameTag Span/div to update
* @param {Object} options Uniform options for this element
*/
function setFilename($el, $filenameTag, options) {
var filenames = $.map($el[0].files, function (file) {return file.name}).join(', ');
if (filenames === "") {
filenames = options.fileDefaultHtml;
} else {
filenames = filenames.split(/[\/\\]+/);
filenames = filenames[(filenames.length - 1)];
}
$filenameTag.text(filenames);
}
/**
* Function from jQuery to swap some CSS values, run a callback,
* then restore the CSS. Modified to pass JSLint and handle undefined
* values with 'use strict'.
*
* @param {jQuery} $elements Element
* @param {Object} newCss CSS values to swap out
* @param {Function} callback Function to run
*/
function swap($elements, newCss, callback) {
var restore, item;
restore = [];
$elements.each(function () {
var name;
for (name in newCss) {
if (Object.prototype.hasOwnProperty.call(newCss, name)) {
restore.push({
el: this,
name: name,
old: this.style[name]
});
this.style[name] = newCss[name];
}
}
});
callback();
while (restore.length) {
item = restore.pop();
item.el.style[item.name] = item.old;
}
}
/**
* The browser doesn't provide sizes of elements that are not visible.
* This will clone an element and add it to the DOM for calculations.
*
* @param {jQuery} $el
* @param {Function} callback
*/
function sizingInvisible($el, callback) {
var targets;
// We wish to target ourselves and any parents as long as
// they are not visible
targets = $el.parents();
targets.push($el[0]);
targets = targets.not(':visible');
swap(targets, {
visibility: "hidden",
display: "block",
position: "absolute"
}, callback);
}
/**
* Standard way to unwrap the div/span combination from an element
*
* @param {jQuery} $el Element that we wish to preserve
* @param {Object} options Uniform options for the element
* @return {Function} This generated function will perform the given work
*/
function unwrapUnwrapUnbindFunction($el, options) {
return function () {
$el.unwrap().unwrap().unbind(options.eventNamespace);
};
}
var allowStyling = true, // False if IE6 or other unsupported browsers
highContrastTest = false, // Was the high contrast test ran?
uniformHandlers = [ // Objects that take care of "unification"
{
// Buttons
match: function ($el) {
return $el.is("a, button, :submit, :reset, input[type='button']");
},
apply: function ($el, options) {
var $div, defaultSpanHtml, ds, getHtml, doingClickEvent;
defaultSpanHtml = options.submitDefaultHtml;
if ($el.is(":reset")) {
defaultSpanHtml = options.resetDefaultHtml;
}
if ($el.is("a, button")) {
// Use the HTML inside the tag
getHtml = function () {
return $el.html() || defaultSpanHtml;
};
} else {
// Use the value property of the element
getHtml = function () {
return htmlify(attrOrProp($el, "value")) || defaultSpanHtml;
};
}
ds = divSpan($el, options, {
divClass: options.buttonClass,
spanHtml: getHtml()
});
$div = ds.div;
bindUi($el, $div, options);
doingClickEvent = false;
bindMany($div, options, {
"click touchend": function () {
var ev, res, target, href;
if (doingClickEvent) {
return false;
}
if ($el.is(':disabled')) {
return false;
}
doingClickEvent = true;
if ($el[0].dispatchEvent) {
ev = document.createEvent("MouseEvents");
ev.initEvent("click", true, true);
res = $el[0].dispatchEvent(ev);
if ($el.is('a') && res) {
target = attrOrProp($el, 'target');
href = attrOrProp($el, 'href');
if (!target || target === '_self') {
document.location.href = href;
} else {
wind.open(href, target);
}
}
} else {
$el.click();
}
doingClickEvent = false;
}
});
noSelect($div, options);
return {
remove: function () {
// Move $el out
$div.after($el);
// Remove div and span
$div.remove();
// Unbind events
$el.unbind(options.eventNamespace);
return $el;
},
update: function () {
classClearStandard($div, options);
classUpdateDisabled($div, $el, options);
$el.detach();
ds.span.html(getHtml()).append($el);
}
};
}
},
{
// Checkboxes
match: function ($el) {
return $el.is(":checkbox");
},
apply: function ($el, options) {
var ds, $div, $span;
ds = divSpan($el, options, {
divClass: options.checkboxClass
});
$div = ds.div;
$span = ds.span;
// Add focus classes, toggling, active, etc.
bindUi($el, $div, options);
bindMany($el, options, {
"click touchend": function () {
classUpdateChecked($span, $el, options);
}
});
classUpdateChecked($span, $el, options);
return {
remove: unwrapUnwrapUnbindFunction($el, options),
update: function () {
classClearStandard($div, options);
$span.removeClass(options.checkedClass);
classUpdateChecked($span, $el, options);
classUpdateDisabled($div, $el, options);
}
};
}
},
{
// File selection / uploads
match: function ($el) {
return $el.is(":file");
},
apply: function ($el, options) {
var ds, $div, $filename, $button;
// Issue #441: Check if the control supports multiple selection.
var multiselect = typeof($el.attr("multiple")) != "undefined";
// The "span" is the button
ds = divSpan($el, options, {
divClass: options.fileClass,
spanClass: options.fileButtonClass,
// Issue #441: Choose a display label based on the control supporting multiple selection.
spanHtml: multiselect ? options.filesButtonHtml : options.fileButtonHtml,
spanWrap: "after"
});
$div = ds.div;
$button = ds.span;
$filename = $("<span />").html(options.fileDefaultHtml);
$filename.addClass(options.filenameClass);
$filename = divSpanWrap($el, $filename, "after");
// Set the size
if (!attrOrProp($el, "size")) {
attrOrProp($el, "size", $div.width() / 10);
}
// Actions
function filenameUpdate() {
setFilename($el, $filename, options);
}
bindUi($el, $div, options);
// Account for input saved across refreshes
filenameUpdate();
// IE7 doesn't fire onChange until blur or second fire.
if (isMsie()) {
// IE considers browser chrome blocking I/O, so it
// suspends tiemouts until after the file has
// been selected.
bindMany($el, options, {
click: function () {
$el.trigger("change");
setTimeout(filenameUpdate, 0);
}
});
} else {
// All other browsers behave properly
bindMany($el, options, {
change: filenameUpdate
});
}
noSelect($filename, options);
noSelect($button, options);
return {
remove: function () {
// Remove filename and button
$filename.remove();
$button.remove();
// Unwrap parent div, remove events
return $el.unwrap().unbind(options.eventNamespace);
},
update: function () {
classClearStandard($div, options);
setFilename($el, $filename, options);
classUpdateDisabled($div, $el, options);
}
};
}
},
{
// Input fields (text)
match: function ($el) {
if ($el.is("input")) {
var t = (" " + attrOrProp($el, "type") + " ").toLowerCase(),
allowed = " color date datetime datetime-local email month number password search tel text time url week ";
return allowed.indexOf(t) >= 0;
}
return false;
},
apply: function ($el, options) {
var elType, $wrapper;
elType = attrOrProp($el, "type");
$el.addClass(options.inputClass);
$wrapper = wrapWithWrapperClass($el, options);
bindUi($el, $el, options);
if (options.inputAddTypeAsClass) {
$el.addClass(elType);
}
return {
remove: function () {
$el.removeClass(options.inputClass);
if (options.inputAddTypeAsClass) {
$el.removeClass(elType);
}
if ($wrapper) {
$el.unwrap();
}
},
update: returnFalse
};
}
},
{
// Radio buttons
match: function ($el) {
return $el.is(":radio");
},
apply: function ($el, options) {
var ds, $div, $span;
ds = divSpan($el, options, {
divClass: options.radioClass
});
$div = ds.div;
$span = ds.span;
// Add classes for focus, handle active, checked
bindUi($el, $div, options);
bindMany($el, options, {
"click touchend": function () {
// Fixes #418 - Find all radios with the same name, then update them with $.uniform.update() so the right per-element options are used
$el.attr('name') !== undefined ? $.uniform.update($(':radio[name="' + attrOrProp($el, "name") + '"]')) : $.uniform.update($el);
}
});
classUpdateChecked($span, $el, options);
return {
remove: unwrapUnwrapUnbindFunction($el, options),
update: function () {
classClearStandard($div, options);
classUpdateChecked($span, $el, options);
classUpdateDisabled($div, $el, options);
}
};
}
},
{
// Select lists, but do not style multiselects here
match: function ($el) {
return !!($el.is("select") && !isMultiselect($el));
},
apply: function ($el, options) {
var ds, $div, $span, origElemWidth;
if (options.selectAutoWidth) {
sizingInvisible($el, function () {
origElemWidth = $el.width();
});
}
ds = divSpan($el, options, {
divClass: options.selectClass,
spanHtml: ($el.find(":selected:first") || $el.find("option:first")).html(),
spanWrap: "before"
});
$div = ds.div;
$span = ds.span;
if (options.selectAutoWidth) {
// Use the width of the select and adjust the
// span and div accordingly
sizingInvisible($el, function () {
// Force "display: block" - related to bug #287
swap($([$span[0], $div[0]]), {
display: "block"
}, function () {
var spanPad;
spanPad = $span.outerWidth() - $span.width();
$div.width(origElemWidth + spanPad);
$span.width(origElemWidth);
});
});
} else {
// Force the select to fill the size of the div
$div.addClass('fixedWidth');
}
// Take care of events
bindUi($el, $div, options);
bindMany($el, options, {
change: function () {
$span.html($el.find(":selected").html());
$div.removeClass(options.activeClass);
},
"click touchend": function () {
// IE7 and IE8 may not update the value right
// until after click event - issue #238
var selHtml = $el.find(":selected").html();
if ($span.html() !== selHtml) {
// Change was detected
// Fire the change event on the select tag
$el.trigger('change');
}
},
keyup: function () {
$span.html($el.find(":selected").html());
}
});
noSelect($span, options);
return {
remove: function () {
// Remove sibling span
$span.remove();
// Unwrap parent div
$el.unwrap().unbind(options.eventNamespace);
return $el;
},
update: function () {
if (options.selectAutoWidth) {
// Easier to remove and reapply formatting
$.uniform.restore($el);
$el.uniform(options);
} else {
classClearStandard($div, options);
// Reset current selected text
$el[0].selectedIndex = $el[0].selectedIndex; // Force IE to have a ":selected" option (if the field was reset for example)
$span.html($el.find(":selected").html());
classUpdateDisabled($div, $el, options);
}
}
};
}
},
{
// Select lists - multiselect lists only
match: function ($el) {
return !!($el.is("select") && isMultiselect($el));
},
apply: function ($el, options) {
var $wrapper;
$el.addClass(options.selectMultiClass);
$wrapper = wrapWithWrapperClass($el, options);
bindUi($el, $el, options);
return {
remove: function () {
$el.removeClass(options.selectMultiClass);
if ($wrapper) {
$el.unwrap();
}
},
update: returnFalse
};
}
},
{
// Textareas
match: function ($el) {
return $el.is("textarea");
},
apply: function ($el, options) {
var $wrapper;
$el.addClass(options.textareaClass);
$wrapper = wrapWithWrapperClass($el, options);
bindUi($el, $el, options);
return {
remove: function () {
$el.removeClass(options.textareaClass);
if ($wrapper) {
$el.unwrap();
}
},
update: returnFalse
};
}
}
];
// IE6 can't be styled - can't set opacity on select
if (isMsie() && !isMsieSevenOrNewer()) {
allowStyling = false;
}
$.uniform = {
// Default options that can be overridden globally or when uniformed
// globally: $.uniform.defaults.fileButtonHtml = "Pick A File";
// on uniform: $('input').uniform({fileButtonHtml: "Pick a File"});
defaults: {
activeClass: "active",
autoHide: true,
buttonClass: "button",
checkboxClass: "checker",
checkedClass: "checked",
disabledClass: "disabled",
eventNamespace: ".uniform",
fileButtonClass: "action",
fileButtonHtml: "Choose File",
filesButtonHtml: "Choose Files",
fileClass: "uploader",
fileDefaultHtml: "No file selected",
filenameClass: "filename",
focusClass: "focus",
hoverClass: "hover",
idPrefix: "uniform",
inputAddTypeAsClass: true,
inputClass: "uniform-input",
radioClass: "radio",
resetDefaultHtml: "Reset",
resetSelector: false, // We'll use our own function when you don't specify one
selectAutoWidth: true,
selectClass: "selector",
selectMultiClass: "uniform-multiselect",
submitDefaultHtml: "Submit", // Only text allowed
textareaClass: "uniform",
useID: true,
wrapperClass: null
},
// All uniformed elements - DOM objects
elements: []
};
$.fn.uniform = function (options) {
var el = this;
options = $.extend({}, $.uniform.defaults, options);
// If we are in high contrast mode, do not allow styling
if (!highContrastTest) {
highContrastTest = true;
if (highContrast()) {
allowStyling = false;
}
}
// Only uniform on browsers that work
if (!allowStyling) {
return this;
}
// Code for specifying a reset button
if (options.resetSelector) {
$(options.resetSelector).mouseup(function () {
wind.setTimeout(function () {
$.uniform.update(el);
}, 10);
});
}
return this.each(function () {
var $el = $(this), i, handler, callbacks;
// Avoid uniforming elements already uniformed - just update
if ($el.data("uniformed")) {
$.uniform.update($el);
return;
}
// See if we have any handler for this type of element
for (i = 0; i < uniformHandlers.length; i = i + 1) {
handler = uniformHandlers[i];
if (handler.match($el, options)) {
callbacks = handler.apply($el, options);
$el.data("uniformed", callbacks);
// Store element in our global array
$.uniform.elements.push($el.get(0));
return;
}
}
// Could not style this element
});
};
$.uniform.restore = $.fn.uniform.restore = function (elem) {
if (elem === undef) {
elem = $.uniform.elements;
}
$(elem).each(function () {
var $el = $(this), index, elementData;
elementData = $el.data("uniformed");
// Skip elements that are not uniformed
if (!elementData) {
return;
}
// Unbind events, remove additional markup that was added
elementData.remove();
// Remove item from list of uniformed elements
index = $.inArray(this, $.uniform.elements);
if (index >= 0) {
$.uniform.elements.splice(index, 1);
}
$el.removeData("uniformed");
});
};
$.uniform.update = $.fn.uniform.update = function (elem) {
if (elem === undef) {
elem = $.uniform.elements;
}
$(elem).each(function () {
var $el = $(this), elementData;
elementData = $el.data("uniformed");
// Skip elements that are not uniformed
if (!elementData) {
return;
}
elementData.update($el, elementData.options);
});
};
}(this, jQuery));