diff --git a/features/comment-newlines/data.json b/features/comment-newlines/data.json new file mode 100644 index 00000000..6b42a3ac --- /dev/null +++ b/features/comment-newlines/data.json @@ -0,0 +1,12 @@ +{ + "title": "Comment Newlines", + "description": "Allows you to view and use multiple lines in comments, rather than just one row of text.", + "credits": [ + { "username": "rgantzos", "url": "https://scratch.mit.edu/users/rgantzos/" } + ], + "type": ["Website"], + "tags": ["New"], + "dynamic": true, + "scripts": [{ "file": "script.js", "runOn": "/users/*", "module": true }], + "styles": [{ "file": "style.css", "runOn": "/*" }] +} diff --git a/features/comment-newlines/script.js b/features/comment-newlines/script.js new file mode 100644 index 00000000..e3892c39 --- /dev/null +++ b/features/comment-newlines/script.js @@ -0,0 +1,56 @@ +export default async function ({ feature, console, className }) { + const FORMATTED_CLASS = className("formatted newline comment"); + + // 2.0 comments + feature.page.waitForElements( + "ul.comments .comment .info", + function (comment) { + if (comment.querySelector(".content." + FORMATTED_CLASS)) return; + const content = comment.querySelector(".content"); + + const clonedContent = content.cloneNode(true); + clonedContent.classList.add(FORMATTED_CLASS); + comment.insertBefore(clonedContent, content); + feature.self.hideOnDisable(clonedContent); + trimCommentText(clonedContent); + } + ); + + function trimCommentText(el) { + let first = el.firstChild; + while ( + first && + first.nodeType === Node.TEXT_NODE && + !first.textContent.trim() + ) { + el.removeChild(first); + first = el.firstChild; + } + + if (first) { + if (first.nodeType === Node.ELEMENT_NODE && first.tagName === "A") { + let afterA = first.nextSibling; + if (afterA && afterA.nodeType === Node.TEXT_NODE) { + afterA.textContent = afterA.textContent.replace(/^\s+/, " "); // ensure 1 space + } else if (!afterA || afterA.nodeType !== Node.TEXT_NODE) { + first.after(document.createTextNode(" ")); + } + } else if (first.nodeType === Node.TEXT_NODE) { + first.textContent = first.textContent.replace(/^\s+/, ""); + } + } + + let last = el.lastChild; + while ( + last && + last.nodeType === Node.TEXT_NODE && + !last.textContent.trim() + ) { + el.removeChild(last); + last = el.lastChild; + } + if (last && last.nodeType === Node.TEXT_NODE) { + last.textContent = last.textContent.replace(/\s+$/, ""); + } + } +} diff --git a/features/comment-newlines/style.css b/features/comment-newlines/style.css new file mode 100644 index 00000000..83fa00f1 --- /dev/null +++ b/features/comment-newlines/style.css @@ -0,0 +1,11 @@ +ul.comments .comment .info .content:not(.ste-formatted-newline-comment) { + display: none !important; +} + +.ste-formatted-newline-comment { + white-space: pre-wrap !important; +} + +.flex-row.comments-list .comment .comment-content, .comment .comment-body .comment-content { + white-space: pre-wrap !important; +} \ No newline at end of file diff --git a/features/features.json b/features/features.json index ea878f7c..ec2b4a66 100644 --- a/features/features.json +++ b/features/features.json @@ -1,4 +1,9 @@ [ + { + "version": 2, + "id": "comment-newlines", + "versionAdded": "v5.0.0" + }, { "version": 2, "id": "recent-followers-and-following", @@ -22,7 +27,7 @@ { "version": 2, "id": "copy-paste-lists", - "versionAdded": "v4.2.0" + "versionAdded": "v5.0.0" }, { "version": 2, @@ -87,7 +92,8 @@ { "version": 2, "id": "align-to-center", - "versionAdded": "v4.0.0" + "versionAdded": "v4.0.0", + "versionUpdated": "v5.0.0" }, { "version": 2, @@ -243,7 +249,8 @@ { "version": 2, "id": "follow-on-projects", - "versionAdded": "v3.5.0" + "versionAdded": "v3.5.0", + "versionUpdated": "v5.0.0" }, { "version": 2, @@ -323,7 +330,8 @@ { "version": 2, "id": "localized-explore", - "versionAdded": "v3.2.0" + "versionAdded": "v3.2.0", + "versionUpdated": "v5.0.0" }, { "version": 2,