// SGF host wrapper only; the shared purchasing package remains unchanged. document.addEventListener('DOMContentLoaded', () => { const dirty = new Set(); let pending=0; for(const form of document.querySelectorAll('form[data-action]')){ const submit=form.onsubmit; if(typeof submit!=='function')continue; form.onsubmit=async e=>{ pending++; try{await submit.call(form,e);if(!document.querySelector('#error')?.textContent.trim())dirty.delete(form);} finally{pending--;} }; } document.addEventListener('input', e => { const form=e.target.closest('form');if(form)dirty.add(form); }); window.addEventListener('beforeunload', e => { if(dirty.size||pending){e.preventDefault();e.returnValue='';} }); const back=document.querySelector('[data-sgf-module-back]'); back?.addEventListener('click', e => { if(pending){e.preventDefault();document.querySelector('#error').textContent='Aguarde a conclusão da operação antes de sair.';return;} if(!dirty.size)return; e.preventDefault(); const dialog=document.createElement('dialog'); dialog.setAttribute('aria-label','Alterações por guardar'); dialog.innerHTML='
Guarde, descarte ou cancele a saída deste percurso.
'; document.body.append(dialog);dialog.showModal(); const close=()=>{dialog.close();dialog.remove();back.focus();}; dialog.querySelector('[data-cancel]').onclick=close; dialog.addEventListener('cancel',e=>{e.preventDefault();close();}); dialog.querySelector('[data-discard]').onclick=()=>{dirty.clear();location.assign(back.href);}; dialog.querySelector('[data-save]').onclick=async()=>{ for(const b of dialog.querySelectorAll('button'))b.disabled=true; try{ if(dirty.size>1)throw Error('Guarde cada formulário no percurso original antes de sair. O contexto foi mantido.'); for(const form of [...dirty]){ if(!form.isConnected){dirty.delete(form);continue;} if(!form.reportValidity())throw Error('Corrija os campos. O contexto foi mantido.'); if(typeof form.onsubmit!=='function')throw Error('Guarde no formulário original antes de sair.'); // Existing package handlers validate, post and report errors in #error. // Successful handlers reload their own page; this destination supersedes // that reload only after the original promise has completed successfully. await form.onsubmit({preventDefault(){}}); if(document.querySelector('#error')?.textContent.trim())throw Error('A gravação falhou. O contexto foi mantido.'); dirty.delete(form); } location.assign(back.href); }catch(error){dialog.querySelector('[role=alert]').textContent=error.message;} finally{for(const b of dialog.querySelectorAll('button'))b.disabled=false;} }; }); });