 Before you start, Jake, you haven't shared your screen, so I actually can see your slides. Ha! Let's maybe just keep rolling, but we'll start again. Wait, you want me to have a natural reaction again? [?]. So how are you alive? Have you noticed that your browser has a back button and a forward button? Yes. Good. Good, and then you have the required knowledge for the upcoming episode. Yep, absolutely, because I have been digging into this sort of stuff recently. And I sort of assumed that the back button and the forward button had, like, their behaviors might be pretty stable and make sense. But I've been around for decades, I guess. Yeah. But I didn't realize how little I know about how they actually work. So I thought I would share with you some of my findings. But to prove how weird it is, I thought I would turn it into a kind of quiz where you, Soma, are the contestants. Oh, no. And if you're playing along at home, you can see if you can beat Soma to any of these. But seriously, like, don't feel bad if you don't know this stuff. I've only recently discovered some of this stuff myself. And a lot of it doesn't make sense. Anyway, let's just jump in. Question one, here you go. The fact that iframes are in here already want to make me eject from this entire quiz. Yeah, they are going to be a big part of this. That's where most of the weirdness happens. So take this, click each link in order, one after the other, and then click the back button. What happens? And feel free to say what you think happens and what you think should happen because these are going to differ. So I click the hashtag hash link, then one, then two. And then the back button goes back to one. And another back button click goes back to hash. And another back button goes back to just slash, whatever it is, I guess. Yeah. Do you know what? You're absolutely correct. And it's a detail that some people miss. It's like, here's how it works. You've got your top-level page with an iframe. I like to visualize it as this kind of timeline. So we'll call this step zero. We navigate that top-level page to a new hash, which doesn't change the document, but it adds a new history entry. And then we navigate the iframe to a new page and again. We navigate the iframe? Yeah. The links weren't in the iframe, were they? Oh, see, do you know what? Here's the cool thing. I was there thinking, God, Sermon's really smart. He's got this bit. I mean, this is just the first question. But still, I feel like you've got it correct by accident. Let's have a look at this code again. I did not see the target, and I did know target was a thing for navigating Ivan. I learned something, Jake. There we go. But you know what? By not knowing something, you got the answer correct. So what have we learned? Ignorance is bliss. That's the moral of this episode. Don't me. But yeah, you click these, it's going to navigate the iframe. The answer of this question really hinges on knowing that it's going to navigate the iframe. And when you click back, it is going to navigate the iframe back. So yeah, it creates these session history entries. But it forms this thing we call, well, I like to give this a timeline. It's actually called the joint session history. But yes, you click the back button. It will actually change what's in the iframe, not just the top level page. So we're at step three here, meaning the top level page is on hash and the iframe is on two. We click back and we go to the previous step, which navigates the iframe, but leaves the top level page where it was. You know what, full disclosure, I'm not sure I would have known that the back button respects navigation within an iframe. I have a hard, I can't go back and pretend I don't know now, but I'm not sure I would have. I was talking to a browser engineer on Friday who didn't know either. It's something that catches people out. All right, next question. Each link is clicked, some of those target iframes, and then the button is clicked. What happens? So I guess the question is that the history value that is exposed by a JavaScript does that encapsulate the overarching history of all embedded iframes and documents and whatnot, or is it specifically the current document? Considering, you know what, I'm going to say history back is supposed to be identical to clicking the back button. So I'm going to say it's going to behave exactly the same. Correct. And you got this one correct, correctly, as well. So full points for that. There is actually a new history API proposal, because there's lots wrong with the history API. There's a new proposal that does target the last entry of the current frame. So there is a proposal where this new back command, which will go all the way back, because it's targeting that top level. Quick question, then. If I called, let's say I click the buttons in reverse order. Like I navigate the iframe first, and then I navigate it to a hash on the top level documents and called history back from within the iframe. Would that navigate the top level page back from hash to no hash? Yes. Yes, it would. Oh, wow. The history API is weird, because it sort of breaks a lot of the cross-origin rules. So even if your iframe was in another origin, it would be affecting the parent page, which is in the origin. Oh, wow. That's interesting. You could have two iframes on your page, each to a different origin, to the parent page. So you've got three origins on the go. And calling history top back in one of those iframes could navigate the other iframe. Yeah, doesn't seem like a good idea. Mate, you know what? We're not even at the really weird questions yet. OK, hit me then. All right, here we go. Each link is clicked, and then back is clicked. OK, so the same happens as before, but then you actually go to a completely different page, which, for all I know, doesn't have any iframes. And so now the question is, if I click back, will the iframes be restored to the state that they were in, or are they going to be restored to what's in the markup? That's the question that I'm asking myself. Now, that is the question. I would say with, oh, does BF Cash play a role here? Does the old page still live in the background with the iframes loaded but frozen in their most recent state? That's a very good catch. Let's assume that for some reason, the BF Cash isn't in play here. So for people watching, we have this concept called the Back Forward Page Cash, where when you navigate to another page, we sometimes just keep the old one alive in memory so you can switch back to it really quickly. That doesn't always happen for a number of reasons. So for this question, we're saying it's not happening. I'm going to say the iframes are loaded with what's in the markup. Mm, interesting, but incorrect. So here's where we're at after clicking those links. And then we leave the page. And like I say, sometimes it keeps the document around, but in this case, it's not going to do that. So the page is gone along with the iframe. That's gone as well. But we go back and the browser knows which top level page to load because it's that one there. But when it does this, it goes, oh, there's an iframe here. And incredibly, the browser goes, I think this is the same iframe from before and it restores the session history and loads too. That is incredible. Then it's not as smart I would have expected from the browser. Every browser does this. It's magic. Like that works across browsers, OK? Yeah. Sometimes the web platform does do a thing. And you know what? This is not in the spec. And this is one of the kind of jobs I have right now is to figure out exactly how this works and spec it. So you can help me with that. So here's a slightly different one. I'm going to click all of these links in order. So one, loads into iframe one. Two, loads into iframe two. And we navigate away and then click back. But plot twist, the page serves the iframes in a different order. So the page that is on has like cache control, no store or something to force the browser actually not going to be HTTP cache. Which means we can serve a different response. Yes, the browser will, by default, go to the memory cache for pages like this. But with no store in play, which we'll assume here, it will go to the server again. I've been recently working on a JavaScript proposal and working on the HTML integration, in which I have learned that something like source position caching is a thing where they cache something, opposing the cache, and the source position is the key. So when you have the same source position, you can access the value. Or source location. And the question is that happening here? Or are they going to, like you said, like in the previous example, it realises this is the same iframe. I'm going to restore that from my cache, where we were in history. If it uses the name, then it will work again. If it uses source position or source location, or something similarly, that wouldn't work. So which is it then? Your analysis of the question is spot on. I'm going to say that either directly or indirectly, this restoration process can only happen if the response was byte identical. And since it isn't, it won't do that. So you're saying it will load the original sources for each high frame? It will load frame start for both, is what I'm going to say. I'm afraid not. And you had a number of correct answers to go for. Unfortunately, you didn't hear any of them. Firefox will reconnect these iframes based on their index in the source, which you suggested. So it will load one in the first iframe and two in the second iframe. Chrome and Safari will use the name attribute to track movements of the iframe around the documents and hook things up. And they will fall back to index if there's no name attribute. And they behave differently if you have a combination of named iframes and indexes. So all the browsers behave slightly differently. But that is roughly what they do. And they both behave differently if the iframes were created with JavaScript. Safari will reconnect them in that case. Chrome won't if they were created with JavaScript. Look, I don't have the time or energy to go fully into it. I'll put some links in the description because it's very, very complicated. Next question. As before, I'm going to click all of the links, loading one into iframe one, loading two into iframe two. And then refresh the page. What happens? If we're assuming no store, I'd say it goes back to frame start. Like, I want to start over. And you are correct. Yeah, that would have been unsettling if that wasn't what's happening. Well, be prepared to be unsettled because it does get weird. So here's where we're at with, you know, we've clicked all of those links. The iframes are on one and two. And then we hit refresh. So here's what happens in Chrome and Safari. Like, the iframes gets this new history entry each, pointing to the original source URLs. But I don't think this makes sense because now if you click back, the first iframe navigates back to one and the second iframe navigates from frame start to frame start, like it effectively reloads the same URL. Yeah, I thought the refresh would create a new entry, not overwrite the current one. But I guess it has never done it in the past. Yeah. I would love to tell you what Firefox does. And I've seen it do stuff a little bit like this. But I have also seen it restore the iframes to one and two. And I haven't figured out why it does one or the other. And weirdly, right now, it feels like it restores the iframes to the one and two URLs if the tab has been opened for a while. I don't want to believe that this is actually the behavior changes based on time. I don't want to believe that. But that's all I've got to go on right now. I will find out. But right now, I just don't know. I don't know, so I will ask some Firefox engineers and hopefully put something in the description. But right now, this is kind of a mystery to me. All right. A bit simpler this time, just a bit simpler. It's not simple. Sorry, I'm lying to you. But there is just one iframe. Click each link. But this time, we're going to go back two steps. So you can long press on the back button and navigate multiple steps at once. There's also the API history.go. And you can pass that minus two to go back two steps. So we're going back two steps at once. What happens? So I guess the difference is that it doesn't actually load the intermediate step. But I would think that this would behave as expected as in the top level page goes back to slash and the frame goes back to frame start. Is that your answer? Are you sticking with that? That is my answer. OK, here's where we're at. We've clicked those links, and we're on step two. So hash in the top page and the iframe is on one. And then we navigate back two items at once, meaning the top level page loses its hash. And that's it. The iframe stays where it is. No, that is wrong, and I do not like it. Every browser, Chrome, Firefox, Safari has a bug where if the parent frame changes its history entry, it won't navigate the child items. It's a bug. It's a bug, but we think it's been around for decades. But now that it's in every browser, do people rely on it and we need to spec it this way? There is some evidence that we try to remove, where we tried to fix this bug in Chrome in 2016 or maybe earlier and we couldn't due to some sites relying it. But other behaviors have changed since then, which might mean we can fix this. We haven't done the research for that bit yet. That is absolutely incredible. It's terrible, isn't it, because it breaks the timeline. Yeah, I'm sorry. I'm just sorry. OK, more sadness. Again, click each link in turn, then click the button. What happens when we click back? Nothing, I think. When we click an order, we navigate to hash first and then put one in the iframe and then two. I think the iframe is just not in the DOM anymore. Maybe the browser has it somewhere in the background and is navigating the iframe off-screen, but I think just nothing happens. OK, so like an empty history entry or something like that? Well, I think there's a history entry. I think the history entry probably has a reference to the iframe. And maybe the iframe still exists in memory and it will get navigated. And if you hold held onto the iframe and put it back in the DOM after, maybe it would then have navigated back successfully. But I don't think it would automatically be put back into the DOM just by clicking the back button. Well, yeah, you're sort of correct. Here's where we're at. I'll be clicking those links and then we remove the iframe. And that means some of our timeline steps don't have history items, history entries against them anymore because the iframe's not there. I'm afraid to say each browser does something differently at this point. We'll start with Firefox. It effectively removes these dead steps as soon as the iframe is removed. So we kind of go back here. So clicking back navigates the top page. Oh, OK. And I think that's great. But that is not what other browsers do. Chrome, it doesn't remove these steps. So if you click back, it seems like nothing happens, which you suggested. So you'd have to click back two more times to change the top page. Safari behaves a little bit similar to Chrome in that it keeps these redundant pages around. But it seems to have a panic at this point, like maybe because it can't find the iframe that it's trying to target. So it sort of panics and reloads the whole page. Yeah, that's one way to go about it, I guess. Yeah, so here I'd say top marks to Firefox. Chrome has a behavior that makes sense, even though I don't think it's the best behavior. And Safari doesn't make sense. There we go. Next question. I click each link, and I press back. What now? Oh, so the difference is that, for once, we don't have a source page, but not like a proper source page. We have about blank as a source page. I guess I would think that this still counts as like a proper navigation. So yeah, we go back, then we would have hash on the top level and about blank in the iframe. That's what I would expect. OK, here's where we are. We've clicked the first link to the hash, and now we're about to navigate the iframe. Firefox and Safari creates a new history entry. So if you click back, it navigates the iframe back to about blank, exactly what you said, basically. That's against the HTML spec. Doing it wrong. Why? Why? About blank is special because it's the initial source for an iframe. If you don't specify a source, it's about blank. And the spec has a special rule that says for the initial iframe navigation from about blank to its destination is a replacement. And Chrome follows the spec here. So that means like about blank that's replaced with the new one. Oh, wow. So if you click back, you'll be navigating the top page, removing the hash. I mean, I understand that about blank is the default if you don't specify a source, but we did specify a source. It just was about blank. Well, here's the deal because Firefox and Safari do follow the spec in some situations. So if you put an iframe on the page with a source to a document, as soon as you put that iframe in the page, it's going to be on about blank because it's not going to be at that source straight away. It has to load. So it's about blank and then the new page loads. And in that case, Firefox and Safari will do a replacement navigation. You will end up like if you put 10 iframes on your page, you don't end up with 10 history entries for about blank before they navigate to where they're going. Right. Yeah. All right. Last question. Here we go. What happens? You grab the iframe. You set the content when you set a property on the content window. You check if it's about blank. And if so, you add the event listener for load. OK, so this is OK. So this will get executed during past time when the page is loading with this markup, which means the iframe hasn't yet loaded. And as you just told me, it has a source attribute, but it hasn't loaded yet. So the location will be about blank. So that if statement will most likely be true and you set something on the content window. However, after load, which means once frame start has loaded, it's a different content window. So will that property still be there? Is there browser magic or not? In my ideal world, I would say no. That would log undefined because it's a new window, but you're probably going to say that's wrong. But I'm going to say, because I'm a purist, it's going to log undefined. That would make sense, wouldn't it? Yes, it would. It's not what happens though. All browsers, in this case, will log world, like it keeps it. And the code inside the iframe on its global, it will have that variable in there, even though it was a different page when you set it. The way it's specced here is that if it's about blank and you navigate it from its initial about blank to a page, it just changes the document. It doesn't change the window. Oh, I should say, only if it's a same origin navigation, only if it's to a same origin URL. Otherwise, it will kick out the window and create a new window object. There are lots of situations where browsers don't do this. If you just add an iframe to the page of JavaScript and then navigate it later, different browsers do different things. This is one of the cases where all browsers will do this super weird, keep the window, but swap the document behavior. And really, there's way more weirdness that I'm encountering just looking at this stuff. And I'll put some links to more of the weird stuff in the description, because there's a lot of it. And I might even encounter more before this episode goes out. It's all made me super sad. And I don't know how I'm going to spec it all, but I'm going to give it a good go. But for now, that's all I've got. How do you feel now, Sermur, after learning some of this stuff? To me, the conclusion is I'm just going to stop using iframes. Or actually, I'm not going to start using iframes now, because without them, everything is so much easier. Deprecate iframes. Good plan. Hoorah! Ha ha ha! I click the link and I press back. What happens? You click both links, because if you say you click a link, there's two links. Which link? Oh, yeah. This code example isn't exactly what I intended. Let's have a look. Oh, no, that's fine. Yeah, no, it's my notes that are wrong. Excellent. Let's try that again.