jquery.ipv4v6ify.js 4.15 KB
Newer Older
Ad Schellevis's avatar
Ad Schellevis committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
/*jslint browser: true, eqeqeq: true, undef: true */
/*global jQuery */
/******************************************************************************
Lines above are for jslint, the JavaScript verifier.  http://www.jslint.com/
******************************************************************************/

/* MIT-licensed code from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some */
/* (C) 2007 Mozilla Developer Network and/or Jeff Walden */
if (!Array.prototype.some) {
	Array.prototype.some = function(fun /*, thisp */) {
		"use strict";
		if (!this) {
			throw new TypeError();
		}
		var t = Object(this);
		var len = t.length >>> 0;
		if (typeof fun !== "function") {
			throw new TypeError();
		}
		var thisp = arguments[1];
		for (var i = 0; i < len; i++) {
			if (i in t && fun.call(thisp, t[i], i, t)) {
				return true;
			}
		}
		return false;
	};
}

(function ($) {
	// --------------------------------------------------------------------
	// find pairs of <input class='ipv4v6'> (textbox for IPv4 or IPv6 addr)
	// and <select class='ipv4v6'> (dropdown for # bits in CIDR) and
	// activate behavior that restricts options in the <select> when an
	// ipv4 address is typed in the <input>.
	// --------------------------------------------------------------------
	var _ipv4v6ify = function (input1, input2) {
		var options = Array.prototype.slice.call(input2.options, 0);
		var has_128  = options.some(function (x) { return parseInt(x.value, 10) === 128; });
		var has_0    = options.some(function (x) { return parseInt(x.value, 10) === 0; });
		var max_ipv6 = has_128 ? 128 : 127;
		var min_ipv6 = has_0 ? 0 : 1;
		var max_ipv4 = has_128 ? 32 : 31;
		var min_ipv4 = has_0 ? 0 : 1;
		var was_ipv4 = undefined;
		var is_ipv4  = undefined;
		var restrict_bits_to_ipv4 = function () {
			input2.options.length = 0;
			for (var i = 0; i < options.length; i += 1) {
				var val = parseInt(options[i].value, 10);
				if (val >= min_ipv4 && val <= max_ipv4) {
					input2.options.add(options[i]);
				}
			}
		};
		var unrestrict_bits = function () {
			input2.options.length = 0;
			for (var i = 0; i < options.length; i += 1) {
				input2.options.add(options[i]);
			}
		};
		var onchange_handler = function () {
			was_ipv4 = is_ipv4;
			is_ipv4  = /\./.test(input1.value) && !/\:/.test(input1.value);
			// handle state transitions to gracefully change the
66
			// value in the dropdown.
Ad Schellevis's avatar
Ad Schellevis committed
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
			var bits = parseInt($(input2).val(), 10);
			if (was_ipv4 === false && is_ipv4 === true) {
				restrict_bits_to_ipv4();
				/* min_ipv4 -> min_ipv4 */
				/*   ...    ->   ...    */
				/* max_ipv4 -> max_ipv4 */
				/*   ...    ->   ...    */
				/* max_ipv6 -> max_ipv4 */
				if (bits < min_ipv4) {
					$(input2).val(min_ipv4);
				}
				else if (bits < max_ipv4) {
					$(input2).val(bits);
				}
				else {
					$(input2).val(max_ipv4);
				}
			}
			else if (was_ipv4 === true && is_ipv4 === false) {
				unrestrict_bits();
				/* min_ipv4 -> min_ipv4 */
				/*   ...    ->   ...    */
				/* max_ipv4 -> max_ipv4 */
				if (bits < min_ipv4) {
					$(input2).val(min_ipv6);
				}
				else if (bits < max_ipv4) {
					$(input2).val(bits);
				}
				else {
					$(input2).val(max_ipv6);
				}
			}
			else if (was_ipv4 === undefined && is_ipv4 === true) {
				// initial value is an ipv4 address
				restrict_bits_to_ipv4();
				/* min_ipv4 -> min_ipv4 */
				/*   ...    ->   ...    */
				/* max_ipv4 -> max_ipv4 */
				/*   ...    ->   ...    */
				/* max_ipv6 -> max_ipv4 */
				if (bits < min_ipv4) {
					$(input2).val(min_ipv4);
				}
				else if (bits < max_ipv4) {
					$(input2).val(bits);
				}
				else {
					$(input2).val(max_ipv4);
				}
			}
		};
		$(input1).unbind("change").bind("change", onchange_handler).trigger("change");
	};
	$.fn.extend({
		"ipv4v6ify": function () {
			return this.each(function () {
				var inputs, i, input1, input2;
				inputs = $(this).find(":input.ipv4v6").toArray();
				for (i = 0; i < inputs.length - 1; i += 1) {
					input1 = inputs[i];
					input2 = inputs[i + 1];
					if (input1.type === "text" && input2.type === "select-one") {
						_ipv4v6ify(input1, input2);
					}
				}
			});
		}
	});
	$(function () {
		$(document).ipv4v6ify();
	});
})(jQuery);