-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.js
187 lines (166 loc) · 6.46 KB
/
main.js
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
66
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
console.clear();
// background : Default Range Slider Background
const sliderProps = {
fill: "#0B1EDF",
background: "rgba(255, 255, 255, 0.214)",
};
// Selecting the Range Slider container which will effect the LENGTH property of the password.
const slider = document.querySelector(".range__slider");
// Text which will show the value of the range slider.
const sliderValue = document.querySelector(".length__title");
// Using Event Listener to apply the fill and also change the value of the text.
slider.querySelector("input").addEventListener("input", event => {
sliderValue.setAttribute("data-length", event.target.value);
applyFill(event.target);
});
// Selecting the range input and passing it in the applyFill func.
applyFill(slider.querySelector("input"));
// This function is responsible to create the trailing color and setting the fill.
function applyFill(slider) {
const percentage = (100 * (slider.value - slider.min)) / (slider.max - slider.min);
const bg = `linear-gradient(90deg, ${sliderProps.fill} ${percentage}%, ${sliderProps.background} ${percentage +
0.1}%)`;
slider.style.background = bg;
sliderValue.setAttribute("data-length", slider.value);
}
// Object of all the function names that we will use to create random letters of password
const randomFunc = {
lower: getRandomLower,
upper: getRandomUpper,
number: getRandomNumber,
symbol: getRandomSymbol,
};
// Random more secure value
function secureMathRandom() {
return window.crypto.getRandomValues(new Uint32Array(1))[0] / (Math.pow(2, 32) - 1);
}
// Generator Functions
// All the functions that are responsible to return a random value taht we will use to create password.
function getRandomLower() {
return String.fromCharCode(Math.floor(Math.random() * 26) + 97);
}
function getRandomUpper() {
return String.fromCharCode(Math.floor(Math.random() * 26) + 65);
}
function getRandomNumber() {
return String.fromCharCode(Math.floor(secureMathRandom() * 10) + 48);
}
function getRandomSymbol() {
const symbols = '~!@#$%^&*()_+{}":?><;.,';
return symbols[Math.floor(Math.random() * symbols.length)];
}
// Selecting all the DOM Elements that are necessary -->
// The Viewbox where the result will be shown
const resultEl = document.getElementById("result");
// The input slider, will use to change the length of the password
const lengthEl = document.getElementById("slider");
// Checkboxes representing the options that is responsible to create differnt type of password based on user
const uppercaseEl = document.getElementById("uppercase");
const lowercaseEl = document.getElementById("lowercase");
const numberEl = document.getElementById("number");
const symbolEl = document.getElementById("symbol");
// Button to generate the password
const generateBtn = document.getElementById("generate");
// Button to copy the text
const copyBtn = document.getElementById("copy-btn");
// Result viewbox container
const resultContainer = document.querySelector(".result");
// Text info showed after generate button is clicked
const copyInfo = document.querySelector(".result__info.right");
// Text appear after copy button is clicked
const copiedInfo = document.querySelector(".result__info.left");
// if this variable is trye only then the copyBtn will appear, i.e. when the user first click generate the copyBth will interact.
let generatedPassword = false;
// Update Css Props of the COPY button
// Getting the bounds of the result viewbox container
let resultContainerBound = {
left: resultContainer.getBoundingClientRect().left,
top: resultContainer.getBoundingClientRect().top,
};
// This will update the position of the copy button based on mouse Position
resultContainer.addEventListener("mousemove", e => {
resultContainerBound = {
left: resultContainer.getBoundingClientRect().left,
top: resultContainer.getBoundingClientRect().top,
};
if(generatedPassword){
copyBtn.style.opacity = '1';
copyBtn.style.pointerEvents = 'all';
copyBtn.style.setProperty("--x", `${e.x - resultContainerBound.left}px`);
copyBtn.style.setProperty("--y", `${e.y - resultContainerBound.top}px`);
}else{
copyBtn.style.opacity = '0';
copyBtn.style.pointerEvents = 'none';
}
});
window.addEventListener("resize", e => {
resultContainerBound = {
left: resultContainer.getBoundingClientRect().left,
top: resultContainer.getBoundingClientRect().top,
};
});
// Copy Password in clipboard
copyBtn.addEventListener("click", () => {
const textarea = document.createElement("textarea");
const password = resultEl.innerText;
if (!password || password == "CLICK GENERATE") {
return;
}
textarea.value = password;
document.body.appendChild(textarea);
textarea.select();
document.execCommand("copy");
textarea.remove();
copyInfo.style.transform = "translateY(200%)";
copyInfo.style.opacity = "0";
copiedInfo.style.transform = "translateY(0%)";
copiedInfo.style.opacity = "0.75";
});
// When Generate is clicked Password id generated.
generateBtn.addEventListener("click", () => {
const length = +lengthEl.value;
const hasLower = lowercaseEl.checked;
const hasUpper = uppercaseEl.checked;
const hasNumber = numberEl.checked;
const hasSymbol = symbolEl.checked;
generatedPassword = true;
resultEl.innerText = generatePassword(length, hasLower, hasUpper, hasNumber, hasSymbol);
copyInfo.style.transform = "translateY(0%)";
copyInfo.style.opacity = "0.75";
copiedInfo.style.transform = "translateY(200%)";
copiedInfo.style.opacity = "0";
});
// Function responsible to generate password and then returning it.
function generatePassword(length, lower, upper, number, symbol) {
let generatedPassword = "";
const typesCount = lower + upper + number + symbol;
const typesArr = [{ lower }, { upper }, { number }, { symbol }].filter(item => Object.values(item)[0]);
if (typesCount === 0) {
return "";
}
for (let i = 0; i < length; i++) {
typesArr.forEach(type => {
const funcName = Object.keys(type)[0];
generatedPassword += randomFunc[funcName]();
});
}
return generatedPassword.slice(0, length)
.split('').sort(() => Math.random() - 0.5)
.join('');
}
// function that handles the checkboxes state, so at least one needs to be selected. The last checkbox will be disabled.
function disableOnlyCheckbox(){
let totalChecked = [uppercaseEl, lowercaseEl, numberEl, symbolEl].filter(el => el.checked)
totalChecked.forEach(el => {
if(totalChecked.length == 1){
el.disabled = true;
}else{
el.disabled = false;
}
})
}
[uppercaseEl, lowercaseEl, numberEl, symbolEl].forEach(el => {
el.addEventListener('click', () => {
disableOnlyCheckbox()
})
})