UNPKG

kasha

Version:

Pre-render your Single-Page Application.

317 lines (269 loc) 9.24 kB
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Kasha</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/png" href="/static/kasha.png"> <style> body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } .textbox, .select{ border: 1px solid #ccc; border-radius: 2px; height: 30px; } .textbox:disabled, .select:disabled { background-color: #ebebe4; } /* from https://medium.com/claritydesignsystem/pure-css-accessible-checkboxes-and-radios-buttons-54063e759bb3 */ .checkbox { position: absolute; left: -99999px; top: -99999px; opacity: 0; } .checkbox + label { position: relative; display: inline-block; /*16px width of fake checkbox + 6px distance between fake checkbox and text*/ padding-left: 22px; } .checkbox + label::before, .checkbox + label::after { position: absolute; content: ""; /*Needed for the line-height to take effect*/ display: inline-block; } /*Outer box of the fake checkbox*/ .checkbox + label::before{ height: 16px; width: 16px; border: 1px solid #ccc; border-radius: 2px; left: 0px; /*(24px line-height - 16px height of fake checkbox) / 2 - 1px for the border *to vertically center it. */ top: 3px; } /*Checkmark of the fake checkbox*/ .checkbox + label::after { height: 5px; width: 9px; border-left: 2px solid #377ef0; border-bottom: 2px solid #377ef0; transform: rotate(-45deg); left: 4px; top: 7px; } /*Hide the checkmark by default*/ .checkbox + label::after { content: none; } /*Unhide on the checked state*/ .checkbox:checked + label::after { content: ""; } /*Adding focus styles on the outer-box of the fake checkbox*/ .checkbox:focus + label::before { outline: #4d90fe auto 5px; } .checkbox:disabled + label::before { background-color: #ebebe4; } .form { width: fit-content; text-align: center; margin: 90px auto; } .address-box { border: none; border-radius: 2px; box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.2); width: 600px; height: 40px; padding-left: 1em; padding-right: 1em; box-sizing: border-box; } .address-box:hover, .address-box:focus { box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.2); } .btn-render { width: 76px; height: 42px; margin-left: 4px; background-color: #377ef0; border: 1px solid #377ef0; border-radius: 2px; box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16); color: #fff; font-weight: bold; cursor: pointer; } .btn-render:hover, .btn-render:focus { box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.2); } .fieldset { text-align: left; margin: 10px 0; border: 1px solid #ddd; border-radius: 2px; padding: 8px 16px 16px; } .opt { margin: 6px 0; } .callback-url-textbox { width: 500px; } </style> </head> <body> <form name="render" action="render" method="get" class="form" target="_blank"> <img src="/static/kasha.svg" alt="kasha logo" width="200"> <h1>Kasha</h1> <input type="url" name="url" required placeholder="https://www.example.com/" class="address-box"><button type="submit" class="btn-render">Render</button> <fieldset class="fieldset"> <legend>Options</legend> <div class="opt"><input type="checkbox" class="checkbox" name="fallback" value="" id="fallback"><label for="fallback">fallback</label></div> <div class="opt"><input type="checkbox" class="checkbox" name="refresh" value="" id="refresh"><label for="refresh">refresh</label></div> <div class="opt"><input type="checkbox" class="checkbox" name="metaOnly" value="" id="metaOnly"><label for="metaOnly">metaOnly</label></div> <div class="opt"><input type="checkbox" class="checkbox" name="noWait" value="" id="noWait"><label for="noWait">noWait</label></div> <div class="opt"><input type="checkbox" class="checkbox" name="followRedirect" value="" id="followRedirect"><label for="followRedirect">followRedirect</label></div> <div class="opt"> <label>type: <select name="type" class="select"> <option value="json">json</option> <option value="html">html</option> <option value="static">static (js stripped html)</option> </select> </label> </div> <div class="opt"> <label>profile: <input type="text" name="profile" placeholder="desktop" class="textbox"></label> </div> <div class="opt"><label>callbackURL: <input type="url" name="callbackURL" placeholder="https://api.example.com/callback" class="textbox callback-url-textbox"></label></div> </fieldset> <fieldset class="fieldset"> <legend>Sitemaps</legend> <ul> <li><a href="#" data-href="/robots.txt" target="_blank">/robots.txt</a></li> <li><a href="#" data-href="/sitemap.index.1.xml" target="_blank">/sitemap.index.1.xml</a></li> <li><a href="#" data-href="/sitemap.index.google.1.xml" target="_blank">/sitemap.index.google.1.xml</a></li> <li><a href="#" data-href="/sitemap.index.google.news.1.xml" target="_blank">/sitemap.index.google.news.1.xml</a></li> <li><a href="#" data-href="/sitemap.index.google.image.1.xml" target="_blank">/sitemap.index.google.image.1.xml</a></li> <li><a href="#" data-href="/sitemap.index.google.video.1.xml" target="_blank">/sitemap.index.google.video.1.xml</a></li> <li><a href="#" data-href="/sitemap.1.xml" target="_blank">/sitemap.1.xml</a></li> <li><a href="#" data-href="/sitemap.google.1.xml" target="_blank">/sitemap.google.1.xml</a></li> <li><a href="#" data-href="/sitemap.google.news.1.xml" target="_blank">/sitemap.google.news.1.xml</a></li> <li><a href="#" data-href="/sitemap.google.image.1.xml" target="_blank">/sitemap.google.image.1.xml</a></li> <li><a href="#" data-href="/sitemap.google.video.1.xml" target="_blank">/sitemap.google.video.1.xml</a></li> <li><a href="#" data-href="/sitemap.debug" data-append-path target="_blank">/sitemap.debug</a></li> </ul> </fieldset> </form> <script> const form = document.forms.render.elements ;[form.fallback, form.refresh, form.metaOnly, form.noWait, form.type, form.callbackURL].forEach(el => el.addEventListener('change', updateInputsState) ) function updateInputsState() { if (this !== form.fallback) { if (form.type.value !== 'html' || form.refresh.checked || form.noWait.checked || form.callbackURL.value) { form.fallback.disabled = true form.fallback.checked = false } else { form.fallback.disabled = false } } if (this !== form.refresh) { if (form.fallback.checked) { form.refresh.disabled = true form.refresh.checked = false } else { form.refresh.disabled = false } } if (this !== form.metaOnly) { if (form.type.value !== 'json' || form.noWait.checked) { form.metaOnly.disabled = true form.metaOnly.checked = false } else { form.metaOnly.disabled = false } } if (this !== form.noWait) { if (form.fallback.checked || form.callbackURL.value) { form.noWait.disabled = true form.noWait.checked = false } else { form.noWait.disabled = false } } if (this !== form.type) { if (form.fallback.checked) { form.type.value = 'html' form.type.options[0].disabled = form.type.options[2].disabled = true } else if (form.metaOnly.checked) { form.type.disabled = true form.type.value = 'json' } else if (form.noWait.checked) { form.type.disabled = true form.type.value = 'json' } else if (form.callbackURL.value) { form.type.disabled = true form.type.value = 'json' } else { form.type.disabled = false form.type.options[0].disabled = form.type.options[1].disabled = form.type.options[2].disabled = false } } if (this !== form.callbackURL) { if (form.fallback.checked || form.noWait.checked || ['html', 'static'].includes(form.type.value)) { form.callbackURL.disabled = true form.callbackURL.value = '' } else { form.callbackURL.disabled = false } } } const urlInput = form.url const sitemapLinks = document.querySelectorAll('a[data-href]') for (const link of sitemapLinks) { link.addEventListener('click', e => { if (!urlInput.reportValidity()) { e.preventDefault() } }) } urlInput.addEventListener('change', function() { let url try { url = new URL(this.value) } catch (e) {} for (const link of sitemapLinks) { if (url) { if (link.dataset.appendPath === '') { link.href = `/${url.origin}${link.dataset.href}${url.pathname}` link.textContent = `${link.dataset.href}${url.pathname}` } else { link.href = `/${url.origin}${link.dataset.href}` } } else { link.href = '#' if (link.dataset.appendPath === '') { link.textContent = link.dataset.href } } } }) </script> </body> </html>