updated to new version of subnets.html with comments support

This commit is contained in:
root 2024-11-23 01:20:57 -06:00
parent 6e7f9de582
commit 7c569db9b5

View File

@ -4,18 +4,9 @@
<script language="javascript" type="text/javascript"> <script language="javascript" type="text/javascript">
<!-- <!--
var visibleColumns = {
subnet: true,
netmask: false,
range: true,
useable: true,
hosts: true,
divide: true,
join: true,
};
var curNetwork = 0; var curNetwork = 0;
var curMask = 0; var curMask = 0;
var curComments = {};
function updateNetwork() function updateNetwork()
{ {
@ -69,12 +60,6 @@ function startOver()
function recreateTables() function recreateTables()
{ {
// Update header visibility
for (const name in visibleColumns) {
console.log(name)
document.getElementById(name + 'Header').style.display = visibleColumns[name] ? 'table-cell' : 'none';
}
var calcbody = document.getElementById('calcbody'); var calcbody = document.getElementById('calcbody');
if (!calcbody) { if (!calcbody) {
alert('Body not found'); alert('Body not found');
@ -91,12 +76,39 @@ function recreateTables()
createRow(calcbody, rootSubnet, curNetwork, curMask, [curMask, rootSubnet[1], rootSubnet], rootSubnet[0]); createRow(calcbody, rootSubnet, curNetwork, curMask, [curMask, rootSubnet[1], rootSubnet], rootSubnet[0]);
document.getElementById('joinHeader').colSpan = (rootSubnet[0] > 0 ? rootSubnet[0] : 1); document.getElementById('joinHeader').colSpan = (rootSubnet[0] > 0 ? rootSubnet[0] : 1);
// document.getElementById('col_join').span = (rootSubnet[0] > 0 ? rootSubnet[0] : 1); document.getElementById('col_join').span = (rootSubnet[0] > 0 ? rootSubnet[0] : 1);
/* Create the bookmark hyperlink */ /* Disable joins for subnets with comments. */
var joinLocks = {}; // a unique collection of join elements to disable
for (var addressWithMask in curComments) {
let splitAddressMask = addressWithMask.split('/');
let addressToLock = inet_aton(splitAddressMask[0]);
let upperMaskToLock = splitAddressMask[1];
for (let maskToLock = upperMaskToLock; maskToLock >= curMask; maskToLock--) {
joinLocks[inet_ntoa(network_address(addressToLock, maskToLock)) + "/" + maskToLock] = true;
}
}
for (var lock in joinLocks) {
let joinElement = document.getElementById("join_" + lock);
if (joinElement && joinElement.onclick) {
joinElement.onclick = null;
joinElement.classList.remove("maskSpanJoinable");
joinElement.classList.add("maskSpan");
}
};
createBookmarkHyperlink();
}
function createBookmarkHyperlink() {
var link = document.getElementById('saveLink'); var link = document.getElementById('saveLink');
if (link) { if (link) {
link.href = 'subnets.html?network='+inet_ntoa(curNetwork)+'&mask='+curMask+'&division='+binToAscii(nodeToString(rootSubnet)); link.href = '?network='+inet_ntoa(curNetwork)
+'&mask='+curMask
+'&division='+binToAscii(nodeToString(rootSubnet))
+'&comments='+encodeURIComponent(JSON.stringify(curComments));
} }
} }
@ -148,9 +160,10 @@ function asciiToBin(str)
return out; return out;
} }
// Recursive function that creates rows working from the outer most mask and working inwards
function createRow(calcbody, node, address, mask, labels, depth) function createRow(calcbody, node, address, mask, labels, depth)
{ {
if (node[2]) { if (node[2]) { // We need to go deeper
var newlabels = labels; var newlabels = labels;
newlabels.push(mask+1); newlabels.push(mask+1);
newlabels.push(node[2][0][1]); newlabels.push(node[2][0][1]);
@ -163,16 +176,14 @@ function createRow(calcbody, node, address, mask, labels, depth)
newlabels.push(node[2][1]); newlabels.push(node[2][1]);
createRow(calcbody, node[2][1], address+subnet_addresses(mask+1), mask+1, newlabels, depth-1); createRow(calcbody, node[2][1], address+subnet_addresses(mask+1), mask+1, newlabels, depth-1);
} }
else { else { // Actually create a row
var newRow = document.createElement('TR'); var newRow = document.createElement('TR');
calcbody.appendChild(newRow); calcbody.appendChild(newRow);
/* subnet address */ /* subnet address */
if (visibleColumns.subnet) { var newCell = document.createElement('TD');
var newCell = document.createElement('TD'); newCell.appendChild(document.createTextNode(inet_ntoa(address)+'/'+mask));
newCell.appendChild(document.createTextNode(inet_ntoa(address)+'/'+mask)); newRow.appendChild(newCell);
newRow.appendChild(newCell);
}
var addressFirst = address; var addressFirst = address;
var addressLast = subnet_last_address(address, mask); var addressLast = subnet_last_address(address, mask);
@ -181,6 +192,7 @@ function createRow(calcbody, node, address, mask, labels, depth)
var numHosts; var numHosts;
var addressRange; var addressRange;
var usaebleRange; var usaebleRange;
var comment = curComments[inet_ntoa(address) + "/" + mask] || null;
if (mask == 32) { if (mask == 32) {
addressRange = inet_ntoa(addressFirst); addressRange = inet_ntoa(addressFirst);
@ -200,91 +212,112 @@ function createRow(calcbody, node, address, mask, labels, depth)
} }
/* netmask */ /* netmask */
if (visibleColumns.netmask) { var newCell = document.createElement('TD');
var newCell = document.createElement('TD'); newCell.appendChild(document.createTextNode(inet_ntoa(subnet_netmask(mask))));
newCell.appendChild(document.createTextNode(inet_ntoa(subnet_netmask(mask)))); newRow.appendChild(newCell);
newRow.appendChild(newCell);
}
/* range of addresses */ /* range of addresses */
if (visibleColumns.range) { var newCell = document.createElement('TD');
var newCell = document.createElement('TD'); newCell.appendChild(document.createTextNode(addressRange));
newCell.appendChild(document.createTextNode(addressRange)); newRow.appendChild(newCell);
newRow.appendChild(newCell);
}
/* useable addresses */ /* useable addresses */
if (visibleColumns.useable) { var newCell = document.createElement('TD');
var newCell = document.createElement('TD'); newCell.appendChild(document.createTextNode(useableRange));
newCell.appendChild(document.createTextNode(useableRange)); newRow.appendChild(newCell);
newRow.appendChild(newCell);
}
/* Hosts */ /* Hosts */
if (visibleColumns.hosts) { var newCell = document.createElement('TD');
var newCell = document.createElement('TD'); newCell.appendChild(document.createTextNode(numHosts));
newCell.appendChild(document.createTextNode(numHosts)); newRow.appendChild(newCell);
newRow.appendChild(newCell);
} /* Comments */
var newCell = document.createElement('TD');
var textarea = document.createElement('TEXTAREA');
textarea.id = "comment_" + inet_ntoa(network_address(address, mask)) + "/" + mask;
textarea.onchange = ((mask, address) => ( function() {
var key = inet_ntoa(address) + "/" + mask;
var needToRedraw = false;
if (this.value == null || this.value === "") {
needToRedraw = curComments[key] !== undefined;
delete curComments[key];
} else {
needToRedraw = curComments[key] === undefined;
curComments[key] = this.value;
}
if (needToRedraw) {
recreateTables();
// Restore previous focus after redrawing table
document.getElementById(this.id).focus();
} else {
// Just update link if we don't need to redraw.
createBookmarkHyperlink();
}
}))(mask, address); // keep some vars in scope
textarea.innerText = comment;
newCell.appendChild(textarea);
newRow.appendChild(newCell);
/* actions */ /* actions */
if (visibleColumns.divide) { var newCell = document.createElement('TD');
var newCell = document.createElement('TD'); newRow.appendChild(newCell);
newRow.appendChild(newCell);
if (mask == 32) { if (mask == 32 || comment != null) {
var newLink = document.createElement('SPAN'); var newLink = document.createElement('SPAN');
newLink.className = 'disabledAction'; newLink.className = 'disabledAction';
newLink.appendChild(document.createTextNode('Divide')); newLink.appendChild(document.createTextNode('Divide'));
newCell.appendChild(newLink); newCell.appendChild(newLink);
}
else {
var newLink = document.createElement('A');
newLink.href = '#';
newLink.onclick = function () { divide(node); return false; }
newLink.appendChild(document.createTextNode('Divide'));
newCell.appendChild(newLink);
}
var colspan = depth - node[0];
for (var i=(labels.length/3)-1; i>=0; i--) {
var mask = labels[i*3];
var rowspan = labels[(i*3)+1];
var joinnode = labels[(i*3)+2];
var newCell = document.createElement('TD');
newCell.rowSpan = (rowspan > 1 ? rowspan : 1);
newCell.colSpan = (colspan > 1 ? colspan : 1);
newCell.id = "join_" + inet_ntoa(network_address(address, mask)) + "/" + mask;
if (i == (labels.length/3)-1) {
newCell.className = 'maskSpan';
} }
else { else {
var newLink = document.createElement('A'); newCell.className = 'maskSpanJoinable';
newLink.href = '#'; newCell.onclick = newJoin(joinnode);
newLink.onclick = function () { divide(node); return false; } // newCell.onmouseover = function() { window.status = joinnode[0]+'---'+joinnode[1]+'---'+joinnode[2]+'>>>>>'+node[2];}
newLink.appendChild(document.createTextNode('Divide'));
newCell.appendChild(newLink);
} }
}
if (visibleColumns.join) { var newImg = document.createElement('IMG');
var colspan = depth - node[0]; newImg.src = 'img/'+mask+'.gif';
newCell.appendChild(newImg);
newRow.appendChild(newCell);
for (var i=(labels.length/3)-1; i>=0; i--) { colspan = 1; // reset for subsequent cells
var mask = labels[i*3];
var rowspan = labels[(i*3)+1];
var joinnode = labels[(i*3)+2];
var newCell = document.createElement('TD');
newCell.rowSpan = (rowspan > 1 ? rowspan : 1);
newCell.colSpan = (colspan > 1 ? colspan : 1);
if (i == (labels.length/3)-1) {
newCell.className = 'maskSpan';
}
else {
newCell.className = 'maskSpanJoinable';
newCell.onclick = newJoin(joinnode);
// newCell.onmouseover = function() { window.status = joinnode[0]+'---'+joinnode[1]+'---'+joinnode[2]+'>>>>>'+node[2];}
}
var newImg = document.createElement('IMG');
newImg.src = 'img/'+mask+'.gif';
newCell.appendChild(newImg);
newRow.appendChild(newCell);
colspan = 1; // reset for subsequent cells
}
} }
} }
} }
/* This is necessary because 'joinnode' changes during the scope of the caller */ /* This is necessary because 'joinnode' changes during the scope of the caller */
function newJoin(joinnode) function newJoin(joinnode)
{ {
return function() { join(joinnode) }; return function() {
join(joinnode);
return false; // prevent click event
};
} }
function divide(node) function divide(node)
@ -370,7 +403,7 @@ function network_address(ip, mask)
function subnet_addresses(mask) function subnet_addresses(mask)
{ {
return 2**(32-mask); return 1<<(32-mask);
} }
function subnet_last_address(subnet, mask) function subnet_last_address(subnet, mask)
@ -407,6 +440,12 @@ function calcOnLoad()
if (args['network'] && args['mask'] && args['division']) { if (args['network'] && args['mask'] && args['division']) {
document.forms['calc'].elements['network'].value = args['network']; document.forms['calc'].elements['network'].value = args['network'];
document.forms['calc'].elements['netbits'].value = args['mask']; document.forms['calc'].elements['netbits'].value = args['mask'];
if (args['comments']) {
curComments = JSON.parse(args['comments']);
} else {
curComments = {};
}
updateNetwork(); updateNetwork();
var division = asciiToBin(args['division']); var division = asciiToBin(args['division']);
rootSubnet = [0, 0, null]; rootSubnet = [0, 0, null];
@ -458,18 +497,14 @@ window.onload = calcOnLoad;
function toggleColumn(cb) function toggleColumn(cb)
{ {
var colName = 'col_'+(cb.id.substr(3)); var colName = 'col_'+(cb.id.substr(3));
// var col = document.getElementById(colName); var col = document.getElementById(colName);
visibleColumns[cb.id.substr(3)] = cb.checked; if (cb.checked) {
col.style.display = 'block';
// if (cb.checked) { }
// col.style.display = 'table-column'; else {
// col.style.visibility = 'visible'; col.style.display = 'none';
// } }
// else {
// col.style.display = 'none';
// col.style.visibility = 'collapse';
// }
recreateTables(); /* because IE draws lines all over the place with border-collapse */ recreateTables(); /* because IE draws lines all over the place with border-collapse */
} }
@ -492,7 +527,8 @@ P {
font-size: 75%; font-size: 75%;
} }
.label {
.label {
font-family: Arial, Verdana, sans-serif; font-family: Arial, Verdana, sans-serif;
font-size: 60%; font-size: 60%;
} }
@ -502,8 +538,7 @@ P {
font-size: 80%; font-size: 80%;
border-collapse: collapse; border-collapse: collapse;
} }
.calc td {
.calc td, .calc th {
border: 1px solid black; border: 1px solid black;
} }
@ -512,6 +547,10 @@ P {
background-color: #eeeeee; background-color: #eeeeee;
} }
.calc textarea {
height: 1.5em;
}
.disabledAction { .disabledAction {
color: #dddddd; color: #dddddd;
} }
@ -523,7 +562,7 @@ P {
.maskSpanJoinable { .maskSpanJoinable {
background-color: #cccccc; background-color: #cccccc;
text-align: right; text-align: right;
cursor: pointer; cursor: grab;
} }
.maskSpanRotate { .maskSpanRotate {
@ -559,12 +598,13 @@ P {
</tr> </tr>
</table> </table>
<p>Show columns: <p>Show columns:
<input type="checkbox" id="cb_subnet" checked onclick="toggleColumn(this)"><label for="cb_subnet">Subnet address</label> <input type="checkbox" id="cb_subnet" checked onclick="toggleColumn(this)"><label for="cb_subnet">Subnet address</label>
<input type="checkbox" id="cb_netmask" onclick="toggleColumn(this)"><label for="cb_netmask">Netmask</label> <input type="checkbox" id="cb_netmask" onclick="toggleColumn(this)"><label for="cb_netmask">Netmask</label>
<input type="checkbox" id="cb_range" checked onclick="toggleColumn(this)"><label for="cb_range">Range of addresses</label> <input type="checkbox" id="cb_range" checked onclick="toggleColumn(this)"><label for="cb_range">Range of addresses</label>
<input type="checkbox" id="cb_useable" checked onclick="toggleColumn(this)"><label for="cb_useable">Useable IPs</label> <input type="checkbox" id="cb_useable" checked onclick="toggleColumn(this)"><label for="cb_useable">Useable IPs</label>
<input type="checkbox" id="cb_hosts" checked onclick="toggleColumn(this)"><label for="cb_hosts">Hosts</label> <input type="checkbox" id="cb_hosts" checked onclick="toggleColumn(this)"><label for="cb_hosts">Hosts</label>
<input type="checkbox" id="cb_comments" checked onclick="toggleColumn(this)"><label for="cb_comments">Comments</label>
<input type="checkbox" id="cb_divide" checked onclick="toggleColumn(this)"><label for="cb_divide">Divide</label> <input type="checkbox" id="cb_divide" checked onclick="toggleColumn(this)"><label for="cb_divide">Divide</label>
<input type="checkbox" id="cb_join" checked onclick="toggleColumn(this)"><label for="cb_join">Join</label> <input type="checkbox" id="cb_join" checked onclick="toggleColumn(this)"><label for="cb_join">Join</label>
</p> </p>
@ -575,7 +615,7 @@ If you wish to save this subnetting for later, bookmark <a href="subnets.html" i
</td> </td>
<td align="right"> <td align="right">
<a href="https://github.com/davidc/subnets"><img alt="Fork me on GitHub" src="https://github.blog/wp-content/uploads/2008/12/forkme_right_white_ffffff.png" style="right: 0;top: 0;position: absolute;"></a> <a href="https://github.com/davidc/subnets"><img alt="Fork me on GitHub" src="https://github.blog/wp-content/uploads/2008/12/forkme_right_white_ffffff.png" style="right: 0;top: 0;position: absolute;" ></a>
</td> </td>
</tr> </tr>
</table> </table>
@ -585,15 +625,26 @@ If you wish to save this subnetting for later, bookmark <a href="subnets.html" i
<br> <br>
<table class="calc" cellspacing="0" cellpadding="2"> <table class="calc" cellspacing="0" cellpadding="2">
<colgroup>
<col id="col_subnet">
<col id="col_netmask" style="display: none">
<col id="col_range">
<col id="col_useable">
<col id="col_hosts">
<col id="col_comments">
<col id="col_divide">
<col id="col_join">
</colgroup>
<thead> <thead>
<tr> <tr>
<th id="subnetHeader">Subnet address</th> <td>Subnet address</td>
<th id="netmaskHeader">Netmask</th> <td>Netmask</td>
<th id="rangeHeader">Range of addresses</th> <td>Range of addresses</td>
<th id="useableHeader">Useable IPs</th> <td>Useable IPs</td>
<th id="hostsHeader">Hosts</th> <td>Hosts</td>
<th id="divideHeader">Divide</th> <td>Comments</td>
<th id="joinHeader">Join</th> <td>Divide</td>
<td id="joinHeader">Join</td>
</tr> </tr>
</thead> </thead>
<tbody id="calcbody"> <tbody id="calcbody">