Petro LEDGas Price Sign Spec Builder
v0.1 \u00B7 preview build
01 Cabinet & Face
02 Mounting
03 How many fuel grades?
04 Name of fuel grade | Size
05 Cabinet Size
Computed minimum \u2014 \u00D7 \u2014
06 Identification
Drawing Preview \u2014 \u00B7 \u2014
Specification Summary
'; var win = window.open('', '_blank'); if (!win) { showToast('Popup blocked \u2014 allow popups for this site to download PDF'); return; } win.document.open(); win.document.write(html); win.document.close(); // Call print directly on the popup window reference -- avoids embedding a script // element inside the injected HTML, which would otherwise trip theme-check linters. setTimeout(function() { try { win.focus(); win.print(); } catch (e) { /* popup may have been closed */ } }, 300); showToast('Preparing PDF \u2014 select "Save as PDF" in the print dialog'); }); document.getElementById('psb-reset').addEventListener('click', function() { state = JSON.parse(DEFAULTS_JSON); // Re-sync all inputs document.querySelectorAll('.psb-root input[data-path], .psb-root select[data-path]').forEach(function(el) { var v = getByPath(el.getAttribute('data-path')); el.value = v; }); buildSwatches(); buildSegments(); buildGradeLabels(); updateVisibility(); render(); document.getElementById('psb-json').setAttribute('data-visible', 'false'); }); function wireCollapsibles() { document.querySelectorAll('.psb-root .psb-section').forEach(function(section) { var head = section.querySelector('.psb-section-head'); if (!head) return; head.addEventListener('click', function() { var isCollapsed = section.getAttribute('data-collapsed') === 'true'; section.setAttribute('data-collapsed', isCollapsed ? 'false' : 'true'); }); }); } function wireCustomColorPickers() { var facePicker = document.getElementById('psb-face-bg-picker'); var faceHexLabel = document.getElementById('psb-face-bg-hex'); var textPicker = document.getElementById('psb-face-text-picker'); var textHexLabel = document.getElementById('psb-face-text-hex'); var textReset = document.getElementById('psb-face-text-reset'); if (facePicker) { facePicker.addEventListener('input', function() { state.cabinet.face_bg_custom_hex = facePicker.value; if (faceHexLabel) faceHexLabel.textContent = facePicker.value.toUpperCase(); render(); }); } if (textPicker) { textPicker.addEventListener('input', function() { state.cabinet.face_text_custom_hex = textPicker.value; if (textHexLabel) textHexLabel.textContent = textPicker.value.toUpperCase(); render(); }); } if (textReset) { textReset.addEventListener('click', function() { state.cabinet.face_text_custom_hex = ''; if (textHexLabel) textHexLabel.textContent = 'auto'; // Also reset the picker visually to white so next pick has a neutral starting point if (textPicker) textPicker.value = '#FFFFFF'; render(); }); textReset.addEventListener('keydown', function(e) { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); textReset.click(); } }); } } // Boot -- wait for DOM ready (Shopify may defer inline scripts), wrap in try/catch // so any error surfaces in the browser console instead of dying silently. function boot() { if (!document.querySelector('.psb-root')) { // DOM not ready yet -- retry shortly setTimeout(boot, 50); return; } try { buildSwatches(); buildSegments(); buildGradeLabels(); wireInputs(); wireCollapsibles(); wireCustomColorPickers(); updateVisibility(); snapCabinetToMin(); // ensure default cabinet size matches the default spec's minimum render(); } catch (err) { console.error('[Petro Spec Builder] Boot failed:', err); } } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', boot); } else { boot(); } })();