1$(document).ready(function () { 2 3 // ============================================= 4 // PRESTASHOP BLOCKCART ORIGINAL 5 // ============================================= 6 prestashop.blockcart = prestashop.blockcart || {}; 7 8 prestashop.on('updateCart', function (event) { 9 actualiza_mini_cart(event); 10 }); 11 12 function actualiza_mini_cart(event) { 13 var refreshURL = $('.blockcart').data('refresh-url'); 14 var requestData = {}; 15 if (event && event.reason && typeof event.resp !== 'undefined' && !event.resp.hasError) { 16 requestData = { 17 id_customization: event.reason.idCustomization, 18 id_product_attribute: event.reason.idProductAttribute, 19 id_product: event.reason.idProduct, 20 action: event.reason.linkAction 21 }; 22 } 23 if (event && event.resp && event.resp.hasError) { 24 prestashop.emit('showErrorNextToAddtoCartButton', { 25 errorMessage: event.resp.errors.join('<br/>') 26 }); 27 } 28 $.post(refreshURL, requestData).then(function (resp) { 29 var html = $('<div />').append($.parseHTML(resp.preview)); 30 isCartUpdating = true; 31 $('.blockcart').replaceWith($(resp.preview).find('.blockcart')); 32 if (!$("body#cart").length) { 33 $("html, body").animate({ scrollTop: 0 }, 300); 34 if (!$("#dropdownminicart.open").length) { 35 $("#show_mini_cart").trigger("click"); 36 } 37 } 38 $(".bg-add-to-cart").remove(); 39 setTimeout(function () { 40 initAllDropdowns(); 41 isCartUpdating = false; 42 }, 300); 43 }).fail(function (resp) { 44 prestashop.emit('handleError', { eventType: 'updateShoppingCart', resp: resp }); 45 }); 46 } 47 48 // Eliminar producto del carrito 49 $('body').on('click', '.remove-from-cart', function (e) { 50 e.preventDefault(); 51 var delete_item = $(this).attr("href") + '&ajax=1&action=remove'; 52 53 $.ajax({ 54 url: delete_item, 55 type: 'GET', 56 success: function (response) { 57 actualiza_mini_cart(e); 58 59 if (typeof prestashop !== 'undefined') { 60 var eventData = { 61 reason: { 62 idProduct: $(e.currentTarget).data('id-product'), 63 idProductAttribute: $(e.currentTarget).data('id-product-attribute'), 64 linkAction: 'remove', 65 cart: response 66 }, 67 resp: response 68 }; 69 prestashop.emit('updateCart', eventData); 70 } 71 }, 72 error: function (xhr, status, error) { 73 console.error('Error al eliminar el producto:', error); 74 } 75 }); 76 }); 77 78 // Añadir al carrito desde mini cart 79 $('body').on('click', '.js-add-to-mini-cart', function (e) { 80 e.preventDefault(); 81 var add_url = $(this).attr("data-url") + '&ajax=1'; 82 $.get(add_url, function (data, status) { 83 actualiza_mini_cart(e); 84 }); 85 }); 86 87 // ============================================= 88 // ACCESIBILIDAD DROPDOWNS 89 // ============================================= 90 var FOCUSABLE = 'a[href], button, input, select, textarea, [tabindex]:not([tabindex="-1"])'; 91 var isCartUpdating = false; 92 93 function lockMenu($dropdown) { 94 var $menu = $dropdown.find('.dropdown-menu'); 95 if (!$menu.length) return; 96 $menu.find(FOCUSABLE).attr('tabindex', '-1'); 97 $menu.attr('aria-hidden', 'true'); 98 } 99 100 function unlockMenu($dropdown) { 101 var $menu = $dropdown.find('.dropdown-menu'); 102 if (!$menu.length) return; 103 $menu.find(FOCUSABLE).removeAttr('tabindex'); 104 $menu.attr('aria-hidden', 'false'); 105 } 106 107 function isOpen($dropdown) { 108 return $dropdown.hasClass('open') || $dropdown.hasClass('show'); 109 } 110 111 function fixCartButton() { 112 var $trigger = $('#show_mini_cart'); 113 if (!$trigger.length) return; 114 if (!$trigger.is('button')) { 115 $trigger.attr({ 'role': 'button', 'tabindex': '0' }); 116 $trigger.off('keydown.a11y').on('keydown.a11y', function (e) { 117 if (e.key === 'Enter' || e.key === ' ') { 118 e.preventDefault(); 119 $(this).trigger('click'); 120 } 121 }); 122 } 123 } 124 125 function initAllDropdowns() { 126 fixCartButton(); 127 $('.dropdown').each(function () { 128 if (!isOpen($(this))) { 129 lockMenu($(this)); 130 } else { 131 unlockMenu($(this)); 132 } 133 }); 134 } 135 136 initAllDropdowns(); 137
138 // Observar cambios de clase (abrir/cerrar) 139 var classObserver = new MutationObserver(function (mutations) { 140 if (isCartUpdating) return; 141 mutations.forEach(function (m) { 142 if (m.type !== 'attributes') return; 143 var $target = $(m.target); 144 var $dropdown = $target.hasClass('dropdown') ? $target : null; 145 if (!$dropdown) return; 146 var $trigger = $dropdown.find('[data-toggle="dropdown"]'); 147 if (isOpen($dropdown)) { 148 $trigger.attr('aria-expanded', 'true'); 149 unlockMenu($dropdown); 150 } else { 151 $trigger.attr('aria-expanded', 'false'); 152 lockMenu($dropdown); 153 } 154 }); 155 }); 156 157 classObserver.observe(document.body, { 158 subtree: true, 159 attributes: true, 160 attributeFilter: ['class'] 161 }); 162 163 // Escape: cerrar y devolver foco 164 $('body').on('keydown', '.dropdown', function (e) { 165 if (e.key === 'Escape') { 166 var $dropdown = $(this); 167 var $trigger = $dropdown.find('[data-toggle="dropdown"]'); 168 $dropdown.removeClass('open show'); 169 $trigger.attr('aria-expanded', 'false'); 170 lockMenu($dropdown); 171 $trigger.focus(); 172 } 173 }); 174 175});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.