`).join(''); toolGrid.addEventListener('click', (e) => { if (e.target.classList.contains('btn')) openModal(e.target.getAttribute('data-tool-id')); }); const closeModal = () => modal.classList.remove('show'); closeBtn.onclick = closeModal; modal.addEventListener('click', (e) => { if (e.target === modal) closeModal(); }); function openModal(toolId) { const tool = tools.find(t => t.id === toolId); modalHost.innerHTML = getToolHTML(toolId, tool.title); modal.classList.add('show'); attachToolListener(toolId, tool.type); } function getToolHTML(toolId, title) { let html = `
${title}
`; const tool = tools.find(t => t.id === toolId); if (tool.type === 'demo_url') { html += `
`; } else if (toolId === 'metaGenerator' || toolId === 'ogGenerator') { html += `
`; } else if (toolId === 'robotsGenerator') { html += `
Default: Allow All
`; } else if (toolId === 'htaccessGenerator' || toolId === 'urlRewriter') { html += `
`; } else if (toolId === 'codeMinifier' || toolId === 'codeFormatter' || toolId === 'jsonToolkit' || toolId === 'metaAnalyser' || toolId === 'xmlFormatter') { html += `
`; } else if (toolId === 'htmlEditor') { html += `
`; } else if (toolId === 'linkTracker') { html += `
`; } else if (toolId === 'hitCounter') { html += `
This counter tracks visits to this page using your browser's local storage.
`; } html += `
`; return html; } function attachToolListener(toolId, type) { const actionBtn = modal.querySelector('#action-btn'); const resultDiv = modal.querySelector('#tool-result-output'); if (type === 'demo_url') { actionBtn.onclick = () => { const url = modal.querySelector('#tool-input-url').value; if (!url.startsWith('http')) { resultDiv.textContent = 'Please enter a valid URL.'; return; } resultDiv.innerHTML = `Analyzing ${url}...`; setTimeout(() => displayDemoResults(toolId, resultDiv), 1500); }; return; } // Functional tools logic switch(toolId) { case 'metaGenerator': case 'ogGenerator': actionBtn.onclick = () => { const title = modal.querySelector('#gen-title').value; const desc = modal.querySelector('#gen-desc').value; let tags = `<title>${title}</title>\n<meta name="description" content="${desc}">`; if (toolId === 'ogGenerator') { const img = modal.querySelector('#gen-image').value; tags += `\n<meta property="og:title" content="${title}">\n<meta property="og:description" content="${desc}">\n<meta property="og:image" content="${img}">`; } resultDiv.innerHTML = tags; }; break; case 'robotsGenerator': actionBtn.onclick = () => { const disallowAll = modal.querySelector('#disallow-all').checked; const extra = modal.querySelector('#robots-extra').value; let content = `User-agent: *\n`; content += disallowAll ? `Disallow: /` : `Disallow:`; if (extra) content += `\n\n${extra}`; resultDiv.textContent = content; }; break; case 'htaccessGenerator': actionBtn.onclick = () => { const oldUrl = modal.querySelector('#old-url').value; const newUrl = modal.querySelector('#new-url').value; resultDiv.textContent = `RewriteEngine On\nRewriteRule ^${new URL(oldUrl).pathname.substring(1)}$ ${newUrl} [R=301,L]`; }; break; case 'urlRewriter': actionBtn.onclick = () => { const oldUrl = modal.querySelector('#old-url').value; const newUrl = modal.querySelector('#new-url').value; resultDiv.textContent = `Dynamic URL: ${oldUrl}\nStatic URL: ${newUrl}\n\nThis tool demonstrates the concept. Implementation requires server-side (.htaccess) rules.`; }; break; case 'codeMinifier': actionBtn.onclick = () => { const type = modal.querySelector('#code-type').value; let code = modal.querySelector('#code-input').value; if (type === 'js') code = code.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '$1'); // remove comments resultDiv.textContent = code.replace(/\s+/g, ' ').trim(); }; break; case 'codeFormatter': case 'xmlFormatter': case 'jsonToolkit': modal.querySelector('#code-type').value = toolId === 'xmlFormatter' ? 'xml' : 'json'; actionBtn.onclick = () => { const type = modal.querySelector('#code-type').value; const code = modal.querySelector('#code-input').value; try { if(type === 'json') { const obj = JSON.parse(code); resultDiv.textContent = JSON.stringify(obj, null, 2); if(toolId==='jsonToolkit'){ // Add validation & HTML conversion for the toolkit resultDiv.innerHTML += "
Validation: JSON is valid.
"; resultDiv.innerHTML += `
HTML Table:
${jsonToTable(obj)}`; } } else { resultDiv.textContent = "Formatting for this code type is a demonstration."; } } catch(e) { resultDiv.textContent = "Error: Invalid code format. " + e.message; } }; break; case 'htmlEditor': modal.querySelector('#code-input').onkeyup = (e) => { modal.querySelector('#preview-pane').srcdoc = e.target.value; }; break; case 'linkTracker': actionBtn.onclick = () => { const url = modal.querySelector('#utm-url').value; const source = modal.querySelector('#utm-source').value; const medium = modal.querySelector('#utm-medium').value; const campaign = modal.querySelector('#utm-campaign').value; resultDiv.textContent = `${url}?utm_source=${source}&utm_medium=${medium}&utm_campaign=${campaign}`; }; break; case 'metaAnalyser': actionBtn.onclick = () => { const html = modal.querySelector('#code-input').value; const titleMatch = html.match(/
(.*?)<\/title>/); const descMatch = html.match(/Title: ${titleMatch ? titleMatch[1] : 'Not Found'}
Description: ${descMatch ? descMatch[1] : 'Not Found'}`; }; break; case 'hitCounter': const countEl = modal.querySelector('#hit-count'); let hits = parseInt(localStorage.getItem('pageHits_seo_demo') || '0'); hits++; countEl.textContent = hits.toLocaleString(); localStorage.setItem('pageHits_seo_demo', hits); break; } } function displayDemoResults(toolId, resultDiv) { const rand = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; let html = ``; switch(toolId) { case 'seoScore': html += `| Overall SEO Score | ${rand(60, 95)}/100 |
| On-Page SEO | Good |
| Backlinks | ${rand(50, 5000).toLocaleString()} |
`; break; case 'pageSpeed': html += `| Performance Score | ${rand(70, 98)} |
| First Contentful Paint | ${(rand(8, 20)/10)}s |
| Time to Interactive | ${(rand(15, 40)/10)}s |
`; break; case 'pageSize': html += `| Total Page Size | ${(rand(500, 4000))} KB |
| Image Size | ${rand(200, 2000)} KB |
| Script Size | ${rand(100, 1000)} KB |
`; break; case 'domainAuthority': html += `| Domain Authority | ${rand(20, 80)} |
`; break; case 'pageAuthority': html += `| Page Authority | ${rand(15, 70)} |
`; break; case 'mozrank': html += `| MozRank | ${(rand(20, 70)/10).toFixed(2)} |
`; break; case 'spamScore': html += `| Spam Score | ${rand(1, 15)}% |
`; break; case 'domainAge': html += `| Domain Age | ${rand(2, 15)} years, ${rand(1,12)} months |
`; break; case 'googleIndex': html += `| Index Status | Indexed Successfully |
`; break; case 'sslChecker': html += `| SSL Status | Valid & Active |
| Issuer | Let's Encrypt |
`; break; default: html = `This is a functional UI demonstration. A real ${tools.find(t=>t.id===toolId).title} requires complex server-side processing.
`; break; } resultDiv.innerHTML = html + `
`; } function jsonToTable(obj) { let table = ''; const arr = Array.isArray(obj) ? obj : [obj]; // Header table += ''; for (const key in arr[0]) { table += `| ${key} | `; } table += '
'; // Rows arr.forEach(row => { table += ''; for (const key in row) { table += `| ${typeof row[key] === 'object' ? JSON.stringify(row[key]) : row[key]} | `; } table += '
'; }); return table + '
'; } })();