<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css" integrity="sha512-Kc323vGBEqzTmouAECnVceyQqyqdsSiqLQISBL29aUW4U/M7pSPA/gEUZQqv1cwx4OnYxTxve5UMg5GT6L4JJg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<title>Online Text Editor</title>
</head>
<body>
<div class="container">
<div class="options">
<button id="bold" class="option-button format">
<i class="fa-solid fa-bold"></i>
</button>
<button id="superscript" class="option-button script">
<i class="fa-solid fa-superscript"></i>
</button>
<button id="subscript" class="option-button script">
<i class="fa-solid fa-subscript"></i>
</button>
<button id="insertOrderedList" class="option-button">
<div class="fa-solid fa-list-ol"></div>
</button>
<button id="insertUnorderedList" class="option-button">
<i class="fa-solid fa-list"></i>
</button>
<button id="undo" class="option-button">
<i class="fa-solid fa-rotate-left"></i>
</button>
<button id="redo" class="option-button">
<i class="fa-solid fa-rotate-right"></i>
</button>
<button id="createLink" class="adv-option-button">
<i class="fa fa-link"></i>
</button>
<button id="unlink" class="option-button">
<i class="fa fa-unlink"></i>
</button>
<button id="justifyLeft" class="option-button align">
<i class="fa-solid fa-align-left"></i>
</button>
<button id="justifyCenter" class="option-button align">
<i class="fa-solid fa-align-center"></i>
</button>
<button id="justifyRight" class="option-button align">
<i class="fa-solid fa-align-right"></i>
</button>
<button id="justifyFull" class="option-button align">
<i class="fa-solid fa-align-justify"></i>
</button>
<button id="indent" class="option-button spacing">
<i class="fa-solid fa-indent"></i>
</button>
<button id="outdent" class="option-button spacing">
<i class="fa-solid fa-outdent"></i>
</button>
<select id="formatBlock" class="adv-option-button">
<option value="H1">H1</option>
<option value="H2">H2</option>
<option value="H3">H3</option>
<option value="H4">H4</option>
<option value="H5">H5</option>
<option value="H6">H6</option>
</select>
<select id="fontName" class="adv-option-button"></select>
<select id="fontSize" class="adv-option-button"></select>
<div class="input-wrapper">
<input type="color" id="foreColor" class="adv-option-button">
<label for="foreColor">Font Color</label>
</div>
<div class="input-wrapper">
<input type="color" id="backColor" class="adv-option-button">
<label for="backColor">Highlight Color</label>
</div>
</div>
<div id="text-input" contenteditable="true"></div>
</div>
<script src="script.js"></script>
</body>
</html>
let optionsButtons = document.querySelectorAll(".option-button");
let advancedOptionButton = document.querySelectorAll(".adv-option-button");
let fontName = document.getElementById("fontName");
let fontSizeRef = document.getElementById("fontSize");
let writingArea = document.getElementById("text-input");
let linkButton = document.getElementById("createLink");
let alignButtons = document.querySelectorAll(".align");
let spacingButtons = document.querySelectorAll(".spacing");
let formatButtons = document.querySelectorAll(".format");
let scriptButtons = document.querySelectorAll(".script");
let fontList = [
"Arial",
"Verdana",
"Times New Roman",
"Garamond",
"Georgia",
"Courier New",
"Cursive",
];
const intializer = () => {
highlighter(alignButtons, true);
highlighter(spacingButtons, true);
highlighter(formatButtons, true);
highlighter(scriptButtons, true);
fontList.map((value) => {
let option = document.createElement("option");
option.value = value;
option.innerHTML = value;
fontName.appendChild(option);
});
for (let i = 1; i <= 7; i++) {
let option = document.createElement("option");
option.value = i;
option.innerHTML = i;
fontSizeRef.appendChild(option);
}
fontSizeRef.value = 3;
};
const modifyText = (command, defaultUi, value) => {
document.execCommand(command, defaultUi, value);
};
optionsButtons.forEach((button) => {
button.addEventListener("click", () => {
modifyText(button.id, false, null);
});
});
advancedOptionButton.forEach((button) => {
button.addEventListener("change", () => {
modifyText(button.id, false, button.value);
});
});
linkButton.addEventListener("click", () => {
let userLink = prompt("Enter a URL?");
if(/http/i.test(userLink)) {
modifyText(linkButton.id, false, userLink);
} else {
userLink = "http://" + userLink;
modifyText(linkButton.id, false, userLink);
}
});
const highlighter = (className, needsRemoval) => {
className.forEach((button) => {
button.addEventListener("click", () => {
if(needsRemoval) {
let alreadyActive = false;
if (button.classList.contains("active")) {
alreadyActive = true;
}
highlighterRemover(className);
if(!alreadyActive) {
button.classList.add("active");
}
} else {
button.classList.toggle("active");
}
});
});
};
const highlighterRemover = (className) => {
className.forEach((button) => {
button.classList.remove("active");
});
};
window.onload = intializer();
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
background-color: #338cf4;
}
.container {
background-color: #fff;
width: 90vmin;
padding: 50px 30px;
position: absolute;
transform: translate(-50%, -50%);
left: 50%;
top: 50%;
border-radius: 10px;
box-shadow: 0 25px 50px rgba(7, 20, 35, 0.2);
}
.options {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 15px;
}
button {
width: 28px;
height: 28px;
display: grid;
place-items: center;
border-radius: 3px;
border: none;
background-color: #fff;
outline: none;
color: #020929;
cursor: pointer;
}
select {
padding: 7px;
border: 1px solid #020929;
border-radius: 3px;
cursor: pointer;
}
.options label,
.options select {
font-family: 'Poppins', sans-serif;
}
input[type="color"] {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: transparent;
width: 40px;
height: 28px;
border: none;
cursor: pointer;
}
input[type="color"]::-webkit-color-swatch {
border-radius: 15px;
box-shadow: 0 0 0 2px #fff, 0 0 0 3px #020929;
}
input[type="color"]::-moz-color-swatch {
border-radius: 15px;
box-shadow: 0 0 0 2px #fff, 0 0 0 3px #020929;
}
#text-input {
margin-top: 10px;
border: 1px solid #ddd;
padding: 20px;
height: 50vh;
}
.active {
background-color: #e0e9ff;
}