/* The OC Guy — page behaviour. Everything degrades: without JS the page is a plain, readable document with working links and a mail form. */ (function () { 'use strict'; var doc = document.documentElement; doc.classList.add('js'); var reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches; /* ---------- entrance for the blocks of each section ---------- */ var targets = document.querySelectorAll( '.lead-caption, .box, .side-list, .section-head, .card, .feature, .news li, .ask-inner' ); if (!reduce && 'IntersectionObserver' in window) { var io = new IntersectionObserver(function (entries) { entries.forEach(function (entry) { if (!entry.isIntersecting) return; entry.target.classList.add('rv-in'); io.unobserve(entry.target); }); }, { rootMargin: '0px 0px -8% 0px', threshold: 0.08 }); Array.prototype.forEach.call(targets, function (el) { el.setAttribute('data-rv', '1'); io.observe(el); }); } else { Array.prototype.forEach.call(targets, function (el) { el.classList.add('rv-in'); }); } /* ---------- the ask form: one question, by mail ---------- */ var form = document.querySelector('.ask-form'); var mail = document.getElementById('ask-mail'); if (form && mail) { form.addEventListener('submit', function (event) { event.preventDefault(); var addr = (mail.value || '').trim(); if (!addr || addr.indexOf('@') === -1) { mail.setAttribute('aria-invalid', 'true'); mail.focus(); return; } mail.removeAttribute('aria-invalid'); var body = 'My question about Odoo Community:\n\n\n— reply to: ' + addr + '\n'; window.location.href = 'mailto:oliver@oc-guy.com' + '?subject=' + encodeURIComponent('Odoo Community question') + '&body=' + encodeURIComponent(body); }); } /* ---------- OCA module status, live from the n8n feed ---------- */ var ocaBody = document.getElementById('oca-rows'); function statusCell(ok, version) { var td = document.createElement('td'); td.className = 'oca-status'; var mark = document.createElement('span'); mark.className = ok ? 'mark is-on' : 'mark'; mark.setAttribute('aria-hidden', 'true'); mark.textContent = ok ? '\u2713' : '\u2014'; var sr = document.createElement('span'); sr.className = 'sr-only'; sr.textContent = ok ? ' has a ' + version + ' branch' : ' no ' + version + ' branch yet'; td.appendChild(mark); td.appendChild(sr); return td; } function renderOca(rows) { ocaBody.textContent = ''; rows.forEach(function (m) { var tr = document.createElement('tr'); var name = document.createElement('td'); name.className = 'oca-name'; var a = document.createElement('a'); a.href = m.URL || '#'; a.target = '_blank'; a.rel = 'noopener'; a.textContent = m.name || 'Module'; name.appendChild(a); var area = document.createElement('td'); area.className = 'oca-area'; area.textContent = m.area || ''; tr.appendChild(name); tr.appendChild(area); tr.appendChild(statusCell(!!m.v19, '19.0')); tr.appendChild(statusCell(!!m.v20, '20.0')); ocaBody.appendChild(tr); }); } if (ocaBody) { fetch('https://n8n.odoo4projects.com/webhook/oc-guy/modules') .then(function (r) { if (!r.ok) throw new Error('http ' + r.status); return r.json(); }) .then(function (payload) { var rows = payload && Array.isArray(payload.data) ? payload.data : (Array.isArray(payload) ? payload : null); if (!rows || !rows.length) throw new Error('empty'); renderOca(rows); }) .catch(function () { /* keep the snapshot already in the markup */ }); } /* ---------- which section the reader is in ---------- */ var links = Array.prototype.slice.call(document.querySelectorAll('.nav a[href^="#"]')); var sections = links .map(function (a) { return document.querySelector(a.getAttribute('href')); }) .filter(Boolean); if (sections.length && 'IntersectionObserver' in window) { var seen = new IntersectionObserver(function (entries) { entries.forEach(function (entry) { if (!entry.isIntersecting) return; links.forEach(function (a) { if (a.getAttribute('href') === '#' + entry.target.id) { a.setAttribute('aria-current', 'true'); } else { a.removeAttribute('aria-current'); } }); }); }, { rootMargin: '-45% 0px -50% 0px' }); sections.forEach(function (s) { seen.observe(s); }); } })();