Refactor web frontend and remove unnecessary dependencies.
- Eliminate frontend JS build step completely: (remove dep: NodeJS, npx, tailwind, postcss, autoprefixer) - Declutter and cleanup index.html (8.49 KB to 3.4 KB) = ~60% savings. - Replace tailwind with custom CSS (10.64 KB to 1.96 KB) = ~81% savings. - Remove Google font (~100 KB) as there is very little text on the page. - Refactor and cleanup main.js and remove tailwind styling logic. (2.82 KB to 1.12 KB) = ~60% savings. - Net static asset reduction = 21.95 KB to 6.48 KB = ~70% savings apart from the 100+ KB elimination of Google fonts.
This commit is contained in:
parent
0dc61ac8ec
commit
b8ba782cf3
5 changed files with 337 additions and 1435 deletions
|
|
@ -1,154 +1,90 @@
|
|||
const $ = document.querySelector.bind(document);
|
||||
const $new = document.createElement.bind(document);
|
||||
const apiURL = "/api/lookup/";
|
||||
const isMobile = window.matchMedia("only screen and (max-width: 760px)").matches;
|
||||
|
||||
function handleNSChange() {
|
||||
if ($('select[name=ns]').value == "custom") {
|
||||
$('div[id=custom_ns]').classList.remove("hidden");
|
||||
$('div[id=ns]').classList.add("hidden");
|
||||
} else {
|
||||
$('div[id=custom_ns]').classList.add("hidden");
|
||||
$('div[id=ns]').classList.remove("hidden");
|
||||
$('input[name=ns]').placeholder = $('select[name=ns]').value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Source: https://stackoverflow.com/a/1026087.
|
||||
function capitalizeFirstLetter(string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', (event) => {
|
||||
handleNSChange();
|
||||
});
|
||||
const $show = (el) => {
|
||||
el.classList.remove('hidden');
|
||||
};
|
||||
const $hide = (el) => {
|
||||
el.classList.add('hidden');
|
||||
};
|
||||
|
||||
const apiURL = '/api/lookup/';
|
||||
|
||||
(function () {
|
||||
const fields = ['name', 'address', 'type', 'ttl', 'rtt', 'nameserver'];
|
||||
const fields = ['name', 'address', 'type', 'ttl', 'rtt'];
|
||||
|
||||
// createRow creates a table row with the given cell values.
|
||||
function createRow(item) {
|
||||
const tr = $new('tr');
|
||||
fields.forEach((f) => {
|
||||
const td = $new('td');
|
||||
td.classList.add("px-6", "py-4", "whitespace-nowrap", "text-sm");
|
||||
if (f == "ttl" || f == "rtt" || f == "nameserver") {
|
||||
td.classList.add("text-gray-500");
|
||||
} else {
|
||||
td.classList.add("text-gray-900");
|
||||
}
|
||||
if (f == "name") {
|
||||
td.classList.add("font-semibold");
|
||||
}
|
||||
if (f == "type") {
|
||||
td.innerHTML = '<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">' + item[f] + '</span>';
|
||||
} else {
|
||||
td.innerText = item[f];
|
||||
}
|
||||
td.innerText = item[f];
|
||||
td.classList.add(f);
|
||||
tr.appendChild(td);
|
||||
});
|
||||
return tr;
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const tbody = $('#table tbody'),
|
||||
tbl = $('#table');
|
||||
tbody.innerHTML = '';
|
||||
$hide(tbl);
|
||||
|
||||
// `createList` creates a table row with the given cell values.
|
||||
function createList(item) {
|
||||
const ul = $new('ul');
|
||||
ul.classList.add("m-4", "block", "bg-indigo-100");
|
||||
fields.forEach((f) => {
|
||||
const li = $new('li');
|
||||
const span = $new('span');
|
||||
span.classList.add("p-2", "text-gray-500", "font-semibold");
|
||||
span.innerText = capitalizeFirstLetter(f) + ': ' + item[f]
|
||||
li.appendChild(span);
|
||||
ul.appendChild(li);
|
||||
});
|
||||
return ul;
|
||||
}
|
||||
const q = $('input[name=q]').value.trim(),
|
||||
typ = $('select[name=type]').value,
|
||||
addr = $('input[name=address]').value.trim();
|
||||
|
||||
function prepareNSAddr(ns) {
|
||||
switch (ns) {
|
||||
// If it's a custom nameserver, get the value from the user's input.
|
||||
case "custom":
|
||||
return $('input[name=custom_ns]').value.trim()
|
||||
// Else get it from the select dropdown field.
|
||||
default:
|
||||
return $('select[name=ns]').value.trim()
|
||||
}
|
||||
}
|
||||
// Post to the API.
|
||||
const req = await fetch(apiURL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ query: [q,], type: [typ,], nameservers: [addr,] })
|
||||
});
|
||||
|
||||
const postForm = body => {
|
||||
return fetch(apiURL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body
|
||||
});
|
||||
};
|
||||
const res = await req.json();
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const tbl = $('table tbody');
|
||||
const list = $('div[id=mobile-answers-sec]');
|
||||
tbl.innerHTML = '';
|
||||
list.innerHTML = '';
|
||||
|
||||
$('p[id=empty-name-sec]').classList.add("hidden");
|
||||
const errSec = $('div[id=api-error-sec]');
|
||||
errSec.classList.add("hidden");
|
||||
|
||||
const q = $('input[name=q]').value.trim(), typ = $('select[name=type]').value;
|
||||
const ns = $('select[name=ns]').value;
|
||||
|
||||
if (!q) {
|
||||
$('p[id=empty-name-sec]').classList.remove("hidden");
|
||||
throw ('Invalid query name.');
|
||||
}
|
||||
|
||||
if (!q || !typ || !ns) {
|
||||
throw ('Invalid or empty query params.');
|
||||
}
|
||||
|
||||
const nsAddr = prepareNSAddr(ns);
|
||||
const body = JSON.stringify({ query: [q,], type: [typ,], nameservers: [nsAddr,] });
|
||||
|
||||
const response = await postForm(body);
|
||||
const res = await response.json();
|
||||
if (res.status != "success") {
|
||||
// get error message from body or default to response statusText
|
||||
if (res.status != 'success') {
|
||||
const error = (res && res.message) || response.statusText;
|
||||
errSec.classList.remove("hidden");
|
||||
errSec.innerHTML = '<p class="text-xl text-red-500">' + error + '</p>'
|
||||
throw (error);
|
||||
throw(error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (res.data[0].answers == null) {
|
||||
const errSec = $('div[id=api-error-sec]');
|
||||
errSec.classList.remove("hidden");
|
||||
errSec.innerHTML = '<p class="text-xl text-red-500">' + 'No records found!' + '</p>'
|
||||
return null;
|
||||
throw('No records found.');
|
||||
return;
|
||||
}
|
||||
|
||||
$('div[id=answer_sec]').classList.remove("hidden");
|
||||
|
||||
if (isMobile === true) {
|
||||
list.classList.remove("hidden");
|
||||
res.data[0].answers.forEach((item) => {
|
||||
console.log("appending", item)
|
||||
list.appendChild(createList(item));
|
||||
});
|
||||
|
||||
} else {
|
||||
res.data[0].answers.forEach((item) => {
|
||||
tbl.appendChild(createRow(item));
|
||||
});
|
||||
}
|
||||
res.data[0].answers.forEach((item) => {
|
||||
tbody.appendChild(createRow(item));
|
||||
});
|
||||
|
||||
$show(tbl);
|
||||
};
|
||||
|
||||
document.querySelector('form').addEventListener('submit', handleSubmit);
|
||||
// Capture the form submit.
|
||||
$('#form').onsubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const msg = $('#message');
|
||||
$hide(msg);
|
||||
|
||||
try {
|
||||
await handleSubmit();
|
||||
} catch(e) {
|
||||
msg.innerText = e.toString();
|
||||
$show(msg);
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
// Change the address on ns change.
|
||||
const ns = $("#ns"), addr = $("#address");
|
||||
addr.value = ns.value;
|
||||
|
||||
ns.onchange = (e) => {
|
||||
addr.value = e.target.value;
|
||||
if(addr.value === "") {
|
||||
addr.focus();
|
||||
}
|
||||
};
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue