From 0f93353907b58c55fc516bf6f4848c97df2f9baa Mon Sep 17 00:00:00 2001 From: Sambit Mondal Date: Thu, 30 May 2024 09:08:33 +0530 Subject: [PATCH] Fixes #368 --- Rich Text Editor/game-28-128.png | Bin 0 -> 2972 bytes Rich Text Editor/game-28-48.png | Bin 0 -> 1478 bytes Rich Text Editor/index.html | 112 +++++++++++++++++++++++++++ Rich Text Editor/manifest.json | 30 ++++++++ Rich Text Editor/scripts/script.js | 117 +++++++++++++++++++++++++++++ Rich Text Editor/src/style.css | 90 ++++++++++++++++++++++ 6 files changed, 349 insertions(+) create mode 100644 Rich Text Editor/game-28-128.png create mode 100644 Rich Text Editor/game-28-48.png create mode 100644 Rich Text Editor/index.html create mode 100644 Rich Text Editor/manifest.json create mode 100644 Rich Text Editor/scripts/script.js create mode 100644 Rich Text Editor/src/style.css diff --git a/Rich Text Editor/game-28-128.png b/Rich Text Editor/game-28-128.png new file mode 100644 index 0000000000000000000000000000000000000000..7838ce203fc775327a6ea291331fa91efbfbdefc GIT binary patch literal 2972 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 literal 0 HcmV?d00001 diff --git a/Rich Text Editor/index.html b/Rich Text Editor/index.html new file mode 100644 index 00000000..3a61f445 --- /dev/null +++ b/Rich Text Editor/index.html @@ -0,0 +1,112 @@ + + + + + + Rich Text Editor + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ + +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Rich Text Editor/manifest.json b/Rich Text Editor/manifest.json new file mode 100644 index 00000000..cfc94352 --- /dev/null +++ b/Rich Text Editor/manifest.json @@ -0,0 +1,30 @@ +{ + "manifest_version": 3, + "name": "Rich Text Editor Extension JS", + "version": "1.0", + "description": "Rich text editor extension built in pure HTML CSS JS...", + "author": "sambitmondal2005@gmail.com", + "icons": { + "48": "game-28-48.png", + "128": "game-28-128.png" + }, + "permissions": [ + "storage" + ], + "optional-permissions": [ + "tabs" + ], + "action": { + "default_popup": "index.html" + }, + "web_accessible_resources": [ + { + "resources": [ + "index.html" + ], + "matches": [ + "" + ] + } + ] +} \ No newline at end of file diff --git a/Rich Text Editor/scripts/script.js b/Rich Text Editor/scripts/script.js new file mode 100644 index 00000000..56d6ac4f --- /dev/null +++ b/Rich Text Editor/scripts/script.js @@ -0,0 +1,117 @@ +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"); + +//List of fontlist +let fontList = [ + "Arial", + "Verdana", + "Times New Roman", + "Garamond", + "Georgia", + "Courier New", + "cursive", +]; + +//Initial Settings +const initializer = () => { + //function calls for highlighting buttons + //No highlights for link, unlink,lists, undo,redo since they are one time operations + highlighter(alignButtons, true); + highlighter(spacingButtons, true); + highlighter(formatButtons, false); + highlighter(scriptButtons, true); + + //create options for font names + fontList.map((value) => { + let option = document.createElement("option"); + option.value = value; + option.innerHTML = value; + fontName.appendChild(option); + }); + + //fontSize allows only till 7 + for (let i = 1; i <= 7; i++) { + let option = document.createElement("option"); + option.value = i; + option.innerHTML = i; + fontSizeRef.appendChild(option); + } + + //default size + fontSizeRef.value = 3; +}; + +//main logic +const modifyText = (command, defaultUi, value) => { + //execCommand executes command on selected text + document.execCommand(command, defaultUi, value); +}; + +//For basic operations which don't need value parameter +optionsButtons.forEach((button) => { + button.addEventListener("click", () => { + modifyText(button.id, false, null); + }); +}); + +//options that require value parameter (e.g colors, fonts) +advancedOptionButton.forEach((button) => { + button.addEventListener("change", () => { + modifyText(button.id, false, button.value); + }); +}); + +//link +linkButton.addEventListener("click", () => { + let userLink = prompt("Enter a URL"); + //if link has http then pass directly else add https + if (/http/i.test(userLink)) { + modifyText(linkButton.id, false, userLink); + } else { + userLink = "http://" + userLink; + modifyText(linkButton.id, false, userLink); + } +}); + +//Highlight clicked button +const highlighter = (className, needsRemoval) => { + className.forEach((button) => { + button.addEventListener("click", () => { + //needsRemoval = true means only one button should be highlight and other would be normal + if (needsRemoval) { + let alreadyActive = false; + + //If currently clicked button is already active + if (button.classList.contains("active")) { + alreadyActive = true; + } + + //Remove highlight from other buttons + highlighterRemover(className); + if (!alreadyActive) { + //highlight clicked button + button.classList.add("active"); + } + } else { + //if other buttons can be highlighted + button.classList.toggle("active"); + } + }); + }); +}; + +const highlighterRemover = (className) => { + className.forEach((button) => { + button.classList.remove("active"); + }); +}; + +window.onload = initializer(); \ No newline at end of file diff --git a/Rich Text Editor/src/style.css b/Rich Text Editor/src/style.css new file mode 100644 index 00000000..585be4cd --- /dev/null +++ b/Rich Text Editor/src/style.css @@ -0,0 +1,90 @@ +* { + padding: 0; + margin: 0; + box-sizing: border-box; +} + +body { + background-color: #338cf4; + overflow: hidden; +} + +.container { + background-color: #ffffff; + 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 { + height: 28px; + width: 28px; + display: grid; + place-items: center; + border-radius: 3px; + border: none; + background-color: #ffffff; + outline: none; + color: #020929; +} + +select { + padding: 7px; + border: 1px solid #020929; + border-radius: 3px; +} + +.options label, +.options select { + font-family: "Poppins", sans-serif; +} + +.input-wrapper { + display: flex; + align-items: center; + gap: 8px; +} + +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 #ffffff, 0 0 0 3px #020929; +} + +input[type="color"]::-moz-color-swatch { + border-radius: 15px; + box-shadow: 0 0 0 2px #ffffff, 0 0 0 3px #020929; +} + +#text-input { + margin-top: 10px; + border: 1px solid #dddddd; + padding: 20px; + height: 50vh; +} + +.active { + background-color: #e0e9ff; +} \ No newline at end of file