From e8799a4e3ac00ec0769f0dae9b476217e65f3485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ste=CC=A8pien=CC=81?= Date: Mon, 9 Oct 2023 22:53:31 +0200 Subject: [PATCH 01/43] top menu removed jquery --- _dev/js/theme/components/TopMenu.js | 30 ------------- _dev/js/theme/components/cart/block-cart.js | 48 --------------------- _dev/js/theme/components/useTopMenu.js | 46 ++++++++++++++++++++ _dev/js/theme/index.js | 11 ++--- 4 files changed, 50 insertions(+), 85 deletions(-) delete mode 100644 _dev/js/theme/components/TopMenu.js delete mode 100644 _dev/js/theme/components/cart/block-cart.js create mode 100644 _dev/js/theme/components/useTopMenu.js diff --git a/_dev/js/theme/components/TopMenu.js b/_dev/js/theme/components/TopMenu.js deleted file mode 100644 index afb9bdb2..00000000 --- a/_dev/js/theme/components/TopMenu.js +++ /dev/null @@ -1,30 +0,0 @@ -import $ from 'jquery'; - -export default class TopMenu { - constructor(el) { - this.$el = $(el); - } - - init() { - const self = this; - self.$el.hoverIntent({ - over: self.toggleClassSubMenu, - out: self.toggleClassSubMenu, - selector: ' > li', - timeout: 300, - }); - } - - toggleClassSubMenu() { - const $item = $(this); - let expanded = $item.attr('aria-expanded'); - - if (typeof expanded !== 'undefined') { - expanded = expanded.toLowerCase() === 'true'; - $item.toggleClass('main-menu__item--active').attr('aria-expanded', !expanded); - $('.main-menu__sub', $item) - .attr('aria-expanded', !expanded) - .attr('aria-hidden', expanded); - } - } -} diff --git a/_dev/js/theme/components/cart/block-cart.js b/_dev/js/theme/components/cart/block-cart.js deleted file mode 100644 index 7166f873..00000000 --- a/_dev/js/theme/components/cart/block-cart.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - */ -import prestashop from 'prestashop'; -import $ from 'jquery'; - -prestashop.blockcart = prestashop.blockcart || {}; - -prestashop.blockcart.showModal = (html) => { - function getBlockCartModal() { - return $('#blockcart-modal'); - } - - const $blockCartModal = getBlockCartModal(); - - if ($blockCartModal.length) { - $blockCartModal.hide(); - } - - $('body').append(html); - - getBlockCartModal() - .modal('show') - .on('hidden.bs.modal', (e) => { - $(e.currentTarget).remove(); - }); -}; diff --git a/_dev/js/theme/components/useTopMenu.js b/_dev/js/theme/components/useTopMenu.js new file mode 100644 index 00000000..0404509c --- /dev/null +++ b/_dev/js/theme/components/useTopMenu.js @@ -0,0 +1,46 @@ +import useEvent from './event/useEvent'; + +const useTopMenu = (selector) => { + const { on, off } = useEvent(); + const menuElement = document.querySelector(selector); + const DOM_SELECTORS = { + SUB_ELEMENTS: '.main-menu__item--top', + SUB_MENU: '.main-menu__sub', + }; + const ITEM_ACTIVE = 'main-menu__item--active'; + + + const toggleSubMenu = (e) => { + const { currentTarget } = e; + const { SUB_MENU } = DOM_SELECTORS; + const expanded = currentTarget.getAttribute('aria-expanded'); + const isExpanded = expanded && expanded.toLowerCase() === 'true'; + const subMenu = currentTarget.querySelector(SUB_MENU); + + currentTarget.classList.toggle(ITEM_ACTIVE); + + if (subMenu) { + currentTarget.setAttribute('aria-expanded', !isExpanded); + + subMenu.setAttribute('aria-hidden', isExpanded); + subMenu.setAttribute('aria-expanded', !isExpanded); + + } + } + + const init = () => { + debugger + const { SUB_ELEMENTS } = DOM_SELECTORS; + + off(menuElement, 'mouseenter', SUB_ELEMENTS, toggleSubMenu); + off(menuElement, 'mouseleave', SUB_ELEMENTS, toggleSubMenu); + on(menuElement, 'mouseenter', SUB_ELEMENTS, toggleSubMenu); + on(menuElement, 'mouseleave', SUB_ELEMENTS, toggleSubMenu); + } + + return { + init + } +} + +export default useTopMenu; diff --git a/_dev/js/theme/index.js b/_dev/js/theme/index.js index df950b45..e73daa7f 100644 --- a/_dev/js/theme/index.js +++ b/_dev/js/theme/index.js @@ -5,8 +5,6 @@ import EventEmitter from 'events'; import '@js/theme/core'; import '@js/theme/vendors/bootstrap/bootstrap-imports'; -import 'bootstrap-touchspin'; -import 'jquery-hoverintent'; import '@js/theme/components/dynamic-bootstrap-components'; import bsCustomFileInput from 'bs-custom-file-input'; import '@js/theme/components/sliders'; @@ -14,7 +12,7 @@ import '@js/theme/components/responsive'; import '@js/theme/components/customer'; import '@js/theme/components/quickview'; import '@js/theme/components/product'; -import '@js/theme/components/cart/block-cart'; +import useTopMenu from './components/useTopMenu'; /* eslint-enable */ import prestashop from 'prestashop'; @@ -26,7 +24,6 @@ for (const i in EventEmitter.prototype) { } import usePasswordPolicy from '@js/theme/components/password/usePasswordPolicy'; import Form from '@js/theme/components/form'; -import TopMenu from '@js/theme/components/TopMenu'; import PageLazyLoad from '@js/theme/components/Lazyload'; import PageLoader from '@js/theme/components/PageLoader'; import useStickyElement from '@js/theme/components/useStickyElement'; @@ -61,14 +58,14 @@ function initStickyHeader() { } $(() => { + const { init: initTopMenu } = useTopMenu('.js-main-menu'); + initStickyHeader(); accLinksTriggerActive(); Form.init(); bsCustomFileInput.init(); - const topMenu = new TopMenu('#_desktop_top_menu .js-main-menu'); usePasswordPolicy('.field-password-policy'); - - topMenu.init(); + initTopMenu(); $('.js-select-link').on('change', ({ target }) => { window.location.href = $(target).val(); From bc6dd1c9b535a7b18a1f0e04a9e958856d0a4e70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ste=CC=A8pien=CC=81?= Date: Mon, 9 Oct 2023 22:57:55 +0200 Subject: [PATCH 02/43] Lint fix --- _dev/js/theme/components/useTopMenu.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/_dev/js/theme/components/useTopMenu.js b/_dev/js/theme/components/useTopMenu.js index 0404509c..da512c3d 100644 --- a/_dev/js/theme/components/useTopMenu.js +++ b/_dev/js/theme/components/useTopMenu.js @@ -9,7 +9,6 @@ const useTopMenu = (selector) => { }; const ITEM_ACTIVE = 'main-menu__item--active'; - const toggleSubMenu = (e) => { const { currentTarget } = e; const { SUB_MENU } = DOM_SELECTORS; @@ -24,23 +23,21 @@ const useTopMenu = (selector) => { subMenu.setAttribute('aria-hidden', isExpanded); subMenu.setAttribute('aria-expanded', !isExpanded); - } - } + }; const init = () => { - debugger const { SUB_ELEMENTS } = DOM_SELECTORS; off(menuElement, 'mouseenter', SUB_ELEMENTS, toggleSubMenu); off(menuElement, 'mouseleave', SUB_ELEMENTS, toggleSubMenu); on(menuElement, 'mouseenter', SUB_ELEMENTS, toggleSubMenu); on(menuElement, 'mouseleave', SUB_ELEMENTS, toggleSubMenu); - } + }; return { - init - } -} + init, + }; +}; export default useTopMenu; From 3edea9aa8c0000fd362e10186f9a9911139821c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ste=CC=A8pien=CC=81?= Date: Mon, 9 Oct 2023 22:58:07 +0200 Subject: [PATCH 03/43] relative import path --- _dev/js/theme/index.js | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/_dev/js/theme/index.js b/_dev/js/theme/index.js index e73daa7f..db2653f4 100644 --- a/_dev/js/theme/index.js +++ b/_dev/js/theme/index.js @@ -4,29 +4,28 @@ import EventEmitter from 'events'; import '@js/theme/core'; -import '@js/theme/vendors/bootstrap/bootstrap-imports'; -import '@js/theme/components/dynamic-bootstrap-components'; +import './vendors/bootstrap/bootstrap-imports'; +import './components/dynamic-bootstrap-components'; import bsCustomFileInput from 'bs-custom-file-input'; -import '@js/theme/components/sliders'; -import '@js/theme/components/responsive'; -import '@js/theme/components/customer'; -import '@js/theme/components/quickview'; -import '@js/theme/components/product'; +import './components/sliders'; +import './components/responsive'; +import './components/customer'; +import './components/quickview'; +import './components/product'; +import prestashop from 'prestashop'; import useTopMenu from './components/useTopMenu'; /* eslint-enable */ -import prestashop from 'prestashop'; - /* eslint-disable */ // "inherit" EventEmitter for (const i in EventEmitter.prototype) { prestashop[i] = EventEmitter.prototype[i]; } -import usePasswordPolicy from '@js/theme/components/password/usePasswordPolicy'; -import Form from '@js/theme/components/form'; -import PageLazyLoad from '@js/theme/components/Lazyload'; -import PageLoader from '@js/theme/components/PageLoader'; -import useStickyElement from '@js/theme/components/useStickyElement'; +import usePasswordPolicy from './components/password/usePasswordPolicy'; +import Form from './components/form'; +import PageLazyLoad from './components/Lazyload'; +import PageLoader from './components/PageLoader'; +import useStickyElement from './components/useStickyElement'; import httpRequestErrorHandler from './handler/error/httpRequestErrorHandler'; prestashop.pageLazyLoad = new PageLazyLoad({ From e9bdb2de06045c14e7e46cd75f02ee16849414a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ste=CC=A8pien=CC=81?= Date: Mon, 9 Oct 2023 23:16:10 +0200 Subject: [PATCH 04/43] customer account jquery removed --- _dev/js/theme/components/customer.js | 18 ---------- _dev/js/theme/components/customer/index.js | 34 +++++++++++++++++++ _dev/js/theme/components/header/index.js | 21 ++++++++++++ .../components/{ => header}/useTopMenu.js | 2 +- _dev/js/theme/components/useStickyElement.js | 9 +++-- _dev/js/theme/index.js | 31 ++--------------- 6 files changed, 65 insertions(+), 50 deletions(-) delete mode 100644 _dev/js/theme/components/customer.js create mode 100644 _dev/js/theme/components/customer/index.js create mode 100644 _dev/js/theme/components/header/index.js rename _dev/js/theme/components/{ => header}/useTopMenu.js (96%) diff --git a/_dev/js/theme/components/customer.js b/_dev/js/theme/components/customer.js deleted file mode 100644 index 5009226a..00000000 --- a/_dev/js/theme/components/customer.js +++ /dev/null @@ -1,18 +0,0 @@ -import $ from 'jquery'; - -function initRmaItemSelector() { - $(`${prestashop.selectors.order.returnForm} table thead input[type=checkbox]`).on('click', ({ currentTarget }) => { - const checked = $(currentTarget).prop('checked'); - $(`${prestashop.selectors.order.returnForm} table tbody input[type=checkbox]`).each((_, checkbox) => { - $(checkbox).prop('checked', checked); - }); - }); -} - -function setupCustomerScripts() { - if ($('body#order-detail')) { - initRmaItemSelector(); - } -} - -$(document).ready(setupCustomerScripts); diff --git a/_dev/js/theme/components/customer/index.js b/_dev/js/theme/components/customer/index.js new file mode 100644 index 00000000..9f1aa423 --- /dev/null +++ b/_dev/js/theme/components/customer/index.js @@ -0,0 +1,34 @@ +import DOMReady from "../../utils/DOMReady"; +import $ from "jquery"; + +const initCustomerLinksTriggerActive = () => { + const url = window.location.pathname; + const customerLinks = document.querySelectorAll('.js-customer-links a'); + + customerLinks.forEach((el) => { + if (el.getAttribute('href').indexOf(url) !== -1) { + el.classList.add('active'); + } + }); +} + +const initRmaForm = () => { + const returnForm = document.querySelector(prestashop.selectors.order.returnForm); + + if (!returnForm) { + return; + } + + returnForm.querySelector('thead input[type=checkbox]').addEventListener('click', ({ currentTarget }) => { + const checked = currentTarget.checked; + returnForm.querySelectorAll('tbody input[type=checkbox]').forEach((checkbox) => { + checkbox.checked = checked; + }); + }); +} + + +DOMReady(() => { + initCustomerLinksTriggerActive(); + initRmaForm(); +}) diff --git a/_dev/js/theme/components/header/index.js b/_dev/js/theme/components/header/index.js new file mode 100644 index 00000000..90b34e45 --- /dev/null +++ b/_dev/js/theme/components/header/index.js @@ -0,0 +1,21 @@ +import DOMReady from "../../utils/DOMReady"; +import useTopMenu from './useTopMenu'; +import useStickyElement from "../useStickyElement"; + +const initStickyHeader = () => { + const header = document.querySelector('.js-header-top'); + const headerWrapper = document.querySelector('.js-header-top-wrapper'); + + if (header && headerWrapper) { + const { init } = useStickyElement(header, headerWrapper); + + init(); + } +} + +DOMReady(() => { + const { init: initTopMenu } = useTopMenu('.js-main-menu'); + + initTopMenu(); + initStickyHeader(); +}); diff --git a/_dev/js/theme/components/useTopMenu.js b/_dev/js/theme/components/header/useTopMenu.js similarity index 96% rename from _dev/js/theme/components/useTopMenu.js rename to _dev/js/theme/components/header/useTopMenu.js index da512c3d..e8556369 100644 --- a/_dev/js/theme/components/useTopMenu.js +++ b/_dev/js/theme/components/header/useTopMenu.js @@ -1,4 +1,4 @@ -import useEvent from './event/useEvent'; +import useEvent from '../event/useEvent'; const useTopMenu = (selector) => { const { on, off } = useEvent(); diff --git a/_dev/js/theme/components/useStickyElement.js b/_dev/js/theme/components/useStickyElement.js index 19059948..dd7ef80a 100644 --- a/_dev/js/theme/components/useStickyElement.js +++ b/_dev/js/theme/components/useStickyElement.js @@ -1,4 +1,4 @@ -import debounce from '@js/theme/utils/debounce'; +import debounce from '../utils/debounce'; /** * Returns sticky element data @@ -65,11 +65,14 @@ export default (element, stickyWrapper, options = {}) => { } }; - window.addEventListener('scroll', debounce(handleSticky, debounceTime)); - handleSticky(); + const init = () => { + window.addEventListener('scroll', debounce(handleSticky, debounceTime)); + handleSticky(); + } return { getExtraOffsetTop, getIsSticky, + init, }; }; diff --git a/_dev/js/theme/index.js b/_dev/js/theme/index.js index db2653f4..c546b29e 100644 --- a/_dev/js/theme/index.js +++ b/_dev/js/theme/index.js @@ -2,18 +2,18 @@ import $ from 'jquery'; import EventEmitter from 'events'; -import '@js/theme/core'; +import './core/index'; import './vendors/bootstrap/bootstrap-imports'; import './components/dynamic-bootstrap-components'; import bsCustomFileInput from 'bs-custom-file-input'; +import './components/header/index'; +import './components/customer/index'; import './components/sliders'; import './components/responsive'; -import './components/customer'; import './components/quickview'; import './components/product'; import prestashop from 'prestashop'; -import useTopMenu from './components/useTopMenu'; /* eslint-enable */ /* eslint-disable */ @@ -25,7 +25,6 @@ import usePasswordPolicy from './components/password/usePasswordPolicy'; import Form from './components/form'; import PageLazyLoad from './components/Lazyload'; import PageLoader from './components/PageLoader'; -import useStickyElement from './components/useStickyElement'; import httpRequestErrorHandler from './handler/error/httpRequestErrorHandler'; prestashop.pageLazyLoad = new PageLazyLoad({ @@ -36,35 +35,11 @@ prestashop.pageLoader = new PageLoader(); prestashop.on('handleError', httpRequestErrorHandler); -function accLinksTriggerActive() { - const url = window.location.pathname; - $('.js-customer-links a').each((i, el) => { - const $el = $(el); - - if ($el.attr('href').indexOf(url) !== -1) { - $el.addClass('active'); - } - }); -} - -function initStickyHeader() { - const header = document.querySelector('.js-header-top'); - const headerWrapper = document.querySelector('.js-header-top-wrapper'); - - if (header && headerWrapper) { - useStickyElement(header, headerWrapper); - } -} $(() => { - const { init: initTopMenu } = useTopMenu('.js-main-menu'); - - initStickyHeader(); - accLinksTriggerActive(); Form.init(); bsCustomFileInput.init(); usePasswordPolicy('.field-password-policy'); - initTopMenu(); $('.js-select-link').on('change', ({ target }) => { window.location.href = $(target).val(); From 63680e2b42fda875ec2b8351a6bbb01f23c07839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ste=CC=A8pien=CC=81?= Date: Mon, 9 Oct 2023 23:34:57 +0200 Subject: [PATCH 05/43] vanilla.js pageloader --- _dev/js/theme/components/PageLoader.js | 17 --------- _dev/js/theme/components/customer/index.js | 1 - _dev/js/theme/components/usePageLoader.js | 40 ++++++++++++++++++++++ _dev/js/theme/index.js | 4 +-- 4 files changed, 42 insertions(+), 20 deletions(-) delete mode 100644 _dev/js/theme/components/PageLoader.js create mode 100644 _dev/js/theme/components/usePageLoader.js diff --git a/_dev/js/theme/components/PageLoader.js b/_dev/js/theme/components/PageLoader.js deleted file mode 100644 index 239c227b..00000000 --- a/_dev/js/theme/components/PageLoader.js +++ /dev/null @@ -1,17 +0,0 @@ -import $ from 'jquery'; - -class PageLoader { - constructor() { - this.$body = $('body'); - } - - showLoader() { - this.$body.addClass('page-loader-active'); - } - - hideLoader() { - this.$body.removeClass('page-loader-active'); - } -} - -export default PageLoader; diff --git a/_dev/js/theme/components/customer/index.js b/_dev/js/theme/components/customer/index.js index 9f1aa423..b5a4ceb0 100644 --- a/_dev/js/theme/components/customer/index.js +++ b/_dev/js/theme/components/customer/index.js @@ -1,5 +1,4 @@ import DOMReady from "../../utils/DOMReady"; -import $ from "jquery"; const initCustomerLinksTriggerActive = () => { const url = window.location.pathname; diff --git a/_dev/js/theme/components/usePageLoader.js b/_dev/js/theme/components/usePageLoader.js new file mode 100644 index 00000000..41a3b8d3 --- /dev/null +++ b/_dev/js/theme/components/usePageLoader.js @@ -0,0 +1,40 @@ +/** + * A utility module for managing the page loader state. + * + * @return {showLoader, hideLoader} + * @example + * const pageLoader = usePageLoader(); + * pageLoader.showLoader(); // Display the page loader + * pageLoader.hideLoader(); // Hide the page loader + */ +const usePageLoader = () => { + const body = document.body; + const ACTIVE_CLASS = 'page-loader-active'; + + /** + * Show the page loader. + * + * @method showLoader + * @returns {void} + */ + const showLoader = () => { + body.classList.add(ACTIVE_CLASS); + }; + + /** + * Hide the page loader. + * + * @method hideLoader + * @returns {void} + */ + const hideLoader = () => { + body.classList.remove(ACTIVE_CLASS); + }; + + return { + showLoader, + hideLoader, + }; +}; + +export default usePageLoader; diff --git a/_dev/js/theme/index.js b/_dev/js/theme/index.js index c546b29e..d8be1ce2 100644 --- a/_dev/js/theme/index.js +++ b/_dev/js/theme/index.js @@ -24,14 +24,14 @@ for (const i in EventEmitter.prototype) { import usePasswordPolicy from './components/password/usePasswordPolicy'; import Form from './components/form'; import PageLazyLoad from './components/Lazyload'; -import PageLoader from './components/PageLoader'; import httpRequestErrorHandler from './handler/error/httpRequestErrorHandler'; +import usePageLoader from "./components/usePageLoader"; prestashop.pageLazyLoad = new PageLazyLoad({ selector: '.lazyload', }); -prestashop.pageLoader = new PageLoader(); +prestashop.pageLoader = usePageLoader(); prestashop.on('handleError', httpRequestErrorHandler); From 315b096faff70c6af8f6ed3c08417b131d81e5ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ste=CC=A8pien=CC=81?= Date: Mon, 9 Oct 2023 23:44:28 +0200 Subject: [PATCH 06/43] Vanilla.js form --- _dev/js/theme/components/customer/index.js | 11 +- _dev/js/theme/components/form.js | 99 ----------------- _dev/js/theme/components/header/index.js | 6 +- _dev/js/theme/components/usePageLoader.js | 2 +- _dev/js/theme/components/useStickyElement.js | 2 +- _dev/js/theme/components/useThemeForm.js | 102 ++++++++++++++++++ _dev/js/theme/index.js | 5 +- .../customer/_partials/customer-form.tpl | 2 +- 8 files changed, 116 insertions(+), 113 deletions(-) delete mode 100644 _dev/js/theme/components/form.js create mode 100644 _dev/js/theme/components/useThemeForm.js diff --git a/_dev/js/theme/components/customer/index.js b/_dev/js/theme/components/customer/index.js index b5a4ceb0..16f745b3 100644 --- a/_dev/js/theme/components/customer/index.js +++ b/_dev/js/theme/components/customer/index.js @@ -1,4 +1,4 @@ -import DOMReady from "../../utils/DOMReady"; +import DOMReady from '../../utils/DOMReady'; const initCustomerLinksTriggerActive = () => { const url = window.location.pathname; @@ -9,7 +9,7 @@ const initCustomerLinksTriggerActive = () => { el.classList.add('active'); } }); -} +}; const initRmaForm = () => { const returnForm = document.querySelector(prestashop.selectors.order.returnForm); @@ -19,15 +19,14 @@ const initRmaForm = () => { } returnForm.querySelector('thead input[type=checkbox]').addEventListener('click', ({ currentTarget }) => { - const checked = currentTarget.checked; + const { checked } = currentTarget; returnForm.querySelectorAll('tbody input[type=checkbox]').forEach((checkbox) => { checkbox.checked = checked; }); }); -} - +}; DOMReady(() => { initCustomerLinksTriggerActive(); initRmaForm(); -}) +}); diff --git a/_dev/js/theme/components/form.js b/_dev/js/theme/components/form.js deleted file mode 100644 index 2134e7d1..00000000 --- a/_dev/js/theme/components/form.js +++ /dev/null @@ -1,99 +0,0 @@ -import $ from 'jquery'; - -const supportedValidity = () => { - const input = document.createElement('input'); - - return ( - 'validity' in input - && 'badInput' in input.validity - && 'patternMismatch' in input.validity - && 'rangeOverflow' in input.validity - && 'rangeUnderflow' in input.validity - && 'tooLong' in input.validity - && 'tooShort' in input.validity - && 'typeMismatch' in input.validity - && 'valid' in input.validity - && 'valueMissing' in input.validity - ); -}; - -export default class Form { - static init() { - Form.togglePasswordVisibility(); - Form.formValidation(); - } - - static togglePasswordVisibility() { - $('[data-action="show-password"]').on('click', (e) => { - e.preventDefault(); - e.stopImmediatePropagation(); - - const $btn = $(e.currentTarget); - const $input = $btn - .closest('.js-parent-focus') - .find('.js-visible-password'); - - if ($input.attr('type') === 'password') { - $input.attr('type', 'text'); - $btn.html($btn.data('text-hide')); - } else { - $input.attr('type', 'password'); - $btn.html($btn.data('textShow')); - } - }); - } - - static formValidation() { - // Fetch all the forms we want to apply custom Bootstrap validation styles to - const forms = document.getElementsByClassName('needs-validation'); - - if (forms.length > 0) { - if (!supportedValidity()) { - return; - } - // Loop over them and prevent submission - let divToScroll = false; - - $('input, textarea', forms).on('blur', (e) => { - const $field = $(e.currentTarget); - $field.val($field.val().trim()); - }); - - Array.prototype.filter.call(forms, (form) => { - form.addEventListener( - 'submit', - (event) => { - if (form.checkValidity() === false) { - event.preventDefault(); - event.stopPropagation(); - $('input:invalid,select:invalid,textarea:invalid', form).each((index, field) => { - const $field = $(field); - const $parent = $field.closest('.form-group'); - - $('.js-invalid-feedback-browser', $parent).text( - $field[0].validationMessage, - ); - if (!divToScroll) { - divToScroll = $parent; - } - }); - - const $form = $(form); - $form.data('disabled', false); - $form.find('[type="submit"]').removeClass('disabled'); - } - form.classList.add('was-validated'); - if (divToScroll) { - $('html, body').animate( - { scrollTop: divToScroll.offset().top }, - 300, - ); - divToScroll = false; - } - }, - false, - ); - }); - } - } -} diff --git a/_dev/js/theme/components/header/index.js b/_dev/js/theme/components/header/index.js index 90b34e45..47e25dd9 100644 --- a/_dev/js/theme/components/header/index.js +++ b/_dev/js/theme/components/header/index.js @@ -1,6 +1,6 @@ -import DOMReady from "../../utils/DOMReady"; +import DOMReady from '../../utils/DOMReady'; import useTopMenu from './useTopMenu'; -import useStickyElement from "../useStickyElement"; +import useStickyElement from '../useStickyElement'; const initStickyHeader = () => { const header = document.querySelector('.js-header-top'); @@ -11,7 +11,7 @@ const initStickyHeader = () => { init(); } -} +}; DOMReady(() => { const { init: initTopMenu } = useTopMenu('.js-main-menu'); diff --git a/_dev/js/theme/components/usePageLoader.js b/_dev/js/theme/components/usePageLoader.js index 41a3b8d3..72eb2ddb 100644 --- a/_dev/js/theme/components/usePageLoader.js +++ b/_dev/js/theme/components/usePageLoader.js @@ -8,7 +8,7 @@ * pageLoader.hideLoader(); // Hide the page loader */ const usePageLoader = () => { - const body = document.body; + const { body } = document; const ACTIVE_CLASS = 'page-loader-active'; /** diff --git a/_dev/js/theme/components/useStickyElement.js b/_dev/js/theme/components/useStickyElement.js index dd7ef80a..b3da4b55 100644 --- a/_dev/js/theme/components/useStickyElement.js +++ b/_dev/js/theme/components/useStickyElement.js @@ -68,7 +68,7 @@ export default (element, stickyWrapper, options = {}) => { const init = () => { window.addEventListener('scroll', debounce(handleSticky, debounceTime)); handleSticky(); - } + }; return { getExtraOffsetTop, diff --git a/_dev/js/theme/components/useThemeForm.js b/_dev/js/theme/components/useThemeForm.js new file mode 100644 index 00000000..1a2ca365 --- /dev/null +++ b/_dev/js/theme/components/useThemeForm.js @@ -0,0 +1,102 @@ +import { each } from '../utils/DOMHelpers'; + +const supportedValidity = () => { + const input = document.createElement('input'); + const validityProps = [ + 'validity', + 'badInput', + 'patternMismatch', + 'rangeOverflow', + 'rangeUnderflow', + 'tooLong', + 'tooShort', + 'typeMismatch', + 'valid', + 'valueMissing', + ]; + + return validityProps.every((prop) => prop in input.validity); +}; + +const togglePasswordVisibility = (btn) => { + btn.addEventListener('click', (e) => { + e.preventDefault(); + e.stopImmediatePropagation(); + + const input = btn.closest('.js-parent-focus').querySelector('.js-visible-password'); + + if (input.getAttribute('type') === 'password') { + input.setAttribute('type', 'text'); + btn.innerHTML = btn.getAttribute('data-text-hide'); + } else { + input.setAttribute('type', 'password'); + btn.innerHTML = btn.getAttribute('data-text-show'); + } + }); +}; + +const formValidation = (form) => { + if (!supportedValidity()) { + return; + } + + const divToScroll = { value: null }; + + Array.from(form.querySelectorAll('input, textarea')).forEach(field => { + field.addEventListener('blur', (e) => { + const inputField = e.currentTarget; + inputField.value = inputField.value.trim(); + }); + }); + + form.addEventListener('submit', (event) => { + if (form.checkValidity() === false) { + event.preventDefault(); + event.stopPropagation(); + + Array.from(form.querySelectorAll('input:invalid, select:invalid, textarea:invalid')).forEach(field => { + const inputField = field; + const parent = inputField.closest('.form-group'); + const invalidFeedback = parent.querySelector('.js-invalid-feedback-browser'); + + invalidFeedback.textContent = inputField.validationMessage; + + if (!divToScroll.value) { + divToScroll.value = parent; + } + }); + + const submitButton = form.querySelector('[type="submit"]'); + form.dataset.disabled = false; + submitButton.classList.remove('disabled'); + } + + form.classList.add('was-validated'); + + if (divToScroll.value) { + window.scrollTo({ + top: divToScroll.value.offsetTop, + behavior: 'smooth', + }); + + divToScroll.value = null; + } + }, false); +}; + +const useThemeForm = ( + validationFormSelector = '.js-needs-validation', + passwordToggleSelector = '[data-action="show-password"]', +) => { + + const init = () => { + each(document.querySelectorAll(passwordToggleSelector), togglePasswordVisibility) + each(document.querySelectorAll(validationFormSelector), formValidation) + } + + return { + init, + } +}; + +export default useThemeForm; diff --git a/_dev/js/theme/index.js b/_dev/js/theme/index.js index d8be1ce2..b7cc612d 100644 --- a/_dev/js/theme/index.js +++ b/_dev/js/theme/index.js @@ -22,7 +22,7 @@ for (const i in EventEmitter.prototype) { prestashop[i] = EventEmitter.prototype[i]; } import usePasswordPolicy from './components/password/usePasswordPolicy'; -import Form from './components/form'; +import useThemeForm from './components/useThemeForm'; import PageLazyLoad from './components/Lazyload'; import httpRequestErrorHandler from './handler/error/httpRequestErrorHandler'; import usePageLoader from "./components/usePageLoader"; @@ -37,7 +37,8 @@ prestashop.on('handleError', httpRequestErrorHandler); $(() => { - Form.init(); + const { init: initForm } = useThemeForm(); + initForm(); bsCustomFileInput.init(); usePasswordPolicy('.field-password-policy'); diff --git a/templates/customer/_partials/customer-form.tpl b/templates/customer/_partials/customer-form.tpl index a3f4f6d8..907f35f0 100644 --- a/templates/customer/_partials/customer-form.tpl +++ b/templates/customer/_partials/customer-form.tpl @@ -28,7 +28,7 @@ {include file='_partials/form-errors.tpl' errors=$errors['']} {/block} -
{block "form_fields"} From d0624167d69acfc6a71ca022410bce1f212315eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ste=CC=A8pien=CC=81?= Date: Mon, 9 Oct 2023 23:48:21 +0200 Subject: [PATCH 07/43] form select link --- _dev/js/theme/components/useThemeForm.js | 19 +++++++++++++++++-- _dev/js/theme/index.js | 4 ---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/_dev/js/theme/components/useThemeForm.js b/_dev/js/theme/components/useThemeForm.js index 1a2ca365..4e58f073 100644 --- a/_dev/js/theme/components/useThemeForm.js +++ b/_dev/js/theme/components/useThemeForm.js @@ -1,4 +1,5 @@ import { each } from '../utils/DOMHelpers'; +import $ from "jquery"; const supportedValidity = () => { const input = document.createElement('input'); @@ -88,10 +89,24 @@ const useThemeForm = ( validationFormSelector = '.js-needs-validation', passwordToggleSelector = '[data-action="show-password"]', ) => { + const DOM_SELECTORS = { + SELECT_LINK: '.js-select-link', + } + + const handleSelectChange = (event) => { + const target = event.target; + + if (target) { + window.location.href = target.value; + } + } const init = () => { - each(document.querySelectorAll(passwordToggleSelector), togglePasswordVisibility) - each(document.querySelectorAll(validationFormSelector), formValidation) + each(document.querySelectorAll(passwordToggleSelector), togglePasswordVisibility); + each(document.querySelectorAll(validationFormSelector), formValidation); + each(document.querySelectorAll(DOM_SELECTORS.SELECT_LINK), (select) => { + select.addEventListener('change', handleSelectChange); + }); } return { diff --git a/_dev/js/theme/index.js b/_dev/js/theme/index.js index b7cc612d..9072b7e1 100644 --- a/_dev/js/theme/index.js +++ b/_dev/js/theme/index.js @@ -41,8 +41,4 @@ $(() => { initForm(); bsCustomFileInput.init(); usePasswordPolicy('.field-password-policy'); - - $('.js-select-link').on('change', ({ target }) => { - window.location.href = $(target).val(); - }); }); From ad9fd99f8caaee7b6f3b43a8a492018334030690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ste=CC=A8pien=CC=81?= Date: Mon, 9 Oct 2023 23:52:16 +0200 Subject: [PATCH 08/43] Removing jquery, slider componnet --- _dev/js/theme/components/sliders.js | 8 ++++---- _dev/js/theme/components/sliders/SwiperSlider.js | 2 +- _dev/js/theme/index.js | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/_dev/js/theme/components/sliders.js b/_dev/js/theme/components/sliders.js index 0fa44d56..e078cae8 100644 --- a/_dev/js/theme/components/sliders.js +++ b/_dev/js/theme/components/sliders.js @@ -1,11 +1,11 @@ import prestashop from 'prestashop'; -import $ from 'jquery'; -import PageSlider from '@js/theme/components/sliders/PageSlider'; -import SwiperSlider from '@js/theme/components/sliders/SwiperSlider'; +import DOMReady from "../utils/DOMReady"; +import PageSlider from './sliders/PageSlider'; +import SwiperSlider from './sliders/SwiperSlider'; prestashop.pageSlider = new PageSlider(); prestashop.SwiperSlider = SwiperSlider; -$(() => { +DOMReady(() => { prestashop.pageSlider.init(); }); diff --git a/_dev/js/theme/components/sliders/SwiperSlider.js b/_dev/js/theme/components/sliders/SwiperSlider.js index 01902ffd..e9de38b8 100644 --- a/_dev/js/theme/components/sliders/SwiperSlider.js +++ b/_dev/js/theme/components/sliders/SwiperSlider.js @@ -2,7 +2,7 @@ import Swiper, { Navigation, Pagination, Autoplay, } from 'swiper'; -import DynamicImportSwiperModule from '@js/theme/components/sliders/DynamicImportSwiperModule'; +import DynamicImportSwiperModule from './DynamicImportSwiperModule'; /* eslint-disable */ const dynamicModulesMap = { diff --git a/_dev/js/theme/index.js b/_dev/js/theme/index.js index 9072b7e1..9441bcb5 100644 --- a/_dev/js/theme/index.js +++ b/_dev/js/theme/index.js @@ -26,6 +26,7 @@ import useThemeForm from './components/useThemeForm'; import PageLazyLoad from './components/Lazyload'; import httpRequestErrorHandler from './handler/error/httpRequestErrorHandler'; import usePageLoader from "./components/usePageLoader"; +import DOMReady from "./utils/DOMReady"; prestashop.pageLazyLoad = new PageLazyLoad({ selector: '.lazyload', @@ -36,7 +37,7 @@ prestashop.pageLoader = usePageLoader(); prestashop.on('handleError', httpRequestErrorHandler); -$(() => { +DOMReady(() => { const { init: initForm } = useThemeForm(); initForm(); bsCustomFileInput.init(); From 98ba80a24d6715c57cf9b7fe73a904220a6ccce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ste=CC=A8pien=CC=81?= Date: Mon, 9 Oct 2023 23:54:12 +0200 Subject: [PATCH 09/43] Slider minor changes to folder structure --- _dev/js/theme/components/{sliders.js => sliders/index.js} | 6 +++--- _dev/js/theme/index.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename _dev/js/theme/components/{sliders.js => sliders/index.js} (55%) diff --git a/_dev/js/theme/components/sliders.js b/_dev/js/theme/components/sliders/index.js similarity index 55% rename from _dev/js/theme/components/sliders.js rename to _dev/js/theme/components/sliders/index.js index e078cae8..a63e90d1 100644 --- a/_dev/js/theme/components/sliders.js +++ b/_dev/js/theme/components/sliders/index.js @@ -1,7 +1,7 @@ import prestashop from 'prestashop'; -import DOMReady from "../utils/DOMReady"; -import PageSlider from './sliders/PageSlider'; -import SwiperSlider from './sliders/SwiperSlider'; +import DOMReady from "../../utils/DOMReady"; +import PageSlider from './PageSlider'; +import SwiperSlider from './SwiperSlider'; prestashop.pageSlider = new PageSlider(); prestashop.SwiperSlider = SwiperSlider; diff --git a/_dev/js/theme/index.js b/_dev/js/theme/index.js index 9441bcb5..f3e3cf37 100644 --- a/_dev/js/theme/index.js +++ b/_dev/js/theme/index.js @@ -9,7 +9,7 @@ import './components/dynamic-bootstrap-components'; import bsCustomFileInput from 'bs-custom-file-input'; import './components/header/index'; import './components/customer/index'; -import './components/sliders'; +import './components/sliders/index'; import './components/responsive'; import './components/quickview'; import './components/product'; From 1612b7ffb9f6eedb46e4ab3a0a6dec5d2569dd17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ste=CC=A8pien=CC=81?= Date: Mon, 9 Oct 2023 23:59:52 +0200 Subject: [PATCH 10/43] responsive component vanilla.js --- _dev/js/theme/components/responsive.js | 58 ++++++++++++++---------- _dev/js/theme/components/useThemeForm.js | 1 - 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/_dev/js/theme/components/responsive.js b/_dev/js/theme/components/responsive.js index 30e66e8f..bdf59872 100644 --- a/_dev/js/theme/components/responsive.js +++ b/_dev/js/theme/components/responsive.js @@ -1,62 +1,70 @@ -import $ from 'jquery'; +import DOMReady from "../utils/DOMReady"; import prestashop from 'prestashop'; -const isMobile = () => prestashop.responsive.current_width < prestashop.responsive.min_width; - -prestashop.responsive = prestashop.responsive || {}; +prestashop.responsive = {}; prestashop.responsive.current_width = window.innerWidth; prestashop.responsive.min_width = 768; prestashop.responsive.mobile = isMobile(); +function isMobile() { + return prestashop.responsive.current_width < prestashop.responsive.min_width; +} + function swapChildren(obj1, obj2) { - const temp = obj2.children().detach(); - obj2.empty().append(obj1.children().detach()); - obj1.append(temp); + const temp = Array.from(obj2.children).map(child => child.cloneNode(true)); + obj2.innerHTML = ''; + temp.forEach(child => obj2.appendChild(child)); + + const childrenObj1 = Array.from(obj1.children); + childrenObj1.forEach(child => obj1.removeChild(child)); + childrenObj1.forEach(child => obj2.appendChild(child)); } function toggleMobileStyles() { if (prestashop.responsive.mobile) { - $("*[id^='_desktop_']").each((idx, el) => { - const target = $(`#${el.id.replace('_desktop_', '_mobile_')}`); + document.querySelectorAll('*[id^="_desktop_"]').forEach(el => { + const target = document.getElementById(el.id.replace('_desktop_', '_mobile_')); - if (target.length) { - swapChildren($(el), target); + if (target) { + swapChildren(el, target); } }); - $('[data-collapse-hide-mobile]').collapse('hide'); + document.querySelectorAll('[data-collapse-hide-mobile]').forEach(el => el.classList.add('collapse')); } else { - $("*[id^='_mobile_']").each((idx, el) => { - const target = $(`#${el.id.replace('_mobile_', '_desktop_')}`); + document.querySelectorAll('*[id^="_mobile_"]').forEach(el => { + const target = document.getElementById(el.id.replace('_mobile_', '_desktop_')); - if (target.length) { - swapChildren($(el), target); + if (target) { + swapChildren(el, target); } }); - $('[data-collapse-hide-mobile]').not('.show').collapse('show'); - $('[data-modal-hide-mobile].show').modal('hide'); + document.querySelectorAll('[data-collapse-hide-mobile]:not(.show)').forEach(el => el.classList.remove('collapse')); + document.querySelectorAll('[data-modal-hide-mobile].show').forEach(el => el.classList.remove('show')); } prestashop.emit('responsive update', { mobile: prestashop.responsive.mobile, }); } -$(window).on('resize', () => { +const handleResize = () => { const { responsive } = prestashop; - const cw = responsive.current_width; - const mw = responsive.min_width; + const cw = prestashop.responsive.current_width; + const mw = prestashop.responsive.min_width; const w = window.innerWidth; const toggle = (cw >= mw && w < mw) || (cw < mw && w >= mw); - responsive.current_width = w; - responsive.mobile = responsive.current_width < responsive.min_width; + prestashop.responsive.current_width = w; + prestashop.responsive.mobile = prestashop.responsive.current_width < prestashop.responsive.min_width; if (toggle) { toggleMobileStyles(); } -}); +} + +window.addEventListener('resize', handleResize); -$(() => { +DOMReady(() => { if (prestashop.responsive.mobile) { toggleMobileStyles(); } diff --git a/_dev/js/theme/components/useThemeForm.js b/_dev/js/theme/components/useThemeForm.js index 4e58f073..b3c055be 100644 --- a/_dev/js/theme/components/useThemeForm.js +++ b/_dev/js/theme/components/useThemeForm.js @@ -1,5 +1,4 @@ import { each } from '../utils/DOMHelpers'; -import $ from "jquery"; const supportedValidity = () => { const input = document.createElement('input'); From b5a66ff5e12da292872e180089747c59d8c13eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ste=CC=A8pien=CC=81?= Date: Tue, 10 Oct 2023 00:05:00 +0200 Subject: [PATCH 11/43] Vanilla.js --- _dev/js/theme/components/product.js | 38 +++++++++++++++++++---------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/_dev/js/theme/components/product.js b/_dev/js/theme/components/product.js index 4a11a510..66e584f8 100644 --- a/_dev/js/theme/components/product.js +++ b/_dev/js/theme/components/product.js @@ -1,18 +1,20 @@ -import $ from 'jquery'; import prestashop from 'prestashop'; import useCustomQuantityInput from './useCustomQuantityInput'; import { each } from '../utils/DOMHelpers'; +import DOMReady from "../utils/DOMReady"; import productEventContextSelector from '../core/product/utils/productEventContextSelector'; -$(() => { +DOMReady(() => { const createInputFile = () => { - $('.js-file-input').on('change', (event) => { - const target = $(event.currentTarget)[0]; - const file = (target) ? target.files[0] : null; + each('.js-file-input', (input) => { + input.addEventListener('change', (event) => { + const target = event.currentTarget; + const file = (target) ? target.files[0] : null; - if (target && file) { - $(target).prev().text(file.name); - } + if (target && file) { + target.previousElementSibling.textContent = file.name; + } + }); }); }; @@ -42,9 +44,10 @@ $(() => { }); prestashop.on('updateCart', (event) => { - if ( - prestashop.page.page_name === 'product' - && parseInt(event.reason.idProduct, 10) === parseInt($('#add-to-cart-or-refresh').find('[name="id_product"]').val(), 10)) { + const productForm = document.getElementById('add-to-cart-or-refresh'); + const idProduct = productForm ? parseInt(productForm.querySelector('[name="id_product"]').value, 10) : null; + + if (prestashop.page.page_name === 'product' && parseInt(event.reason.idProduct, 10) === idProduct) { prestashop.emit('updateProduct', { event, resp: {}, @@ -60,8 +63,17 @@ $(() => { const contextSelector = productEventContextSelector(); if (updateEvenType === 'updatedProductCombination') { - $(`${contextSelector} .js-product-images`).replaceWith(event.product_cover_thumbnails); - $(`${contextSelector} .js-product-images-modal`).replaceWith(event.product_images_modal); + const productImages = document.querySelector(`${contextSelector} .js-product-images`); + const productImagesModal = document.querySelector(`${contextSelector} .js-product-images-modal`); + + if (productImages) { + productImages.replaceWith(event.product_cover_thumbnails); + } + + if (productImagesModal) { + productImagesModal.replaceWith(event.product_images_modal); + } + prestashop.emit('updatedProductCombination', event); } From d7260dfa2457ca883dba3ec8a0f80bfe16245d1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ste=CC=A8pien=CC=81?= Date: Tue, 10 Oct 2023 00:06:22 +0200 Subject: [PATCH 12/43] Quickview vanilla.js --- _dev/js/theme/components/quickview.js | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/_dev/js/theme/components/quickview.js b/_dev/js/theme/components/quickview.js index f9d5baa6..bc27665f 100644 --- a/_dev/js/theme/components/quickview.js +++ b/_dev/js/theme/components/quickview.js @@ -1,4 +1,3 @@ -import $ from 'jquery'; import prestashop from 'prestashop'; import DOMReady from '../utils/DOMReady'; import parseToHtml from '../utils/parseToHtml'; @@ -6,21 +5,18 @@ import parseToHtml from '../utils/parseToHtml'; /** * Handle open quick view */ -const handleQuickViewOpen = ({ - resp, -}) => { - const body = document.querySelector('body'); - body.append(parseToHtml(resp.quickview_html)); +const handleQuickViewOpen = ({ resp }) => { + const body = document.body; - // TO DO REMOVE JQUERY - const productModal = $( - `#quickview-modal-${resp.product.id}-${resp.product.id_product_attribute}`, - ); - productModal.modal('show'); + const quickviewHtml = parseToHtml(resp.quickview_html); + body.appendChild(quickviewHtml); + + const productModal = document.getElementById(`quickview-modal-${resp.product.id}-${resp.product.id_product_attribute}`); + productModal.classList.add('show'); body.classList.add('js-quickview-open'); - productModal.on('hidden.bs.modal', () => { + productModal.addEventListener('hidden.bs.modal', () => { productModal.remove(); body.classList.remove('js-quickview-open'); }); From e0cd01ce1f6acd5acba0bac5f23907014c29a838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ste=CC=A8pien=CC=81?= Date: Tue, 10 Oct 2023 00:10:15 +0200 Subject: [PATCH 13/43] eslint fix --- _dev/js/theme/components/product.js | 2 +- _dev/js/theme/components/quickview.js | 2 +- _dev/js/theme/components/responsive.js | 32 ++++++++++++----------- _dev/js/theme/components/sliders/index.js | 2 +- _dev/js/theme/components/useThemeForm.js | 14 +++++----- _dev/js/theme/index.js | 2 -- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/_dev/js/theme/components/product.js b/_dev/js/theme/components/product.js index 66e584f8..d43ebb34 100644 --- a/_dev/js/theme/components/product.js +++ b/_dev/js/theme/components/product.js @@ -1,7 +1,7 @@ import prestashop from 'prestashop'; import useCustomQuantityInput from './useCustomQuantityInput'; import { each } from '../utils/DOMHelpers'; -import DOMReady from "../utils/DOMReady"; +import DOMReady from '../utils/DOMReady'; import productEventContextSelector from '../core/product/utils/productEventContextSelector'; DOMReady(() => { diff --git a/_dev/js/theme/components/quickview.js b/_dev/js/theme/components/quickview.js index bc27665f..20ff3d76 100644 --- a/_dev/js/theme/components/quickview.js +++ b/_dev/js/theme/components/quickview.js @@ -6,7 +6,7 @@ import parseToHtml from '../utils/parseToHtml'; * Handle open quick view */ const handleQuickViewOpen = ({ resp }) => { - const body = document.body; + const { body } = document; const quickviewHtml = parseToHtml(resp.quickview_html); body.appendChild(quickviewHtml); diff --git a/_dev/js/theme/components/responsive.js b/_dev/js/theme/components/responsive.js index bdf59872..003b71d7 100644 --- a/_dev/js/theme/components/responsive.js +++ b/_dev/js/theme/components/responsive.js @@ -1,29 +1,31 @@ -import DOMReady from "../utils/DOMReady"; import prestashop from 'prestashop'; +import DOMReady from '../utils/DOMReady'; +function isMobile() { + return prestashop.responsive.current_width < prestashop.responsive.min_width; +} + +/* eslint-disable */ prestashop.responsive = {}; +/* eslint-enable */ prestashop.responsive.current_width = window.innerWidth; prestashop.responsive.min_width = 768; prestashop.responsive.mobile = isMobile(); -function isMobile() { - return prestashop.responsive.current_width < prestashop.responsive.min_width; -} - function swapChildren(obj1, obj2) { - const temp = Array.from(obj2.children).map(child => child.cloneNode(true)); + const temp = Array.from(obj2.children).map((child) => child.cloneNode(true)); obj2.innerHTML = ''; - temp.forEach(child => obj2.appendChild(child)); + temp.forEach((child) => obj2.appendChild(child)); const childrenObj1 = Array.from(obj1.children); - childrenObj1.forEach(child => obj1.removeChild(child)); - childrenObj1.forEach(child => obj2.appendChild(child)); + childrenObj1.forEach((child) => obj1.removeChild(child)); + childrenObj1.forEach((child) => obj2.appendChild(child)); } function toggleMobileStyles() { if (prestashop.responsive.mobile) { - document.querySelectorAll('*[id^="_desktop_"]').forEach(el => { + document.querySelectorAll('*[id^="_desktop_"]').forEach((el) => { const target = document.getElementById(el.id.replace('_desktop_', '_mobile_')); if (target) { @@ -31,9 +33,9 @@ function toggleMobileStyles() { } }); - document.querySelectorAll('[data-collapse-hide-mobile]').forEach(el => el.classList.add('collapse')); + document.querySelectorAll('[data-collapse-hide-mobile]').forEach((el) => el.classList.add('collapse')); } else { - document.querySelectorAll('*[id^="_mobile_"]').forEach(el => { + document.querySelectorAll('*[id^="_mobile_"]').forEach((el) => { const target = document.getElementById(el.id.replace('_mobile_', '_desktop_')); if (target) { @@ -41,8 +43,8 @@ function toggleMobileStyles() { } }); - document.querySelectorAll('[data-collapse-hide-mobile]:not(.show)').forEach(el => el.classList.remove('collapse')); - document.querySelectorAll('[data-modal-hide-mobile].show').forEach(el => el.classList.remove('show')); + document.querySelectorAll('[data-collapse-hide-mobile]:not(.show)').forEach((el) => el.classList.remove('collapse')); + document.querySelectorAll('[data-modal-hide-mobile].show').forEach((el) => el.classList.remove('show')); } prestashop.emit('responsive update', { mobile: prestashop.responsive.mobile, @@ -60,7 +62,7 @@ const handleResize = () => { if (toggle) { toggleMobileStyles(); } -} +}; window.addEventListener('resize', handleResize); diff --git a/_dev/js/theme/components/sliders/index.js b/_dev/js/theme/components/sliders/index.js index a63e90d1..ad4c1230 100644 --- a/_dev/js/theme/components/sliders/index.js +++ b/_dev/js/theme/components/sliders/index.js @@ -1,5 +1,5 @@ import prestashop from 'prestashop'; -import DOMReady from "../../utils/DOMReady"; +import DOMReady from '../../utils/DOMReady'; import PageSlider from './PageSlider'; import SwiperSlider from './SwiperSlider'; diff --git a/_dev/js/theme/components/useThemeForm.js b/_dev/js/theme/components/useThemeForm.js index b3c055be..73fa0146 100644 --- a/_dev/js/theme/components/useThemeForm.js +++ b/_dev/js/theme/components/useThemeForm.js @@ -42,7 +42,7 @@ const formValidation = (form) => { const divToScroll = { value: null }; - Array.from(form.querySelectorAll('input, textarea')).forEach(field => { + Array.from(form.querySelectorAll('input, textarea')).forEach((field) => { field.addEventListener('blur', (e) => { const inputField = e.currentTarget; inputField.value = inputField.value.trim(); @@ -54,7 +54,7 @@ const formValidation = (form) => { event.preventDefault(); event.stopPropagation(); - Array.from(form.querySelectorAll('input:invalid, select:invalid, textarea:invalid')).forEach(field => { + Array.from(form.querySelectorAll('input:invalid, select:invalid, textarea:invalid')).forEach((field) => { const inputField = field; const parent = inputField.closest('.form-group'); const invalidFeedback = parent.querySelector('.js-invalid-feedback-browser'); @@ -90,15 +90,15 @@ const useThemeForm = ( ) => { const DOM_SELECTORS = { SELECT_LINK: '.js-select-link', - } + }; const handleSelectChange = (event) => { - const target = event.target; + const { target } = event; if (target) { window.location.href = target.value; } - } + }; const init = () => { each(document.querySelectorAll(passwordToggleSelector), togglePasswordVisibility); @@ -106,11 +106,11 @@ const useThemeForm = ( each(document.querySelectorAll(DOM_SELECTORS.SELECT_LINK), (select) => { select.addEventListener('change', handleSelectChange); }); - } + }; return { init, - } + }; }; export default useThemeForm; diff --git a/_dev/js/theme/index.js b/_dev/js/theme/index.js index f3e3cf37..d15bbba5 100644 --- a/_dev/js/theme/index.js +++ b/_dev/js/theme/index.js @@ -1,5 +1,3 @@ -import $ from 'jquery'; - import EventEmitter from 'events'; import './core/index'; From 21ff91fc8fc6905f7b09c51a4b8ee83b6f4df561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ste=CC=A8pien=CC=81?= Date: Tue, 10 Oct 2023 00:13:35 +0200 Subject: [PATCH 14/43] eslint fix --- _dev/js/theme/components/responsive.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/_dev/js/theme/components/responsive.js b/_dev/js/theme/components/responsive.js index 003b71d7..b699b703 100644 --- a/_dev/js/theme/components/responsive.js +++ b/_dev/js/theme/components/responsive.js @@ -5,10 +5,7 @@ function isMobile() { return prestashop.responsive.current_width < prestashop.responsive.min_width; } -/* eslint-disable */ prestashop.responsive = {}; -/* eslint-enable */ - prestashop.responsive.current_width = window.innerWidth; prestashop.responsive.min_width = 768; prestashop.responsive.mobile = isMobile(); @@ -52,7 +49,6 @@ function toggleMobileStyles() { } const handleResize = () => { - const { responsive } = prestashop; const cw = prestashop.responsive.current_width; const mw = prestashop.responsive.min_width; const w = window.innerWidth; From f1885f048ac88a3b8c583a58eb47dd2cf6e1a1e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ste=CC=A8pien=CC=81?= Date: Wed, 11 Oct 2023 01:51:14 +0200 Subject: [PATCH 15/43] Removed not used js code --- _dev/js/checkout/index.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/_dev/js/checkout/index.js b/_dev/js/checkout/index.js index 4b37133e..d3a57694 100644 --- a/_dev/js/checkout/index.js +++ b/_dev/js/checkout/index.js @@ -67,11 +67,6 @@ $(document).ready(() => { // and show the one related to the selected carrier params.deliveryOption.nextElementSibling.classList.remove('d-none'); }); - prestashop.on('changedCheckoutStep', (params) => { - if (typeof params.event.currentTarget !== 'undefined') { - $('.collapse', params.event.currentTarget).not('.show').not('.collapse .collapse').collapse('show'); - } - }); }); $(document).on('change', '.checkout-option input[type="radio"]', (event) => { @@ -82,9 +77,3 @@ $(document).on('change', '.checkout-option input[type="radio"]', (event) => { $relatedBlocks.find('.checkout-option').removeClass('selected'); $block.addClass('selected'); }); - -$(document).on('click', '.js-checkout-step-header', (event) => { - const stepIdentifier = $(event.currentTarget).data('identifier'); - $(`#${stepIdentifier}`).addClass('-current'); - $(`#content-${stepIdentifier}`).collapse('show').scrollTop(); -}); From db815db3fd98cc4807fa4e776d885560df0b2bd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ste=CC=A8pien=CC=81?= Date: Thu, 12 Oct 2023 23:20:13 +0200 Subject: [PATCH 16/43] Removed jquery form product entry --- _dev/js/product/components/ProductGallery.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/_dev/js/product/components/ProductGallery.js b/_dev/js/product/components/ProductGallery.js index 61f50b0f..d3375f21 100644 --- a/_dev/js/product/components/ProductGallery.js +++ b/_dev/js/product/components/ProductGallery.js @@ -93,8 +93,7 @@ class ProductGallery { } }; - // TO REFACTO LATER WITH BS5 REMOVE JQUERY! - $(this.galleryModalSelector).on('show.bs.modal', handleModalOpen); + document.querySelector(this.galleryModalSelector).addEventListener('show.bs.modal', handleModalOpen); } } From 42496cf258748dcc8999d1ec8d2f6a17f2b7af3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ste=CC=A8pien=CC=81?= Date: Thu, 12 Oct 2023 23:20:38 +0200 Subject: [PATCH 17/43] Removed not useful code --- _dev/js/theme/components/responsive.js | 3 --- modules/ps_mainmenu/ps_mainmenu.tpl | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/_dev/js/theme/components/responsive.js b/_dev/js/theme/components/responsive.js index b699b703..fe4eff35 100644 --- a/_dev/js/theme/components/responsive.js +++ b/_dev/js/theme/components/responsive.js @@ -39,9 +39,6 @@ function toggleMobileStyles() { swapChildren(el, target); } }); - - document.querySelectorAll('[data-collapse-hide-mobile]:not(.show)').forEach((el) => el.classList.remove('collapse')); - document.querySelectorAll('[data-modal-hide-mobile].show').forEach((el) => el.classList.remove('show')); } prestashop.emit('responsive update', { mobile: prestashop.responsive.mobile, diff --git a/modules/ps_mainmenu/ps_mainmenu.tpl b/modules/ps_mainmenu/ps_mainmenu.tpl index 136f0b13..840fac22 100644 --- a/modules/ps_mainmenu/ps_mainmenu.tpl +++ b/modules/ps_mainmenu/ps_mainmenu.tpl @@ -33,7 +33,7 @@
{/if} {if $node.children|count} -