 I downloaded this. Why is it not downloaded, Jake? What did you do? So we did an episode where we were looking at future JavaScript stuff. We did. People liked that. Yes. So what I thought we'd do is look at new stuff that's already landed. Oh, I thought you were going to say, let's look at old stuff. And we're like, well, that doesn't mean. Well, I think new stuff that's already landed is probably how you would define old stuff really. I feel like I'm doing a bad job of introducing what this actually is. So I'm just going to show you. Here's three. Well, yes. Oh, I was trying to make a joke. Don't ever do that again, mate. Just tell me, what is going on here? This is like the throwback to object or in the programming in JavaScript before we had classes, isn't it? Exactly, yeah. Where you define a function and suddenly you can add properties on the prototype of that function. It sounds really weird, but that's how you did. So what's happening? So you define a function car. I'm not going to talk about what's inside the function for now, but then you can add things on the prototype of this function called car. And I think that prototype is used when you use the function with the new keyword. So if I say new car, then the things that have the prototype in that thing, I can use also in the instance of car. That was a really bad explanation. It was. But also, I always find it confusing. It's what is it called in prototypical inheritance? Yes, something like that. Prototypical, prototypical. But what about, so I'm not. Oh, you're just already doing weird stuff. This is this. So I guess we should explain that you were relatively recent to the web. You ramped up fast. Yeah, I never did. But you will have never done this. I've done it at university, not that specific. I just used car.prototype.first function equals and then the function. But this car inherits from vehicle. And this is how we used to do inheritance. But that's disgusting. Yes, isn't it? Isn't it horrible? Wow. Because I mean, that's where people use frameworks, right? Or like little libraries that would give you that. Exactly. And so because you want car.prototype to be an instance of vehicle, but vehicle has, you need to call the function with stuff. It has options and things. So what you needed to do is create a new constructor, copy the prototype over, or reference the prototype over, create a new one of those. And that meant your car now inherits from vehicle. And then here, this is where you were doing the supercall. My point is we've got classes. This is what we have. Yeah. I mean, so this is what I want to talk about is just there's some of the things that we've got now. Are we taking for granted almost, isn't it? Then we almost take for granted. It reminds the old version, the prototypical inheritance also reminds me of Lua, where you only have tables and you have tables within tables. If you want to inherit this, it gets super weird. It feels very similar. And this is just feels better. Never done Lua. I'll take your word for it. What's happening here? You're defining a function called spin. Correct. Let's take a closer look. So the options, OK. So this is basically sanitization of the options object, which even there is also libraries where you just define in a syntax what the options object should look like. Because otherwise you would have to write this. And this is just like it took me a while to actually understand what you were doing. And now I didn't read every detail because I recognized the pattern because I've written that before. If you don't know the pattern, this would be a lot of reading time spent until you know, oh, you are just checking that certain properties are present. And if they're not, you're setting the default value. Yes. And this got a lot easier with object.assign, which was essentially what the library to. We all had a library doing something like object.assign. And that's what we'd use here. But nowadays, destructuring with the fault values. Yes. So what we see here, we're destructuring. We're giving it the default values and then a default value for the option object there. So it's entirely optional. But I brought this example for a reason. Because I don't like it. Because you don't like it, do you? So I do like destructuring in default ways. I have gotten around to it a little bit. I don't like it in the actual function parameter definition. I prefer this, where you destructure in a separate place. Because otherwise, it gets a little bit nested and it looks a bit crammed. And especially if you have TypeScript, it gets even weirder because the types just go all over the place. When I use TypeScript, I often have a type that's called function name with the word options appended to the end, where I define what structure the options object have. And then I have the first line in my function will then assign the default values. Yeah, and I agree. Yeah, this looks a lot neater. The reason I would still do this is because a static analyzer knows that these are the properties of the option object. In this case, it's not. So this is basic, probably preferable if you don't have TypeScript. Right, so that's that. What's happening here? If you don't know what's happening here, we have to find it. You are making the DOM element with a class, whatever, be 100-pixel tall. Well-saved. So I spend a lot of my time designing in DevTools. I'll throw some rough styles just into the editor. And then I'll go into DevTools. And that's where I'll be shifting values around to make it look. Then at the end, you're copying and pasting. Copying and pasting exactly there. In this case, editing this in DevTools is hard because what I want in this case, I want whatever to be the same width as it is high. Like, I want it to be square, how a human would say that. And it means that if I'm shifting values around in DevTools, I shift one. And then I have to tab twice or whatever and shift the other one. And that's a pain. So here's one of the solutions. That's the proper solution, I'd say. Yeah, and it's been nice now that this is supported in all modern browsers. I've just found this a dream. But what it's worth, size is coming to CSS. Is that right? And it is just nearly as a width plus height. Oh, that's exciting. Yeah, because we have a lot of other things. For example, I think background image size. Certain other size properties exist where you can have one value or two values. And if it's only one value, it's the same for width and height. But we don't have it for the actual size of a dynamic. So size becomes a shortcut for width and height in the same way you can also do size 200 pixels if you want it to be 100 pixels wide. In the same way you do some background size. Exactly. OK, that's good. But in the meantime, this works. This works, yeah. Right. What's happening here? I'm assuming that UL and LI are well-named variables and you're not trying to throw me off. So you have a list that you add a click handler and then you get the event targets from the LI. And if it's not an LI, then you say, well, you bubble up. Oh, OK, so what you're doing is you basically do the event delegation where you have one click handler on the UL itself, like each individual list item. And then you try to figure out on the click event what is the actual list item that you clicked on. So one event listener on the list, but you're using it to detect a click on all the list items. So that means you can move those list items around, add and remove them. You don't have to change the list. But then the problem becomes that if your list item has like an anchor tag that event or target might be the anchor tag within the list item. Well, it might just be the list itself. Or it might be the list itself. Click to list item. So and now what you have to do is you actually have to walk up the tree manually to find what the containing list element is if it exists. Yeah, and I always found this, it's only a little bit of code, but it always felt like a barrier to using event delegation. Whereas now we got closest. We got closest. And it's so good because it doesn't have to be a tag name. I wonder if I did a supercharged episode on this. Oh, wait, I did. Oh, right. Yeah. I did worry that maybe there's going to be a lot of crossover between what I show now and supercharged. I probably should watch the show. This is just because, as far as I know, closest was inspired by jQuery. Well. And I did the jQuery series. Well, there might be some of those coming up as well. Let's carry on. What is happening here? Good luck. All right, wait, all right. So you're replacing just a plus? Because that's the right, with no anything before the plus. So will that match pluses? Yes, it would be a literal plus. Yeah, that's fine. Wow, that is confusing. Because usually the plus means the preceding matcher once or many times repeated. But if there's no preceding matcher, I'm pretty sure that works. Some of these I haven't checked thoroughly. I'm pretty sure that works. I would probably backslash it for clarity anyway, unless it then breaks, because reg-axis. Get over the first line. OK, yeah. We're replacing pluses with spaces. And then we have a result. Oh, you are totally parsing URLs, aren't you? Yes, I am. Well, specifically the query string. The query string, yeah, because your spaces are encoded as pluses. And the individual parameters are separated by ampersands. And then you do the quality split. Then actually in the end, oh, you do the URI component decode. That is a lot of work. It's a lot of work. And it looks, obviously examples. And it's frustrating because the browser can actually enter the encoding, and doing it yourself is super frustrating. Exactly. And it's useful to look at the URL to decide stuff. It could either be the current URL, or it could be the URL of a link. Or it could be some form data that you're trying to send, because it's the same encoding. And having to do this to figure it out there. URL search parents. Yeah. It's just so much nicer that we have that now, and we have that across all modern browsers. I'm still very annoyed that they didn't add a new property onto the location object. So do you know why? So it is on, if you do new URL and pass a URL in, you now have URL.searchparams, which is an instance of this, which is representing the query string. The problem is, the location object is available across windows. Also, if I open a window, I can get access to the. Yeah. And even if that window is in another process, like an iframe, you still have access to the location object. And this has been the whole problem of implementing that, is having this extra object that exists into. Why is it a problem? Well, because we have window proxy, right? And so we would need the equivalent of a search params proxy, because of things like expandos and all of that sort of stuff. It's not referencing exactly the same object. I would be fine if we just defined a getter function that just gives me a new instance. In the same realm or something. Yeah. It's just like every time I do new URL search or new URL and then location.tostring or something and just. Yeah. Exactly. It's a small woo compared to what we had to do before. Agreed. It's work-aroundable, but it would be nice if it was there. But yeah, this getter setters, it does the encoding, the decoding. And it's just there. And it's brilliant. Excellent. So. Oh, file reader. Yeah. Yeah, that was. I'm not sure about file reader. So it was supposed to help you read blobs and files that are given from file pickers and these kind of things. And it's like this super non-promised based API, which are always great. It's like XHR, but for files in a way. Yeah. I feel like it's a support super flaky across browser. Is this actually? No, this is well supported. As you say, it predicts promises. It will take a blob or a file, because file inherits from blob. If you wanted to take that, because blob is you don't get access to the bytes. If you want access to the bytes as like text or an array buffer, this is the mess you would have to deal with. Nowadays. Yes. I said something that you recently taught me, that you just tweet it, I think, and that's where I learned it. Yeah, I never thought about abusing response in that way. I don't think it's actually abuse. Well, it's creating a response when you don't really need to, just because it has these methods on it. Yeah, but it's suddenly promise-based. Much more because actually, you know what's going on, and I think it's a big difference. And that's one of the things when we design the response API, we want it to be very easy to get these other formats out, like text array buffer, those sort of things, and nice promise-based API. Obviously, async functions are a thing we used to have, that I take for granted now in all major browsers. So much easier. Right, this is the last one. Wait, what? If you could at least get a flavor for what's going on here. We are creating a styles object. We're creating a random animation. Generating the animation. I'll go with this wide translation. We add the new styles, then we add that new animation to an object. Wait for. Do you know what? I'll save you time. This is if you're wanting to create a programmatic animation. I see. Because back in the day, you only had CSS. Yes. So if I wanted to animate from something to something else, this is the kind of thing I have to do. I have to create the keyframes. You create an ad hoc keyframe animation, add it as a styles tag. And this is because an animation could end or it could cancel. So I need to listen for both to know when the animation is done and turn that into a promise. And it's, ta-da. Web Animations API. It's finally coming to a point where it becomes usable across browsers. Yeah, and this is themed differently from the other examples because we still don't have this. And it's not one. Well, we have it in Chrome, at least a subset of. We don't have the finished promise. No, we don't. We still don't. That's true. And do you know whose fault that is? That's my mom's? Well, by extension, yes. It's my fault. Because at the time that he designed this, we hadn't decided what to do with cancelable promises at the time. And because finished is a promise that may cancel, I put the brakes on it and said, we can't ship this yet because it might turn out to be incalable. Ladies and gentlemen, please tweet at Jake. I'm sorry. And do you know what's worse? The thing they were doing is what we ended up doing. So if we shipped it, it would have been fine. Well, I used to do a JavaScript library for the BBC and we were having to target things like Safari 1.3. And this is the sort of stuff, all of this stuff I showed you. I was killed for this stuff back then. And it's nice to see that we look at the future cool stuff that might land and it's like, oh, that looks interesting. And it's nice to stop and look at it. Things have got better. We've got nice things in our. Things have got better. I tend to, on stage, I lock my arms in, but not the front that my front. I walk around just like a camp zombie. It's that armpit sweat fear. I think it might be that. Yeah. I have that. So I'm talking. And here's how this is working. T-Rex mode engaged. Yeah. Hiking on my keyboard, driving my car.