diff options
Diffstat (limited to 'html/content/js')
51 files changed, 2287 insertions, 0 deletions
diff --git a/html/content/js/Cart/miniCart.js b/html/content/js/Cart/miniCart.js new file mode 100644 index 0000000..c02cc38 --- /dev/null +++ b/html/content/js/Cart/miniCart.js @@ -0,0 +1,96 @@ +$$plugins.define('miniCart', ['dom'], function (element, options, dom) {
+ const plugin = this,
+ selectors = {
+ openMiniCart: '.open-mini-cart', // Link that opens cart
+ closeMiniCart: '.close-mini-cart', // Link that closes cart
+ contentOuterContainer: '.miniCart', // Container for loader and inner content inner
+ loaderContainer: '.miniCart__holder', // Spinner or any other loader
+ contentInnerContainer: '.miniCart__main', // Content of mini cart
+ cartPluginElement: '[data-plugin-cart]'
+ }, cssClasses = {
+ opened: 'opened', // Added to 'openMinicart' link when opened
+ containerOpened: 'active'
+ };
+ let pendingXhr, clearOnClick;
+
+ function onBodyClick(e) {
+ if (element.contains(e.target)) {
+ return;
+ }
+ // case where node is removed from DOM. This means we dont know it's parent. Usually the case of cart remove.
+ if (!document.body.contains(e.target)) {
+ return;
+ }
+ close();
+ }
+
+ function close() {
+ // Remove opened class from link
+ element.querySelector(selectors.openMiniCart).classList.remove(cssClasses.opened);
+
+ //Hide outer element
+ var outterContainer = element.querySelector(selectors.contentOuterContainer);
+ // dom.hide(outterContainer);
+ outterContainer.classList.remove(cssClasses.containerOpened);
+ // Hide and reset inner element
+ const inner = element.querySelector(selectors.contentInnerContainer);
+ //dom.empty(inner);
+ // dom.hide(inner);
+
+
+ // Show loader again to be ready for next time
+ //dom.show(element.querySelector(selectors.loaderContainer));
+
+ // Unbind body click
+ clearOnClick && clearOnClick();
+ }
+
+ function open() {
+ // Add opened class to link
+ element.querySelector(selectors.openMiniCart).classList.add(cssClasses.opened);
+
+ // Show outer container
+ //dom.show();
+ var outterContainer = element.querySelector(selectors.contentOuterContainer);
+ outterContainer.style.display = "block";
+ outterContainer.classList.add(cssClasses.containerOpened);
+ // Listen for body clicks to close
+ clearOnClick && clearOnClick();
+ clearOnClick = plugin.on('click', document.body, onBodyClick);
+ return true;
+ }
+
+ function updateContent() {
+ return;
+ if (pendingXhr) {
+ return;
+ }
+ pendingXhr = true;
+ http.post(options.RefreshUrl, { responseType: "text" })
+ .then(function (r) {
+ const container = element.querySelector(selectors.contentInnerContainer);
+ container.innerHTML = r.data;
+ dom.hide(element.querySelector(selectors.loaderContainer));
+ dom.show(container);
+ })
+ .finally(function () {
+ pendingXhr = false;
+ });
+ }
+
+ const openedStateSelector = selectors.openMiniCart + '.' + cssClasses.opened,
+ closedStateSelector = selectors.openMiniCart + ':not(.' + cssClasses.opened + ')';
+
+ plugin.on('click', element, function (e) {
+ if (dom.closest(e.target, openedStateSelector)) {
+ e.preventDefault();
+ close();
+ } else if (dom.closest(e.target, closedStateSelector)) {
+
+ if (open()) {
+ e.preventDefault();
+ updateContent();
+ }
+ }
+ });
+});
diff --git a/html/content/js/Filters/filterStatus.js b/html/content/js/Filters/filterStatus.js new file mode 100644 index 0000000..1338b4c --- /dev/null +++ b/html/content/js/Filters/filterStatus.js @@ -0,0 +1,113 @@ +$$plugins.define('filterStatus', ['domHelper'], function (element, options, $) {
+ var filterName = element.dataset.inputname,
+ filterInput = element.querySelectorAll('.filter__input'),
+ clear = element.querySelectorAll('.filtersClear'),
+ clearAll = document.querySelectorAll('.filtersClearAll'),
+ selectedRadios,
+ selectedRadio;
+
+ //on radiobutton, checkbox change
+ if (filterInput.length > 0) {
+ for (var i = 0; i < filterInput.length; i++) {
+ filterInput[i].addEventListener('change', function (e) {
+ filterGroupStatus();
+ selectedFilters(e.target);
+ filterBarStatus();
+ activeFilters();
+ });
+ }
+ }
+
+ //clear filter group
+ for (var i = 0; i < clear.length; i++) {
+ clear[i].addEventListener('click', function (e) {
+ clearFilterGroup();
+ filterBarStatus();
+ activeFilters();
+ })
+ }
+
+ //clearAll
+ for (var i = 0; i < clearAll.length; i++) {
+ clearAll[i].addEventListener('click', function (e) {
+ document.querySelectorAll('.selectedFilters__remove').forEach((elem) => elem.click());
+ filterBarStatus();
+ activeFilters();
+ })
+ }
+
+ //check filter group status
+ function filterGroupStatus() {
+ if ($('.filter__input[name=' + filterName + ']:checked').length >= 1) {
+ element.classList.add('filter--checked');
+ }
+ else {
+ element.classList.remove('filter--checked');
+ }
+ }
+
+ //add-remove selected filters on filters bar and on filter
+ function selectedFilters(inputElm) {
+ if (inputElm.checked) {
+ var selectedValue = $(inputElm).siblings('.filter__value').text(),
+ selectedItemId = inputElm.id,
+ selectedItem = document.createElement('li'),
+ selectedItemValue = document.createElement('span'),
+ selectedItemButton = document.createElement('button');
+
+ selectedItem.dataset.id = selectedItemId;
+ selectedItem.dataset.name = filterName;
+ selectedItem.setAttribute("class", "selectedFilters__item");
+ selectedItemValue.setAttribute("class", "selectedFilters__value");
+ selectedItemValue.innerHTML = selectedValue;
+ selectedItemButton.setAttribute("class", "selectedFilters__remove");
+
+ selectedItem.prepend(selectedItemButton);
+ selectedItem.prepend(selectedItemValue);
+ document.querySelector('.selectedFilters__list').prepend(selectedItem);
+
+ if (inputElm.classList.contains('radiobutton__input')) {
+
+ selectedRadios = Object.values(element.querySelectorAll('[name=' + filterName + ']')).filter(selectedRadio => selectedRadio !== inputElm);
+ for (var i = 0; i < selectedRadios.length; i++) {
+ selectedRadio = document.querySelector('[data-id=' + selectedRadios[i].id + ']')
+ if (typeof(selectedRadio) != 'undefined' && selectedRadio != null) {
+ selectedRadio.remove();
+ //$('.filter__selectedValItem[data-id=' + $(this).attr('id') + ']').remove();
+ }
+ }
+ }
+ } else {
+ if (inputElm.classList.contains('checkbox__input')) {
+ document.querySelector('[data-id=' + inputElm.id + ']').remove();
+ //$('.filter__selectedValItem[data-id=' + inputElm.attr('id') + ']').remove();
+ }
+ }
+ }
+
+ //clear filter group
+ function clearFilterGroup() {
+ document.querySelectorAll('input[name=' + filterName + ']').forEach((elem) => elem.checked = false);
+ document.querySelectorAll('[data-name=' + filterName + ']').forEach((elem) => elem.remove());
+ //$('.filter__selectedVal[data-name=' + filterName + ']').empty();
+ filterGroupStatus();
+ }
+
+ function filterBarStatus() {
+ if ($('.selectedFilters__item').length > 1) {
+ $('.selectedFilters').addClass('active');
+ } else {
+ $('.selectedFilters').removeClass('active');
+ }
+ }
+
+ //no of active filter groups
+ function activeFilters() {
+ document.getElementsByClassName("filters__mobButton")[0].dataset.activefilters = $('.filter--checked').length;
+ if ($('.filter--checked').length > 0) {
+ $('.filters').addClass('filters--checked');
+ } else {
+ $('.filters').removeClass('filters--checked');
+ }
+ }
+});
\ No newline at end of file diff --git a/html/content/js/Filters/filters.js b/html/content/js/Filters/filters.js new file mode 100644 index 0000000..e5ade01 --- /dev/null +++ b/html/content/js/Filters/filters.js @@ -0,0 +1,110 @@ +$$plugins.define('filters', ['domHelper','throttle'], function (element, options, $, throttle) {
+ var filterTitle = element.querySelectorAll(".filter__title"),
+ closeButton = element.querySelectorAll(".filters__close"),
+ filterBack = element.querySelectorAll(".filters__mobTitle--prev"),
+ filterContent;
+
+ document.documentElement.style.setProperty('--windowHeight', window.innerHeight + "px");
+
+ //filter accordions
+ for (var i = 0; i < filterTitle.length; i++) {
+ filterTitle[i].addEventListener('click', function (e) {
+ filterContent = $(e.target).siblings('.filter__content');
+ if ($(e.target).parents('.filter').hasClass('filter--closed')) {
+ $(e.target).parents('.filter').removeClass('filter--closed');
+ filterContent.slideDown(240, function () {
+ filterContent.removeAttr('style');
+ });
+ if ($('.filter:not(.filter--closed)').not($(e.target).parents('.filter')).length > 0) {
+ $('.filter:not(.filter--closed)').not($(e.target).parents('.filter')).addClass('filter--closed');
+ //$('.filter:not(.filter--closed)').not($(e.target).parents('.filter')).find('.filter__title').trigger('click');
+ }
+ } else {
+ filterContent.slideUp(240, function () {
+ $(e.target).parents('.filter').addClass('filter--closed');
+ filterContent.removeAttr('style');
+ });
+ }
+ });
+ };
+
+ //mobile filter back
+ for (var i = 0; i < filterBack.length; i++) {
+ filterBack[i].addEventListener('click', function (e) {
+ e.target.closest('.filters__item').classList.remove('filters__item--opened');
+ element.classList.remove('filters--2levelOpened');
+ })
+ }
+
+ //mobile filter button
+ //function scrollEvents() {
+ // var button = document.getElementsByClassName("filters__mobButton")[0];
+ // if (window.scrollY > window.innerHeight * 0.5) {
+ // button.classList.add("filters__mobButton--mini");
+ // } else {
+ // button.classList.remove("filters__mobButton--mini");
+ // }
+ //}
+
+ function resizeEvents() {
+ //close mobile menu on desktop
+ if (window.innerWidth >= 1024 && document.documentElement.classList.contains('filtersOpened')) {
+ element.classList.remove('filters--opened');
+ element.classList.remove('filters--2levelOpened');
+ element.querySelector('.filters__item').classList.remove('filters__item--opened');
+ document.documentElement.classList.remove('filtersOpened');
+ element.style.setProperty('--mobFiltersTop', 0 + "px");
+ document.querySelector('.mainContainer').style.transform = '';
+ }
+
+ ////mobile filters Height
+ if (window.innerWidth < 1024) {
+ document.documentElement.style.setProperty('--windowHeight', window.innerHeight + "px");
+ }
+ }
+
+ //scrollEvents();
+
+ //window.addEventListener('scroll', EventUtils.throttle(scrollEvents, 50));
+ window.addEventListener('resize', throttle(resizeEvents, 200));
+
+ element.querySelector('.filters__mobButton').addEventListener('click', function (e) {
+ openFilters();
+ });
+
+ for (var i = 0; i < closeButton.length; i++) {
+ closeButton[i].addEventListener('click', function (e) {
+ closeFilters();
+ })
+ }
+
+ var positionTop;
+ function openFilters() {
+ positionTop = -window.pageYOffset;
+ element.classList.add('filters--opened');
+ document.documentElement.classList.add('filtersOpened');
+ element.style.setProperty('--mobFiltersTop', -positionTop + "px");
+ document.querySelector('.mainContainer').style.transform = "translateY(" + positionTop + "px)";
+ }
+
+ function closeFilters() {
+ element.classList.remove('filters--opened');
+ element.classList.remove('filters--2levelOpened');
+ setTimeout(function () { element.querySelector('.filters__item--opened').classList.remove('filters__item--opened'); }, 350);
+ document.documentElement.classList.remove('filtersOpened');
+ element.style.setProperty('--mobFiltersTop', 0 + "px");
+ document.querySelector('.mainContainer').style.transform = '';
+
+ window.scrollTo({
+ top: -positionTop
+ });
+ }
+
+ document.addEventListener('click', function (event) {
+ if (!$('.filter').not('.filter--closed').length || $(event.target).parents('.filter').length) {
+ return;
+ }
+
+ $('.filter').not('.filter--closed').find('.filter__title').trigger('click');
+ });
+});
\ No newline at end of file diff --git a/html/content/js/Filters/filtersBar.js b/html/content/js/Filters/filtersBar.js new file mode 100644 index 0000000..feb3cd9 --- /dev/null +++ b/html/content/js/Filters/filtersBar.js @@ -0,0 +1,32 @@ +$$plugins.define('filtersBar', ['domHelper'], function (element, options, $) {
+ //clear filter item
+ //$('.selectedFilters').on('click', '.selectedFilters__remove', function () {
+ // var filterItemId = $(this).parents('.selectedFilters__item').data('id'),
+ // filterName = $(this).parents('.selectedFilters__item').data('name'),
+ // filterGroup = $('.filters__item[data-input-name=' + filterName + ']');
+
+ // if ($("#" + filterItemId).hasClass('checkbox__input') || $("#" + filterItemId).hasClass('radiobutton__input')) {
+ // $("#" + filterItemId).prop("checked", false);
+ // $(this).parents('.selectedFilters__item').remove();
+ // $('.filter__selectedValItem[data-id=' + filterItemId + ']').remove();
+ // }
+
+ // if ($("#" + filterItemId).hasClass('range')) {
+ // $(this).parents('.selectedFilters__item').remove();
+ // $("#" + filterItemId).parents('.filters__item').find('.filtersClear').trigger('click');
+ // }
+
+ // if (filterGroup.find('.filter__input:checked').length >= 1) {
+ // filterGroup.addClass('filter--checked');
+ // }
+ // else {
+ // filterGroup.removeClass('filter--checked');
+ // }
+
+ // if ($('.selectedFilters__item').length > 1) {
+ // $('.selectedFilters').addClass('active');
+ // } else {
+ // $('.selectedFilters').removeClass('active');
+ // }
+ //});
+});
diff --git a/html/content/js/Filters/range.js b/html/content/js/Filters/range.js new file mode 100644 index 0000000..fb8c941 --- /dev/null +++ b/html/content/js/Filters/range.js @@ -0,0 +1,98 @@ +$$plugins.define('range', ['domHelper', 'nouislider', 'wNumb', 'debounce'], function (element, options, $, noUiSlider, wNumb, debounce) {
+ var slider = element.querySelector('.range__slider'),
+ inputs = $('.range__input--min,.range__input--max'),
+ selectedMin = element.closest('.filters__item').querySelector('.filter__selectedPriceMin'),
+ selectedMax = element.closest('.filters__item').querySelector('.filter__selectedPriceMax');
+
+
+ noUiSlider.create(slider, {
+ start: [options.selectedMin, options.selectedMax],
+ connect: true,
+ tooltips: [wNumb({ decimals: 0, postfix: '€' }), wNumb({ decimals: 0, postfix: '€' })],
+ range: {
+ 'min': options.initMin,
+ 'max': options.initMax
+ }
+ });
+
+
+ slider.noUiSlider.on('update', function (values, handle) {
+ var input = inputs.get(handle);
+ var previousValue = input.value;
+
+ input.value = parseFloat(values[handle]).toFixed(0);
+ if (input.value == previousValue) {
+ return;
+ }
+ changing = true;
+
+ $(input).trigger('change');
+ changing = false;
+
+ selectedMin.innerHTML = slider.noUiSlider.get(true)[0].toFixed(0);
+ selectedMax.innerHTML = slider.noUiSlider.get(true)[1].toFixed(0);
+ });
+
+ var changing = false;
+ var setValue = debounce(function (handle, value) {
+ slider.noUiSlider.setHandle(handle, value);
+ $(inputs.get(handle)).trigger('change');
+ }, 500);
+
+ inputs.each(function (input, handle) {
+ $(input).on('change', function () {
+ if (changing) {
+ return;
+ }
+ slider.noUiSlider.setHandle(handle, this.value);
+ });
+
+ $(input).on('keydown', function (e) {
+ var value = Number($(this).val());
+ var steps = slider.noUiSlider.steps();
+
+ var step = steps[handle];
+ var position;
+ switch (e.which) {
+ //enter
+ case 13:
+ slider.noUiSlider.setHandle(handle, this.value);
+ break;
+ // key up
+ case 38:
+ e.preventDefault();
+ // Get step to go increase slider value (up)
+ position = step[1];
+
+ // false = no step is set
+ if (position === false) {
+ position = 1;
+ }
+
+ // null = edge of slider
+ if (position !== null) {
+ setValue(handle, input.value = value + position)
+ }
+
+ break;
+ // key down
+ case 40:
+ e.preventDefault();
+ position = step[0];
+
+ if (position === false) {
+ position = 1;
+ }
+
+ if (position !== null) {
+ setValue(handle, input.value = value - 1)
+ }
+
+ break;
+ }
+ input.focus();
+ });
+ });
+
+
+});
diff --git a/html/content/js/Forms/ajaxForm.js b/html/content/js/Forms/ajaxForm.js new file mode 100644 index 0000000..6ade446 --- /dev/null +++ b/html/content/js/Forms/ajaxForm.js @@ -0,0 +1,188 @@ +$.defineAttributePlugin('ajaxform', ['serialize', 'debounce'], function ($element, options, serialize, debounce) {
+ options = options || {};
+ options.Url = options.Url || $element.attr('action');
+
+ var loader = '<span class="loading"><span class="loading-inner"><span class="loader-bullet"></span><span class="loader-bullet"></span><span class="loader-bullet"></span><span class="loader-bullet"></span><span class="loader-bullet"></span></span></span >';
+ var submit;
+ var onError = debounce(scrollToFirstError, 100);
+
+ onError();
+
+ function getElementToReplace() {
+ var $toReplace;
+ if (options.ElementID) {
+ $toReplace = $("#" + options.ElementID);
+ }
+ else {
+ $toReplace = $element.closest('.ajax-replace-container');
+ if ($toReplace.length === 0) {
+ $toReplace = $element.closest('div.form');
+ }
+ if ($toReplace.length === 0) {
+ $toReplace = $element;
+ }
+ }
+ return $toReplace;
+ }
+
+ function ajaxComplete(response, $element) {
+ var flow = response.getResponseHeader("X-FlowComplete");
+
+ if (flow) {
+
+ $element.trigger('flowcomplete', flow);
+ }
+ }
+
+ function createReplacement(content) {
+ return $(content); // $('<div>' + content + '</div>'); //.find('> *');
+ }
+ var submitting = false;
+ submit = function () {
+ if (!options.Url || submitting) {
+ return;
+ }
+ submitting = true;
+ mask();
+ var headers = {
+ "X-NoRedirect": "true"
+ };
+ var $toReplace = getElementToReplace();
+ if ($toReplace.is('.ajax-modal')) {
+ headers["X-Modal"] = "true";
+ }
+ var result = {
+ redirected: false
+ };
+
+ var ajaxOptions = {
+ url: options.Url,
+ headers: headers,
+ beforeSend: function () {
+ $('body').trigger('TopLoader:Show');
+ $element.find('[type="submit"]').attr('disabled', 'disabled');
+ },
+ type: 'post',
+ success: function (content, status, response) {
+ if (content.RedirectUrl) {
+ result.redirected = true;
+ window.location.href = content.RedirectUrl;
+ return;
+ }
+ if (content) {
+ var $replacement = createReplacement(content);
+ $toReplace.replaceWith($replacement);
+ $replacement.parseAttributePlugins();
+ ajaxComplete(response, $replacement);
+ $replacement.trigger('ajaxForm.submitted');
+ }
+ else {
+ ajaxComplete(response, $element);
+ }
+
+
+ },
+ complete: function () {
+ $('body').trigger('TopLoader:Hide');
+ if (!result.redirected) {
+ unmask();
+ $element.find('[clicked]').removeAttr('clicked');
+ $element.find('[type="submit"]').removeAttr('disabled');
+ submitting = false;
+ }
+ },
+ error: function (r) {
+ if (r.status === 401) {
+ location.reload();
+ return;
+ }
+ }
+ };
+
+ if ($element.is("form") && $element.prop("enctype") === "multipart/form-data") {
+ ajaxOptions.data = new FormData($element.get(0));
+ ajaxOptions.contentType = false;
+ ajaxOptions.processData = false;
+ } else {
+ var $elements = $element.find('input[name], textarea[name], select[name], :submit[name][clicked=true]')
+ ajaxOptions.data = serialize($elements);
+ }
+
+ $.ajax(ajaxOptions);
+ };
+
+ function mask() {
+ $element.find('[clicked]').addClass('in-progress').append(loader);
+ $element.trigger('ajaxform.submitting');
+ }
+ function unmask() {
+ $element.find('[clicked]').removeClass('in-progress').find('.ajax-loader').remove();
+ $element.trigger('ajaxform.complete');
+ }
+
+ if (options.LazyVerification) {
+ var s = submit;
+ submit = function () {
+ $.ajax({
+ url: options.LazyVerification,
+ beforeSend: function () {
+ $element.find('[type="submit"]').attr('disabled', 'disabled');
+ },
+ type: 'post',
+ success: function (content, status, response) {
+ $element.append(content);
+ s();
+ },
+ complete: function () {
+ $element.find('[type="submit"]').removeAttr('disabled');
+ }
+ });
+ };
+ }
+ $element.find("[type=submit]").click(function () {
+ $element.find("[type=submit]").removeAttr("clicked");
+ $(this).attr("clicked", "true");
+ });
+ if ($element.is('form')) {
+ $element.on('submit', function (e) {
+
+ if (options.Url) {
+ e.preventDefault();
+ }
+ var clickedButton = $element.find('[clicked]');
+ if (!clickedButton.is('.cancel')) {
+ if (!$element.valid()) {
+ console.warn('validation error');
+ onError();
+ return;
+ }
+ }
+ submit();
+ });
+ }
+ else {
+ $element.find('[type="submit"]').click(function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ submit();
+ });
+ }
+ $element.data('ajaxform.submit', submit);
+
+ function scrollToFirstError() {
+ var $erroneousElement = $element.find(".field-validation-error").eq(0).parents(".field");
+
+ if ($erroneousElement.length === 1) {
+ var top = $erroneousElement.offset().top;
+ var $header = $('.headerWrp');
+ if ($header.length) {
+ top -= $header.height() + 80;
+ }
+ $('html,body').animate({
+ scrollTop: top
+ }, 500);
+ $erroneousElement.find("input").focus();
+ }
+ }
+
+});
diff --git a/html/content/js/Forms/clearinput.js b/html/content/js/Forms/clearinput.js new file mode 100644 index 0000000..903244f --- /dev/null +++ b/html/content/js/Forms/clearinput.js @@ -0,0 +1,16 @@ +$$plugins.define('clearinput', function (element, options) {
+ var input = element.previousElementSibling;
+
+ input.addEventListener("keyup", function (e) {
+ e.preventDefault();
+ if (input.value !== "") {
+ element.classList.add("active");
+ }
+ });
+
+ element.addEventListener("click", function (e) {
+ e.preventDefault();
+ input.value = "";
+ element.classList.remove("active");
+ });
+});
diff --git a/html/content/js/Forms/customValidators.js b/html/content/js/Forms/customValidators.js new file mode 100644 index 0000000..3ebecf9 --- /dev/null +++ b/html/content/js/Forms/customValidators.js @@ -0,0 +1,11 @@ +define(['jQuery', 'jquery.validate', 'jquery.validate.unobtrusive'], function () {
+ $.validator.unobtrusive.adapters.add("requirechecked", [],
+ function (options) {
+ options.rules['requirechecked'] = 'requirechecked';
+ options.messages['requirechecked'] = options.message;
+ }
+ );
+ $.validator.addMethod("requirechecked", function (value, element, e) {
+ return $(element).is(':checked');
+ });
+});
\ No newline at end of file diff --git a/html/content/js/Forms/password.js b/html/content/js/Forms/password.js new file mode 100644 index 0000000..c0ccbef --- /dev/null +++ b/html/content/js/Forms/password.js @@ -0,0 +1,15 @@ +$$plugins.define('password', function (element, options) {
+ var input = element.previousElementSibling;
+
+ element.addEventListener("click", function (e) {
+ e.preventDefault();
+ if (input.type === 'password') {
+ input.type = 'text';
+ element.classList.add('disabled');
+ }
+ else {
+ input.type = 'password';
+ element.classList.remove('disabled');
+ }
+ });
+});
diff --git a/html/content/js/Forms/select.js b/html/content/js/Forms/select.js new file mode 100644 index 0000000..3ea5435 --- /dev/null +++ b/html/content/js/Forms/select.js @@ -0,0 +1,52 @@ +$$plugins.define('select', ['domHelper'], function (element, options, $) {
+ var list = element.querySelector('.select__listWrap'),
+ selected = $('.select__button'),
+ selectedMob = element.querySelector('.select__button--mobile'),
+ input = element.querySelector('.select__input'),
+ options = $('.select__option');
+
+ function open() {
+ element.classList.add('select--open');
+ $(list).slideDown(250);
+ }
+
+ function close() {
+ $(list).slideUp(250, function () {
+ element.classList.remove('select--open');
+ });
+ }
+
+ document.addEventListener('click', function (event) {
+ if (!isOpen() || element == event.target || $(event.target).parents().contains(element)) {
+ return;
+ }
+ close();
+ });
+
+ selected.on("click", function (e) {
+ e.preventDefault();
+ if (element.classList.contains('select--open')) {
+ close();
+ } else {
+ open();
+ }
+ });
+
+ function isOpen() {
+ return element.classList.contains('select--open');
+ }
+
+ options.on('click', function (e) {
+ e.target.classList.add('selected');
+ prevActiveOption = Object.values(element.querySelectorAll('.selected')).filter(prevActive => prevActive !== e.target);
+ if (prevActiveOption.length != 0) {
+ prevActiveOption[0].classList.remove('selected');
+ }
+ selected.text(e.target.innerHTML);
+ if (selectedMob) {
+ selectedMob.innerHTML = e.target.innerHTML;
+ }
+ $(input).val(e.target.dataset.value).trigger('change');
+ close();
+ });
+});
diff --git a/html/content/js/Forms/serialize.js b/html/content/js/Forms/serialize.js new file mode 100644 index 0000000..0bdd44c --- /dev/null +++ b/html/content/js/Forms/serialize.js @@ -0,0 +1,30 @@ +define(function () {
+ return function ($elements) {
+ var values = {};
+ $elements.each(function () {
+ var $input = $(this);
+ var value = $input.val();
+ if (!value) {
+ return;
+ }
+ if ($input.is(':checkbox, :radio') && !$input.is(':checked')) {
+ return;
+ }
+ var name = $(this).attr('name');
+ var v = values[name] || [];
+ values[name] = v;
+ v.push(value);
+ });
+ var s = '';
+ for (var k in values) {
+ for (var i = 0; i < values[k].length; i++) {
+ s += '&' + k + '=' + encodeURIComponent(values[k][i]);
+ }
+ }
+ if (s) {
+ s = s.substr(1);
+ }
+ return s;
+ };
+
+});
\ No newline at end of file diff --git a/html/content/js/Forms/textarea.js b/html/content/js/Forms/textarea.js new file mode 100644 index 0000000..493c78f --- /dev/null +++ b/html/content/js/Forms/textarea.js @@ -0,0 +1,26 @@ +$$plugins.define('textarea', function (element, options) {
+ const textarea = element.querySelector('textarea');
+
+ //style focus
+ textarea.addEventListener('focus', (event) => {
+ textarea.closest(".textarea").classList.add("focus");
+ });
+
+ textarea.addEventListener('blur', (event) => {
+ textarea.closest(".textarea").classList.remove("focus");
+ });
+
+ //characters count
+ textarea.addEventListener("input", event => {
+ const target = event.currentTarget;
+ const maxLength = target.getAttribute("maxlength");
+ const currentLength = target.value.length;
+ const currentLengthText = document.getElementsByClassName("textarea__remaining")[0];
+
+ currentLengthText.innerHTML = currentLength;
+
+ if (currentLength >= maxLength) {
+ return;
+ }
+ });
+});
diff --git a/html/content/js/Forms/validateform.js b/html/content/js/Forms/validateform.js new file mode 100644 index 0000000..38629e2 --- /dev/null +++ b/html/content/js/Forms/validateform.js @@ -0,0 +1,3 @@ +$.defineAttributePlugin('validateform', ['jQuery', 'jquery.validate', 'jquery.validate.unobtrusive', 'customValidators'], function ($element) {
+ $.validator.unobtrusive.parse($element);
+});
\ No newline at end of file diff --git a/html/content/js/Images/lazyload.js b/html/content/js/Images/lazyload.js new file mode 100644 index 0000000..4f954af --- /dev/null +++ b/html/content/js/Images/lazyload.js @@ -0,0 +1,61 @@ +$$plugins.define('lazyload', function (element, options) {
+ const plugin = this;
+ plugin.logger.debug("lazy loading");
+ const mutationObserver =
+ new MutationObserver(function (mutations) {
+ mutations.forEach(function (mutation, index) {
+ if (mutation.type === 'childList') {
+ mutation.addedNodes.forEach(update);
+ }
+ });
+ }),
+ observer =
+ new IntersectionObserver(function (entries, self) {
+ entries.forEach(function (entry) {
+ if (entry.isIntersecting) {
+ load(entry.target);
+ self.unobserve(entry.target);
+ }
+ });
+ }, options || {
+ rootMargin: '0px 0px 1250px 0px',
+ threshold: 0
+ }),
+ elms = element.querySelectorAll('.lazy');
+ elms.forEach(elm => observer.observe(elm));
+ mutationObserver.observe(element, { childList: true, subtree: true });
+
+ function update(element) {
+ if (!(element instanceof (HTMLElement))) {
+ return;
+ }
+ const container = element || document;
+ if (!container.querySelectorAll) {
+ return;
+ }
+ const elms = container.querySelectorAll('.lazy');
+ Array.prototype.forEach.call(elms, (elm) => !elm.getAttribute('data-loaded') && observer.observe(elm));
+ }
+
+ function load(elm) {
+ let i = 0, source, attr, picture = elm.parentElement, sources = picture.querySelectorAll('.lazysrcset');
+ if (sources.length) {
+ for (; i < sources.length; i++) {
+ source = sources[i];
+ attr = source.getAttribute('data-srcset');
+ if (attr) {
+ source.srcset = source.getAttribute('data-srcset');
+ }
+ }
+ }
+
+ if (!elm.getAttribute('data-loaded') && elm.getAttribute('data-src')) {
+ elm.src = elm.getAttribute('data-src');
+ elm.setAttribute('data-loaded', true);
+ }
+ }
+
+ return {
+ update: update
+ };
+});
\ No newline at end of file diff --git a/html/content/js/Modals/modal.js b/html/content/js/Modals/modal.js new file mode 100644 index 0000000..7ce9145 --- /dev/null +++ b/html/content/js/Modals/modal.js @@ -0,0 +1,6 @@ +$$plugins.define('modal', ['domHelper'], function (element, options, $) {
+ var close = $(element).find('.modal__close');
+ close.on('click', function () {
+ $(element).removeClass('open');
+ });
+});
diff --git a/html/content/js/Plugins/accordion.js b/html/content/js/Plugins/accordion.js new file mode 100644 index 0000000..62e25ad --- /dev/null +++ b/html/content/js/Plugins/accordion.js @@ -0,0 +1,43 @@ +$$plugins.define('accordion', ['domHelper'], function (element, options, $) {
+ var animating = false,
+ $header = $(element).find('.acc:not(.acc--disabled) .acc__header'),
+ $content,
+ $prevActiveAcc,
+ $this,
+ $accItem,
+ singleOpen = options.singleOpen ? options.singleOpen : false;
+
+ $header.on('click', function (e) {
+ $this = $(this);
+ $accItem = $this.parent('.acc');
+ $content = $this.next('.acc__content');
+ if (animating === true) {
+ return;
+ }
+ animating = true;
+ if ($accItem.is('.open')) {
+ $content.slideUp(300, function () {
+ $accItem.removeClass('open');
+ $content.removeAttr('style');
+ animating = false;
+ });
+ } else {
+ $content.slideDown(300, function () {
+ $accItem.addClass('open');
+ $content.removeAttr('style');
+ animating = false;
+ });
+
+ if (singleOpen) {
+ $prevActiveAcc = $accItem.siblings('.acc.open');
+ if ($prevActiveAcc.length != 0) {
+ $prevActiveAcc.find('.acc__content').slideUp(300, function () {
+ $prevActiveAcc.removeClass('open');
+ $prevActiveAcc.find('.acc__content').removeAttr('style');
+ animating = false;
+ });
+ }
+ }
+ }
+ });
+});
diff --git a/html/content/js/Plugins/breadcrumb.js b/html/content/js/Plugins/breadcrumb.js new file mode 100644 index 0000000..112824b --- /dev/null +++ b/html/content/js/Plugins/breadcrumb.js @@ -0,0 +1,9 @@ +$$plugins.define('breadcrumb', function (element, options) {
+ var scrollPos = element.querySelector('.breadcrumb__item:last-child').offsetLeft - element.offsetLeft;
+
+ element.scroll({
+ top: 0,
+ left: scrollPos,
+ behavior: 'smooth'
+ });
+});
diff --git a/html/content/js/Plugins/copy.js b/html/content/js/Plugins/copy.js new file mode 100644 index 0000000..c33430f --- /dev/null +++ b/html/content/js/Plugins/copy.js @@ -0,0 +1,25 @@ +$$plugins.define('copy', function (element, options) {
+ //copyButton: data-copy-btn
+ //content to be copied: data-copy-text
+ //tooltip: data-copy-tooltip
+
+ const copyButton = element,
+ copyButtonId = copyButton.getAttribute('data-copy-btn'),
+ copyText = document.querySelector(`[data-copy-text='${copyButtonId}']`),
+ tooltip = document.querySelector(`[data-copy-tooltip='${copyButtonId}']`);
+
+ function copy() {
+ var r = document.createRange();
+ r.selectNode(copyText);
+ window.getSelection().removeAllRanges();
+ window.getSelection().addRange(r);
+ document.execCommand('copy');
+ window.getSelection().removeAllRanges();
+ tooltip.classList.add('copyText__tooltip--open');
+ setTimeout(function () {
+ tooltip.classList.remove('copyText__tooltip--open');
+ }, 1600);
+ }
+
+ copyButton.addEventListener("click", copy);
+});
diff --git a/html/content/js/Plugins/expand.js b/html/content/js/Plugins/expand.js new file mode 100644 index 0000000..533e978 --- /dev/null +++ b/html/content/js/Plugins/expand.js @@ -0,0 +1,38 @@ +$$plugins.define('expand', ['domHelper'], function (element, options, $) {
+ //triggerButton: data-trigger-expand
+ //content to be initialized: data-content-expand
+ const triggerButton = element.querySelector('[data-trigger-expand]'),
+ triggerButtonId = triggerButton.getAttribute('data-trigger-expand'),
+ content = $(`[data-content-expand='${triggerButtonId}']`);
+
+ var $triggerButton = $(triggerButton);
+
+ $triggerButton.on('click', function (e) {
+ e.preventDefault();
+ if ($triggerButton.hasClass('active')) {
+ content.slideUp(300, function () {
+ $triggerButton.removeClass('active');
+ content.removeAttr('style');
+ });
+ } else {
+ $triggerButton.addClass('active');
+ content.slideDown(300, function () {
+ if (content.find('.scrollbarShadow').length > 0 && !content.find('.scrollbarShadow').hasClass('initialized')) {
+ content.find('.scrollbarShadow').addClass('initialized');
+ }
+ });
+ }
+ });
+
+ if (options.closeOnCLickAway == true) {
+ document.addEventListener('click', function (event) {
+ if (!$triggerButton.hasClass('active') || element == event.target || $(event.target).parents().contains(element)) {
+ return;
+ }
+ content.slideUp(300, function () {
+ $triggerButton.removeClass('active');
+ content.removeAttr('style');
+ });
+ });
+ }
+});
diff --git a/html/content/js/Plugins/expandText.js b/html/content/js/Plugins/expandText.js new file mode 100644 index 0000000..0b58cb7 --- /dev/null +++ b/html/content/js/Plugins/expandText.js @@ -0,0 +1,5 @@ +$$plugins.define('expandText', function (element, options) {
+ element.querySelector('.expandText__button').addEventListener('click', () => {
+ element.classList.toggle('open');
+ });
+});
diff --git a/html/content/js/Plugins/fileinput.js b/html/content/js/Plugins/fileinput.js new file mode 100644 index 0000000..10ba891 --- /dev/null +++ b/html/content/js/Plugins/fileinput.js @@ -0,0 +1,20 @@ +$$plugins.define('fileinput', function (element, options) {
+ const inputfile = element.querySelector('.file-upload__input');
+ const filedelete = element.querySelector('.file-upload__delete');
+
+ inputfile.addEventListener('change', (event) => {
+ const inputname = element.querySelector('.file-upload__name');
+ const filename = inputfile.files[0].name;
+ inputname.innerText = filename;
+ element.classList.add('file-upload__filled');
+ });
+
+ filedelete.addEventListener('click', (event) => {
+ const inputname = element.querySelector('.file-upload__name');
+
+ inputname.innerText = "";
+ element.classList.remove('file-upload__filled');
+ inputfile.value = "";
+ });
+
+});
diff --git a/html/content/js/Plugins/gallery.js b/html/content/js/Plugins/gallery.js new file mode 100644 index 0000000..6ac147a --- /dev/null +++ b/html/content/js/Plugins/gallery.js @@ -0,0 +1,51 @@ +$$plugins.define('gallery', ['swiper-bundle', 'domHelper'], function (element, options, Swiper, $) {
+ var $galleryImg = $('.gallery__figure img'),
+ thumbs = document.querySelector('.galleryThumbs'),
+ sliderModal = document.querySelector('.gallerySliderModal'),
+ $image;
+
+ var swiperThumbs = new Swiper(".galleryThumbs", {
+ direction: "horizontal",
+ freeMode: true,
+ init: false,
+ slidesPerView: 4,
+ spaceBetween: 8,
+ speed: 800,
+ watchSlidesProgress: true,
+ pagination: {
+ el: '.swiper-pagination',
+ },
+ breakpoints: {
+ 768: {
+ slidesPerView: 5,
+ spaceBetween: 17,
+ }
+ },
+ });
+
+ var swiperMain = new Swiper(".galleryMainImg", {
+ init: false,
+ loop: true,
+ navigation: {
+ nextEl: ".swiper-button-next",
+ prevEl: ".swiper-button-prev",
+ },
+ speed: 800,
+ thumbs: {
+ swiper: swiperThumbs,
+ },
+ });
+
+ $galleryImg.on('click', function () {
+ if (!thumbs.classList.contains('swiper-initialized')) {
+ swiperThumbs.init();
+ swiperMain.init();
+ }
+ sliderModal.classList.add('open');
+ $image = $(this).parents('.gallery__figure');
+ swiperMain.slideTo($image.index() + 1, 0);
+
+ //document.documentElement.classList.add('noScroll');
+
+ });
+});
\ No newline at end of file diff --git a/html/content/js/Plugins/infoPopup.js b/html/content/js/Plugins/infoPopup.js new file mode 100644 index 0000000..e11ad16 --- /dev/null +++ b/html/content/js/Plugins/infoPopup.js @@ -0,0 +1,8 @@ +$$plugins.define('infoPopup', function (element, options) {
+ element.addEventListener('click', event => {
+ element.closest('.infoPopup').classList.add('moveOut');
+ setTimeout(function () {
+ element.closest('.infoPopup').remove()
+ }, 500);
+ });
+});
diff --git a/html/content/js/Plugins/initialize.js b/html/content/js/Plugins/initialize.js new file mode 100644 index 0000000..ecdca48 --- /dev/null +++ b/html/content/js/Plugins/initialize.js @@ -0,0 +1,11 @@ +$$plugins.define('initialize', function (element, options) {
+ //triggerButton: data-trigger-initialize
+ //content to be initialized: data-content-initialize
+
+ const triggerButton = element.getAttribute('data-trigger-initialize'),
+ content = document.querySelector(`[data-content-initialize='${triggerButton}']`);
+
+ element.addEventListener('click', function (event) {
+ content.classList.add("initialized");
+ });
+});
diff --git a/html/content/js/Plugins/intersecting.js b/html/content/js/Plugins/intersecting.js new file mode 100644 index 0000000..87faf61 --- /dev/null +++ b/html/content/js/Plugins/intersecting.js @@ -0,0 +1,18 @@ +$$plugins.define('intersecting', function (element, options) {
+ const el = document.querySelector(options.target);
+
+ const observer = new window.IntersectionObserver(([entry]) => {
+ const intersectionRatio = entry.intersectionRatio.toFixed(2);
+ if (entry.isIntersecting) {
+ element.classList.add("sticky");
+ } else {
+ element.classList.remove("sticky");
+ }
+ }, {
+ root: null,
+ rootMargin: '-30% 0px -70%',
+ threshold: 0
+ })
+
+ observer.observe(el)
+});
diff --git a/html/content/js/Plugins/menu.js b/html/content/js/Plugins/menu.js new file mode 100644 index 0000000..d6dced2 --- /dev/null +++ b/html/content/js/Plugins/menu.js @@ -0,0 +1,97 @@ +$$plugins.define('menu', ['domHelper'], function (element, options, $) {
+ var level1 = $('.mainNav__link--hasChildren', element),
+ closeElements = $('.mainLayer, .megamenu__close'),
+ body = $('body'),
+ burgerMenu = $('.burgerMenu'),
+ mainContainer = $('.mainContainer'),
+ header = $('.header'),
+ megaMenuBack = $('.megamenu__back'),
+ positionTopDesktop,
+ scrollBarWidth;
+
+
+ level1.on('click', function (event) {
+ event.preventDefault();
+ var $this = $(this);
+ if ($this.parent('.mainNav__item').is('.mainNav__item--active')) {
+ closeMenuLevel1($this);
+ }
+ else {
+ openMenuLevel1($this);
+ }
+ });
+
+ //close menu
+ closeElements.on('click', function () {
+ if (window.innerWidth < 1024) {
+ closeMobileMenu();
+ } else {
+ closeMenuLevel1($('.mainNav__item--active .mainNav__link'));
+ }
+ });
+
+ function openMenuLevel1($activeItem) {
+ var $activeItemParent = $activeItem.parent('.mainNav__item');
+
+ positionTopDesktop = -window.scrollY;
+ scrollBarWidth = window.innerWidth - mainContainer.innerWidth();
+
+ var activeItemsExceptCurrent = $('.mainNav__item--active').not($activeItemParent);
+ if (activeItemsExceptCurrent.length > 0) {
+ activeItemsExceptCurrent.removeClass('mainNav__item--active').addClass('mainNav__item--fadeOut');
+ setTimeout(function () {
+ activeItemsExceptCurrent.removeClass('mainNav__item--fadeOut');
+ }, 350);
+ }
+
+ $activeItemParent.addClass('mainNav__item--active');
+ body.addClass('menuOpened menuOpened--level2').each(e => e.style.paddingRight = scrollBarWidth + "px");
+ burgerMenu.addClass('burgerMenu--opened');
+
+ mainContainer.each(e => e.style.transform = "translateY(" + positionTopDesktop + "px)");
+ header.each(e => e.style.width = "calc(100vw - " + scrollBarWidth + "px)");
+ }
+
+ function closeMenuLevel1($activeItem) {
+ var $activeItemParent = $activeItem.parent('.mainNav__item');
+ $activeItemParent.removeClass('mainNav__item--active');
+ body.removeClass('menuOpened').each(e => e.style.paddingRight = "");
+ burgerMenu.removeClass('burgerMenu--opened');
+ mainContainer.each(e => e.style.transform = "");
+ header.each(e => e.style.width = "");
+ body.scroll({
+ top: -positionTopDesktop
+ });
+ }
+
+ burgerMenu.on('click', function (e) {
+ e.preventDefault();
+ if (e.target.matches('.burgerMenu--opened')) {
+ closeMobileMenu();
+ } else {
+ openMobileMenu();
+ }
+ });
+
+ var positionTop;
+ function openMobileMenu() {
+ positionTop = -window.scrollY;
+ burgerMenu.addClass('burgerMenu--opened');
+ body.addClass('menuOpened menuOpened--level2');
+ mainContainer.each(e => e.style.transform = "translateY(" + positionTop + "px)");
+ }
+
+ function closeMobileMenu() {
+ burgerMenu.removeClass('burgerMenu--opened');
+ body.removeClass('menuOpened menuOpened--level2');
+ mainContainer.each(e => e.style.transform = "");
+ body.scroll({
+ top: -positionTop
+ });
+ }
+
+ megaMenuBack.on('click', function (event) {
+ $('.mainNav__item--active').removeClass('mainNav__item--active');
+ body.removeClass('menuOpened--level2');
+ });
+});
diff --git a/html/content/js/Plugins/quantity.js b/html/content/js/Plugins/quantity.js new file mode 100644 index 0000000..f124c63 --- /dev/null +++ b/html/content/js/Plugins/quantity.js @@ -0,0 +1,55 @@ +$$plugins.define('quantity', ['dom'], function (element, options, dom) {
+ //const plugin = this,
+ // increaseButton = element.querySelector('.quantity__btn--inc'),
+ // decreaseButton = element.querySelector('.quantity__btn--dec'),
+ // input = element.querySelector('input'),
+ // maxQuantity = options.MaxQuantity,
+ // minQuantity = options.MinQuantity || 1;
+
+ //let currentValue = parseInt(input.value);
+
+ //checkButtons();
+ //plugin.on('click', increaseButton, updateValue);
+ //plugin.on('click', decreaseButton, updateValue);
+
+ //function updateValue(e) {
+ // const button = dom.closest(e.target, '[data-ref="quantity-control"]'),
+ // previousValue = currentValue;
+ // if (!button || button.classList.contains('disabled')) {
+ // return false;
+ // }
+ // if (button === increaseButton) {
+ // currentValue += 1;
+ // } else {
+ // currentValue -= 1;
+ // }
+
+ // console.log(button)
+ // input.value = currentValue;
+ // checkButtons();
+ // if (options.ItemId) {
+ // plugin.emit('cart:quantity.changed', {
+ // quantity: currentValue,
+ // item: options.ItemId,
+ // element: e.target,
+ // fail: function onFail() {
+ // currentValue = previousValue;
+ // }
+ // });
+ // }
+ //}
+
+ //function checkButtons() {
+ // if (currentValue > minQuantity) {
+ // decreaseButton.classList.remove('disabled');
+ // } else {
+ // decreaseButton.classList.add('disabled');
+ // }
+
+ // if (currentValue < maxQuantity) {
+ // increaseButton.classList.remove('disabled');
+ // } else {
+ // increaseButton.classList.add('disabled');
+ // }
+ //}
+});
diff --git a/html/content/js/Plugins/scrollShadowHor.js b/html/content/js/Plugins/scrollShadowHor.js new file mode 100644 index 0000000..eed0325 --- /dev/null +++ b/html/content/js/Plugins/scrollShadowHor.js @@ -0,0 +1,42 @@ +$$plugins.define('scrollShadowHor', function (element, options) {
+ var scrollElm = element.querySelector('.scrollbar'),
+ listInner = element.querySelector('.scrollbar__inner');
+
+ const observer = new MutationObserver(function(mutations) {
+ var childrenMutations = mutations.filter((x) => x.type === "childList");
+ if (childrenMutations.length > 0){
+ checkScrollPos(scrollElm);
+ }
+ });
+
+ observer.observe(listInner, { subtree: true, childList: true });
+
+ checkScrollPos(scrollElm);
+
+ scrollElm.addEventListener("scroll", function () {
+ checkScrollPos(this);
+ });
+
+ function checkScrollPos(scrollContainer) {
+ if (scrollContainer.scrollLeft + element.offsetWidth > listInner.offsetWidth - 8) {
+ element.classList.add('scrollbarShadow--right');
+ } else {
+ element.classList.remove('scrollbarShadow--right');
+ }
+ if (scrollContainer.scrollLeft < 8) {
+ element.classList.add('scrollbarShadow--left');
+ } else {
+ element.classList.remove('scrollbarShadow--left');
+ }
+ }
+
+ //checkScrollInit();
+
+ //function checkScrollInit() {
+ // if (element.offsetWidth >= listInner.offsetWidth) {
+ // element.classList.add('scrollbarShadow--noScroll');
+ // } else {
+ // element.classList.remove('scrollbarShadow--noScroll');
+ // }
+ //}
+});
diff --git a/html/content/js/Plugins/scrollShadowVert.js b/html/content/js/Plugins/scrollShadowVert.js new file mode 100644 index 0000000..2824c22 --- /dev/null +++ b/html/content/js/Plugins/scrollShadowVert.js @@ -0,0 +1,57 @@ +$$plugins.define('scrollShadowVert', function (element, options) {
+ var scrollElm = element.querySelector('.scrollbar'),
+ listInner = element.querySelector('.scrollbar__inner');
+
+ //observer for adding/removing children elements
+ const observer = new MutationObserver(function (mutations) {
+ var childrenMutations = mutations.filter((x) => x.type === "childList");
+ if (childrenMutations.length > 0) {
+ checkScrollPos(scrollElm);
+ }
+ });
+
+ observer.observe(listInner, { subtree: true, childList: true });
+
+ //observer for initialized class
+ if (options.initialize == true) {
+ const targetNode = element;
+
+ const observer2 = new MutationObserver(function (mutations) {
+ var classMutations = mutations.filter((x) => x.type === "attributes");
+ if (classMutations.length > 0 && targetNode.classList.contains('initialized')) {
+ checkScrollPos(scrollElm);
+ observer2.disconnect();
+ }
+ });
+ observer2.observe(targetNode, { attributes: true, attributeFilter: ['class'] });
+ }
+
+ checkScrollPos(scrollElm);
+
+ scrollElm.addEventListener("scroll", function () {
+ checkScrollPos(this);
+ });
+
+ function checkScrollPos(scrollContainer) {
+ if (scrollContainer.scrollTop + element.offsetHeight > listInner.offsetHeight - 8) {
+ element.classList.add('scrollbarShadow--bottom');
+ } else {
+ element.classList.remove('scrollbarShadow--bottom');
+ }
+ if (scrollContainer.scrollTop < 8) {
+ element.classList.add('scrollbarShadow--top');
+ } else {
+ element.classList.remove('scrollbarShadow--top');
+ }
+ }
+
+ //checkScrollInit();
+
+ //function checkScrollInit() {
+ // if (element.offsetHeight >= listInner.offsetHeight) {
+ // element.classList.add('scrollbarShadow--noScroll');
+ // } else {
+ // element.classList.remove('scrollbarShadow--noScroll');
+ // }
+ //}
+});
diff --git a/html/content/js/Plugins/tabs.js b/html/content/js/Plugins/tabs.js new file mode 100644 index 0000000..74d4efc --- /dev/null +++ b/html/content/js/Plugins/tabs.js @@ -0,0 +1,28 @@ +$.defineAttributePlugin('tabs', function ($element, options) {
+ var animating = false,
+ dataTab,
+ slideSpeed = options.slideSpeed ? options.slideSpeed : 400;
+
+ if (!$element.find("[data-tab-trigger]").hasClass('active')) {
+ setTimeout(function () { $element.find("[data-tab-trigger]").first().trigger('click'); }, 50);
+ }
+
+ $element.find("[data-tab-trigger]").click(function (e) {
+ e.preventDefault();
+ if (animating === true || $(this).hasClass('active')) {
+ return;
+ }
+ animating = true;
+ $(this).addClass('active').siblings().removeClass('active');
+ dataTab = $(this).data('tab-trigger');
+
+ $('[data-tab-content="' + dataTab + '"]').siblings('.active').slideUp(slideSpeed, function () {
+ $(this).removeClass('active').removeAttr('style');
+ });
+
+ $('[data-tab-content="' + dataTab + '"]').slideDown(slideSpeed, function () {
+ $(this).addClass('active').removeAttr('style');
+ animating = false;
+ });
+ });
+});
diff --git a/html/content/js/Plugins/tabtoggle.js b/html/content/js/Plugins/tabtoggle.js new file mode 100644 index 0000000..84a0508 --- /dev/null +++ b/html/content/js/Plugins/tabtoggle.js @@ -0,0 +1,27 @@ +$$plugins.define('tabtoggle', function (element, options) {
+ var activeTab = element.querySelector(".active");
+ var sliderNav = element.querySelector(".tabToggle__tabs");
+ var activeTabContent = document.querySelector("[data-tabToggle-content].active");
+
+ if (element.querySelector(".tabToggle__tab:nth-child(2)").classList.contains("active")) {
+ sliderNav.classList.add("slide");
+ }
+
+ element.addEventListener("click", function (e) {
+ if (!(e.target.classList.contains("active"))) {
+ activeTab.classList.remove("active");
+ activeTab = e.target;
+
+ activeTab.classList.add("active");
+ sliderNav.classList.toggle("slide");
+ activeTabContent.classList.remove("active");
+ activeTabContent = document.querySelector("[data-tabToggle-content=" + activeTab.dataset.tabtoggleTarget)
+ activeTabContent.classList.add("active");
+
+ window.scrollTo({
+ top: activeTabContent.getBoundingClientRect().top + window.scrollY - document.querySelector(".header").offsetHeight,
+ behavior: 'smooth'
+ });
+ }
+ });
+});
diff --git a/html/content/js/Plugins/tooltip.js b/html/content/js/Plugins/tooltip.js new file mode 100644 index 0000000..2326caf --- /dev/null +++ b/html/content/js/Plugins/tooltip.js @@ -0,0 +1,45 @@ +$$plugins.define('tooltip', ['throttle'], function (element, options, throttle) {
+ var openBtn = element.querySelector('.tooltip__btn'),
+ tooltipMain = element.querySelector('.tooltip__main');
+
+ openBtn.addEventListener('click', (event) => {
+ event.preventDefault();
+ if (element.classList.contains('tooltip--open')) {
+ element.classList.remove('tooltip--open');
+ } else {
+ $('.tooltip').not(element).removeClass('tooltip--open');
+ element.classList.add('tooltip--open');
+ }
+ });
+
+ document.addEventListener('click', function (event) {
+ if (element !== event.target && !element.contains(event.target) && element.classList.contains('tooltip--open')) {
+ element.classList.remove('tooltip--open');
+ }
+ });
+
+ function tooltipPosition() {
+ element.classList.remove('tooltip--bottom');
+ element.classList.remove('tooltip--right');
+ element.classList.remove('tooltip--left');
+
+ if (element.getBoundingClientRect().top < window.innerHeight / 2) {
+ element.classList.add('tooltip--bottom');
+ } else {
+ element.classList.remove('tooltip--bottom');
+ }
+
+ if (element.getBoundingClientRect().left < tooltipMain.offsetWidth / 2) {
+ element.classList.add('tooltip--right');
+ }
+
+ if (document.body.clientWidth - element.getBoundingClientRect().left < tooltipMain.offsetWidth / 2) {
+ element.classList.add('tooltip--left');
+ }
+ }
+
+ tooltipPosition();
+
+ window.addEventListener('scroll', throttle(tooltipPosition, 50));
+ window.addEventListener('resize', throttle(tooltipPosition, 200));
+});
diff --git a/html/content/js/Products/productHeader.js b/html/content/js/Products/productHeader.js new file mode 100644 index 0000000..3e12eee --- /dev/null +++ b/html/content/js/Products/productHeader.js @@ -0,0 +1,21 @@ +$$plugins.define('productHeader', function (element, options) {
+ const el = document.querySelector('#addToCartButton');
+ const header = document.querySelector(".productHeader");
+
+ const observer = new window.IntersectionObserver(([entry]) => {
+ if (entry.isIntersecting) {
+ header.classList.remove("active");
+ return
+ }
+ if (entry.boundingClientRect.top > 0) {
+ header.classList.remove("active");
+ } else {
+ header.classList.add("active");
+ }
+ }, {
+ root: null,
+ threshold: 0,
+ })
+
+ observer.observe(el)
+});
diff --git a/html/content/js/Products/productImageModal.js b/html/content/js/Products/productImageModal.js new file mode 100644 index 0000000..9873bed --- /dev/null +++ b/html/content/js/Products/productImageModal.js @@ -0,0 +1,47 @@ +$$plugins.define('productImageModal', ['swiper-bundle', 'domHelper'], function (element, options, Swiper, $) {
+ var $productImg = $('.productPage__image'),
+ thumbs = document.querySelector('.productThumbs'),
+ sliderModal = document.querySelector('.productSliderModal'),
+ $image;
+
+ var swiperThumbs = new Swiper(".productThumbs", {
+ direction: "vertical",
+ freeMode: true,
+ init: false,
+ slidesPerView: 'auto',
+ spaceBetween: 8,
+ speed: 800,
+ watchSlidesProgress: true,
+ breakpoints: {
+ 0: {
+ direction: "horizontal",
+ },
+ 640: {
+ direction: "vertical",
+ }
+ }
+ });
+
+ var swiperMain = new Swiper(".productMainImg", {
+ init: false,
+ loop: true,
+ navigation: {
+ nextEl: ".swiper-button-next",
+ prevEl: ".swiper-button-prev",
+ },
+ speed: 800,
+ thumbs: {
+ swiper: swiperThumbs,
+ },
+ });
+
+ $productImg.on('click', function () {
+ if (!thumbs.classList.contains('swiper-initialized')) {
+ swiperThumbs.init();
+ swiperMain.init();
+ }
+ sliderModal.classList.add('open');
+ $image = $(this).parents('.productPage__image');
+ swiperMain.slideTo($image.index() + 1, 0);
+ })
+});
diff --git a/html/content/js/Products/productattr.js b/html/content/js/Products/productattr.js new file mode 100644 index 0000000..d28c0a7 --- /dev/null +++ b/html/content/js/Products/productattr.js @@ -0,0 +1,11 @@ +$$plugins.define('productattr', function (element, options) {
+ const selected = element.querySelector('.productAttr__selected');
+ element.querySelectorAll('.radiobutton__input').forEach(input => {
+ if (input.checked) {
+ selected.innerHTML = input.parentElement.querySelector('.radiobutton__text').innerText;
+ }
+ input.addEventListener('change', function (event) {
+ selected.innerHTML = event.target.parentElement.querySelector('.radiobutton__text').innerText;
+ });
+ })
+});
diff --git a/html/content/js/Sliders/productsSlider.js b/html/content/js/Sliders/productsSlider.js new file mode 100644 index 0000000..cc043b9 --- /dev/null +++ b/html/content/js/Sliders/productsSlider.js @@ -0,0 +1,45 @@ +// Modules included:
+// 'virtual',
+// 'mousewheel',
+// 'navigation',
+// 'pagination',
+// 'zoom',
+// 'lazy',
+// 'autoplay',
+// 'thumbs',
+// 'manipulation',
+// 'effect-fade',
+
+$$plugins.define('productsSlider', ['swiper-bundle'], function (element, options, Swiper) {
+ if (element.childNodes.length == 0) {
+ return;
+ }
+
+ // init Swiper
+ const swiper = new Swiper(element, {
+ breakpoints: {
+ 0: {
+ slidesPerGroup: 1
+ },
+ 768: {
+ slidesPerGroup: 2
+ },
+ 1024: {
+ slidesPerGroup: 3
+ }
+ },
+ navigation: {
+ nextEl: element.querySelector('.swiper-button-next'),
+ prevEl: element.querySelector('.swiper-button-prev'),
+ },
+ pagination: {
+ el: element.querySelector('.swiper-pagination'),
+ type: 'bullets',
+ clickable: 'true'
+ },
+ slidesPerGroup: 3,
+ slidesPerView: 'auto',
+ spaceBetween: 16,
+ speed: 1000
+ });
+});
diff --git a/html/content/js/Sliders/slider.js b/html/content/js/Sliders/slider.js new file mode 100644 index 0000000..a9f5824 --- /dev/null +++ b/html/content/js/Sliders/slider.js @@ -0,0 +1,42 @@ +// Modules included:
+// 'virtual',
+// 'mousewheel',
+// 'navigation',
+// 'pagination',
+// 'zoom',
+// 'lazy',
+// 'autoplay',
+// 'thumbs',
+// 'manipulation',
+// 'effect-fade',
+
+$$plugins.define('slider', ['swiper-bundle'], function (element, options, Swiper) {
+ if (element.childNodes.length == 0) {
+ return;
+ }
+
+ // init Swiper
+ const swiper = new Swiper(element, {
+ autoHeight: options.autoHeight ? options.autoHeight : false,
+ breakpoints: options.breakpoints,
+ centerInsufficientSlides: options.centerInsufficientSlides ? options.centerInsufficientSlides : false,
+ centeredSlides: options.centeredSlides ? options.centeredSlides : false,
+ direction: options.direction ? options.direction : 'horizontal',
+ effect: options.effect ? options.effect : 'slide',
+ loop: options.loop ? options.loop : false,
+ navigation: {
+ nextEl: element.querySelector('.swiper-button-next'),
+ prevEl: element.querySelector('.swiper-button-prev'),
+ },
+ pagination: {
+ el: element.querySelector('.swiper-pagination'),
+ type: 'bullets',
+ clickable: 'true'
+ },
+ slidesPerGroup: options.slidesPerGroup ? options.slidesPerGroup : 1,
+ slidesPerView: options.slidesPerView ? options.slidesPerView : 1,
+ spaceBetween: options.spaceBetween ? options.spaceBetween : 0,
+ speed: options.speed ? options.speed : 800,
+ watchSlidesProgress: true
+ });
+});
diff --git a/html/content/js/Utils/Event.js b/html/content/js/Utils/Event.js new file mode 100644 index 0000000..7a5ada8 --- /dev/null +++ b/html/content/js/Utils/Event.js @@ -0,0 +1,13 @@ +define(function () {
+ return function () {
+ var handlers = [];
+ this.bind = function (handler) {
+ handlers.push(handler);
+ }
+ this.trigger = function (_this, arguments) {
+ for (var i = 0; i < handlers.length; i++) {
+ handlers[i].apply(_this, arguments);
+ }
+ }
+ }
+});
\ No newline at end of file diff --git a/html/content/js/Utils/EventUtils.js b/html/content/js/Utils/EventUtils.js new file mode 100644 index 0000000..21a1ce9 --- /dev/null +++ b/html/content/js/Utils/EventUtils.js @@ -0,0 +1,75 @@ +(function(){
+ var _ = {};
+ _.now = Date.now || function(){
+ return new Date().getTime();
+ };
+ // Returns a function, that, when invoked, will only be triggered at most once
+ // during a given window of time. Normally, the throttled function will run
+ // as much as it can, without ever going more than once per `wait` duration;
+ // but if you'd like to disable the execution on the leading edge, pass
+ // `{leading: false}`. To disable execution on the trailing edge, ditto.
+ _.throttle = function(func, wait, options) {
+ var context, args, result;
+ var timeout = null;
+ var previous = 0;
+ if (!options) options = {};
+ var later = function() {
+ previous = options.leading === false ? 0 : _.now();
+ timeout = null;
+ result = func.apply(context, args);
+ if (!timeout) context = args = null;
+ };
+ return function() {
+ var now = _.now();
+ if (!previous && options.leading === false) previous = now;
+ var remaining = wait - (now - previous);
+ context = this;
+ args = arguments;
+ if (remaining <= 0 || remaining > wait) {
+ if (timeout) {
+ clearTimeout(timeout);
+ timeout = null;
+ }
+ previous = now;
+ result = func.apply(context, args);
+ if (!timeout) context = args = null;
+ } else if (!timeout && options.trailing !== false) {
+ timeout = setTimeout(later, remaining);
+ }
+ return result;
+ };
+ };
+ // Returns a function, that, as long as it continues to be invoked, will not
+ // be triggered. The function will be called after it stops being called for
+ // N milliseconds. If `immediate` is passed, trigger the function on the
+ // leading edge, instead of the trailing.
+ _.debounce = function(func, wait, immediate) {
+ var timeout, args, context, timestamp, result;
+ var later = function() {
+ var last = _.now() - timestamp;
+ if (last < wait && last >= 0) {
+ timeout = setTimeout(later, wait - last);
+ } else {
+ timeout = null;
+ if (!immediate) {
+ result = func.apply(context, args);
+ if (!timeout) context = args = null;
+ }
+ }
+ };
+ return function() {
+ context = this;
+ args = arguments;
+ timestamp = _.now();
+ var callNow = immediate && !timeout;
+ if (!timeout) timeout = setTimeout(later, wait);
+ if (callNow) {
+ result = func.apply(context, args);
+ context = args = null;
+ }
+ return result;
+ };
+ };
+
+ window.EventUtils = _;
+}());
\ No newline at end of file diff --git a/html/content/js/Utils/apiready.js b/html/content/js/Utils/apiready.js new file mode 100644 index 0000000..17f1ad4 --- /dev/null +++ b/html/content/js/Utils/apiready.js @@ -0,0 +1,15 @@ +define(function () {
+ return function ($element, name) {
+ return new Promise(function (resolve, reject) {
+ var api = $element.data(name);
+ if (api) {
+ resolve(api);
+ }
+ else {
+ $element.one(name + '.ready', function () {
+ resolve($element.data(name));
+ });
+ }
+ });
+ };
+});
\ No newline at end of file diff --git a/html/content/js/Utils/confirm.js b/html/content/js/Utils/confirm.js new file mode 100644 index 0000000..ef59cbb --- /dev/null +++ b/html/content/js/Utils/confirm.js @@ -0,0 +1,27 @@ +define(function () {
+ return function (options, callback) {
+ var $dialog = $(options.template instanceof jQuery ? options.template.html() : options.template);
+ $dialog.hide();
+ $('body').append($dialog);
+ $dialog.parseAttributePlugins();
+
+ function close() {
+ $dialog.remove();
+ }
+
+ function open() {
+ $dialog.show();
+ }
+
+ open();
+ $dialog.find('.button.yes').click(function (e) {
+ e.preventDefault();
+ close();
+ callback();
+ });
+ $dialog.find('.button.no').click(function (e) {
+ e.preventDefault();
+ close();
+ });
+ };
+});
\ No newline at end of file diff --git a/html/content/js/Utils/debounce.js b/html/content/js/Utils/debounce.js new file mode 100644 index 0000000..f81d9a5 --- /dev/null +++ b/html/content/js/Utils/debounce.js @@ -0,0 +1,16 @@ +define('debounce', function () {
+ return function (func, wait, immediate) {
+ var timeout;
+ return function () {
+ var context = this, args = arguments;
+ var later = function () {
+ timeout = null;
+ if (!immediate) func.apply(context, args);
+ };
+ var callNow = immediate && !timeout;
+ clearTimeout(timeout);
+ timeout = setTimeout(later, wait);
+ if (callNow) func.apply(context, args);
+ };
+ };
+});
diff --git a/html/content/js/Utils/defineApi.js b/html/content/js/Utils/defineApi.js new file mode 100644 index 0000000..3215714 --- /dev/null +++ b/html/content/js/Utils/defineApi.js @@ -0,0 +1,9 @@ +define(function () {
+ return function ($element, name, api) {
+ if (typeof (api) === 'undefined' || !api) {
+ throw 'undefined api';
+ }
+ $element.data(name, api);
+ $element.trigger(name + '.ready');
+ };
+});
\ No newline at end of file diff --git a/html/content/js/Utils/destroyevent.js b/html/content/js/Utils/destroyevent.js new file mode 100644 index 0000000..e6fe48a --- /dev/null +++ b/html/content/js/Utils/destroyevent.js @@ -0,0 +1,11 @@ +define(function () {
+ (function ($) {
+ $.event.special.destroyed = {
+ remove: function (o) {
+ if ((o.handler && o.type !== 'destroyed')) {
+ o.handler()
+ }
+ }
+ }
+ })(jQuery)
+});
\ No newline at end of file diff --git a/html/content/js/Utils/dom.js b/html/content/js/Utils/dom.js new file mode 100644 index 0000000..78f3562 --- /dev/null +++ b/html/content/js/Utils/dom.js @@ -0,0 +1,68 @@ +define(function () {
+ const reduce = (elements, fn, initialValue) => {
+ return Array.prototype.reduce.call(elements, fn, initialValue);
+ }
+
+ const forEach = (elements, fn) => {
+ Array.prototype.forEach.call(elements, fn);
+ }
+ const map = (elements, fn) => {
+ return Array.prototype.map.call(elements, fn);
+ }
+
+ const replace = (toReplace, replacement) => {
+ var parentElement = toReplace.parentElement
+ if (parentElement) {
+ parentElement.replaceChild(replacement, toReplace);
+ }
+ }
+
+ const matches = (element, selector) => {
+ var m = element.matches
+ || Element.prototype.matchesSelector
+ || Element.prototype.mozMatchesSelector
+ || Element.prototype.msMatchesSelector
+ || Element.prototype.oMatchesSelector
+ || Element.prototype.webkitMatchesSelector;
+ return m.call(element, selector);
+ }
+
+ const closest = (element, selector) => {
+ while (element) {
+ if (matches(element, selector)) {
+ return element;
+ } else {
+ element = element.parentElement;
+ }
+ }
+ return null;
+ }
+ const isFunction = (input) => (typeof input === "function");
+ const dispatchEvent = (eventName, data) => {
+ let event;
+ if (window.CustomEvent && isFunction(window.CustomEvent)) {
+ event = new CustomEvent(eventName, { detail: data, cancelable: true, bubbles: false });
+ } else {
+ event = document.createEvent('CustomEvent');
+ event.initCustomEvent(eventName, false, true, data);
+ }
+ return window.document.dispatchEvent(event);
+ }
+
+ const parseHtml = (htmlString) => {
+ const c = document.createElement('div');
+ c.innerHTML = htmlString.trim();
+ return c.firstChild;
+ }
+
+ return {
+ dispatchEvent,
+ closest,
+ matches,
+ reduce,
+ map,
+ forEach,
+ replace,
+ parseHtml
+ };
+});
\ No newline at end of file diff --git a/html/content/js/Utils/domHelper.js b/html/content/js/Utils/domHelper.js new file mode 100644 index 0000000..f36ab1a --- /dev/null +++ b/html/content/js/Utils/domHelper.js @@ -0,0 +1,375 @@ +define(function () {
+
+ function isElement(obj) {
+ //instanceof fails for elements that have been created by another document (iframe case)
+ //in that case we check other properties existing in all element nodes
+ return obj instanceof HTMLElement || ((typeof obj === "object") &&
+ (obj.nodeType === 1) && (typeof obj.style === "object") &&
+ (typeof obj.ownerDocument === "object"));
+ }
+
+ let slideUp = (target, duration = 500, callback = null) => {
+ target.style.transitionProperty = 'height, margin, padding';
+ target.style.transitionDuration = duration + 'ms';
+ target.style.boxSizing = 'border-box';
+ target.style.height = target.offsetHeight + 'px';
+ target.offsetHeight;
+ target.style.overflow = 'hidden';
+ target.style.height = 0;
+ target.style.paddingTop = 0;
+ target.style.paddingBottom = 0;
+ target.style.marginTop = 0;
+ target.style.marginBottom = 0;
+ window.setTimeout(() => {
+ target.style.display = 'none';
+ target.style.removeProperty('height');
+ target.style.removeProperty('padding-top');
+ target.style.removeProperty('padding-bottom');
+ target.style.removeProperty('margin-top');
+ target.style.removeProperty('margin-bottom');
+ target.style.removeProperty('overflow');
+ target.style.removeProperty('transition-duration');
+ target.style.removeProperty('transition-property');
+ if (callback) {
+ callback();
+ }
+ }, duration);
+ }
+
+ let slideDown = (target, duration = 500, callback = null) => {
+ target.style.removeProperty('display');
+ let display = window.getComputedStyle(target).display;
+
+ if (display === 'none')
+ display = 'block';
+
+ target.style.display = display;
+ let height = target.offsetHeight;
+ target.style.overflow = 'hidden';
+ target.style.height = 0;
+ target.style.paddingTop = 0;
+ target.style.paddingBottom = 0;
+ target.style.marginTop = 0;
+ target.style.marginBottom = 0;
+ target.offsetHeight;
+ target.style.boxSizing = 'border-box';
+ target.style.transitionProperty = "height, margin, padding";
+ target.style.transitionDuration = duration + 'ms';
+ target.style.height = height + 'px';
+ target.style.removeProperty('padding-top');
+ target.style.removeProperty('padding-bottom');
+ target.style.removeProperty('margin-top');
+ target.style.removeProperty('margin-bottom');
+ window.setTimeout(() => {
+ target.style.removeProperty('height');
+ target.style.removeProperty('overflow');
+ target.style.removeProperty('transition-duration');
+ target.style.removeProperty('transition-property');
+ if (callback) {
+ callback();
+ }
+ }, duration);
+ }
+
+ var slideToggle = (target, duration = 500, callback = null) => {
+ if (window.getComputedStyle(target).display === 'none') {
+ return slideDown(target, duration, callback);
+ } else {
+ return slideUp(target, duration, callback);
+ }
+ }
+
+ function resolveSelector(selector, context) {
+ if (typeof (selector) !== "string") {
+ if (context) {
+ throw 'Context is allowed only when selector is a string.';
+ }
+ if (Array.isArray(selector)) {
+ return selector;
+ }
+ if (isElement(selector)) {
+ return [selector];
+ }
+
+ throw 'Selector can either be a string or an array';
+ }
+ if (!context) {
+ return document.querySelectorAll(selector);
+ }
+ if (typeof (context) == "string") {
+ return resolveSelector(selector).filter(element => element.matches(selector));
+ }
+ else if (Array.isArray(context)) {
+ return context.filter(element => element.matches(selector));
+ }
+ else if (isElement(context)) {
+ return context.querySelectorAll(selector);
+ }
+ else {
+ throw 'Unknown context type: ' + typeof (context) + ". Not a string, array or HTMLElement.";
+ }
+ }
+
+ var factory = (target, context) => new domHelper(target, context);
+ function domHelper(target, context) {
+ this.elements = Array.from(resolveSelector(target, context));
+ this.on = function (event, callback) {
+ for (let i = 0; i < this.elements.length; i++) {
+ this.elements[i].addEventListener(event, function (e) {
+ callback.apply(e.target, arguments);
+ });
+ }
+ return this;
+ }
+ this.parent = function (selector) {
+ if (!selector) {
+ return factory(
+ this.elements.map(e => e.parentElement).filter(e => e)
+ );
+ }
+ return factory(
+ this.elements.map(element => {
+ do {
+ if (element.parentElement.matches(selector)) {
+ return element.parentElement;
+ }
+ element = element.parentElement;
+
+ } while (element.parentElement);
+ return null;
+ }).filter(e => e)
+ );
+ }
+ this.parents = function (selector) {
+ var parents = this.elements.map(e => {
+ var r = [];
+ while (e.parentElement) {
+ r.push(e.parentElement);
+ e = e.parentElement;
+ }
+ return r;
+ }).reduce((acc, curVal) => {
+ return acc.concat(curVal)
+ }).filter(e => e);
+
+ if (!selector) {
+ return factory(parents);
+ }
+ return factory(selector, parents);
+ }
+ this.find = function (selector) {
+ return factory(this.elements.map(e => {
+ return factory(selector, e).elements;
+ }).reduce((acc, curVal) => {
+ return acc.concat(curVal)
+ }));
+ }
+ this.show = function () {
+ this.each(e => e.style.display = "block");
+ }
+ this.hide = function () {
+ this.each(e => e.style.display = "none");
+ }
+ this.innerWidth = function () {
+ var element = this.elements[0];
+ return parseInt(window.getComputedStyle(element).width);
+ }
+ this.toggle = function () {
+ this.each(e => {
+ if ((e.offsetParent === null)) // hidden
+ {
+ e.style.display = "block";
+ }
+ else {
+ e.style.display = "none";
+ }
+ });
+ }
+ this.each = function (callback) {
+ this.elements.forEach(callback);
+ return this;
+ }
+ this.scroll = function () {
+ this.each(element => element.scroll.apply(element, arguments));
+ return this;
+ }
+ this.addClass = function (cssClass) {
+ if (!cssClass) {
+ return;
+ }
+ var classes = cssClass.split(' ');
+ this.elements.forEach(element => {
+ classes.forEach(cssClass => {
+ element.classList.add(cssClass);
+ });
+ });
+ return this;
+ }
+ this.removeClass = function (cssClass) {
+ if (!cssClass) {
+ return;
+ }
+ var classes = cssClass.split(' ');
+ this.elements.forEach(element => {
+ classes.forEach(cssClass => {
+ element.classList.remove(cssClass);
+ });
+ });
+ return this;
+ }
+ this.toggleClass = function (cssClass) {
+ if (!cssClass) {
+ return;
+ }
+ var classes = cssClass.split(' ');
+ this.elements.forEach(element => {
+ classes.forEach(cssClass => {
+ element.classList.toggle(cssClass);
+ });
+ });
+ return this;
+ }
+ this.is = function (selector) {
+ return factory(selector, this.elements).elements.length > 0;
+ }
+ this.not = function (exclude) {
+ if (typeof (exclude) == "string") {
+ return factory(this.elements.filter(e => !e.matches(exclude)));
+ }
+ else if (Array.isArray(exclude)) {
+ return factory(this.elements.filter(e => exclude.indexOf(e) == -1));
+ }
+ else if (isElement(exclude)) {
+ return factory(this.elements.filter(e => e != exclude));
+ }
+ else if (exclude instanceof domHelper) {
+ return factory(this.elements.filter(e => exclude.elements.indexOf(e) == -1));
+ }
+ else {
+ throw 'Unknown exclude type: ' + typeof (exclude) + ". Not a string, array or HTMLElement or domHelper.";
+ }
+ }
+ this.get = (index) => this.elements[index];
+ this.length = this.elements.length;
+ this.siblings = function (selector) {
+ var next = this.next(selector);
+ var prev = this.prev(selector);
+ return factory(prev.elements.concat(next.elements));
+ }
+ this.next = function (selector) {
+ var siblings = this.elements.map(e => {
+ var r = [];
+ while (e.nextElementSibling) {
+ r.push(e.nextElementSibling);
+ e = e.nextElementSibling;
+ }
+ return r;
+ }).reduce((acc, curVal) => {
+ return acc.concat(curVal)
+ }).filter(e => e);
+
+ if (!selector) {
+ return factory(siblings);
+ }
+ return factory(selector, siblings);
+ }
+ this.prev = function (selector) {
+ var siblings = this.elements.map(e => {
+ var r = [];
+ while (e.previousElementSibling) {
+ r.push(e.previousElementSibling);
+ e = e.previousElementSibling;
+ }
+ return r;
+ }).reduce((acc, curVal) => {
+ return acc.concat(curVal)
+ }).filter(e => e);
+
+ if (!selector) {
+ return factory(siblings);
+ }
+ return factory(selector, siblings);
+ }
+ this.index = function () {
+ var items = [];
+ this.prev().each(function (e) {
+ items.push(e);
+ });
+ items.push(this.get(0));
+ this.next().each(function (e) {
+ items.push(e);
+ });
+ return items.indexOf(this.get(0));
+ }
+ this.slideDown = function (duration, callback) {
+ return this.each(function (e) {
+ slideDown(e, duration, callback);
+ });
+ }
+ this.slideUp = function (duration, callback) {
+ return this.each(function (e) {
+ slideUp(e, duration, callback);
+ });
+ }
+ this.slideToggle = function (duration, callback) {
+ return this.each(function (e) {
+ slideToggle(e, duration, callback);
+ });
+ }
+ this.removeAttr = function (attribute) {
+ this.each(e => e.removeAttribute(attribute));
+ }
+ this.hasClass = function (cssClass) {
+ if (!cssClass) {
+ return;
+ }
+ return new RegExp('(\\s|^)' + cssClass + '(\\s|$)').test(this.get(0).className);
+ }
+ this.val = function (inputValue) {
+ if (typeof (inputValue) === 'undefined') {
+ return this.elements[0].value;
+ }
+ return this.each(function (e) {
+ e.value = inputValue;
+ });
+ }
+ this.data = function (attribute, inputValue) {
+ if (typeof (inputValue) === 'undefined') {
+ return this.elements[0].dataset[attribute];
+ }
+ return this.each(function (e) {
+ e.dataset[attribute] = inputValue;
+ });
+ }
+ this.text = function (inputValue) {
+ if (typeof (inputValue) === 'undefined') {
+ return this.elements[0].innerText;
+ }
+ return this.each(function (e) {
+ e.innerText = inputValue;
+ });
+ }
+ this.contains = function (element) {
+ return this.elements.indexOf(element) >= 0;
+ }
+
+ this.trigger = function (eventName) {
+
+ if ("createEvent" in document) {
+ var evt = document.createEvent("HTMLEvents");
+ evt.initEvent(eventName, false, true);
+ return this.each(function (e) {
+ e.dispatchEvent(evt);
+ });
+ }
+ else {
+ return this.each(function (e) {
+ e.fireEvent("on" + eventName);
+ });
+
+ }
+ }
+ }
+
+ return factory;
+});
\ No newline at end of file diff --git a/html/content/js/Utils/enabled.js b/html/content/js/Utils/enabled.js new file mode 100644 index 0000000..658b2dc --- /dev/null +++ b/html/content/js/Utils/enabled.js @@ -0,0 +1,6 @@ +define(function () {
+ $.fn.enabled = function (e) {
+ $(this).prop('disabled', !e);
+ $(this).trigger('enabled:change', e);
+ };
+});
\ No newline at end of file diff --git a/html/content/js/Utils/getApis.js b/html/content/js/Utils/getApis.js new file mode 100644 index 0000000..46788a6 --- /dev/null +++ b/html/content/js/Utils/getApis.js @@ -0,0 +1,17 @@ +define(['apiReady', 'whenAll'], function (apiReady, whenAll) {
+ return function ($elements, name) {
+ var result = [];
+ var d = $.Deferred();
+ var p = $elements.map(function () {
+ var $element = $(this);
+ return apiReady($element, name).then(function (api) {
+ result.push({ api: api, $element: $element });
+ });
+ });
+ whenAll(p).then(function () {
+ d.resolve(result);
+ });
+
+ return d;
+ };
+});
\ No newline at end of file diff --git a/html/content/js/Utils/throttle.js b/html/content/js/Utils/throttle.js new file mode 100644 index 0000000..ccfc9a7 --- /dev/null +++ b/html/content/js/Utils/throttle.js @@ -0,0 +1,15 @@ +define(function () {
+ return function (func, limit) {
+ var timeout;
+ var inThrottle;
+ return function () {
+ var context = this, args = arguments;
+ if (!inThrottle) {
+ func.apply(context, args);
+ inThrottle = true;
+ }
+ setTimeout(() => inThrottle = false, limit);
+
+ };
+ };
+});
diff --git a/html/content/js/Utils/whenAll.js b/html/content/js/Utils/whenAll.js new file mode 100644 index 0000000..8d1c3e2 --- /dev/null +++ b/html/content/js/Utils/whenAll.js @@ -0,0 +1,13 @@ +define(function () {
+ return function (deferreds) {
+ return $.Deferred(function (def) {
+ $.when.apply(jQuery, deferreds).then(
+ function () {
+ def.resolveWith(this, [Array.prototype.slice.call(arguments)]);
+ },
+ function () {
+ def.rejectWith(this, [Array.prototype.slice.call(arguments)]);
+ });
+ });
+ };
+});
diff --git a/html/content/js/Wishlist/wishlistbutton.js b/html/content/js/Wishlist/wishlistbutton.js new file mode 100644 index 0000000..bde43c1 --- /dev/null +++ b/html/content/js/Wishlist/wishlistbutton.js @@ -0,0 +1,25 @@ +$$plugins.define('wishlistbutton', ['domHelper'], function (element, options, $) {
+ const $button = $(element).find('.listsClose');
+
+ $button.on('click', function () {
+ if (window.innerWidth > 768) {
+ $button.siblings('.listsBlock').slideToggle(300, function () {
+ $(element).toggleClass('open');
+ $button.siblings('.listsBlock').removeAttr('style');
+ });
+ } else {
+ $(element).toggleClass('open');
+ }
+ });
+
+ document.addEventListener('click', function (event) {
+ if (!$(element).hasClass('open') || element == event.target || $(event.target).parents().contains(element)) {
+ return;
+ }
+ $button.siblings('.listsBlock').slideUp(300, function () {
+ $(element).removeClass('open');
+ $button.siblings('.listsBlock').removeAttr('style');
+ });
+ });
+
+});
\ No newline at end of file |
