Viewing File: /usr/local/cpanel/whostmgr/docroot/templates/ipv6/enable.js
CPANEL.namespace("CPANEL.App");
/**
* The EnableIPv6 module provides methods to set IPv6 addresses for accounts.
*
* @module EnableIPv6
*
*/
CPANEL.App.EnableIPv6 = (function() {
var Handlebars = window.Handlebars,
CALLBACK_TIMEOUT = 120000,
SELECTOR = YAHOO.util.Selector,
EVENT = YAHOO.util.Event,
DOM = YAHOO.util.Dom,
PAGE = CPANEL.PAGE,
accountsContainer,
lastFilterValue,
accountFilterInput,
accountSelectButton,
accountFilterButton,
accountSelected,
accountList,
accountsTemplate,
accountsShiftKeyListener,
accountsKeyListener,
accountInformationTemplate,
enableAccountButton,
disableAccountButton,
apiNoticeContainer,
rangeListNames,
rangeAvailable;
/**
* Builds a string of addressed from an array of objects
*
* @method ipList
* @param {Array} context An array of ipv6 addresses
* @returns {String} The serialized string of addresses
*/
var ipList = function(context) {
var addressList = context[0];
for (var i = 1, length = context.length; i < length; i++) {
addressList += "," + context[i];
}
return addressList;
};
/**
* Sets the input filter and swaps the button for clear icon
*
* @method setFilter
* @param {Event} e The event object
*/
var setFilter = function(e) {
var target = e.target || e.srcElement;
if (target.value !== "") {
if (target.value !== lastFilterValue) {
DOM.removeClass(SELECTOR.query("li.selected", accountList), "selected");
accountSelected.value = "";
}
lastFilterValue = target.value;
DOM.removeClass(accountFilterButton, "filter-search");
DOM.addClass(accountFilterButton, "filter-clear");
var visibleElements = SELECTOR.query("li", accountList);
var filterPattern = new RegExp(target.value, "i");
// loop over the list and hide accounts not matching the filter
for (var i = 0, length = visibleElements.length; i < length; i++) {
var currentElement = visibleElements[i],
account = DOM.getAttribute(currentElement, "id"),
domain = DOM.getAttribute(currentElement, "data-domain");
// hide acounts that do not match
if (filterPattern.test(account)) {
DOM.removeClass(currentElement, "hidden");
} else if (filterPattern.test(domain)) {
DOM.removeClass(currentElement, "hidden");
} else {
DOM.addClass(currentElement, "hidden");
DOM.removeClass(currentElement, "selected");
}
}
} else {
var hiddenElements = SELECTOR.query("li.hidden", accountList);
DOM.removeClass(hiddenElements, "hidden");
lastFilterValue = "";
clearFilter({
target: accountFilterButton,
});
}
};
/**
* Clears the input filter and swaps the button for search glass icon
*
* @method clearFilter
* @param {Event} e The event object
*/
var clearFilter = function(e) {
var target = e.target || e.srcElement;
if (DOM.hasClass(target, "filter-clear")) {
var hiddenElements = SELECTOR.query("li.hidden", accountList);
accountFilterInput.value = "";
DOM.removeClass(hiddenElements, "hidden");
DOM.removeClass(target, "filter-clear");
DOM.addClass(target, "filter-search");
}
};
/**
* Selects all accounts from the list and add them to the account_selected
*
* @method selectAll
* @param {Event} e The event object
*/
var selectAll = function() {
var accounts = SELECTOR.query("li:not(.hidden)", accountList),
cursor = SELECTOR.query("li.cursor", accountList, true);
// empty the selected form field and populate with all accounts
accountSelected.value = "";
DOM.removeClass(cursor, "cursor");
for (var i = 0, length = accounts.length; i < length; i++) {
var currentAccount = accounts[i];
accountSelected.value += currentAccount.id;
if (i !== length - 1) {
accountSelected.value += ", ";
}
DOM.addClass(currentAccount, "selected");
}
apiNoticeContainer.innerHTML = accountInformationTemplate({
type: "info",
ranges: rangeListNames,
rangeAvailability: rangeAvailable,
multipleAccounts: true,
});
if (rangeAvailable) {
disableAccountButton.disabled = false;
DOM.removeClass(disableAccountButton, "disabled");
enableAccountButton.disabled = false;
DOM.removeClass(enableAccountButton, "disabled");
}
};
/**
* Handles selection of an account from the list
*
* @method selectAccount
* @param {Event} e The event object
*/
var selectAccount = function(e) {
if (!DOM.hasClass(accountList, "loading")) {
var selected = e.selected || SELECTOR.query("li.selected", accountList),
cursor = e.cursor || SELECTOR.query("li.cursor", accountList, true),
newSelection = e.target || e.srcElement,
accountSelectedValue = accountSelected.value || false,
removal = e.cursor ? cursor : newSelection;
if (e.shiftKey) {
if (accountSelectedValue && accountSelectedValue.indexOf(",")) {
var accounts = accountSelectedValue.split(", ");
if (DOM.hasClass(newSelection, "selected")) {
// remove account from selection
accounts.splice($.inArray(removal.id, accounts), 1);
accountSelected.value = accounts.join(", ");
DOM.removeClass(removal, "selected");
} else {
// add account to selection
if ($.inArray(newSelection.id, accounts)) {
accounts.push(newSelection.id);
accountSelected.value = accounts.join(", ");
DOM.addClass(newSelection, "selected");
}
}
} else {
if (DOM.hasClass(newSelection, "selected")) {
// remove account from selection
accountSelected.value = "";
DOM.removeClass(removal, "selected");
} else {
// add account to selection
accountSelected.value = newSelection.id;
DOM.addClass(newSelection, "selected");
}
}
} else {
// replace the existing account selection
DOM.removeClass(selected, "selected");
accountSelected.value = newSelection.id;
DOM.addClass(newSelection, "selected");
}
// update cursor class
DOM.removeClass(cursor, "cursor");
DOM.addClass(newSelection, "cursor");
if (newSelection.tagName === "LI") {
var noticeData = {
type: "info",
multipleAccounts: SELECTOR.query("li.selected", accountList).length > 1,
ranges: rangeListNames,
rangeAvailability: rangeAvailable,
};
if (noticeData.multipleAccounts) {
if (rangeAvailable) {
disableAccountButton.disabled = false;
DOM.removeClass(disableAccountButton, "disabled");
enableAccountButton.disabled = false;
DOM.removeClass(enableAccountButton, "disabled");
}
} else {
noticeData.domain = DOM.getAttribute(newSelection, "data-domain");
noticeData.ipv6 = DOM.getAttribute(newSelection, "data-ipv6");
if (noticeData.ipv6) {
noticeData.ipv6 = noticeData.ipv6.split(",");
enableAccountButton.disabled = true;
DOM.addClass(enableAccountButton, "disabled");
disableAccountButton.disabled = false;
DOM.removeClass(disableAccountButton, "disabled");
} else {
if (rangeAvailable) {
enableAccountButton.disabled = false;
DOM.removeClass(enableAccountButton, "disabled");
}
disableAccountButton.disabled = true;
DOM.addClass(disableAccountButton, "disabled");
}
}
apiNoticeContainer.innerHTML = accountInformationTemplate(noticeData);
} else {
enableAccountButton.disabled = true;
DOM.addClass(enableAccountButton, "disabled");
disableAccountButton.disabled = true;
DOM.addClass(disableAccountButton, "disabled");
apiNoticeContainer.innerHTML = accountInformationTemplate({
type: "info",
noAccount: true,
});
}
}
};
/**
* Handles keyboard navigation of the accounts list
*
* @method keyboardSelectList
* @param {String} e The event name
* @param {Object} key The array of key and event information
*/
var keyboardSelectList = function(e, key) {
var list = SELECTOR.query("li:not(.hidden)", accountList),
selected = SELECTOR.query("li.selected", accountList),
cursor = SELECTOR.query("li.cursor", accountList, true),
hasScroll = accountList.scrollHeight > accountList.offsetHeight,
lastElement = list[list.length - 1],
firstElement = list[0],
keyPressed = key[0],
keyEvent = key[1],
newSelection;
var visible = function(sibling) {
return !DOM.hasClass(sibling, "hidden");
};
// escape, clear the filter and return
if (keyPressed === 27) {
clearFilter({
target: accountFilterButton,
});
return;
}
if (selected) {
if (keyPressed === 40) {
// scroll user list down
newSelection = DOM.getNextSiblingBy(cursor, visible);
if (!newSelection) {
newSelection = firstElement;
}
} else if (keyPressed === 38) {
// scroll user list up
newSelection = DOM.getPreviousSiblingBy(cursor, visible);
if (!newSelection) {
newSelection = lastElement;
}
} else if (keyPressed === 13) {
// enter pressed so enable IPv6 for the current account
enableAccountButton.click();
EVENT.stopEvent(keyEvent);
}
} else {
if (keyPressed === 40) {
// select first user in the list
newSelection = firstElement;
} else if (keyPressed === 38) {
// select last user in the list
newSelection = lastElement;
}
}
if (newSelection) {
// ensure cursor does not move
EVENT.preventDefault(keyEvent);
if (hasScroll) {
newSelection.scrollIntoView(false);
}
// select the account
selectAccount({
cursor: cursor,
selected: selected,
target: newSelection,
shiftKey: keyEvent.shiftKey,
});
}
};
/**
* Toggles the loading and enabled states of a button
*
* @method toggleLoadingButton
* @param {String | HTMLElement} action The button to set a loading state on
*/
var toggleLoadingButton = function(action) {
if (typeof action === "string") {
action = DOM.get(action);
}
var spinner = DOM.getElementsByClassName("spinner", "div", action)[0];
if (!spinner) {
action = action.parentNode;
spinner = DOM.getElementsByClassName("spinner", "div", action)[0];
} // Chrome focus is on the button text instead of the button
if (DOM.hasClass(action, "loading")) {
// remove loading state
DOM.removeClass(action, "loading");
DOM.removeClass(action, "disabled");
action.disabled = false;
} else {
// set loading state
action.disabled = true;
DOM.addClass(action, "disabled");
spinner.style.width = action.offsetWidth + "px";
DOM.addClass(action, "loading");
}
};
/**
* Enables IPv6 Addressing for an account
*
* @method enableIPv6
*/
var enableIPv6 = function() {
var account = accountSelected.value,
callbackTimeout = SELECTOR.query("li.selected", accountList).length * CALLBACK_TIMEOUT || CALLBACK_TIMEOUT,
selectedRange = DOM.get("select_range").value,
dedicated = 1;
toggleLoadingButton(enableAccountButton);
accountsKeyListener.disable();
DOM.addClass(accountList, "loading");
CPANEL.api({
func: "ipv6_enable_account",
data: {
"user": account,
"dedicated": dedicated,
"range": selectedRange,
},
catch_api_errors: true,
callback: {
argument: {
account: account,
dedicated: dedicated,
},
success: function(o) {
var ipv6Set = o.cpanel_data.ipv6,
successAccounts = "",
successCount = 0,
failCount = o.cpanel_data.fail_cnt,
failures = o.cpanel_data.failures,
message,
accountListItem,
multipleAccounts = false,
accountDomain = [],
accountIPv6 = [];
for (var account in ipv6Set) {
if (ipv6Set.hasOwnProperty(account)) {
successAccounts += account + ", ";
successCount++;
}
}
successAccounts = successAccounts.substr(0, successAccounts.length - 2);
// message handle
if (successCount > 1) {
message = LOCALE.maketext("IPv6 is enabled for the following accounts: [_1]", successAccounts);
multipleAccounts = true;
} else if (successCount === 1) {
message = LOCALE.maketext("IPv6 enabled for the “[_1]” account.", account);
}
if (successCount !== 0) {
for (var user in ipv6Set) {
if (ipv6Set.hasOwnProperty(user)) {
accountListItem = DOM.get(user);
accountDomain.push(accountListItem.getAttribute("data-domain"));
accountListItem.setAttribute("data-ipv6", ipv6Set[user]);
accountIPv6.push(ipv6Set[user]);
DOM.addClass(accountListItem, "Enabled");
}
}
apiNoticeContainer.innerHTML = accountInformationTemplate({
type: "success",
message: message,
domain: accountDomain,
multipleAccounts: multipleAccounts,
ipv6: accountIPv6,
});
} else {
apiNoticeContainer.innerHTML = "";
}
if (failCount > 0) {
message = "";
for (var failure in failures) {
message = failure + ": " + failures[failure];
apiNoticeContainer.innerHTML += accountInformationTemplate({
type: "error",
error: true,
message: message,
});
}
}
// remove loading states
accountsKeyListener.enable();
DOM.removeClass(accountList, "loading");
toggleLoadingButton(enableAccountButton);
enableAccountButton.disabled = true;
DOM.addClass(enableAccountButton, "disabled");
disableAccountButton.disabled = false;
DOM.removeClass(disableAccountButton, "disabled");
accountFilterInput.focus();
},
failure: function(o) {
var error = LOCALE.maketext("Request timed out.");
if (o && o.status > 0) {
error = String(o.cpanel_error || o.error || o).html_encode();
}
apiNoticeContainer.innerHTML = accountInformationTemplate({
type: "error",
error: true,
message: error,
});
// remove loading states
accountsKeyListener.enable();
DOM.removeClass(accountList, "loading");
toggleLoadingButton(enableAccountButton);
},
timeout: callbackTimeout,
},
});
};
/**
* Disables IPv6 Addressing for an account
*
* @method disableIPv6
*/
var disableIPv6 = function() {
var account = accountSelected.value,
callbackTimeout = SELECTOR.query("li.selected", accountList).length * CALLBACK_TIMEOUT || CALLBACK_TIMEOUT;
toggleLoadingButton(disableAccountButton);
accountsKeyListener.disable();
DOM.addClass(accountList, "loading");
CPANEL.api({
func: "ipv6_disable_account",
data: {
"user": account,
},
catch_api_errors: true,
callback: {
success: function() {
// handle multiple account disables
var accounts = accountSelected.value.split(", "),
length = accounts.length;
if (length > 1) {
apiNoticeContainer.innerHTML = accountInformationTemplate({
type: "success",
message: LOCALE.maketext("IPv6 is disabled for the following accounts: [_1]", account),
ranges: rangeListNames,
rangeAvailability: rangeAvailable,
multipleAccounts: true,
});
} else {
apiNoticeContainer.innerHTML = accountInformationTemplate({
type: "success",
message: LOCALE.maketext("IPv6 is disabled for the “[_1]” account.", account),
ranges: rangeListNames,
rangeAvailability: rangeAvailable,
});
}
for (var i = 0; i < length; i++) {
account = DOM.get(accounts[i]);
if (account.hasAttribute("data-ipv6")) {
account.removeAttribute("data-ipv6");
}
DOM.removeClass(account, "Enabled");
}
// remove loading states
accountsKeyListener.enable();
DOM.removeClass(accountList, "loading");
toggleLoadingButton(disableAccountButton);
enableAccountButton.disabled = false;
DOM.removeClass(enableAccountButton, "disabled");
disableAccountButton.disabled = true;
DOM.addClass(disableAccountButton, "disabled");
accountFilterInput.focus();
},
failure: function(o) {
var error = LOCALE.maketext("Request timed out.");
if (o && o.status > 0) {
error = String(o.cpanel_error || o.error || o).html_encode();
}
apiNoticeContainer.innerHTML = accountInformationTemplate({
type: "error",
error: true,
message: error,
});
// remove loading states
accountsKeyListener.enable();
DOM.removeClass(accountList, "loading");
toggleLoadingButton(disableAccountButton);
},
timeout: callbackTimeout,
},
});
};
Handlebars.registerHelper("if_eq", function(a, b, opts) {
if (a === b) {
return opts.fn(this);
} else {
return opts.inverse(this);
}
});
Handlebars.registerHelper("wrap", function(text, characters) {
var template = "<wbr>";
// escape our input
var escaped_text = Handlebars.Utils.escapeExpression(text);
// return the string if we are do not have something to match on
if (!characters) {
return new Handlebars.SafeString(escaped_text);
}
// replace the matching characters with our template
var match = "[" + characters + "]";
var expression = new RegExp("(" + match + ")", "g");
var result = escaped_text.replace(expression, "$1" + template);
// return an html-escaped string
return new Handlebars.SafeString(result);
});
/**
* Initializes page elements and attaches listeners
*
* @method initialize
*/
var initialize = function() {
rangeListNames = [];
// load available ranges names for enable dropdown
for (var i = 0, length = CPANEL.PAGE.ranges.length; i < length; i++) {
if (parseInt(CPANEL.PAGE.ranges[i].enabled)) {
rangeListNames.push(CPANEL.PAGE.ranges[i].name);
}
}
rangeAvailable = (rangeListNames.length === 0) ? false : true;
accountInformationTemplate = Handlebars.compile(DOM.get("account_information_template").text.trim());
accountSelected = DOM.get("account_selected");
// register handlebars helpers
Handlebars.registerHelper("ipList", ipList);
// build the account list
accountList = DOM.get("account_list");
accountsTemplate = Handlebars.compile(DOM.get("accounts_template").text.trim());
var accounts = "";
for (i = 0, length = PAGE.users.length; i < length; i++) {
accounts += accountsTemplate({
account: PAGE.users[i].user,
ipv6: PAGE.users[i].ipv6,
domain: PAGE.users[i].domain,
});
}
accountList.innerHTML = accounts;
lastFilterValue = "";
accountFilterInput = DOM.get("account_filter");
EVENT.on(accountFilterInput, "keyup", setFilter);
accountSelectButton = DOM.get("account_select_button");
EVENT.on(accountSelectButton, "click", selectAll);
accountFilterButton = DOM.get("account_filter_button");
EVENT.on(accountFilterButton, "click", clearFilter);
accountsContainer = DOM.get("accounts_container");
// handle selecting multiple users at once
accountsShiftKeyListener = new YAHOO.util.KeyListener(
accountsContainer, {
ctrl: false,
shift: true,
keys: [13, 27, 38, 40],
},
keyboardSelectList).enable();
// handle keyboard selection of a single user
accountsKeyListener = new YAHOO.util.KeyListener(
accountsContainer, {
keys: [13, 27, 38, 40],
},
keyboardSelectList);
accountsKeyListener.enable();
// mouse selection handler
EVENT.on(accountList, "click", selectAccount);
enableAccountButton = DOM.get("enable_account");
enableAccountButton.disabled = true;
EVENT.on(enableAccountButton, "click", enableIPv6);
disableAccountButton = DOM.get("disable_account");
disableAccountButton.disabled = true;
EVENT.on(disableAccountButton, "click", disableIPv6);
apiNoticeContainer = DOM.get("api_notice");
// prevent hitting enter in input elements causing a form submit
EVENT.on("ipv6_accounts_form", "submit", function(e) {
EVENT.stopEvent(e);
});
accountFilterInput.focus();
};
EVENT.onDOMReady(initialize);
}());
Back to Directory
File Manager