From 1566d77b79bbf64b2c1594d45120239946ec2a1e Mon Sep 17 00:00:00 2001 From: MaterArc <105017592+MaterArc@users.noreply.github.com> Date: Sat, 6 Jul 2024 17:45:59 -0400 Subject: [PATCH 1/8] Align to Center --- features/align-to-center/data.json | 18 +++++++++ features/align-to-center/script.js | 63 ++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 features/align-to-center/data.json create mode 100644 features/align-to-center/script.js diff --git a/features/align-to-center/data.json b/features/align-to-center/data.json new file mode 100644 index 00000000..e926f233 --- /dev/null +++ b/features/align-to-center/data.json @@ -0,0 +1,18 @@ +{ + "title": "Align to Center", + "description": "Use Control + U / Command + U to center text within the instruction box on projects", + "credits": [ + { + "username": "Brass_Glass", + "url": "https://scratch.mit.edu/users/Brass_Glass/" + }, + { + "username": "MaterArc", + "url": "https://scratch.mit.edu/users/MaterArc/" + } + ], + "type": ["Website"], + "tags": ["New", "Recommended"], + "dynamic": true, + "scripts": [{ "file": "script.js", "runOn": "/projects/*" }] +} diff --git a/features/align-to-center/script.js b/features/align-to-center/script.js new file mode 100644 index 00000000..d7181bde --- /dev/null +++ b/features/align-to-center/script.js @@ -0,0 +1,63 @@ +export default async function ({ feature, console }) { + const availableWidth = 405; + + function getSpaceWidth() { + const span = document.createElement("span"); + span.style.visibility = "hidden"; + span.style.whiteSpace = "pre"; + span.textContent = " "; + document.body.appendChild(span); + const spaceWidth = span.getBoundingClientRect().width; + document.body.removeChild(span); + return spaceWidth; + } + + function getTextWidth(text) { + const span = document.createElement("span"); + span.style.visibility = "hidden"; + span.style.whiteSpace = "pre"; + span.textContent = text; + document.body.appendChild(span); + const textWidth = span.getBoundingClientRect().width; + document.body.removeChild(span); + return textWidth; + } + + function centerAlignText() { + const form = document.querySelector(".project-description-form"); + if (form) { + const activeElement = document.activeElement; + if ( + activeElement.tagName === "TEXTAREA" && + form.contains(activeElement) + ) { + const spaceWidth = getSpaceWidth(); + const lines = activeElement.value.split("\n"); + const centeredLines = lines.map((line) => { + const textWidth = getTextWidth(line); + const totalSpaces = (availableWidth - textWidth) / spaceWidth / 2; + const spaces = " ".repeat(Math.floor(totalSpaces)); + return spaces + line; + }); + activeElement.value = centeredLines.join("\n"); + } + } + } + + window.addEventListener("keydown", (event) => { + if ((event.ctrlKey || event.metaKey) && event.key === "u") { + centerAlignText(); + } + }); + + await ScratchTools.waitForElements( + ".project-description-form textarea", + (textareas) => { + textareas.forEach((textarea) => { + textarea.addEventListener("input", function () { + centerAlignText(); + }); + }); + } + ); +} From 6f14f05b60154e9c77e6e0e07b940099009299be Mon Sep 17 00:00:00 2001 From: MaterArc <105017592+MaterArc@users.noreply.github.com> Date: Sat, 6 Jul 2024 17:46:38 -0400 Subject: [PATCH 2/8] Update features.json --- features/features.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/features/features.json b/features/features.json index 9e7bf259..e2252726 100644 --- a/features/features.json +++ b/features/features.json @@ -1,4 +1,9 @@ [ + { + "version": 2, + "id": "align-to-center", + "versionAdded": "v4.0.0" + }, { "version": 2, "id": "upload-thumbnail", From 5028bf35b08f6e9d317b10773a56e260eeb14756 Mon Sep 17 00:00:00 2001 From: MaterArc <105017592+MaterArc@users.noreply.github.com> Date: Sat, 6 Jul 2024 17:48:12 -0400 Subject: [PATCH 3/8] Prevent Shifting --- features/align-to-center/script.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/features/align-to-center/script.js b/features/align-to-center/script.js index d7181bde..ae3cd5a7 100644 --- a/features/align-to-center/script.js +++ b/features/align-to-center/script.js @@ -23,6 +23,14 @@ export default async function ({ feature, console }) { return textWidth; } + function clearCenterAlignment(textarea) { + const lines = textarea.value.split("\n"); + const uncenteredLines = lines.map((line) => { + return line.replace(/^\s+/, ""); + }); + textarea.value = uncenteredLines.join("\n"); + } + function centerAlignText() { const form = document.querySelector(".project-description-form"); if (form) { @@ -31,6 +39,8 @@ export default async function ({ feature, console }) { activeElement.tagName === "TEXTAREA" && form.contains(activeElement) ) { + clearCenterAlignment(activeElement); + const spaceWidth = getSpaceWidth(); const lines = activeElement.value.split("\n"); const centeredLines = lines.map((line) => { @@ -61,3 +71,4 @@ export default async function ({ feature, console }) { } ); } + From 65650a3bf40d835d7fac024efc1d3bdbf39d6c6b Mon Sep 17 00:00:00 2001 From: MaterArc <105017592+MaterArc@users.noreply.github.com> Date: Sun, 7 Jul 2024 14:41:19 -0400 Subject: [PATCH 4/8] Remove waitForElements --- features/align-to-center/script.js | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/features/align-to-center/script.js b/features/align-to-center/script.js index ae3cd5a7..7eef27f8 100644 --- a/features/align-to-center/script.js +++ b/features/align-to-center/script.js @@ -23,14 +23,6 @@ export default async function ({ feature, console }) { return textWidth; } - function clearCenterAlignment(textarea) { - const lines = textarea.value.split("\n"); - const uncenteredLines = lines.map((line) => { - return line.replace(/^\s+/, ""); - }); - textarea.value = uncenteredLines.join("\n"); - } - function centerAlignText() { const form = document.querySelector(".project-description-form"); if (form) { @@ -39,8 +31,6 @@ export default async function ({ feature, console }) { activeElement.tagName === "TEXTAREA" && form.contains(activeElement) ) { - clearCenterAlignment(activeElement); - const spaceWidth = getSpaceWidth(); const lines = activeElement.value.split("\n"); const centeredLines = lines.map((line) => { @@ -59,16 +49,4 @@ export default async function ({ feature, console }) { centerAlignText(); } }); - - await ScratchTools.waitForElements( - ".project-description-form textarea", - (textareas) => { - textareas.forEach((textarea) => { - textarea.addEventListener("input", function () { - centerAlignText(); - }); - }); - } - ); } - From 8fdde1c13ba549f5e20b56fff1d95a3c0541f00c Mon Sep 17 00:00:00 2001 From: MaterArc <105017592+MaterArc@users.noreply.github.com> Date: Sun, 7 Jul 2024 14:50:13 -0400 Subject: [PATCH 5/8] More Fixes + Add back prevent multiple --- features/align-to-center/script.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/features/align-to-center/script.js b/features/align-to-center/script.js index 7eef27f8..1ebb0ae6 100644 --- a/features/align-to-center/script.js +++ b/features/align-to-center/script.js @@ -23,6 +23,14 @@ export default async function ({ feature, console }) { return textWidth; } + function clearCenterAlignment(textarea) { + const lines = textarea.value.split("\n"); + const uncenteredLines = lines.map((line) => { + return line.replace(/^\s+/, ""); + }); + textarea.value = uncenteredLines.join("\n"); + } + function centerAlignText() { const form = document.querySelector(".project-description-form"); if (form) { @@ -31,6 +39,8 @@ export default async function ({ feature, console }) { activeElement.tagName === "TEXTAREA" && form.contains(activeElement) ) { + clearCenterAlignment(activeElement); // Clear any existing center alignment + const spaceWidth = getSpaceWidth(); const lines = activeElement.value.split("\n"); const centeredLines = lines.map((line) => { From e72c91c9d20a01be461e50393912b656aa41f5c2 Mon Sep 17 00:00:00 2001 From: MaterArc <105017592+MaterArc@users.noreply.github.com> Date: Sun, 7 Jul 2024 14:51:02 -0400 Subject: [PATCH 6/8] Update script.js --- features/align-to-center/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/align-to-center/script.js b/features/align-to-center/script.js index 1ebb0ae6..8f792b9c 100644 --- a/features/align-to-center/script.js +++ b/features/align-to-center/script.js @@ -39,7 +39,7 @@ export default async function ({ feature, console }) { activeElement.tagName === "TEXTAREA" && form.contains(activeElement) ) { - clearCenterAlignment(activeElement); // Clear any existing center alignment + clearCenterAlignment(activeElement); const spaceWidth = getSpaceWidth(); const lines = activeElement.value.split("\n"); From 2157d3a3b1775e7ac2ced69b47a3af5c81bdf72e Mon Sep 17 00:00:00 2001 From: rgantzos <86856959+rgantzos@users.noreply.github.com> Date: Sun, 7 Jul 2024 12:45:03 -0700 Subject: [PATCH 7/8] Let it work for Notes & Credits too --- features/align-to-center/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/align-to-center/script.js b/features/align-to-center/script.js index 8f792b9c..514da195 100644 --- a/features/align-to-center/script.js +++ b/features/align-to-center/script.js @@ -32,7 +32,7 @@ export default async function ({ feature, console }) { } function centerAlignText() { - const form = document.querySelector(".project-description-form"); + const form = document.querySelector(".project-notes"); if (form) { const activeElement = document.activeElement; if ( From e45bd65d30e6a4c92931d3c645723bb5c4c4ec84 Mon Sep 17 00:00:00 2001 From: rgantzos <86856959+rgantzos@users.noreply.github.com> Date: Sun, 7 Jul 2024 13:37:20 -0700 Subject: [PATCH 8/8] A few fixes and improvements and stuff --- features/align-to-center/data.json | 22 ++++++++++++++-- features/align-to-center/icon.svg | 1 + features/align-to-center/script.js | 42 +++++++++++++++++++++++++++--- features/align-to-center/style.css | 17 ++++++++++++ 4 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 features/align-to-center/icon.svg create mode 100644 features/align-to-center/style.css diff --git a/features/align-to-center/data.json b/features/align-to-center/data.json index e926f233..4cc6dda2 100644 --- a/features/align-to-center/data.json +++ b/features/align-to-center/data.json @@ -1,6 +1,6 @@ { "title": "Align to Center", - "description": "Use Control + U / Command + U to center text within the instruction box on projects", + "description": "Allows you to align text in Instructions and Notes & Credits boxes to the center of the input.", "credits": [ { "username": "Brass_Glass", @@ -14,5 +14,23 @@ "type": ["Website"], "tags": ["New", "Recommended"], "dynamic": true, - "scripts": [{ "file": "script.js", "runOn": "/projects/*" }] + "scripts": [{ "file": "script.js", "runOn": "/projects/*" }], + "styles": [{ "file": "style.css", "runOn": "/projects/*" }], + "resources": [{ "name": "center-align", "path": "/icon.svg" }], + "options": [{ "id": "use-align-hotkey", "name": "Use Hotkey (Ctrl + U)", "type": "boolean" }], + "components": [ + { + "type": "info", + "content": "For Mac users, use Command + U when the hotkey option is enabled to center text.", + "if": { + "type": "all", + "conditions": [ + { + "type": "os", + "value": "Macintosh" + } + ] + } + } + ] } diff --git a/features/align-to-center/icon.svg b/features/align-to-center/icon.svg new file mode 100644 index 00000000..c1304368 --- /dev/null +++ b/features/align-to-center/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/features/align-to-center/script.js b/features/align-to-center/script.js index 514da195..2ec53b9e 100644 --- a/features/align-to-center/script.js +++ b/features/align-to-center/script.js @@ -31,10 +31,12 @@ export default async function ({ feature, console }) { textarea.value = uncenteredLines.join("\n"); } - function centerAlignText() { + function centerAlignText(textarea) { + if (!feature.self.enabled) return; + const form = document.querySelector(".project-notes"); if (form) { - const activeElement = document.activeElement; + const activeElement = textarea || document.activeElement; if ( activeElement.tagName === "TEXTAREA" && form.contains(activeElement) @@ -46,7 +48,8 @@ export default async function ({ feature, console }) { const centeredLines = lines.map((line) => { const textWidth = getTextWidth(line); const totalSpaces = (availableWidth - textWidth) / spaceWidth / 2; - const spaces = " ".repeat(Math.floor(totalSpaces)); + const spaces = + totalSpaces > 0 ? " ".repeat(Math.floor(totalSpaces)) : ""; return spaces + line; }); activeElement.value = centeredLines.join("\n"); @@ -56,7 +59,38 @@ export default async function ({ feature, console }) { window.addEventListener("keydown", (event) => { if ((event.ctrlKey || event.metaKey) && event.key === "u") { - centerAlignText(); + if (feature.settings.get("use-align-hotkey")) { + centerAlignText(); + } } }); + + console.log("hey"); + + ScratchTools.waitForElements( + ".project-notes .project-textlabel", + function (div) { + if (div.querySelector(".ste-align-center")) return; + + let textarea = div.parentElement.querySelector("textarea"); + + let img = document.createElement("img"); + img.src = feature.self.getResource("center-align"); + img.className = "ste-align-center"; + img.addEventListener("click", function () { + centerAlignText(textarea); + }); + feature.self.hideOnDisable(img); + + div.appendChild(img); + + textarea.addEventListener("focusin", function () { + img.classList.add("show"); + }); + + textarea.addEventListener("focusout", function () { + img.classList.remove("show"); + }); + } + ); } diff --git a/features/align-to-center/style.css b/features/align-to-center/style.css new file mode 100644 index 00000000..c1937d8a --- /dev/null +++ b/features/align-to-center/style.css @@ -0,0 +1,17 @@ +.project-notes .project-textlabel { + position: relative; + width: 100%; +} + +.ste-align-center { + position: absolute; + right: 0px; + top: 0px; + height: 100%; + cursor: pointer; + display: none; +} + +.ste-align-center.show { + display: block; +} \ No newline at end of file