Viewing File: /usr/local/cpanel/base/frontend/jupiter/domains/directives/tldPriorityInputDirective.js

//                                      Copyright 2026 WebPros International, LLC
//                                                           All rights reserved.
// copyright@cpanel.net                                         http://cpanel.net
// This code is subject to the cPanel license. Unauthorized copying is prohibited.

/* global define */

/**
 * @namespace cpanel.domains.directive.tldPriorityInput
 *
 * Shared "Filter TLDs" input control.  Both the create-domain
 * "purchase" chooser (views/listDomains) and the domain-recommendations
 * modal (directives/domainSearchModal) used to ship near-identical copies
 * of this logic; this directive centralizes them so they cannot diverge.
 *
 * Bindings:
 *   priorities    (=)  Array of selected TLD strings (with leading dot).
 *                       Two-way bound so callers can read the latest set.
 *                       (Binding name preserved for backwards compatibility;
 *                       the values are now used as filters by callers.)
 *   supportedTlds (=)  null while loading, [] when unavailable, otherwise
 *                       array of supported TLDs (with leading dot).
 *   disabled      (<?) Optional boolean that disables the add button.
 *   inputId       (@?) Optional id for the text input (so an external
 *                       <label for="..."> can target it).
 */

define(
    [
        "angular",
        "cjt/util/locale",
    ],
    function(angular, LOCALE) {

        "use strict";

        var MODULE_NAMESPACE = "cpanel.domains.tldPriorityInput";
        var TEMPLATE_URL = "directives/tldPriorityInput.ptt";

        var module = angular.module(MODULE_NAMESPACE, []);

        function _normalizeTld(raw) {
            var s = (raw || "").trim().toLowerCase();
            if (!s) {
                return "";
            }
            if (s.charAt(0) !== ".") {
                s = "." + s;
            }
            return s;
        }

        module.directive("tldPriorityInput", [function() {
            return {
                restrict: "E",
                scope: {
                    priorities: "=",
                    supportedTlds: "=",
                    disabled: "=?",
                    inputId: "@?",
                },
                templateUrl: TEMPLATE_URL,
                link: function(scope) {
                    if (!angular.isArray(scope.priorities)) {
                        scope.priorities = [];
                    }

                    scope.tldForm = { input: "", error: null };
                    scope.inputId = scope.inputId || "tldPriorityInput";
                    scope.errorId = scope.inputId + "Error";

                    // Localized strings owned by the directive — keeps the
                    // visual + textual contract identical at every call site.
                    scope.strings = {
                        heading: LOCALE.maketext("Filter TLDs"),
                        description: LOCALE.maketext("A Top-Level Domain (TLD) is the last part of a domain name."),
                        enterTldLabel: LOCALE.maketext("Enter a TLD"),
                        addLabel: LOCALE.maketext("Add"),
                        example: LOCALE.maketext("Ex: .com, .net"),
                        selectedTldsLabel: LOCALE.maketext("Selected TLDs"),
                    };

                    scope.removeTldLabel = function(tld) {
                        return LOCALE.maketext("Remove “[_1]”", tld);
                    };

                    scope.validateTldInput = function() {
                        var raw = _normalizeTld(scope.tldForm.input);
                        if (!raw) {
                            scope.tldForm.error = null;
                            return;
                        }

                        // Skip validation while TLDs are loading or unavailable.
                        if (!scope.supportedTlds || !scope.supportedTlds.length) {
                            scope.tldForm.error = null;
                            return;
                        }

                        scope.tldForm.error = scope.supportedTlds.indexOf(raw) === -1
                            ? LOCALE.maketext('“[_1]” is not a supported TLD.', raw)
                            : null;
                    };

                    scope.addTldPriority = function() {
                        var raw = _normalizeTld(scope.tldForm.input);
                        if (!raw) {
                            return;
                        }
                        if (scope.supportedTlds && scope.supportedTlds.length &&
                                scope.supportedTlds.indexOf(raw) === -1) {
                            scope.tldForm.error = LOCALE.maketext('“[_1]” is not a supported TLD.', raw);
                            return;
                        }
                        scope.tldForm.error = null;
                        if (!angular.isArray(scope.priorities)) {
                            scope.priorities = [];
                        }
                        if (scope.priorities.indexOf(raw) === -1) {
                            scope.priorities.push(raw);
                        }
                        scope.tldForm.input = "";
                    };

                    scope.removeTldPriority = function(tld) {
                        if (!angular.isArray(scope.priorities)) {
                            return;
                        }
                        var idx = scope.priorities.indexOf(tld);
                        if (idx !== -1) {
                            scope.priorities.splice(idx, 1);
                        }
                    };

                    scope.handleTldKeydown = function($event) {
                        if ($event.keyCode === 13) {
                            $event.preventDefault();
                            scope.addTldPriority();
                        }
                    };
                },
            };
        }]);

        return {
            namespace: MODULE_NAMESPACE,
        };
    }
);
Back to Directory