Hello, I am the lead developer of the Rehike project, and I have a fair amount of experience working with ECMAScript and I know how to design good code. If I take it correctly, you seem to have some beginner level code that has some simple mistakes that complicate the flow of your code a lot.
For example, look at this section of the main JS file that forms a triangle with nested if statements. There are a few bad things going on, notably, a lack of proper formatting and an unclear use of asynchronous code. I recommend that you format long conditional operations like this to use &&
rather than using multiple nested if statements. That is to say:
// Instead of this:
if (flags.hasOperationA) {
if (flags.hasOperationB) {
if (flags.hasOperationC) {
operationD();
}
}
}
// Do this:
if (
flags.hasOperationA &&
flags.hasOperationB &&
flags.hasOperationC
) {
operationD();
}
This approach not only makes it more clear to you and other developers what is going on here and doesn't require scrolling in the same way, but it also makes you intent more obvious and looks nicer to the eyes. It's just all around a better way to write the same thing.
I also reckon you're unfamiliar with asynchronous ECMAScript, which is fine because I made many mistakes when I first started working with it too. I highly recommend you build your APIs around Promises rather than pure setInterval
or setTimeout
calls. It sounds complicated at first, especially if you're still thinking with a synchronous mindset like I did, but it is so much easier than what you're doing right now. A benefit of using Promises is you can break up your tasks system that you used in the aforementioned examples into multiple functions that each return a Promise, with a master function that returns a status based on a composite response of the Promises. To put that simply, you can easily implement a nuanced API that has error handling functionality and so on while just using regular function-based programming like you are using. It'll be less global state to keep track of, easier to understand and maintain, and more stable.
Finally, there are quite a few behavioral quirks of how Polymer YouTube works that I haven't really written documentation on, but they're worth knowing, especially for a project of your calibre, and I wish to inform you of them. I'll share some code snippets and techniques I've used in my various Polymer modifications I've made which you can also use for certain purposes involving the modification of any Polymer HTML.
Polymer or how YouTube implements it (I'm not sure which) is very odd in that it reuses elements (and in a very weird way too). I am not sure how any of it works or the motivations for implementing this in such a manner. All I can tell you is that once a custom element (ytd
elements) is created, it will not be deleted by YouTube's scripts, but simply moved to outside the DOM. Yes, you can actually do this. I believe that you can use DOMDocument objects in ECMAScript or something similar to create a user-inaccessible element, even through Inspect Element. Though, obviously, I haven't looked into this much to prove that this is something that they do.
You can get the InnerTube API data of most ytd
elements by accessing their data
property. As an example, document.querySelector("ytd-app").data
will give you data for the entire website, including the current page and some miscellaneous information as well. This is provided in a pretty consistent format. For the main watch page contents, the data schema has hardly changed since 2016, which marks our earliest sight of it, so it has pretty much been the same for as long as we know. You can also modify this, to some degree, on certain elements, although that gets pretty complicated quickly.
If you are modifying the data of an element, it can often help to "data cycle" it. This is a term we have adopted in my little community for forcing an element to refresh its data. Here are the two methods that we developed to do this:
// The simple, "classical" method. Simply refreshes the same element:
var dataCopy = elm.data;
elm.data = {};
elm.data = dataCopy;
// The new, advanced method. Creates a new copy element to replace the original:
var newElm = elm.cloneNode();
newElm.data = elm.data;
for (var i in elm.properties)
newElm[i] = elm[i];
elm.insertAdjacentElement("afterend", newElm);
elm.remove();
I use this code snippet a lot to wait for elements that I am certain that are going to exist:
async function waitForElement(elm)
{
while (null == document.querySelector(elm))
{
await new Promise(r => requestAnimationFrame(r);
}
return document.querySelector(elm);
}
Finally, you can look through my profile or ask me further questions wherever about this. I have a good repo where I demonstrate use of a lot of what I described here called yt-anti-shorts. I highly recommend that you look through it no matter what you intend on doing with this project, since I think it is a very high quality project for modifying Polymer reliably.