That's weird, it worked for shaggyze
I use console.log or the dev tools debugger.
No wait I'm dumb, I have other userscripts interfering with it. As a helpful suggestion, instead of overriding the reply button, add a new one called "auto-format with titles". This is how to add a new button after the reply button:
So, one thing I noticed was that it'll auto format links as you paste them in. While it would be desirable for most cases, it could become problematic if you wanted to manually format them, although you could always just edit the text part of the URL tags.
Another thing is that there's no indicator of progress, and so if it's formatting a lot of things then it could become very slow.
Finally, I'd love to restructure the code into functions and then deploy the hashmap-based replacement. Maybe we could also put in a cache so that if a link is rendered and then pasted in again it doesn't need to make a whole network request.
I also just noticed a bug where the script will touch quotes. I don't think that's a good idea because it then stops being a direct quote. At this point it might require a bbcode parser of some sort, so we would know where the quotes start and end. Alternatively, I'm thinking we could regex out all the quotes into an array and insert a marker instead, such as "__QUOTE_1__", "__QUOTE_2__", and so on. At the end of processing, we just read back the array and put the quotes back in.
It's more practical if users just edit the text part of the URL tags if they don't want it to be the entry title, or just the entry title.
But that's the purpose of the script...
If an user most of the time don't want it to be the entry title, or just the entry title the user would probably not install the script anyway.
That's true, so I would just tell users to watch and wait in the script installation page. But I suppose any user will know this and always check if the script worked properly or not anyway.
I couldn't find since becoming a mal user a topic where users have to post more than 10 mal links at once.
Users posting much more than 20 links at once is a rare case, although it's rare it worked in a blink of an eye in my tests too, so it's not something I'm worried about.
I was going to also do the hashmap-based replacement when the user is writing a link, not only when the page loads. But even without it the API isn't called more than once if the link was previously converted by the script no matter how much the user writes.
The hashmap-based replacement was harder to implement than the .replaceAll regexes when the user is typing.
Adding more functions would make the code look better, but they are all well wrapped already and overly commented, there's no way someone won't know where something starts or finish. + the fact that most users don't see the code, and even less users try to modify the code anyway. So I think that adding more functions would only make more lines of code... There are currently only 5 things the script does
1 works when typed (onkeyup event listener)
2 works when mal loads (after the onkeyup event listener ends)
3 "Function" to convert links that already have titles on it
4 "Function" to convert links that DO NOT have titles on it
5 "Function" to convert forum links
The first 2 one's are very easy to find where they start and end. Reading the comments of the other "functions" also make them easy to see that too. Since it's only 3 functions, 3 for each "listener" the program isn't big or complex enough to have a need of functions for better visual formatting for other devs. I'm a fan of having fewer lines when possible and when it doesn't look terrible.
As for the cache I already had that idea too, it would use tampermonkey storage. But I guess the just implemented hashmap-based replacement on page load is already a good enough way to make the script not do too many API calls. The API seems to support up to 1350 calls without any timeout every 5mins, so using tampermonkey storage would be good in the sense that there would be no API calls made if the user reloads or opens again the same page for example, but then there would be no way to know when the title changed and no way to update it either. Unless I make like an right or middle click event listener to update the link and make an API call, what would be some work (copying and slightly changing the codes I already did for it in other scripts) and more lines of code.
You are right, I really suppose MAL doesn't often update titles that much, but the API currently seems to have a good rate limit, what makes me not worry about having a cache too much. It will be considered if the rate limit decreases too much.
Not really all symbols are ignored or replaced to nothing now, but the way it currently is, seems to be working great for at least almost all MAL links. Maybe your array idea would work, but then I would probably have to change all loops and everything else in the code.
This should be fixable using only regex the way the code is right now, so I would just have to update the regex what would be much easier and better to do I think.
I would appreciate if you want to try making the regex not replace " with nothing and work better. I will probably look more into this in the future I guess, but not right now I think.
@hacker09 By the way, if you ever want to make it easier to work with the forum post text, I made a library to convert BBCode into an AST. I intentionally built it so that calling `toString()` on the root node will give you back exactly what you put into the tree. The nodes are mutable, so it would be possible to carry out the URL replacements in-tree and then just cast it to a string. This also makes it easier to skip undesirable elements, as actual text is always stored in a "TextNode" while all other nodes have a name corresponding to the BBCode tag (a url node has the "url" name, for example).
You could do this:
function getTextNodes(tree){
const skipNodeNames = ["url", "img", "code", "quote"];
let nodeQueue = [tree.children];
let textNodes = [];
while (nodeQueue.length > 0){
const nextNode = nodeQueue[0];
nodeQueue = nodeQueue.slice(1);
if (nextNode.name === "TextNode"){
textNodes.push(nextNode);
} else if (!skipNodeNames.includes(nextNode.name)){
nodeQueue.push(...nextNode.children);
}
return textNodes;
}
This would give you all text nodes with the exception of any text nodes in blacklisted tags. There is no blacklist against putting tags inside of the text nodes, so you can always do this:
textNodes.forEach(node => {
node.text = replaceWithFormattedBBCode(node.text);
});
console.log(tree.toString()); // This is the formatted BBCode.
Oh okay, I like to use CDNs but I didn't know which name I should look for
I'm confused? Were you able to get an instance of RootNode? In the context you load the script, there will be a 'bbcode_ast" global variable (alternatively you can always use "window.bbcode_ast"). The "default" attribute is a parser that is set up for MyAnimeList. From there, there is a "parse" method. So you should usually use "bbcode_ast.default.parse("text goes here")".
This URL is invalid. But let me show you an example:
// ==UserScript==
// @name New Userscript
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match [url=https://myanimelist.net/forum/?topicid=2033985&show=50]Links to titles - MAL[/url]
// @require https://cdn.jsdelivr.net/npm/bbcode-ast@1.0.2/dist/bundle.js
// @icon https://www.google.com/s2/favicons?sz=64&domain=myanimelist.net
// @grant none
// ==/UserScript==
(function() {
'use strict';
const text = `[quote=hacker09 message=67215797]@Remocracy
Looks interesting, how do I actually test it?
I probably think it's easier to fix the regex though, but let's see.[/quote]
Put this line into your userscript:
[code]// @require https://cdn.jsdelivr.net/npm/bbcode-ast@1.0.2/dist/bundle.js[/code]
Then you can access it globally, like so:
[code]bbcode ast.default.parse(textToParse)[/code]
If you want to use it inside of a JS console, you can open this URL (in chrome at least, idk about firefox): [code]data:text/html,<script src=https://cdn.jsdelivr.net/npm/bbcode-ast@1.0.2/dist/bundle.js></script>[/code]`
console.log(bbcode ast.default.parse(text))
})();
Updated version, I just noticed the script ran a replace on the old one:
// ==UserScript==
// @name New Userscript
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match https://myanimelist.net/*
// @require https://cdn.jsdelivr.net/npm/bbcode-ast@1.0.2/dist/bundle.js
// @icon https://www.google.com/s2/favicons?sz=64&domain=myanimelist.net
// @grant none
// ==/UserScript==
(function() {
'use strict';
const text = `[quote=hacker09 message=67215797]@Remocracy
Looks interesting, how do I actually test it?
I probably think it's easier to fix the regex though, but let's see.[/quote]
Put this line into your userscript:
[code]// @require https://cdn.jsdelivr.net/npm/bbcode-ast@1.0.2/dist/bundle.js[/code]
Then you can access it globally, like so:
[code]bbcode ast.default.parse(textToParse)[/code]
If you want to use it inside of a JS console, you can open this URL (in chrome at least, idk about firefox): [code]data:text/html,<script src=https://cdn.jsdelivr.net/npm/bbcode-ast@1.0.2/dist/bundle.js></script>[/code]`
console.log(bbcode_ast.default.parse(text))
})();