I want to use the checkedCount
variable inside of the generatePassword
function in order to not call the function matrixEffect
at the end of generatePassword
if the value of checkedCount
is 0.
I used the argument checkedCountValue
to be able to use the variable outside its function. But because I'm calling the generatePassword
function at the end of updateSafetyIndicator
I'm receiving the error "RangeError: Maximum call stack size exceeded" due to an infinite call of these functions.
const lengthSlider = document.querySelector(".length-wrapper input"),
options = document.querySelectorAll(".container input"),
generateBtn = document.querySelector(".generate-btn"),
copyBtn = document.querySelector(".copy-btn"),
passwordSafetyIndicator = document.querySelector(".safety-indicator"),
passwordInput = document.querySelector(".display-font");
const characters = {
lowercase: "abcdefghijkilmnopqrstuvwxyz",
uppercase: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
digits: "0123456789",
specials: "^!$%&|[](){}:;.,*+-#@<>~"
}
// generate password
function generatePassword(checkedCountValue) {
let staticPassword = "",
randomPassword = "",
passwordLength = lengthSlider.value;
options.forEach(option => {
if(option.checked) {
staticPassword += characters[option.id];
}
});
for (let i = 0; i < passwordLength; i++) {
randomPassword += staticPassword[Math.floor(Math.random() * staticPassword.length)];
}
passwordInput.innerText = randomPassword;
if (checkedCountValue > 0) {
matrixEffect(randomPassword);
}
updateSafetyIndicator();
}
// matrix effect
const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let interval = null;
function matrixEffect(password) {
let iteration = 0;
clearInterval(interval);
interval = setInterval(() => {
passwordInput.innerText = passwordInput.innerText
.split("")
.map((letter, index) => {
if(index < iteration) {
return password[index];
}
return letters[Math.floor(Math.random() * 26)]
})
.join("");
if(iteration >= lengthSlider.value){
clearInterval(interval);
}
iteration += 1 / 3;
}, 30);
};
// safety indicator update
function updateSafetyIndicator() {
var uppercaseCheck = document.getElementById("uppercase");
var lowercaseCheck = document.getElementById("lowercase");
var digitsCheck = document.getElementById("digits");
var specialsCheck = document.getElementById("specials");
var passwordLength = lengthSlider.value;
var checkedCount = 0;
if (uppercaseCheck.checked) {
checkedCount++;
}
if (lowercaseCheck.checked) {
checkedCount++;
}
if (digitsCheck.checked) {
checkedCount++;
}
if (specialsCheck.checked) {
checkedCount++;
}
if (checkedCount == 0) {
passwordInput.innerText = "Please select first...";
}
else if (checkedCount == 1) {
passwordSafetyIndicator.id = "veryweak";
}
else if (checkedCount == 2) {
passwordSafetyIndicator.id = "weak";
}
else if (checkedCount == 3) {
passwordSafetyIndicator.id = "medium";
}
else if (checkedCount == 4) {
passwordSafetyIndicator.id = "strong";
}
if (checkedCount == 4 && passwordLength >= 10) {
passwordSafetyIndicator.id = "verystrong";
}
if (checkedCount == 3 && passwordLength >= 10) {
passwordSafetyIndicator.id = "strong";
}
if (checkedCount == 2 && passwordLength >= 10) {
passwordSafetyIndicator.id = "medium";
}
if (checkedCount == 1 && passwordLength >= 10) {
passwordSafetyIndicator.id = "weak";
}
generatePassword(checkedCount);
}
// slider length update
function updateSlider() {
document.querySelector(".length-wrapper span").innerText = (lengthSlider.value);
}
updateSlider();
// copy password
function copyPassword(htmlElement) {
if (!htmlElement) {
return;
}
let password = passwordInput.innerText;
let inputPassword = document.createElement("input");
inputPassword.setAttribute("value", password);
document.body.appendChild(inputPassword);
inputPassword.select();
document.execCommand("copy");
inputPassword.parentNode.removeChild(inputPassword);
passwordInput.innerText = "COPIED";
setTimeout (() => {
passwordInput.innerText = password;
}, 1300);
}
copyBtn.onclick = function () {
copyPassword(passwordInput);
}
lengthSlider.addEventListener("input", updateSlider);
generateBtn.addEventListener("click", generatePassword);