WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000 00:00:00.000 --> 00:00:02.994 [MUSIC PLAYING] 00:01:02.490 --> 00:01:03.540 DAVID MALAN: All right. 00:01:03.540 --> 00:01:04.980 This is CS50. 00:01:04.980 --> 00:01:06.960 And this is already Week 8. 00:01:06.960 --> 00:01:11.580 But this is a CS50 bingo board from one of your classmates at Yale, Shoshannah, 00:01:11.580 --> 00:01:12.780 kindly sent this to us. 00:01:12.780 --> 00:01:16.400 And she's apparently been taking close notice of certain expressions 00:01:16.400 --> 00:01:18.150 that I apparently tend to say quite a bit. 00:01:18.150 --> 00:01:20.580 Some of which I'm aware of, but not all of them. 00:01:20.580 --> 00:01:24.480 And the idea here as she described it is that if and when 00:01:24.480 --> 00:01:27.120 I say any of these expressions on the screen, 00:01:27.120 --> 00:01:29.260 you can draw a line through that box. 00:01:29.260 --> 00:01:32.370 And if you get five in a row, you win a fabulous prize. 00:01:32.370 --> 00:01:35.220 It seems only fair, then, if we maybe give away some cookies today 00:01:35.220 --> 00:01:38.790 if and when I actually do say five such things in a row. 00:01:38.790 --> 00:01:43.110 Perhaps it'll be all the more motivation to keep a rapt ear against everything 00:01:43.110 --> 00:01:44.620 we're talking about today. 00:01:44.620 --> 00:01:48.690 So if and when that happens, feel free to just yell out bingo. 00:01:48.690 --> 00:01:52.360 And then please see Carter during the break or after class for adjudication. 00:01:52.360 --> 00:01:52.860 All right. 00:01:52.860 --> 00:01:56.370 So today, ultimately though, Week 8 is about the internet and, in turn, 00:01:56.370 --> 00:01:59.790 how it works and, in fact, how we can start building software on top of it. 00:01:59.790 --> 00:02:03.070 So up until now, of course, we've experimented with Scratch, 00:02:03.070 --> 00:02:05.320 spent quite a bit of time with C, only really 00:02:05.320 --> 00:02:09.130 spent a week plus so far on Python, and about the same on SQL. 00:02:09.130 --> 00:02:11.650 But ultimately, we're going to come full circle next week 00:02:11.650 --> 00:02:13.485 and tie all of those languages together. 00:02:13.485 --> 00:02:15.610 But we're going to do it in the context of the web. 00:02:15.610 --> 00:02:17.610 And in fact to do that, we're going to introduce 00:02:17.610 --> 00:02:20.560 three different languages today, but only one of which 00:02:20.560 --> 00:02:22.390 is a proper programming language. 00:02:22.390 --> 00:02:25.780 The other two are more about presentation, markup languages, 00:02:25.780 --> 00:02:26.470 so to speak. 00:02:26.470 --> 00:02:29.472 And those languages are HTML and CSS, commonly used in conjunction. 00:02:29.472 --> 00:02:32.680 Some of you might have done this middle school, high school even, if you ever 00:02:32.680 --> 00:02:34.750 made a personal website of sorts. 00:02:34.750 --> 00:02:37.000 And JavaScript, a programming language that 00:02:37.000 --> 00:02:39.400 is very commonly used in the context of browsers 00:02:39.400 --> 00:02:43.250 to make interfaces that are all the more interactive. 00:02:43.250 --> 00:02:45.070 But it can also be used server side. 00:02:45.070 --> 00:02:47.260 And what you'll find that is our goal this week, 00:02:47.260 --> 00:02:51.070 like last week, like two weeks ago is really to teach you ultimately 00:02:51.070 --> 00:02:54.070 how to program, how to program procedurally 00:02:54.070 --> 00:02:56.800 and also with elements of what we'll call functional 00:02:56.800 --> 00:02:58.630 programming, object-oriented programming, 00:02:58.630 --> 00:03:02.230 concepts that you'll explore more if you pursue more programming or higher level 00:03:02.230 --> 00:03:02.930 classes. 00:03:02.930 --> 00:03:05.110 But at the end of the day, you will exit this class 00:03:05.110 --> 00:03:08.740 having learned how to program, particularly 00:03:08.740 --> 00:03:12.100 in a context that's very much in vogue nowadays, be it for the web 00:03:12.100 --> 00:03:13.810 or be it for mobile devices. 00:03:13.810 --> 00:03:16.870 And all of the ideas thus far will be applicable as we now 00:03:16.870 --> 00:03:19.100 begin to build on top of the internet. 00:03:19.100 --> 00:03:20.180 So what is it? 00:03:20.180 --> 00:03:23.720 So back in the late '60s and 1970s, it wasn't much of anything. 00:03:23.720 --> 00:03:26.560 This is an early diagram depicting a few access points 00:03:26.560 --> 00:03:29.020 on the West Coast of the United States, which represents 00:03:29.020 --> 00:03:30.490 what was originally called ARPANET. 00:03:30.490 --> 00:03:33.010 And this was a project from the US Department of Defense 00:03:33.010 --> 00:03:36.160 to begin to internetwork computers by enabling 00:03:36.160 --> 00:03:39.460 them to exchange data using what's now known as packets, 00:03:39.460 --> 00:03:41.360 packets of information back and forth. 00:03:41.360 --> 00:03:44.050 It wasn't too long before East Coast was eventually connected 00:03:44.050 --> 00:03:46.480 through MIT, Harvard, and others. 00:03:46.480 --> 00:03:48.400 And nowadays, fast forward to present day, 00:03:48.400 --> 00:03:51.370 just a few decades later, everything, it would seem, 00:03:51.370 --> 00:03:54.970 is somehow interconnected, either with wires or wirelessly. 00:03:54.970 --> 00:03:57.580 But how do you actually get data from any of these points 00:03:57.580 --> 00:04:00.520 to any of these other points or all of the points that now exist? 00:04:00.520 --> 00:04:02.440 Well, let me stipulate, for today's purposes, 00:04:02.440 --> 00:04:04.720 that the world nowadays is filled with routers, 00:04:04.720 --> 00:04:09.160 simply computers, servers whose purpose in life is to route information from 00:04:09.160 --> 00:04:11.260 left to right, top to bottom, geographically, 00:04:11.260 --> 00:04:14.920 so to speak, to just get data from point A to point B. 00:04:14.920 --> 00:04:18.579 But typically, you're not going to have a direct connection between points A 00:04:18.579 --> 00:04:21.320 and B. You might have C, D, E. In other words, 00:04:21.320 --> 00:04:24.613 you might have many different servers between you and someone else. 00:04:24.613 --> 00:04:26.530 So if you have a friend at Stanford University 00:04:26.530 --> 00:04:29.350 and you simply send them an email, well, odds 00:04:29.350 --> 00:04:33.130 are that email is going to be put inside what we're soon going to call a packet. 00:04:33.130 --> 00:04:37.280 And that packet might actually pass through the hands, so to speak, 00:04:37.280 --> 00:04:41.800 of any number of routers, typically more than one or two, 00:04:41.800 --> 00:04:44.980 but typically fewer than 30 such routers. 00:04:44.980 --> 00:04:49.510 And it's up to the IT administrators of the world to figure out how 00:04:49.510 --> 00:04:51.010 to route data between these servers. 00:04:51.010 --> 00:04:54.052 And we have software nowadays that dynamically figures out the best path. 00:04:54.052 --> 00:04:55.960 It's not necessarily a straight line, as it 00:04:55.960 --> 00:04:57.502 might be in the world of mathematics. 00:04:57.502 --> 00:05:01.300 But hopefully, it's the fastest way to get data from point A to point B. 00:05:01.300 --> 00:05:04.300 So the teaching fellows, thanks to Zoom, kindly put together in years 00:05:04.300 --> 00:05:08.080 past a demonstration of this whereby each of the teaching fellows or TAs 00:05:08.080 --> 00:05:11.920 that you see on the screen here consider representing a router, that 00:05:11.920 --> 00:05:14.530 is a device on the internet that its purpose in life 00:05:14.530 --> 00:05:16.120 is to get data, North, South. 00:05:16.120 --> 00:05:18.277 East, or West, between two points ultimately. 00:05:18.277 --> 00:05:20.110 And if we assume that Phyllis, for instance, 00:05:20.110 --> 00:05:24.220 wants to send a packet of information to Brian up here at top left, 00:05:24.220 --> 00:05:29.380 from bottom right, it turns out that by design the internet can send that data 00:05:29.380 --> 00:05:30.992 over any number of routes. 00:05:30.992 --> 00:05:32.200 It can go up and to the left. 00:05:32.200 --> 00:05:33.580 It can go left and then up. 00:05:33.580 --> 00:05:35.080 It can double back a little bit. 00:05:35.080 --> 00:05:37.030 Again, it's not necessarily a straight line. 00:05:37.030 --> 00:05:39.460 And this is a feature, not a bug. 00:05:39.460 --> 00:05:41.650 The intent of the internet early on was to be 00:05:41.650 --> 00:05:44.570 able to route around downed servers. 00:05:44.570 --> 00:05:48.160 So if one router is overwhelmed, or if one router is offline, 00:05:48.160 --> 00:05:52.070 the internet can still adapt dynamically and just route it some other direction. 00:05:52.070 --> 00:05:54.910 So here, for instance, is one representative route 00:05:54.910 --> 00:05:56.950 that our packets might take. 00:05:56.950 --> 00:05:58.120 Thanks to the team. 00:05:58.120 --> 00:06:01.114 [CLASSICAL MUSIC PLAYING] 00:06:26.040 --> 00:06:27.370 So my thanks to the team. 00:06:27.370 --> 00:06:29.520 And if you've ever used Zoom before, you know 00:06:29.520 --> 00:06:33.010 that you don't often see exactly the same layout that someone else sees. 00:06:33.010 --> 00:06:35.220 So it took us forever to actually get that right. 00:06:35.220 --> 00:06:38.440 Because no one actually knew to whom they were necessarily passing it. 00:06:38.440 --> 00:06:41.910 But if all of those TFs and TAs represent routers, well, what is it 00:06:41.910 --> 00:06:42.660 they were handing? 00:06:42.660 --> 00:06:44.550 What is it that Phyllis wanted to send to Brian? 00:06:44.550 --> 00:06:46.300 Well, I've called it generically a packet. 00:06:46.300 --> 00:06:49.050 And a packet is a generic term for some amount of information. 00:06:49.050 --> 00:06:51.660 But it's kind of analogous to an envelope in the real world. 00:06:51.660 --> 00:06:54.510 If you're still in the habit of sending letters or postal mail, 00:06:54.510 --> 00:06:58.090 you typically put your information inside of an envelope such as this. 00:06:58.090 --> 00:07:00.090 And then you hand it off to the mail carrier, 00:07:00.090 --> 00:07:01.590 or you drop it into the mail box. 00:07:01.590 --> 00:07:03.990 And then humans, in the case of the Postal Service, 00:07:03.990 --> 00:07:06.300 actually get it from point A to point B. 00:07:06.300 --> 00:07:09.347 But odds are it goes through different cities, different countries, even. 00:07:09.347 --> 00:07:12.180 So you can think of that as roughly analogous to these things called 00:07:12.180 --> 00:07:12.780 routers. 00:07:12.780 --> 00:07:15.960 But the technical term for what it is the TFs were just doing 00:07:15.960 --> 00:07:20.880 is they were implementing a protocol that we know as TCP/IP. 00:07:20.880 --> 00:07:23.670 And this is actually probably a pair of acronyms 00:07:23.670 --> 00:07:26.560 that you've probably seen, maybe on your Mac, PC, or phone, 00:07:26.560 --> 00:07:29.270 even if you haven't really thought much about it. 00:07:29.270 --> 00:07:31.990 But this is actually a pair of protocols, two protocols 00:07:31.990 --> 00:07:35.020 that the internet generally uses nowadays and has 00:07:35.020 --> 00:07:37.750 for some time to get data from point A to point B. 00:07:37.750 --> 00:07:39.940 And let's consider each of these halves so you 00:07:39.940 --> 00:07:43.960 have a sense of what it is the internet is doing when you do send an email 00:07:43.960 --> 00:07:45.160 or do anything else. 00:07:45.160 --> 00:07:48.430 Well, first, IP stands for internet protocol. 00:07:48.430 --> 00:07:51.850 And you've probably even heard this in popular media, since a lot of humans 00:07:51.850 --> 00:07:54.700 are indeed familiar with this notion of IP. 00:07:54.700 --> 00:07:58.060 And they associate it typically with IP addresses, as you might. 00:07:58.060 --> 00:08:02.110 So I'll stipulate for today that every computer, every internet work 00:08:02.110 --> 00:08:06.250 device in the world has an IP address, an internet protocol 00:08:06.250 --> 00:08:09.340 address similar in spirit to buildings in the physical world. 00:08:09.340 --> 00:08:15.850 Here we are at 45 Quincy Street, Cambridge, Massachusetts, 02138, USA. 00:08:15.850 --> 00:08:20.390 That is a unique string, theoretically, that uniquely identifies this building. 00:08:20.390 --> 00:08:23.800 Similarly, in the world of computers, we use a simpler mechanism, just 00:08:23.800 --> 00:08:28.120 numbers of this format that uniquely represent computers. 00:08:28.120 --> 00:08:29.650 Now that's a bit of a white lie. 00:08:29.650 --> 00:08:32.230 Because there's actually a way to share IP addresses. 00:08:32.230 --> 00:08:35.559 And within your home, often within your dorm, or your apartment, 00:08:35.559 --> 00:08:39.700 you'll actually have what appears to be the same IP address as your roommates 00:08:39.700 --> 00:08:40.520 or family members. 00:08:40.520 --> 00:08:42.520 But for now, let's keep things simple and assume 00:08:42.520 --> 00:08:44.500 that every Mac, PC, and phone in the world 00:08:44.500 --> 00:08:48.730 has a unique IP address that's formatted like this, number dot number 00:08:48.730 --> 00:08:50.230 dot number dot number. 00:08:50.230 --> 00:08:55.365 Each of these number signs represents a value between 0 and 255. 00:08:55.365 --> 00:08:58.240 And even though we haven't played around with this kind of arithmetic 00:08:58.240 --> 00:09:02.800 in some time, if each of these placeholders is 0 through 255, 00:09:02.800 --> 00:09:08.070 how many bits are being used to represent each number? 00:09:08.070 --> 00:09:09.630 Think back to Week 0, Week 1. 00:09:09.630 --> 00:09:11.160 Yeah, so 8, in fact. 00:09:11.160 --> 00:09:13.110 8 bits in total, or 1 byte. 00:09:13.110 --> 00:09:17.520 So IP addresses are generally 4 bytes or 32 bits. 00:09:17.520 --> 00:09:21.630 And the other math we kept doing early on is if you've got 4 bytes or 32 bits, 00:09:21.630 --> 00:09:25.560 that's a maximum of 2 to the 32nd power total number of values. 00:09:25.560 --> 00:09:28.680 How many IP addresses can you have, it would seem, maximally in the world? 00:09:31.300 --> 00:09:31.900 Enough. 00:09:31.900 --> 00:09:34.270 Actually, not enough would be a better answer nowadays. 00:09:34.270 --> 00:09:38.810 But roughly, 4 billion was the rough math that we typically 00:09:38.810 --> 00:09:41.190 did anytime 2 to the 32 was involved. 00:09:41.190 --> 00:09:45.200 But it turns out with all of the humans, and all of the devices, servers, 00:09:45.200 --> 00:09:48.830 clients, PCs, Macs, phones, and everything else, 00:09:48.830 --> 00:09:52.580 internet of things devices nowadays, even 4 billion is not quite enough. 00:09:52.580 --> 00:09:56.300 So the world is gradually in the process of transitioning 00:09:56.300 --> 00:10:01.460 from this format, which is technically IPv4, version 4, to IPv6. 00:10:01.460 --> 00:10:05.690 And in the world of IPv6, we've actually bumped things up from 32 bits 00:10:05.690 --> 00:10:11.930 to 128 bits, which is a crazy number of possible permutations, 2 to the 128. 00:10:11.930 --> 00:10:13.890 So you'll gradually see that over time. 00:10:13.890 --> 00:10:17.780 But those are a lot messier of a format because there's so much larger. 00:10:17.780 --> 00:10:20.570 So we'll use the more commonplace ones IPv4. 00:10:20.570 --> 00:10:24.860 Now just to get into the weeds briefly, this is some ASCII art. 00:10:24.860 --> 00:10:27.320 That is, someone wrote this up decades ago in a text 00:10:27.320 --> 00:10:30.470 file to represent the layout of one of these packets. 00:10:30.470 --> 00:10:34.730 So think of this as, like, the digital representation of this here envelope. 00:10:34.730 --> 00:10:38.250 And even though we won't get into the weeds of what this represents, 00:10:38.250 --> 00:10:41.190 up here you just have some values saying that this is byte 0. 00:10:41.190 --> 00:10:42.300 This is byte 10. 00:10:42.300 --> 00:10:43.140 This is byte 20. 00:10:43.140 --> 00:10:45.930 And this is byte 32, but 0 indexed. 00:10:45.930 --> 00:10:50.100 So that is to say that this is just kind of an artist's rendition of a grid 00:10:50.100 --> 00:10:52.950 of bits, top to bottom, left to right. 00:10:52.950 --> 00:10:57.540 And what's going to be interesting for us today is not most of these fields. 00:10:57.540 --> 00:11:00.360 There's a whole bunch of information that's encapsulated inside 00:11:00.360 --> 00:11:01.560 of any one of these packets. 00:11:01.560 --> 00:11:05.520 But we'll focus initially on these two, source address and destination address. 00:11:05.520 --> 00:11:08.370 Maybe the most important thing IP does is 00:11:08.370 --> 00:11:11.860 it standardizes what you put, so to speak, 00:11:11.860 --> 00:11:13.890 on the outside of these envelopes. 00:11:13.890 --> 00:11:17.070 It says that every computer is going to have a unique address of that form, 00:11:17.070 --> 00:11:19.240 something dot something dot something dot something. 00:11:19.240 --> 00:11:21.600 And so just like in the real world, if I want 00:11:21.600 --> 00:11:23.910 to send this packet from Phyllis to Brian, 00:11:23.910 --> 00:11:26.940 and suppose that Brian's IP address is a number, 00:11:26.940 --> 00:11:31.980 like, very simply 1.2.3.4, what Phyllis would do 00:11:31.980 --> 00:11:34.758 is put that IP address in the middle of this envelope, 00:11:34.758 --> 00:11:37.050 just like you would address a letter in the real world. 00:11:37.050 --> 00:11:41.760 But so that Brian could reply to her, if only to confirm receipt, 00:11:41.760 --> 00:11:44.280 she's also going to put in the top left of this envelope, 00:11:44.280 --> 00:11:47.700 virtually, her own IP address, which for the sake of discussion 00:11:47.700 --> 00:11:50.085 is maybe 5.6.7.8. 00:11:50.085 --> 00:11:51.960 In practice, they won't be as pretty as that. 00:11:51.960 --> 00:11:53.590 But it's the general idea. 00:11:53.590 --> 00:11:58.110 So you have a source address from which it's coming and a destination | 00:11:58.110 --> 00:11:59.610 to which it's going. 00:11:59.610 --> 00:12:01.140 And that's what IP does. 00:12:01.140 --> 00:12:04.440 It sort of standardizes, in addition to a bunch of other numbers and values 00:12:04.440 --> 00:12:06.450 that need to be in this envelope, too. 00:12:06.450 --> 00:12:09.630 It really just mandates that computers on the internet minimally 00:12:09.630 --> 00:12:11.670 provide a source address and a destination 00:12:11.670 --> 00:12:15.900 address so that the envelope can get from point A to point B. 00:12:15.900 --> 00:12:17.250 But that's not quite enough. 00:12:17.250 --> 00:12:21.240 Because it turns out, and if you saw the bloopers from the TFs' Zoom 00:12:21.240 --> 00:12:24.690 session there, you would see that it's very common not only for humans 00:12:24.690 --> 00:12:27.060 to physically drop an envelope like that, 00:12:27.060 --> 00:12:29.460 and frankly, even in the real world, for mail carriers 00:12:29.460 --> 00:12:33.550 to lose mail occasionally, undelivered to recipients. 00:12:33.550 --> 00:12:38.160 And so it turns out that IP alone is not enough to guarantee delivery 00:12:38.160 --> 00:12:41.670 because sometimes the packet just might not get to its destination. 00:12:41.670 --> 00:12:45.930 More technically, that might happen because the router is overwhelmed. 00:12:45.930 --> 00:12:47.400 It only has so much memory. 00:12:47.400 --> 00:12:49.020 It only has so fast a CPU. 00:12:49.020 --> 00:12:51.300 And if it's receiving way too many packets 00:12:51.300 --> 00:12:54.400 because so many people are on the internet at some moment in time, 00:12:54.400 --> 00:12:57.660 well, it might just kind of get overwhelmed and metaphorically 00:12:57.660 --> 00:13:01.140 drop certain packets in the sense that there's just not 00:13:01.140 --> 00:13:04.510 enough room in its memory to keep up with the traffic. 00:13:04.510 --> 00:13:08.230 So the effect for the sender is that the packet just doesn't get through. 00:13:08.230 --> 00:13:12.510 And so there's this other protocol, TCP, that humans typically 00:13:12.510 --> 00:13:15.060 use in conjunction with IP via their Macs, 00:13:15.060 --> 00:13:18.820 PCs, and phones that does a couple of other things for us. 00:13:18.820 --> 00:13:23.010 One, it guarantees delivery, or really "guarantees" delivery. 00:13:23.010 --> 00:13:26.070 And it does that actually by doing this. 00:13:26.070 --> 00:13:30.420 It does that by having Phyllis write on the outside of the envelope not 00:13:30.420 --> 00:13:32.590 just the source address and destination address, 00:13:32.590 --> 00:13:34.600 but also what we'll call a sequence number. 00:13:34.600 --> 00:13:38.112 So, for instance, this would be packet one of two 00:13:38.112 --> 00:13:39.570 that she might be sending to Brian. 00:13:39.570 --> 00:13:42.480 So maybe in, like, the memo field, she could write one of two. 00:13:42.480 --> 00:13:45.360 And then, if she happens to send a second packet to Brian, 00:13:45.360 --> 00:13:49.660 she might write similarly a source address and destination address. 00:13:49.660 --> 00:13:51.450 But she might write two out of two. 00:13:51.450 --> 00:13:54.960 Because now, logically, if Brian only gets one of these, 00:13:54.960 --> 00:13:57.330 that sequence number is enough information for him 00:13:57.330 --> 00:13:59.700 to know wait a minute, I need to ask Phyllis to resend 00:13:59.700 --> 00:14:02.160 number one, or maybe resend number two. 00:14:02.160 --> 00:14:04.620 If both of them don't get through, I mean, honestly, 00:14:04.620 --> 00:14:07.710 that's probably when Phyllis hits reload or resends the email. 00:14:07.710 --> 00:14:12.000 But in general, these sequence numbers help with guaranteeing delivery. 00:14:12.000 --> 00:14:15.990 But if Phyllis and Brian are each representing computers in this story, 00:14:15.990 --> 00:14:17.580 they can be doing different things. 00:14:17.580 --> 00:14:21.420 They can be doing email, chat, video conferencing, direct messaging, 00:14:21.420 --> 00:14:24.540 or any number of services on the internet nowadays. 00:14:24.540 --> 00:14:28.860 So TCP gives us one other feature, namely port numbers. 00:14:28.860 --> 00:14:31.380 Because when Brian receives that envelope, assuming he's 00:14:31.380 --> 00:14:33.750 indeed a computer, how does he know that what's 00:14:33.750 --> 00:14:37.900 inside of that envelope is indeed an email, versus a direct message, 00:14:37.900 --> 00:14:43.060 versus a little bit of video, versus sound, versus any other type of media. 00:14:43.060 --> 00:14:46.540 Ideally, the outside of the envelope would have a bit of a clue for him 00:14:46.540 --> 00:14:49.840 that indicates this is the type of data herein. 00:14:49.840 --> 00:14:52.900 Or more specifically, this is the program, really, 00:14:52.900 --> 00:14:56.710 that should open this envelope, the email program, the video conferencing 00:14:56.710 --> 00:14:58.310 program, or whatever else. 00:14:58.310 --> 00:15:04.060 So what Phyllis would typically do on the outside of this envelope lastly, 00:15:04.060 --> 00:15:08.440 in addition to the source address, destination address, 00:15:08.440 --> 00:15:13.360 and the memo field, the sequence number, she would also write a port number. 00:15:13.360 --> 00:15:17.290 And it turns out two of the most common port numbers in the world of TCP 00:15:17.290 --> 00:15:20.080 are these two, 80, which represents the web. 00:15:20.080 --> 00:15:23.320 That is to say, something called HTTP, more on that today, 00:15:23.320 --> 00:15:27.760 or HTTPS, which most everyone nowadays probably knows means secure, 00:15:27.760 --> 00:15:30.130 so it's some kind of secure version of HTTP. 00:15:30.130 --> 00:15:32.323 And that number happens to be 443. 00:15:32.323 --> 00:15:34.240 There's no mathematical significance of these. 00:15:34.240 --> 00:15:35.532 They're just kind of arbitrary. 00:15:35.532 --> 00:15:38.580 But humans decades ago decided to standardize on these numbers. 00:15:38.580 --> 00:15:42.230 So what it means for Phyllis is that on the outside of her envelope, 00:15:42.230 --> 00:15:46.460 she should generally put a colon after the destination 00:15:46.460 --> 00:15:51.350 address and then the number of the port that she wants to receive this packet. 00:15:51.350 --> 00:15:54.530 So if she's actually not sending an email, but maybe making a web request, 00:15:54.530 --> 00:15:57.510 and Brian is a web server and Phyllis is a web browser, 00:15:57.510 --> 00:15:58.910 she would write colon 80. 00:15:58.910 --> 00:16:04.070 Or if she's using HTTPS securely, we would change that 80 to a 443. 00:16:04.070 --> 00:16:06.750 There's other stuff on the outside of that envelope. 00:16:06.750 --> 00:16:10.610 In fact, just like with IP, there might be fields that look like this. 00:16:10.610 --> 00:16:14.840 But just to give you a sense of this, which is a TCP packet, 00:16:14.840 --> 00:16:18.290 you'll see that indeed sequence numbers are actually really big. 00:16:18.290 --> 00:16:22.160 They use all 32 bits of this part of the picture, which 00:16:22.160 --> 00:16:24.620 is to say that generally computers are sending way 00:16:24.620 --> 00:16:26.240 more than one packet or two. 00:16:26.240 --> 00:16:28.430 They might be sending dozens, hundreds, thousands 00:16:28.430 --> 00:16:31.070 even, depending on the size of the data in question. 00:16:31.070 --> 00:16:33.440 And there's some other features therein, including 00:16:33.440 --> 00:16:36.000 source port and destination port. 00:16:36.000 --> 00:16:39.530 Destination port is the 80 or the 443 that I mentioned earlier. 00:16:39.530 --> 00:16:44.810 But long story short, Phyllis also gets to pick a source port to uniquely 00:16:44.810 --> 00:16:47.180 identify this particular request. 00:16:47.180 --> 00:16:49.320 But more on that another time. 00:16:49.320 --> 00:16:52.490 For now, just know that TCP is the pair of protocols 00:16:52.490 --> 00:16:54.740 that the internet uses to get data from point A 00:16:54.740 --> 00:16:58.700 to point B. IP standardizes how the addresses work. 00:16:58.700 --> 00:17:02.630 And TCP guarantees delivery with those sequence numbers 00:17:02.630 --> 00:17:06.650 and also helps the servers do more than one thing, helps them multiplex, 00:17:06.650 --> 00:17:09.859 so to speak, among email, web, video conferencing 00:17:09.859 --> 00:17:11.760 by using those port numbers. 00:17:11.760 --> 00:17:14.720 So at the end of the day, everything, even now, weeks into the class, 00:17:14.720 --> 00:17:19.369 it all boils down somehow to zeros and ones, or in turn, numbers, 00:17:19.369 --> 00:17:22.200 as we might think of them in this case. 00:17:22.200 --> 00:17:29.020 Questions on any of these building blocks thus far? 00:17:29.020 --> 00:17:31.470 Questions on any of these? 00:17:31.470 --> 00:17:32.050 No? 00:17:32.050 --> 00:17:32.550 All right. 00:17:32.550 --> 00:17:35.717 Well, on the outside of this envelope are just some arbitrary numbers, 1, 2, 00:17:35.717 --> 00:17:37.320 3, 4, 5, 6, 7, 8. 00:17:37.320 --> 00:17:40.080 That's obviously not what you and I are in the habit of typing. 00:17:40.080 --> 00:17:42.750 When we actually visit websites, for instance, you and I 00:17:42.750 --> 00:17:46.230 are generally in the habit of typing harvard.edu, or yale.edu, 00:17:46.230 --> 00:17:49.620 or google.com, or the like, otherwise known as domain names. 00:17:49.620 --> 00:17:53.880 But your Mac, your PC has to, at the end of the day, 00:17:53.880 --> 00:17:58.860 address those virtual envelopes, AKA packets, with actual IP addresses. 00:17:58.860 --> 00:18:02.662 There is no room for words, letters of the English alphabet in those pictures 00:18:02.662 --> 00:18:03.870 that we showed on the screen. 00:18:03.870 --> 00:18:07.060 It's just 32 bits, here 32 bits here. 00:18:07.060 --> 00:18:10.680 So it turns out, on the internet, there's another type of server. 00:18:10.680 --> 00:18:14.370 That, unlike routers, which route information from point A to point B, 00:18:14.370 --> 00:18:17.730 there's another type of server that are all over the place, frankly, 00:18:17.730 --> 00:18:21.480 in your home, on campus, in a company on the internet 00:18:21.480 --> 00:18:26.890 more broadly, known as DNS servers, domain name system servers. 00:18:26.890 --> 00:18:28.230 So what do these things do? 00:18:28.230 --> 00:18:31.300 This is just a type of server on the internet whose purpose in life 00:18:31.300 --> 00:18:36.110 is to answer questions of the form, what is the IP address for this domain name. 00:18:36.110 --> 00:18:38.320 So for instance, if you do pull up your browser 00:18:38.320 --> 00:18:40.540 on your Mac or PC or your phone, you type 00:18:40.540 --> 00:18:45.460 in harvard.edu and hit Enter, what your device is designed to do 00:18:45.460 --> 00:18:51.130 is to ask some local DNS server on campus, on your mobile carrier's 00:18:51.130 --> 00:18:54.670 network, on your apartment or dorm's network, what is the IP 00:18:54.670 --> 00:18:57.340 address of harvard.edu, or yale.edu? 00:18:57.340 --> 00:18:59.620 Whatever you actually typed in, hopefully there 00:18:59.620 --> 00:19:03.003 is a nearby DNS server that will respond with a numeric address of the form 00:19:03.003 --> 00:19:05.170 something dot something dot something dot something. 00:19:05.170 --> 00:19:07.240 And that's the number that your computer, 00:19:07.240 --> 00:19:11.260 your device will actually use on the outside of that virtual envelope. 00:19:11.260 --> 00:19:14.110 So you can think of DNS servers, honestly, 00:19:14.110 --> 00:19:17.500 as fitting the model that we keep coming back to, this notion of a dictionary, 00:19:17.500 --> 00:19:22.570 or a hash table, more specifically, whereby inside of a DNS server 00:19:22.570 --> 00:19:27.410 is essentially a dictionary, a two column spreadsheet or database table, 00:19:27.410 --> 00:19:27.910 if you will. 00:19:27.910 --> 00:19:32.410 And in one column are domain names, harvard.edu, yale.edu, google.com. 00:19:32.410 --> 00:19:34.570 On the right-hand side, right-hand column 00:19:34.570 --> 00:19:36.610 are just the corresponding IP addresses. 00:19:36.610 --> 00:19:37.570 And that's it. 00:19:37.570 --> 00:19:40.780 To be technical, if they're not generally called just domain names, 00:19:40.780 --> 00:19:43.360 technically, it's a fully qualified domain name. 00:19:43.360 --> 00:19:44.590 More on that another time. 00:19:44.590 --> 00:19:47.380 But domain names as we know them, generally have different parts. 00:19:47.380 --> 00:19:51.340 And we'll soon see how to tease them apart beyond the usual. 00:19:51.340 --> 00:19:56.290 Questions though, on what DNS server's purpose in life is 00:19:56.290 --> 00:19:59.960 or how this might work? 00:19:59.960 --> 00:20:00.600 No. 00:20:00.600 --> 00:20:01.100 All right. 00:20:01.100 --> 00:20:03.860 So how does your Mac, how does your PC, how does your phone 00:20:03.860 --> 00:20:05.810 know what these IP addresses are? 00:20:05.810 --> 00:20:08.140 Well, they don't come from the manufacturer this way. 00:20:08.140 --> 00:20:10.640 And there's this whole hierarchy in the world of DNS servers 00:20:10.640 --> 00:20:13.760 such that your phone, your Mac, your PC, will generally 00:20:13.760 --> 00:20:18.170 ask the nearest DNS server, which is usually owned by your internet service 00:20:18.170 --> 00:20:22.230 provider at home, in your apartment, or by your university or by your company. 00:20:22.230 --> 00:20:23.690 But it's a hierarchical system. 00:20:23.690 --> 00:20:25.550 And it's kind of a recursive design. 00:20:25.550 --> 00:20:28.910 In that if that local DNS server does not have the answer, 00:20:28.910 --> 00:20:31.640 it's going to ask someone bigger, more important than it. 00:20:31.640 --> 00:20:34.910 If that one doesn't know, it might ask someone, again, recursively for it. 00:20:34.910 --> 00:20:37.130 And throughout the world, there's a finite number 00:20:37.130 --> 00:20:41.270 of what are called root servers that essentially know about all the dot 00:20:41.270 --> 00:20:44.390 coms in the world, all of the dot edus in the world, all 00:20:44.390 --> 00:20:46.440 of the dot whatever is in the world. 00:20:46.440 --> 00:20:49.460 And so someone, at the end of the day, knows about those systems. 00:20:49.460 --> 00:20:53.900 And in fact, if you've ever bought, or in the future might buy a domain name, 00:20:53.900 --> 00:20:58.760 part of that process is paying someone to associate an IP address for you 00:20:58.760 --> 00:21:01.670 with the actual server that you're going to actually be using. 00:21:01.670 --> 00:21:04.920 So your final projects, for instance, in CS50, it's sometimes common for folks 00:21:04.920 --> 00:21:07.170 to actually buy for personal use their own domain name 00:21:07.170 --> 00:21:08.670 for a few dollars a year, typically. 00:21:08.670 --> 00:21:11.003 So you're sort of renting it more than you're buying it. 00:21:11.003 --> 00:21:13.080 But among the steps you'll go through if you ever 00:21:13.080 --> 00:21:17.970 do that is to essentially inform the world what will be the IP address or IP 00:21:17.970 --> 00:21:20.790 addresses of your particular domain name that you've 00:21:20.790 --> 00:21:23.740 bought for, say, that calendar year. 00:21:23.740 --> 00:21:24.240 All right. 00:21:24.240 --> 00:21:26.100 So how does all this get started? 00:21:26.100 --> 00:21:30.225 Well, back in the day, when you arrived on campus here at Yale, anyone, 00:21:30.225 --> 00:21:33.420 or in the world, you would actually configure your Mac or PC 00:21:33.420 --> 00:21:38.625 to know the IP addresses of your nearest router, of your nearest DNS server. 00:21:38.625 --> 00:21:40.500 So literally, someone would come to your home 00:21:40.500 --> 00:21:42.667 back in the day when signing up for internet service 00:21:42.667 --> 00:21:45.180 and configure your Mac or PC for you. 00:21:45.180 --> 00:21:48.900 Of course, nowadays I don't remember anyone really touching my computer 00:21:48.900 --> 00:21:50.460 recently to configure it for me. 00:21:50.460 --> 00:21:52.315 It all seems to happen automatically. 00:21:52.315 --> 00:21:54.940 And indeed, there's this other type of server now in the world, 00:21:54.940 --> 00:21:59.640 another solution to a human made problem known as DHCP. 00:21:59.640 --> 00:22:04.680 And I think this is among the remaining acronyms for today, dynamic host 00:22:04.680 --> 00:22:05.757 configuration protocol. 00:22:05.757 --> 00:22:08.340 And it's not that intellectually interesting to memorize that. 00:22:08.340 --> 00:22:11.610 But what DHCP servers do is answer questions 00:22:11.610 --> 00:22:17.430 of the form "what should be my DNS server and router," quote, unquote. 00:22:17.430 --> 00:22:20.730 So nowadays, when you turn on your phone in the morning, 00:22:20.730 --> 00:22:23.640 if you actually powered it off, if you open 00:22:23.640 --> 00:22:27.690 your laptop lid for the first day of classes or the like, your Mac, your PC, 00:22:27.690 --> 00:22:30.810 your phone is essentially broadcasting a Hello, World message, 00:22:30.810 --> 00:22:34.860 unbeknownst to you, that's just asking the local network, hey, 00:22:34.860 --> 00:22:39.060 what IP address should I use for my DNS server and for my router. 00:22:39.060 --> 00:22:42.540 And hopefully, Harvard or Yale or your apartment or your home more 00:22:42.540 --> 00:22:46.380 generally has a DHCP server nearby whose purpose in life 00:22:46.380 --> 00:22:49.170 is just to hand out answers to that question. 00:22:49.170 --> 00:22:51.750 And what these DHCP servers also do is they 00:22:51.750 --> 00:22:54.510 tell your Mac, your PC, your phone, what IP 00:22:54.510 --> 00:22:57.720 address your device should use because that too 00:22:57.720 --> 00:23:00.490 is no longer manually configured. 00:23:00.490 --> 00:23:03.010 So this all just nowadays happens automatically. 00:23:03.010 --> 00:23:05.190 And in the case of a campus like this or at Yale, 00:23:05.190 --> 00:23:09.210 it's because, at the very beginning of your visit to campus, 00:23:09.210 --> 00:23:10.800 you did register somehow. 00:23:10.800 --> 00:23:12.000 You probably logged in. 00:23:12.000 --> 00:23:15.840 You authenticated against your Harvard account or your Yale account. 00:23:15.840 --> 00:23:19.800 And that is what enabled the DHCP servers henceforth 00:23:19.800 --> 00:23:23.100 and forever to recognize your particular computer 00:23:23.100 --> 00:23:25.920 and answer those questions for you. 00:23:25.920 --> 00:23:26.550 All right. 00:23:26.550 --> 00:23:29.490 So that's it for how the internet works, at least so 00:23:29.490 --> 00:23:31.080 far as we are concerned today. 00:23:31.080 --> 00:23:33.090 We're going to now start building on top of it. 00:23:33.090 --> 00:23:35.970 And undoubtedly, the most popular form of the internet 00:23:35.970 --> 00:23:38.010 nowadays is something called HTTP. 00:23:38.010 --> 00:23:42.180 That is the World Wide Web, though most people don't really say it in long form 00:23:42.180 --> 00:23:42.810 anymore. 00:23:42.810 --> 00:23:49.020 But HTTP is just another protocol that governs how web browsers 00:23:49.020 --> 00:23:51.960 and how web servers speak, just like IP is 00:23:51.960 --> 00:23:55.320 a protocol that governs how computers address each other on the internet, 00:23:55.320 --> 00:23:59.730 and how TCP governs how computers keep track of sequences of packets 00:23:59.730 --> 00:24:03.360 from point A to point B and also multiplex among different services 00:24:03.360 --> 00:24:04.920 using those port numbers. 00:24:04.920 --> 00:24:09.333 And to be clear, what's a protocol-- well, in the human world, 00:24:09.333 --> 00:24:10.500 it's a very common protocol. 00:24:10.500 --> 00:24:11.830 And I can't reach any of you. 00:24:11.830 --> 00:24:14.205 But if I were to reach over and say hi, nice to meet you. 00:24:14.205 --> 00:24:17.240 You presumably, if we weren't five feet apart, would extend your hand. 00:24:17.240 --> 00:24:19.990 We would sort of acknowledge, in this strange cultural convention. 00:24:19.990 --> 00:24:21.000 But that's a protocol. 00:24:21.000 --> 00:24:21.870 I know how to do it. 00:24:21.870 --> 00:24:22.930 You know how to do it. 00:24:22.930 --> 00:24:23.700 I'm initiating. 00:24:23.700 --> 00:24:24.450 You're responding. 00:24:24.450 --> 00:24:27.158 And that's exactly what's happening all the time on the internet. 00:24:27.158 --> 00:24:30.250 You have a client, like me in this case, that's initiating a request. 00:24:30.250 --> 00:24:32.250 You have a server, like you in this case, that's 00:24:32.250 --> 00:24:33.720 responding to that request. 00:24:33.720 --> 00:24:37.080 Or analogously, if you're in a restaurant, 00:24:37.080 --> 00:24:39.242 you might be the client sitting down at the table. 00:24:39.242 --> 00:24:40.200 You want to order food. 00:24:40.200 --> 00:24:44.220 And there's a server that serves you that food after you have requested it. 00:24:44.220 --> 00:24:48.310 So computers, really, on the internet are implementing that same paradigm. 00:24:48.310 --> 00:24:52.462 So when it comes very specifically to the web, which is different, of course, 00:24:52.462 --> 00:24:54.170 from email and video conferencing and all 00:24:54.170 --> 00:24:57.690 of these other services on the internet, the world wide web 00:24:57.690 --> 00:25:01.230 uses this protocol, HTTP, which standardizes 00:25:01.230 --> 00:25:04.710 what goes inside of those envelopes in order 00:25:04.710 --> 00:25:09.790 to allow a web browser to request and receive information from a web server. 00:25:09.790 --> 00:25:12.990 So we've talked about really the lower level details up until now, 00:25:12.990 --> 00:25:14.350 the outside of the envelope. 00:25:14.350 --> 00:25:18.210 Let's now look inside of the envelope when it comes to actual web pages 00:25:18.210 --> 00:25:22.350 that you might visit or soon today, you yourselves might design. 00:25:22.350 --> 00:25:27.660 So HTTP stands for Hypertext Transfer Protocol, which is another mouthful, 00:25:27.660 --> 00:25:31.080 but, again, just standardizes how we're going to get web traffic from point A 00:25:31.080 --> 00:25:33.990 to point B, from browser to server and back. 00:25:33.990 --> 00:25:38.110 HTTPS is literally the secure version of that. 00:25:38.110 --> 00:25:41.550 And what that means for today's purposes is that the connection is somehow 00:25:41.550 --> 00:25:44.490 encrypted, scrambled using very fancy mathematics 00:25:44.490 --> 00:25:48.360 so that it is very, very, very unlikely that anyone 00:25:48.360 --> 00:25:52.230 who intercepts your traffic, your packets between point A and point B 00:25:52.230 --> 00:25:55.110 will have any idea what is inside of those envelopes. 00:25:55.110 --> 00:25:57.540 They might intercept the packet itself digitally. 00:25:57.540 --> 00:25:59.230 They might try to open it up. 00:25:59.230 --> 00:26:02.500 But it's going to look metaphorically like random zeros 00:26:02.500 --> 00:26:08.110 and ones on the inside when using HTTPS because of what's called encryption. 00:26:08.110 --> 00:26:10.738 But let's look at some canonical URLs. 00:26:10.738 --> 00:26:13.780 All of us are in the habit of seeing these and typing these all the time. 00:26:13.780 --> 00:26:16.280 Well, let's actually tease apart some of the jargon here. 00:26:16.280 --> 00:26:20.450 So here is an example URL with all of the usual components. 00:26:20.450 --> 00:26:23.680 So here, for instance, with the yellow slash, 00:26:23.680 --> 00:26:26.860 this generally means, even though you rarely type it 00:26:26.860 --> 00:26:34.000 and you rarely see it nowadays, this means the default page for the website. 00:26:34.000 --> 00:26:37.070 Give me the root of the website, so to speak. 00:26:37.070 --> 00:26:39.400 So this is to say this represents a folder, 00:26:39.400 --> 00:26:43.310 like, the default folder inside of which is presumably the default web page. 00:26:43.310 --> 00:26:45.880 And we'll see what that means more concretely in just a bit. 00:26:45.880 --> 00:26:48.970 If, though, you're visiting a more specific URL, 00:26:48.970 --> 00:26:51.160 we're going to henceforth call this a path. 00:26:51.160 --> 00:26:55.720 So slash something is representative of a path, maybe a file, maybe a folder, 00:26:55.720 --> 00:26:58.960 just like in the world of Macs, PCs, and cloud services. 00:26:58.960 --> 00:27:02.410 Specifically, you might sometimes be in the habit of visiting an actual file, 00:27:02.410 --> 00:27:05.230 something like /file.html. 00:27:05.230 --> 00:27:08.050 Nowadays, this is kind of very '90s, early 2000s. 00:27:08.050 --> 00:27:11.330 Nowadays most web servers hide the file extension, 00:27:11.330 --> 00:27:14.330 the dot HTML, even if it's there on the server. 00:27:14.330 --> 00:27:16.270 It just looks a little messy nowadays. 00:27:16.270 --> 00:27:18.460 It sort of reveals information that's not necessary. 00:27:18.460 --> 00:27:22.960 So very often you won't see dot HTML, even if there is actually 00:27:22.960 --> 00:27:25.150 a file ending in that suffix. 00:27:25.150 --> 00:27:27.700 You might instead see /folder, with a slash. 00:27:27.700 --> 00:27:30.130 Maybe not a slash, maybe a slash, but that generally 00:27:30.130 --> 00:27:32.020 represents a folder on the server. 00:27:32.020 --> 00:27:34.480 And sometimes there are, of course, files in folders. 00:27:34.480 --> 00:27:38.560 So all of this stuff you're probably familiar with on Macs and PCs and even 00:27:38.560 --> 00:27:39.790 Google Drive and the like. 00:27:39.790 --> 00:27:43.000 Those same semantics exist in the context of URLs. 00:27:43.000 --> 00:27:48.040 So there's a mapping between this URL and something on a hard drive somewhere 00:27:48.040 --> 00:27:49.160 on some server. 00:27:49.160 --> 00:27:49.660 All right. 00:27:49.660 --> 00:27:51.110 What about the other parts? 00:27:51.110 --> 00:27:55.952 So this is the fully qualified domain name, so the full domain name. 00:27:55.952 --> 00:27:57.910 Even though you and I, when we say domain name, 00:27:57.910 --> 00:28:01.250 we typically just mean this example.com, for instance. 00:28:01.250 --> 00:28:06.460 So technically, the W-W-W is what we would typically call a host name. 00:28:06.460 --> 00:28:11.020 A host name is like the name of a specific server that lives somewhere 00:28:11.020 --> 00:28:12.130 in that domain. 00:28:12.130 --> 00:28:13.810 And this is just a human convention. 00:28:13.810 --> 00:28:19.450 Even though most URLs still probably start with W-W-W dot something, 00:28:19.450 --> 00:28:21.070 that's not strictly required. 00:28:21.070 --> 00:28:22.930 That's just a configuration detail. 00:28:22.930 --> 00:28:26.290 And historically, this was just to kind of signal 00:28:26.290 --> 00:28:29.620 to less technical people in particular, when you would see a URL in print, 00:28:29.620 --> 00:28:31.600 that oh, this is a web address. 00:28:31.600 --> 00:28:34.180 This is an address on that new world wide web. 00:28:34.180 --> 00:28:36.430 W-W-W just kind of connotes that. 00:28:36.430 --> 00:28:39.400 But decreasingly, do you see websites using this? 00:28:39.400 --> 00:28:42.370 I mean, some of CS50's own tools, it's just cs50.dev. 00:28:42.370 --> 00:28:44.020 It's just CS50.ai. 00:28:44.020 --> 00:28:46.780 Because most of us are now conditioned to know that, 00:28:46.780 --> 00:28:51.190 oh, OK, that's probably a URL, even though there's no explicit W-W-W. 00:28:51.190 --> 00:28:56.020 And in fact, even if you type the W-W-W using tricks that we'll soon see, 00:28:56.020 --> 00:28:58.480 you can redirect the user from one to another. 00:28:58.480 --> 00:29:01.870 Essentially, remove the W-W-W or add it to the server, 00:29:01.870 --> 00:29:04.450 to the address bar in their browser. 00:29:04.450 --> 00:29:07.180 This thing here is called the top level domain. 00:29:07.180 --> 00:29:09.800 And many of the domain names that you and I are in the habit, 00:29:09.800 --> 00:29:14.500 certainly in the US nowadays, end in .com, which stands for commercial, 00:29:14.500 --> 00:29:18.040 .edu stands for educational, .gov stands for US government. 00:29:18.040 --> 00:29:21.340 But of course, there's hundreds of country codes, too, that by convention 00:29:21.340 --> 00:29:22.180 are two letters. 00:29:22.180 --> 00:29:25.690 So .uk for the United Kingdom, .jp for Japan, 00:29:25.690 --> 00:29:29.030 and two characters for every other country in the world. 00:29:29.030 --> 00:29:32.540 But even those have kind of been used in clever ways. 00:29:32.540 --> 00:29:38.020 So .tv, for instance, is actually a country code that's been used by a lot 00:29:38.020 --> 00:29:40.870 of the English-speaking world to represent television, 00:29:40.870 --> 00:29:42.730 for TV shows and the like. 00:29:42.730 --> 00:29:46.310 .ai, similarly, does not actually mean artificial intelligence. 00:29:46.310 --> 00:29:50.410 It's a two character country code that has been used by the world nowadays 00:29:50.410 --> 00:29:51.910 to represent AI. 00:29:51.910 --> 00:29:58.880 .ly for bitly and CS50.ly, too, that's a country code that allows people like us 00:29:58.880 --> 00:30:02.120 to essentially buy domain names in that subdomain. 00:30:02.120 --> 00:30:04.430 But long story short, back in the day there only 00:30:04.430 --> 00:30:06.630 used to be a few of these top level domains. 00:30:06.630 --> 00:30:08.490 Now there are hundreds of them. 00:30:08.490 --> 00:30:12.290 So I do think, over time, it's going to become 00:30:12.290 --> 00:30:17.390 a lot less regimented as it seems to be now as to what URLs actually look like. 00:30:17.390 --> 00:30:23.840 Lastly, beyond the :// here is the scheme, or the protocol. 00:30:23.840 --> 00:30:25.940 And this just means that this URL is going 00:30:25.940 --> 00:30:32.690 to be securely accessing the server thanks to the HTTPS instead of HTTP. 00:30:32.690 --> 00:30:33.320 Mouthful. 00:30:33.320 --> 00:30:35.570 But just to get some vocabulary out there. 00:30:35.570 --> 00:30:38.780 Questions on these here URLs that we've probably 00:30:38.780 --> 00:30:40.430 been taking for granted for years? 00:30:40.430 --> 00:30:42.810 AUDIENCE: Who approves .edu? 00:30:42.810 --> 00:30:45.030 DAVID MALAN: Really good question, who approves .edu. 00:30:45.030 --> 00:30:49.172 So you have to be in an accredited educational institution to use .edu. 00:30:49.172 --> 00:30:51.630 I don't recall the name of the organization that does this. 00:30:51.630 --> 00:30:53.255 But it can't be anyone on the internet. 00:30:53.255 --> 00:30:55.920 You actually have to apply and be a seemingly legitimate 00:30:55.920 --> 00:30:57.450 educational institution. 00:30:57.450 --> 00:30:59.910 That is not true of a lot of domain names. 00:30:59.910 --> 00:31:01.350 Anyone can buy a .com. 00:31:01.350 --> 00:31:05.593 Anyone can buy .org, a .net, not a .gov, for instance. 00:31:05.593 --> 00:31:08.010 And then different countries might have their own policies 00:31:08.010 --> 00:31:12.280 over who can be in what domain or subdomain as well. 00:31:12.280 --> 00:31:12.780 All right. 00:31:12.780 --> 00:31:16.530 So now that we have URLs so defined, there's 00:31:16.530 --> 00:31:19.680 a couple of verbs with which to be familiar in the context of the web, 00:31:19.680 --> 00:31:21.180 namely GET and POST. 00:31:21.180 --> 00:31:23.400 And that is to say, there's two different ways 00:31:23.400 --> 00:31:25.530 to request information from a server. 00:31:25.530 --> 00:31:28.140 That is, there's two different ways to format requests 00:31:28.140 --> 00:31:29.700 that go inside of this envelope. 00:31:29.700 --> 00:31:33.990 And the default, daresay, and the most common one is just what's called GET, 00:31:33.990 --> 00:31:36.390 literally the verb, the English verb get. 00:31:36.390 --> 00:31:40.113 And we'll see in a moment what this means exactly concretely. 00:31:40.113 --> 00:31:42.280 But just know that there's an alternative that we'll 00:31:42.280 --> 00:31:44.650 play with over time known as POST. 00:31:44.650 --> 00:31:49.660 And whereas GET, as the verb suggests, is all about just getting information, 00:31:49.660 --> 00:31:53.740 POST, as the verb kind of suggests, is more about sending information. 00:31:53.740 --> 00:31:56.620 So POST is used when you submit a credit card. 00:31:56.620 --> 00:31:59.380 Because you're sort of sending potentially sensitive information. 00:31:59.380 --> 00:32:03.190 POST is used when you upload an image to a website or the like, 00:32:03.190 --> 00:32:05.830 but GET is used when you're just clicking on links 00:32:05.830 --> 00:32:09.950 and visiting web pages and not really pushing any information to the server. 00:32:09.950 --> 00:32:13.540 So for today, we'll focus primarily on GET. 00:32:13.540 --> 00:32:16.150 So what does this mean? 00:32:16.150 --> 00:32:19.930 Inside of this envelope, probably unbeknownst to you up until now, 00:32:19.930 --> 00:32:22.330 is our messages that look like this. 00:32:22.330 --> 00:32:26.920 These are HTTP messages that are being put automatically 00:32:26.920 --> 00:32:30.940 in these virtual envelopes for you by your Mac, your PC, for your phone. 00:32:30.940 --> 00:32:38.440 So for instance, if you were to visit HTTPS://www.harvard.edu, 00:32:38.440 --> 00:32:39.880 you would hit Enter. 00:32:39.880 --> 00:32:41.830 What your Mac, PC, or phone is going to do 00:32:41.830 --> 00:32:44.260 is put a textual message that looks literally 00:32:44.260 --> 00:32:48.190 like this inside of a virtual envelope, address it on the outside 00:32:48.190 --> 00:32:51.760 to the appropriate IP address for harvard.edu using your own IP 00:32:51.760 --> 00:32:55.060 address as the source address, and then hand it off to some nearest router. 00:32:55.060 --> 00:32:58.750 But inside of this envelope is enough information to the server 00:32:58.750 --> 00:33:00.440 to know what it is you want. 00:33:00.440 --> 00:33:02.292 So for instance, GET is the verb. 00:33:02.292 --> 00:33:04.000 So you just want to get some information. 00:33:04.000 --> 00:33:05.920 The information you want to get is /, which 00:33:05.920 --> 00:33:09.730 I defined earlier as just the default page on the website. 00:33:09.730 --> 00:33:13.810 HTTP/2 just means what version of HTTP we're talking about. 00:33:13.810 --> 00:33:17.110 You'll see nowadays in the wild, 1.1, you'll see 2, 00:33:17.110 --> 00:33:19.180 you'll start to see version 3 over time. 00:33:19.180 --> 00:33:21.220 But I'll use 2 for all of my examples here. 00:33:21.220 --> 00:33:23.440 And you'll see inside of this envelope, too, 00:33:23.440 --> 00:33:27.910 what we're going to start calling an HTTP header, a single line of text that 00:33:27.910 --> 00:33:32.770 literally tells the server what fully qualified domain name it's looking for. 00:33:32.770 --> 00:33:37.910 And this is important only insofar as nowadays, generally on a server, 00:33:37.910 --> 00:33:40.300 you might have multiple websites being hosted. 00:33:40.300 --> 00:33:44.050 This is not going to be true probably of Google or of Microsoft 00:33:44.050 --> 00:33:46.352 or Meta or massive companies like that. 00:33:46.352 --> 00:33:49.060 But it's definitely going to be true of smaller enterprises, even 00:33:49.060 --> 00:33:52.180 places like Harvard that don't need thousands of web servers, 00:33:52.180 --> 00:33:54.770 but maybe just a couple, or maybe just a few. 00:33:54.770 --> 00:33:58.780 So in this case, this ensures that when the server receives this packet, 00:33:58.780 --> 00:34:02.350 it knows to serve up harvard.edu and not yale.edu 00:34:02.350 --> 00:34:04.990 or some other website that, by coincidence, might just be 00:34:04.990 --> 00:34:08.409 hosted on the same server because both Harvard and Yale are maybe 00:34:08.409 --> 00:34:11.900 paying the same cloud provider to host their websites. 00:34:11.900 --> 00:34:14.980 So dot dot dot just means there's other HTTP headers. 00:34:14.980 --> 00:34:18.830 But notice the colon here is just giving us yet another one of those key value 00:34:18.830 --> 00:34:19.330 pairs. 00:34:19.330 --> 00:34:20.230 The key is HOST. 00:34:20.230 --> 00:34:22.600 The value is www.harvard.edu. 00:34:22.600 --> 00:34:25.389 There, again, are those dictionaries that I 00:34:25.389 --> 00:34:28.330 claimed we would continue to see all over the place. 00:34:28.330 --> 00:34:30.820 What then comes back from the server? 00:34:30.820 --> 00:34:34.449 If this is what's inside the message from browser to server, 00:34:34.449 --> 00:34:36.070 what does the server send back? 00:34:36.070 --> 00:34:38.170 Ideally, the server sends back a message that 00:34:38.170 --> 00:34:41.560 looks like this, an acknowledgment of what version is being used, 00:34:41.560 --> 00:34:45.699 a status code, which is going to be an arcane looking number, like 200. 00:34:45.699 --> 00:34:48.429 It's going to then have another HTTP header of its own saying 00:34:48.429 --> 00:34:51.730 what type of content is in this envelope, ideally, 00:34:51.730 --> 00:34:53.469 something called text/html. 00:34:53.469 --> 00:34:56.350 That is hypertext markup language, which we're about to see. 00:34:56.350 --> 00:34:57.820 And then some other stuff. 00:34:57.820 --> 00:35:00.790 That's what's coming back from the server to the browser. 00:35:00.790 --> 00:35:02.680 And we can actually now see this. 00:35:02.680 --> 00:35:05.240 Let me actually go over to VS Code here. 00:35:05.240 --> 00:35:08.620 Let me maximize my terminal window just so we can see more at once. 00:35:08.620 --> 00:35:11.200 And let me go ahead and type in this command, 00:35:11.200 --> 00:35:21.520 curl -I https://www.harvard.edu/, so a complete URL that's secure, 00:35:21.520 --> 00:35:24.340 that's got the host name of W-W-W. 00:35:24.340 --> 00:35:27.040 And curl just means connect to a URL. 00:35:27.040 --> 00:35:30.960 It's a command line program that comes with Linux, comes with Mac OS, Windows. 00:35:30.960 --> 00:35:32.710 You might have to install it individually. 00:35:32.710 --> 00:35:35.180 And it just lets me simulate being a browser,. 00:35:35.180 --> 00:35:37.900 It's going to let me simulate sending a packet like this 00:35:37.900 --> 00:35:40.460 without caring what the website actually looks like, 00:35:40.460 --> 00:35:45.410 so no pictures, no images, no text, no nothing, just what's inside 00:35:45.410 --> 00:35:47.900 of the envelope in terms of the server's response. 00:35:47.900 --> 00:35:52.070 And here's mostly dot dot dot, the ellipses I raised my hand at earlier? 00:35:52.070 --> 00:35:54.210 There's a lot of these key value pairs. 00:35:54.210 --> 00:35:57.770 But if I scroll up to the top, you'll see that 200 00:35:57.770 --> 00:35:59.450 is the status code that came back. 00:35:59.450 --> 00:36:04.790 And you'll see that the content type is indeed text/html. 00:36:04.790 --> 00:36:07.340 And there's a whole lot of other stuff here, clearly. 00:36:07.340 --> 00:36:08.900 A lot of this is diagnostic. 00:36:08.900 --> 00:36:10.820 It reveals information about the server that 00:36:10.820 --> 00:36:13.520 might be useful generally to more technical people than me 00:36:13.520 --> 00:36:17.270 at this point in the conversation, or maybe my Mac or my PC or my phone. 00:36:17.270 --> 00:36:19.820 For now, we can focus really on just the essence 00:36:19.820 --> 00:36:22.400 of this response, which is this here. 00:36:22.400 --> 00:36:25.040 But here's where even these arcane numbers might start 00:36:25.040 --> 00:36:28.310 to get a little more familiar, in fact. 00:36:28.310 --> 00:36:31.658 Suppose that I want to see this in my browser. 00:36:31.658 --> 00:36:32.700 Actually, let me do this. 00:36:32.700 --> 00:36:35.430 Let me go back to VS Code here. 00:36:35.430 --> 00:36:37.820 Let me open up incognito mode here, which 00:36:37.820 --> 00:36:40.250 generally is to give you private browsing, so to speak. 00:36:40.250 --> 00:36:41.958 And we'll talk more about this next week. 00:36:41.958 --> 00:36:47.070 In incognito mode or private mode, you have no history, you have no cookies, 00:36:47.070 --> 00:36:49.682 you have no sessions, terms we'll define next week. 00:36:49.682 --> 00:36:51.390 I'm going to use it again and again today 00:36:51.390 --> 00:36:53.182 to make sure that my browser is essentially 00:36:53.182 --> 00:36:57.510 starting from scratch, freshly, so that I don't have anything in my history 00:36:57.510 --> 00:36:58.652 from previous examples. 00:36:58.652 --> 00:37:00.360 And what I'm going to do, actually, first 00:37:00.360 --> 00:37:04.320 is open up, via my browser's menu, so-called developer tools. 00:37:04.320 --> 00:37:07.380 These are going to look a little different in Chrome 00:37:07.380 --> 00:37:12.510 versus Edge versus Firefox versus Safari versus other browsers as well. 00:37:12.510 --> 00:37:15.870 But almost any modern browser, whatever your favorite is nowadays, 00:37:15.870 --> 00:37:17.970 has built into it developer tools. 00:37:17.970 --> 00:37:20.470 And you might have to click a different button to access it. 00:37:20.470 --> 00:37:22.950 But these are tools for developers, like, 00:37:22.950 --> 00:37:26.460 web developers that want to not just use the browser to go places, 00:37:26.460 --> 00:37:30.400 but use the browser to develop their own websites and web applications. 00:37:30.400 --> 00:37:32.190 Now there's a whole bunch of tabs here. 00:37:32.190 --> 00:37:34.650 And I'm going to focus on the Network tab initially. 00:37:34.650 --> 00:37:39.120 Essentially, this is like diagnostic information, kind of like debug50, 00:37:39.120 --> 00:37:39.990 like a debugger. 00:37:39.990 --> 00:37:43.090 But it's specific to the web and the web browser here. 00:37:43.090 --> 00:37:46.440 So with my developer tools open and with the Network tab open, 00:37:46.440 --> 00:37:53.880 I'm going to go up to the URL bar and type in https://www.harvard.edu/. 00:37:53.880 --> 00:37:58.380 So the exact same thing that I typed in curl a moment ago in my terminal, 00:37:58.380 --> 00:38:01.360 I'm just typing in my browser like I would normally do. 00:38:01.360 --> 00:38:04.620 And if I hit Enter, what's interesting about developer tools, 00:38:04.620 --> 00:38:07.500 and let me go ahead and drag them to the top and maximize the window, 00:38:07.500 --> 00:38:12.900 is you see all of the HTTP requests, all of the virtual envelopes 00:38:12.900 --> 00:38:16.650 that just went instantaneously it would seem back and forth 00:38:16.650 --> 00:38:20.310 between my Mac here and Harvard's own web server. 00:38:20.310 --> 00:38:22.680 And notice it's way more than a single envelope. 00:38:22.680 --> 00:38:24.180 It's way more than a single request. 00:38:24.180 --> 00:38:24.690 Why? 00:38:24.690 --> 00:38:27.780 For now, assume that each of those rows of output 00:38:27.780 --> 00:38:30.810 represents maybe a sound that was downloaded, 00:38:30.810 --> 00:38:32.970 a video, an image, some text. 00:38:32.970 --> 00:38:35.340 There's all sorts of media in web pages nowadays. 00:38:35.340 --> 00:38:38.040 And they might actually be spread across multiple files. 00:38:38.040 --> 00:38:41.010 Browsers are designed, if you will, to recursively get 00:38:41.010 --> 00:38:44.550 all of the media for a single web page and download it automatically 00:38:44.550 --> 00:38:48.780 with we humans only typing the URL itself once. 00:38:48.780 --> 00:38:49.740 But watch this. 00:38:49.740 --> 00:38:52.110 At the very top of this output, I scrolled all the way 00:38:52.110 --> 00:38:53.820 to the top of my network tab. 00:38:53.820 --> 00:38:56.550 I'll see a request, a row that represents 00:38:56.550 --> 00:38:58.590 my original request for the website. 00:38:58.590 --> 00:39:03.060 And if I Zoom in here, we'll see that 200 means apparently OK. 00:39:03.060 --> 00:39:04.350 So all is well. 00:39:04.350 --> 00:39:06.360 Here's the contents of the website. 00:39:06.360 --> 00:39:07.420 But there's a lot. 00:39:07.420 --> 00:39:09.720 In fact, if I look at the very bottom of the window, 00:39:09.720 --> 00:39:14.190 harvard.edu is composed of 91 separate files it would seem. 00:39:14.190 --> 00:39:16.890 And that's just the landing page itself, not 00:39:16.890 --> 00:39:20.400 to mention everything else we might click on ultimately. 00:39:20.400 --> 00:39:22.470 But 200, OK, is a good thing. 00:39:22.470 --> 00:39:25.920 And odds are you've never actually seen that, because it's, indeed, OK. 00:39:25.920 --> 00:39:28.920 So let's consider actually what else could 00:39:28.920 --> 00:39:30.780 happen when you make these requests. 00:39:30.780 --> 00:39:32.940 Well, here, for instance, is a shorter request. 00:39:32.940 --> 00:39:37.010 Suppose that I omit the W-W-W just because it's faster to type. 00:39:37.010 --> 00:39:38.760 And honestly, you and I are almost always, 00:39:38.760 --> 00:39:43.050 nowadays I bet, in the habit of just typing something.com, or something.edu. 00:39:43.050 --> 00:39:46.590 We don't bother typing the HTTPS, the so-called scheme or protocol. 00:39:46.590 --> 00:39:48.453 We probably don't bother typing the W-W-W. 00:39:48.453 --> 00:39:50.370 You can probably think of someone in your life 00:39:50.370 --> 00:39:53.280 who's very pedantic like that, typing it out in its full. 00:39:53.280 --> 00:39:56.350 But you don't need to do that typically for a couple of reasons. 00:39:56.350 --> 00:39:59.910 If I, in fact, go back to VS Code here, let 00:39:59.910 --> 00:40:03.375 me use curl again to connect to another URL that's similar, 00:40:03.375 --> 00:40:07.500 https://harvard.edu. 00:40:07.500 --> 00:40:11.910 Now notice before I went to W-W-W. And that's indeed Harvard's preferred URL, 00:40:11.910 --> 00:40:12.660 if you will. 00:40:12.660 --> 00:40:14.640 But harvard.edu will still work. 00:40:14.640 --> 00:40:16.590 But watch what happens when I hit Enter. 00:40:16.590 --> 00:40:19.103 I'm going to get back the contents of the virtual envelope 00:40:19.103 --> 00:40:20.520 that Harvard just sent back to me. 00:40:20.520 --> 00:40:22.200 But it's not OK. 00:40:22.200 --> 00:40:23.920 It's not 200 anymore. 00:40:23.920 --> 00:40:27.360 It's actually this number here, 301, which 00:40:27.360 --> 00:40:29.010 actually means something specific. 00:40:29.010 --> 00:40:34.450 301 actually means that Harvard's website moved permanently, so to speak. 00:40:34.450 --> 00:40:36.510 In other words, Harvard, Yale, any server 00:40:36.510 --> 00:40:39.900 can configure itself to redirect the user to another place 00:40:39.900 --> 00:40:43.000 if they prefer to canonicalize on some other URL. 00:40:43.000 --> 00:40:45.850 So by default for branding purposes, most websites still 00:40:45.850 --> 00:40:48.730 probably use www.something.something. 00:40:48.730 --> 00:40:50.358 So Harvard is, in fact, doing this. 00:40:50.358 --> 00:40:52.150 And for reasons we'll talk about next week, 00:40:52.150 --> 00:40:55.090 there's technical motivations to do so related to something 00:40:55.090 --> 00:40:56.660 called cookies and sessions. 00:40:56.660 --> 00:41:01.340 But for now, that just seems to be a different status code. 00:41:01.340 --> 00:41:05.320 But if I now open up another browser window and I'll do this again in, 00:41:05.320 --> 00:41:11.860 let's say, how about incognito mode, just to start fresh with a brand 00:41:11.860 --> 00:41:12.580 new window. 00:41:12.580 --> 00:41:14.980 Let me open my developer tools again. 00:41:14.980 --> 00:41:22.540 Let me go to the URL bar and only type https://harvard.edu/ Enter. 00:41:22.540 --> 00:41:24.350 I'm still in my network tab here. 00:41:24.350 --> 00:41:26.770 And if I scroll to the very top of this, notice, ah, 00:41:26.770 --> 00:41:29.050 the top row looks a little different now. 00:41:29.050 --> 00:41:30.670 It's not 200 anymore. 00:41:30.670 --> 00:41:32.390 And I can click on that here. 00:41:32.390 --> 00:41:37.100 And what I'm now seeing in yellow is that 301, AKA, moved permanently. 00:41:37.100 --> 00:41:40.450 So this is to say you've been able to do this all this time in your browser 00:41:40.450 --> 00:41:41.730 if you care to. 00:41:41.730 --> 00:41:45.500 You can see what's going on underneath the hood, if you will. 00:41:45.500 --> 00:41:46.760 Check that off, I think. 00:41:46.760 --> 00:41:50.930 Underneath the hood so as to just understand what's going on. 00:41:50.930 --> 00:41:54.290 Now for users, this is not that useful or intellectually interesting. 00:41:54.290 --> 00:41:57.410 But for developers, this can be very useful for understanding things 00:41:57.410 --> 00:42:00.380 and also diagnosing problems ultimately. 00:42:00.380 --> 00:42:05.090 So that's just a couple of the status codes that can come back, not just 200, 00:42:05.090 --> 00:42:06.530 but perhaps 301. 00:42:06.530 --> 00:42:12.110 There's also this one now, with which humans generally are familiar, 404. 00:42:12.110 --> 00:42:16.353 Well, it turns out 404 is what happens when a file is not found. 00:42:16.353 --> 00:42:17.520 So I can simulate that here. 00:42:17.520 --> 00:42:19.710 Let me go back to VS Code and my terminal window. 00:42:19.710 --> 00:42:24.290 Let me do curl -I https://www-- 00:42:24.290 --> 00:42:27.800 because Harvard prefers that-- harvard.edu/cats. 00:42:27.800 --> 00:42:30.980 Let's see if there's a page about cats within Harvard's website. 00:42:30.980 --> 00:42:32.370 I'm pretty sure there's not. 00:42:32.370 --> 00:42:36.710 And so, indeed, when I hit Enter, a whole lot of output, a lot of HTTP 00:42:36.710 --> 00:42:37.250 headers. 00:42:37.250 --> 00:42:39.710 But notice at the top, 404. 00:42:39.710 --> 00:42:41.390 It's File Not Found. 00:42:41.390 --> 00:42:44.720 Now what you see in the browser is going to completely depend on the website. 00:42:44.720 --> 00:42:48.740 Some websites just display an error message or a status code number. 00:42:48.740 --> 00:42:52.960 And that's why you and I have seen probably in the world 404 messages. 00:42:52.960 --> 00:42:54.710 Sometimes they're much more user friendly. 00:42:54.710 --> 00:42:57.377 Sometimes there are links back to the home page to help you out. 00:42:57.377 --> 00:42:58.700 It's entirely up to the server. 00:42:58.700 --> 00:43:02.185 But that status code indicates that something has gone wrong. 00:43:02.185 --> 00:43:04.560 And in fact, there's a whole bunch of these status codes. 00:43:04.560 --> 00:43:06.740 Some of which you'll now start to see in the class. 00:43:06.740 --> 00:43:07.667 200's OK. 00:43:07.667 --> 00:43:09.500 And it's a good thing if you never see that, 00:43:09.500 --> 00:43:11.090 because it means everything's working. 00:43:11.090 --> 00:43:12.890 404 is not found. 00:43:12.890 --> 00:43:14.690 301 is moved permanently. 00:43:14.690 --> 00:43:17.750 Any of these that start with 3 relate to redirects. 00:43:17.750 --> 00:43:21.350 Long story short, there's different ways to redirect the user from one place 00:43:21.350 --> 00:43:25.340 to another, as we saw from that location header a moment ago. 00:43:25.340 --> 00:43:27.240 400s are generally bad. 00:43:27.240 --> 00:43:30.890 It means that the user, the browser somehow did something wrong. 00:43:30.890 --> 00:43:36.290 Like, 403 forbidden probably means you're not logged in. 00:43:36.290 --> 00:43:39.410 500 you're going to start doing next week most likely. 00:43:39.410 --> 00:43:42.965 500 is, like, the segfault of the web, if you will. 00:43:42.965 --> 00:43:44.840 So there's no pointers or anything like that. 00:43:44.840 --> 00:43:48.470 But 500 means that you wrote some buggy code, as invariably we all will 00:43:48.470 --> 00:43:49.430 next week. 00:43:49.430 --> 00:43:52.640 418 is an April Fool's joke from years ago. 00:43:52.640 --> 00:43:53.810 Some servers honor this. 00:43:53.810 --> 00:43:56.300 But someone wrote up literally this long technical document 00:43:56.300 --> 00:44:00.420 proposing a response that says I'm a teapot for a server, 00:44:00.420 --> 00:44:03.590 even though it was just a joke on April 1 some years ago, 00:44:03.590 --> 00:44:06.270 so sort of geek humor, if you will. 00:44:06.270 --> 00:44:10.400 So those are then the status codes that are available to us. 00:44:10.400 --> 00:44:11.960 Let me show you one other. 00:44:11.960 --> 00:44:15.260 Has anyone been to this URL here? 00:44:15.260 --> 00:44:15.870 So you have? 00:44:15.870 --> 00:44:16.370 All right. 00:44:16.370 --> 00:44:18.680 So without spoiling here, let me actually-- 00:44:18.680 --> 00:44:23.220 well, let me go into incognito mode here. 00:44:23.220 --> 00:44:25.220 Someone's pulling it up on their phone, clearly. 00:44:25.220 --> 00:44:26.955 Safetyschool.org/ Enter. 00:44:29.810 --> 00:44:31.940 Oh, my goodness. 00:44:31.940 --> 00:44:34.670 Another box gets crossed out today, too, I think. 00:44:34.670 --> 00:44:36.020 So how is that working? 00:44:36.020 --> 00:44:39.980 Well, if we actually diagnose this with curl-- let me go into VS Code, 00:44:39.980 --> 00:44:45.080 curl -I HTTP-- and it doesn't support HTTPS because this is an old website-- 00:44:45.080 --> 00:44:52.850 ://safetyschool.org/ Enter, all this server does is return an HTTP 301 00:44:52.850 --> 00:44:58.010 response with a location that literally refers us back to yale.edu. 00:44:58.010 --> 00:44:58.880 And this is amazing. 00:44:58.880 --> 00:45:02.480 Someone has been paying for this domain name for decades. 00:45:02.480 --> 00:45:05.240 And all it does is literally this. 00:45:05.240 --> 00:45:08.510 Now I know for our friends at Yale who are watching this, 00:45:08.510 --> 00:45:10.550 it's not quite fair to poke fun. 00:45:10.550 --> 00:45:12.240 It turns out Yale got us even better. 00:45:12.240 --> 00:45:15.890 So later today, we'll turn the tables a little bit. 00:45:15.890 --> 00:45:16.700 All right. 00:45:16.700 --> 00:45:21.140 So let's go ahead and take a look now at what 00:45:21.140 --> 00:45:25.550 it is that composes this web page when it is indeed 200 OK. 00:45:25.550 --> 00:45:28.820 Let's introduce another language here, or an actual language 00:45:28.820 --> 00:45:33.180 called HTML, which is not a programming language but is a mark up language. 00:45:33.180 --> 00:45:35.180 Which is to say it's all about aesthetics, like, 00:45:35.180 --> 00:45:38.840 mocking up a web page so that you can see the information you care about. 00:45:38.840 --> 00:45:42.400 But HTML is not going to have functions and loops and conditionals 00:45:42.400 --> 00:45:44.560 and all of that stuff we talked about in Week 0 00:45:44.560 --> 00:45:46.970 It's just about presenting information. 00:45:46.970 --> 00:45:49.300 So here are some of the building blocks of HTML. 00:45:49.300 --> 00:45:52.330 You're about to see really only two vocabulary words. 00:45:52.330 --> 00:45:56.138 HTML honestly is the kind of language that you learn in, like, 30 minutes 00:45:56.138 --> 00:45:58.930 and then you're just kind of off and running with online tutorials, 00:45:58.930 --> 00:46:00.250 documentation, and the like. 00:46:00.250 --> 00:46:02.200 I still remember years ago just learning it 00:46:02.200 --> 00:46:04.900 from a teaching fellow who kind of gave me a crash course 00:46:04.900 --> 00:46:07.360 and then you kind of fill in the blanks yourself 00:46:07.360 --> 00:46:10.780 because it has relatively few concepts associated with it. 00:46:10.780 --> 00:46:13.330 Even though, in fairness, it can take years 00:46:13.330 --> 00:46:17.320 to get good at making pretty websites, today we 00:46:17.320 --> 00:46:21.040 can get good very quickly at making functional websites, so 00:46:21.040 --> 00:46:22.390 that artistic disclaimer. 00:46:22.390 --> 00:46:26.735 So in the world of HTML, there's really two concepts, tags and attributes. 00:46:26.735 --> 00:46:29.110 And those of you who have played with websites growing up 00:46:29.110 --> 00:46:31.130 might be familiar with some of these already. 00:46:31.130 --> 00:46:34.120 So here is some sample HTML. 00:46:34.120 --> 00:46:35.872 HTML is just a text-based language. 00:46:35.872 --> 00:46:37.330 You type it out with your keyboard. 00:46:37.330 --> 00:46:38.955 Again, it's not a programming language. 00:46:38.955 --> 00:46:41.180 So you can't call functions or write logic. 00:46:41.180 --> 00:46:43.290 But you can mock up a web page. 00:46:43.290 --> 00:46:45.350 And this web page, for instance, is quite simply 00:46:45.350 --> 00:46:48.770 going to say hello, title in its title bar, or the tab. 00:46:48.770 --> 00:46:51.200 And then the body of it, the big white box, 00:46:51.200 --> 00:46:55.340 it's going to say hello comma body, just to distill this really into its essence 00:46:55.340 --> 00:46:57.200 before we make more interesting pages. 00:46:57.200 --> 00:47:02.960 So what's going on in this HTML is enough detail 00:47:02.960 --> 00:47:06.300 that the server can display the information for it. 00:47:06.300 --> 00:47:09.300 So in fact, let me go ahead and reveal this as follows. 00:47:09.300 --> 00:47:13.040 I'm going to go over to VS Code here. 00:47:13.040 --> 00:47:18.330 I'm going to create a new file here called, for instance-- 00:47:18.330 --> 00:47:21.110 let's just call it hello.html. 00:47:21.110 --> 00:47:24.140 And I'm going to really quickly whip up that same web page from memory. 00:47:24.140 --> 00:47:29.870 So DOCTYPE html html lang equals quote, unquote "en" close bracket. 00:47:29.870 --> 00:47:35.480 Open head, open title, hello comma title. 00:47:35.480 --> 00:47:37.040 And then down here, open body. 00:47:37.040 --> 00:47:40.130 And you'll notice I'm actually not quite as fast as I might seem to be. 00:47:40.130 --> 00:47:44.220 VS Code is configured to automatically finish half of my thought for me. 00:47:44.220 --> 00:47:47.330 So when I open one of these things that we're about to call tags, 00:47:47.330 --> 00:47:50.000 VS Code is doing some of the heavy lifting for me. 00:47:50.000 --> 00:47:52.700 And in here, I'm going to do hello comma body. 00:47:52.700 --> 00:47:55.370 But I think this is the entirety of the file 00:47:55.370 --> 00:47:58.440 that I just proposed in the slide version thereof. 00:47:58.440 --> 00:48:03.470 So this is clearly now a text file in my code space within VS Code. 00:48:03.470 --> 00:48:06.530 How do I actually view it with a web browser? 00:48:06.530 --> 00:48:08.960 So if this file were created on my Mac or PC, 00:48:08.960 --> 00:48:12.470 I could literally double click it and Chrome or my default browser 00:48:12.470 --> 00:48:14.510 would open up and show me this web page. 00:48:14.510 --> 00:48:17.300 But this file, technically, is not on my Mac or PC. 00:48:17.300 --> 00:48:18.140 It's in the cloud. 00:48:18.140 --> 00:48:19.590 It's in your code space. 00:48:19.590 --> 00:48:23.210 So all that we need to do is actually turn on a web server 00:48:23.210 --> 00:48:27.290 to serve this file to me or to anyone else in the world, in fact. 00:48:27.290 --> 00:48:31.820 And the command we're going to run now is literally called http-server. 00:48:31.820 --> 00:48:33.830 This is a piece of software that someone else 00:48:33.830 --> 00:48:36.620 wrote that we pre-installed in everyone's code space. 00:48:36.620 --> 00:48:40.160 And by running this, it starts a server whose purpose in life 00:48:40.160 --> 00:48:42.563 is to listen for HTTP requests. 00:48:42.563 --> 00:48:44.480 And as soon as it receives one from a browser, 00:48:44.480 --> 00:48:48.870 be it mine or anyone else's, it will respond with the contents of that file. 00:48:48.870 --> 00:48:51.210 So let me go into VS Code here. 00:48:51.210 --> 00:48:53.220 Let me reopen my terminal window. 00:48:53.220 --> 00:48:58.400 And I'm going to go ahead and literally run http-server Enter. 00:48:58.400 --> 00:49:01.190 And now you'll see a whole bunch of output, most of which 00:49:01.190 --> 00:49:03.080 isn't germane to our discussion yet. 00:49:03.080 --> 00:49:05.790 But here is this URL here. 00:49:05.790 --> 00:49:10.280 And if I hover over it, I'll see a little Open URL pop up 00:49:10.280 --> 00:49:14.840 that I can click on, or on my Mac, I can Command click on the URL itself, 00:49:14.840 --> 00:49:19.260 and that will open up in a new tab this folder. 00:49:19.260 --> 00:49:22.460 So this is going to look a little esoteric at first glance. 00:49:22.460 --> 00:49:25.100 But this is what's called a directory listing. 00:49:25.100 --> 00:49:27.630 It's just literally the contents of the folder that I'm in. 00:49:27.630 --> 00:49:29.630 So I'm in my Codespaces default folder. 00:49:29.630 --> 00:49:31.850 I deleted everything from last week and weeks prior. 00:49:31.850 --> 00:49:33.975 Your folder will, of course, have many other things 00:49:33.975 --> 00:49:35.330 that you've created and kept. 00:49:35.330 --> 00:49:37.610 I have a Source 8 directory that I downloaded 00:49:37.610 --> 00:49:40.580 in advance because it's got all of today's examples made in advance. 00:49:40.580 --> 00:49:42.140 But there's the file I just created. 00:49:42.140 --> 00:49:45.140 And there's some other information here, like the date and time at which 00:49:45.140 --> 00:49:47.430 I created this file, and so forth. 00:49:47.430 --> 00:49:51.540 But you'll see that this is just a web page that lives at this URL here. 00:49:51.540 --> 00:49:54.890 And this is actually somewhat specific to Codespaces, 00:49:54.890 --> 00:49:57.060 the infrastructure we're using. 00:49:57.060 --> 00:50:01.160 But if I Zoom in up here, you'll see that I am effectively 00:50:01.160 --> 00:50:04.910 running my own web server at this weird looking URL 00:50:04.910 --> 00:50:08.070 that GitHub dynamically generated for us, for me. 00:50:08.070 --> 00:50:10.190 And you'll have a different unique one as well. 00:50:10.190 --> 00:50:13.640 You'll see that baked into this URL is actually a port number. 00:50:13.640 --> 00:50:15.170 And they're doing some trickery. 00:50:15.170 --> 00:50:20.270 Normally, I would have to access this web server at Port 80, or 443, 00:50:20.270 --> 00:50:21.650 or even 8080. 00:50:21.650 --> 00:50:25.370 And the reason for this is because cs50.dev, 00:50:25.370 --> 00:50:28.430 that is to say Codespaces, the tool that we're using in the cloud, 00:50:28.430 --> 00:50:30.740 is obviously itself already a web server. 00:50:30.740 --> 00:50:35.120 And it's GitHub's web server that's listening already on Port 80 and 443. 00:50:35.120 --> 00:50:38.840 So if I want to run my own web server on their web server, 00:50:38.840 --> 00:50:40.650 I just have to pick another port number. 00:50:40.650 --> 00:50:43.430 And so what you're seeing in the URL here is a hint of that. 00:50:43.430 --> 00:50:48.590 By convention, the program I just ran, http-server, does not try to use 80. 00:50:48.590 --> 00:50:50.330 It does not try to use 443. 00:50:50.330 --> 00:50:54.350 It uses 8080 by default. And that's why you see it in the URL here. 00:50:54.350 --> 00:50:59.000 And underneath the hood, that virtual envelope actually contains Port 8080. 00:50:59.000 --> 00:51:00.930 Because this is not an official web server. 00:51:00.930 --> 00:51:04.370 This is not CS50.dev or GitHub.dev. 00:51:04.370 --> 00:51:09.410 This is little old me trying to serve up my brand new hello.html file. 00:51:09.410 --> 00:51:11.150 But the point here is this. 00:51:11.150 --> 00:51:15.260 When I click on this file, I should see the results of my hard work. 00:51:15.260 --> 00:51:19.100 And there is a big white box, otherwise known as the view port, inside of which 00:51:19.100 --> 00:51:22.080 are the only words in the body of my page, hello, body. 00:51:22.080 --> 00:51:26.550 And if I scroll up further, you'll see in my tab here hello comma title. 00:51:26.550 --> 00:51:29.420 So this now maps back to the code we just saw. 00:51:29.420 --> 00:51:32.300 Here is the HTML that I just pulled up in my browser. 00:51:32.300 --> 00:51:36.052 And it is what told the browser what to do visually. 00:51:36.052 --> 00:51:37.760 So let's walk through this top to bottom. 00:51:37.760 --> 00:51:41.370 This first line here is what's called the document type declaration. 00:51:41.370 --> 00:51:43.380 Honestly, you just copy paste this nowadays. 00:51:43.380 --> 00:51:47.250 And it means hey, browser, I'm using version 5 of HTML. 00:51:47.250 --> 00:51:49.290 Odds are in some number of years, this line 00:51:49.290 --> 00:51:51.720 might change over time to indicate different versions. 00:51:51.720 --> 00:51:55.080 But for now, this just means I'm using the latest version of this HTML 00:51:55.080 --> 00:51:55.860 language. 00:51:55.860 --> 00:51:58.110 That's kind of anomaly, because you're not going 00:51:58.110 --> 00:52:00.150 to see this exclamation point again. 00:52:00.150 --> 00:52:02.910 Everywhere else, you're going to see a lot of less than signs 00:52:02.910 --> 00:52:05.910 and greater than signs or angled brackets, so to speak. 00:52:05.910 --> 00:52:10.110 But they're almost always going to be symmetric, as follows. 00:52:10.110 --> 00:52:16.530 This tag here, this is an HTML tag, says, hey browser, here comes my HTML. 00:52:16.530 --> 00:52:18.880 And this is what's known as an attribute. 00:52:18.880 --> 00:52:22.260 So anything after the name of a tag is what we'd call an attribute. 00:52:22.260 --> 00:52:23.910 And attributes can have values. 00:52:23.910 --> 00:52:27.060 Those values that are associated with the attributes with an equal sign 00:52:27.060 --> 00:52:30.180 and typically quotation marks, single quotes or double quotes, 00:52:30.180 --> 00:52:31.210 as in this case. 00:52:31.210 --> 00:52:35.250 So here we, again, have that paradigm of a dictionary, key, value, pairs. 00:52:35.250 --> 00:52:38.160 They're everywhere in computing, even though the syntax obviously 00:52:38.160 --> 00:52:42.260 keeps changing, whether when we're in SQL, or Python, or now HTML. 00:52:42.260 --> 00:52:47.400 This tag at the very bottom now means hey, browser, that's it for my HTML. 00:52:47.400 --> 00:52:50.180 So when you see a tag that looks like another, 00:52:50.180 --> 00:52:52.228 but starts with a forward slash-- 00:52:52.228 --> 00:52:54.770 and you do not need to repeat the attributes, that would just 00:52:54.770 --> 00:52:57.530 be very annoying to have to type it here and here, we 00:52:57.530 --> 00:53:03.620 keep it succinct-- this is what's known as a close tag, or an end tag that 00:53:03.620 --> 00:53:07.910 conceptually corresponds to this start tag or open tag. 00:53:07.910 --> 00:53:09.590 So they're sort of symmetric. 00:53:09.590 --> 00:53:12.030 Inside of that are two children, so to speak. 00:53:12.030 --> 00:53:15.770 So there's actually a notion of a family tree-type hierarchy here, or a tree, 00:53:15.770 --> 00:53:17.420 as we've discussed in data structures. 00:53:17.420 --> 00:53:20.390 The HTML tag, per the indentation here, has 00:53:20.390 --> 00:53:25.100 one child called head and another child called body. 00:53:25.100 --> 00:53:27.680 Everything between the start tag and an end tag 00:53:27.680 --> 00:53:30.780 here is what's also generically known as an element. 00:53:30.780 --> 00:53:32.640 So this is the head element. 00:53:32.640 --> 00:53:33.708 This is the body element. 00:53:33.708 --> 00:53:36.500 A bunch of new vocab, but it's not that intellectually interesting. 00:53:36.500 --> 00:53:38.600 It's just jargon that we'll use. 00:53:38.600 --> 00:53:42.100 Here means hey, browser, here comes the head of my page. 00:53:42.100 --> 00:53:44.700 So like the very top of it, which generally for now 00:53:44.700 --> 00:53:46.350 means just the title bar. 00:53:46.350 --> 00:53:52.650 In fact, this means, hey, browser, here comes the title of my page. 00:53:52.650 --> 00:53:54.940 And then here, notice there's no more angle brackets. 00:53:54.940 --> 00:53:56.310 This is literally raw text. 00:53:56.310 --> 00:54:01.050 And this is why we saw in the actual gray tab of my browser hello comma 00:54:01.050 --> 00:54:01.680 title. 00:54:01.680 --> 00:54:03.930 This means, hey, browser, that's it for the title. 00:54:03.930 --> 00:54:06.000 This means, hey, browser, that's it for the head. 00:54:06.000 --> 00:54:10.410 Meanwhile, down here, hey, browser, here comes the body of my main page. 00:54:10.410 --> 00:54:13.500 Like, 90-plus percent of the page inside of the so-called viewport, 00:54:13.500 --> 00:54:16.590 the big rectangular region, hey, browser, here comes the body. 00:54:16.590 --> 00:54:18.550 Hey, browser, sir, that's it for the body. 00:54:18.550 --> 00:54:19.650 What is in the body? 00:54:19.650 --> 00:54:23.280 In this super simple case, literally just hello comma body. 00:54:23.280 --> 00:54:24.150 That's it. 00:54:24.150 --> 00:54:26.190 So HTML really is that pedantic. 00:54:26.190 --> 00:54:28.620 It just tells the browser start doing this. 00:54:28.620 --> 00:54:29.380 Stop doing this. 00:54:29.380 --> 00:54:29.880 Start. 00:54:29.880 --> 00:54:30.210 Stop. 00:54:30.210 --> 00:54:30.510 Start. 00:54:30.510 --> 00:54:31.010 Stop. 00:54:31.010 --> 00:54:33.370 And that's how it knows what to do, top to bottom, 00:54:33.370 --> 00:54:38.080 left to right when actually reading the code therein. 00:54:38.080 --> 00:54:38.580 All right. 00:54:38.580 --> 00:54:43.200 Questions about any of this here HTML code. 00:54:43.200 --> 00:54:45.860 And yeah, in front? 00:54:45.860 --> 00:54:49.623 AUDIENCE: Would browsers be considered a HTML interpreter? 00:54:49.623 --> 00:54:50.790 DAVID MALAN: Say that again? 00:54:50.790 --> 00:54:53.850 AUDIENCE: Would browsers be considered a HTML code interpreter? 00:54:53.850 --> 00:54:55.860 DAVID MALAN: Oh, yes. 00:54:55.860 --> 00:54:57.180 I think that's fair. 00:54:57.180 --> 00:55:00.480 The question is, can browsers be considered HTML interpreters? 00:55:00.480 --> 00:55:02.790 Yes, I don't think people tend to call it that. 00:55:02.790 --> 00:55:05.470 Interpretation generally implies that you're 00:55:05.470 --> 00:55:08.220 parsing something that's logical in nature, your functions, loops, 00:55:08.220 --> 00:55:09.690 conditionals, and so forth. 00:55:09.690 --> 00:55:12.510 Parser is a term you might indeed hear much more often. 00:55:12.510 --> 00:55:16.020 A parser is a piece of software that analyzes code, 00:55:16.020 --> 00:55:18.270 analyzes text top to bottom, left to right, 00:55:18.270 --> 00:55:22.440 breaks it down into chunks that have semantic meaning, like the tags, 00:55:22.440 --> 00:55:25.740 like the attributes, like the elements that we're talking about 00:55:25.740 --> 00:55:27.820 and then it displays them, in this case. 00:55:27.820 --> 00:55:31.440 There's not as much to interpret in quite the same way. 00:55:31.440 --> 00:55:32.970 But that's reasonable, nonetheless. 00:55:32.970 --> 00:55:33.470 Yeah? 00:55:33.470 --> 00:55:35.178 AUDIENCE: With all the frameworks, do you 00:55:35.178 --> 00:55:37.440 think is is worth learning HTML from scratch 00:55:37.440 --> 00:55:39.133 or just use a Bootstrap [INAUDIBLE]? 00:55:39.133 --> 00:55:40.550 DAVID MALAN: Really good question. 00:55:40.550 --> 00:55:41.750 With all the frameworks out there, should you 00:55:41.750 --> 00:55:44.625 bother learning HTML and writing it from scratch or using frameworks, 00:55:44.625 --> 00:55:45.958 like something called Bootstrap. 00:55:45.958 --> 00:55:48.980 Well, we spent a few minutes today talking about that very framework. 00:55:48.980 --> 00:55:51.530 But even frameworks like Bootstrap absolutely 00:55:51.530 --> 00:55:54.230 assume that something about HTML, something 00:55:54.230 --> 00:55:57.440 also about something called CSS, more on that in a bit, and better still, 00:55:57.440 --> 00:55:59.330 something about JavaScript. 00:55:59.330 --> 00:56:01.910 If you really don't want to know and understand these things, 00:56:01.910 --> 00:56:04.118 that's when you reach for like a third party service, 00:56:04.118 --> 00:56:08.360 like Squarespace nowadays or Wix, where you really just click and drag and drop 00:56:08.360 --> 00:56:12.380 and create websites that are, at the end of the day, still HTML. 00:56:12.380 --> 00:56:15.170 But the developers at Wix and Squarespace 00:56:15.170 --> 00:56:18.180 have automated the process with a graphical user interface 00:56:18.180 --> 00:56:19.850 or GUI of letting you create it. 00:56:19.850 --> 00:56:23.953 But even then, most web developers, or even just business people 00:56:23.953 --> 00:56:26.120 who want to create their own website and they're not 00:56:26.120 --> 00:56:28.310 programmers themselves or technical folks, 00:56:28.310 --> 00:56:31.350 they might still like to know a little something about HTML, CSS, 00:56:31.350 --> 00:56:34.910 and JavaScript because then you can open like the advanced settings 00:56:34.910 --> 00:56:36.090 and configure things. 00:56:36.090 --> 00:56:37.923 And indeed, that's a frustration that you'll 00:56:37.923 --> 00:56:42.280 tend to feel if you can't quite drop down conceptually to that level. 00:56:42.280 --> 00:56:42.780 All right. 00:56:42.780 --> 00:56:45.570 So just to make this a little more-- 00:56:45.570 --> 00:56:47.720 to give you more of a mental model for this, 00:56:47.720 --> 00:56:50.460 this indentation is not strictly necessary. 00:56:50.460 --> 00:56:54.660 Kind of, like, in C, where we care, where style50 cares, but not 00:56:54.660 --> 00:56:56.850 Clang, about what your code looks like. 00:56:56.850 --> 00:56:58.805 Similarly, browsers are pretty tolerant. 00:56:58.805 --> 00:57:01.680 You can have all of this white space, all of this pretty indentation. 00:57:01.680 --> 00:57:02.910 Or you cannot. 00:57:02.910 --> 00:57:06.393 It's not going to care, generally, one way or the other. 00:57:06.393 --> 00:57:08.310 However, this is certainly much more readable. 00:57:08.310 --> 00:57:11.980 But we'll see next week as we start to generate HTML automatically, 00:57:11.980 --> 00:57:16.410 it's not always important that the code you generate be pretty printed. 00:57:16.410 --> 00:57:18.780 But when you're writing in this format, it absolutely 00:57:18.780 --> 00:57:22.180 should be when you're collaborating or submitting to other people. 00:57:22.180 --> 00:57:25.900 So this, though, is what we would call a tree representation of this. 00:57:25.900 --> 00:57:27.332 So here is that hierarchy. 00:57:27.332 --> 00:57:30.540 So if we think of the whole web page as what's generally known as a document, 00:57:30.540 --> 00:57:34.800 that document has a root element called the HTML element, which 00:57:34.800 --> 00:57:36.900 it's open HTML tag and its closed tag. 00:57:36.900 --> 00:57:38.910 It has, as I claim, two children. 00:57:38.910 --> 00:57:40.800 The head tag has one child title. 00:57:40.800 --> 00:57:44.370 And then both of those leaf nodes, or leaves 00:57:44.370 --> 00:57:49.140 to borrow the family tree vernacular, have text nodes of hello, title 00:57:49.140 --> 00:57:51.040 and hello, body, respectively. 00:57:51.040 --> 00:57:54.270 So this is going to be useful later today because it turns out, 00:57:54.270 --> 00:57:57.480 with JavaScript, an actual programming language, 00:57:57.480 --> 00:58:01.800 we can start to modify this tree in the computer's memory or RAM 00:58:01.800 --> 00:58:05.220 and make the page dynamically change by essentially 00:58:05.220 --> 00:58:09.750 creating new HTML on the fly, even if that didn't come from the server. 00:58:09.750 --> 00:58:13.020 Case in point, many of you use Gmail or maybe Outlook. 00:58:13.020 --> 00:58:15.660 Generally speaking, you don't have to reload the page 00:58:15.660 --> 00:58:16.950 to see if you've got new mail. 00:58:16.950 --> 00:58:20.550 It just magically appears at the top of the page in kind of a stack. 00:58:20.550 --> 00:58:23.340 And it just keeps pushing old mail down, down, down. 00:58:23.340 --> 00:58:26.130 Well, that's going to be the result of some JavaScript 00:58:26.130 --> 00:58:28.860 code updating this tree in memory. 00:58:28.860 --> 00:58:31.110 And it has the effect of just dynamically generating 00:58:31.110 --> 00:58:36.340 more and more HTML that represents your email's inbox, for instance. 00:58:36.340 --> 00:58:36.840 All right. 00:58:36.840 --> 00:58:39.870 So with that said, why don't we go ahead and actually 00:58:39.870 --> 00:58:42.190 try this out in a couple of ways. 00:58:42.190 --> 00:58:44.290 So let me go back to VS Code here. 00:58:44.290 --> 00:58:50.440 Let me propose to actually tweak my code here a little bit. 00:58:50.440 --> 00:58:55.980 So let me go into, let's see, my VS Code editor here. 00:58:55.980 --> 00:58:57.000 Let me zoom out. 00:58:57.000 --> 00:59:00.090 And notice down below, actually, all this time 00:59:00.090 --> 00:59:04.650 as I was clicking on hello.html, my HTTP server program 00:59:04.650 --> 00:59:07.860 actually is outputting sort of the logs from a server. 00:59:07.860 --> 00:59:11.610 It turns out any time you request a page with a browser from a server, 00:59:11.610 --> 00:59:14.520 that server is probably logging a little something about you. 00:59:14.520 --> 00:59:16.980 One, it's probably logging your IP address. 00:59:16.980 --> 00:59:19.170 Two, it's probably logging the type of browser 00:59:19.170 --> 00:59:22.500 you're using Chrome, or Safari, or Edge, or something like that. 00:59:22.500 --> 00:59:25.810 It's probably logging the operating system version you're using, 00:59:25.810 --> 00:59:28.800 be it Windows, or Mac OS, or Android, or iOS, or the like, 00:59:28.800 --> 00:59:30.922 and maybe some other information as well. 00:59:30.922 --> 00:59:32.130 We won't dwell on this today. 00:59:32.130 --> 00:59:36.000 But there's a lot of information that will be logged about you, even if you 00:59:36.000 --> 00:59:38.790 are in incognito mode or private mode. 00:59:38.790 --> 00:59:40.180 So more on that next week. 00:59:40.180 --> 00:59:43.380 And today, unlike all past lectures, even though by default you 00:59:43.380 --> 00:59:46.530 see this in your own code space, you see here 00:59:46.530 --> 00:59:51.240 a ports tab, which for the most part is not that useful for us today. 00:59:51.240 --> 00:59:55.660 But you will see that this row here mentions HTTP server. 00:59:55.660 --> 00:59:56.160 Why? 00:59:56.160 --> 00:59:58.680 Because in my terminal, that command is still running. 00:59:58.680 --> 00:59:59.640 It is a server. 00:59:59.640 --> 01:00:02.880 And it's just there living to serve now by waiting and waiting and waiting 01:00:02.880 --> 01:00:04.650 for me to click on more of those links. 01:00:04.650 --> 01:00:08.290 And every time I do click on a link, I'll see another line of output here. 01:00:08.290 --> 01:00:12.330 But it turns out that all this time in your ports tab of VS Code, you 01:00:12.330 --> 01:00:16.740 can see all of the TCP ports, for instance, that are in use. 01:00:16.740 --> 01:00:20.340 Now generally, you haven't needed any of those, at least for your own work. 01:00:20.340 --> 01:00:24.660 But notice that HTTP server is indeed listening on Port 8080. 01:00:24.660 --> 01:00:26.940 CS50 has some of its own customizations. 01:00:26.940 --> 01:00:28.570 And this is a bit of a geek Easter egg. 01:00:28.570 --> 01:00:34.420 But we presume to use Port 1337, which perhaps those more comfortable 01:00:34.420 --> 01:00:35.420 will know what it means. 01:00:35.420 --> 01:00:36.378 This is like leetspeak. 01:00:36.378 --> 01:00:39.700 So it actually spells Leet if you're cool and use a 1, 7, and 2, 3. 01:00:39.700 --> 01:00:40.200 OK. 01:00:40.200 --> 01:00:42.838 So anyhow, we chose that port number. 01:00:42.838 --> 01:00:44.130 But there are some conventions. 01:00:44.130 --> 01:00:46.920 Next week we're going to actually start using Port 5,000, which 01:00:46.920 --> 01:00:48.060 isn't in use at the moment. 01:00:48.060 --> 01:00:52.118 But long story short, you can see this stuff underneath the hood. 01:00:52.118 --> 01:00:53.910 And indeed, we're just sort of peeling back 01:00:53.910 --> 01:00:56.565 some of these layers that have been there now for some time. 01:00:56.565 --> 01:00:57.940 Well, let's go ahead and do this. 01:00:57.940 --> 01:01:03.210 I'm going to go ahead and create another terminal window using my plus icon down 01:01:03.210 --> 01:01:04.300 here in the console. 01:01:04.300 --> 01:01:08.370 Notice that at the right-hand side of my screen, I now have two bash shells. 01:01:08.370 --> 01:01:13.230 Bash is the name of your prompt, so to speak, where the dollar sign is. 01:01:13.230 --> 01:01:16.138 If I click on the first one, there's HTTP server. 01:01:16.138 --> 01:01:16.930 It's still running. 01:01:16.930 --> 01:01:18.430 And I want it to keep running today. 01:01:18.430 --> 01:01:22.360 But I'd also like to be able to run more commands in my code space. 01:01:22.360 --> 01:01:24.270 So I've simply created a second terminal. 01:01:24.270 --> 01:01:26.760 And I can go back and forth by clicking it right. 01:01:26.760 --> 01:01:32.190 Let me go ahead now and copy hello.html like that and create a brand new file 01:01:32.190 --> 01:01:33.360 called-- 01:01:33.360 --> 01:01:36.450 how about paragraphs.html? 01:01:36.450 --> 01:01:39.790 And in paragraphs.html, I'm going to first paste all of that. 01:01:39.790 --> 01:01:43.600 I'm going to hide my terminal window now without stopping HTTP server. 01:01:43.600 --> 01:01:46.690 And I'm going to go ahead and just create some paragraphs of text. 01:01:46.690 --> 01:01:49.160 And in fact, let me go ahead and cheat here real quick. 01:01:49.160 --> 01:01:54.010 I'm going to go ahead and, in my other window here secretly, open up 01:01:54.010 --> 01:02:00.200 a whole bunch of text so that I can grab some Latin-like text to copy paste. 01:02:00.200 --> 01:02:01.120 So now I'm back. 01:02:01.120 --> 01:02:03.765 And all I did was secretly copy paste a whole bunch of text. 01:02:03.765 --> 01:02:06.640 I'm going to make a couple of changes to this file, where I currently 01:02:06.640 --> 01:02:08.530 have just a title and a body. 01:02:08.530 --> 01:02:12.220 One, I'm going to rename this to paragraphs, just so I can keep straight 01:02:12.220 --> 01:02:13.420 which file is which. 01:02:13.420 --> 01:02:17.890 And down here, I'm going to go ahead and paste in a big paragraph of text. 01:02:17.890 --> 01:02:19.360 This is not actually Latin. 01:02:19.360 --> 01:02:23.650 It's sort of lorem ipsum text, which is Latin-like random words that's 01:02:23.650 --> 01:02:24.925 meant to look like Latin. 01:02:24.925 --> 01:02:27.550 And typographers historically used this as sort of placeholders 01:02:27.550 --> 01:02:28.540 for actual text. 01:02:28.540 --> 01:02:31.900 But notice this is a pretty decently long paragraph. 01:02:31.900 --> 01:02:34.580 And so it's going to make my web page a bit bigger. 01:02:34.580 --> 01:02:39.490 So let me go back to my other tab, where I have hello.html open from before. 01:02:39.490 --> 01:02:40.570 Let me click back. 01:02:40.570 --> 01:02:45.195 And now notice, in my directory listing, I have a new file, paragraphs.html. 01:02:45.195 --> 01:02:46.570 Let me go ahead and open that up. 01:02:46.570 --> 01:02:50.260 And voila, there is a big paragraph of text. 01:02:50.260 --> 01:02:53.780 Just for fun, let me create three such paragraphs. 01:02:53.780 --> 01:02:58.112 So I'm going to cheat temporarily and just copy and paste two more times. 01:02:58.112 --> 01:03:00.070 But I'm going to separate it with a blank line, 01:03:00.070 --> 01:03:03.040 as you would in, like, Google Docs or Microsoft Word for paragraphs 01:03:03.040 --> 01:03:04.600 in English or any language. 01:03:04.600 --> 01:03:06.520 And I'm going to go back to my paragraphs. 01:03:06.520 --> 01:03:10.990 Nothing has changed yet because HTTP, just like the exercise with Phyllis 01:03:10.990 --> 01:03:14.320 and Brian, requires that we send the packets back and forth if we 01:03:14.320 --> 01:03:16.010 want to get updated content. 01:03:16.010 --> 01:03:20.860 So I have to click my browser's reload button, or hit Control R or Command R, 01:03:20.860 --> 01:03:24.850 depending on your browser or OS, and notice that when I do that, 01:03:24.850 --> 01:03:26.630 I definitely get more text. 01:03:26.630 --> 01:03:31.240 But it just looks like one big blob, not three separate paragraphs. 01:03:31.240 --> 01:03:33.760 What might your intuition be for why that 01:03:33.760 --> 01:03:39.190 is, even though I've clearly indented this and given blank lines between? 01:03:39.190 --> 01:03:39.850 Yeah? 01:03:39.850 --> 01:03:41.590 AUDIENCE: HTML doesn't care about the whitespace. 01:03:41.590 --> 01:03:42.340 DAVID MALAN: Yeah. 01:03:42.340 --> 01:03:45.070 So HTML doesn't care about the whitespace or technically, 01:03:45.070 --> 01:03:47.290 more than one whitespace. 01:03:47.290 --> 01:03:49.840 I can hit as many Enters as I want. 01:03:49.840 --> 01:03:52.540 All of them are going to be ignored except for a single space. 01:03:52.540 --> 01:03:55.090 It's going to be normalized to just a single space. 01:03:55.090 --> 01:03:56.680 In general, this is useful. 01:03:56.680 --> 01:04:00.430 Because it means I can pretty print my HTML and indent things visually, 01:04:00.430 --> 01:04:03.393 even if I don't want the browser to indent anything manually for me. 01:04:03.393 --> 01:04:05.560 But here's where we're going to need some more tags. 01:04:05.560 --> 01:04:08.020 And it turns out the simplest fix for this problem 01:04:08.020 --> 01:04:10.150 is to use the paragraph tag. 01:04:10.150 --> 01:04:13.373 And for short, it's just open bracket p close bracket. 01:04:13.373 --> 01:04:15.790 I'm going to be a little pedantic, and even though VS Code 01:04:15.790 --> 01:04:18.640 is being a little annoying because it's trying to autocomplete my thoughts 01:04:18.640 --> 01:04:20.290 but I don't want it to autocomplete just yet, 01:04:20.290 --> 01:04:22.332 sometimes you have to fight with the text editor. 01:04:22.332 --> 01:04:25.600 So these autocomplete features have upsides and downsides. 01:04:25.600 --> 01:04:28.480 But I'm going to go ahead and put a paragraph tag, 01:04:28.480 --> 01:04:31.600 open and close around each of these paragraphs. 01:04:31.600 --> 01:04:33.850 And I'm going to maintain my indentation, just to keep 01:04:33.850 --> 01:04:35.690 it visually clean on the screen. 01:04:35.690 --> 01:04:40.250 And now I'm going to put this one last close tag on this line here. 01:04:40.250 --> 01:04:42.770 And so it's a lot more verbose. 01:04:42.770 --> 01:04:46.100 But notice that it's effectively telling the browser start a paragraph, 01:04:46.100 --> 01:04:49.860 end a paragraph, start a paragraph, end a paragraph, and so forth. 01:04:49.860 --> 01:04:53.240 So if I go back to my other tab and I click Reload, 01:04:53.240 --> 01:04:55.950 now we have some semblance of what I expected, 01:04:55.950 --> 01:04:58.830 which is three separate paragraphs in this case. 01:04:58.830 --> 01:04:59.330 All right? 01:04:59.330 --> 01:05:01.323 So that's the p tag, the paragraph tag. 01:05:01.323 --> 01:05:03.740 P for short, because as you'll see, many of these tags are 01:05:03.740 --> 01:05:06.410 abbreviated just because they're slightly faster to type. 01:05:06.410 --> 01:05:08.010 Let's do another example. 01:05:08.010 --> 01:05:10.020 Let me go back to VS Code here. 01:05:10.020 --> 01:05:11.400 I'm going to copy this text. 01:05:11.400 --> 01:05:13.130 I'm going to create a new file called-- 01:05:13.130 --> 01:05:17.000 how about headings.html? 01:05:17.000 --> 01:05:21.180 And I'm going to paste this, close my terminal just to give me more room. 01:05:21.180 --> 01:05:23.060 I'm going to rename the title to be Headings, 01:05:23.060 --> 01:05:24.770 just to keep straight which is which. 01:05:24.770 --> 01:05:27.873 I'm going to delete all of these paragraphs to make it-- actually, 01:05:27.873 --> 01:05:28.790 no, let's not do that. 01:05:28.790 --> 01:05:30.200 Let's keep the paragraphs. 01:05:30.200 --> 01:05:33.390 But like an academic paper or a textbook, 01:05:33.390 --> 01:05:37.130 let's give these chapter headings or section headings or the like. 01:05:37.130 --> 01:05:40.820 Well, I could just do something like this. 01:05:40.820 --> 01:05:42.740 How about 1? 01:05:42.740 --> 01:05:47.210 And then down here I could put 2, and then down here I could put 3. 01:05:47.210 --> 01:05:52.130 But of course, if I reload this, it's not really going to look as I-- whoops, 01:05:52.130 --> 01:05:57.260 if I go back to this directory listing, open up headings.html, it's fine. 01:05:57.260 --> 01:05:58.370 It's not super pretty. 01:05:58.370 --> 01:06:01.370 But it would be nice to give a little more prominence to these headings. 01:06:01.370 --> 01:06:03.740 And in fact, there's a bunch of tags for this. 01:06:03.740 --> 01:06:07.730 I can use H1, for instance, for one really big heading. 01:06:07.730 --> 01:06:10.308 And then let me close the tag over here and indent. 01:06:10.308 --> 01:06:12.600 Then down here-- and, again, whitespace doesn't matter, 01:06:12.600 --> 01:06:15.380 so I'm going to give myself a little bit of breathing room just so it's clear 01:06:15.380 --> 01:06:16.550 which of these is which. 01:06:16.550 --> 01:06:19.070 For this, maybe it's not Chapter 2, but Section 2. 01:06:19.070 --> 01:06:20.660 So let me do H2. 01:06:20.660 --> 01:06:24.260 And then inside of this, I'm going to go ahead and do 2. 01:06:24.260 --> 01:06:27.712 And just to be clear, I don't have to put these on their own lines. 01:06:27.712 --> 01:06:29.420 I'm just doing that to be a bit pedantic. 01:06:29.420 --> 01:06:32.030 You can technically just do this and keep everything on one line. 01:06:32.030 --> 01:06:33.500 But I'll be consistent, at least. 01:06:33.500 --> 01:06:35.060 But either approach is fine. 01:06:35.060 --> 01:06:37.770 And then, down here, I'm going to use maybe a sub subsection. 01:06:37.770 --> 01:06:39.735 So let me delete this and do h3. 01:06:39.735 --> 01:06:41.360 I'm just going to write the word three. 01:06:41.360 --> 01:06:45.210 And then just to be neat, I'm going to indent everything like this here. 01:06:45.210 --> 01:06:47.810 So now if I go back to headings and I reload, 01:06:47.810 --> 01:06:49.692 I'm going to get some default formatting. 01:06:49.692 --> 01:06:51.650 It might not be the formatting you want, but it 01:06:51.650 --> 01:06:54.470 looks like it's big and bold, but in decreasing order. 01:06:54.470 --> 01:06:56.270 H1 is the biggest. 01:06:56.270 --> 01:06:57.560 H2 is smaller. 01:06:57.560 --> 01:06:58.940 H3 is even smaller. 01:06:58.940 --> 01:07:00.560 And you can go down to h6. 01:07:00.560 --> 01:07:02.040 And it gets smaller and smaller. 01:07:02.040 --> 01:07:04.850 And at that point, if you've got, like, sub sub sub sub 01:07:04.850 --> 01:07:08.730 subsections of your book or paper, you're probably organizing it poorly. 01:07:08.730 --> 01:07:10.740 So they stop at some point there. 01:07:10.740 --> 01:07:11.240 All right. 01:07:11.240 --> 01:07:12.740 Well, what else can we do in HTML? 01:07:12.740 --> 01:07:13.948 These things are omnipresent. 01:07:13.948 --> 01:07:17.930 Let me copy this HTML and close that tab, open my terminal, 01:07:17.930 --> 01:07:21.470 and create a new file, like, code list.html. 01:07:21.470 --> 01:07:23.430 And let's make a list of information. 01:07:23.430 --> 01:07:26.960 Let me just paste that HTML, just to save some time today, and change 01:07:26.960 --> 01:07:28.310 my title to list. 01:07:28.310 --> 01:07:32.370 Let me get rid of all of these paragraphs, just to simplify things. 01:07:32.370 --> 01:07:35.810 So now I'm sort of back to where I began. 01:07:35.810 --> 01:07:39.800 And then inside of the body of this page, let me go ahead and make a list, 01:07:39.800 --> 01:07:41.395 like foo, bar, baz. 01:07:41.395 --> 01:07:43.520 If you've never heard these words, these are, like, 01:07:43.520 --> 01:07:45.230 computer scientists go-to words. 01:07:45.230 --> 01:07:48.030 A mathematician might choose x, y, and z by default. 01:07:48.030 --> 01:07:51.990 CS people tend to go with foo, bar, and baz for historical reasons. 01:07:51.990 --> 01:07:54.690 So here's a list of three arbitrary words. 01:07:54.690 --> 01:07:59.120 If I go over to my other tab, go back to my directory listing, 01:07:59.120 --> 01:08:00.240 there's my new file. 01:08:00.240 --> 01:08:03.300 Let's click on list.html, same problem. 01:08:03.300 --> 01:08:03.990 It's a list. 01:08:03.990 --> 01:08:06.140 But it's not one after the other. 01:08:06.140 --> 01:08:08.670 Last time, of course, we fixed this with paragraphs. 01:08:08.670 --> 01:08:09.380 But you know what'd be nice? 01:08:09.380 --> 01:08:11.390 To make it a little prettier, like a bulleted list, which 01:08:11.390 --> 01:08:12.807 are kind of everywhere these days. 01:08:12.807 --> 01:08:15.350 So I could try to simulate this. 01:08:15.350 --> 01:08:18.350 And you might be in the habit of doing this in some programs. 01:08:18.350 --> 01:08:21.649 But of course, if I go back to my other tab, Reload, 01:08:21.649 --> 01:08:23.930 I'm just sort of making the problem worse visually. 01:08:23.930 --> 01:08:25.790 But it turns out-- 01:08:25.790 --> 01:08:30.740 let me undo that-- there is an unordered list tag, otherwise known 01:08:30.740 --> 01:08:33.560 as ul for short, that I can put all three 01:08:33.560 --> 01:08:35.819 of these words in an unordered list. 01:08:35.819 --> 01:08:38.750 Let me go ahead and indent everything consistently. 01:08:38.750 --> 01:08:41.689 But to have three items in this list, I actually 01:08:41.689 --> 01:08:44.330 need another tag, a list item tag. 01:08:44.330 --> 01:08:50.210 And I'm going to go ahead and add that tag there, list item here and there, 01:08:50.210 --> 01:08:52.290 and then another list item tag here. 01:08:52.290 --> 01:08:54.770 And here's where it's a stylistic choice. 01:08:54.770 --> 01:08:57.598 I could move foo and bar and baz onto their own lines. 01:08:57.598 --> 01:09:00.140 But this is going to start to get excessively tall, like, too 01:09:00.140 --> 01:09:00.848 much white space. 01:09:00.848 --> 01:09:02.520 So reasonable people will disagree. 01:09:02.520 --> 01:09:04.399 But this feels a little more readable to me. 01:09:04.399 --> 01:09:05.990 So I'm going to leave it as such. 01:09:05.990 --> 01:09:07.310 Go back to my other tab. 01:09:07.310 --> 01:09:11.132 And now when I reload, you get a nice bulleted list by default. 01:09:11.132 --> 01:09:12.590 And you see these all over the web. 01:09:12.590 --> 01:09:16.550 What if I want to have a numbered list, that is to say, ordered list? 01:09:16.550 --> 01:09:20.930 Any instincts for changing these bullets to numbers? 01:09:20.930 --> 01:09:22.640 So ol is a good instinct. 01:09:22.640 --> 01:09:25.310 And, indeed, sometimes HTML makes perfect sense. 01:09:25.310 --> 01:09:29.870 As in this case, if I change ul to ol, I don't have to manually number anything. 01:09:29.870 --> 01:09:33.590 Because when I reload, it's going to use Arabic numerals automatically 01:09:33.590 --> 01:09:35.450 for me like this, top to bottom. 01:09:35.450 --> 01:09:39.260 And what's nice about this is, if I go in and I insert things in the middle, 01:09:39.260 --> 01:09:41.189 I don't have to manually renumber things. 01:09:41.189 --> 01:09:43.180 The browser is going to do the counting for me. 01:09:43.180 --> 01:09:45.180 And if you're doing an outline, you can actually 01:09:45.180 --> 01:09:49.020 specify whether you want 1, 2, 3, or A, B, C, or I, 01:09:49.020 --> 01:09:50.939 double I, triple I, or so forth. 01:09:50.939 --> 01:09:53.010 There's different numbering systems you can use. 01:09:53.010 --> 01:09:56.640 But by default, we get our decimal numbers here. 01:09:56.640 --> 01:09:57.450 I'm going quickly. 01:09:57.450 --> 01:10:01.080 But it's hard to get too excited about bulleted lists and such. 01:10:01.080 --> 01:10:06.300 But any questions on these tags thus far? 01:10:06.300 --> 01:10:09.670 We'll by design try to escalate quickly momentarily. 01:10:09.670 --> 01:10:10.230 All right. 01:10:10.230 --> 01:10:14.340 So how about just a few other tags to make things more visually interesting? 01:10:14.340 --> 01:10:18.030 Let me go ahead here and cheat by opening up a file 01:10:18.030 --> 01:10:21.940 that I made in advance that's going to demonstrate what a table looks like. 01:10:21.940 --> 01:10:25.650 So here let me open a file that I brought with me called table.html. 01:10:25.650 --> 01:10:29.220 And because I brought it with me, I actually included a comment at the top. 01:10:29.220 --> 01:10:31.720 And in fact, if you download today's files from the website, 01:10:31.720 --> 01:10:33.630 you'll see that they're generally commented, 01:10:33.630 --> 01:10:35.640 like our C code and Python code was. 01:10:35.640 --> 01:10:36.660 It's a little weird. 01:10:36.660 --> 01:10:39.720 But here is the syntax for a comment in HTML. 01:10:39.720 --> 01:10:45.140 It's a less than sign, or open bracket, then an exclamation point, then dash 01:10:45.140 --> 01:10:46.470 dash, two hyphens. 01:10:46.470 --> 01:10:50.910 Then at the very end of the comment, it's almost the opposite but not quite. 01:10:50.910 --> 01:10:53.160 It's hyphen hyphen close bracket instead. 01:10:53.160 --> 01:10:54.840 Why these symbols? 01:10:54.840 --> 01:10:56.940 Humans probably decided years ago that there's 01:10:56.940 --> 01:11:00.420 no way someone's going to accidentally type or rather, intentionally 01:11:00.420 --> 01:11:02.110 type those characters visually. 01:11:02.110 --> 01:11:04.260 So let's use them for comment symbols as well. 01:11:04.260 --> 01:11:06.760 If you really want to type them, there is a way around that. 01:11:06.760 --> 01:11:08.890 But here is my table title. 01:11:08.890 --> 01:11:12.910 And here is just kind of a little, maybe, guessing game. 01:11:12.910 --> 01:11:16.870 Here is a table tag with a tr child. 01:11:16.870 --> 01:11:18.550 And here's the closed child. 01:11:18.550 --> 01:11:20.980 And then there's a bunch of td tags. 01:11:20.980 --> 01:11:23.920 So I'll give you tr stands for table row. 01:11:23.920 --> 01:11:28.090 td stands for table data, AKA cell, to borrow language 01:11:28.090 --> 01:11:29.950 from, like, spreadsheet software. 01:11:29.950 --> 01:11:32.050 Does anyone want to guess what this file is 01:11:32.050 --> 01:11:37.603 going to look like if I open table.html in my browser? 01:11:37.603 --> 01:11:38.770 What is this reminiscent of? 01:11:38.770 --> 01:11:39.400 Yeah? 01:11:39.400 --> 01:11:40.150 AUDIENCE: Num pad. 01:11:40.150 --> 01:11:40.540 DAVID MALAN: Yeah. 01:11:40.540 --> 01:11:42.603 So it's like a numeric keypad from a phone, 01:11:42.603 --> 01:11:45.020 for instance, if you're dialing someone's number manually. 01:11:45.020 --> 01:11:46.870 So let me actually go to my other tab. 01:11:46.870 --> 01:11:49.030 Go back to my directory index. 01:11:49.030 --> 01:11:50.385 There's table.html. 01:11:50.385 --> 01:11:52.010 And it's not going to look very pretty. 01:11:52.010 --> 01:11:54.293 But it is structured in the way I might expect. 01:11:54.293 --> 01:11:56.710 And in my browser, I'm going to go ahead and just zoom in. 01:11:56.710 --> 01:11:59.080 Command plus or Control plus will generally do this. 01:11:59.080 --> 01:12:02.530 It does look like it's laid out tabular in rows and columns 01:12:02.530 --> 01:12:04.360 with everything very nicely aligned. 01:12:04.360 --> 01:12:07.510 So that might be useful as we get to larger and larger data sets. 01:12:07.510 --> 01:12:09.350 Let me go back to VS Code here. 01:12:09.350 --> 01:12:12.130 Let me create one more program, for instance. 01:12:12.130 --> 01:12:15.130 And how about code image.html? 01:12:15.130 --> 01:12:18.040 And just to save time, let me paste that code. 01:12:18.040 --> 01:12:21.550 And also, let me secretly copy over a file 01:12:21.550 --> 01:12:23.860 that I brought with me that we've seen in the past. 01:12:23.860 --> 01:12:25.360 Let me close my terminal. 01:12:25.360 --> 01:12:28.593 I'm going to delete everything about tables from this file 01:12:28.593 --> 01:12:30.760 because I'm just saving time by copying and pasting. 01:12:30.760 --> 01:12:32.553 But I'm going to rename the top to image. 01:12:32.553 --> 01:12:35.470 I'm going to get rid of the comment because it's no longer applicable. 01:12:35.470 --> 01:12:40.250 But in the body of this page, I'm going to link to maybe an image of the Weeks 01:12:40.250 --> 01:12:41.540 bridge by the river. 01:12:41.540 --> 01:12:45.200 So I'm going to use an image tag, img for short. 01:12:45.200 --> 01:12:49.850 And now, huh, it's obviously not going to be sufficient to just say image tag. 01:12:49.850 --> 01:12:50.940 Because what image? 01:12:50.940 --> 01:12:53.690 So here is where attributes, again, get useful. 01:12:53.690 --> 01:12:56.570 This attribute earlier, though I didn't quite highlight it, 01:12:56.570 --> 01:12:59.930 seems to indicate that this page is largely in English, as have 01:12:59.930 --> 01:13:01.910 been my past ones, the Latin one aside. 01:13:01.910 --> 01:13:07.190 That attribute on the HTML tag is useful for browsers that have Google Translate 01:13:07.190 --> 01:13:08.760 or something similar built in. 01:13:08.760 --> 01:13:11.630 And also, it's useful for SEO, search engine optimization. 01:13:11.630 --> 01:13:14.030 Because when Google and Bing sort of automatically 01:13:14.030 --> 01:13:17.090 crawl my web page in the future, they'll know what language 01:13:17.090 --> 01:13:20.720 I intend for most of the content to be in, which might help them index 01:13:20.720 --> 01:13:22.770 it and keep track of it for search results. 01:13:22.770 --> 01:13:26.330 So here, for the image tag, I'm similarly going to need an attribute. 01:13:26.330 --> 01:13:29.370 And that attribute is called source, src for short. 01:13:29.370 --> 01:13:32.990 And what you put inside of its quotes for its value, double quotes 01:13:32.990 --> 01:13:36.600 or single quotes, is the name of the image that you want to include. 01:13:36.600 --> 01:13:39.020 And I include it in advance in my code space, 01:13:39.020 --> 01:13:43.800 a file called bridge dot ping from Week 4 when we played around with images. 01:13:43.800 --> 01:13:48.710 And if I go ahead now and go to my other tab, go back to my directory index 01:13:48.710 --> 01:13:52.460 and zoom out, you'll see now not only bridge.png, 01:13:52.460 --> 01:13:55.640 portable network graphic, which I manually copied in, but also 01:13:55.640 --> 01:13:57.950 image.html, which I just created. 01:13:57.950 --> 01:14:01.220 And voila, here is that same Weeks bridge. 01:14:01.220 --> 01:14:03.300 It's a little too big for my browser window. 01:14:03.300 --> 01:14:06.380 We'll see in a little bit how we can fix things like that. 01:14:06.380 --> 01:14:10.850 But indeed, that's an image that's now embedded into the page. 01:14:10.850 --> 01:14:13.460 But notice, if this image were ever broken, 01:14:13.460 --> 01:14:17.180 or if I had visual difficulties such that I might have screen reader 01:14:17.180 --> 01:14:19.250 software for accessibility installed, it's 01:14:19.250 --> 01:14:22.610 generally good practice to also make sure 01:14:22.610 --> 01:14:24.510 that pages are accessible as possible. 01:14:24.510 --> 01:14:27.560 And so some tags have additional attributes you can include. 01:14:27.560 --> 01:14:29.390 Like, for an image here, there's actually 01:14:29.390 --> 01:14:32.840 an Alt attribute that specifies alternative text 01:14:32.840 --> 01:14:34.070 to describe this image. 01:14:34.070 --> 01:14:36.080 This is what a human would see if they have 01:14:36.080 --> 01:14:37.640 a very slow interconnect connection. 01:14:37.640 --> 01:14:40.880 And before the image downloads, they can see this alternative text. 01:14:40.880 --> 01:14:43.310 Or if I'm blind, I need a screen reader, I 01:14:43.310 --> 01:14:47.000 could have these words recited to me verbally by providing this clue. 01:14:47.000 --> 01:14:50.780 So it's best practice to include this, like, photo of bridge 01:14:50.780 --> 01:14:54.660 so that all users can know what they're looking at, clicking on, or the like, 01:14:54.660 --> 01:14:56.460 so keeping that in mind, too. 01:14:56.460 --> 01:14:56.960 All right. 01:14:56.960 --> 01:14:59.210 Let's do one other piece of multimedia. 01:14:59.210 --> 01:15:01.340 Let me close these two tabs. 01:15:01.340 --> 01:15:06.290 Let me open my terminal and open up a file called video.html. 01:15:06.290 --> 01:15:10.970 Let me go ahead and copy, secretly, a file called video.mp4, 01:15:10.970 --> 01:15:15.020 which is a common video file format, and close my terminal window 01:15:15.020 --> 01:15:18.470 and go ahead and paste in here some HTML from before. 01:15:18.470 --> 01:15:23.120 But let's now embed a video file, as you might if making a video-based website. 01:15:23.120 --> 01:15:25.220 Let me rename this one, too, to video. 01:15:25.220 --> 01:15:27.890 Let me get rid of the old comment, which is not applicable. 01:15:27.890 --> 01:15:30.410 And it turns out videos are almost as simple. 01:15:30.410 --> 01:15:33.110 There is a video tag. 01:15:33.110 --> 01:15:36.505 There is a bunch of different attributes we can put on that. 01:15:36.505 --> 01:15:38.130 But I'll come back to that in a moment. 01:15:38.130 --> 01:15:42.202 But videos, because you might want to have high resolution, low resolution, 01:15:42.202 --> 01:15:44.910 depending on people's bandwidth, because these things can be big, 01:15:44.910 --> 01:15:47.240 they actually have source children. 01:15:47.240 --> 01:15:52.880 And confusingly, it's actually S-O-U-R-C-E, not S-R-C, in this case. 01:15:52.880 --> 01:15:57.440 And even more annoyingly, it takes an attribute called source.src. 01:15:57.440 --> 01:15:58.730 This is not good design. 01:15:58.730 --> 01:16:01.923 But this is what we're stuck with, video.mp4. 01:16:01.923 --> 01:16:04.340 And then the type of this video, which you could generally 01:16:04.340 --> 01:16:07.550 look up if the browser doesn't recognize it, video/mp4. 01:16:07.550 --> 01:16:10.593 This is what's known as a content type or mime type. 01:16:10.593 --> 01:16:12.260 And then, I can actually configure this. 01:16:12.260 --> 01:16:14.570 And you would only know this by taking a class, reading a book, 01:16:14.570 --> 01:16:16.080 looking at an online reference. 01:16:16.080 --> 01:16:19.610 I can actually add some video controls to the website, 01:16:19.610 --> 01:16:21.800 like a Play button, a Pause button, and all of that. 01:16:21.800 --> 01:16:24.530 I can mute the video by default. And so this 01:16:24.530 --> 01:16:26.930 is just going to modify the behavior of this video tag. 01:16:26.930 --> 01:16:28.430 But this is anomalous. 01:16:28.430 --> 01:16:32.840 For some attributes, it just doesn't make sense to have values. 01:16:32.840 --> 01:16:36.380 Because muted, it sort of says all the information we need. 01:16:36.380 --> 01:16:38.780 We could do, quote, unquote, "true." 01:16:38.780 --> 01:16:41.690 But humans decided years ago not to bother with that. 01:16:41.690 --> 01:16:44.300 So some attributes do not need value. 01:16:44.300 --> 01:16:46.810 So you do not need equal signs or quotation marks. 01:16:46.810 --> 01:16:49.600 And you would only know this from, say, documentation. 01:16:49.600 --> 01:16:50.440 All right. 01:16:50.440 --> 01:16:52.300 Let me go back to my directory listing. 01:16:52.300 --> 01:16:54.970 Let me go back here to this here. 01:16:54.970 --> 01:16:59.793 You'll see that there's now not only video.mp4, but also video.html. 01:16:59.793 --> 01:17:01.210 I hope you'll forgive me for this. 01:17:01.210 --> 01:17:02.300 There's at least no sound. 01:17:02.300 --> 01:17:05.150 But when I click on this page, it embeds a video here, 01:17:05.150 --> 01:17:07.150 which I can then click on the controls for. 01:17:07.150 --> 01:17:11.180 And you see some short video file playing here, albeit without sound. 01:17:11.180 --> 01:17:11.680 All right. 01:17:11.680 --> 01:17:14.080 None of that, let me go back here to my VS Code. 01:17:14.080 --> 01:17:17.720 And let's play around now with what the web is really known for, 01:17:17.720 --> 01:17:19.210 which is hyperlinks. 01:17:19.210 --> 01:17:22.570 So hypertext markup language, HTML, is all 01:17:22.570 --> 01:17:26.200 about linking one site to another, one page to another. 01:17:26.200 --> 01:17:28.330 And nothing we've done thus far is interactive 01:17:28.330 --> 01:17:30.010 beyond this own video controls. 01:17:30.010 --> 01:17:31.710 So let me go ahead and do this. 01:17:38.500 --> 01:17:41.260 Let me go into VS Code here. 01:17:41.260 --> 01:17:44.590 And let me go ahead and create the simplest of files 01:17:44.590 --> 01:17:46.670 that just allows me to click on a link. 01:17:46.670 --> 01:17:49.360 So let me go ahead and copy this to save time, 01:17:49.360 --> 01:17:51.280 open up VS code's terminal window. 01:17:51.280 --> 01:17:54.070 Code a file called link.html. 01:17:54.070 --> 01:17:55.240 I'll close my terminal. 01:17:55.240 --> 01:17:56.110 Paste this code. 01:17:56.110 --> 01:17:57.610 Rename video to link. 01:17:57.610 --> 01:17:59.410 Get rid of the actual video tag. 01:17:59.410 --> 01:18:02.710 And in the body of this page, let's do something simple like invite people 01:18:02.710 --> 01:18:06.380 to visit, for instance, Harvard. 01:18:06.380 --> 01:18:06.880 All right. 01:18:06.880 --> 01:18:11.800 If I now go to my directory index and reload, we'll now see link.html. 01:18:11.800 --> 01:18:15.250 And of course, this doesn't really do anything useful, 01:18:15.250 --> 01:18:17.480 because I literally just used English text. 01:18:17.480 --> 01:18:17.980 All right. 01:18:17.980 --> 01:18:20.147 Well, what if I do what you're in the habit of doing 01:18:20.147 --> 01:18:25.180 on social media and various websites, visit harvard.edu. 01:18:25.180 --> 01:18:27.580 Let me go back to the web page, reload. 01:18:27.580 --> 01:18:28.750 The text changes. 01:18:28.750 --> 01:18:31.180 But it's clearly not automatically linking. 01:18:31.180 --> 01:18:32.830 I still can't click on this. 01:18:32.830 --> 01:18:33.340 All right. 01:18:33.340 --> 01:18:36.670 Well, maybe it needs to be www.harvard.edu. 01:18:36.670 --> 01:18:38.930 Let me go back, reload. 01:18:38.930 --> 01:18:39.430 All right. 01:18:39.430 --> 01:18:40.690 Still not auto linking. 01:18:40.690 --> 01:18:41.530 Let me go over here. 01:18:41.530 --> 01:18:46.300 And maybe it needs https:// and a slash at the end, like a full URL. 01:18:46.300 --> 01:18:47.980 Let's go over here, reload. 01:18:47.980 --> 01:18:49.720 And it's still not working. 01:18:49.720 --> 01:18:52.600 I can highlight and copy it, but that's not very user friendly. 01:18:52.600 --> 01:18:53.680 So what's going on? 01:18:53.680 --> 01:18:57.490 Well, all of today's social media sites, when you copy paste a URL, 01:18:57.490 --> 01:19:00.640 someone at the server side wrote code, be it 01:19:00.640 --> 01:19:03.100 in Python or JavaScript or anything else, 01:19:03.100 --> 01:19:06.580 to automatically notice and detect URLs and then 01:19:06.580 --> 01:19:11.330 wrap them with HTML tags that actually hyperlink them. 01:19:11.330 --> 01:19:14.200 So what I actually need to do here is this. 01:19:14.200 --> 01:19:18.290 I'm going to introduce an anchor tag, a for short. 01:19:18.290 --> 01:19:21.610 The hyper reference attribute of which is the URL that I want 01:19:21.610 --> 01:19:25.180 to send the user to, so href for short. 01:19:25.180 --> 01:19:26.830 I'm going to close the tag. 01:19:26.830 --> 01:19:29.920 But then, in between the start tag and close tag, 01:19:29.920 --> 01:19:33.650 I'm now going to put the text that I want the human to see. 01:19:33.650 --> 01:19:35.740 So it's a lot more verbose. 01:19:35.740 --> 01:19:38.770 But this is what websites like social media sites 01:19:38.770 --> 01:19:42.850 are generating automatically for you when they just detect with a pattern 01:19:42.850 --> 01:19:45.940 that you have typed something that indeed looks like a URL. 01:19:45.940 --> 01:19:47.440 Let me go back to VS Code. 01:19:47.440 --> 01:19:49.460 Let me go back to this tab here and reload. 01:19:49.460 --> 01:19:52.990 And now we actually see a working link. 01:19:52.990 --> 01:19:54.530 And this is going to be super small. 01:19:54.530 --> 01:19:56.090 You're not going to be able to see this quite well. 01:19:56.090 --> 01:19:59.140 But if you hover over this link, you'll generally see in most browsers 01:19:59.140 --> 01:20:01.630 a little clue at the bottom as to where you're going 01:20:01.630 --> 01:20:03.320 to be directed before you click there. 01:20:03.320 --> 01:20:04.870 This can help if you're a little suspicious 01:20:04.870 --> 01:20:06.610 and might not want to click on the actual link. 01:20:06.610 --> 01:20:09.152 It's small on my screen, but hopefully more visible on yours. 01:20:09.152 --> 01:20:13.070 That's not generally the case on mobile in quite, though, the same way. 01:20:13.070 --> 01:20:16.810 But notice that this very simple primitive of anchor tags like this 01:20:16.810 --> 01:20:20.440 can pretty quickly be abused, unfortunately. 01:20:20.440 --> 01:20:24.340 In fact, let me go ahead here and go back to VS Code. 01:20:24.340 --> 01:20:26.590 And I could do something malicious like this, 01:20:26.590 --> 01:20:30.430 like, actually trick someone into applying to Harvard instead of Yale 01:20:30.430 --> 01:20:35.180 by just changing the href to not match the text that the human is seeing. 01:20:35.180 --> 01:20:37.300 And if I reload the page here, you'll see 01:20:37.300 --> 01:20:39.070 that it looks like I'm going to Yale. 01:20:39.070 --> 01:20:42.190 But notice, super small, bottom left-hand of my screen, 01:20:42.190 --> 01:20:44.050 it still says the real URL. 01:20:44.050 --> 01:20:45.880 But you can get even more malicious. 01:20:45.880 --> 01:20:47.020 You can not just say Yale. 01:20:47.020 --> 01:20:50.800 You could literally say https://www.yale.edu/. 01:20:50.800 --> 01:20:54.460 You can make it look like a real URL, reload it. 01:20:54.460 --> 01:20:57.220 And now it's really quite malicious. 01:20:57.220 --> 01:21:00.940 And this is representative of what you all probably know already as phishing 01:21:00.940 --> 01:21:05.650 attacks, P-H-I-S-H-I-N-G, whereby you're being socially engineered. 01:21:05.650 --> 01:21:07.990 People are trying to dupe you into clicking something 01:21:07.990 --> 01:21:10.720 that leads you to your PayPal account, typically, 01:21:10.720 --> 01:21:12.970 so that you log into some bogus website. 01:21:12.970 --> 01:21:16.150 Now you've given them access to your account and you're out some money. 01:21:16.150 --> 01:21:19.090 It's this simple because of, unfortunately, 01:21:19.090 --> 01:21:22.780 these building blocks of HTML. 01:21:22.780 --> 01:21:23.410 All right. 01:21:23.410 --> 01:21:29.100 With that said, any questions on this? 01:21:29.100 --> 01:21:29.600 No? 01:21:29.600 --> 01:21:30.100 All right. 01:21:30.100 --> 01:21:34.640 How about just for one final flourish before snacks will be served, 01:21:34.640 --> 01:21:39.500 let me propose to introduce some final features herein. 01:21:39.500 --> 01:21:42.830 It turns out, and I'll open some of these premade already. 01:21:42.830 --> 01:21:48.050 Let me open up VS Code and open up a file called meta0.html. 01:21:48.050 --> 01:21:51.410 This has nothing to do with Meta, the social media company. 01:21:51.410 --> 01:21:55.070 It has to do with metadata, or specifically, meta tag. 01:21:55.070 --> 01:21:58.470 It turns out that in the head of the web pages that we've written thus far, 01:21:58.470 --> 01:21:59.630 we've only had titles. 01:21:59.630 --> 01:22:02.120 But it turns out there's actually literally a tag 01:22:02.120 --> 01:22:06.110 called meta that has a couple of attributes like name and content. 01:22:06.110 --> 01:22:09.530 And this one here, it's a little arcane, but it's very common 01:22:09.530 --> 01:22:12.500 to copy paste these into the source code for websites 01:22:12.500 --> 01:22:15.680 nowadays because essentially, this makes them mobile friendly. 01:22:15.680 --> 01:22:18.410 Instead of making the font some default small size, 01:22:18.410 --> 01:22:21.050 it will take into account the width of the phone 01:22:21.050 --> 01:22:24.090 or the tablet and sort of scale the font proportionally. 01:22:24.090 --> 01:22:27.650 So there's some useful accessibility and user friendly tips like this. 01:22:27.650 --> 01:22:30.970 There's other use cases for meta tags like this. 01:22:30.970 --> 01:22:34.590 Let me open a file called meta1.html that I made in advance. 01:22:34.590 --> 01:22:38.070 Here are three meta tags inside of this file. 01:22:38.070 --> 01:22:42.460 They're using a property attribute with a content attribute as well. 01:22:42.460 --> 01:22:44.220 And this is a little more specific. 01:22:44.220 --> 01:22:47.160 But nowadays, too, on social media, when you copy and paste 01:22:47.160 --> 01:22:50.400 a URL into a message online and hit Enter, 01:22:50.400 --> 01:22:52.638 you very often see a preview of that link. 01:22:52.638 --> 01:22:54.180 It's sort of automatically generated. 01:22:54.180 --> 01:22:56.880 It makes a nice pretty image and some nice fonts. 01:22:56.880 --> 01:22:58.750 Where does that image come from? 01:22:58.750 --> 01:23:00.765 Where does that information come from? 01:23:00.765 --> 01:23:04.740 From these meta tags, any web page can have meta tags like this 01:23:04.740 --> 01:23:07.590 so that when this page's URL is copy pasted 01:23:07.590 --> 01:23:10.440 into social media sites or others, those sites 01:23:10.440 --> 01:23:13.080 know what preview to show to humans. 01:23:13.080 --> 01:23:15.960 It comes literally from the values of these tags. 01:23:15.960 --> 01:23:18.690 So for instance, this would create some user friendly preview 01:23:18.690 --> 01:23:21.292 that says CS50, Introduction to The Intellectual Enterprises 01:23:21.292 --> 01:23:23.250 of Computer Science and The Art of Programming. 01:23:23.250 --> 01:23:25.710 And in this case, it would show a picture of a cat 01:23:25.710 --> 01:23:28.230 as the default image for that particular page. 01:23:28.230 --> 01:23:33.330 You have full control as a web developer over those kinds of things. 01:23:33.330 --> 01:23:39.810 Lastly, when it comes to features of HTML, let's go ahead and quickly 01:23:39.810 --> 01:23:41.580 reimplement Google, if we may. 01:23:41.580 --> 01:23:47.550 So let me go ahead and create a new file here called search.html. 01:23:47.550 --> 01:23:50.050 Let me copy paste some code to save time. 01:23:50.050 --> 01:23:53.580 Let me go ahead and get rid of all of these meta 01:23:53.580 --> 01:23:55.890 tags to make a different point with this one. 01:23:55.890 --> 01:23:57.390 Let me get rid of that comment. 01:23:57.390 --> 01:24:01.950 Change this title to be, say, search instead. 01:24:01.950 --> 01:24:04.470 And inside of the body here, let's do this. 01:24:04.470 --> 01:24:06.480 I'm going to introduce a form tag. 01:24:06.480 --> 01:24:10.650 And now in the form tag, I'm going to create an input, a text input. 01:24:10.650 --> 01:24:15.240 And let's go ahead and let's just say that. 01:24:15.240 --> 01:24:18.670 And now I'm going to have a button that has, 01:24:18.670 --> 01:24:25.770 let's say, button, that has a value of search, so super simple and not yet 01:24:25.770 --> 01:24:26.280 complete. 01:24:26.280 --> 01:24:29.220 But let me go to my directory index and back. 01:24:29.220 --> 01:24:31.260 Let me open up search.html. 01:24:31.260 --> 01:24:33.420 And I actually have the beginnings of a search 01:24:33.420 --> 01:24:35.692 form, an interactive form for the web. 01:24:35.692 --> 01:24:37.650 But it doesn't actually do anything useful yet. 01:24:37.650 --> 01:24:38.680 But let me do this. 01:24:38.680 --> 01:24:41.040 Let me go to the actual google.com. 01:24:41.040 --> 01:24:43.748 Let me search for something like cats, C-A-T-S. 01:24:43.748 --> 01:24:46.290 And of course, we're going to see a whole bunch of cats here. 01:24:46.290 --> 01:24:50.100 And we're going to see that the search box was automatically 01:24:50.100 --> 01:24:52.180 populated at the very top of the page. 01:24:52.180 --> 01:24:55.020 Now the URL that Google led me to, even though I 01:24:55.020 --> 01:24:59.062 started at the very simple google.com, is actually pretty long. 01:24:59.062 --> 01:25:01.770 And I'm going to frankly just delete anything I don't understand. 01:25:01.770 --> 01:25:05.340 Because I'm going to distill this URL to just this one here. 01:25:05.340 --> 01:25:09.150 It turns out that in URLs you can also put user input 01:25:09.150 --> 01:25:11.080 in the form of key value pairs. 01:25:11.080 --> 01:25:14.610 So in any URL, you can actually have not only a path 01:25:14.610 --> 01:25:18.780 like we saw earlier, you can have a path with a key 01:25:18.780 --> 01:25:21.672 and a value prefixed with a single question mark. 01:25:21.672 --> 01:25:23.880 And in fact, if you want to have two keys and values, 01:25:23.880 --> 01:25:27.070 you just interpose them with an ampersand instead. 01:25:27.070 --> 01:25:30.690 So this is to say there is a standard way in HTML 01:25:30.690 --> 01:25:35.065 and really HTTP for sending input from a browser to a server. 01:25:35.065 --> 01:25:36.690 And it's generally formatted like this. 01:25:36.690 --> 01:25:39.180 What this means is actually this. 01:25:39.180 --> 01:25:42.190 Let me zoom out, close that tab, and open a brand new one. 01:25:42.190 --> 01:25:44.760 And let me manually go to-- and I'll zoom 01:25:44.760 --> 01:25:53.880 in-- https://wwww.google.com/search?q=dogs. 01:25:53.880 --> 01:25:56.940 Now it has to be q, because that's what Larry and Sergey of Google fame 01:25:56.940 --> 01:25:59.940 decided two decades ago when they made Google itself. 01:25:59.940 --> 01:26:01.140 Q stands for query. 01:26:01.140 --> 01:26:03.460 But they could have called that key anything they want. 01:26:03.460 --> 01:26:05.520 I'm going to hit Enter after zooming out. 01:26:05.520 --> 01:26:08.850 And what you'll see is that I don't need google.com to search for me. 01:26:08.850 --> 01:26:13.735 I can literally go to a URL of all of the dog search results manually. 01:26:13.735 --> 01:26:15.360 Now no one's normally going to do that. 01:26:15.360 --> 01:26:16.200 That makes no sense. 01:26:16.200 --> 01:26:20.100 But it does suggest how simple the mechanics of the web are. 01:26:20.100 --> 01:26:23.850 If you want to pass input to a server, you suffix the URL 01:26:23.850 --> 01:26:26.370 with a question mark, key equals value. 01:26:26.370 --> 01:26:30.480 Key equals value may be separated you buy these ampersands, as I proposed. 01:26:30.480 --> 01:26:31.870 So what does this mean? 01:26:31.870 --> 01:26:34.890 Well, Google really did the hard part, the back end, the database. 01:26:34.890 --> 01:26:37.590 They crawled the internet and found all of these cats and dogs. 01:26:37.590 --> 01:26:39.810 But I can make the front end, that is the user 01:26:39.810 --> 01:26:41.640 interface that still works for it. 01:26:41.640 --> 01:26:42.930 And I'm going to do this. 01:26:42.930 --> 01:26:45.600 I'm going to add an attribute to my form tag that 01:26:45.600 --> 01:26:55.140 specifies an action attribute of https://www.google.com/search. 01:26:55.140 --> 01:26:58.140 And I'm going to specify that the method I want the browser to use 01:26:58.140 --> 01:26:59.010 is indeed get. 01:26:59.010 --> 01:27:00.120 This is inconsistent. 01:27:00.120 --> 01:27:02.730 I capitalized it as all caps before. 01:27:02.730 --> 01:27:04.793 In HTML, you actually do it as lowercase. 01:27:04.793 --> 01:27:06.960 But that's also the default. So strictly speaking, I 01:27:06.960 --> 01:27:08.380 don't even need to specify that. 01:27:08.380 --> 01:27:10.440 But I will, just to be pedantic. 01:27:10.440 --> 01:27:13.260 Inside of my input, my text box, which used 01:27:13.260 --> 01:27:15.700 to look like this, just a big white rectangle, 01:27:15.700 --> 01:27:18.330 I'm going to actually give it a name of q, because I 01:27:18.330 --> 01:27:20.310 know that's what Google servers expect. 01:27:20.310 --> 01:27:24.900 And I'm also going to specify-- 01:27:24.900 --> 01:27:26.100 eh, just that for now. 01:27:26.100 --> 01:27:28.130 Let me go back now and reload. 01:27:28.130 --> 01:27:30.200 And it's going to still look very simple. 01:27:30.200 --> 01:27:31.100 But notice this. 01:27:31.100 --> 01:27:35.390 If I type in cats and click Search, in just a moment, 01:27:35.390 --> 01:27:39.380 I'm going to be whisked away from my own Codespaces URL ending 01:27:39.380 --> 01:27:45.980 in search.html to, after zooming out and clicking Search, the actual google.com. 01:27:45.980 --> 01:27:50.060 Which prepopulates the URL with q equals cats up top, 01:27:50.060 --> 01:27:52.950 prepopulates this text box with the user's input, 01:27:52.950 --> 01:27:57.080 which is to say, like, the front end of google.com is trivial, 01:27:57.080 --> 01:27:58.730 as is most every website. 01:27:58.730 --> 01:28:03.477 It's as simple as these key value pairs and things like web forms like that. 01:28:03.477 --> 01:28:05.060 Now I can make this a little prettier. 01:28:05.060 --> 01:28:08.630 And just so you've seen it, if I specified that the type of this input 01:28:08.630 --> 01:28:11.720 isn't text, which is the default, but is search, 01:28:11.720 --> 01:28:13.140 I actually get some nice features. 01:28:13.140 --> 01:28:14.390 Let me reload this now. 01:28:14.390 --> 01:28:17.360 And if I start typing in, like, dogs, now I get this little x 01:28:17.360 --> 01:28:18.570 to click, which clears it. 01:28:18.570 --> 01:28:19.862 So a lot of websites have that. 01:28:19.862 --> 01:28:21.170 It's a little bit of a nicety. 01:28:21.170 --> 01:28:23.393 If you don't know what you want the user to type in, 01:28:23.393 --> 01:28:25.310 you can actually be kind of explicit for them. 01:28:25.310 --> 01:28:29.573 And you can add a placeholder attribute that says query or keywords 01:28:29.573 --> 01:28:30.990 or whatever you want to show them. 01:28:30.990 --> 01:28:33.420 If I go back to the browser and reload, you'll 01:28:33.420 --> 01:28:36.270 see a grayed out text that's not actually there. 01:28:36.270 --> 01:28:38.710 It goes away if I type in bird, for instance. 01:28:38.710 --> 01:28:41.610 But it's explanatory, placeholder text for the user. 01:28:41.610 --> 01:28:45.330 You'll notice that it wants to autocomplete cats or bird or dog 01:28:45.330 --> 01:28:46.770 or anything I've typed before. 01:28:46.770 --> 01:28:48.030 You can disable that. 01:28:48.030 --> 01:28:51.930 There is an attribute called autocomplete 01:28:51.930 --> 01:28:55.830 whose value can be either on, which is default, or off, which 01:28:55.830 --> 01:28:57.510 can be explicitly specified. 01:28:57.510 --> 01:28:58.770 And notice this, too. 01:28:58.770 --> 01:29:03.030 When I reload the page, it's actually annoying in terms of user experience. 01:29:03.030 --> 01:29:05.610 Before I can search for anything, I have to move my cursor, 01:29:05.610 --> 01:29:06.990 I have to click in the text box. 01:29:06.990 --> 01:29:08.850 And now it has focus, so to speak. 01:29:08.850 --> 01:29:11.160 It gets highlighted in some color, usually blue. 01:29:11.160 --> 01:29:12.570 That's not the best website. 01:29:12.570 --> 01:29:15.750 Why are you making the users pick up their mouse or their trackpad just 01:29:15.750 --> 01:29:18.270 to click on the only thing they're going to do anyway? 01:29:18.270 --> 01:29:20.670 So there's another attribute that's handy, 01:29:20.670 --> 01:29:24.795 Auto Focus, which will just move the cursor there for the user. 01:29:24.795 --> 01:29:27.420 So this is to say, even though a lot of websites don't do this, 01:29:27.420 --> 01:29:30.300 there's a lot of functionality that you can enable by just 01:29:30.300 --> 01:29:32.700 knowing the language all the more. 01:29:32.700 --> 01:29:36.120 So with that, we now have a pretty useful feature. 01:29:36.120 --> 01:29:38.550 In fact, heck, I can say this is Google Search, 01:29:38.550 --> 01:29:41.230 change the value of that button, reload. 01:29:41.230 --> 01:29:45.570 And now I'll go ahead and type in birds, Enter, and voila. 01:29:45.570 --> 01:29:49.450 Now we have a whole bunch of birds as well. 01:29:49.450 --> 01:29:50.852 So that's a lot. 01:29:50.852 --> 01:29:52.560 I think it's definitely time for a snack. 01:29:52.560 --> 01:29:53.890 So let's take a 10-minute break for a snack. 01:29:53.890 --> 01:29:56.730 And when we come back, we'll make all of this look prettier. 01:29:56.730 --> 01:29:57.810 All right. 01:29:57.810 --> 01:29:59.220 So we are back. 01:29:59.220 --> 01:30:02.520 And it was brought to my attention during break 01:30:02.520 --> 01:30:05.730 that we were pretty darn close to clearing one of these rows. 01:30:05.730 --> 01:30:09.120 And I will concede that your classmates, Darwin and Jude, 01:30:09.120 --> 01:30:12.450 socially engineered me into saying one of the remaining squares 01:30:12.450 --> 01:30:13.270 that they needed. 01:30:13.270 --> 01:30:17.100 And so I'm sad to say that bingo was declared during break, which Carter 01:30:17.100 --> 01:30:19.530 has already confirmed, because I was tricked into giving 01:30:19.530 --> 01:30:21.840 a long answer to a short question. 01:30:21.840 --> 01:30:24.030 So congratulations to those two. 01:30:24.030 --> 01:30:29.430 I do dare say, too, that whole bit with safetyschool.org probably 01:30:29.430 --> 01:30:30.990 isn't going over well in New Haven. 01:30:30.990 --> 01:30:33.210 So I'm pretty sure we can check off this box here. 01:30:33.210 --> 01:30:37.550 However, as promised, in fairness, since we love them both equally, 01:30:37.550 --> 01:30:42.120 I thought it only fair to resume now with a look at perhaps one of the best 01:30:42.120 --> 01:30:44.940 Harvard-Yale pranks that was actually on us, 01:30:44.940 --> 01:30:50.880 with this 2.5-minute glimpse at how our classmates at Yale pranked Harvard some 01:30:50.880 --> 01:30:51.390 years back. 01:30:51.390 --> 01:30:53.580 If we could dim the lights now for this. 01:30:53.580 --> 01:30:54.570 [VIDEO PLAYBACK] 01:30:54.570 --> 01:30:57.540 [MUSIC PLAYING] 01:31:16.845 --> 01:31:17.835 [CHEERING] 01:31:17.835 --> 01:31:21.300 [BAND MUSIC PLAYING] 01:31:23.975 --> 01:31:26.100 - All the way at the top and then you pass it down. 01:31:26.100 --> 01:31:26.642 [CROWD NOISE] 01:31:26.642 --> 01:31:29.230 - [INAUDIBLE] this for you, Yale. 01:31:29.230 --> 01:31:30.430 We love you, Yale. 01:31:30.430 --> 01:31:32.790 - We're here to cheer for Harvard. 01:31:32.790 --> 01:31:33.478 - Yeah! 01:31:33.478 --> 01:31:34.374 Go Harvard! 01:31:34.374 --> 01:31:36.170 - Go Harvard! 01:31:36.170 --> 01:31:37.790 - [INAUDIBLE] one and pass it down? 01:31:37.790 --> 01:31:40.250 - Pass them down. 01:31:40.250 --> 01:31:41.834 - Great. 01:31:41.834 --> 01:31:44.030 - It says go Harvard. 01:31:44.030 --> 01:31:45.650 - We're nice. 01:31:45.650 --> 01:31:47.092 - You see that [BLEEP]? 01:31:47.092 --> 01:31:48.054 - Look at them. 01:31:48.054 --> 01:31:49.020 They have the paper! 01:31:49.020 --> 01:31:51.688 - It's going to happen. 01:31:51.688 --> 01:31:54.320 - It's actually gonna happen! 01:31:54.320 --> 01:31:55.670 - I can't [BLEEP] believe this! 01:31:55.670 --> 01:31:57.770 - What do you think of Yale? 01:31:57.770 --> 01:31:58.910 - They don't think good. 01:31:58.910 --> 01:31:59.426 [LAUGHTER] 01:31:59.426 --> 01:32:00.593 - It may be a complete mess. 01:32:00.593 --> 01:32:02.540 I don't know. 01:32:02.540 --> 01:32:03.790 - Dude, does everyone have it? 01:32:03.790 --> 01:32:05.080 Does everyone have their stuff? 01:32:05.080 --> 01:32:06.320 Does everyone have their stuff? 01:32:06.320 --> 01:32:09.320 - The probability that it's going to be legible it's very small, though. 01:32:09.320 --> 01:32:10.278 - I agree. 01:32:10.278 --> 01:32:11.236 - It's too complicated. 01:32:11.236 --> 01:32:12.190 - [INAUDIBLE]. 01:32:12.190 --> 01:32:12.760 - I know. 01:32:12.760 --> 01:32:14.280 But it's too complicated. 01:32:14.280 --> 01:32:16.307 - What houses are you guys in? 01:32:16.307 --> 01:32:16.890 - [INAUDIBLE]. 01:32:16.890 --> 01:32:17.790 - That's not a real house. 01:32:17.790 --> 01:32:18.990 - How many extra are there? 01:32:18.990 --> 01:32:19.350 - Ho-fo. 01:32:19.350 --> 01:32:19.850 - Yeah. 01:32:22.603 --> 01:32:24.270 - You guys aren't from Harvard, are you? 01:32:24.270 --> 01:32:26.010 - Fo-ho. 01:32:26.010 --> 01:32:26.850 - Pforzheimer. 01:32:26.850 --> 01:32:28.000 - Yeah, but you said ho-fi. 01:32:28.000 --> 01:32:28.830 - Just make sure everyone has it. 01:32:28.830 --> 01:32:30.020 - Well, she's probably drunk. 01:32:30.020 --> 01:32:31.185 - It looks like they're still passing. 01:32:31.185 --> 01:32:32.734 Are all the cards distributed? 01:32:32.734 --> 01:32:34.090 - [INAUDIBLE]. 01:32:34.090 --> 01:32:34.590 - All right. 01:32:34.590 --> 01:32:35.589 Let's do it now. 01:32:35.589 --> 01:32:38.523 [CHEERING] 01:32:47.325 --> 01:32:48.792 - Hold up your signs! 01:32:48.792 --> 01:32:50.740 - [BLEEP]. 01:32:50.740 --> 01:32:51.240 [CHANTING] 01:32:51.240 --> 01:32:52.320 - You suck. 01:32:52.320 --> 01:32:53.400 You suck. 01:32:53.400 --> 01:32:54.360 You suck. 01:32:54.360 --> 01:32:55.290 You suck. 01:32:55.290 --> 01:32:56.220 You suck. 01:32:56.220 --> 01:32:57.030 You [BLEEP]. 01:32:57.030 --> 01:32:58.172 - Did it. 01:32:58.172 --> 01:32:58.672 - [BLEEP]. 01:32:58.672 --> 01:32:59.780 - You suck. 01:32:59.780 --> 01:33:00.680 You suck. 01:33:00.680 --> 01:33:01.490 You suck. 01:33:01.490 --> 01:33:02.240 You suck. 01:33:02.240 --> 01:33:02.870 You suck. 01:33:02.870 --> 01:33:05.290 You suck. 01:33:05.290 --> 01:33:07.550 - What do you think of Yale, sir? 01:33:07.550 --> 01:33:08.930 - [INAUDIBLE]. 01:33:08.930 --> 01:33:09.880 - One more time! 01:33:09.880 --> 01:33:10.510 One more time! 01:33:17.880 --> 01:33:20.628 - Oh, and there it goes again! 01:33:20.628 --> 01:33:21.128 [CHANTING] 01:33:21.128 --> 01:33:22.559 - Harvard sucks! 01:33:22.559 --> 01:33:23.990 Harvard sucks! 01:33:23.990 --> 01:33:25.421 Harvard sucks! 01:33:25.421 --> 01:33:27.329 Harvard sucks! 01:33:27.329 --> 01:33:28.760 Harvard sucks! 01:33:28.760 --> 01:33:30.210 Harvard sucks! 01:33:30.210 --> 01:33:30.815 Harvard sucks! 01:33:30.815 --> 01:33:32.037 Harvard sucks! 01:33:32.037 --> 01:33:33.498 Harvard sucks! 01:33:33.498 --> 01:33:34.472 Harvard sucks! 01:33:34.472 --> 01:33:35.837 Harvard sucks! 01:33:35.837 --> 01:33:36.420 Harvard sucks! 01:33:36.420 --> 01:33:37.037 [END PLAYBACK] 01:33:37.037 --> 01:33:38.840 DAVID MALAN: So fair is fair there. 01:33:38.840 --> 01:33:41.740 So now back to some HTML. 01:33:41.740 --> 01:33:44.770 And we will transition momentarily then to this other language, CSS, 01:33:44.770 --> 01:33:47.110 by which we can style things all the more. 01:33:47.110 --> 01:33:51.050 So there's this feature in HTML that's actually present in Python, 01:33:51.050 --> 01:33:53.800 even though we didn't use it yet, and that's present in JavaScript 01:33:53.800 --> 01:33:57.410 and, really, most modern languages known as regular expressions. 01:33:57.410 --> 01:33:59.710 Which is otherwise known as regexes, which 01:33:59.710 --> 01:34:04.660 is a way of using patterns to validate input 01:34:04.660 --> 01:34:06.970 or to extract information from strings. 01:34:06.970 --> 01:34:08.200 And so by that I mean this. 01:34:08.200 --> 01:34:10.640 Let me go over to VS Code here. 01:34:10.640 --> 01:34:14.380 Let me go ahead and create a new file called register.html. 01:34:14.380 --> 01:34:17.890 I'm going to copy paste some code from earlier, just to save some keystrokes. 01:34:17.890 --> 01:34:21.220 And in here, I'm going to go ahead and change my title to register. 01:34:21.220 --> 01:34:24.610 And in my code, I'm going to go ahead and create a very simple form 01:34:24.610 --> 01:34:26.980 representative of a registration form now. 01:34:26.980 --> 01:34:30.525 So in this body, I'm going to do a form tag. 01:34:30.525 --> 01:34:33.650 I'm not going to bother sending it to Google or to any server in particular 01:34:33.650 --> 01:34:34.160 here. 01:34:34.160 --> 01:34:38.480 I'm going to give it an input tag with autocomplete equals off, as before. 01:34:38.480 --> 01:34:40.610 I'm going to have auto focus on as before. 01:34:40.610 --> 01:34:44.957 I'm going to give this form field the name of email this time instead of q. 01:34:44.957 --> 01:34:46.790 I'm going to give it a placeholder of quote, 01:34:46.790 --> 01:34:50.480 unquote "email," just so that the user knows what they're supposed to type. 01:34:50.480 --> 01:34:57.020 And it turns out that browsers have not only type text or search, but also 01:34:57.020 --> 01:35:00.230 type email, whereby you can rely on the browser to ensure that the human has 01:35:00.230 --> 01:35:02.070 actually typed in an email address. 01:35:02.070 --> 01:35:03.440 Now I'm going to go ahead and have a button 01:35:03.440 --> 01:35:05.090 that this time will be called Register. 01:35:05.090 --> 01:35:09.140 And now let's go over to my other tab, reload my directory index. 01:35:09.140 --> 01:35:10.790 There's register.html. 01:35:10.790 --> 01:35:13.490 And we'll see a relatively simple form field now. 01:35:13.490 --> 01:35:16.110 But it's prompting me to register with some email address. 01:35:16.110 --> 01:35:19.730 If I go ahead and sort of type in just my name and try Register, 01:35:19.730 --> 01:35:22.880 you'll notice that the browser sort of yells at me with the built-in error 01:35:22.880 --> 01:35:25.970 message saying, oh, please include an at in the email address. 01:35:25.970 --> 01:35:29.930 And it's pretty good in that if I do mail an at, but nothing more, 01:35:29.930 --> 01:35:33.380 which is also not valid, and try to register, it's telling me still 01:35:33.380 --> 01:35:34.400 that it's incomplete. 01:35:34.400 --> 01:35:39.590 So built into browsers is some defense against incorrect user input 01:35:39.590 --> 01:35:40.640 in this way. 01:35:40.640 --> 01:35:44.240 If I finally do type in malan@harvard.edu and click Register, 01:35:44.240 --> 01:35:47.630 then the form would be submitted successfully to the server. 01:35:47.630 --> 01:35:52.280 If, though, I want to tolerate only .edu addresses because I'm making 01:35:52.280 --> 01:35:55.340 an education-themed website for students in the US, 01:35:55.340 --> 01:35:59.210 I can actually add another attribute here, which is actually quite useful, 01:35:59.210 --> 01:35:59.750 too. 01:35:59.750 --> 01:36:01.940 I can add a pattern attribute. 01:36:01.940 --> 01:36:05.270 And inside of its value, I can put one of these things called 01:36:05.270 --> 01:36:07.190 a regular expression, or a regex. 01:36:07.190 --> 01:36:09.890 That is an actual pattern that the browser 01:36:09.890 --> 01:36:13.310 should match the user's input against and make sure it indeed matches. 01:36:13.310 --> 01:36:15.320 And this is going to look a little cryptic. 01:36:15.320 --> 01:36:17.150 But I'm going to go ahead and do this. 01:36:17.150 --> 01:36:22.850 .+@.+ backslash dot edu. 01:36:22.850 --> 01:36:24.210 Now this looks a little weird. 01:36:24.210 --> 01:36:26.960 But it turns out I'm using certain building blocks that we'll just 01:36:26.960 --> 01:36:28.280 scratch the surface of today. 01:36:28.280 --> 01:36:32.510 But it's an incredibly useful and powerful feature in programming 01:36:32.510 --> 01:36:33.680 languages more generally. 01:36:33.680 --> 01:36:35.862 Because in the world of regular expressions, 01:36:35.862 --> 01:36:37.820 there are certain patterns that mean something. 01:36:37.820 --> 01:36:40.160 And here's a really good URL of some documentation 01:36:40.160 --> 01:36:43.250 they're for in the world of the web and JavaScript, specifically. 01:36:43.250 --> 01:36:46.040 And here's kind of a short cheat sheet, some excerpts thereof. 01:36:46.040 --> 01:36:48.950 It turns out in the world of regular expressions or patterns, 01:36:48.950 --> 01:36:52.820 a dot represents any single character except line terminators, 01:36:52.820 --> 01:36:54.290 like backslash n. 01:36:54.290 --> 01:36:58.850 A star or an asterisk represents 0 or more times. 01:36:58.850 --> 01:37:00.800 A plus means one or more times. 01:37:00.800 --> 01:37:03.230 A question mark means 0 or one time. 01:37:03.230 --> 01:37:07.970 A number inside of curly braces means n times, or n occurrences. 01:37:07.970 --> 01:37:11.150 And then two numbers in curly braces, n comma n, 01:37:11.150 --> 01:37:15.590 means at least n times, but at most, m times or occurrences. 01:37:15.590 --> 01:37:17.330 And then there's a few other, actually. 01:37:17.330 --> 01:37:18.420 So what does that mean? 01:37:18.420 --> 01:37:21.530 Well, let me go over to VS Code again. 01:37:21.530 --> 01:37:24.110 And let me zoom in on the pattern I used. 01:37:24.110 --> 01:37:28.370 And it would seem that, in this case, a dot represents any character. 01:37:28.370 --> 01:37:29.810 Plus means one or more. 01:37:29.810 --> 01:37:34.160 So one or more characters to the left of an sign, then literally the at sign. 01:37:34.160 --> 01:37:38.360 Then another dot plus means one or more characters to the right of the at sign. 01:37:38.360 --> 01:37:42.050 But the whole thing has to end in .edu. 01:37:42.050 --> 01:37:45.830 But there's this additional backslash before the last dot. 01:37:45.830 --> 01:37:48.500 And why might that be, intuitively? 01:37:48.500 --> 01:37:49.820 Even though I've not said? 01:37:49.820 --> 01:37:54.120 Because I want a literal dot, a literal period, not any one character there. 01:37:54.120 --> 01:37:56.180 So I escape the period to make it have not 01:37:56.180 --> 01:37:59.880 special significance per this cheat sheet, but rather a literal period. 01:37:59.880 --> 01:38:03.020 So what this means is if I go actually back to VS Code here 01:38:03.020 --> 01:38:08.000 and I try to claim to work at like malan@harvard.com and click Register, 01:38:08.000 --> 01:38:10.320 that's a valid-looking email address. 01:38:10.320 --> 01:38:11.700 But when I click Register now. 01:38:11.700 --> 01:38:12.200 Whoops! 01:38:12.200 --> 01:38:12.770 Sorry. 01:38:12.770 --> 01:38:16.380 It went through because I did not reload the page after making the change. 01:38:16.380 --> 01:38:17.120 So I screwed up. 01:38:17.120 --> 01:38:21.560 Let me go back to the register.html URL. 01:38:21.560 --> 01:38:26.660 Let me reload the page and type in malan@harvard.com, for instance, 01:38:26.660 --> 01:38:27.860 and even-- sorry. 01:38:27.860 --> 01:38:30.800 Let me type in malan@harvard.com. 01:38:30.800 --> 01:38:35.330 And even though it's a valid-looking URL, it does not in fact and in .edu. 01:38:35.330 --> 01:38:37.890 So the browser can defend against that in this way. 01:38:37.890 --> 01:38:40.370 But the more important takeaway for now is 01:38:40.370 --> 01:38:44.090 that as useful as this is, as user friendly as this, 01:38:44.090 --> 01:38:47.780 this is not generally the best technique for validating user input 01:38:47.780 --> 01:38:50.810 and protecting against invalid user input. 01:38:50.810 --> 01:38:51.590 Why? 01:38:51.590 --> 01:38:53.120 Browsers can't be trusted. 01:38:53.120 --> 01:38:55.530 Or more generally, clients can't be trusted. 01:38:55.530 --> 01:38:56.030 Why? 01:38:56.030 --> 01:38:59.240 Because the way HTML works as we've seen it thus far 01:38:59.240 --> 01:39:02.960 is that everything is happening on my own Mac, or your own PC, 01:39:02.960 --> 01:39:05.120 or your own phone locally. 01:39:05.120 --> 01:39:08.988 Per the envelope story we told earlier, your browser is downloading the HTML, 01:39:08.988 --> 01:39:11.030 reading it top to bottom, left to right, and then 01:39:11.030 --> 01:39:13.160 displaying it on your computer. 01:39:13.160 --> 01:39:15.930 But we've already seen that my computer, for instance, 01:39:15.930 --> 01:39:18.380 has built into it these developer tools. 01:39:18.380 --> 01:39:21.200 And there among the tabs here, are not just that network tab, 01:39:21.200 --> 01:39:25.220 let me actually go to the Elements tab, which we haven't seen previously. 01:39:25.220 --> 01:39:29.840 In the Elements tab, you actually will see a pretty, printed version 01:39:29.840 --> 01:39:31.400 of the same HTML. 01:39:31.400 --> 01:39:34.530 But what that means is that you can not only see the HTML, 01:39:34.530 --> 01:39:36.270 you can actually change it. 01:39:36.270 --> 01:39:38.800 Now you're not going to be able to change it on the server. 01:39:38.800 --> 01:39:41.530 But I can absolutely change my own copy thereof. 01:39:41.530 --> 01:39:43.462 So suppose I'm now a hacker in the story. 01:39:43.462 --> 01:39:45.420 And I really want to register for this website, 01:39:45.420 --> 01:39:48.010 but it's apparently restricted to people with .edu addresses. 01:39:48.010 --> 01:39:50.550 I don't have a .edu address, let me propose. 01:39:50.550 --> 01:39:51.540 So that's fine. 01:39:51.540 --> 01:39:55.050 Let me actually go into the developer tools. 01:39:55.050 --> 01:39:57.540 Let me just double click on the attribute 01:39:57.540 --> 01:39:59.280 there, highlight it, and boom. 01:39:59.280 --> 01:40:02.760 Now gone is that pattern entirely. 01:40:02.760 --> 01:40:07.110 The web browser now will let me register with malan@harvard.com 01:40:07.110 --> 01:40:10.900 because the developer tools give you full-fledged access to the underlying 01:40:10.900 --> 01:40:11.400 HTML. 01:40:11.400 --> 01:40:14.640 So if I've changed the HTML, the defense is no longer in place. 01:40:14.640 --> 01:40:18.090 Now what's the takeaway then is client-side validation 01:40:18.090 --> 01:40:19.770 is wonderfully user friendly. 01:40:19.770 --> 01:40:21.190 But it's not secure. 01:40:21.190 --> 01:40:21.870 It's not safe. 01:40:21.870 --> 01:40:24.420 So next week, we'll spend more time server-side 01:40:24.420 --> 01:40:28.050 at making sure that even if someone messes with my HTML or my website, 01:40:28.050 --> 01:40:32.075 they still can't actually get through and do anything bad on the server. 01:40:32.075 --> 01:40:33.450 And this is true in general, too. 01:40:33.450 --> 01:40:39.420 Let me actually, just for fun, go to, maybe, let's say, harvard.edu. 01:40:39.420 --> 01:40:41.670 Let me open up my development tools. 01:40:41.670 --> 01:40:45.630 And let's see where I might go here. 01:40:45.630 --> 01:40:48.180 Suppose that I want to hack into harvard.edu. 01:40:48.180 --> 01:40:50.610 Well, notice that I'm on my elements tab and there's 01:40:50.610 --> 01:40:52.777 a lot of HTML that composes this page. 01:40:52.777 --> 01:40:55.860 And notice that these triangles indicate that most of it's been collapsed. 01:40:55.860 --> 01:40:59.380 But if I expanded them, I could see more and more of the tags and attributes. 01:40:59.380 --> 01:41:01.200 But suppose I'm now a hacker. 01:41:01.200 --> 01:41:03.700 And I want to maybe delete this menu. 01:41:03.700 --> 01:41:05.910 Notice that you can also right click or Control 01:41:05.910 --> 01:41:08.790 click on any element in a web page, typically. 01:41:08.790 --> 01:41:12.930 With these developer tools, click Inspect or some similarly named menu 01:41:12.930 --> 01:41:18.090 option, and you can actually been whisked away to the actual HTML tags 01:41:18.090 --> 01:41:20.143 that implement that feature of the web page. 01:41:20.143 --> 01:41:22.560 One, it's wonderfully useful for learning how things work, 01:41:22.560 --> 01:41:25.092 teaching yourself new tricks, and even fixing problems. 01:41:25.092 --> 01:41:27.300 Here, though, I'm going to try to use it maliciously. 01:41:27.300 --> 01:41:31.092 And I'm going to highlight this tag here, div tag, as it's called. 01:41:31.092 --> 01:41:32.050 I'm going to delete it. 01:41:32.050 --> 01:41:34.140 And watch what happens at top right. 01:41:34.140 --> 01:41:35.690 Gone is the menu. 01:41:35.690 --> 01:41:39.210 Now, of course, if you go to harvard.edu right now, the menu is still there. 01:41:39.210 --> 01:41:42.060 If I reload harvard.edu the menu is back. 01:41:42.060 --> 01:41:43.760 So it's only my own local copy. 01:41:43.760 --> 01:41:45.920 But this does speak to how you should not 01:41:45.920 --> 01:41:48.530 trust anything happening client side. 01:41:48.530 --> 01:41:51.360 Because someone can be mutating that same code. 01:41:51.360 --> 01:41:53.690 Now it turns out there's other patterns that you 01:41:53.690 --> 01:41:55.490 can use in regular expressions. 01:41:55.490 --> 01:41:58.130 For instance, these are what are called character classes. 01:41:58.130 --> 01:42:01.070 You can, for instance, specify in square brackets 01:42:01.070 --> 01:42:04.370 some number of digits or characters that you want to match against. 01:42:04.370 --> 01:42:06.695 This is a range of characters, 0 through 9. 01:42:06.695 --> 01:42:09.320 So it's effectively the same thing as that, but easier to type. 01:42:09.320 --> 01:42:14.030 There are certain shortcuts, backslash lowercase d means any decimal digit. 01:42:14.030 --> 01:42:17.690 Backslash capital d means anything that's not a decimal digit. 01:42:17.690 --> 01:42:20.390 And dot dot dot, there's bunches of other patterns. 01:42:20.390 --> 01:42:23.808 You might use these to maybe validate a phone number in a web page, 01:42:23.808 --> 01:42:26.850 if you want it to be formatted in a certain way, for better or for worse. 01:42:26.850 --> 01:42:29.900 But long story short, regular expressions will be, 01:42:29.900 --> 01:42:34.880 someday, your friend as you try to solve certain problems with data. 01:42:34.880 --> 01:42:37.240 As an aside, it does escalate quickly. 01:42:37.240 --> 01:42:39.930 So this is typically the regular expression 01:42:39.930 --> 01:42:43.650 that browsers nowadays use to validate email addresses. 01:42:43.650 --> 01:42:48.180 It is way more complicated than . +@.+. 01:42:48.180 --> 01:42:48.870 Why? 01:42:48.870 --> 01:42:50.540 Because you can't have @@@.edu. 01:42:53.225 --> 01:42:55.350 There's certain characters you don't want to allow. 01:42:55.350 --> 01:42:57.433 There are certain characters you do want to allow. 01:42:57.433 --> 01:43:01.110 So long story short, this is a much larger regular expression 01:43:01.110 --> 01:43:04.920 that is more correct when it comes to valid email addresses. 01:43:04.920 --> 01:43:05.520 All right. 01:43:05.520 --> 01:43:10.080 So with that said, there's one tool with which you should be familiar. 01:43:10.080 --> 01:43:13.860 And that is at this URL here, validator.w3.org. 01:43:13.860 --> 01:43:17.820 And this is a free web service from the World Wide Web Consortium, 01:43:17.820 --> 01:43:21.638 which is the group that essentially standardizes this HTML language. 01:43:21.638 --> 01:43:24.180 And if you go to their web page, there's a few different ways 01:43:24.180 --> 01:43:25.830 to validate your own code. 01:43:25.830 --> 01:43:29.850 Essentially, check it for correctness by typing in its URL, 01:43:29.850 --> 01:43:34.150 otherwise known more generally as a URI, by uploading a file or by direct input. 01:43:34.150 --> 01:43:37.210 So just for kicks, for instance, I'm going to go into VS Code 01:43:37.210 --> 01:43:39.880 and grab my HTML that I just made. 01:43:39.880 --> 01:43:44.830 I'm going to go back to validator.w3.org and paste it into the direct input box 01:43:44.830 --> 01:43:45.910 and click Check. 01:43:45.910 --> 01:43:49.180 And it's just a nice handy website that, if I scroll down, in green, 01:43:49.180 --> 01:43:53.380 you will hopefully see this, no errors or warnings to show. 01:43:53.380 --> 01:43:56.830 So it's a handy feature just to make sure that at least syntactically 01:43:56.830 --> 01:44:01.600 your code is correct, even if it's not behaving the way that you might want. 01:44:01.600 --> 01:44:02.170 All right. 01:44:02.170 --> 01:44:04.902 With that said, the second of today's three languages, 01:44:04.902 --> 01:44:07.360 and we'll just scratch the surface ultimately of JavaScript 01:44:07.360 --> 01:44:09.838 to give you a sense of its capabilities, but CSS 01:44:09.838 --> 01:44:12.880 is something that's worth understanding some of the basic building blocks 01:44:12.880 --> 01:44:13.580 thereof. 01:44:13.580 --> 01:44:19.090 So let me propose that there are some additional terms to know. 01:44:19.090 --> 01:44:23.030 In the world of CSS, we're, again, going to have key value pairs. 01:44:23.030 --> 01:44:25.790 In this world, they're called properties instead of attributes. 01:44:25.790 --> 01:44:26.290 Why? 01:44:26.290 --> 01:44:29.350 It was invented by different people, but it's the same kinds of ideas. 01:44:29.350 --> 01:44:31.240 In the world of CSS, you're going to have 01:44:31.240 --> 01:44:34.610 ways of specifying different selectors, as they're called. 01:44:34.610 --> 01:44:36.920 That is to say we're going to be able to specify 01:44:36.920 --> 01:44:40.640 the font size, the color, the margins and a lot of aesthetics 01:44:40.640 --> 01:44:43.190 when it relates to tags in our web page. 01:44:43.190 --> 01:44:46.220 And there's going to be different ways to select those tags, 01:44:46.220 --> 01:44:47.390 as we'll soon see. 01:44:47.390 --> 01:44:51.350 In an HTML page like this, this is our super simple one with which we began, 01:44:51.350 --> 01:44:54.560 it turns out that you can also include a style 01:44:54.560 --> 01:44:56.840 tag in the head of the page that has some 01:44:56.840 --> 01:44:59.870 of your stylistic decisions, font sizes, colors, margins, 01:44:59.870 --> 01:45:01.760 and all of those kinds of aesthetics. 01:45:01.760 --> 01:45:05.300 We'll also see another approach whereby you can relegate all of that stuff 01:45:05.300 --> 01:45:09.220 to a separate file, like styles.css, or something .css. 01:45:09.220 --> 01:45:12.050 And you can link to it in the head of the page. 01:45:12.050 --> 01:45:16.370 Link here does not mean A, like, ideally our anchor tag before 01:45:16.370 --> 01:45:17.790 would have been called a link. 01:45:17.790 --> 01:45:18.500 But it's not. 01:45:18.500 --> 01:45:22.650 This just means that these two files are linked in some way conceptually. 01:45:22.650 --> 01:45:23.150 All right. 01:45:23.150 --> 01:45:29.130 So that is to say we can use these kinds of tags now to enhance our own code. 01:45:29.130 --> 01:45:31.110 So let me propose that we do this. 01:45:31.110 --> 01:45:32.970 Let me go into VS Code here. 01:45:32.970 --> 01:45:35.870 Let me go ahead and create a very, very simple home 01:45:35.870 --> 01:45:42.950 page for someone like John Harvard by running code of-- how about home.html? 01:45:42.950 --> 01:45:46.850 And in home.html, I'm going to copy paste some of my starter HTML 01:45:46.850 --> 01:45:47.810 from before. 01:45:47.810 --> 01:45:50.570 And now in the body of this page, I'm going to do a few things. 01:45:50.570 --> 01:45:53.420 I'm going to have a web page with a paragraph 01:45:53.420 --> 01:45:57.500 up here that just says John Harvard as the title thereof. 01:45:57.500 --> 01:45:59.450 Another paragraph that says something simple 01:45:59.450 --> 01:46:02.790 like welcome to my home page exclamation point. 01:46:02.790 --> 01:46:05.630 And then, like, a footer at the bottom and a third paragraph 01:46:05.630 --> 01:46:10.470 that's a copyright, say, John Harvard, for instance. 01:46:10.470 --> 01:46:14.180 So super simple, but representative of a header, a main part of the page, 01:46:14.180 --> 01:46:15.560 and a footer thereof. 01:46:15.560 --> 01:46:20.480 If I go into my other tab and reload my directory listing, 01:46:20.480 --> 01:46:23.090 I will see now home.html. 01:46:23.090 --> 01:46:25.370 And it's going to be pretty bare bones, right? 01:46:25.370 --> 01:46:27.080 It's the same text, same font size. 01:46:27.080 --> 01:46:28.640 It is three separate paragraphs. 01:46:28.640 --> 01:46:31.370 But let me start to stylize this a little bit differently. 01:46:31.370 --> 01:46:35.600 Let me make the top bigger and bolder, perhaps, or rather, 01:46:35.600 --> 01:46:39.870 the top bigger and centered and make this text shrink thereafter. 01:46:39.870 --> 01:46:41.520 So I'm going to go ahead and do this. 01:46:41.520 --> 01:46:44.960 It turns out that you can have not necessarily a style tag, 01:46:44.960 --> 01:46:48.930 but even more simply, a style attribute on certain tags, like this. 01:46:48.930 --> 01:46:54.410 I'm going to add a style attribute that has a font size of maybe large. 01:46:54.410 --> 01:47:00.770 And how about a style attribute here, a font size medium. 01:47:00.770 --> 01:47:03.440 And then maybe down here-- oops, close quotes. 01:47:03.440 --> 01:47:05.250 And then down here-- 01:47:05.250 --> 01:47:05.990 whoops. 01:47:05.990 --> 01:47:06.800 Thank you. 01:47:06.800 --> 01:47:07.940 OK. 01:47:07.940 --> 01:47:09.120 I owe you some cookies. 01:47:09.120 --> 01:47:14.610 All right, so style here of font size small, so relatively simple ideas. 01:47:14.610 --> 01:47:18.173 And here is just another stupid syntax for key value pairs. 01:47:18.173 --> 01:47:20.090 Again, left hand is not talking to right hand. 01:47:20.090 --> 01:47:24.980 In CSS, cascading style sheets, which is the language we're now talking about, 01:47:24.980 --> 01:47:27.710 it's key colon value. 01:47:27.710 --> 01:47:31.520 In HTML, it's key equals quote unquote value. 01:47:31.520 --> 01:47:34.770 It's just different techniques for the exact same dictionary-like idea. 01:47:34.770 --> 01:47:35.270 All right. 01:47:35.270 --> 01:47:39.270 If I go back to my other tab and reload, notice that it's a little subtle, 01:47:39.270 --> 01:47:41.600 but it is large, medium, and small. 01:47:41.600 --> 01:47:44.070 I didn't center things yet, so let me do that. 01:47:44.070 --> 01:47:45.830 It turns out that this thing collectively 01:47:45.830 --> 01:47:47.090 is what's called a property. 01:47:47.090 --> 01:47:49.430 And a property is defined by a key value pair. 01:47:49.430 --> 01:47:52.400 If you want to have multiple properties for key value pairs, 01:47:52.400 --> 01:47:55.800 in CSS, you separate them with semicolons. 01:47:55.800 --> 01:47:56.760 So those are back. 01:47:56.760 --> 01:48:00.860 And if I want to center the text, I can do text-align: center. 01:48:00.860 --> 01:48:03.020 I could now end my thought with the semicolon. 01:48:03.020 --> 01:48:04.880 It's not strictly necessary. 01:48:04.880 --> 01:48:06.890 But I'll keep it just so that I'm consistent. 01:48:06.890 --> 01:48:10.093 But it's only necessary if you have more than one. 01:48:10.093 --> 01:48:12.260 I'm going to go ahead and center everything, though. 01:48:12.260 --> 01:48:15.800 So I'm going to go down here and add a semicolon after medium, down here 01:48:15.800 --> 01:48:17.570 and add a semicolon after small. 01:48:17.570 --> 01:48:22.100 So I align, text-align center, center, center for all three paragraphs. 01:48:22.100 --> 01:48:25.580 If I go back to this other tab and I reload, voila. 01:48:25.580 --> 01:48:27.830 Now it is, in fact, centered. 01:48:27.830 --> 01:48:32.450 But here's where we can start to have a conversation about, maybe, design. 01:48:32.450 --> 01:48:34.190 So I claim this is correct. 01:48:34.190 --> 01:48:36.680 But is this perhaps the best design? 01:48:36.680 --> 01:48:38.030 Well, maybe not. 01:48:38.030 --> 01:48:41.210 I mean, these aren't really paragraphs, first of all, semantically. 01:48:41.210 --> 01:48:43.160 It's not even complete sentences. 01:48:43.160 --> 01:48:45.692 But there are three different divisions of the page, 01:48:45.692 --> 01:48:48.650 right, like, the header up there, the main part in the middle, and then 01:48:48.650 --> 01:48:49.340 the footer. 01:48:49.340 --> 01:48:52.670 So it turns out, and we saw a glimpse of this in Harvard's source code, 01:48:52.670 --> 01:48:58.120 there's another tag instead of p for paragraph called div, for division. 01:48:58.120 --> 01:48:59.870 And even though this is actually not going 01:48:59.870 --> 01:49:02.660 to have much of a functional effect at first, 01:49:02.660 --> 01:49:04.850 it's maybe semantically a bit better. 01:49:04.850 --> 01:49:06.890 Because, again, these aren't really paragraphs. 01:49:06.890 --> 01:49:09.900 So if I really want to nitpick, I do have three divisions of the page. 01:49:09.900 --> 01:49:14.180 So div is a very common way to give yourself just a rectangular region 01:49:14.180 --> 01:49:16.310 of the page to style as you see fit. 01:49:16.310 --> 01:49:20.360 If I go back now and reload, notice that it does tighten things up. 01:49:20.360 --> 01:49:23.480 The paragraph tag gave me some vertical whitespace for free. 01:49:23.480 --> 01:49:24.380 So I've lost that. 01:49:24.380 --> 01:49:26.780 But I could add it back if I really wanted to. 01:49:26.780 --> 01:49:29.750 But now, let's come to this question of design. 01:49:29.750 --> 01:49:32.760 What's redundant about what I've done thus far, even if you've never 01:49:32.760 --> 01:49:34.950 seen CSS before? 01:49:34.950 --> 01:49:35.670 Yeah? 01:49:35.670 --> 01:49:36.900 AUDIENCE: [INAUDIBLE]. 01:49:36.900 --> 01:49:37.650 DAVID MALAN: Yeah. 01:49:37.650 --> 01:49:40.967 I mean, I had to center all three divs, which is just sort of stupid, 01:49:40.967 --> 01:49:41.550 it would seem. 01:49:41.550 --> 01:49:43.398 Copy paste has generally not been necessary. 01:49:43.398 --> 01:49:45.690 Even though I'm doing it to save time today in general, 01:49:45.690 --> 01:49:48.600 when the results are copied and pasted, ultimately, this 01:49:48.600 --> 01:49:51.120 has not been good practice in any of our languages. 01:49:51.120 --> 01:49:52.990 So it turns out I can do this. 01:49:52.990 --> 01:49:54.750 Let me actually delete this one. 01:49:54.750 --> 01:49:57.660 And I can keep or get rid of the semicolon, but I'll get rid of it 01:49:57.660 --> 01:49:59.460 for parity with our first version. 01:49:59.460 --> 01:50:01.350 I'm going to get rid of this one, too. 01:50:01.350 --> 01:50:02.710 And you know what? 01:50:02.710 --> 01:50:05.460 Here's the C in CSS cascading. 01:50:05.460 --> 01:50:07.390 It's more like a waterfall effect. 01:50:07.390 --> 01:50:10.620 And if I go up to a parent tag here, like, the body is 01:50:10.620 --> 01:50:15.150 the parent of all three divs, I could put the style attribute here 01:50:15.150 --> 01:50:18.150 and say text-align: center there. 01:50:18.150 --> 01:50:21.090 And that has the effect of cascading down onto all three 01:50:21.090 --> 01:50:23.170 of the children that are nested inside of it. 01:50:23.170 --> 01:50:25.740 So now it's sort of better designed because I've only 01:50:25.740 --> 01:50:27.660 said text-align: center once. 01:50:27.660 --> 01:50:31.860 If I go back to the web page and reload, it has no functional impact visually. 01:50:31.860 --> 01:50:32.910 But it's better design. 01:50:32.910 --> 01:50:35.640 Because if I want to align it left, or right, or center, 01:50:35.640 --> 01:50:39.290 I can change it in one place and not three independent places. 01:50:39.290 --> 01:50:39.790 All right. 01:50:39.790 --> 01:50:42.710 What else might I change after this here? 01:50:42.710 --> 01:50:48.830 Well, it turns out that I could do something a little clearer as well. 01:50:48.830 --> 01:50:50.170 This copyright symbol? 01:50:50.170 --> 01:50:53.410 I mean, it's just sort of homemade with two parentheses and a C. 01:50:53.410 --> 01:50:56.920 It turns out that there are ways to get special symbols in HTML. 01:50:56.920 --> 01:50:59.162 And you can use what are called HTML entities. 01:50:59.162 --> 01:51:02.120 You would only know these by looking them up or memorizing the numbers. 01:51:02.120 --> 01:51:07.630 But it turns out that number 169 is the special HTML 01:51:07.630 --> 01:51:10.210 entity for an actual copyright symbol. 01:51:10.210 --> 01:51:12.700 So let me zoom in here and then reload. 01:51:12.700 --> 01:51:16.750 And you'll see that the parenthetical C actually becomes the proper mark 01:51:16.750 --> 01:51:19.090 for copyright, so marginally useful. 01:51:19.090 --> 01:51:21.250 Or you could copy paste it from some other website, 01:51:21.250 --> 01:51:24.125 for instance, if you didn't know how to type it on your own keyboard. 01:51:24.125 --> 01:51:27.280 So that's an HTML entity, another feature with which to be familiar. 01:51:27.280 --> 01:51:32.150 But having three divs on a page isn't necessarily ideal nowadays, 01:51:32.150 --> 01:51:35.080 especially for search engine optimization, SEO, 01:51:35.080 --> 01:51:37.180 for screen readers for accessibility. 01:51:37.180 --> 01:51:40.060 Because at a glance, I don't really know which of these divs 01:51:40.060 --> 01:51:41.830 is the most important. 01:51:41.830 --> 01:51:44.470 Arguably the footer is generally for the human reader, 01:51:44.470 --> 01:51:48.110 like, the least information-bearing piece of content. 01:51:48.110 --> 01:51:51.670 So why don't I try to signal as much to the browser, to the screen reader, 01:51:51.670 --> 01:51:53.240 to the search engine? 01:51:53.240 --> 01:51:56.320 So it turns out there are what are called semantic tags nowadays. 01:51:56.320 --> 01:51:58.000 Indeed, we're up to version 5 of HTML. 01:51:58.000 --> 01:52:01.840 And one of the relatively newer features is, instead of using generic divs, 01:52:01.840 --> 01:52:04.270 you can actually use actual names of tags, 01:52:04.270 --> 01:52:07.690 like header and main and even footer. 01:52:07.690 --> 01:52:10.810 And here, too, the visual effect is not going 01:52:10.810 --> 01:52:13.870 to be any different if I go here and reload. 01:52:13.870 --> 01:52:17.410 But there's more semantic information underneath the hood. 01:52:17.410 --> 01:52:19.300 So that, again, all of those different types 01:52:19.300 --> 01:52:22.600 of services, the browser, the screen reader, and the like 01:52:22.600 --> 01:52:24.910 just know a little more about the page. 01:52:24.910 --> 01:52:28.180 And maybe a screen reader now would focus on the main part of the page 01:52:28.180 --> 01:52:32.260 before reciting all of the fine print in the footer, for instance, to the human. 01:52:32.260 --> 01:52:32.770 All right. 01:52:32.770 --> 01:52:34.520 Well, what else could we do here? 01:52:34.520 --> 01:52:38.470 Well, it would be nice at some point to be able to reuse these styles. 01:52:38.470 --> 01:52:43.240 And if I find myself making not one page but two pages or 10 pages or 100 pages, 01:52:43.240 --> 01:52:47.230 it's kind of annoying to have to type out all of the same styles. 01:52:47.230 --> 01:52:50.060 So wouldn't it be nice to start to factor this stuff out? 01:52:50.060 --> 01:52:51.370 Well, I can do that, too. 01:52:51.370 --> 01:52:53.510 Let me actually go ahead and do this. 01:52:53.510 --> 01:52:58.450 Let me get rid of this attribute and this attribute and this attribute. 01:52:58.450 --> 01:53:02.050 And honestly, too, as I do this, I would argue that the code 01:53:02.050 --> 01:53:04.030 looks just a little cleaner now. 01:53:04.030 --> 01:53:07.450 It's more obvious what is a tag and what the actual data of the page 01:53:07.450 --> 01:53:09.260 is, metadata and data, if you will. 01:53:09.260 --> 01:53:10.870 But I've lost all of my styling. 01:53:10.870 --> 01:53:13.450 But wouldn't it be nice to preserve some of the styling 01:53:13.450 --> 01:53:15.670 by doing what I proposed earlier, which is using 01:53:15.670 --> 01:53:19.060 not a style attribute, but a style tag. 01:53:19.060 --> 01:53:22.802 And indeed, you can put a style tag in the head of your web page 01:53:22.802 --> 01:53:24.760 where you can put all of those same properties. 01:53:24.760 --> 01:53:27.970 And you need a little more syntax, a few more keystrokes. 01:53:27.970 --> 01:53:29.140 But I can say this. 01:53:29.140 --> 01:53:32.350 If I want to center the entire body of my page, 01:53:32.350 --> 01:53:38.470 I can actually do so by specifying text-align: center;. 01:53:38.470 --> 01:53:41.003 Here the semi-colons are going to be generally necessary, 01:53:41.003 --> 01:53:42.670 especially have you multiple properties. 01:53:42.670 --> 01:53:44.200 Next I'm going to say header. 01:53:44.200 --> 01:53:47.260 And inside of these curly braces, font-size: 01:53:47.260 --> 01:53:51.070 large, unlike C, where you could get away with no curly braces 01:53:51.070 --> 01:53:54.070 if there's a single line, you do need them in CSS. 01:53:54.070 --> 01:53:58.630 In the main tag, let's go ahead and style with font-size: medium. 01:53:58.630 --> 01:54:04.700 And then in the footer tag, let's go ahead and style with font-size: small. 01:54:04.700 --> 01:54:06.010 Now this looks a little worse. 01:54:06.010 --> 01:54:08.860 Because it just kind of blew up and it's a lot longer. 01:54:08.860 --> 01:54:11.410 But it is a step toward factoring this out. 01:54:11.410 --> 01:54:13.720 And honestly, when it comes to web pages, 01:54:13.720 --> 01:54:15.460 I'm not the best artist in the world. 01:54:15.460 --> 01:54:17.440 I can make the data display. 01:54:17.440 --> 01:54:20.140 But friends of mine are certainly better at making things really 01:54:20.140 --> 01:54:22.400 pretty and pixel perfect, so to speak. 01:54:22.400 --> 01:54:26.440 So it's kind of nice if I can isolate all of the style to one part of my file 01:54:26.440 --> 01:54:27.867 and all of the content to another. 01:54:27.867 --> 01:54:30.200 Because maybe I could now collaborate with someone else. 01:54:30.200 --> 01:54:33.490 So if I go back to now the other tab and reload, 01:54:33.490 --> 01:54:35.530 functionally, no different still. 01:54:35.530 --> 01:54:37.390 It still looks exactly the same. 01:54:37.390 --> 01:54:40.457 But I'm starting to make it a little better designed. 01:54:40.457 --> 01:54:42.290 And in fact, there's another way to do this. 01:54:42.290 --> 01:54:47.592 Suppose that I find myself in the habit of very often centering text on a page. 01:54:47.592 --> 01:54:49.300 And honestly, it's just a little annoying 01:54:49.300 --> 01:54:52.240 to have to type this out for every tag that I want centered. 01:54:52.240 --> 01:54:57.640 Well, I could create what are called classes as well in CSS. 01:54:57.640 --> 01:54:59.763 It turns out you can make up your own words-- 01:54:59.763 --> 01:55:01.930 but I'm going to choose some reasonably named ones-- 01:55:01.930 --> 01:55:04.340 by prefixing them with a dot or a period. 01:55:04.340 --> 01:55:06.880 And if I want to call this set of properties, 01:55:06.880 --> 01:55:11.290 even though there's just one, centered, I can literally write .centered there 01:55:11.290 --> 01:55:11.980 instead. 01:55:11.980 --> 01:55:13.660 I can write this .large. 01:55:13.660 --> 01:55:16.070 I can call this .medium. 01:55:16.070 --> 01:55:18.640 I can call this .small. 01:55:18.640 --> 01:55:22.900 And what this means now is I have reusable sets of properties, 01:55:22.900 --> 01:55:25.900 kind of like containers whereby anywhere I use the word "centered," 01:55:25.900 --> 01:55:30.400 it's going to get that one text-align: center property applied. 01:55:30.400 --> 01:55:33.250 Anywhere I use quote, unquote "large," it's going to be made large. 01:55:33.250 --> 01:55:37.410 And so if I scroll down now here, I do need to reintroduce another attribute-- 01:55:37.410 --> 01:55:41.600 but it's a very common one in the world of HTML now-- that of class. 01:55:41.600 --> 01:55:43.820 So class equals large. 01:55:43.820 --> 01:55:46.910 Down here I'm going to do class equals medium. 01:55:46.910 --> 01:55:49.910 Down here I'm going to do class equals small. 01:55:49.910 --> 01:55:53.930 And it's getting a little more verbose, but I'm not polluting all of my HTML 01:55:53.930 --> 01:55:55.158 with the actual styles. 01:55:55.158 --> 01:55:57.200 I'm just kind of having this layer of indirection 01:55:57.200 --> 01:56:01.010 and of abstraction, if you will, on top of those very specific properties. 01:56:01.010 --> 01:56:02.990 And then for the body, I can do the same idea. 01:56:02.990 --> 01:56:05.210 Class equals centered. 01:56:05.210 --> 01:56:10.010 And if I go back to my web page here and reload, still looks exactly the same. 01:56:10.010 --> 01:56:12.680 But I've kind of centralized where I can do things. 01:56:12.680 --> 01:56:15.500 And frankly, I could do something like this, color: red;. 01:56:15.500 --> 01:56:19.530 I can package up multiple properties, go back to the page here, and reload. 01:56:19.530 --> 01:56:22.350 And now that has applied to everything. 01:56:22.350 --> 01:56:24.470 So I have a reusable set of properties. 01:56:24.470 --> 01:56:27.020 Even though centered is maybe not the best name now, 01:56:27.020 --> 01:56:28.520 because it also makes things red. 01:56:28.520 --> 01:56:31.400 But I can come up with reusable sets of properties. 01:56:31.400 --> 01:56:33.410 And honestly, one final flourish here would 01:56:33.410 --> 01:56:36.830 be let's not assume that my buddy, whether it's 01:56:36.830 --> 01:56:39.200 my project partner or a colleague in the real world, 01:56:39.200 --> 01:56:41.600 it's kind of stupid to try to edit the same file. 01:56:41.600 --> 01:56:44.430 Because invariably we're going to break things on each other. 01:56:44.430 --> 01:56:45.880 So I could actually do this. 01:56:45.880 --> 01:56:46.880 Let me take all of this. 01:56:46.880 --> 01:56:48.110 And I'll get rid of the red. 01:56:48.110 --> 01:56:52.290 Let me go ahead and highlight everything I just did and cut it to my clipboard. 01:56:52.290 --> 01:56:54.740 I'm going to get rid of the style tag altogether. 01:56:54.740 --> 01:56:59.690 But I am going to go into VS Code and create-- how about a file called 01:56:59.690 --> 01:57:02.660 home.css, just so I know what's what. 01:57:02.660 --> 01:57:06.530 And in this file, I'm just going to literally paste everything I just made. 01:57:06.530 --> 01:57:08.820 But I'm going to go back to my home page here. 01:57:08.820 --> 01:57:16.610 And I'm going to add that other tag I proposed earlier, link href="home.css", 01:57:16.610 --> 01:57:18.740 and I need one weird attribute, too. 01:57:18.740 --> 01:57:24.890 The relationship of this link is that of quote, unquote "style sheets." 01:57:24.890 --> 01:57:27.530 And that's just the way it is according to the tag. 01:57:27.530 --> 01:57:30.710 And now one last time, if I reload this page, the red is going to go away. 01:57:30.710 --> 01:57:31.790 Because I deleted that. 01:57:31.790 --> 01:57:35.310 But the font sizes and centering are still there. 01:57:35.310 --> 01:57:37.670 But what I've done was introduce some basic building 01:57:37.670 --> 01:57:40.910 blocks in this language I claim is called CSS that's 01:57:40.910 --> 01:57:46.130 going to allow me to now centralize all of the styling, the aesthetics now 01:57:46.130 --> 01:57:47.670 of my web page. 01:57:47.670 --> 01:57:48.170 All right. 01:57:48.170 --> 01:57:53.510 Let me pause here and see if there are any questions on these techniques 01:57:53.510 --> 01:57:54.650 thus far. 01:57:54.650 --> 01:57:58.140 It's just more key value pairs. 01:57:58.140 --> 01:57:59.740 Questions on this? 01:57:59.740 --> 01:58:00.240 No? 01:58:00.240 --> 01:58:00.740 All right. 01:58:00.740 --> 01:58:03.720 So here's where things can get prettier quickly. 01:58:03.720 --> 01:58:06.360 Let me go ahead now and close these two tabs. 01:58:06.360 --> 01:58:10.980 Let me go into a file we created earlier called link.html, which you'll recall 01:58:10.980 --> 01:58:12.580 looked a little something like this. 01:58:12.580 --> 01:58:16.540 And now we can make this web page behave a little more like the real world. 01:58:16.540 --> 01:58:19.920 Let me undo the phishing attack and just literally say Harvard down here. 01:58:19.920 --> 01:58:23.670 But let me go ahead and start to style the anchor tag as follows. 01:58:23.670 --> 01:58:26.400 Previously, this page looked a little boring like this. 01:58:26.400 --> 01:58:27.780 The link was blue originally. 01:58:27.780 --> 01:58:31.605 But because I visited harvard.edu, by default, the browser changes to purple. 01:58:31.605 --> 01:58:33.480 Which is fine, but maybe you don't want that. 01:58:33.480 --> 01:58:36.430 Maybe we want something that's a little more crimson, for instance. 01:58:36.430 --> 01:58:37.480 So let me do this. 01:58:37.480 --> 01:58:40.230 Let me go into the head of this link.html page. 01:58:40.230 --> 01:58:42.510 Let me add a style tag herein. 01:58:42.510 --> 01:58:46.140 And in there, let me style the anchor tag as follows. 01:58:46.140 --> 01:58:50.790 Inside of this anchor tag, I'm going to do color: red. 01:58:50.790 --> 01:58:55.050 And let's go ahead and leave it as such for now. 01:58:55.050 --> 01:58:56.978 Let me go back to the link page and reload. 01:58:56.978 --> 01:58:58.520 And it's going to be a little subtle. 01:58:58.520 --> 01:58:59.680 But right now it's purple. 01:58:59.680 --> 01:59:01.520 And now it's definitely red. 01:59:01.520 --> 01:59:02.620 So I've modified that. 01:59:02.620 --> 01:59:05.050 Now underlining links is good for accessibility. 01:59:05.050 --> 01:59:08.883 But a lot of websites choose to not underline them and instead 01:59:08.883 --> 01:59:10.550 underline them when you hover over them. 01:59:10.550 --> 01:59:13.840 So that is an effect we can achieve, even though it might not be ideal. 01:59:13.840 --> 01:59:16.720 But let's at least demonstrate how websites are doing that. 01:59:16.720 --> 01:59:21.700 I can specify that this link should have text decoration of none. 01:59:21.700 --> 01:59:24.400 Now I would only know that by having taken a class, read a book, 01:59:24.400 --> 01:59:25.650 looked at an online reference. 01:59:25.650 --> 01:59:28.690 The default is underline. 01:59:28.690 --> 01:59:31.330 But I can override that by saying none. 01:59:31.330 --> 01:59:35.350 So if I now go back to my page, reload, it's still going to be red. 01:59:35.350 --> 01:59:38.530 But it's now not going to be underlined. 01:59:38.530 --> 01:59:42.400 But notice if I hover over it, it changes to a little pointer finger 01:59:42.400 --> 01:59:43.480 if I zoom in here. 01:59:43.480 --> 01:59:46.600 But it's clearly not underlining, so that's OK. 01:59:46.600 --> 01:59:49.210 Because there's another way of selecting tags here. 01:59:49.210 --> 01:59:51.790 I can say a:hover. 01:59:51.790 --> 01:59:55.810 And then inside of this CSS, I can say text-decoration: 01:59:55.810 --> 02:00:00.340 underline when the anchor tag is being hovered over with the cursor. 02:00:00.340 --> 02:00:04.250 If I go back to my tab here and reload, still looks the same. 02:00:04.250 --> 02:00:06.460 But watch as my mouse gets close. 02:00:06.460 --> 02:00:09.370 It now underlines, as a lot of websites do. 02:00:09.370 --> 02:00:11.210 So it's a relatively simple idea. 02:00:11.210 --> 02:00:13.085 It's not as compelling on mobile, especially, 02:00:13.085 --> 02:00:15.377 because it doesn't do anything if you hover your finger 02:00:15.377 --> 02:00:16.630 over the glass of your phone. 02:00:16.630 --> 02:00:19.070 But it does work on laptops and desktops in this way, 02:00:19.070 --> 02:00:22.450 even though it's perhaps a little passé now to do this kind of technique. 02:00:22.450 --> 02:00:25.810 But there's other ways to select tags on a page. 02:00:25.810 --> 02:00:27.730 And in fact, let me go back to this one here. 02:00:27.730 --> 02:00:31.780 And in this page, let me propose that you can go in one of two places. 02:00:31.780 --> 02:00:41.080 Visit Harvard or a href = https://www.yale.edu/ and then 02:00:41.080 --> 02:00:42.380 Yale's website. 02:00:42.380 --> 02:00:43.630 So it's getting a little long. 02:00:43.630 --> 02:00:44.650 So I'm going to hit Enter. 02:00:44.650 --> 02:00:47.200 Because the browser won't care that there's some whitespace. 02:00:47.200 --> 02:00:49.760 But at least, now I have two links on the page. 02:00:49.760 --> 02:00:52.420 If I reload this, you'll see that both of them 02:00:52.420 --> 02:00:55.750 are red or crimson, which isn't quite right. 02:00:55.750 --> 02:00:56.710 But that's OK. 02:00:56.710 --> 02:00:59.480 I can actually distinguish these two somehow. 02:00:59.480 --> 02:01:03.070 One way to do this would actually be to add one more HTML 02:01:03.070 --> 02:01:06.130 attribute that we haven't needed or used before, that of ID. 02:01:06.130 --> 02:01:10.180 I can use almost any name for this ID that I want. 02:01:10.180 --> 02:01:12.640 And I'm going to say, quote, unquote, "Harvard" 02:01:12.640 --> 02:01:14.500 is the unique ID of this link. 02:01:14.500 --> 02:01:18.580 And the unique ID of this link is quote, unquote, "Yale," for instance. 02:01:18.580 --> 02:01:22.510 And what I can now do up here is I'm going to get rid of this color red. 02:01:22.510 --> 02:01:25.750 Because I don't want all anchor tags to be red, but I do 02:01:25.750 --> 02:01:27.950 want Harvard tags to be red. 02:01:27.950 --> 02:01:33.610 So I can say #harvard and then color: red;, and then I can do #Yale 02:01:33.610 --> 02:01:36.260 and I can say color: blue;, for instance. 02:01:36.260 --> 02:01:39.130 The hash symbol here represents an ID. 02:01:39.130 --> 02:01:41.988 The dot we saw earlier represents a class. 02:01:41.988 --> 02:01:43.780 And when you don't have a symbol before it, 02:01:43.780 --> 02:01:46.430 it represents literally the name of the tag. 02:01:46.430 --> 02:01:49.390 So when I mentioned these various selectors earlier, 02:01:49.390 --> 02:01:51.460 type selector is just the name of the tag. 02:01:51.460 --> 02:01:53.290 Class selector is the dot. 02:01:53.290 --> 02:01:54.580 ID selector is the hash. 02:01:54.580 --> 02:01:57.830 And there's also ways to select attributes specifically. 02:01:57.830 --> 02:02:02.080 So if I go back here in VS Code now, I've added a bunch of CSS here, 02:02:02.080 --> 02:02:02.900 properties. 02:02:02.900 --> 02:02:07.850 But if I reload now, one of these should be red and the other is in fact blue. 02:02:07.850 --> 02:02:12.730 So in short, just by way of these style attributes and these style tags, 02:02:12.730 --> 02:02:18.558 we have a lot more control over how we can actually stylize our pages. 02:02:18.558 --> 02:02:20.350 And here's now where this gets interesting. 02:02:20.350 --> 02:02:24.040 And you asked about Bootstrap, a popular framework or library. 02:02:24.040 --> 02:02:27.850 There do, indeed, in the real world exist a lot of third party frameworks 02:02:27.850 --> 02:02:30.515 that a lot of smart people have just figured out what 02:02:30.515 --> 02:02:32.140 would make our web pages look prettier. 02:02:32.140 --> 02:02:34.307 And they've come up with design patterns for us that 02:02:34.307 --> 02:02:37.120 make it way easier and way faster to make pretty looking forms, 02:02:37.120 --> 02:02:38.710 pretty looking tables, and the like. 02:02:38.710 --> 02:02:40.918 And one of these products is indeed called Bootstrap. 02:02:40.918 --> 02:02:41.930 It's freely available. 02:02:41.930 --> 02:02:45.100 And you can see its own documentation at getbootstrap.com. 02:02:45.100 --> 02:02:49.090 And what I've done in advance is I've actually prepared some of our past data 02:02:49.090 --> 02:02:52.180 to actually be formatted a little more prettily. 02:02:52.180 --> 02:02:54.280 So let me actually go back to VS Code here. 02:02:54.280 --> 02:02:56.190 And I'm going to open up a terminal. 02:02:56.190 --> 02:03:01.060 And I'm going to cheat and copy a file I brought with me called phonebook0.html. 02:03:01.060 --> 02:03:04.300 And if I open this file, you'll see that it looks like this. 02:03:04.300 --> 02:03:09.627 It's a big table that has two columns now called name and number. 02:03:09.627 --> 02:03:12.210 And I've added some other tags which are not that interesting, 02:03:12.210 --> 02:03:13.620 but I didn't need them before. 02:03:13.620 --> 02:03:16.880 But in this table, there's a table head and there's a table body. 02:03:16.880 --> 02:03:18.630 So there's, like, a special row at the top 02:03:18.630 --> 02:03:21.630 and then all of the rest of the data in a CSV or a spreadsheet. 02:03:21.630 --> 02:03:26.340 And you can probably infer from this table row, from this table row, 02:03:26.340 --> 02:03:29.380 from this table row, it kind of looks like, indeed, a phone book. 02:03:29.380 --> 02:03:33.450 So if I go back to my browser here, go into my directory listing 02:03:33.450 --> 02:03:36.930 and open up phonebook0.html, it's not the prettiest thing. 02:03:36.930 --> 02:03:38.310 But it is tabular. 02:03:38.310 --> 02:03:42.210 And notice that the browser has automatically put in bold the name, 02:03:42.210 --> 02:03:44.230 and the number, and everything's in columns. 02:03:44.230 --> 02:03:45.510 But it's not very pretty. 02:03:45.510 --> 02:03:47.530 But what if I do this? 02:03:47.530 --> 02:03:50.340 Let me actually go into VS Code here. 02:03:50.340 --> 02:03:55.980 And let me borrow another file I came with called phonebook1.html. 02:03:55.980 --> 02:04:01.500 And that file is going to look a little bit 02:04:01.500 --> 02:04:06.820 different than the [INAUDIBLE] in that I've included a link tag in the header. 02:04:06.820 --> 02:04:09.510 Now I'm not linking to my own CSS. 02:04:09.510 --> 02:04:11.382 I actually went to getbootstrap.com. 02:04:11.382 --> 02:04:12.840 I read some of their documentation. 02:04:12.840 --> 02:04:18.400 And I'm linking now to Bootstrap's CSS file, which is actually really, 02:04:18.400 --> 02:04:18.990 really big. 02:04:18.990 --> 02:04:23.640 And in fact, if I open this file here, let me actually open this up in a tab, 02:04:23.640 --> 02:04:27.540 and visit this URL here, the folks at Bootstrap 02:04:27.540 --> 02:04:30.930 have written a crazy amount of properties 02:04:30.930 --> 02:04:34.350 by defining their own classes and other such keywords. 02:04:34.350 --> 02:04:36.720 And you and I and really anyone on the internet 02:04:36.720 --> 02:04:38.670 is welcome to use all of this CSS. 02:04:38.670 --> 02:04:41.100 And the documentation makes clear what all of this does. 02:04:41.100 --> 02:04:44.370 A normal person would not need to read through any of this in that way. 02:04:44.370 --> 02:04:48.180 But I've included this file called bootstrap.min.css. 02:04:48.180 --> 02:04:50.670 And min just means they got rid of most of the whitespace. 02:04:50.670 --> 02:04:55.770 And if I now go back to my other tab and go back to phonebook1.html, 02:04:55.770 --> 02:04:57.420 it's the exact same data. 02:04:57.420 --> 02:05:01.155 But thanks to that link tag, it now looks much prettier. 02:05:01.155 --> 02:05:04.030 And I didn't have to figure out how to move things over to the right. 02:05:04.030 --> 02:05:06.405 I didn't have to figure out how to draw these gray lines. 02:05:06.405 --> 02:05:09.880 I didn't have to figure out how to format things in precisely this way. 02:05:09.880 --> 02:05:13.070 Bootstrap, wonderfully, did most of that for me. 02:05:13.070 --> 02:05:14.945 Now this is still a very static table. 02:05:14.945 --> 02:05:15.820 It's not interactive. 02:05:15.820 --> 02:05:18.200 I can't sort by names or columns or the like. 02:05:18.200 --> 02:05:22.280 So let's revisit one other program that we made in advance together. 02:05:22.280 --> 02:05:26.330 And this one is actually a new version of the search program. 02:05:26.330 --> 02:05:34.120 So if I open up this program, search2.html, and close my terminal 02:05:34.120 --> 02:05:38.470 window, you'll see that I've borrowed some of the same content before. 02:05:38.470 --> 02:05:40.120 Let me go to the essence of it. 02:05:40.120 --> 02:05:44.020 Here is the form and the action that I used earlier. 02:05:44.020 --> 02:05:46.157 But I've added a whole bunch of classes to it. 02:05:46.157 --> 02:05:48.490 And this is the essence of these third party frameworks. 02:05:48.490 --> 02:05:52.330 They generally create a whole bunch of classes that you can use and reuse. 02:05:52.330 --> 02:05:54.560 But they figured out all of the relevant properties. 02:05:54.560 --> 02:05:56.890 So for instance, for my Google search button, 02:05:56.890 --> 02:06:00.490 I've given it two classes, a class of button, BTN for short, 02:06:00.490 --> 02:06:01.810 and button-light. 02:06:01.810 --> 02:06:04.660 These are not standard HTML or CSS things. 02:06:04.660 --> 02:06:08.650 These are Bootstrap names that they invented, just like I invented center 02:06:08.650 --> 02:06:10.690 and large and medium and small. 02:06:10.690 --> 02:06:17.110 I've also specified that there are a whole bunch of other classes associated 02:06:17.110 --> 02:06:19.490 with pretty much every tag in this file. 02:06:19.490 --> 02:06:23.920 So if I zoom out here and go back to my directory index 02:06:23.920 --> 02:06:26.350 and open this, the first version of search. 02:06:26.350 --> 02:06:30.400 It was super, super simple because it only contained the HTML form. 02:06:30.400 --> 02:06:33.310 Let me go ahead and open up search2.html. 02:06:33.310 --> 02:06:36.040 And the essence of the form is exactly the same. 02:06:36.040 --> 02:06:38.300 Therein is the query at the bottom of the page. 02:06:38.300 --> 02:06:41.800 But thanks to CSS, I now have a button that looks a little more interesting. 02:06:41.800 --> 02:06:42.925 It's gray and it's rounded. 02:06:42.925 --> 02:06:46.092 I also have an I'm feeling lucky button, which will send a different request 02:06:46.092 --> 02:06:48.380 and show me by default the very first search result. 02:06:48.380 --> 02:06:51.400 So in short, the file that I just opened, even though I made it 02:06:51.400 --> 02:06:54.100 in advance, it's only 55 lines. 02:06:54.100 --> 02:06:55.502 And most of that is whitespace. 02:06:55.502 --> 02:06:58.210 And it did take me a little bit of time to figure out the classes 02:06:58.210 --> 02:06:59.530 and read the documentation. 02:06:59.530 --> 02:07:03.010 But most of the work is done by this third party framework 02:07:03.010 --> 02:07:09.170 or library of CSS classes and properties that someone else made for me. 02:07:09.170 --> 02:07:13.010 And so as CSS goes, that's kind of it for the basics. 02:07:13.010 --> 02:07:17.110 It's just a bunch of more key value pairs in the form of these properties, 02:07:17.110 --> 02:07:20.980 whereby you can select elements of a web page by way of their ID, 02:07:20.980 --> 02:07:24.493 or classes, or even the names thereof. 02:07:24.493 --> 02:07:26.410 And here's something that's kind of neat, too. 02:07:26.410 --> 02:07:29.270 Let me go to harvard.edu again. 02:07:29.270 --> 02:07:32.650 Let me go ahead and open up the inspector, as before, 02:07:32.650 --> 02:07:35.890 and draw your attention to one final feature of these developer tools 02:07:35.890 --> 02:07:37.210 under the Elements tab. 02:07:37.210 --> 02:07:39.640 So under the Elements tab here is all of the HTML 02:07:39.640 --> 02:07:41.930 that composes harvard.edu as of today. 02:07:41.930 --> 02:07:44.590 But let me go ahead and expand this right-hand portion. 02:07:44.590 --> 02:07:47.290 It turns out you can also see all of the CSS 02:07:47.290 --> 02:07:50.000 that is being applied to the website as of now. 02:07:50.000 --> 02:07:56.227 So for instance, if I go to a page here-- let's go to Give Now. 02:07:56.227 --> 02:07:56.810 Might as well. 02:07:56.810 --> 02:07:58.180 Let's give them a plug here. 02:07:58.180 --> 02:08:02.320 Under Give Now, let's see if this is going to go well. 02:08:02.320 --> 02:08:04.900 Let's go ahead and highlight this part. 02:08:04.900 --> 02:08:07.870 Suppose they really want to draw attention to give online. 02:08:07.870 --> 02:08:09.430 And I right click on that. 02:08:09.430 --> 02:08:11.110 I choose inspect, as before. 02:08:11.110 --> 02:08:13.840 And here now, notice that the developer tools 02:08:13.840 --> 02:08:17.110 jumped right to the HTML tag that represents 02:08:17.110 --> 02:08:18.610 that particular line of text. 02:08:18.610 --> 02:08:20.620 If I zoom in, it turns out it's an H1 tag. 02:08:20.620 --> 02:08:21.730 It's big and bold. 02:08:21.730 --> 02:08:23.950 Suppose, though, I want to change its color. 02:08:23.950 --> 02:08:27.520 Well, if I go over on the right here, you can see all of the CSS properties 02:08:27.520 --> 02:08:30.700 that currently apply to that specific tag. 02:08:30.700 --> 02:08:34.390 And most of these we haven't even talked about line, height, margin bottom, 02:08:34.390 --> 02:08:38.600 font, weight, margin top, and a bunch of other fairly self-explanatory things. 02:08:38.600 --> 02:08:43.318 But if I want to experiment, I can go up here in top and say color: red. 02:08:43.318 --> 02:08:46.360 And I can literally change that on the web page live to see how it looks. 02:08:46.360 --> 02:08:47.568 It's not changing the server. 02:08:47.568 --> 02:08:48.700 It's just changing my copy. 02:08:48.700 --> 02:08:50.920 But I can at least make that change. 02:08:50.920 --> 02:08:53.530 You can do even fancier things where, if you click computed, 02:08:53.530 --> 02:08:55.900 you can scroll down and figure out, OK, wait a minute. 02:08:55.900 --> 02:08:57.250 It's white right now. 02:08:57.250 --> 02:09:01.060 That's the same thing as this, rgb(255, 255, 255). 02:09:01.060 --> 02:09:04.790 That's the same thing as ffffff from weeks prior. 02:09:04.790 --> 02:09:10.030 But I can click this little arrow and it will even show me where in Harvard CSS 02:09:10.030 --> 02:09:12.210 that white color comes from. 02:09:12.210 --> 02:09:14.710 So if it's actually my site I can actually figure things out 02:09:14.710 --> 02:09:16.070 and make changes as well. 02:09:16.070 --> 02:09:20.170 So in short, if you find that you like the world of web development, 02:09:20.170 --> 02:09:22.540 in your own browser that you've had all this time, 02:09:22.540 --> 02:09:24.852 there's so much darn functionality built in. 02:09:24.852 --> 02:09:27.310 And it's just up to you now to start experimenting with it, 02:09:27.310 --> 02:09:30.670 exploring what you can actually do with it. 02:09:30.670 --> 02:09:36.640 But let us use our final moments today to introduce you to a final language 02:09:36.640 --> 02:09:40.540 called JavaScript, which is itself a proper programming language. 02:09:40.540 --> 02:09:42.730 And you're about to see a bunch of syntax that's 02:09:42.730 --> 02:09:45.190 kind of new, but kind of familiar. 02:09:45.190 --> 02:09:47.830 And the goal here is not to teach you JavaScript per se, 02:09:47.830 --> 02:09:50.650 but to begin to lay the foundation for you yourselves 02:09:50.650 --> 02:09:52.930 learning a new language on your own. 02:09:52.930 --> 02:09:54.945 By the end of CS50, you will not have learned 02:09:54.945 --> 02:09:56.320 all that is out there, certainly. 02:09:56.320 --> 02:09:58.640 And the goal here ultimately is to help you 02:09:58.640 --> 02:10:01.400 have a sense with a support structure in place, be it the humans 02:10:01.400 --> 02:10:05.490 or the [INAUDIBLE] involved that you can ask questions of along the way. 02:10:05.490 --> 02:10:09.200 Let's go ahead and do this. 02:10:09.200 --> 02:10:12.230 In my directory index, I'm going to go into the source 8 directory 02:10:12.230 --> 02:10:15.270 where I've got all of today's examples ready to go. 02:10:15.270 --> 02:10:19.640 I'm going to go into VS Code's Explorer, where I can see all of those files. 02:10:19.640 --> 02:10:22.670 And in my source 8 directory, let me go ahead and open up 02:10:22.670 --> 02:10:25.220 hello version 1 dot HTML. 02:10:25.220 --> 02:10:29.390 Recall that the last time we played with hello.html, it was literally just HTML. 02:10:29.390 --> 02:10:32.300 But here's an example of a language called JavaScript. 02:10:32.300 --> 02:10:35.340 And at this page, it's going to work as follows. 02:10:35.340 --> 02:10:39.080 If I open hello 1 dot html in my page, I have a very simple form. 02:10:39.080 --> 02:10:40.040 Let me zoom in. 02:10:40.040 --> 02:10:42.890 Let me type in my name, for instance, D-A-V-I-D, and hit Enter. 02:10:42.890 --> 02:10:43.520 And voila! 02:10:43.520 --> 02:10:45.290 This is not a very good user interface. 02:10:45.290 --> 02:10:49.220 But you can see that this web page says, quote, unquote, hello, David. 02:10:49.220 --> 02:10:51.920 So how did I get this form to trigger a pop up? 02:10:51.920 --> 02:10:55.730 Well, if I go into VS Code here, you'll see a web form. 02:10:55.730 --> 02:11:00.630 But I've added another attribute, namely an onsubmit attribute. 02:11:00.630 --> 02:11:05.390 And in the world of HTML, onsubmit allows 02:11:05.390 --> 02:11:08.570 you to write a tiny bit of JavaScript code inside of the quotes 02:11:08.570 --> 02:11:11.880 that will be executed whenever the user submits this form. 02:11:11.880 --> 02:11:14.990 So what this is saying is call a function called greet 02:11:14.990 --> 02:11:16.470 and then return false. 02:11:16.470 --> 02:11:19.130 And what return false means is that don't actually 02:11:19.130 --> 02:11:22.490 submit this form to the server, like keep the user on this page 02:11:22.490 --> 02:11:23.990 so we can just see a pop up. 02:11:23.990 --> 02:11:25.790 So what is this greet function? 02:11:25.790 --> 02:11:28.070 Well, it turns out, in the world of HTML, 02:11:28.070 --> 02:11:31.730 there's not only a style tag you can put in your head of your page, 02:11:31.730 --> 02:11:35.720 but also a script tag, inside of which is JavaScript code. 02:11:35.720 --> 02:11:38.570 The syntax is a little different from Python and from C. 02:11:38.570 --> 02:11:40.310 But it's maybe a little closer to Python. 02:11:40.310 --> 02:11:42.830 Instead of def last week or two weeks ago, 02:11:42.830 --> 02:11:46.920 we'll now use function, literally, to begin the definition of a function. 02:11:46.920 --> 02:11:49.280 And if I want to call this function greet, so be it. 02:11:49.280 --> 02:11:52.080 JavaScript comes with a function called alert. 02:11:52.080 --> 02:11:56.870 And so if I literally do alert, hello, quote, unquote, and then 02:11:56.870 --> 02:12:00.470 plus something else, just like in Python, that's going to concatenate, 02:12:00.470 --> 02:12:02.690 or join the two things left and right. 02:12:02.690 --> 02:12:05.750 But here's some functionality that comes with your browser, too. 02:12:05.750 --> 02:12:09.710 It turns out, per the notion of this whole page being a document, 02:12:09.710 --> 02:12:13.100 you can call document.queryselector, which 02:12:13.100 --> 02:12:16.520 allows you to select any of the tags or elements in the page, 02:12:16.520 --> 02:12:20.960 specifically you can select the tag that has an ID of name. 02:12:20.960 --> 02:12:23.150 So CSS and JavaScript use the same syntax. 02:12:23.150 --> 02:12:27.470 If you see hash something, that is referring to the ID of a tag 02:12:27.470 --> 02:12:28.770 that you created. 02:12:28.770 --> 02:12:33.980 If you then, after selecting the element of HTML with that unique ID, 02:12:33.980 --> 02:12:36.330 want its value, you just do dot value. 02:12:36.330 --> 02:12:40.040 So we saw dots a lot in Python and in C to go inside of structures. 02:12:40.040 --> 02:12:43.140 You can go inside of that text box and get its value. 02:12:43.140 --> 02:12:46.130 So notice here if I scroll down, not only 02:12:46.130 --> 02:12:49.770 am I using autocomplete and autofocus and so forth, 02:12:49.770 --> 02:12:54.590 I also, for convenience, gave my input box a unique ID of name. 02:12:54.590 --> 02:12:57.380 So what's effectively happening is, when I click Submit, 02:12:57.380 --> 02:13:02.900 my JavaScript's greet function is called, it queries for that text box, 02:13:02.900 --> 02:13:04.850 goes inside of it and gets its value. 02:13:04.850 --> 02:13:07.610 And then, using this plus operator, just like in Python, 02:13:07.610 --> 02:13:10.220 concatenates the two together and passes them 02:13:10.220 --> 02:13:15.530 to this alert function for an underwhelming, but functional alert 02:13:15.530 --> 02:13:17.070 in the window. 02:13:17.070 --> 02:13:17.570 All right. 02:13:17.570 --> 02:13:20.960 How else can we do this? 02:13:20.960 --> 02:13:25.768 This is generally frowned upon to use onsubmit in this way. 02:13:25.768 --> 02:13:27.560 Generally speaking, the world does not like 02:13:27.560 --> 02:13:32.280 mixing attributes, rather JavaScript code with HTML so closely as this. 02:13:32.280 --> 02:13:34.460 So let me show you another variant of this, 02:13:34.460 --> 02:13:36.627 even though it's going to look a little bit cryptic. 02:13:36.627 --> 02:13:41.840 But at least it will be representative of how else you can solve this problem. 02:13:41.840 --> 02:13:45.380 In hello2.html, we have this code. 02:13:45.380 --> 02:13:48.870 Notice that at the top of my body now is the form. 02:13:48.870 --> 02:13:51.950 But at the bottom of the body is this script tag. 02:13:51.950 --> 02:13:54.560 So I've just moved it from head to the body of the page. 02:13:54.560 --> 02:13:56.870 Because I'm going to then instead do this. 02:13:56.870 --> 02:14:01.490 If I want to tell the browser to listen for submissions of that form, 02:14:01.490 --> 02:14:04.790 I can use this fairly cryptic syntax, but you'll see it again and again 02:14:04.790 --> 02:14:06.710 over time as follows. 02:14:06.710 --> 02:14:09.230 Go into the document. 02:14:09.230 --> 02:14:12.470 Select with this query the form tag. 02:14:12.470 --> 02:14:15.650 And then call this special function that comes with the browser called 02:14:15.650 --> 02:14:16.830 addEventListener. 02:14:16.830 --> 02:14:21.350 So tell the browser to listen for a certain type of event for this form. 02:14:21.350 --> 02:14:23.030 What event do you want to listen for? 02:14:23.030 --> 02:14:26.150 The submission of the form, so quote, unquote submit. 02:14:26.150 --> 02:14:29.870 What do you want to have happen whenever that event is heard? 02:14:29.870 --> 02:14:32.730 You want to call this function here. 02:14:32.730 --> 02:14:35.240 So this is what's known as an anonymous function. 02:14:35.240 --> 02:14:38.300 The syntax is a little weird, but I've not given the function a name. 02:14:38.300 --> 02:14:40.820 It apparently takes an argument as input called event, 02:14:40.820 --> 02:14:43.160 but that's per the documentation. 02:14:43.160 --> 02:14:45.680 And what these two lines of code do essentially 02:14:45.680 --> 02:14:47.420 is they still call the alert function. 02:14:47.420 --> 02:14:49.760 They still output hello comma space. 02:14:49.760 --> 02:14:55.670 And they still query the HTML for the ID name 02:14:55.670 --> 02:14:57.470 to get the value that the humans typed in. 02:14:57.470 --> 02:15:00.265 And then just for good measure, we prevent the default behavior 02:15:00.265 --> 02:15:03.140 for any form with this line of code, just so that it doesn't actually 02:15:03.140 --> 02:15:04.550 submit anything to the server. 02:15:04.550 --> 02:15:07.070 It keeps the user actually here. 02:15:07.070 --> 02:15:10.310 This will be a little scarier, too, but just so you've seen it. 02:15:10.310 --> 02:15:14.750 In hello3.html, this is actually a more common technique. 02:15:14.750 --> 02:15:19.378 Whereby you can listen for one other special event. 02:15:19.378 --> 02:15:22.170 It turns out when you load a web page, lots of stuff has to happen. 02:15:22.170 --> 02:15:23.690 It's got to be read top to bottom, left to right. 02:15:23.690 --> 02:15:27.110 It's got to download other files, the images, the sounds, the videos, and so 02:15:27.110 --> 02:15:27.660 forth. 02:15:27.660 --> 02:15:32.510 If you want to wait until the whole page has been read into memory essentially, 02:15:32.510 --> 02:15:36.080 you can use this event as well, DOMContentLoaded. 02:15:36.080 --> 02:15:39.660 That tree we drew earlier is what's called a DOM, document object model, 02:15:39.660 --> 02:15:42.830 which is just a fancy way of saying a tree in the computer's memory 02:15:42.830 --> 02:15:44.520 that represents the web page. 02:15:44.520 --> 02:15:46.790 So this is the syntax that you'll find that people 02:15:46.790 --> 02:15:52.010 use to tell the browser once the whole DOM, the whole tree has been loaded, 02:15:52.010 --> 02:15:54.950 then go ahead and execute this code. 02:15:54.950 --> 02:16:00.650 And it means that no matter what, the whole web page will be ready in order 02:16:00.650 --> 02:16:02.750 before this code is actually executed. 02:16:02.750 --> 02:16:04.730 And this ensures, for instance, that even 02:16:04.730 --> 02:16:07.760 though this script is at the top of my file 02:16:07.760 --> 02:16:11.420 and my form is at the bottom of my file, none of this code 02:16:11.420 --> 02:16:15.830 will get executed until the whole DOM is ready, all of the HTML 02:16:15.830 --> 02:16:19.940 has been read top to bottom, left to right. 02:16:19.940 --> 02:16:20.510 All right. 02:16:20.510 --> 02:16:23.052 Well, let's go ahead and make this a little more interesting, 02:16:23.052 --> 02:16:25.400 just to show you some of the capabilities of JavaScript 02:16:25.400 --> 02:16:26.760 within a browser nowadays. 02:16:26.760 --> 02:16:31.040 So if I open up maybe this one here, background.html. 02:16:31.040 --> 02:16:33.052 And let me open it up in the browser. 02:16:33.052 --> 02:16:35.719 And this is going to be super simple in terms of user interface. 02:16:35.719 --> 02:16:39.469 But here's a big white viewport, big body that's just white in color 02:16:39.469 --> 02:16:40.129 by default. 02:16:40.129 --> 02:16:41.969 But there's three buttons at top left. 02:16:41.969 --> 02:16:44.719 And if I click R, it makes the background red. 02:16:44.719 --> 02:16:46.190 G makes the background green. 02:16:46.190 --> 02:16:48.170 And B makes the background blue. 02:16:48.170 --> 02:16:51.530 What's interesting about this demo, sort of underwhelming 02:16:51.530 --> 02:16:54.170 as the user interface is, is it demonstrates that you 02:16:54.170 --> 02:16:57.320 can modify CSS using JavaScript. 02:16:57.320 --> 02:17:00.049 And HTML, CSS, and JavaScript are therefore 02:17:00.049 --> 02:17:02.420 very intertwined in the context of a browser. 02:17:02.420 --> 02:17:02.959 How? 02:17:02.959 --> 02:17:04.700 Here's the raw HTML. 02:17:04.700 --> 02:17:06.200 Here are the three buttons. 02:17:06.200 --> 02:17:08.750 And I've given them three separate IDs red, green, and blue, 02:17:08.750 --> 02:17:10.670 just so I can refer to the specific button. 02:17:10.670 --> 02:17:12.469 And notice what I've done here. 02:17:12.469 --> 02:17:14.750 I've declared a variable in JavaScript, which 02:17:14.750 --> 02:17:17.690 uses slightly different syntax of let as the keyword. 02:17:17.690 --> 02:17:20.209 Instead of int or char or string, you can 02:17:20.209 --> 02:17:22.820 use the keyword let, which essentially means let 02:17:22.820 --> 02:17:25.230 me create this variable called body. 02:17:25.230 --> 02:17:27.170 And this is just how, using query selector, 02:17:27.170 --> 02:17:29.478 I can select the body element from the web page. 02:17:29.478 --> 02:17:31.520 Because I'm going to use it three separate times. 02:17:31.520 --> 02:17:33.709 What do I want to do three separate times? 02:17:33.709 --> 02:17:35.059 For instance, this. 02:17:35.059 --> 02:17:38.930 I want to go into the document and select whatever 02:17:38.930 --> 02:17:41.240 element has the unique ID of red. 02:17:41.240 --> 02:17:44.959 I want to tell the browser to listen for this event, click. 02:17:44.959 --> 02:17:46.129 So we saw submit before. 02:17:46.129 --> 02:17:47.959 You can listen for clicks as well. 02:17:47.959 --> 02:17:51.799 When the click happens on this button, I want this function to be called. 02:17:51.799 --> 02:17:52.969 What does this function do? 02:17:52.969 --> 02:17:54.930 Something super, super simple-- 02:17:54.930 --> 02:17:59.840 all it does is it changes the body's styles, background color 02:17:59.840 --> 02:18:02.910 to be, quote, unquote red instead. 02:18:02.910 --> 02:18:04.430 So what's going on here? 02:18:04.430 --> 02:18:05.670 We didn't see this earlier. 02:18:05.670 --> 02:18:08.180 But it turns out in CSS there is actually 02:18:08.180 --> 02:18:10.593 a CSS property called background-color. 02:18:10.593 --> 02:18:11.760 And I can see it as follows. 02:18:11.760 --> 02:18:12.860 Let me reload this page. 02:18:12.860 --> 02:18:14.480 Open the browser's inspector. 02:18:14.480 --> 02:18:15.870 Open up elements. 02:18:15.870 --> 02:18:19.820 And if I hover over the body here, notice 02:18:19.820 --> 02:18:22.020 that there's no background color by default. 02:18:22.020 --> 02:18:28.940 But if I do in, say, lowercase, background color colon yellow, 02:18:28.940 --> 02:18:31.610 it immediately changes the background to yellow. 02:18:31.610 --> 02:18:37.400 Unfortunately, in JavaScript, you can't do background dash color. 02:18:37.400 --> 02:18:40.740 Why might this be? 02:18:40.740 --> 02:18:41.263 Yeah? 02:18:41.263 --> 02:18:42.180 AUDIENCE: [INAUDIBLE]. 02:18:42.180 --> 02:18:44.129 DAVID MALAN: It thinks it's minus or subtraction. 02:18:44.129 --> 02:18:44.370 Right? 02:18:44.370 --> 02:18:47.459 So I would wager there was a human at some point in the room designing 02:18:47.459 --> 02:18:50.309 JavaScript where they realized like, damn it. 02:18:50.309 --> 02:18:52.920 We shouldn't have used a hyphen in CSS. 02:18:52.920 --> 02:18:55.590 Because it's now going to be misinterpreted as a subtraction 02:18:55.590 --> 02:18:57.120 operator in JavaScript. 02:18:57.120 --> 02:19:01.740 So the way the JavaScript world solved this was whatever has a hyphen in it 02:19:01.740 --> 02:19:05.430 as background dash color, you change it in the JavaScript version 02:19:05.430 --> 02:19:09.030 thereof to be camelcase, so to speak, whereby there's this hump in the middle 02:19:09.030 --> 02:19:13.860 with it's a capital C, no hyphen, instead of a lowercase C instead. 02:19:13.860 --> 02:19:16.440 And I do this here, and I do this here so 02:19:16.440 --> 02:19:19.480 as to essentially listen for a click on any of those three buttons 02:19:19.480 --> 02:19:23.730 so that the end result is that it changes it from red to green to blue 02:19:23.730 --> 02:19:24.930 based on what I'm clicking. 02:19:24.930 --> 02:19:27.180 And here's where the developer tools get kind of cool. 02:19:27.180 --> 02:19:30.719 Notice at bottom right here, notice that as I click on this, 02:19:30.719 --> 02:19:33.690 the CSS of the page at bottom right is changing 02:19:33.690 --> 02:19:35.340 to match whatever is happening. 02:19:35.340 --> 02:19:39.090 So you can really see and understand what's going on underneath that hood 02:19:39.090 --> 02:19:39.980 there. 02:19:39.980 --> 02:19:40.480 All right. 02:19:40.480 --> 02:19:42.520 We have time for a few other demonstrations. 02:19:42.520 --> 02:19:46.840 Back in my day when I learned HTML, there was a bunch of hideous tags 02:19:46.840 --> 02:19:48.430 still in circulation. 02:19:48.430 --> 02:19:51.430 Among them was a blink tag, which literally, 02:19:51.430 --> 02:19:55.330 if you used blink and put words in between its open tag and close tag, 02:19:55.330 --> 02:19:58.090 you would get text on your screen just kind of doing this. 02:19:58.090 --> 02:20:01.600 Even uglier was what was called the marquee tab, which would actually 02:20:01.600 --> 02:20:03.850 scroll text across the screen like this. 02:20:03.850 --> 02:20:07.192 And no self-respecting website tends to have blinking text or scrolling 02:20:07.192 --> 02:20:07.900 text in this way. 02:20:07.900 --> 02:20:09.910 Because it's just tends to be ugly. 02:20:09.910 --> 02:20:13.510 However, even though the blink tag is among the few tags that's 02:20:13.510 --> 02:20:17.530 ever been removed from the language, you can bring it back 02:20:17.530 --> 02:20:18.610 with a bit of JavaScript. 02:20:18.610 --> 02:20:21.860 So here, for instance, is an example in blink.html. 02:20:21.860 --> 02:20:23.450 Here's a super simple page. 02:20:23.450 --> 02:20:26.090 The only thing in the body is hello, world. 02:20:26.090 --> 02:20:29.770 But there is a script tag up in my head of my page here. 02:20:29.770 --> 02:20:32.320 And let's see what's inside of this script tag. 02:20:32.320 --> 02:20:36.880 Well, I've defined on line 8 downward, a function called blink. 02:20:36.880 --> 02:20:38.090 What does it do? 02:20:38.090 --> 02:20:38.710 Well. 02:20:38.710 --> 02:20:40.990 I first declare a variable called body. 02:20:40.990 --> 02:20:44.110 And I get the body element using queryselector. 02:20:44.110 --> 02:20:45.880 I then ask this question. 02:20:45.880 --> 02:20:49.848 If the body's styles visibility property, 02:20:49.848 --> 02:20:51.640 which we haven't talked about yet is quote, 02:20:51.640 --> 02:20:56.320 unquote, hidden, then change the body's styles visibility property 02:20:56.320 --> 02:20:57.940 to be, quote, unquote, visible. 02:20:57.940 --> 02:21:03.042 Else, if it's not hidden, that is it's visible, change it to hidden instead. 02:21:03.042 --> 02:21:06.250 And here, too, this is another one of these left-hand, right-hand situations. 02:21:06.250 --> 02:21:10.180 I do not know why the opposite of visible is not invisible. 02:21:10.180 --> 02:21:11.290 It is, instead, hidden. 02:21:11.290 --> 02:21:15.080 So, again, arguably poor design, but this is what we have. 02:21:15.080 --> 02:21:16.910 How is this useful? 02:21:16.910 --> 02:21:17.830 Well, there turns out. 02:21:17.830 --> 02:21:20.080 In your browser, there's a JavaScript function 02:21:20.080 --> 02:21:23.260 called setinterval that's associated not with the document per se, 02:21:23.260 --> 02:21:26.500 but the window, which is another global variable that you just 02:21:26.500 --> 02:21:29.230 get automatic access to in the browser that 02:21:29.230 --> 02:21:33.640 allows you to call a function, any number of milliseconds, again 02:21:33.640 --> 02:21:35.330 and again and again. 02:21:35.330 --> 02:21:39.250 So if I want my text to blink every half a second or 500 milliseconds, 02:21:39.250 --> 02:21:43.240 I just use window.setinterval to call blink every 500 milliseconds. 02:21:43.240 --> 02:21:48.010 And notice, it's very important not to call blink here, as with parentheses, 02:21:48.010 --> 02:21:49.240 like in C or Python. 02:21:49.240 --> 02:21:51.730 Because I don't want to call blink at this moment in time. 02:21:51.730 --> 02:21:54.190 I just want to inform the setinterval function 02:21:54.190 --> 02:21:56.510 of the name of the blink function. 02:21:56.510 --> 02:21:58.420 So I just pass in the name blink. 02:21:58.420 --> 02:22:04.090 And if I go back to my directory listing, I open up blink.html, 02:22:04.090 --> 02:22:08.260 you'll see what I used to see in the late '90s, when HTML 1 was 02:22:08.260 --> 02:22:11.780 all the rage, like at the beginnings of a ugly websites, 02:22:11.780 --> 02:22:14.140 including my own personal home page at the time. 02:22:14.140 --> 02:22:16.640 My own personal home page, too, at the time, 02:22:16.640 --> 02:22:19.412 which is probably findable somewhere online in the archives, 02:22:19.412 --> 02:22:21.370 it was back in the days where you wouldn't just 02:22:21.370 --> 02:22:22.912 show people the content of your page. 02:22:22.912 --> 02:22:25.570 You had to click a Enter button to enter the web 02:22:25.570 --> 02:22:27.280 page and just really ridiculous. 02:22:27.280 --> 02:22:30.470 There's a lot of things in tech that you can do, but should not do. 02:22:30.470 --> 02:22:33.110 And the world has learned this as have I, the hard way. 02:22:33.110 --> 02:22:33.610 All right. 02:22:33.610 --> 02:22:35.650 Let's do a couple of final examples that are now 02:22:35.650 --> 02:22:37.660 representative of what modern websites do 02:22:37.660 --> 02:22:41.770 and what you and I take for granted on web apps and mobile apps alike. 02:22:41.770 --> 02:22:43.960 For instance, this feature of autocomplete. 02:22:43.960 --> 02:22:46.010 Case in point, when I went to google.com before 02:22:46.010 --> 02:22:48.160 and I started searching for cats or dogs or birds, 02:22:48.160 --> 02:22:50.860 it was trying to finish my thought and populating a dropdown 02:22:50.860 --> 02:22:52.690 with a bunch of different suggestions. 02:22:52.690 --> 02:22:55.880 I can actually do that myself in JavaScript as follows. 02:22:55.880 --> 02:23:01.480 Let me open up a file called large.js, which 02:23:01.480 --> 02:23:05.770 is a file that I made based on speller's own dictionary. 02:23:05.770 --> 02:23:09.580 Recall that we gave you a big list of words, like 100,000 plus words. 02:23:09.580 --> 02:23:11.890 I copied those into this JavaScript file. 02:23:11.890 --> 02:23:15.440 But I formatted them in what's called the JavaScript array. 02:23:15.440 --> 02:23:16.840 So JavaScript has arrays. 02:23:16.840 --> 02:23:20.050 They're more like Python lists than they are like C arrays. 02:23:20.050 --> 02:23:21.970 The syntax is square brackets. 02:23:21.970 --> 02:23:24.757 Let is my keyword to say give me a variable called 02:23:24.757 --> 02:23:27.340 WORDS, which is all caps because I'm going to use it globally. 02:23:27.340 --> 02:23:32.140 And here is a 100,000 words from that dictionary in this file. 02:23:32.140 --> 02:23:32.770 All right? 02:23:32.770 --> 02:23:35.890 Now let me close this file and open up the actual HTML 02:23:35.890 --> 02:23:38.440 file, autocomplete.html. 02:23:38.440 --> 02:23:40.040 Let me scroll down to the bottom. 02:23:40.040 --> 02:23:44.720 And you'll see that in this page in the body are two things. 02:23:44.720 --> 02:23:48.730 One, an input, so a text box so I can start typing words. 02:23:48.730 --> 02:23:51.400 And then, two, an unordered list that's empty. 02:23:51.400 --> 02:23:56.960 So there's no actual list items in that unordered list initially, 02:23:56.960 --> 02:23:58.510 but there is a lot of JavaScript. 02:23:58.510 --> 02:24:00.760 Here's how I'm including the large dictionary. 02:24:00.760 --> 02:24:03.520 And here's how I'm implementing autocomplete. 02:24:03.520 --> 02:24:05.410 So let me first show you what this does. 02:24:05.410 --> 02:24:10.210 Let me go back to my directory index, click on autocomplete.html. 02:24:10.210 --> 02:24:11.050 I'll zoom in. 02:24:11.050 --> 02:24:15.940 And if I type in C, I immediately get an unordered list of all words 02:24:15.940 --> 02:24:16.780 starting with C. 02:24:16.780 --> 02:24:18.478 If I type CA, it gets filtered further. 02:24:18.478 --> 02:24:21.770 But we can't see the difference because there's so many words starting with CA. 02:24:21.770 --> 02:24:23.770 CAT, the list is changing. 02:24:23.770 --> 02:24:25.960 CATS, the list is changing. 02:24:25.960 --> 02:24:29.290 And notice that if I were to open my developer tools, what 02:24:29.290 --> 02:24:33.190 gets really interesting is you can see this list being made in real time. 02:24:33.190 --> 02:24:34.150 Let me delete it. 02:24:34.150 --> 02:24:37.370 Notice that the UL at bottom left is now empty. 02:24:37.370 --> 02:24:42.400 But if I type in suddenly CATS, notice that the triangle appears and there 02:24:42.400 --> 02:24:46.390 are all of the list items that my JavaScript code is apparently 02:24:46.390 --> 02:24:48.310 dynamically creating. 02:24:48.310 --> 02:24:49.970 And indeed, how do I do this? 02:24:49.970 --> 02:24:52.840 Well, this one's more of a mouthful, but here's the idea. 02:24:52.840 --> 02:24:57.160 I used a queryselector function to get that input text box. 02:24:57.160 --> 02:25:02.182 I then add a listener to that input, listening for what's called key up. 02:25:02.182 --> 02:25:04.390 It turns out you can listen for the finger going down 02:25:04.390 --> 02:25:05.540 or the finger going up. 02:25:05.540 --> 02:25:08.530 So I'm waiting until the user lifts their finger off the keyboard, AKA, 02:25:08.530 --> 02:25:09.400 key up. 02:25:09.400 --> 02:25:11.930 When it hears that event, it should do the following. 02:25:11.930 --> 02:25:15.670 It's going to create a variable, a temp variable called HTML equal to quote, 02:25:15.670 --> 02:25:17.050 unquote nothing. 02:25:17.050 --> 02:25:19.420 In JavaScript, as an aside, you can use single quotes 02:25:19.420 --> 02:25:22.870 or double quotes for whatever reasons stylistically, JavaScript programmers 02:25:22.870 --> 02:25:24.400 tend to use single quotes. 02:25:24.400 --> 02:25:28.360 I can then say if that input has a value, because the humans typed 02:25:28.360 --> 02:25:31.402 in one or more letters, then iterate over 02:25:31.402 --> 02:25:32.860 all of the words in the dictionary. 02:25:32.860 --> 02:25:35.980 And we've not seen of before, but it's Javascript's equivalent 02:25:35.980 --> 02:25:37.630 of Python's for loop. 02:25:37.630 --> 02:25:42.670 If that word starts with whatever the input value is, go ahead and add-- 02:25:42.670 --> 02:25:47.380 that is concatenate to the HTML variable and open tag LI. 02:25:47.380 --> 02:25:51.610 Then, whatever the word is, using this JavaScript specific syntax, and then 02:25:51.610 --> 02:25:52.690 close the tag. 02:25:52.690 --> 02:25:57.190 And then lastly, using queryselector, grab the UL tag, 02:25:57.190 --> 02:26:00.820 go into its inner HTML, so to speak, inside of it, 02:26:00.820 --> 02:26:03.890 and change it to be this HTML I just created. 02:26:03.890 --> 02:26:07.060 And so in this way, using JavaScript, I can dynamically add to 02:26:07.060 --> 02:26:10.180 and subtract from the HTML in the page. 02:26:10.180 --> 02:26:14.470 There are so many other events here, too, clicking, submitting, key up, 02:26:14.470 --> 02:26:16.430 dragging, and dropping, and so forth. 02:26:16.430 --> 02:26:19.870 This is just some of the events that web pages and mobile apps can listen for. 02:26:19.870 --> 02:26:23.350 But we'll do one final one, which speaks to the power of browsers nowadays 02:26:23.350 --> 02:26:25.840 and even the implications for privacy. 02:26:25.840 --> 02:26:31.720 If I go into geolocation.html, it turns out 02:26:31.720 --> 02:26:36.520 you can figure out where in the world a user is with, like, three lines of code 02:26:36.520 --> 02:26:38.770 nowadays, assuming they've turned on location services 02:26:38.770 --> 02:26:40.450 and opted in on their device. 02:26:40.450 --> 02:26:43.920 Here, albeit cryptically, is a final global variable 02:26:43.920 --> 02:26:46.410 that comes with browsers today called navigator. 02:26:46.410 --> 02:26:50.320 It has a geolocation object associated with it, 02:26:50.320 --> 02:26:52.860 which comes with a function called getCurrentPosition. 02:26:52.860 --> 02:26:57.390 You can then specify or figure out the user's latitude and the user's 02:26:57.390 --> 02:26:57.893 longitude. 02:26:57.893 --> 02:27:00.060 And all I'm going to do is write these to the screen 02:27:00.060 --> 02:27:02.040 so I can see this demonstration live. 02:27:02.040 --> 02:27:05.370 So our very final demonstration here of JavaScript 02:27:05.370 --> 02:27:08.160 is going to be this one here for geolocation to show you how easy 02:27:08.160 --> 02:27:15.690 and how invasive even code can be if I click on geolocation and wait. 02:27:15.690 --> 02:27:19.020 There are my GPS coordinates, latitude and longitude. 02:27:19.020 --> 02:27:22.740 And to confirm as much roughly, let's go ahead and open up a browser, 02:27:22.740 --> 02:27:27.570 paste in those coordinates, click on the Google Maps result that comes up first. 02:27:27.570 --> 02:27:32.250 Zoom in, in, turn on satellite mode. 02:27:32.250 --> 02:27:35.760 And in-- and I'm not quite in that corner of the building. 02:27:35.760 --> 02:27:38.820 But I'm presumably close to an access point that Google has known about 02:27:38.820 --> 02:27:40.620 and associates with my GPS coordinates. 02:27:40.620 --> 02:27:45.550 It's that easy when you actually use something like Uber or Lyft or the like 02:27:45.550 --> 02:27:49.180 to figure out where the user is by just asking their browser via code 02:27:49.180 --> 02:27:50.030 like this. 02:27:50.030 --> 02:27:52.820 So that's it for HTML, CSS, and JavaScript. 02:27:52.820 --> 02:27:54.820 In the problem set, you'll explore all of these. 02:27:54.820 --> 02:27:57.280 One more lecture to go in which we'll combine all of these. 02:27:57.280 --> 02:27:59.470 But until then we'll see you next time. 02:27:59.470 --> 02:28:04.780 [MUSIC PLAYING] Buffering, OK. 02:28:04.780 --> 02:28:07.830 Josh, nice. 02:28:07.830 --> 02:28:08.986 [INAUDIBLE], oh! 02:28:08.986 --> 02:28:13.210 [LAUGHING] 02:28:13.210 --> 02:28:14.440 [INAUDIBLE] 02:28:14.440 --> 02:28:15.310 No, oh, wait. 02:28:21.242 --> 02:28:22.200 That was amazing, Josh. 02:28:26.705 --> 02:28:27.205 Sophie! 02:28:30.388 --> 02:28:34.600 [LAUGHTER] 02:28:34.600 --> 02:28:36.920 Amazing. 02:28:36.920 --> 02:28:39.330 That was perfect. 02:28:39.330 --> 02:28:40.450 [INAUDIBLE] 02:28:40.450 --> 02:28:42.350 [LAUGHTER] 02:28:42.350 --> 02:28:45.920 I think I-- 02:28:45.920 --> 02:28:47.720 [INAUDIBLE] 02:28:47.720 --> 02:28:48.650 AUDIENCE: [INAUDIBLE]. 02:28:48.650 --> 02:28:49.358 DAVID MALAN: Guy. 02:28:53.280 --> 02:28:54.480 That was amazing. 02:28:54.480 --> 02:28:55.505 Thank you all. 02:28:55.505 --> 02:28:56.130 AUDIENCE: Good. 02:28:56.130 --> 02:28:59.180 [APPLAUSE]