/** * Capa de datos (dataLayer) - Chocolate Corona * * Se apoya en window.CORONA_DL (impreso por /inc/datalayer.php) para conocer * la jerarquia del menu y los datos de cada producto/receta, y en delegacion * de eventos para no tener que tocar el marcado de las plantillas. * * Eventos: menu_principal, recetas, producto, filtro, formulario, Comprar, busqueda. */ (function () { 'use strict'; window.dataLayer = window.dataLayer || []; function ctx() { return window.CORONA_DL || {}; } function norm(path) { path = (path || '').toLowerCase().replace(/\/+$/, ''); return '' === path ? '/' : path; } function pathOf(url) { try { return norm(new URL(url, window.location.origin).pathname); } catch (e) { return ''; } } function here() { return norm(window.location.pathname); } function sameUrl(a, b) { if (!a || !b) { return false; } return String(a).replace(/\/+$/, '') === String(b).replace(/\/+$/, ''); } function text(el) { return el ? el.textContent.replace(/\s+/g, ' ').trim() : ''; } function each(list, fn) { Array.prototype.forEach.call(list || [], fn); } function push(data) { data.url = here(); window.dataLayer.push(data); if (ctx().debug) { console.log('[Corona dataLayer]', data); } } /* ------------------------------------------------------------------ */ /* Producto y receta */ /* ------------------------------------------------------------------ */ function cardOf(link) { return link.closest('article') || link.parentElement; } function recetaFromDom(link) { var card = cardOf(link); if (!card) { return null; } var data = { type: 'receta', title: text(card.querySelector('h1, h2, h3')), descripcion: text(card.querySelector('.card-receta-desc')), duracion: '', porciones: '' }; each(card.querySelectorAll('span'), function (span) { var value = text(span); var min = value.match(/(\d+)\s*min/i); if (min) { data.duracion = min[1] + 'min'; } else if (/porcion/i.test(value)) { data.porciones = value; } }); return data; } function productoFromDom(link) { var card = cardOf(link); if (!card) { return null; } var gramos = ''; each(card.querySelectorAll('p, span'), function (el) { if (gramos) { return; } var match = text(el).match(/^\d+(?:[.,]\d+)?\s*g\b/i); if (match) { gramos = match[0]; } }); return { type: 'producto', title: text(card.querySelector('h1, h2, h3')), gramos: gramos }; } /** * Datos del producto/receta al que apunta un enlace. Primero el mapa que * envia PHP (dato exacto de ACF); si no esta -por ejemplo las recetas que * llegan por AJAX- se leen de la card. */ function itemFor(link) { var key = pathOf(link.href); var map = ctx().posts || {}; if (map[key]) { return map[key]; } if (/\/recetas\/[^/]+$/.test(key)) { return recetaFromDom(link); } if (/\/productos\/[^/]+$/.test(key)) { return productoFromDom(link); } return null; } /* ------------------------------------------------------------------ */ /* Menu */ /* ------------------------------------------------------------------ */ function menuInfo(link) { var map = ctx().menu || {}; var info = map[pathOf(link.href)]; if (info) { return info; } var drop = link.closest('.dropdown-content, .mobile-dropdown-content'); if (drop && drop.parentElement) { return { category: text(drop.parentElement.querySelector('.dropdown-btn, .mobile-dropdown-btn')), subcategory: text(link) }; } var label = text(link); if (!label) { var img = link.querySelector('img'); label = img ? (img.getAttribute('alt') || 'Logo') : ''; } return { category: label, subcategory: '' }; } /* ------------------------------------------------------------------ */ /* Filtros */ /* ------------------------------------------------------------------ */ /** * Estado de un grupo de filtros (un acordeon). `clicked` es el enlace que * el usuario acaba de pulsar: se reporta el estado que quedara aplicado. */ function groupState(group, clicked) { var values = []; var slider = group.querySelector('input[type="range"]'); if (slider) { values.push(text(group.querySelector('[id^="tooltipValor"]'))); } else { each(group.querySelectorAll('.filtro-contenido a'), function (option) { var active = option.classList.contains('font-bold'); if (option === clicked) { active = !active; } if (active) { values.push(text(option)); } }); } return { name: text(group.querySelector('h3')), value: values.filter(Boolean).join('|') }; } function pushFiltro(panel, clicked, destino) { if (!panel) { return; } var data = { event: 'filtro' }; each(panel.querySelectorAll('.filtro'), function (group, index) { var suffix = 0 === index ? '' : index + 1; var state = groupState(group, clicked); data['event_category' + suffix] = state.name; data['event_subcategory' + suffix] = state.value; }); data.url_destino = destino; push(data); } /* ------------------------------------------------------------------ */ /* Clics */ /* ------------------------------------------------------------------ */ document.addEventListener('click', function (event) { var target = event.target; if (!target || !target.closest) { return; } var link = target.closest('a[href]'); // 7A - Resultado del buscador. if (link && link.closest('#search-results')) { push({ event: 'busqueda', event_category: text(link.querySelector('p')) || text(link), url_destino: pathOf(link.href) }); return; } // 4A - Opcion de filtro. var filterOption = target.closest('.filtro-contenido a'); if (filterOption) { var filterGroup = filterOption.closest('.filtro'); pushFiltro(filterGroup ? filterGroup.parentElement : null, filterOption, pathOf(filterOption.href)); return; } if (!link) { return; } // 6A - Boton flotante "Comprar". if (sameUrl(link.href, ctx().comprarUrl) || link.matches('a.fixed[target="_blank"]')) { push({ event: 'Comprar', event_label: text(link) || 'Comprar', url_destino: pathOf(link.href) }); return; } // 1A - Menu principal (incluye el menu movil, que vive dentro del header). if (link.closest('header')) { var info = menuInfo(link); push({ event: 'menu_principal', event_category: info.category, event_subcategory: info.subcategory || '', url_destino: pathOf(link.href) }); return; } var item = itemFor(link); if (!item) { return; } // 3A - Producto. if ('producto' === item.type) { push({ event: 'producto', event_category: item.title, event_subcategory: item.gramos || '', event_label: text(link), url_destino: pathOf(link.href) }); return; } // 2A - Receta. if ('receta' === item.type) { push({ event: 'recetas', event_category: item.title, event_subcategory: item.descripcion || '', duracion: item.duracion || '', porciones: item.porciones || '', url_destino: pathOf(link.href) }); } }, true); /* 4A - Filtro de cantidad/tiempo (slider): dispara al soltar. */ document.addEventListener('change', function (event) { var slider = event.target; if (!slider || !slider.matches || !slider.matches('.filtro input[type="range"]')) { return; } var group = slider.closest('.filtro'); pushFiltro(group ? group.parentElement : null, null, here()); }, true); /* ------------------------------------------------------------------ */ /* 5A - Formulario PQRS */ /* ------------------------------------------------------------------ */ /** * El formulario de /contacto es un iframe de Salesforce * (crmnutresa.my.salesforce-sites.com). Por politica de mismo origen la * pagina NO puede saber si el envio fue exitoso. * * Este puente ya queda listo: en cuanto Salesforce publique el mensaje * parent.postMessage({ event: 'formulario' }, '*') al confirmar el envio, * el evento se dispara solo. Mientras tanto no se emite nada. */ window.addEventListener('message', function (event) { if (!/^https?:\/\/([a-z0-9-]+\.)*(salesforce-sites\.com|force\.com|salesforce\.com)$/i.test(String(event.origin))) { return; } var data = event.data; var name = 'string' === typeof data ? data : (data && (data.event || data.type)); if (!name || !/formulario|form[_-]?(submit|success)|envio[_-]?exitoso/i.test(String(name))) { return; } push({ event: 'formulario', event_label: 'Enviar', url_destino: here() }); }); }()); Postres – Chocolate Corona

Postre de mora

ROLLO DE CHOCOLATE CON MORA Este increíble postre de moras tiene la gran ventaja de poderse preparar no…

Duración 50 min Duración 6 porciones Porciones

Torta de leche

Convirtamos esta receta en la excusa de los momentos más inspiradores para la familia. Una torta de leche…

Duración 60 min Duración 10 porciones Porciones

Creppes con Banano y Fresa

Los creppes con rellenos dulces, son sencillamente una debilidad, pues son perfectos para combinar sabores citricos, dulces, cremosos…

Duración 15 min Duración 4-6 porciones Porciones

Volcan de Chocolate

Con esta deliciosa receta te garantizamos que no se activarán los planes de evacuación, sino los de integración.…

Duración 45 min Duración 4 porciones Porciones

Fondue de Chocolate

Nos encantan las reuniones en familia o con los amigos de siempre, pero a veces no sabemos con…

Duración 10 min Duración 6-7 porciones Porciones

Pizza de Chocolate

¿Alguna vez habías pensado que con la mezcla para pancakes podrías preparar una pizza de chocolate? Esta mezcla…

Duración 20 min Duración 4 porciones Porciones

Waffles con Centro de Chocolate

Nuestra mezcla para pancakes es tan versátil que puedes preparar una gran variedad de platos para sorprender a…

Duración 15 min Duración 4 porciones Porciones
carrito Comprar