-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Discussion] Having this repo (and others) as a single extension? #14
Comments
You are free to comment about the extension itself (feedback very welcome, or tell me if you're interested on working on it!) but the main point I want to make here is: how do you convert an existing userstyle or extension into an addon? Manually? It would work because of the small scale, but it would be hard to easily push updates to the userstyle and to the addon at once. It would probably mean manually replicating every change in the user.css file here in the addon, manually. |
@World_Lanuages Wow! That sounds great! There's one for dark mode, this one, and a few others. I can link them… |
@Explosion-Scratch Sure please collect all the userscripts you can find. Sadly I don't use many so I don't really know about more than a few of them. Don't send them here tho, since this is a little offtopic. Let's see what @mxmou has to say about this idea. |
@World_Languages I made a (unshared) project with several in it. |
Here are some people who make/have made userscripts: Scratch usernames are first, then github ones. |
nanalan's github username is "nanaian". And there's also these |
@mxmou You can close this issue since it's not directly related to the userstyle. I didn't find a better way to contact you so I made an issue. For obvious reasons, we can't talk about extensions on Scratch |
I think it's related enough to this repo so I'm going to keep it open for now. I'll explain my opinion later (tomorrow?). |
I'm sure some of the scratchers I mentioned above would be intrested in contributing to this dicussion, should I nofity them? |
@Explosion-Scratch I already have ways to contact them for most of them. I think we should wait until we have something that works. After that, anyone can contribute and extend existing addons, or create their own. |
@World_Languages Okay, that's fine! :) About the second part of your posts, since the userstyles work fine on their own it would be easy to turn them on and off from one place. The complicated part is the messaging part. |
I think the best option is to have builtin methods that both background scripts and content scripts can use. For example, getMessageCount(). If the second request to the message count comes less than a few seconds after the first one, instead of requesting the message count again to Scratch, it could reuse the previous value.
This will be a nice challenge, because it will involve passing data from background pages to addon content scripts. Each addon content script (and background script) is supposed to be isolated with each other to avoid stuff like variable collisions. |
Maybe to have userstyles like these one work cleanly, the extension could provide an API for background addon scripts to register a userstyle, by providing the path to the CSS file and the Scratch URL pattern accordingly. This sounds better than doing lots of if statements inside an addon content scripts. (Note: then for this to be ported into an addon, every moz-document media property should be split up into its own CSS file, which doesn't sound very hard to automate tbh, but we could still do it manually. At least we're not mixing JS and CSS with this approach.) This would mean that addons can have background scripts, content scripts (used for userscripts) or both. |
I really like this idea. About converting userscripts and userstyles to addons, I would try to automate it as much as possible. A userscript would just become a single content script, and the conversion seems to be quite straightforward (some parts still need to be changed manually), so only userstyles might be a problem. Some like this one (not really a great example because it isn't Scratch-related but I don't use many userstyles) are just a few lines of plain CSS, but mine is written in Stylus, uses
Using built-in methods for most of the Scratch API (or, alternatively, a single method for accessing the API) would be useful. I don't think having addons which depend on other addons is a good idea.
Having an API for that is probably the best idea. I am interested in helping with this, although I believe you know more about browser extensions than me. |
@mxmou Thanks for sharing your thoughts!
Agreed, after we notice 2 addons would duplicate each other's work, we should implement APIs so both can "collaborate". For example, showing message count in the editor in a "project enhancements" addon should use the message count already obtained a few seconds before by the new message notifier. This means the addon API might not ever be finished! As new ideas appear, we might notice something is about to get duplicated.
I see, but after I have a prototype with basic APIs working hopefully you'll understand how it works! About the userstyle itself:
Eh, that sounds weird... If we already have the code to convert Stylus to CSS, why not run it ourselves? Remember userstyles can't autoupdate (nothing in the addon library can) so we'd have to update the Stylus code in the extension itself anyway. Also, about this userstyle using variables, I'm not sure how that could be handled. Different css files depending on whether an addon setting is enabled? Pseudocode for the background script for this userstyle as an addon: addon.userstyles.register({
styles: "main.css", // Relative to the addon's root folder
urls: ["https://scratch.mit.edu/*"]
});
addon.userstyles.register({
styles: "dark.css",
urls: ["https://scratch.mit.edu/*"],
if_setting_enabled: "dark_mode" // Making the extension handle this allows already opened tabs to update the userstyles without the addon caring about it (and no refresh needed!)
}); Note: this is regards boolean variables in userstyles (like light or dark mode). If we want to let users choose, for example, a color, that should probably be handled with a CSS variable and we should provide mechanisms for these to be accessed by the userstyles with syntax like |
@World_Languages, sounds good. |
@Explosion-Scratch Nickynouse's GitHub is Airhogs777, but he left GitHub. He made this userscript. (No longer available) |
@BoomerScratch Thanks! Please try to get as many userscripts as possible and list them somewhere. @mxmou I'm working on background scripts and content scripts first, so I won't think a lot about the userstyles API for now, but have any ideas or suggestions? Specially how to handle user choices (like dark mode or not). Split different option choices between different CSS files? |
Let's see we should do these steps to archive/collect userscripts and userstyles: |
Thanks so much for helping out @Explosion-Scratch In the meanwhile I'm playing with implementing the let msgCount = null;
let mostRecentMsgIds = [];
const emojis = {
"addcomment": "💬",
"forumpost": "📚",
"loveproject": "❤️",
"favoriteproject": "⭐",
"followuser": "👤",
"curatorinvite": "✉️",
"remixproject": "🔄"
};
checkCount();
setInterval(checkCount, 6000);
async function checkCount() {
const newCount = await addon.account.getMsgCount();
console.log(newCount);
if(msgCount !== newCount) {
const oldMsgCount = msgCount;
msgCount = newCount;
//addon.badge.setText(msgCount);
if(msgCount !== oldMsgCount) checkMessages();
}
}
function getMostRecentIds(messagesObj) {
const arr = [];
for(const message of messagesObj) {
arr.push(message.id);
// We only need a non-comment as a reference, since comments
// are the only types of messages that could dissapear.
if(message.type !== "addcomment") break;
}
return arr;
}
function newMessage(message) {
addon.notifications.create("test", {
type: "basic",
title: "New message!",
iconUrl: "/images/icon.png",
message: message,
buttons: [{
title: "Open messages page"
}, {
title: "Mark all as read"
}],
requireInteraction: true
});
}
function markAsRead() {
addon.fetch("https://scratch.mit.edu/site-api/messages/messages-clear/", {method: "POST"});
//addon.badge.setText("");
}
async function checkMessages() {
const res = await addon.fetch(`https://api.scratch.mit.edu/users/${addon.auth.username}/messages?limit=40&offset=0`);
const messages = await res.json();
if(mostRecentMsgIds.length === 0) mostRecentMsgIds = getMostRecentIds(messages);
else if(messages[0].id !== mostRecentMsgIds[0]) {
for(const message of messages) {
if(mostRecentMsgIds.includes(message.id)) break;
// We found a new message! No need to notify, we continue...
let messageType = message.type;
if(message.type === "addcomment") {
messageType += "/";
if(message.comment_type === 0) {
// Project comment
const replyFor = message.commentee_username;
if(replyFor === null) messageType += "ownProjectNewComment";
else if(replyFor === addon.auth.username) messageType += "projectReplyToSelf";
else messageType += "ownProjectReplyToOther";
} else if(message.comment_type === 1) {
const profile = message.comment_obj_title;
const replyFor = message.commentee_username;
if(profile === addon.auth.username) {
if(replyFor === null) messageType += "ownProfileNewComment";
else if(replyFor === addon.auth.username) messageType += "ownProfileReplyToSelf";
else messageType += "ownProfileReplyToOther";
} else {
messageType += "otherProfileReplyToSelf";
}
} else if(message.comment_type === 2) messageType = "studio";
}
newMessage(messageType);
const emoji = emojis[message.type] || "";
}
mostRecentMsgIds = getMostRecentIds(messages);
}
}
|
Also there is the issue of where to store this info, here are a few options:
|
@World_Languages That looks AMAZING!! Thanks :) Also I'm going to notify the otjer scratchers I mentioned with the "@person" thing. |
Lol you always get my username wrong here. GitHub usernames don't support underscores. |
I'd say you collect userscripts privately for now, we can see how to merge the lists in the future. |
@griffpatch @apple502j @MegaApuTurkUltra @nanaian @towerofnix |
Ohh that's what you meant by mentioning them lool. I would not disturb them yet but you already did lol so ¯\(ツ)/¯ |
(Dang, I hit comment on accdent, continued here) […] userscripts and userstyles that many scratchers have worked on for 3.0. Eventually this will become a browser extension meant to improve and customize scratch! |
@WorldLanguages (<-- fixed!) Umm, I guess we can still collect them privately, oh well… XD |
Also could we consider fitting griffpatch's Scratch Developer Tools extension into here, it adds a lot of functionality tok the scratch editor such as searching blocks, copy and pasting them, confirmation before sharing, deleting orphan blocks and a lot more. |
|
@tb148 Okay! Thanks :) |
(Mentioning maximouse will notify a completely different user, don't forget my GitHub username is mxmou) |
@mxmou I guess this is okay then. |
Yeah I own @ScratchAddons. Stuff that works already on my machine: |
@WorldLanages. Why don't we stop with the collecting and organizing userscripts for now and I'll just work on that on my own. You and MaxiMouse can work on the coding for the addon itself, once a working addon is in shape we can start adding userscripts and userstyles to it. I'll close the other issue for collescting them for now, we might want to re-open it later when the userscripts are ready to be put into the addon. Also could you invite a few users to ScratchAddons? Me, @mxmou and ask BoomerScratch and tb148 if they want to join as well |
@Explosion-Scratch I do want to join. |
also, @WorldLanguages, who have you invited yet? |
@WorldLanguages Again, great. And yes, please invite me and @Explosion-Scratch to the organization. When the code becomes public this discussion should be moved there. |
@tb148 Thanks for helping! WorldLanguages has not invited me yet and t my knowledge no-one else. |
@WorldLanguages Injecting the userscripts and userstyles is easy. We can use this to get the URLs of all the tabs and the IDs of the tabs (from a StackOverflow question, which I modified): tabsInfo = [];
chrome.windows.getAll({populate:true},windows => {
windows.forEach(window => {
window.tabs.forEach(tab => {
tabsInfo.push({"url":tab.url,"id":tab.id});
});
});
});
tabsInfo.filter(x=>x.url.startsWith("https://scratch.mit.edu")); Now, inject a script in the tab. tabsInfo.forEach(e => {
chrome.tabs.executeScript(e.id,{code:'document.body.appendChild(document.createElement("style")).innerText = "USERSTYLE CODE HERE"'});
}); For a userscript: tabsInfo.forEach(e => {
chrome.tabs.executeScript(e.id,{code:`element=document.body.appendChild(document.createElement("script"));
element.innerText = "USERSCRIPT CODE HERE";
setTimeout(()=>element.remove());`});
}); Turning off userstyles is easy, but turning off userscripts requires you to reload the page. |
@BoomerScratch. Okay. Thanks for finding that! A "save" button that reloaded wouldn't be to hard would it? Also would you be intrested in joining this collab long term? (Like for the rest of the project) |
Thanks for the help @BoomerScratch however don't worry, I haven't coded content scripts yet but I have it all in my head lol. I don't think I should go with that approach because Chrome (and other browsers) "sandbox" extension code if you inject it like that. Most uses for content scripts won't care if they are sanboxed or not, however some ones (like griffpatch's developer tools) only work if they aren't sandboxed, and are ran in the same context as the page. So to simplify it I'll just run all content scripts unsandboxed, which might require a bit more work but makes important addons work. |
I've been kinda lazy lately these last few days but I promise you'll be able to write your own addons by August. However, implementing more complex addons like griffpatch's developer tools might take some more work because of the event listener traps, but most userscripts will just work. |
I'll try to move this to the org tomorrow. I'll invite you all. Will create specific issues for each thing. And I might start working on addon APIs documentation. I'll create a specific issue to think how to implement this userstyle so this can be closed by that point. |
@WorldLanguages Sounds great! I'm not doing that much for this amyways exept finding random stuff and posting it here :P I appreciate your help on this project! The final product will be amazing! |
@WorldLanguages Have anyone been invited yet? |
Not all userstyles are plain CSS, and we should also find a not very ugly/complex way to handle |
@tb148 I wasn't. |
@tb148 I was not invited yet either. |
Invited! |
Did you invite @tb148? |
Yep |
Heh, where it all began lol |
Yeah! I just saw this! |
Finding userscripts and userstyles for Scratch is very hard because of the sharing policy in place. Don't you think there should be an extension similar to 2014's Mega Scratch Userscript? A single extension that lets you toggle different Scratch related extensions (like Griffpatch's developer tools and message manager), userscripts and userstyles (like the ones on this repo).
This is just in my head now, but I don't think it would be super complex to make it easy to scale this extension. What I have in mind is creating a new extension called "Scratch Addons" (or similar) that is basically a userscript manager, but just for Scratch, and only allows you to use the built-in addons approved by us, living inside a folder inside the extension's source code (they couldn't auto update because of Chrome's policy on remote code execution). These addons can run background scripts and userscripts as if they were extensions. Every addon has a pseudo-manifest where it tells the main extension what content scripts (extension's equivalents of userscripts) run for each URL pattern, if it wants to run in the extension's background page, if it has a popup, and maybe even declare permissions (for example, 2 addons might want to use the extension's number badge, so the user will have to choose a single one). Maybe this manifest could declare what user settings these addons have available.
Having said this, I think you notice creating an "addon" and a userscript wouldn't be very different. A userscript could be easily converted into an addon, and an extension with a little more work too. A userstyle is also not as easy (like the one in this repo) but I don't see why the stylus syntax couldn't be converted into CSS, and the moz-document media queries into JavaScript if statements.
What do you think? This is a centralized approach, but because of the policy I think it's a good option. It's a fun project (because of this many addons in an extension architecture) and it would be way easier for new userscripts, userstyles or extensions made by Scratchers to be available immediately to existing extension users.
The text was updated successfully, but these errors were encountered: