diff --git a/features/align-to-center/data.json b/features/align-to-center/data.json new file mode 100644 index 00000000..4cc6dda2 --- /dev/null +++ b/features/align-to-center/data.json @@ -0,0 +1,36 @@ +{ + "title": "Align to Center", + "description": "Allows you to align text in Instructions and Notes & Credits boxes to the center of the input.", + "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/*" }], + "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 new file mode 100644 index 00000000..2ec53b9e --- /dev/null +++ b/features/align-to-center/script.js @@ -0,0 +1,96 @@ +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 clearCenterAlignment(textarea) { + const lines = textarea.value.split("\n"); + const uncenteredLines = lines.map((line) => { + return line.replace(/^\s+/, ""); + }); + textarea.value = uncenteredLines.join("\n"); + } + + function centerAlignText(textarea) { + if (!feature.self.enabled) return; + + const form = document.querySelector(".project-notes"); + if (form) { + const activeElement = textarea || document.activeElement; + if ( + activeElement.tagName === "TEXTAREA" && + form.contains(activeElement) + ) { + clearCenterAlignment(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 = + totalSpaces > 0 ? " ".repeat(Math.floor(totalSpaces)) : ""; + return spaces + line; + }); + activeElement.value = centeredLines.join("\n"); + } + } + } + + window.addEventListener("keydown", (event) => { + if ((event.ctrlKey || event.metaKey) && event.key === "u") { + 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 diff --git a/features/features.json b/features/features.json index 7a11d107..5eb894bd 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": "more-editor-fonts",