p2ns.admin updates for local DNS

This commit is contained in:
Raven Scott
2026-05-30 21:20:15 -04:00
parent a37daab971
commit 1c6419f7ce
4 changed files with 798 additions and 153 deletions
+62 -39
View File
@@ -432,6 +432,7 @@ window.tabs = {
filteredKey: 'filteredLocalDns',
containerId: 'localDnsTable',
paginationId: 'localDnsPagination',
sentinelId: 'localDnsScrollSentinel',
sort: (a, b) => a.name.localeCompare(b.name, undefined, { sensitivity: 'base' }),
filter: (item, query) => {
const queryLower = query.toLowerCase();
@@ -442,36 +443,40 @@ window.tabs = {
);
},
renderItem: (item) => {
let valueStr = '';
if (item.type === 'MX') {
valueStr = `${item.preference || ''} ${item.exchange || ''}`.trim();
} else if (item.type === 'SRV') {
valueStr = `${item.priority || ''} ${item.weight || ''} ${item.port || ''} ${item.target || ''}`.trim();
} else if (item.type === 'SOA') {
valueStr = `${item.mname || ''} ${item.rname || ''} ${item.serial || ''} ${item.refresh || ''} ${item.retry || ''} ${item.expire || ''} ${item.minimum || ''}`.trim();
} else if (item.type === 'CAA') {
valueStr = `${item.flags || ''} ${item.tag || ''} ${item.value || ''}`.trim();
} else {
valueStr = item.data || item.value || '';
}
const esc = window.escapeHtml || ((value) => String(value));
const typeInfo = window.classifyDnsRecordType ? window.classifyDnsRecordType(item.type) : { label: item.type, className: 'dns-type-badge--muted' };
const valueStr = window.formatLocalDnsValue ? window.formatLocalDnsValue(item) : (item.data || item.value || '');
const tr = document.createElement('tr');
tr.className = 'border-b hover:bg-gray-50 dark:hover:bg-gray-700';
tr.className = 'local-dns-row';
tr.innerHTML = `
<td class="p-3">${item.name}</td>
<td class="p-3">${item.type}</td>
<td class="p-3 break-all">${valueStr}</td>
<td class="p-3">${item.ttl}</td>
<td class="p-3">
<button onclick="editLocalDns(${item.index})" class="px-2 py-1 bg-blue-500 text-white rounded hover:bg-blue-600 mr-2">Edit</button>
<button onclick="deleteLocalDns(${item.index})" class="px-2 py-1 bg-red-500 text-white rounded hover:bg-red-600">Delete</button>
<td class="p-3"><code class="local-dns-name">${esc(item.name)}</code></td>
<td class="p-3"><span class="dns-type-badge ${typeInfo.className}">${esc(typeInfo.label)}</span></td>
<td class="p-3"><span class="local-dns-value">${esc(valueStr)}</span></td>
<td class="p-3 tabular-nums">${esc(String(item.ttl ?? ''))}</td>
<td class="p-3 text-right">
<div class="local-dns-row-actions">
<button type="button" class="admin-btn admin-btn--secondary admin-btn--sm" onclick="editLocalDns(${item.index})" title="Edit record">
<i class="fas fa-pen" aria-hidden="true"></i>
</button>
<button type="button" class="admin-btn admin-btn--danger admin-btn--sm" onclick="deleteLocalDns(${item.index})" title="Delete record">
<i class="fas fa-trash" aria-hidden="true"></i>
</button>
</div>
</td>`;
return tr;
},
preRender: (visibleCount) => {
if (window.updateLocalDnsChrome) window.updateLocalDnsChrome(visibleCount);
},
onAllItemsLoaded: () => {
if (window.showLocalDnsListEnd) window.showLocalDnsListEnd();
},
postFetch: (data) => {
window.dnsConflictsData = data.conflicts || [];
window.filteredDnsConflicts = window.dnsConflictsData;
data.records = data.records.map((rec, index) => ({ ...rec, index }));
if (window.renderDnsConflicts) window.renderDnsConflicts();
if (window.updateLocalDnsSubtabBadges) window.updateLocalDnsSubtabBadges();
return data.records;
}
},
@@ -482,28 +487,37 @@ window.tabs = {
filteredKey: 'filteredDnsConflicts',
containerId: 'dnsConflictsTable',
paginationId: 'dnsConflictsPagination',
sentinelId: 'dnsConflictsScrollSentinel',
sort: (a, b) => a.domain.localeCompare(b.domain, undefined, { sensitivity: 'base' }),
filter: (item, query) => item.domain.toLowerCase().includes(query) || item.version.toLowerCase().includes(query) || item.publicIP.toLowerCase().includes(query),
renderItem: (item) => {
const esc = window.escapeHtml || ((value) => String(value));
const domainAttr = esc(item.domain).replace(/"/g, '&quot;');
const isPublic = item.version === 'public';
const tr = document.createElement('tr');
tr.className = 'border-b hover:bg-gray-50 dark:hover:bg-gray-700';
tr.className = 'local-dns-row';
tr.innerHTML = `
<td class="p-3">${item.domain}</td>
<td class="p-3">${item.publicIP}</td>
<td class="p-3"><code class="local-dns-name">${esc(item.domain)}</code></td>
<td class="p-3"><span class="local-dns-value">${esc(item.publicIP || '—')}</span></td>
<td class="p-3">
<label class="inline-flex items-center cursor-pointer">
<span class="mr-2">${item.version === 'public' ? 'Public' : 'P2P'}</span>
<input type="checkbox" ${item.version === 'public' ? 'checked' : ''} onchange="toggleVersionPreference('${item.domain}', this.checked)" class="sr-only peer">
<div class="relative w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-primary rounded-full peer peer-checked:bg-primary">
<div class="absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full transition-transform peer-checked:translate-x-5"></div>
</div>
<label class="local-dns-toggle">
<span class="local-dns-toggle-label">${isPublic ? 'Public' : 'P2P'}</span>
<input type="checkbox" class="sr-only" ${isPublic ? 'checked' : ''} data-domain="${domainAttr}" onchange="toggleVersionPreference(this.dataset.domain, this.checked)">
<span class="plugin-toggle-switch" aria-hidden="true"></span>
</label>
</td>`;
return tr;
},
preRender: (visibleCount) => {
if (window.updateDnsConflictsChrome) window.updateDnsConflictsChrome(visibleCount);
},
onAllItemsLoaded: () => {
if (window.showDnsConflictsListEnd) window.showDnsConflictsListEnd();
},
postFetch: (data) => {
window.localDnsData = data.records.map((rec, index) => ({ ...rec, index }));
window.filteredLocalDns = window.localDnsData;
if (window.updateLocalDnsSubtabBadges) window.updateLocalDnsSubtabBadges();
return data.conflicts || [];
}
},
@@ -514,27 +528,36 @@ window.tabs = {
filteredKey: 'filteredP2pDomainConflicts',
containerId: 'p2pDomainConflictsTable',
paginationId: 'p2pDomainConflictsPagination',
sentinelId: 'p2pDomainConflictsScrollSentinel',
sort: (a, b) => a.domain.localeCompare(b.domain, undefined, { sensitivity: 'base' }),
filter: (item, query) => item.domain.toLowerCase().includes(query) || item.localHash.toLowerCase().includes(query) || item.resolvedHash.toLowerCase().includes(query),
renderItem: (item) => {
const esc = window.escapeHtml || ((value) => String(value));
const domainAttr = esc(item.domain).replace(/"/g, '&quot;');
const useLocal = item.hashPreference === 'local';
const tr = document.createElement('tr');
tr.className = 'border-b hover:bg-gray-50 dark:hover:bg-gray-700';
tr.className = 'local-dns-row';
tr.innerHTML = `
<td class="p-3">${item.domain}</td>
<td class="p-3 break-all">${item.localHash || 'N/A'}</td>
<td class="p-3 break-all">${item.resolvedHash || 'N/A'}</td>
<td class="p-3"><code class="local-dns-name">${esc(item.domain)}</code></td>
<td class="p-3"><code class="local-dns-hash">${esc(item.localHash || 'N/A')}</code></td>
<td class="p-3"><code class="local-dns-hash">${esc(item.resolvedHash || 'N/A')}</code></td>
<td class="p-3">
<label class="inline-flex items-center cursor-pointer">
<span class="mr-2">${item.hashPreference === 'local' ? 'Local' : 'Resolved'}</span>
<input type="checkbox" ${item.hashPreference === 'local' ? 'checked' : ''} onchange="toggleHashPreference('${item.domain}', this.checked)" class="sr-only peer">
<div class="relative w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-primary rounded-full peer peer-checked:bg-primary">
<div class="absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full transition-transform peer-checked:translate-x-5"></div>
</div>
<label class="local-dns-toggle">
<span class="local-dns-toggle-label">${useLocal ? 'Local' : 'Resolved'}</span>
<input type="checkbox" class="sr-only" ${useLocal ? 'checked' : ''} data-domain="${domainAttr}" onchange="toggleHashPreference(this.dataset.domain, this.checked)">
<span class="plugin-toggle-switch" aria-hidden="true"></span>
</label>
</td>`;
return tr;
},
preRender: (visibleCount) => {
if (window.updateP2pConflictsChrome) window.updateP2pConflictsChrome(visibleCount);
},
onAllItemsLoaded: () => {
if (window.showP2pConflictsListEnd) window.showP2pConflictsListEnd();
},
postFetch: (data) => {
if (window.updateLocalDnsSubtabBadges) window.updateLocalDnsSubtabBadges();
return data.conflicts || [];
}
},
+223 -9
View File
@@ -1,4 +1,196 @@
// Local DNS UI functions
const LOCAL_DNS_FIELD = 'theme-input w-full';
function classifyDnsRecordType(type) {
const t = String(type || '').toUpperCase();
if (t === 'A' || t === 'AAAA') return { label: t, className: 'dns-type-badge--address' };
if (t === 'CNAME') return { label: t, className: 'dns-type-badge--cname' };
if (t === 'MX' || t === 'TXT') return { label: t, className: 'dns-type-badge--mail' };
if (t === 'SRV' || t === 'NS' || t === 'PTR') return { label: t, className: 'dns-type-badge--service' };
return { label: t || 'OTHER', className: 'dns-type-badge--muted' };
}
function formatLocalDnsValue(item) {
if (!item) return '';
if (item.type === 'MX') {
return `${item.preference || ''} ${item.exchange || ''}`.trim();
}
if (item.type === 'SRV') {
return `${item.priority || ''} ${item.weight || ''} ${item.port || ''} ${item.target || ''}`.trim();
}
if (item.type === 'SOA') {
return `${item.mname || ''} ${item.rname || ''} ${item.serial || ''} ${item.refresh || ''} ${item.retry || ''} ${item.expire || ''} ${item.minimum || ''}`.trim();
}
if (item.type === 'CAA') {
return `${item.flags || ''} ${item.tag || ''} ${item.value || ''}`.trim();
}
return item.data || item.value || '';
}
function computeLocalDnsStats(data) {
const records = Array.isArray(data) ? data : [];
let address = 0;
let cname = 0;
let other = 0;
for (const rec of records) {
const type = String(rec?.type || '').toUpperCase();
if (type === 'A' || type === 'AAAA') address += 1;
else if (type === 'CNAME') cname += 1;
else other += 1;
}
return { total: records.length, address, cname, other };
}
function setSubtabBadge(id, count) {
const el = document.getElementById(id);
if (!el) return;
if (count > 0) {
el.textContent = count.toLocaleString();
el.hidden = false;
} else {
el.hidden = true;
}
}
function updateLocalDnsSubtabBadges() {
setSubtabBadge('localDnsSubtabBadge', (window.localDnsData || []).length);
setSubtabBadge('dnsConflictsSubtabBadge', (window.dnsConflictsData || []).length);
setSubtabBadge('p2pConflictsSubtabBadge', (window.p2pDomainConflictsData || []).length);
}
function updateListChrome({ totalData, filteredData, searchId, emptyId, filteredEmptyId, tableSelector, endId, countId, countEmptyLabel, countSingular, countPlural }) {
const totalCount = (totalData || []).length;
const visibleCount = (filteredData || totalData || []).length;
const searchEl = document.getElementById(searchId);
const hasSearch = Boolean(searchEl?.value?.trim());
const trulyEmpty = totalCount === 0;
const filteredToZero = !trulyEmpty && visibleCount === 0 && hasSearch;
const emptyEl = document.getElementById(emptyId);
const filteredEmptyEl = document.getElementById(filteredEmptyId);
const endEl = document.getElementById(endId);
const tableEl = document.querySelector(tableSelector);
const countEl = document.getElementById(countId);
if (emptyEl) emptyEl.classList.toggle('local-dns-empty--visible', trulyEmpty);
if (filteredEmptyEl) filteredEmptyEl.classList.toggle('local-dns-empty--visible', filteredToZero);
if (tableEl) tableEl.classList.toggle('local-dns-table--hidden', trulyEmpty || filteredToZero);
if (endEl) endEl.classList.remove('local-dns-list-end--visible');
if (countEl) {
if (trulyEmpty) {
countEl.textContent = countEmptyLabel;
} else if (hasSearch && visibleCount !== totalCount) {
countEl.textContent = `${visibleCount.toLocaleString()} of ${totalCount.toLocaleString()} shown`;
} else {
const noun = totalCount === 1 ? countSingular : countPlural;
countEl.textContent = `${totalCount.toLocaleString()} ${noun}`;
}
}
}
function updateLocalDnsChrome(filteredCount) {
const visibleCount = filteredCount != null
? filteredCount
: (window.filteredLocalDns || window.localDnsData || []).length;
updateListChrome({
totalData: window.localDnsData,
filteredData: window.filteredLocalDns,
searchId: 'search-local-dns',
emptyId: 'localDnsEmpty',
filteredEmptyId: 'localDnsFilteredEmpty',
tableSelector: '.local-dns-table',
endId: 'localDnsEnd',
countId: 'localDnsCount',
countEmptyLabel: 'No local DNS records',
countSingular: 'record',
countPlural: 'records'
});
const stats = computeLocalDnsStats(window.localDnsData || []);
const setStat = (id, value) => {
const el = document.getElementById(id);
if (el) el.textContent = value.toLocaleString();
};
setStat('localDnsStatTotal', stats.total);
setStat('localDnsStatAddress', stats.address);
setStat('localDnsStatCname', stats.cname);
setStat('localDnsStatOther', stats.other);
const overviewEl = document.getElementById('localDnsOverviewLine');
if (overviewEl) {
overviewEl.textContent = stats.total === 0
? 'No overrides configured'
: `${stats.address} address · ${stats.cname} CNAME`;
}
updateLocalDnsSubtabBadges();
}
function updateDnsConflictsChrome(filteredCount) {
updateListChrome({
totalData: window.dnsConflictsData,
filteredData: window.filteredDnsConflicts,
searchId: 'search-dns-conflicts',
emptyId: 'dnsConflictsEmpty',
filteredEmptyId: 'dnsConflictsFilteredEmpty',
tableSelector: '.local-dns-conflicts-table',
endId: 'dnsConflictsEnd',
countId: 'dnsConflictsCount',
countEmptyLabel: 'No DNS conflicts',
countSingular: 'conflict',
countPlural: 'conflicts'
});
updateLocalDnsSubtabBadges();
}
function updateP2pConflictsChrome(filteredCount) {
updateListChrome({
totalData: window.p2pDomainConflictsData,
filteredData: window.filteredP2pDomainConflicts,
searchId: 'search-p2p-domain-conflicts',
emptyId: 'p2pConflictsEmpty',
filteredEmptyId: 'p2pConflictsFilteredEmpty',
tableSelector: '.local-dns-p2p-table',
endId: 'p2pConflictsEnd',
countId: 'p2pConflictsCount',
countEmptyLabel: 'No P2P conflicts',
countSingular: 'conflict',
countPlural: 'conflicts'
});
updateLocalDnsSubtabBadges();
}
function showLocalDnsListEnd() {
const totalCount = (window.localDnsData || []).length;
const visibleCount = (window.filteredLocalDns || window.localDnsData || []).length;
const endEl = document.getElementById('localDnsEnd');
if (endEl && totalCount > 0 && visibleCount > 0) endEl.classList.add('local-dns-list-end--visible');
}
function showDnsConflictsListEnd() {
const totalCount = (window.dnsConflictsData || []).length;
const visibleCount = (window.filteredDnsConflicts || window.dnsConflictsData || []).length;
const endEl = document.getElementById('dnsConflictsEnd');
if (endEl && totalCount > 0 && visibleCount > 0) endEl.classList.add('local-dns-list-end--visible');
}
function showP2pConflictsListEnd() {
const totalCount = (window.p2pDomainConflictsData || []).length;
const visibleCount = (window.filteredP2pDomainConflicts || window.p2pDomainConflictsData || []).length;
const endEl = document.getElementById('p2pConflictsEnd');
if (endEl && totalCount > 0 && visibleCount > 0) endEl.classList.add('local-dns-list-end--visible');
}
function localDnsFieldHtml(label, inputHtml) {
return `<label class="local-dns-form-field"><span class="local-dns-form-label">${label}</span>${inputHtml}</label>`;
}
function openLocalDnsModal(editIndex = -1) {
const modal = document.getElementById('localDnsModal');
const title = document.getElementById('local-dns-title');
@@ -42,32 +234,44 @@ function updateLocalForm(rec = null) {
switch (type) {
case 'A':
case 'AAAA':
inputHtml = `<input id="local-data" placeholder="IP Address" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
inputHtml = localDnsFieldHtml('Value', `<input id="local-data" placeholder="IP address" class="${LOCAL_DNS_FIELD}">`);
break;
case 'CNAME':
inputHtml = `<input id="local-data" placeholder="Target Domain" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
inputHtml = localDnsFieldHtml('Target', `<input id="local-data" placeholder="Target domain" class="${LOCAL_DNS_FIELD}">`);
break;
case 'TXT':
inputHtml = `<input id="local-data" placeholder="Text" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
inputHtml = localDnsFieldHtml('Text', `<input id="local-data" placeholder="Text value" class="${LOCAL_DNS_FIELD}">`);
break;
case 'MX':
inputHtml = `<input id="local-preference" type="number" placeholder="Preference" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-exchange" placeholder="Exchange" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
inputHtml = localDnsFieldHtml('Preference', `<input id="local-preference" type="number" placeholder="10" class="${LOCAL_DNS_FIELD}">`)
+ localDnsFieldHtml('Exchange', `<input id="local-exchange" placeholder="mail.example.tld" class="${LOCAL_DNS_FIELD}">`);
break;
case 'SRV':
inputHtml = `<input id="local-priority" type="number" placeholder="Priority" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-weight" type="number" placeholder="Weight" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-port" type="number" placeholder="Port" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-target" placeholder="Target" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
inputHtml = localDnsFieldHtml('Priority', `<input id="local-priority" type="number" placeholder="0" class="${LOCAL_DNS_FIELD}">`)
+ localDnsFieldHtml('Weight', `<input id="local-weight" type="number" placeholder="0" class="${LOCAL_DNS_FIELD}">`)
+ localDnsFieldHtml('Port', `<input id="local-port" type="number" placeholder="443" class="${LOCAL_DNS_FIELD}">`)
+ localDnsFieldHtml('Target', `<input id="local-target" placeholder="host.example.tld" class="${LOCAL_DNS_FIELD}">`);
break;
case 'SOA':
inputHtml = `<input id="local-mname" placeholder="Primary Name Server" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-rname" placeholder="Responsible Person" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-serial" type="number" placeholder="Serial" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-refresh" type="number" placeholder="Refresh" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-retry" type="number" placeholder="Retry" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-expire" type="number" placeholder="Expire" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-minimum" type="number" placeholder="Minimum TTL" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
inputHtml = localDnsFieldHtml('Primary NS', `<input id="local-mname" placeholder="ns1.example.tld" class="${LOCAL_DNS_FIELD}">`)
+ localDnsFieldHtml('Responsible', `<input id="local-rname" placeholder="hostmaster.example.tld" class="${LOCAL_DNS_FIELD}">`)
+ localDnsFieldHtml('Serial', `<input id="local-serial" type="number" placeholder="1" class="${LOCAL_DNS_FIELD}">`)
+ localDnsFieldHtml('Refresh', `<input id="local-refresh" type="number" placeholder="3600" class="${LOCAL_DNS_FIELD}">`)
+ localDnsFieldHtml('Retry', `<input id="local-retry" type="number" placeholder="600" class="${LOCAL_DNS_FIELD}">`)
+ localDnsFieldHtml('Expire', `<input id="local-expire" type="number" placeholder="86400" class="${LOCAL_DNS_FIELD}">`)
+ localDnsFieldHtml('Minimum TTL', `<input id="local-minimum" type="number" placeholder="300" class="${LOCAL_DNS_FIELD}">`);
break;
case 'CAA':
inputHtml = `<input id="local-flags" type="number" placeholder="Flags" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-tag" placeholder="Tag (e.g., issue, issuewild, iodef)" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"><input id="local-value" placeholder="Value" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
inputHtml = localDnsFieldHtml('Flags', `<input id="local-flags" type="number" placeholder="0" class="${LOCAL_DNS_FIELD}">`)
+ localDnsFieldHtml('Tag', `<input id="local-tag" placeholder="issue, issuewild, iodef" class="${LOCAL_DNS_FIELD}">`)
+ localDnsFieldHtml('Value', `<input id="local-value" placeholder="ca.example.tld" class="${LOCAL_DNS_FIELD}">`);
break;
case 'NS':
case 'PTR':
inputHtml = `<input id="local-data" placeholder="Name Server" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
inputHtml = localDnsFieldHtml('Name server', `<input id="local-data" placeholder="ns.example.tld" class="${LOCAL_DNS_FIELD}">`);
break;
default:
inputHtml = `<input id="local-data" placeholder="Record Data" class="w-full p-3 mb-4 border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary">`;
inputHtml = localDnsFieldHtml('Record data', `<input id="local-data" placeholder="Record data" class="${LOCAL_DNS_FIELD}">`);
break;
}
fields.innerHTML = inputHtml;
@@ -299,4 +503,14 @@ window.submitLocalDns = submitLocalDns;
window.editLocalDns = editLocalDns;
window.deleteLocalDns = deleteLocalDns;
window.toggleVersionPreference = toggleVersionPreference;
window.toggleHashPreference = toggleHashPreference;
window.classifyDnsRecordType = classifyDnsRecordType;
window.formatLocalDnsValue = formatLocalDnsValue;
window.updateLocalDnsChrome = updateLocalDnsChrome;
window.updateDnsConflictsChrome = updateDnsConflictsChrome;
window.updateP2pConflictsChrome = updateP2pConflictsChrome;
window.updateLocalDnsSubtabBadges = updateLocalDnsSubtabBadges;
window.showLocalDnsListEnd = showLocalDnsListEnd;
window.showDnsConflictsListEnd = showDnsConflictsListEnd;
window.showP2pConflictsListEnd = showP2pConflictsListEnd;