CS50 Video Player
    • 🧁

    • 🍦

    • 🍇

    • 🍿
    • 0:00:00Introduction
    • 0:01:15TCP/IP
    • 0:15:39Ports
    • 0:19:25DNS
    • 0:25:10DHCP
    • 0:28:52HTTP
    • 0:40:40Inspect
    • 0:41:29Status Codes
    • 0:49:41HTML
    • 1:43:56Regular Expressions
    • 1:51:56CSS
    • 2:24:15Bootstrap
    • 2:28:16JavaScript
    • 3:00:54Background
    • 3:05:18Blink
    • 3:07:40Autocomplete
    • 0:00:00[MUSIC PLAYING]
    • 0:01:14DAVID MALAN: All right, this is CS50.
    • 0:01:18And this week, we begin to introduce web programming.
    • 0:01:20That is still writing code ultimately, but whereby the user interface
    • 0:01:24is now going to be a browser, or even a mobile device ultimately.
    • 0:01:27To do that, we're going to introduce you to, first, some fundamentals of how
    • 0:01:30the internet works itself.
    • 0:01:32Then we'll transition to a language, but not technically a programming language,
    • 0:01:36called HTML-- hypertext markup language, followed
    • 0:01:39by another language, though also not a programming language quite yet, called
    • 0:01:43Cascading Style Sheets.
    • 0:01:44And ultimately, we'll reintroduce some proper programming,
    • 0:01:47so as to automate much of what we'll be now discussing.
    • 0:01:50But first, let's begin with what underlies the World Wide
    • 0:01:52Web, or web for short, which is the internet itself.
    • 0:01:55And it's perhaps simplest to think of the internet
    • 0:01:57as the underlying plumbing that allows us to get data from point A to point B.
    • 0:02:01So there's lots of computers in the world nowadays.
    • 0:02:04They are all physically connected somehow or virtually connected,
    • 0:02:07with wires or wirelessly.
    • 0:02:09And if you can imagine, each of those computers somehow
    • 0:02:11being able to talk to one another, that then
    • 0:02:13is our internet, an internetworked set of computers
    • 0:02:17that can somehow intercommunicate.
    • 0:02:19But it wasn't always that way, even though you and I
    • 0:02:21take for granted the fact that we can all talk electronically nowadays online.
    • 0:02:25Indeed, early on, there were only a few points
    • 0:02:27of presence on this here internet.
    • 0:02:29So, for instance, here is the United States in 1969,
    • 0:02:32when ARPANET was developing what we now know as the internet.
    • 0:02:37And there were only a few locations here, primarily on the West Coast.
    • 0:02:40And those universities initially were indeed able to intercommunicate,
    • 0:02:43sending the first emails, for instance, even before there was a worldwide web.
    • 0:02:48Eventually, some other universities came online--
    • 0:02:50Harvard, for instance, among them on the East Coast of the United States.
    • 0:02:53And then East Coast and West Coast were suddenly
    • 0:02:55able to intercommunicate, as well as with emails and the like.
    • 0:02:59But in order to get data from point A to point B,
    • 0:03:02so to speak-- in this case, West Coast to East Coast, not to mention
    • 0:03:05the rest of the world, once more and more servers were
    • 0:03:08introduced to this mix, we needed to somehow route the information.
    • 0:03:12And so one of our first terms of art today will be that of "routers."
    • 0:03:15Routers are simply computers, or technically servers,
    • 0:03:17whose purpose in life is to route information from one point to another.
    • 0:03:22Now, these servers might look a little different from your laptops and phones
    • 0:03:25certainly.
    • 0:03:26They might look different from your desktop PCs.
    • 0:03:28But they're still just PCs, computers that maybe have a different form
    • 0:03:31factor, a different shape, but that typically
    • 0:03:33live in what are called data centers, like big warehouses that
    • 0:03:36store lots and lots of computers.
    • 0:03:38Those computers have lots of cables that interconnect them
    • 0:03:41with other computers there, as well as other warehouses and data centers,
    • 0:03:44much like the dots you just saw on the screen.
    • 0:03:46But the software that those servers are running
    • 0:03:49give them the ability to route information
    • 0:03:52from one location to another.
    • 0:03:54So if I here am representing the server, essentially, these devices
    • 0:03:57need to decide when they receive some information-- an email, a web
    • 0:04:01page, or the like, does it go this way or this way,
    • 0:04:03or this way or this other way.
    • 0:04:05And they use software to figure all of that out.
    • 0:04:07Now, here, we have a visualization, in the spirit of using Zoom,
    • 0:04:12from some of our former teaching fellows who acted this out.
    • 0:04:14So if you can imagine a teaching fellow named
    • 0:04:16Phyllis wanting to send, say, an email to a teaching fellow
    • 0:04:20whom you might know, in fact named Brian,
    • 0:04:22well, Phyllis might put that message in some kind of envelope-- here, physical.
    • 0:04:26But think of it as virtual as well.
    • 0:04:28And she's going to hand that envelope off to the next router near her.
    • 0:04:33And maybe it's above, below, to the left, or the right.
    • 0:04:36But generally, this envelope is going to take some path from point A,
    • 0:04:40Phyllis, to point B-- no pun intended, Brian.
    • 0:04:44Let's take a look.
    • 0:04:44[GIUSEPPE VERDI, "BRINDISI FROM LA TRAVIATA"]
    • 0:05:14Wonderful.
    • 0:05:14So many thanks to CS50's team for making that visualization possible,
    • 0:05:18and how well it worked, getting the data up,
    • 0:05:20down, left, right from Phyllis to Brian ultimately.
    • 0:05:23But how were those teaching fellows-- how were those routers making decisions?
    • 0:05:27Well, in this case, we actually practiced quite a bit.
    • 0:05:29But in the real world, it's all dynamically
    • 0:05:31figured out via software in some form.
    • 0:05:33And the language that routers typically talk,
    • 0:05:36in order to figure out how to get from point A to point B,
    • 0:05:39is a language, or really a protocol, called
    • 0:05:41TCP/IP, which is technically two protocols
    • 0:05:45together that each do a little something different.
    • 0:05:47And in fact, let's focus on the one that's probably generally
    • 0:05:50familiar to many of you, namely IP.
    • 0:05:52So even if you're not a computer person, odds are at some point,
    • 0:05:55you've heard of IP, perhaps in the context of an IP address.
    • 0:06:00IP stands for Internet protocol.
    • 0:06:01And you can think of this as a language, or a protocol
    • 0:06:04to be more proper, that computers speak when trying
    • 0:06:07to send information between each other.
    • 0:06:10And a protocol is really just a set of conventions.
    • 0:06:12And so, for instance, in the human world,
    • 0:06:14much of it, if I were to extend my hand to you upon greeting you
    • 0:06:17for the first time, most likely, depending on where you're from
    • 0:06:19would know instinctively to reach out with your hand and shake my hand,
    • 0:06:23completing a human protocol.
    • 0:06:25So it's not so much a language that we're speaking,
    • 0:06:27but a set of conventions.
    • 0:06:28And indeed, that's what TCP and IP are.
    • 0:06:31But IP is very specifically focused on addressing servers in the world.
    • 0:06:36So what do I mean by that?
    • 0:06:38Well, it turns out that every computer in the world that's
    • 0:06:40connected to the internet has what's called, indeed,
    • 0:06:42an IP address, a unique identifier that typically is of this format--
    • 0:06:47something dot something dot something dot
    • 0:06:50something, where each of those somethings
    • 0:06:52is a number, a simple integer.
    • 0:06:54Those integers are typically 0 through 255,
    • 0:06:58which is to say that you have four values in a typical IP address that's
    • 0:07:02between 0 and 255.
    • 0:07:04If you're doing some mental math now, you might recognize those numbers.
    • 0:07:07Any time you're counting from 0 to 255, you're using 8 bits, or 1 byte,
    • 0:07:12which is to say that an IP address, as represented here
    • 0:07:16with these hash symbols, is 32 bits in total, or 4 bytes.
    • 0:07:20So your mind can immediately start to wander if you do some of that mental
    • 0:07:23math to conclude that, oh, it would seem that you can have no more than,
    • 0:07:27per past discussions, 4 billion IP addresses,
    • 0:07:32because 2 to the 32nd power gives us four billion,
    • 0:07:34especially if we don't have to worry about negative numbers,
    • 0:07:36which is to imply that there can only be 4 billion devices on the internet
    • 0:07:41in total.
    • 0:07:42Now that's a lot.
    • 0:07:43But there's also a lot of humans in the world.
    • 0:07:45And there's a lot of humans with multiple devices, laptops,
    • 0:07:47desktops, not to mention all of those servers and Internet of Things devices.
    • 0:07:50So the world not only uses this format nowadays,
    • 0:07:54which is technically called IP version 4.
    • 0:07:56There's also a new and improved version of IP addresses known
    • 0:07:59as IP version 6, which the world is starting to use,
    • 0:08:03especially some of the bigger companies and internet service providers
    • 0:08:06out there.
    • 0:08:07But odds are, your computer and my computer
    • 0:08:09still tend to use IPv4 for this format.
    • 0:08:12So we'll focus on this one, if only because you're
    • 0:08:14likely to see it in the near term in the real world as such.
    • 0:08:18So how does this all work?
    • 0:08:20Well, this is perhaps the most cryptic-looking diagram
    • 0:08:22I could find that represents exactly how IP works.
    • 0:08:27Now, this is ASCII art, and this is actually
    • 0:08:29a diagram from the specification, or RFC-- request for comments,
    • 0:08:33that defines how IP, the internet protocol, is supposed to work.
    • 0:08:38And what this diagram is implying is that, any time you
    • 0:08:40want to send a message over the internet, using this protocol called IP,
    • 0:08:45you first have to make sure that you write an address on the envelope.
    • 0:08:48And you write another address on the envelope that is your sender address
    • 0:08:52or source address.
    • 0:08:54And the way you do this, of course, is not something physical in an envelope.
    • 0:08:57But rather, you use a sequence of bits that
    • 0:09:00indicates what the source IP address should be
    • 0:09:03and what the destination IP address should be.
    • 0:09:06And then let me wave my hand.
    • 0:09:07There's a whole bunch of other bits being used any time you send information
    • 0:09:12on the internet, in addition to that source address and destination address.
    • 0:09:16So this, though, is essentially written on the outside of this envelope,
    • 0:09:19in this here way.
    • 0:09:21Now, what does that really mean?
    • 0:09:22Well, let me make this a little more concrete.
    • 0:09:24And just for the sake of discussion, suppose that Phyllis, in our example,
    • 0:09:28was sending indeed an envelope virtually to Brian, from point A to point B.
    • 0:09:32Then let's suppose for the sake of discussion that Brian's IP address is
    • 0:09:36a number like 1.2.3.4.
    • 0:09:40So metaphorically, what Phyllis would do--
    • 0:09:42or really Phyllis's computer would do is write
    • 0:09:44that IP address right in the middle of the envelope, just
    • 0:09:46like a human would when addressing a letter in the real world.
    • 0:09:49But so that Brian could potentially reply
    • 0:09:52to her, either with new information, or at least
    • 0:09:54to acknowledge receipt of this same envelope,
    • 0:09:56she's also going to put her IP address in the top left corner.
    • 0:09:59And maybe her IP address is 5.6.7.8.
    • 0:10:04Suffice it to say, I'm making up these numbers to keep them simple.
    • 0:10:07But they could be actual IP addresses because they
    • 0:10:09fall into that format of something dot something dot something dot something.
    • 0:10:13So now when Phyllis hands this envelope off to the person,
    • 0:10:17or the router next to her, that router can look at the same envelope
    • 0:10:22and realize, oh, this is going to address 1.2.3.4.
    • 0:10:26I might not be physically next to Brian, that IP address.
    • 0:10:29But I can at least hand it off to some other router
    • 0:10:32that might be closer to Brian, and therefore
    • 0:10:34know how to get it to him eventually.
    • 0:10:37And so what routing is all about is exactly that-- these servers passing off
    • 0:10:41metaphorically these envelopes back and forth, back and forth,
    • 0:10:45ideally getting them closer to their destination.
    • 0:10:47Now, unlike the real world, where the shortest distance between two points
    • 0:10:50is a straight line, you might recall that Phyllis didn't actually
    • 0:10:53hand that envelope up and to the right diagonally to Brian.
    • 0:10:57Rather, it went up and down, and it didn't necessarily
    • 0:10:59follow the shortest path.
    • 0:11:01But in the real world, routers might, at least ideally,
    • 0:11:04route data in the fastest way possible.
    • 0:11:07So even though they might traverse geographically disparate routes,
    • 0:11:10sometimes, because the servers are faster or less busy,
    • 0:11:13it might make more sense to spend a little more distance
    • 0:11:16to get the data there based on how the servers are configured.
    • 0:11:19And also, finances might be involved.
    • 0:11:21There's a lot of big internet service providers in the world.
    • 0:11:23The Comcasts, the Verizons of the world in the United States,
    • 0:11:26for instance, they might have relationships
    • 0:11:28with other internet service providers such
    • 0:11:31that they want to ideally keep data on their network,
    • 0:11:34so as to not have to pay fees to route the data on someone else's network,
    • 0:11:38so to speak.
    • 0:11:38So there's lots of ingredients that go into deciding
    • 0:11:41how to get the data from point A to point
    • 0:11:43B. But in general, it doesn't really take more than 30 hops, so to speak--
    • 0:11:4830 passings of the envelope from router to router, because at that point,
    • 0:11:52it's probably stuck in a loop if it's going
    • 0:11:53on for more than, say, 30 such hops.
    • 0:11:56So what's really written on the envelope is more arcane information like this,
    • 0:12:00but it's just patterns of bits.
    • 0:12:02So it's as though Phyllis was just writing patterns of zeros and ones
    • 0:12:04on this envelope that adhere to this pattern.
    • 0:12:07And then inside of the envelope is what Phyllis might actually
    • 0:12:11want to send Brian.
    • 0:12:12Now, what might that be?
    • 0:12:13Well, as you know, the internet is filled with cats.
    • 0:12:16And for instance, here is one such picture of a very happy cat.
    • 0:12:20Unfortunately, it's a pretty big picture.
    • 0:12:22And if you can imagine this being maybe a video instead,
    • 0:12:24it would be even bigger in terms of its file size, even more bytes.
    • 0:12:27And so what computers typically do is additionally
    • 0:12:30fragment information when they're sending it on the internet.
    • 0:12:33So rather than try to shove this big cat inside of that envelope, what
    • 0:12:36a computer would do-- even though this feels a little sacrilegious,
    • 0:12:39would be to tear happy cat in two, maybe even into four parts,
    • 0:12:44and then put each of these fragments inside of an envelope, followed
    • 0:12:48by another fragment inside of another envelope.
    • 0:12:52At that point, to be fair, Phyllis had better
    • 0:12:55address the second envelope as well, probably
    • 0:12:57with the same amount of information.
    • 0:12:59So she would probably put 1.2.3.4 on the middle of the envelope,
    • 0:13:03and 5.6.7.8 in the top of the envelope to indicate that this one too is
    • 0:13:09destined for Brian's IP address as well.
    • 0:13:14Unfortunately, once we start chopping things up into fragments like this,
    • 0:13:18it's no longer sufficient for the outside of the envelope
    • 0:13:21to indicate only the destination.
    • 0:13:24Because what if they arrive in this order or maybe this order,
    • 0:13:27or some other order altogether?
    • 0:13:29After all, there's nothing stopping Phyllis
    • 0:13:30from handing one envelope here and another envelope here,
    • 0:13:33so long as they eventually make their way to Brian.
    • 0:13:35So he's going to need a little more information in order
    • 0:13:38to reassemble this data at its destination,
    • 0:13:41and know ultimately just how many total envelopes were sent to him.
    • 0:13:46So how can we go about doing that?
    • 0:13:48Well, let me propose that we introduce another protocol
    • 0:13:51as well that will help us guarantee delivery of this information.
    • 0:13:54So there's this other protocol, TCP/IP.
    • 0:13:57And it's typically written or said in the same breath as IP,
    • 0:14:00such that we talk about TCP/IP.
    • 0:14:03But it's a separate protocol.
    • 0:14:04And TCP's perfect purpose in life is to solve a few problems.
    • 0:14:08For instance, among the problems that TCP does for us is,
    • 0:14:12it ensures that we acknowledge exactly how many envelopes were sent.
    • 0:14:17So, for instance, on the outside of this envelope,
    • 0:14:20we might write not only the destination and the source address.
    • 0:14:23But I'm also going to say something like 1 of 4
    • 0:14:27in the memo field of the envelope.
    • 0:14:29We don't often use this in the real world.
    • 0:14:31But if you were to, you could put it down there.
    • 0:14:33And then in the other envelope, I might write 2 of 4.
    • 0:14:36And so now, Brian, upon receipt of that, can see that, oh,
    • 0:14:40this is the second such envelope and.
    • 0:14:41I could keep doing this for number 3 and number 4.
    • 0:14:44And what this allows Brian to do ultimately,
    • 0:14:45is not only confirm that, OK, I got pieces 1 and 2 and 3 and 4.
    • 0:14:50He can also infer if he's missing any pieces,
    • 0:14:53lest he have a very unhappy cat that's missing an entire quadrant of that there
    • 0:14:58picture.
    • 0:14:58So TCP accordingly can help Phyllis guarantee delivery
    • 0:15:03by establishing an additional protocol on these virtual envelopes that
    • 0:15:07dictates that we also keep track of the sequence numbers of these here
    • 0:15:11envelopes, so that Brian can infer if anything has been missed.
    • 0:15:14Otherwise, he can acknowledge, thank you, Phyllis, I got all four of these.
    • 0:15:18But there's another problem that TCP solves
    • 0:15:20for us, which is that the internet itself
    • 0:15:22does so many different things nowadays.
    • 0:15:24We've got email.
    • 0:15:25We've got the World Wide Web-- more on that soon.
    • 0:15:28We've got video conferencing.
    • 0:15:30We've got streaming media, and so many other applications
    • 0:15:33that run on top of the physical infrastructure that is the internet.
    • 0:15:36So what else does TCP do?
    • 0:15:38It also defines a convention for what we're going to call ports.
    • 0:15:42A port is simply a unique numeric identifier
    • 0:15:45for a specific internet service.
    • 0:15:48And years ago, a bunch of humans decided to standardize
    • 0:15:51what these port numbers are.
    • 0:15:52So, for instance, a bunch of humans in a room decided that, you know what?
    • 0:15:55To uniquely identify worldwide web traffic, let's use port 80--
    • 0:16:00so the number, the integer 80.
    • 0:16:02But if it's securely sent, using not HTTP but HTTPS-- more on those also
    • 0:16:08a bit later, then it's going to use port 443.
    • 0:16:12And there's other numbers as well.
    • 0:16:1325, for instance, is commonly used for email.
    • 0:16:1553 is commonly used for DNS.
    • 0:16:17And there's other integers as well-- much longer list than the two
    • 0:16:20here on the screen.
    • 0:16:21What Phyllis can then do is, if she specifically
    • 0:16:23wants to request a web page of Brian, whereby
    • 0:16:26Brian is now not only the recipient, but a web server that has pages of content--
    • 0:16:30what Phyllis can do on the outside of this envelope is add essentially
    • 0:16:34a colon, and then a port number, such that now the destination is still
    • 0:16:381.2.3.4:80.
    • 0:16:41And this indicates that when Brian receives this envelope, he as a server
    • 0:16:45knows that this envelope is destined for not the email server, not
    • 0:16:48the video conferencing server, not the streaming media server,
    • 0:16:52but rather for the web server that happens
    • 0:16:54to be running at Brian's location.
    • 0:16:56And in fact, this is because, as an aside, when we talk about a server,
    • 0:17:00a server, singular, can actually do multiple things.
    • 0:17:03A single server can handle email and web and video conferencing and more.
    • 0:17:08And so what these port numbers ultimately allow servers to do
    • 0:17:11is to multiplex, so to speak, or distinguish which server
    • 0:17:16or which type of service should be handling this inbound request.
    • 0:17:20So Brian replies with a web page, and not, for instance, an email or something
    • 0:17:25that's inappropriate like that.
    • 0:17:27Meanwhile, if we want to get our hands a little dirtier with the underlying
    • 0:17:32format of these things, even though I wrote it on the outside of the envelope
    • 0:17:35as just colon 80, what's really happening underneath the hood
    • 0:17:38is a little something more complicated like this,
    • 0:17:40whereby Phyllis would write not only a destination port,
    • 0:17:43but also a source port.
    • 0:17:45So it turns out, even Phyllis uses a unique identifier,
    • 0:17:47so that Brian knows how to address his response to her specifically.
    • 0:17:52And there's that sequence number and the acknowledgment number
    • 0:17:55that I alluded to earlier, whereby TCP ensures
    • 0:17:58that we can keep track of 1 of 4, 2 of 4, 3 of 4, 4 of 4.
    • 0:18:03So long story short, what TCP/IP together allow us to do
    • 0:18:07is uniquely address computers on the internet
    • 0:18:10as by using IP addresses in a standard way,
    • 0:18:13and to guarantee delivery of data between two points
    • 0:18:16by using the sequence numbers, as well as these port numbers, to make sure
    • 0:18:20that the data gets where it needs to go.
    • 0:18:22Now, I'm using "guarantee" a little bit generously.
    • 0:18:25If the internet goes down, the power goes out,
    • 0:18:27TCP is not going to get data from point A to point B.
    • 0:18:30But assuming the internet itself is working,
    • 0:18:32that is what these protocols together do.
    • 0:18:36But to recap then, with TCP/IP, we have this mechanism
    • 0:18:40for addressing computers uniquely, much like we do already in the real world.
    • 0:18:45And in fact, Sanders Theatre, for instance, is 45 Quincy Street,
    • 0:18:48Cambridge, Massachusetts, 02138 USA.
    • 0:18:51That is exactly what you could write on the outside of an envelope
    • 0:18:53to mail it physically to Sanders Theatre.
    • 0:18:56What we're talking about, then, with these virtual envelopes
    • 0:18:59is exactly the same idea, but in a way that
    • 0:19:02supports servers sending the same data.
    • 0:19:04And it turns out that just dealing with numbers, like IP addresses,
    • 0:19:07is much easier than full text, like things
    • 0:19:10on the outside of our own envelopes.
    • 0:19:12Indeed, imagine how much happier the mail service, the postal workers,
    • 0:19:16would be if all we were writing were very clean numbers
    • 0:19:18on the outside of the envelopes And they wouldn't
    • 0:19:20have to read messy handwriting with much more complicated strings of text.
    • 0:19:25All right, so it stands to reason, then, that this seems
    • 0:19:29to work, at least as I've told it here.
    • 0:19:31But of course, none of us probably use IP addresses explicitly every day.
    • 0:19:36In fact, when you go to a website, you probably
    • 0:19:38type google.com or CS50.ai or other such domain names.
    • 0:19:44And yet, here I am telling this story that, underneath the hood, a la Phyllis
    • 0:19:49communicating with Brian, everything uses IP addresses,
    • 0:19:52not to mention port numbers and sequence numbers,
    • 0:19:54on the outside of these envelopes.
    • 0:19:56Well, suffice it to say, your Mac, your PC, your phone
    • 0:19:59is somehow figuring out how to write those numbers on the envelope,
    • 0:20:03even though you and as the humans, are only
    • 0:20:05typing in actual domain names, like google.com, CS50.ai, and the like.
    • 0:20:10So how does that all work?
    • 0:20:12Well, in the world of the internet, there's other types of servers
    • 0:20:14out there as well, not just routers that route data from point A
    • 0:20:17to point B. There's also DNS servers as well-- domain name system servers.
    • 0:20:22And these typically live inside of your internet service provider's network
    • 0:20:26or on your university's campus or in your company's office,
    • 0:20:30or somewhere in-between you and the rest in the world.
    • 0:20:34And what a DNS server does, in short, is translate domain names to IP addresses,
    • 0:20:40so that you and I as humans can type the more user-friendly version of google.com
    • 0:20:44and CS50.ai And you and I don't have to worry about or figure out
    • 0:20:48what the underlying IP addresses are.
    • 0:20:50Now, it turns out the implementation of a DNS server
    • 0:20:52follows a familiar paradigm.
    • 0:20:54We've long talked about dictionaries now,
    • 0:20:56an abstract data type that allows us to associate keys with values.
    • 0:21:00Well, in the case of a DNS server, they essentially
    • 0:21:02have, inside of their memory, a two-column sheet or table,
    • 0:21:07the first of which is the domain name, the second of which is an IP address.
    • 0:21:10Technically, those domain names are called fully qualified domain names
    • 0:21:14because it might be something like google.com or www.google.com,
    • 0:21:19or some other subdomain therein.
    • 0:21:22So what you type would be in the left-hand column here.
    • 0:21:25And what gets written on the envelope would be in the right-hand column here
    • 0:21:29instead.
    • 0:21:30So now this table, you could imagine it being very, very big.
    • 0:21:34I mean, there's thousands, hundreds of thousands, millions
    • 0:21:36of domain names out there nowadays.
    • 0:21:39And surely, your phone in your pocket doesn't know about all of them.
    • 0:21:42But that's OK because the design of DNS is actually
    • 0:21:45to be very hierarchical, so that your internet service provider probably
    • 0:21:50has its own DNS server that can translate many domain
    • 0:21:53names to IP addresses, especially if they're popular ones.
    • 0:21:56And therefore, they have looked up the IP address
    • 0:21:58already in the past for their customers.
    • 0:22:00But if you visit a random website that's not very popular,
    • 0:22:03and no one has visited at all or recently,
    • 0:22:06your internet service provider can recursively
    • 0:22:09ask another DNS server for the answer to the question, what
    • 0:22:12is the IP address of that domain name.
    • 0:22:15And in fact, around the world, there are what are called root servers,
    • 0:22:18a small number of servers that, for instance,
    • 0:22:21know about all of the .coms and all of the .orgs and all of the .govs,
    • 0:22:26and similarly for other countries as well, whereby those servers--
    • 0:22:30even if they don't know the exact IP address,
    • 0:22:32they might know the IP address of another DNS server
    • 0:22:35who does have the answer.
    • 0:22:37And so long story short, if you've ever bought, or really
    • 0:22:39rented, your own domain name before, or if that's
    • 0:22:42something you choose to do in the future, essentially what you're doing,
    • 0:22:45when you pay someone some number of dollars per year to buy a domain name,
    • 0:22:49is asking them to add an entry to their DNS server,
    • 0:22:53or someone's DNS server, that associates that domain name henceforth
    • 0:22:56with a specific IP address of your server or servers.
    • 0:23:00So someone somewhere is doing that for you.
    • 0:23:03But the whole process is indeed recursive,
    • 0:23:06because if your ISP doesn't know the answer,
    • 0:23:08it can maybe ask another DNS server, or maybe these root DNS servers as well.
    • 0:23:12Your own Mac, your PC, your phone might itself
    • 0:23:15cache or remember these answers though, too,
    • 0:23:18because it's a little silly in terms of design
    • 0:23:21if your phone or your laptop or desktop has to constantly ask that same question
    • 0:23:25every time you visit google.com.
    • 0:23:28Odds are the IP address is not going to change,
    • 0:23:30or at least it's not going to change that frequently.
    • 0:23:32However, again, if you've ever set up your own domain name,
    • 0:23:35if you've ever moved it around or something has changed about it,
    • 0:23:38sometimes you can break a website by changing its IP address,
    • 0:23:41because there's lots of servers in the world that have cached--
    • 0:23:44C-A-C-H-E-D, or remembered the old IP address.
    • 0:23:49But thankfully, the other feature that DNS provides is expiration dates.
    • 0:23:52So essentially, the answer to the question,
    • 0:23:55what is the IP address for this domain name,
    • 0:23:57typically expires after a few seconds, a few minutes, a few hours, a few days.
    • 0:24:02Unless you really mess things up and say, don't expire this for a year,
    • 0:24:05then your website could, in fact, be a dead end somehow.
    • 0:24:08So this is worth knowing for future web developers doing
    • 0:24:12things in the real world.
    • 0:24:13So DNS, to recap then, simply converts domain names to IP addresses.
    • 0:24:18And technically, it can go in the other direction as well.
    • 0:24:21And so when you as a human go to a browser on a laptop, desktop,
    • 0:24:25or phone and type in google.com, Enter, or CS50, Enter, what essentially happens
    • 0:24:30is your device checks its local cache to see if it's already
    • 0:24:35been asked that question before.
    • 0:24:36And if it has, it just immediately knows the IP address,
    • 0:24:39writes it on the outside of the envelope, so to speak,
    • 0:24:40and sends out your data.
    • 0:24:42If it doesn't know the answer, your computer
    • 0:24:44is going to ask the local DNS server, which
    • 0:24:46might ask another DNS server, which might ask another DNS server.
    • 0:24:49But recursively, you will eventually get your answer
    • 0:24:51if that domain name actually exists.
    • 0:24:54And at that point, your computer can indeed
    • 0:24:56write the correct IP address on the outside of the envelope,
    • 0:24:59add any sequence numbers, add any port numbers.
    • 0:25:01And voila, it's on its way from point A to point B. So that, then, is DNS.
    • 0:25:09How about one other acronym that's a bit related here adhere too-- that of DHCP?
    • 0:25:14And let me assure that it's not really that important to memorize
    • 0:25:17what all of these acronyms stand for.
    • 0:25:20But rather, it is useful, I think, to generally know what they in fact do.
    • 0:25:23So DHCP is Dynamic Host Configuration Protocol.
    • 0:25:27So there we have it-- another protocol, a set of conventions.
    • 0:25:30And the purpose of DHCP is to actually give your computer
    • 0:25:35an IP address when it boots up.
    • 0:25:38This wasn't always the case back in the day.
    • 0:25:40If you've had internet connectivity for a while,
    • 0:25:42some technician probably would come to your house when you or your family
    • 0:25:45signed up for internet service.
    • 0:25:47They would probably have a sheet of paper
    • 0:25:48on which was your personal IP address.
    • 0:25:51And if you wanted to connect your PC to the internet,
    • 0:25:53they would type that IP address manually into your computer,
    • 0:25:57so that your computer knows what IP address
    • 0:25:59to use when talking to other servers.
    • 0:26:01That's not particularly scalable.
    • 0:26:03That's not particularly maintainable.
    • 0:26:04You don't want the technician to have to come out just
    • 0:26:06to make a change or something like that.
    • 0:26:08And you probably want to be able to use multiple devices as well.
    • 0:26:11And so nowadays, what most computers use is DHCP to dynamically figure out
    • 0:26:16what is their IP address.
    • 0:26:18And so nowadays, when you first open your laptop in the morning
    • 0:26:21or boot up your PC or take out your phone--
    • 0:26:23if you haven't used it in a while, and therefore it
    • 0:26:26no longer has an IP address, because these two expire
    • 0:26:28after some amount of time, your phone, your device
    • 0:26:31will broadcast a message like, what is my IP address?
    • 0:26:34And hopefully, on the nearby network in your home, in your company,
    • 0:26:39at your university, or in your internet service provider more generally,
    • 0:26:42you will hear an answer, oh, use the IP address 5.6.7.8, for instance,
    • 0:26:49in the case of Phyllis, or 1.2.3.4 in the case of Brian's recipient address
    • 0:26:53as well.
    • 0:26:54So the people who run these servers, the internet service providers of the world,
    • 0:26:58the system administrators at your company or campus,
    • 0:27:01they can come up with the rules via which these IP addresses are assigned
    • 0:27:05or who gets what number.
    • 0:27:06But ultimately, DHCP is just another protocol
    • 0:27:09that governs how your device gets its IP address.
    • 0:27:14But that's not quite everything.
    • 0:27:15It's actually neat.
    • 0:27:17DHCP servers also tell your computer what DNS server to use.
    • 0:27:22They give you the IP address of one or more DNS servers to ask questions of.
    • 0:27:25DHCP servers also tell you the IP address
    • 0:27:28of your default gateway, the router that you should use by default
    • 0:27:32to hand one of those envelopes to.
    • 0:27:35And this is indeed why Phyllis probably knew
    • 0:27:37to whom to hand that envelope in the first place,
    • 0:27:39because when she booted up, so to speak, she was assigned an IP address.
    • 0:27:43She was told what default gateway to use and the default gateway, a.k.a.,
    • 0:27:47router--
    • 0:27:48these are just synonyms, is the device to which she
    • 0:27:51should hand off data by default in order to get it from point A to point B.
    • 0:27:55So why do we focus on all of these acronyms, all of these technologies?
    • 0:27:59Well, on the one hand, they're omnipresent.
    • 0:28:01And even though you might not need to say these acronyms verbally
    • 0:28:03all that often, you're going to see them on occasion.
    • 0:28:06When something goes wrong, you're going to need
    • 0:28:07to troubleshoot things like this.
    • 0:28:08But more importantly, they're representative of very real-world
    • 0:28:12engineering problems that the world has had and encountered over the years.
    • 0:28:15But they're relatively simple solutions there too.
    • 0:28:19I don't necessarily know how I could write code
    • 0:28:21to implement a DNS server or DHCP server, and perhaps neither you.
    • 0:28:26But it sounds like a pretty simple idea.
    • 0:28:28If I have the ability in code to hear requests,
    • 0:28:31I can respond to those requests by maybe using
    • 0:28:33a dictionary in memory in the case of a DNS server,
    • 0:28:36and responding to those answers.
    • 0:28:38So this is to say all of the fundamentals,
    • 0:28:39all of the ideas we've been talking about throughout CS50
    • 0:28:42really are used as building blocks to solve
    • 0:28:45these very real-world, very omnipresent technologies that you and I now
    • 0:28:49take for granted every day.
    • 0:28:51Let's now consider one other protocol that's with us every day nowadays,
    • 0:28:56that of HTTP-- hypertext transfer protocol, which is indeed itself
    • 0:29:00a protocol, a set of conventions, that governs in this case how web browsers
    • 0:29:04and web servers intercommunicate.
    • 0:29:07It is very much related to HTTPS, which is literally the secure version
    • 0:29:11thereof that somehow uses encryption, somehow scrambles the data,
    • 0:29:16to ensure that when you're visiting a web page, you and only
    • 0:29:19you can see that web page.
    • 0:29:20And no one in-between you on the internet
    • 0:29:22actually knows what it is you're looking at
    • 0:29:24or the specific URL that you are visiting, beyond the name or the IP
    • 0:29:28address of the website itself.
    • 0:29:31So even though you and I probably don't even bother typing http:// or https://.
    • 0:29:39Odds are nowadays, you and I just type google.com, Enter, CS50.ai, Enter.
    • 0:29:43Or you click on a bookmark.
    • 0:29:45Underneath the hood, this protocol is everywhere.
    • 0:29:48And those prefixes, http:// and https:// are required when using a browser,
    • 0:29:55even though your browser automatically tends to insert those prefixes
    • 0:29:58automatically if you, the human, don't bother typing them yourself.
    • 0:30:02So they're used, of course, in URLs--
    • 0:30:04Uniform Resource Locators, which specifically
    • 0:30:07are the addresses that we use to get to useful information
    • 0:30:10on the World Wide Web, or web for short.
    • 0:30:13Here, for instance, is one of the simplest URLs we can talk about.
    • 0:30:16I'm going to use HTTPS deliberately to imply
    • 0:30:18that you really do want to try to use secure sites alone nowadays.
    • 0:30:22But this domain name would seem to be www.example.com, or that's
    • 0:30:26the fully qualified domain name itself.
    • 0:30:29But let's tease apart what's going on here.
    • 0:30:31Typically, in your browser, you might see a trailing slash, so a forward slash
    • 0:30:37at the end of it, which just indicates, albeit non-obviously,
    • 0:30:40that you want the default web page at that domain name.
    • 0:30:45In particular, you want to be able to access whatever the default content is
    • 0:30:48for that website.
    • 0:30:49Nowadays, though, browsers like Safari and Chrome, and even others,
    • 0:30:53tend to hide these details, just to simplify what
    • 0:30:55you're actually seeing in your browser.
    • 0:30:57But typically, if you click or double-click on the URL bar
    • 0:31:00in your own browser, you'll see more information,
    • 0:31:02including this trailing slash.
    • 0:31:04So if you only type in google.com, Enter, probably your browser
    • 0:31:07is automatically appending to indicate you want the default home page.
    • 0:31:12But sometimes there's more to the URL.
    • 0:31:13Sometimes it's /path, whereby path, I just mean a folder or a file name,
    • 0:31:19or something along those lines.
    • 0:31:20And that's more specifically referring to probably a directory on the server
    • 0:31:24containing some web page specifically.
    • 0:31:27Sometimes, it's more explicit.
    • 0:31:28Sometimes the URL might literally end in .html,
    • 0:31:31which is going to stand for hypertext markup language,
    • 0:31:34one of the first languages we'll soon look at in detail.
    • 0:31:37And that's the language in which web pages are written.
    • 0:31:39So this URL indicates that, at the server called www.example.com,
    • 0:31:44there is a file called file.html that this user wants to see in their browser.
    • 0:31:50Sometimes, though-- and it's not often the case
    • 0:31:52any more that you see these file extensions.
    • 0:31:54The world decided years ago that these are just ugly and not strictly
    • 0:31:57necessary technically.
    • 0:31:59So sometimes, you'll just see /folder/, which just means there's a folder,
    • 0:32:03a.k.a., directory somewhere in the server,
    • 0:32:04whose web page contents you want to see.
    • 0:32:07Sometimes, it's nested.
    • 0:32:08Sometimes, it's a folder, and then a file inside of which
    • 0:32:12is the web page contents that you want to see.
    • 0:32:14So in short, URLs generally follow this kind of format.
    • 0:32:17And there might be zero or more of these folders, and maybe
    • 0:32:20a file name explicitly or not.
    • 0:32:22But what else is going on here?
    • 0:32:24Well, here we have the fully qualified domain name.
    • 0:32:27And just to toss out a bit more jargon, technically, when you say "domain name,"
    • 0:32:31typically you mean something like this-- just the example.com.
    • 0:32:34Because the www in this context is generally referred to as a host name.
    • 0:32:40It's like the name of a specific server at a company,
    • 0:32:43at a university that is providing some service like this-- the world wide web,
    • 0:32:48a.k.a., a web server.
    • 0:32:50It is not strictly necessary for a server to have a name of www just
    • 0:32:54to be a web server.
    • 0:32:55For many years, MIT'S website was web.mit.edu,
    • 0:33:00whereas everyone else in the world was using www.
    • 0:33:02But odds are many of you are probably not
    • 0:33:04even the habit of typing www.something.something.
    • 0:33:08Rather you type in google.com and hit Enter.
    • 0:33:10And the browser somehow automatically brings you to www.google.com.
    • 0:33:15So the host name is the name of a specific server.
    • 0:33:19The domain name is typically just something like the example.com.
    • 0:33:22And let me disclaim, that's a bit of a white lie,
    • 0:33:24because if you're Google, if you're Meta,
    • 0:33:26if you're any of these big companies, you don't just have one web server.
    • 0:33:30So technically, the www refers to a collection of servers.
    • 0:33:34Maybe it's two, maybe it's 20, maybe it's 20,000 servers.
    • 0:33:38There are technologies that allow you to support that as well.
    • 0:33:41But lastly, there's one other piece of jargon that's worth knowing.
    • 0:33:45The last part of these fully qualified domain names
    • 0:33:48is known as the TLD, or top level domain.
    • 0:33:51And that is what generally historically indicated what type of domain it is.
    • 0:33:56In the US, .com means commercial, .gov means government,
    • 0:33:59.org means organization.
    • 0:34:01However, there are so many more top-level domains nowadays.
    • 0:34:06And in fact they're not US-centric.
    • 0:34:08And in fact, just because you have .com does not mean you are in the US.
    • 0:34:11It just means that you paid someone to use that there domain name.
    • 0:34:14In fact, there's other TLDs too.
    • 0:34:16Every country has its own-- .us for the United States, .uk for the UK,
    • 0:34:20.jp for Japan, and so forth.
    • 0:34:22Anytime the TLD is just two characters, that's a country code.
    • 0:34:27And yet that's curious, because we're in the habit of using cs50.ai.
    • 0:34:33There are websites that use .tv There are websites that use .io,
    • 0:34:39CS50 included.
    • 0:34:40And if you'd like to go down that rabbit hole,
    • 0:34:42feel free to Google "top level domain" or TLD and any of those.
    • 0:34:46And you'll actually see that, even though we are using cs50.ai to imply
    • 0:34:50artificial intelligence, .ai has nothing to do with artificial intelligence,
    • 0:34:55except that is how you can abbreviate it in English as an acronym.
    • 0:34:59It actually is a two-character country code.
    • 0:35:02And that country and others have decided to actually monetize
    • 0:35:05the TLD by selling it to, really, anyone who's
    • 0:35:07willing to pay per year to use that there TLD.
    • 0:35:11So lastly, within these here URLs, we of course, have the actual http or https.
    • 0:35:19And that dictates the protocol that is going
    • 0:35:21to be used when a web browser requests a web page at that there address.
    • 0:35:26Now, what does this protocol do.
    • 0:35:28It's similar in spirit, again, to a handshake, whereby a web browser,
    • 0:35:32when it wants a web page, it's like extending a hand,
    • 0:35:34hoping that the web server will respond and know what to do.
    • 0:35:37Of course, there's no such handshake physically here.
    • 0:35:40But rather metaphorically, the web server
    • 0:35:42should know how to respond, so long as the web browser standardizes
    • 0:35:45the message that it sends.
    • 0:35:47So what do I mean by that?
    • 0:35:49Well, let me propose that inside of this envelope can be one of two messages,
    • 0:35:54and this is a bit of a simplification.
    • 0:35:56But the first of those messages is GET.
    • 0:35:58And what GET means is literally, get me a specific web page.
    • 0:36:02By contrast, you can use POST inside of these envelopes.
    • 0:36:06And POST generally means to send information somewhere else.
    • 0:36:09And this too is an oversimplification.
    • 0:36:11But generally the word GET is used by a browser
    • 0:36:15when it just wants to get information.
    • 0:36:16The word POST is used when it wants to send information--
    • 0:36:20often sensitive information like a credit card, an email address,
    • 0:36:24a password, or any time you're filling out a form,
    • 0:36:26it's generally sent via the POST keyword instead.
    • 0:36:29And these are indeed verbs.
    • 0:36:31Like, GET and POST are both verbs in English,
    • 0:36:33implying that this is some here action.
    • 0:36:35Now dot dot dot means that there's other verbs that can be used inside
    • 0:36:38of these envelopes as well.
    • 0:36:39But let's be more specific.
    • 0:36:41Inside of the envelope that's being sent from browser to server
    • 0:36:44is more specifically a message like this.
    • 0:36:46So if I, with my browser, visit www.harvard.edu,
    • 0:36:51the message that goes inside of that virtual envelope,
    • 0:36:54as we discussed earlier, is literally text that looks quite like this.
    • 0:36:58So the cat is gone.
    • 0:36:59There's no more pictures of cats just yet if you're just
    • 0:37:01requesting Harvard's own home page.
    • 0:37:03But inside of that envelope is indeed GET / HTTP/2, for instance,
    • 0:37:09then HOST, then the actual host name or fully qualified domain
    • 0:37:13name that you are seeking, and dot, dot, dot.
    • 0:37:15There's some other stuff there.
    • 0:37:17But that's what's inside of that envelope.
    • 0:37:19Hopefully, what's going to come back from the server
    • 0:37:22is another envelope inside of which is a response.
    • 0:37:25So whereas the first message is a request to get something,
    • 0:37:28the response is indeed a response that hopefully contains the actual web
    • 0:37:32page that you requested.
    • 0:37:34And you'll see that the response might look like HTTP/2 200,
    • 0:37:38and then Content-Type text/html which just means that the web page is written,
    • 0:37:41indeed, in this language we're about to spend time with today,
    • 0:37:44HTML, below, which is the actual content.
    • 0:37:47So how can I actually go about seeing some of this?
    • 0:37:50Well, let me actually go over to VS Code.
    • 0:37:52And up until now, we've been using VS Code for the purposes of writing code.
    • 0:37:56But we do have this terminal window, and the terminal window gives me access
    • 0:37:59to an underlying operating system.
    • 0:38:00That operating system, recall, is called Linux.
    • 0:38:03And I have a command line interface here.
    • 0:38:04And up until now, I've been using this command line interface
    • 0:38:07for commands like cd and ls, make, debug50, Python, sqlite, 3,
    • 0:38:15and the like.
    • 0:38:15But there's other commands that typically come on a system,
    • 0:38:18including this one, that allows me to make internet requests as well-- not
    • 0:38:21even with a browser, but textually.
    • 0:38:24Moreover, there's always been-- even though I generally
    • 0:38:26hide it during class, a second tab, namely ports.
    • 0:38:29And if you yourself look at cs50.dev after logging in,
    • 0:38:33odds are you will see a ports tab, among others.
    • 0:38:35And what you'll see here is that, all this time, CS50's own development
    • 0:38:40environment has been using by default a TCP port number, namely 1337, which
    • 0:38:46is a very elite number for us to use.
    • 0:38:48And that is the port number that's used by CS50's customizations of VS Code.
    • 0:38:52Our so-called extension uses that TCP port number,
    • 0:38:55so that when our extension is talking to VS Code,
    • 0:38:57it uses a standard port number on the outside of its own virtual envelopes,
    • 0:39:02if you will.
    • 0:39:02You, as users, don't need to care about that.
    • 0:39:04But that's why that tab all this time, if you've seen it,
    • 0:39:07has had numbers in there.
    • 0:39:09And soon, we're going to see some additional numbers as well.
    • 0:39:11But if I go back to my terminal window here, I of course could type commands.
    • 0:39:15And one of the commands I could type is actually this.
    • 0:39:18Let me increase the size of my terminal window.
    • 0:39:20Let me go ahead and type curl, which means connect URL, dash capital I.
    • 0:39:26And now let me go ahead and type in https://www.harvard.edu/.
    • 0:39:32So I'm going to manually type this into my terminal window's command line
    • 0:39:35interface and see what comes back.
    • 0:39:38I'm going to hit Enter, and I get a bunch of stuff back.
    • 0:39:41That's why I used a dot dot dot on my slide a moment ago.
    • 0:39:44But in this output is some familiar text now.
    • 0:39:46One, we saw this line earlier on my slide--
    • 0:39:49HTTP/2 and then some number 200.
    • 0:39:52And then there are other lines here that I waved my hands at earlier
    • 0:39:56because they weren't strictly necessary, including the host line.
    • 0:39:59If this server is only doing one thing, we
    • 0:40:01don't even need to clarify that this is www.harvard.edu.
    • 0:40:05But what, then, is this HTTP/2 and this 200?
    • 0:40:08Well, it turns out that the 2 is just the version of HTTP
    • 0:40:12that my browser or my keystrokes were using a moment ago.
    • 0:40:151.1 is a common version number.
    • 0:40:172 is a common number.
    • 0:40:183 is catching on over time.
    • 0:40:20But this just indicates what version of the protocol
    • 0:40:22the browser and server are speaking, even though this browser has
    • 0:40:25no graphical user interface.
    • 0:40:26It's just a command simulating an HTTP request to get back these headers.
    • 0:40:32And that's in fact what dash I means.
    • 0:40:34Show me just the headers.
    • 0:40:35I don't want to see any cats or Harvard News.
    • 0:40:37I just want to see the headers inside of the envelope.
    • 0:40:39But it turns out all this time, for as many years as you've
    • 0:40:42been using a browser, you could actually do this in your own browser as well.
    • 0:40:47Let me open up another tab here.
    • 0:40:48And let me manually go to https://www.harvard.edu/enter.
    • 0:40:56And what I'll see here is Harvard's home page as of right now today.
    • 0:41:00It all worked, as you might expect.
    • 0:41:02But it turns out all this time, you've had access
    • 0:41:04to some powerful tools underneath the hood.
    • 0:41:06Let me actually right-click anywhere on this web page and select Inspect.
    • 0:41:11And that's going to open what are called developer tools in the context
    • 0:41:14of my browser, which is Chrome.
    • 0:41:16Most every browser nowadays--
    • 0:41:18Safari, Edge, and others, have similar-looking tools,
    • 0:41:20though you might have to access them via different menus.
    • 0:41:23And in fact, in Chrome, you can also go up to the dot dot dot menu
    • 0:41:26and find your way to developer tools.
    • 0:41:28There's a lot going on here.
    • 0:41:29But what I'm going to do is go to the Network tab here for a moment.
    • 0:41:32And I'm going to zoom in, just for the sake of legibility.
    • 0:41:35And notice here that, when I clear this Network tab,
    • 0:41:39this is giving me access essentially to a log of everything that you're
    • 0:41:43about to see on the screen.
    • 0:41:44And notice, it just undeleted itself.
    • 0:41:47Apparently, Harvard is doing something behind the scenes every few seconds,
    • 0:41:50which is why that row reappeared, because indeed, I'm
    • 0:41:53trying to record my network activity.
    • 0:41:55But let's go ahead and do this.
    • 0:41:56Let me clear that one more time and reload the page.
    • 0:42:00And so many rows just flashed across the screen.
    • 0:42:03In fact, in the bottom left-hand corner, you'll
    • 0:42:05see that my browser, unbeknownst to me, made not one, but 67, HTTP requests.
    • 0:42:10That's how many envelopes essentially went back and forth between my browser
    • 0:42:13and harvard.edu a moment ago.
    • 0:42:15Here comes another.
    • 0:42:16And if we just keep this open, it's going to come again and again.
    • 0:42:18Harvard is keeping the page alive.
    • 0:42:20But let me zoom out and scroll back to the very top of this,
    • 0:42:23and focus on just the first page I requested and click on www.harvard.edu.
    • 0:42:28And let me click on Headers here.
    • 0:42:31What I'm seeing is diagnostic information, if you will,
    • 0:42:34about what I just did.
    • 0:42:36And you'll see that the URL I requested was indeed this thing here.
    • 0:42:40I used a request method of GET.
    • 0:42:43Unbeknownst to me, GET is what is used by default.
    • 0:42:45When you just type a URL and hit Enter.
    • 0:42:47Then the status code that came back, ah, there's that 200.
    • 0:42:51So it turns out that what web servers and browsers have done over the years,
    • 0:42:55thanks to HTTP, is they have standardized what these numeric codes
    • 0:43:00are to indicate success or failure.
    • 0:43:02In the world of programs that you and I have been writing,
    • 0:43:04we typically use 0 to indicate success, and maybe 1 or 2 or some other integer
    • 0:43:09to indicate failure.
    • 0:43:10In the context of the web, it's the same idea.
    • 0:43:13But the web uses 200 to indicate success and other numbers to indicate failure,
    • 0:43:19or something else happening as well.
    • 0:43:22Well, what else can those status codes represent?
    • 0:43:25Well, let's take a look here.
    • 0:43:27Notice that when I'm in my browser, and I
    • 0:43:28go to simply harvard.edu with no https, no colon slash slash,
    • 0:43:34no www, no trailing slash, Enter.
    • 0:43:36It all just works, and brings me to the intended place.
    • 0:43:40Now, why is that?
    • 0:43:41Well, at the lowest level, we can actually
    • 0:43:43see this in our command line interface.
    • 0:43:44Let me go back to my terminal window, which I've still full screened.
    • 0:43:47And let me type this time curl, dash capital I,
    • 0:43:50and then simply http://harvard.edu.
    • 0:43:55So I'm going to help the program a little bit
    • 0:43:57and provide it with the protocol.
    • 0:43:59But I'm not going to provide it with the secure version.
    • 0:44:02I'm not even going to mention www.
    • 0:44:04Let's see what comes back.
    • 0:44:05Ideally, it's a 200 OK because that's what means success.
    • 0:44:08But what I see here is, weirdly, that harvard.edu has moved permanently.
    • 0:44:13And this time, the status code-- coming back from an older version of HTTP
    • 0:44:17in this case, 1.1 instead of 2, apparently has a status code of 301.
    • 0:44:22So it turns out that different types of responses
    • 0:44:25indeed have different numbers associated with them.
    • 0:44:27And 301 means moved permanently, a sort of redirection, if you will.
    • 0:44:31And where is Harvard's new location?
    • 0:44:33Well, if we scroll down among these headers,
    • 0:44:35you'll see that, oh, the server is additionally telling me
    • 0:44:38that the location to which Harvard has moved permanently
    • 0:44:41is https://harvard.edu.
    • 0:44:44OK, so what this seems to indicate is that Harvard server really
    • 0:44:47wants me to stay on the secure version of the website.
    • 0:44:50All right, so let me go ahead and highlight and copy that.
    • 0:44:54Let me go ahead and do curl, dash I, and that URL, so almost the same,
    • 0:44:58except for the https this time and the trailing slash, and hit Enter.
    • 0:45:02But this time too notice--
    • 0:45:03and this time, the server is using a newer version of the protocol.
    • 0:45:06We're back to version 2.
    • 0:45:07It's still telling me 301.
    • 0:45:09It's not berating me by saying, move permanently again.
    • 0:45:12But 301 is enough for, me, the browser to know, oh,
    • 0:45:15Harvard's website is now at this location, www.harvard.edu, again using
    • 0:45:21HTTPS.
    • 0:45:22And so OK, let's do this one more time.
    • 0:45:24Let me go ahead and copy that URL, and do curl, dash I, and that full URL.
    • 0:45:30And now we're back to getting a 200 OK.
    • 0:45:32So among the reasons that your browser is able to figure out what you want
    • 0:45:37is because, one, the server might be telling it, no, go here.
    • 0:45:41No, go here.
    • 0:45:41OK, now you're in the right place.
    • 0:45:43And frankly, browsers nowadays, in cooperation
    • 0:45:46with servers that are configured in a certain way,
    • 0:45:48will tolerate you typing in only harvard.edu,
    • 0:45:51and just know proactively, no, no, no, no, no.
    • 0:45:53You don't want that.
    • 0:45:54You want HTTPS and you want the www because the browser, for instance,
    • 0:45:59has seen that response before from the server.
    • 0:46:02But at the end of the day, it's really just these status codes
    • 0:46:04that are enabling us to actually forge these responses.
    • 0:46:08So we've seen a couple now.
    • 0:46:10We've seen 200 for OK.
    • 0:46:11We've seen 301 for moved permanently.
    • 0:46:13There's bunches of others as well, including, for instance, this one here.
    • 0:46:18Odds are, most everyone here has seen 404 at some point in their lives.
    • 0:46:23I mean, it's in the human vernacular.
    • 0:46:25We all know that 404 means file not found.
    • 0:46:27Like, the URL is wrong, the file was deleted, something is missing.
    • 0:46:31That's a little weird that we as humans have been acclimated
    • 0:46:33to a fairly esoteric HTTP status code.
    • 0:46:36But that's all it is.
    • 0:46:38If you visit a web page that simply does not exist,
    • 0:46:41you will get back not 200, not even 301.
    • 0:46:43You'll get back a similar header like this saying 404, file not found.
    • 0:46:48Now, you might see a web page, and it might be a cute web page
    • 0:46:50or it might be a black and white text only web page.
    • 0:46:53It depends how the web server has been configured to show you that information.
    • 0:46:57But 404 indeed means file not found.
    • 0:47:00And here is a non-exhaustive list of other status codes.
    • 0:47:03We've seen 200 OK, 301 OK.
    • 0:47:05There's other 300-level status codes that generally refer to redirecting
    • 0:47:09the user from one URL to another.
    • 0:47:12The 400s generally indicate user error, like your fault, my fault.
    • 0:47:16So 401 is unauthorized.
    • 0:47:18403 is forbidden, like you haven't logged in properly.
    • 0:47:20404 is not found.
    • 0:47:22418 is actually an April Fool's joke from years ago.
    • 0:47:25"I'm a Teapot."
    • 0:47:25It was a funny joke among engineers.
    • 0:47:28More on that if you Google it, if you'd like.
    • 0:47:29500 range errors mean server error.
    • 0:47:33So someone screwed up, maybe not you.
    • 0:47:36But frankly, in a couple of weeks time, when
    • 0:47:38you're writing web-based applications yourself, any time you see a 500,
    • 0:47:41it is your fault also.
    • 0:47:43So you are both the user and the server in that there case.
    • 0:47:47But long story short, the way these things work
    • 0:47:49are simply underneath the hood via these status
    • 0:47:52codes, which really are being sent virtually inside of envelopes
    • 0:47:55like these.
    • 0:47:56Your browser is generally hiding that detail
    • 0:47:58because normal users don't need to care about this level of detail.
    • 0:48:01But you've always had the power of opening your own browser's developer
    • 0:48:05tools and poking around and seeing these things.
    • 0:48:07And all I'm doing in my black and white window
    • 0:48:10here with curl, which connects me to a URL using a command line interface,
    • 0:48:14is showing you even more in detail what's inside of those envelopes.
    • 0:48:18But it's just another way of viewing the same kind of information.
    • 0:48:22Now, we can actually have a little bit of fun
    • 0:48:24with this, with a smile and a wink to our students at Yale
    • 0:48:29who are perhaps watching this now.
    • 0:48:31It turns out-- has anyone ever been to this URL here, safetyschool.org?
    • 0:48:38I'll zoom in here in a new tab.
    • 0:48:40Has anyone applied to safetyschool.org or visited safetyschool.org?
    • 0:48:45Well, we love them equally.
    • 0:48:46But it turns out, if you go to safetyschool.org,
    • 0:48:49you end up at this here website, which if I zoom back in,
    • 0:48:52is apparently https://www.yale.edu.
    • 0:48:56So what is going on there?
    • 0:48:58Well, I could open my developer tools.
    • 0:48:59But let me use my newfound command line skills and do it here-- curl, dash I,
    • 0:49:03http://safetyschool.org, Enter.
    • 0:49:08And you'll see that, oh, safetyschool.org has moved permanently
    • 0:49:12to yale.edu's own website.
    • 0:49:15So this is a practical joke that has lived on the internet for years.
    • 0:49:19There is someone out there--
    • 0:49:20I don't know who they are.
    • 0:49:21They have been paying an annual fee, for years now,
    • 0:49:24simply to have this esoteric joke for us computer scientists.
    • 0:49:29There are ones for Harvard as well, in all fairness.
    • 0:49:31But this is one that's perhaps been around the longest.
    • 0:49:34So somewhere, there's a Harvard alum who's getting older and older
    • 0:49:36but is still paying this bill year over year since the web was invented.
    • 0:49:41All right, we're back.
    • 0:49:43And we now focus on HTML-- hypertext markup
    • 0:49:46language, which is the language in which web pages are written.
    • 0:49:49It is not a programming language.
    • 0:49:50And as such, we won't need to spend all that much time on it,
    • 0:49:53because the basics of HTML are fairly straightforward, even though it
    • 0:49:56has a decently large vocabulary, different features that you'll
    • 0:49:59pick up invariably over time.
    • 0:50:01What HTML does have fundamentally are what are called tags and attributes.
    • 0:50:05These are the basic building blocks of the language.
    • 0:50:07And what the language looks like is this.
    • 0:50:10So here is perhaps the simplest web page that I could come up with, a "hello,
    • 0:50:13world" web page, if you will.
    • 0:50:15And it's just text.
    • 0:50:17It is text that's typically stored in a file like index.html for short.
    • 0:50:22And in that file would just be these lines of code.
    • 0:50:25And these lines here are going to indicate
    • 0:50:27to the browser what it should do upon receipt
    • 0:50:30of an envelope containing this message.
    • 0:50:33Now how are we going to go about serving up this content?
    • 0:50:36Ultimately, we just need to put this content on an actual web server.
    • 0:50:39Well, it turns out you already have a web server, even though you
    • 0:50:42haven't been using it as such.
    • 0:50:44In other words, when you visit cs50.dev, and use VS Code in the cloud,
    • 0:50:48you're obviously using a browser.
    • 0:50:50But you're less obviously using a web server
    • 0:50:52that is serving up a copy of VS code to you in that browser.
    • 0:50:56But the caveat there is that by default, you've
    • 0:50:58probably been in the habit of typing cs50.dev, Enter.
    • 0:51:01And you've probably noticed, if not prior to today, then after today,
    • 0:51:05that the full URL ends up being https: //cs50.dev/ and then maybe some other
    • 0:51:12stuff after that.
    • 0:51:13But implicit in that URL is one of those port numbers
    • 0:51:17that we saw in TCP, either 80 or 443.
    • 0:51:20Because it's HTTPS, it's actually the latter, 443,
    • 0:51:24which indicates implicitly that there must be a server on cs50.dev that
    • 0:51:30is listening for requests, and is serving up that version of VS Code.
    • 0:51:35In fact, we eventually redirect you to GitHub's version
    • 0:51:38of VS Code, a.k.a., Codespaces.
    • 0:51:40But the idea is the same.
    • 0:51:41And in that URL, you have a web page that's being served up to you.
    • 0:51:46But it's already running on port 443, and perhaps 80, which is to say,
    • 0:51:50if we want to come up with our own web server,
    • 0:51:53we could start up our own server, connect it to the internet,
    • 0:51:56give it an IP address, and then communicate
    • 0:51:58with it using port 80 or 443.
    • 0:52:01But it's actually a lot simpler to embrace the reality
    • 0:52:03that any server can have multiple services,
    • 0:52:06be it web or email or video conferencing or the like-- or heck,
    • 0:52:10two different web servers.
    • 0:52:11And so even though VS Code in the cloud is already
    • 0:52:13running a web server, because that's indeed how it works,
    • 0:52:16there's nothing stopping you and me from, inside of VS Code,
    • 0:52:19starting a second web server, so long as we choose a different port number--
    • 0:52:24a different TCP port that's not already being used by the server itself.
    • 0:52:28So how are we going to do that?
    • 0:52:30Well, we're going to introduce you to a new command today,
    • 0:52:32called quite appropriately HTTP server.
    • 0:52:36This is a command that you can run in your terminal
    • 0:52:38window that will start your very own web server by default on port 8080.
    • 0:52:438080 isn't that special, but it tends to be a convention.
    • 0:52:45Whenever you want to run a web server on a port other than 80 by default,
    • 0:52:49you would just use 8080 as a go-to.
    • 0:52:52But it could really be any number within a large range.
    • 0:52:55Now, this HTTP server command is going to allow
    • 0:52:57me to serve up some actual content.
    • 0:52:59What might that content be?
    • 0:53:01Well, let me go ahead and do this.
    • 0:53:03Let me go ahead and run code, index.html.
    • 0:53:07And let me go ahead and whip up a very simple web page here in.
    • 0:53:10And I'll explain in just a moment what these lines are.
    • 0:53:12But let me go ahead and just transcribe it in this here file.
    • 0:53:16So angle bracket exclamation point DOCTYPE HTML close bracket.
    • 0:53:21Then I had HTML lang equals, quote unquote, "en."
    • 0:53:24Then I had head.
    • 0:53:25Then I had title.
    • 0:53:27And inside of that title, I had "hello, title."
    • 0:53:30Below that head, I had open tag body, inside of which I had "hello, body."
    • 0:53:35So there's a lot of weird stuff going on here if you've never seen this before.
    • 0:53:38But I think I have recreated the file you just saw in slide form a moment ago.
    • 0:53:43What I'm now going to do is try to view this file inside of my browser.
    • 0:53:48But to do that, I need to do this.
    • 0:53:50I'm going to go ahead and run http-server, Enter.
    • 0:53:53And a whole bunch of stuff is going to appear in my terminal window--
    • 0:53:57some diagnostic output, a URL, and the like.
    • 0:53:59But in particular, I'm going to get this little pop-up that's
    • 0:54:01telling me, oh, my application running on port 8080 is now available.
    • 0:54:06This is just a user-friendly feature of VS Code, specifically
    • 0:54:09CS50's own extension therein, that allows me to click Open in browser.
    • 0:54:13I immediately get a second tab inside of which
    • 0:54:15I see the contents of my code space at this moment in time.
    • 0:54:20Now notice, to save myself some time today,
    • 0:54:22I've downloaded in advance a src8 folder inside
    • 0:54:26of which are a lot of today's examples, if I so need them.
    • 0:54:29And there's a file I literally just created called index.html.
    • 0:54:33What you're seeing here is a directory index of my current folder.
    • 0:54:38So this is a dynamically automatically generated
    • 0:54:41web page that's simply showing me in a web browser what
    • 0:54:44is inside of my code space.
    • 0:54:45Now, what's my URL?
    • 0:54:46Well, it turns out it's going to be something
    • 0:54:48that ends in GitHub.dev, which is a domain that GitHub itself controls.
    • 0:54:51So that's going to be generated for me automatically.
    • 0:54:54It's not a domain name I had to buy or sign up for.
    • 0:54:56And it's really meant to be temporary, because I'm
    • 0:54:58going to use my code space as a development environment
    • 0:55:00to develop web pages.
    • 0:55:02But most important for now is that, indeed, this server program
    • 0:55:06is running on localhost, which is a nickname
    • 0:55:08for the local computer, no matter what its actual name is, specifically
    • 0:55:12on port 8080.
    • 0:55:13And this is why I'm now seeing my folder instead of VS Code.
    • 0:55:18This tab has port 8080.
    • 0:55:20This tab would appear to have port 443, which is GitHub's own web
    • 0:55:24server running at this domain.
    • 0:55:27Now I'm going to go ahead and click my index.html.
    • 0:55:30And we will see what the simplest web page in the world might look like.
    • 0:55:33And voila, there is my "hello, body," which is the only thing in this
    • 0:55:37otherwise big white rectangular region, otherwise known as the viewport
    • 0:55:40of my browser.
    • 0:55:41And if I zoom in at the top here, you'll see that my title of my tab
    • 0:55:46is indeed what we saw earlier--
    • 0:55:48"hello, title."
    • 0:55:49So long story short, even if you're completely new to developing web pages,
    • 0:55:53clearly we have the ability, with this language called HTML,
    • 0:55:56to indicate what the title of a page should be in its tab
    • 0:55:59and what the contents of its body should be,
    • 0:56:02as underwhelming and as black and white as all of this might be.
    • 0:56:05Well, let me go back to my sample code here, and let's
    • 0:56:09now actually introduce some building blocks here in.
    • 0:56:12So what is actually going on?
    • 0:56:13The first line of code that I type that you see highlighted here
    • 0:56:16is the page's so-called document type declaration.
    • 0:56:19That's a silly mouthful.
    • 0:56:20But it's really just a standardized line of text that says,
    • 0:56:23hey, browser, here comes a web page written in HTML--
    • 0:56:27specifically version 5 of HTML, which is what most of the world is now using.
    • 0:56:33Odds are this line of code will change over time,
    • 0:56:35but for now, this is what we have.
    • 0:56:37Below that, things get a little more interesting and a little more symmetric,
    • 0:56:40if you will, and no more exclamation points like you see in this first line.
    • 0:56:44That's a bit of an anomaly.
    • 0:56:45Down here, you'll see what I'll describe as open bracket html, then the space,
    • 0:56:51then lang equals, quote unquote, "en," then close bracket.
    • 0:56:54And by open and close bracket, I mean a less than sign
    • 0:56:58and a greater than sign, respectively, which you can type on your keyboard.
    • 0:57:01What this is doing is the following.
    • 0:57:04This is the beginning of an HTML element, as we might call it.
    • 0:57:08And the tag here for this element is called HTML.
    • 0:57:12So anything immediately after a less than sign is the name of the tag.
    • 0:57:17And the way that browsers work is by relying on these tags to know what to do
    • 0:57:22and where within the confines of the browser.
    • 0:57:24So you can think of this first tag as saying, hey, browser,
    • 0:57:27here comes some HTML.
    • 0:57:29Now, what is that HTML all about?
    • 0:57:32Well, this thing here highlighted lang, short for language,
    • 0:57:35indicates what human language is presumably
    • 0:57:39going to be used throughout the rest of the page.
    • 0:57:41All of the tags, all of the attributes, for better or for worse,
    • 0:57:44are going to be in English, because the language HTML itself was standardized
    • 0:57:47by English-speaking people.
    • 0:57:49You can write web pages with your own content in any human language.
    • 0:57:52In this case, I have opted to write my page, as simple as it is,
    • 0:57:55in English as well-- "hello, title" and "hello, body."
    • 0:57:59And the "en" attribute value here, so to speak,
    • 0:58:02is just a clue to the browser that, in case you've got Google Translate or any
    • 0:58:06kind of automatic translation, this is a little hint as to what the human
    • 0:58:10language is to facilitate automatic translation or search engine
    • 0:58:14optimization--
    • 0:58:15SEO, or the like.
    • 0:58:16But that whole thing started the HTML page.
    • 0:58:19Now we have a sequence of other tags.
    • 0:58:21Hey, browser, here comes the head of the page, which metaphorically
    • 0:58:24is like the very top of the page here, a.k.a.,
    • 0:58:27the tab that we looked at a moment ago.
    • 0:58:29Hey browser, here comes the title of my page.
    • 0:58:32What's the title?
    • 0:58:33The title is "hello, title."
    • 0:58:35Now things are a little weird.
    • 0:58:36The next line of text here is open bracket, title, close bracket.
    • 0:58:42And whereas therefore, I might call the previous tag the open tag or the start
    • 0:58:47tag, this one here now would be the close tag or the end tag.
    • 0:58:53So there's a symmetry here that effectively
    • 0:58:55is conveying to the browser, hey, browser, that's it for the title.
    • 0:58:58The title is now complete.
    • 0:59:00What comes next?
    • 0:59:01Hey browser, that's it for the head of the web page.
    • 0:59:03Nothing left in there.
    • 0:59:05What comes next?
    • 0:59:05Hey browser, here comes the body of the web page--
    • 0:59:09everything else.
    • 0:59:10The big contents of that white rectangular region
    • 0:59:12is the so-called body of the page.
    • 0:59:13Hey browser, here's the contents of the body.
    • 0:59:16Hey browser, that's it for the body.
    • 0:59:18Hey browser, that's it for the HTML itself.
    • 0:59:22Now notice, the indicates the end tag or the close tag.
    • 0:59:26And you don't need to be super verbose.
    • 0:59:28Even though my HTML tag started with a language attribute, lang equals,
    • 0:59:34quote unquote, "en," you don't need to repeat the lang.
    • 0:59:36You don't need to repeat the quotes or the en.
    • 0:59:39It's obvious to the browser that this is closing the previously opened HTML tag.
    • 0:59:45Now, in general, the tags you're seeing should exist in one and only one place.
    • 0:59:49You must use these tags in certain locations.
    • 0:59:52We will soon see bunches of other tags that you
    • 0:59:54can use zero or more times to structure the actual contents of your own page.
    • 0:59:59So how do we get into that?
    • 1:00:01And what are we ultimately doing?
    • 1:00:03Well, what we really have is, in this HTML code,
    • 1:00:07a textual representation of a tree, one of our now-familiar data structures,
    • 1:00:12whereby there's a root of this tree that has
    • 1:00:14some number of children that might have some number of grandchildren
    • 1:00:17and so forth.
    • 1:00:18And so depicted here at right is what you might call a document object
    • 1:00:22model, or DOM for short, which is actually what the browser is probably
    • 1:00:27doing in its own memory, or RAM, when it accesses a web page.
    • 1:00:33In other words, if you type in google.com and hit Enter,
    • 1:00:36you immediately see the contents of Google's website in your browser.
    • 1:00:39What Google has probably done is sent text that looks like this,
    • 1:00:43but more complicated than this simple example.
    • 1:00:45That text is read top to bottom, left to right by your browser,
    • 1:00:48and loaded somehow into memory, using malloc or other techniques like that,
    • 1:00:53to create bunches of nodes in memory with a lot of pointers that somehow
    • 1:00:56represent this tree structure in the computer's memory
    • 1:00:59so that it actually knows what to display on the screen.
    • 1:01:03So with that said, let me go back here to VS Code.
    • 1:01:06And I'm going to go do a sequence of examples now.
    • 1:01:08And I'm going to go back to the code, and then back to my browser
    • 1:01:11to show you exactly what's going on.
    • 1:01:12Recall that at this moment in time, the only two things I have are
    • 1:01:15a source 8 folder, which I came with by default today
    • 1:01:18in advance, in case I need to copy-paste anything,
    • 1:01:20and index.html, which I just created for the first time.
    • 1:01:24So let me go back to my VS Code tab here.
    • 1:01:26And you'll notice that, in my terminal window,
    • 1:01:29there's actually a bunch of logging information, diagnostic information.
    • 1:01:32Long story short, anytime anyone visits a web server with a browser,
    • 1:01:37odds are the server is logging that visit.
    • 1:01:39In fact, this is how companies know.
    • 1:01:41This is how internet service providers know.
    • 1:01:43This is how parental controls know what websites
    • 1:01:46you are visiting, because all of this information
    • 1:01:48is going back and forth between browser and server.
    • 1:01:51Here, because I am running the server via that HTTP server command,
    • 1:01:55I now get access to all of this juicy information,
    • 1:01:57including the browser that the user is using,
    • 1:02:01what day and time they visited my page, and so forth.
    • 1:02:03But for the sake of discussion, I'm not going to really care
    • 1:02:06about this diagnostic information.
    • 1:02:07I'm going to hide this for the most part.
    • 1:02:09But notice 2 under ports now, whereas previously
    • 1:02:12I only had one TCP port in use--
    • 1:02:141337, which is CS50-specific, now notice that VS Code
    • 1:02:18has detected that I'm running something else on port 8080.
    • 1:02:22So you see a second port there.
    • 1:02:24And you might over time, if you open more and more tabs,
    • 1:02:26see even additional ports as well.
    • 1:02:27That all happened for you automatically.
    • 1:02:30So for now, I'm going to go ahead and hide my terminal window because I don't
    • 1:02:33really care what's going on there.
    • 1:02:34But that's still going to keep HTTP server for me running in the background.
    • 1:02:38Let's go ahead and introduce some new tags.
    • 1:02:40So for instance, let me go ahead and create a new file.
    • 1:02:44Actually, let me retract that.
    • 1:02:45Let me open my terminal window.
    • 1:02:46And instead of showing the log, let me create a second terminal window
    • 1:02:50with the plus icon.
    • 1:02:51So I'm still running the other one with the command,
    • 1:02:53but I still have the ability to run commands now in my here prompt.
    • 1:02:56For instance, I want to run a command--
    • 1:02:58code paragraphs.html.
    • 1:03:00Let's go ahead and create a more interesting web page
    • 1:03:03with actual paragraphs of English or other type of text.
    • 1:03:06To save myself some keystrokes, I'm going to be in the habit today
    • 1:03:09of copying the "hello, world" example as a starting point perhaps,
    • 1:03:13and then just changing it as needed.
    • 1:03:15For instance, I'm going to change the title of this here page to "paragraphs."
    • 1:03:18And then in here, I'm going to type out some paragraphs of text.
    • 1:03:22Now, what are those paragraphs.
    • 1:03:23Well, I wanted to save some time.
    • 1:03:25So in advance, I generated some Latin-like text here.
    • 1:03:28So I can copy paste three long paragraphs of Latin text, some lorem
    • 1:03:33ipsum text here.
    • 1:03:34Now, it doesn't matter what this means.
    • 1:03:35It's nonsensical words.
    • 1:03:37But this is a web page that is going to have ultimately
    • 1:03:39some paragraphs of text--
    • 1:03:42not English but fake Latin.
    • 1:03:44So let's go ahead and open this.
    • 1:03:46Let me go back to my other tab.
    • 1:03:48I do need to reload this tab because I've
    • 1:03:50created a new file that this browser didn't know about before.
    • 1:03:53There it is, Paragraphs.html.
    • 1:03:55Let me go ahead and click now paragraphs.html.
    • 1:03:57And there are my three paragraphs.
    • 1:04:01Well, wait a minute.
    • 1:04:02This is just like one big blob of a paragraph instead of the three
    • 1:04:05paragraphs that I was promised.
    • 1:04:06Well, why is that?
    • 1:04:07Well, let me go back to my editor here.
    • 1:04:11And you'll see that even if I hide my terminal here,
    • 1:04:14even though I've got these blank lines, clearly the browser is just ignoring me.
    • 1:04:18And this is because HTML is pretty pedantic.
    • 1:04:21It is designed to only do what you tell it to do.
    • 1:04:25And so if you don't tell it explicitly, give me a new paragraph,
    • 1:04:28it's just going to combine adjacent texts, as we've seen already.
    • 1:04:33So how do I do this?
    • 1:04:34It's actually pretty simple.
    • 1:04:35Let me go into my body tag, and let me actually open a paragraph tag,
    • 1:04:39or p for short.
    • 1:04:40Now notice, VS Code is trying to be helpful by automatically
    • 1:04:44completing the rest of this thought by giving me both a start tag and an end
    • 1:04:48tag.
    • 1:04:48In this case, that's not really helpful because I already
    • 1:04:51have the text that I want to put inside of this paragraph.
    • 1:04:54So I'm going to go ahead and delete the close tag manually.
    • 1:04:56And I'm going to move over here and close this myself.
    • 1:05:00And just to be stylistically nice, I'm going to go ahead and indent that.
    • 1:05:03Now down here, I'm going to do one more paragraph tag, p for short.
    • 1:05:07I'm going to cut that out.
    • 1:05:08And I'm going to paste this in here.
    • 1:05:10And again, I'm fighting with the autoformatting
    • 1:05:14because it is trying to understand what I intend,
    • 1:05:18even though I'm going back and fixing this now.
    • 1:05:19Let me fix that.
    • 1:05:21Let me go down here.
    • 1:05:22Let me go ahead and fix this now, indent here.
    • 1:05:25And voila, now we've got three paragraph elements.
    • 1:05:30And to clear, an HTML element is generally
    • 1:05:32everything between a start tag and an end tag.
    • 1:05:35So I have three paragraph elements-- p for short.
    • 1:05:37Why is it only p?
    • 1:05:38Well, the designers of the HTML language years
    • 1:05:41ago decided, why write out paragraphs, when open bracket, p, close
    • 1:05:45bracket suffices?
    • 1:05:46So let's now go back to my other tab.
    • 1:05:48Now, I see nothing changed.
    • 1:05:50But again, that's because I already received
    • 1:05:53the virtual envelope in my browser that contained
    • 1:05:55the previous version of that page.
    • 1:05:57If I want to get a new copy of paragraphs.html,
    • 1:06:00I need to reload this tab.
    • 1:06:02And now I see the same text, but broken down into three separate paragraphs.
    • 1:06:08So this is just to demonstrate the point that, if you want something to happen,
    • 1:06:11you really need to tell the browser to do exactly that.
    • 1:06:14Well, let's introduce some other tags too.
    • 1:06:16Let me go back to my editor here.
    • 1:06:19Let me go ahead and open my terminal window,
    • 1:06:21and let's create something called headings.html.
    • 1:06:24Much like a book, much like an academic paper,
    • 1:06:29you might have section headings, like the chapter and the section
    • 1:06:33and the subsection and so forth.
    • 1:06:34We can actually implement this with some HTML, too.
    • 1:06:37So let me cut a corner here, and copy and paste paragraphs.html
    • 1:06:41into headings.html.
    • 1:06:43Let me hide my terminal window.
    • 1:06:45Let me change the title here just to be "headings,"
    • 1:06:47to be super-explicit as to what's going on.
    • 1:06:49And let me go ahead now and say H1 One.
    • 1:06:53And down here, let me say H2 Two.
    • 1:06:56And down here, let me say H3 Three.
    • 1:06:59Now, these are three new P tags--
    • 1:07:00H1, H2 and H3.
    • 1:07:02By definition, H1 is typically big and bold.
    • 1:07:05H2 is typically not quite as big, but still bold.
    • 1:07:09H3 is not quite as big still, but still bold.
    • 1:07:12And these are the default stylizations of these here tags that come with HTML.
    • 1:07:16Let me go back to my other tab.
    • 1:07:18Let me click back.
    • 1:07:19So I now see my new file, headings.html.
    • 1:07:22Let me click on headings.html.
    • 1:07:24And now, even though it's still nonsensical Latin-like text,
    • 1:07:27at least it's starting to look pretty.
    • 1:07:29It looks like a chapter of a book with some sections and subsections
    • 1:07:33and so forth.
    • 1:07:34That's because the browser now understands what it is I want of it.
    • 1:07:38Now, you could simulate this by just literally typing
    • 1:07:40the word One in its own paragraph, the word Two in its own paragraph,
    • 1:07:43the word Three in its own paragraph.
    • 1:07:45But it wouldn't be bigger and it wouldn't be bolder.
    • 1:07:47And when it comes to the semantics of web pages,
    • 1:07:51it's probably useful to use tags, in this case, like H1, H2, H3,
    • 1:07:55because it indicates the relative importance of the text.
    • 1:07:59Like, this is the beginning of the text, this is maybe some finer detail,
    • 1:08:02and then this is the finest detail.
    • 1:08:03It might actually help search engines-- or heck, even AI nowadays,
    • 1:08:07understand that these are different sections in your text.
    • 1:08:09And we'll soon see, there's even other tags
    • 1:08:11you can do to be even more helpful to the browser and search engines and AI.
    • 1:08:16Well, how about something else?
    • 1:08:17Let's move away from big blobs of nonsensical text,
    • 1:08:20and let's do something with a chunk of nonsensical lists.
    • 1:08:24Let me go into my terminal window.
    • 1:08:27Create a new file called list.html.
    • 1:08:30And let me copy-paste my Hello code from earlier, just to save some steps.
    • 1:08:35And let me go ahead and rename the title to "list" in this case.
    • 1:08:38And let's just have a list of three things-- foo bar and baz.
    • 1:08:43If you've never heard these words before,
    • 1:08:44they're go-to computer science words when you just
    • 1:08:47want some random placeholders.
    • 1:08:48They mean nothing per se.
    • 1:08:50But foo, bar, and baz are go to default words like x, y,
    • 1:08:53and z for mathematicians.
    • 1:08:54All right, this looks like a nice, pretty list.
    • 1:08:56I've indented it, which looks great.
    • 1:08:58But if I go back to my other tab, hit Back, and I click on list.html,
    • 1:09:03I think you probably know where this is going.
    • 1:09:05Just like the paragraphs, we just get one big paragraph of "foo bar baz."
    • 1:09:09We don't get "foo" on one line, "bar on the next line, "baz" on the third.
    • 1:09:13Well, why is that?
    • 1:09:14Well, just as before, the browser seems to be ignoring whitespace,
    • 1:09:19beyond single white spaces.
    • 1:09:21In fact, I can try to be really explicit, like, please give me
    • 1:09:24some breaks between these lines.
    • 1:09:26But if I go back to my other tab, click Reload,
    • 1:09:29it just canonicalizes multiple spaces into a single space,
    • 1:09:33for better or for worse.
    • 1:09:34So if I really want a list, I need to tell the browser that I want a list.
    • 1:09:39And one way I can do that is as follows.
    • 1:09:41Let me delete that temporarily, and let me
    • 1:09:43do UL for unordered list, which means I'm
    • 1:09:46going to get a bulleted list with little circles next to each word.
    • 1:09:49Let me then use an li tag for list item and type "foo" inside of the first.
    • 1:09:54Let me type another li tag and "bar" for the next one,
    • 1:09:58and then a third with "baz."
    • 1:09:59And again VS Code is autocompleting, which
    • 1:10:01is why I'm able to type the close tag so quickly.
    • 1:10:04But I've got now foo, bar, and baz inside of li tags,
    • 1:10:07which in turn are inside of.
    • 1:10:08A UL tag.
    • 1:10:10Now let me go back to my other tab.
    • 1:10:13Click Reload.
    • 1:10:14And now we have a bulleted list of items, one at a time.
    • 1:10:18Well, what if I want to number this list?
    • 1:10:20Well, I could certainly just go in here and start manually
    • 1:10:23writing 1 and 2 and 3.
    • 1:10:25But you could imagine that getting a little annoying over time,
    • 1:10:27because if you need to reorder the list or add things to it,
    • 1:10:31it's just minorly annoying to have to maintain numbers for lists of things.
    • 1:10:35Like, this is what software is good at.
    • 1:10:36This is an easy fix.
    • 1:10:37And you might guess where I'm going with this.
    • 1:10:40If I want to move from an unordered list, which is just bullets
    • 1:10:43by default, to an ordered list, which is numbered,
    • 1:10:46I can change the ul to an ol in both places,
    • 1:10:50so that my start tag and end tag still match.
    • 1:10:52I can go back to my other tab, click Reload.
    • 1:10:54And what's going to happen by default now is, ah, I get 1 and 2 and 3.
    • 1:11:00And long story short, there are actually techniques
    • 1:11:02whereby you can change this behavior using attributes
    • 1:11:05to not just be these Arabic numerals.
    • 1:11:07But you can use Roman numerals or other symbols
    • 1:11:09that browsers are designed to support.
    • 1:11:11And it all just happens for you, which is great,
    • 1:11:13because if you're writing something like an outline for a paper or the like,
    • 1:11:16you don't really want to have to think about all of those numbers.
    • 1:11:19Just like Google Docs and Microsoft Word,
    • 1:11:21the software should figure that out for you.
    • 1:11:23And indeed, HTML can do just that.
    • 1:11:26All right, how about one other here this time.
    • 1:11:29Let me go ahead and cut a corner and open a file I created in advance, just
    • 1:11:33to save a few keystrokes.
    • 1:11:34Let me close most of those files for now.
    • 1:11:37Let me go ahead and copy from my src8 directory
    • 1:11:41a file I brought with me called table.html.
    • 1:11:44And let me open this up in its own tab.
    • 1:11:46And you'll see this file here that demonstrates a table.
    • 1:11:49And indeed, I know that, because I have atop this file
    • 1:11:52that I wrote in advance something called a comment.
    • 1:11:54We've seen comments in C with slash slash.
    • 1:11:56We've seen comments in Python with hash symbols.
    • 1:11:59In HTML, a little weirdly, you can write comments
    • 1:12:02with open bracket, exclamation point, dash dash.
    • 1:12:05Then you write your comment, and you finish your thought
    • 1:12:08with another dash dash, close bracket, but no additional exclamation point.
    • 1:12:13Why these keystrokes?
    • 1:12:15Well, the humans who designed this probably
    • 1:12:17figured, who is ever going to type that sequence of keystrokes?
    • 1:12:20Like that's what we'll use for our comments tag.
    • 1:12:22As an aside, if you ever actually want to write those patterns of characters,
    • 1:12:25there's a way to escape those things, as we've seen in other languages as well.
    • 1:12:29But let's focus on the juicy part here.
    • 1:12:31What's inside the body of this here page.
    • 1:12:34Apparently, something called a table.
    • 1:12:36And a table, by that we mean tabular data, like in a spreadsheet
    • 1:12:39or in a database table.
    • 1:12:41TR, I'll tell you, is short for table row--
    • 1:12:44tr.
    • 1:12:45TD is a little less obvious, but it's short for table data.
    • 1:12:48So it's like the cell in that row.
    • 1:12:51And the fact that there are three table data elements inside of this one table
    • 1:12:56row element means that there's going to be three cells, or really three columns,
    • 1:13:00from left to right inside of this row.
    • 1:13:03Below that is going to be another table row, inside of which
    • 1:13:06are three more cells, 4, 5, 6, as their contents, then 7, 8, 9, then curiously,
    • 1:13:12an asterisk, a 0, and a pound symbol.
    • 1:13:15So where are we going with this?
    • 1:13:16Well, if you're imagining in your mind's eye, a telephone that
    • 1:13:19has buttons and labels, it seems like I've just
    • 1:13:22been laying out rows and columns of numbers
    • 1:13:24you'd see on your cell phone or an old-time landline phone.
    • 1:13:28Well, let's open this.
    • 1:13:29Let me go back to my other tab.
    • 1:13:31Click Back.
    • 1:13:32Now you see table.html.
    • 1:13:34And this isn't going to be all that pretty, but it is tabular data.
    • 1:13:38And if I zoom in with command-plus here in my browser,
    • 1:13:40you can see that this is laid out rather like a phone pad.
    • 1:13:44Now, this is not a super-compelling use.
    • 1:13:46But you can imagine actual tabular data--
    • 1:13:48maybe data that came from a database, or maybe Google
    • 1:13:50in fact, when they implemented Google Sheets, or Microsoft when they
    • 1:13:53implemented office 365 in the cloud for Excel, maybe
    • 1:13:57that's how they're laying out all of your data in your browser
    • 1:14:00as it is underneath the hood.
    • 1:14:02They are using, of course, HTML, but specifically table tags like this.
    • 1:14:06Now, as an aside, they're probably doing even fancier things than that nowadays,
    • 1:14:10but they certainly could use TR tags, TD tags, and these table tags as well.
    • 1:14:16All right, enough about text.
    • 1:14:17Let me actually go back to VS Code here.
    • 1:14:20Let's close table.html, and let's do something with an image.
    • 1:14:23In fact, let me go ahead and grab a file called maybe bridge.png,
    • 1:14:28which is a Portable Network Graphic version of the bridge, with which you're
    • 1:14:32now familiar, that we ran a number of filters on in the past.
    • 1:14:35And this is now in PNG format, because BMP format, which
    • 1:14:39we used in a previous problem set, tends not to be used on the web
    • 1:14:43or supported necessarily by browsers.
    • 1:14:45But PNGs are, GIFs are, JPEGs are, and potentially a few other formats as well.
    • 1:14:50So I'm pretty good going with Portable Network Graphics.
    • 1:14:52We're good to go.
    • 1:14:53So let's create a web page that actually includes
    • 1:14:56this image, because at the moment I'm just showing you the image.
    • 1:14:59I'm not actually embedding this image in a web page,
    • 1:15:02like Google or other websites would.
    • 1:15:05So let's do this.
    • 1:15:05Let's close that tab.
    • 1:15:07Let's open a new file called image.html.
    • 1:15:10Just to save some keystrokes, let me copy-paste my "hello, world"
    • 1:15:13example again, changing the title to "image."
    • 1:15:16And in the body of this page, instead of any text,
    • 1:15:19let's actually put an image from Harvard University.
    • 1:15:22Let me go ahead and use open bracket IMG for short, source equals, quote unquote,
    • 1:15:28"bridge.png."
    • 1:15:30So in this case, we have a couple of new things going on here.
    • 1:15:33We've got a new tag, of course, IMG, which is short for image.
    • 1:15:36Why?
    • 1:15:37It was just faster to type for humans than "image."
    • 1:15:39So they called it three letters instead of five.
    • 1:15:41Source is representative of another attribute.
    • 1:15:44We saw an attribute earlier, lang equals en.
    • 1:15:47Well, it turns out that the image tag, if you read its documentation,
    • 1:15:50or listen to me now, has an attribute called source--
    • 1:15:54src for short, that allows you to specify the source of an image
    • 1:15:58that you want to display in the page.
    • 1:16:00But somewhat differently here, the image tag that I've written
    • 1:16:04has no close tag, no end tag.
    • 1:16:08I could do this--
    • 1:16:10open bracket slash image.
    • 1:16:12But frankly, this seems a little unnecessary, if not confusing.
    • 1:16:15And it is technologically unnecessary.
    • 1:16:17It turns out that some tags can be empty in the sense
    • 1:16:20that they don't need a close tag.
    • 1:16:22And an image makes sense.
    • 1:16:24Unlike a head of the page, the title of a page,
    • 1:16:27the body of a page that start over here, and maybe
    • 1:16:30end down here, an image is either there or it's not.
    • 1:16:34You can't start showing the image and eventually stop showing the image.
    • 1:16:37it's either there or it's not.
    • 1:16:39So you don't really need an end tag for certain start tags.
    • 1:16:42An image is among the examples.
    • 1:16:44If now I go back to my table here and click Back to see my directory index,
    • 1:16:49there is not only my PNG, but also my image.html page.
    • 1:16:53And if I click on this, it's not all that
    • 1:16:55different from looking at the image itself.
    • 1:16:57But apparently, this is a pretty high-resolution photograph that we took.
    • 1:17:00I haven't done anything to resize it.
    • 1:17:02And so what I'm seeing is a web page inside of which is this entire image.
    • 1:17:08So that's OK, but I'm going to need eventually
    • 1:17:11some techniques for shrinking this down.
    • 1:17:13And we'll come back to that in a little bit.
    • 1:17:15CSS, another language, is going to be one of our solutions
    • 1:17:18to that there problem.
    • 1:17:20But of course, things can go wrong.
    • 1:17:21For instance, suppose that I mistyped this and I wrote "bridge" without the E.
    • 1:17:26And I go back to this page and reload, that's, of course,
    • 1:17:28a typographical error.
    • 1:17:29And I see this broken icon.
    • 1:17:30And you might have seen this on the real web.
    • 1:17:32Sometimes, images are broken because it's essentially
    • 1:17:35a 404 happening underneath the hood.
    • 1:17:38And in fact, the image just cannot be found.
    • 1:17:40So if I want to help the user with this, for a number of reasons,
    • 1:17:44I can actually do this.
    • 1:17:45Let me add an Alt attribute for alternative,
    • 1:17:48and say something like "Harvard University."
    • 1:17:51In other words, in the event this image can't be displayed, go ahead
    • 1:17:54and at least show the user some explanatory text.
    • 1:17:57Better still, if someone is blind, or they
    • 1:18:00are using a screen reader to help them hear what is on a web page
    • 1:18:04that they otherwise can't see, the Alt attributes value
    • 1:18:07can be spoken aloud to someone with a screen reader,
    • 1:18:10so they know exactly what the image is that everyone else can see,
    • 1:18:13so they can still appreciate what the contents of this web page are.
    • 1:18:16If I go back to my tab here, in this case, it's still a typographical error.
    • 1:18:20But at least now, people with and without screen readers
    • 1:18:23can see what this image is supposed to be.
    • 1:18:25And even if I fix the typographical error and reload the page,
    • 1:18:29if someone can see the image, they now will.
    • 1:18:31But if someone's using screen reader software, which for those unfamiliar,
    • 1:18:34is software that looks at a web page and tries to describe in English,
    • 1:18:37or some other human language, what is on the web page,
    • 1:18:40now we have helped that device be all the more accessible as well.
    • 1:18:46So you might have zero or one, or now it seems two, attributes on a given tag.
    • 1:18:51All right, well, what else can we do in terms of media?
    • 1:18:53Well, there's something else we can do here.
    • 1:18:54And I'll just show you this one and let you play around
    • 1:18:56with it online if you'd like.
    • 1:18:57In my src8 directory, I've actually got a video file called video.html,
    • 1:19:03as well as video.mp4.
    • 1:19:05And if I open the former of those, you'll
    • 1:19:08see a page I wrote in advance that shows another technique about HTML.
    • 1:19:12At the end of the day, we still only have tags and attributes.
    • 1:19:15So fundamentally, we've not really pushed ourselves too far here.
    • 1:19:19But notice that there's a video tag in HTML that does come with two
    • 1:19:23attributes at least-- one called controls, one called muted.
    • 1:19:27The controls attribute just means please show the user a Play button
    • 1:19:31and a Pause button and maybe some other things.
    • 1:19:34The muted attribute means literally that-- mute the audio by default.
    • 1:19:37And that tends to be a good thing, because nowadays, browsers
    • 1:19:40are pretty defensive against advertisements,
    • 1:19:43and annoying advertisements like videos autoplaying on websites.
    • 1:19:46So you can ensure that your video will still autoplay,
    • 1:19:49but without bothering the user.
    • 1:19:51So you can mute the volume at least by default.
    • 1:19:53But what's worth noting for our purposes is that some attributes apparently
    • 1:19:56don't even need values.
    • 1:19:58There's no equal sign.
    • 1:20:00There's no quotes, which in some cases are
    • 1:20:03necessary to specify the language of this page is in English.
    • 1:20:06But some attributes indeed do not need values.
    • 1:20:09And even if they do, you can use, as in Python, single quotes or double quotes,
    • 1:20:13and sometimes no quotes at all.
    • 1:20:15But I would get into the habit still stylistically
    • 1:20:17of using double quotes for consistency as I have.
    • 1:20:21But as for the rest of this, a source tag
    • 1:20:25exists, which you can put inside of the video tag.
    • 1:20:27It itself has, confusingly, a source attribute-- src for short,
    • 1:20:31as well as a type attribute, which indicates what type of video
    • 1:20:35are you trying to play for the user.
    • 1:20:36So I'll wave my hands at some of that media.
    • 1:20:38But you're welcome to play that page and open it on your own,
    • 1:20:41and even unmute it to see what I've otherwise shown.
    • 1:20:45But let's now make the web all the more interactive.
    • 1:20:47Let me close that example.
    • 1:20:49Let me go ahead and open a new file called link.html,
    • 1:20:52and start making the hyperlinks with which
    • 1:20:55we're all familiar-- clickable links in web pages, which
    • 1:20:58is what makes the web the web itself.
    • 1:21:00Let me cut some corners here and copy-paste my "hello, world"
    • 1:21:03example into link.html.
    • 1:21:05Let me change the title to "link," just so we know what's what.
    • 1:21:08And let's actually make a page that has a genuine link to maybe that image
    • 1:21:13of Harvard called image.html.
    • 1:21:16I could say something like this--
    • 1:21:18visit Harvard, period.
    • 1:21:21Now, this of course, is just text.
    • 1:21:22So this is not that interesting.
    • 1:21:23But just to make sure we're on the same page, let me click back.
    • 1:21:26Let me go to link.html.
    • 1:21:29And you'll see that I've called it link.html, but there's no link there.
    • 1:21:32I can click Harvard all I want, but nothing actually happens.
    • 1:21:35So let's make it a link.
    • 1:21:36What do I want to link to?
    • 1:21:38Well, I could link to Harvard's website, but I already have a picture of Harvard.
    • 1:21:41Let's try linking to a page relative to this one.
    • 1:21:44Let me go ahead and open a new tag called the anchor tag--
    • 1:21:48a for short.
    • 1:21:49Let me use its attribute called href, which is a little arcane.
    • 1:21:53But it stands for hyperreference, the destination of this link.
    • 1:21:56Let me add some quotes and say image.html, close quote, close tag.
    • 1:22:02And then notice, VS Code is trying to be helpful.
    • 1:22:04But sometimes, it doesn't know what I intend.
    • 1:22:06So I'm going to delete the end tag, move my cursor over, and paste it at the end
    • 1:22:10and finish my period there, just because I want everything to be balanced.
    • 1:22:14And now, even though this one looks a little more cryptic,
    • 1:22:17this is now the beginning of hyperlinking pages on websites.
    • 1:22:21If I go back to my other tab, click Reload, ah,
    • 1:22:24now I see the familiar underline text, which of course signals in many web
    • 1:22:28pages that this here is a link.
    • 1:22:30If I hover over it, it's going to be a little small.
    • 1:22:33But in the bottom left-hand corner of my browser, which is Chrome,
    • 1:22:36I can actually see that this will lead me to a page called image.html.
    • 1:22:41And indeed, if I click on Harvard for real, I get back to image.html.
    • 1:22:47And the URL in my browser has changed from link.html to image.html.
    • 1:22:52So this is what's known as a relative link, whereby I'm linking from one
    • 1:22:55of my own pages to another of my pages.
    • 1:22:57They're in the same folder, so I don't need to mention any folder names.
    • 1:23:00The server just knows what I want.
    • 1:23:03So that's then a link.
    • 1:23:05But what if I want to link to an actual URL, and not just a relative page,
    • 1:23:10like Harvard's own website?
    • 1:23:11Well, that I can do too.
    • 1:23:12I can change the value of this href attribute.
    • 1:23:15And I could just do harvard.edu.
    • 1:23:18Unfortunately, this is not going to work.
    • 1:23:20The values of HREFs in a web page, if they're going to be full fledged URLs,
    • 1:23:25have to be actual URLs, protocol and all in this case.
    • 1:23:29And so I'm going to do https://www.harvard.edu.
    • 1:23:34And heck, I'm going to include the trailing slash,
    • 1:23:36even though I don't strictly need it.
    • 1:23:37And technically speaking, I could omit the protocol
    • 1:23:40if I want the same protocol to be used.
    • 1:23:42But in general, I'm going to link to the full-fledged URL of harvard.edu here.
    • 1:23:46I'm going to go over to my Image tab.
    • 1:23:48I'm going to click Back to go back to my Link tab.
    • 1:23:52I'm going to reload to make sure I get the latest HTML in my browser.
    • 1:23:55And if I hover over this now-- super-subtle.
    • 1:23:57But in the bottom corner of my browser now, ah, this indeed
    • 1:24:01leads me to harvard.edu.
    • 1:24:02And if I click that, we should see the familiar forests
    • 1:24:06that we saw a little bit ago.
    • 1:24:08And now this is an external link, not a relative link,
    • 1:24:11that I've now implemented in this web page.
    • 1:24:14All right, let me click back.
    • 1:24:16And let me reveal one other feature now of those so-called developer tools.
    • 1:24:20Previously, I opened up developer tools when
    • 1:24:22I wanted to play around with HTTP, the protocol that just gets the web
    • 1:24:26pages from browser to server and back.
    • 1:24:28But now it turns out I'm going to use another feature of my developer tools
    • 1:24:32by right-clicking or Control-clicking anywhere on my page
    • 1:24:34or going through the main menu.
    • 1:24:37I'm going to click Inspect.
    • 1:24:38And now Inspect makes a little more sense,
    • 1:24:40because now, I'm literally inspecting the web page itself.
    • 1:24:44Notice at left here is a visualization of the underlying HTML of this web page.
    • 1:24:51And some of it's hidden, but I'm going to click the little triangles to reveal
    • 1:24:55the rest of it.
    • 1:24:55And you will see essentially, at left here,
    • 1:24:58under the Elements tab in Chrome, a list of all of the elements
    • 1:25:02that compose this web page.
    • 1:25:03And again, an element is everything between an open tag and a close tag.
    • 1:25:07So in this case.
    • 1:25:08I'm seeing a very pretty printed version of my own source code.
    • 1:25:11And some things are broken out onto different lines,
    • 1:25:13just to make clear that here's some text.
    • 1:25:15Here's a link.
    • 1:25:16Here's some other text, both of which are inside of this body tag.
    • 1:25:19And notice too, as I hover over things, Chrome--
    • 1:25:22just to be helpful, because if I'm a developer, I want some help here,
    • 1:25:25I can see in light blue what I am hovering over in my HTML
    • 1:25:30being mirrored in the actual body of the page.
    • 1:25:33If I hover over the body, I see everything to the body as well.
    • 1:25:37Now, what I can take away from this is the following.
    • 1:25:41This here is my web page and it's very pretty printed.
    • 1:25:43If I close this tab, I can see my same code in another way.
    • 1:25:47If I right-click or Control-click, I can also go to View Page Source.
    • 1:25:51View Page Source is a feature that's been in browsers for years.
    • 1:25:54And you can see the same code, but exactly as it came from the server.
    • 1:25:58I happen to be pretty nitpicky, so it's all nicely indented as well.
    • 1:26:01But this is a static version of the page,
    • 1:26:04whereas the developer tools allows me to actually poke around with things.
    • 1:26:10In fact, let me close this tab.
    • 1:26:11Let me re-click again on Inspect.
    • 1:26:13And watch this.
    • 1:26:14If I want to poke around here, I could actually go into the developer tools
    • 1:26:19and temporarily, without even going back to my terminal window,
    • 1:26:23I can click on or double-click on anything in this page.
    • 1:26:26And I can actually change it in real time.
    • 1:26:28Like, I can change Harvard to Harvard University, and then hit Command Enter.
    • 1:26:32And in this case, I can change the contents of the web page.
    • 1:26:35But curiously, that has not changed anything on the server
    • 1:26:39because this makes clear the point that, once the browser has requested a web
    • 1:26:42page from the server, and downloaded that virtual envelope
    • 1:26:46inside of which is the original version of link.html, that's what the browser is
    • 1:26:50going to keep in its memory.
    • 1:26:52You can change your copy of that page all you want,
    • 1:26:55but it doesn't affect the server at all.
    • 1:26:58The browser gets a copy of what's on the server.
    • 1:27:01In fact, we can take this feature out for a spin, seemingly maliciously,
    • 1:27:05but not in a way that has any effect.
    • 1:27:07In fact, let me pull up not just harvard.edu,
    • 1:27:08but specifically the admissions page for Harvard College and scroll down here.
    • 1:27:12And you'll see this advertisement toward the end, "Why Harvard?"
    • 1:27:15Well, notice that if I want to see the underlying HTML of this page,
    • 1:27:19I can see it in a couple of ways.
    • 1:27:20I can right-click and choose View Page Source.
    • 1:27:23And it's going to look like way more code than we've written to date.
    • 1:27:26This is me scrolling through all of the HTML
    • 1:27:28that composes the admissions website's HTML at Harvard.
    • 1:27:31There's a lot there, but it's going to follow that same pattern of tags
    • 1:27:35and attributes.
    • 1:27:36Or I can pretty print it by going to Inspect, going to the Elements tab.
    • 1:27:41And there, notice, is the exact same content,
    • 1:27:43even though I was scrolling through it super fast.
    • 1:27:45But it shows you everything pretty printed, so you can poke around.
    • 1:27:48More importantly, I can click on any part of the page
    • 1:27:51with my Control key or two fingers and select Inspect.
    • 1:27:55And what's nice is that Chrome, and really any browser,
    • 1:27:58will jump to the specific HTML in the browser's memory
    • 1:28:01that corresponds to that part of the page.
    • 1:28:03The upside of this is, I can actually infer
    • 1:28:05how did Harvard make this web page?
    • 1:28:07How did they structure their HTML?
    • 1:28:09Now, we haven't talked about all of these tags yet,
    • 1:28:11but notice that there's all of these div tags--
    • 1:28:13D-I-V. There's a section tag, but there are some familiar ones.
    • 1:28:17Here's an H2.
    • 1:28:18Harvard is using an H2 tag for "Why Harvard?"
    • 1:28:20Here's a ul down below for some kind of unordered list.
    • 1:28:24But notice here, I can be a little playful here,
    • 1:28:26and maybe we should nudge people to go to Yale instead.
    • 1:28:28Let me change, in the Elements tab, Harvard to Yale.
    • 1:28:32Hit Enter, and now I seem to have hacked Harvard's website,
    • 1:28:36and it suddenly says "Why Yale" instead.
    • 1:28:38But of course, this changes nothing on the server, because this too is a copy.
    • 1:28:42And the moment I reload Harvard's website,
    • 1:28:45I get a fresh copy of what's actually on the server.
    • 1:28:48So what's the value here.
    • 1:28:49Well, one, pedagogically, it's just a useful mechanism, these developer tools,
    • 1:28:53for understanding and learning how a website is structured.
    • 1:28:56If you want to do something similar yourself, as a developer tool,
    • 1:29:00frankly, sometimes it's a lot faster to just mock things
    • 1:29:02up in the developer tools.
    • 1:29:04Decide, OK, I like how this looks.
    • 1:29:06And then go over to your actual HTML and make the changes for real.
    • 1:29:10It's a faster way of iterating, and it's also
    • 1:29:13a helpful way of diagnosing certain problems that we might otherwise
    • 1:29:16run into.
    • 1:29:18All right, but there's still a danger here.
    • 1:29:21Speaking of Harvard and speaking of Yale,
    • 1:29:23let me go ahead and close that tab there,
    • 1:29:25and return to the HTML of link.html.
    • 1:29:28It turns out that the attacks with which you're
    • 1:29:31familiar in the real world, namely phishing attacks,
    • 1:29:34are all too easily waged via HTML alone.
    • 1:29:38To be phished typically means to receive some kind of spam email
    • 1:29:41that's trying to trick you into clicking on a link that
    • 1:29:44purports to be legitimate, but is really taking you to some adversary--
    • 1:29:47some bad guy's website that's trying to steal your credit card
    • 1:29:50information, your username, your password, or something like that.
    • 1:29:53And those emails in Gmail, in Outlook, and other tools,
    • 1:29:56they themselves are using HTML.
    • 1:29:58Any time you get an email that's not just black and white text,
    • 1:30:00but has colors, and maybe images and formatting, it's using HTML.
    • 1:30:04So HTML is used not only for web pages, not only for mobile apps,
    • 1:30:08but also for emails as well.
    • 1:30:10And here's how easy it is to, unfortunately, deceive users.
    • 1:30:13Suppose that I still have a link here to Harvard,
    • 1:30:16but I actually changed the actual href to be yale.edu.
    • 1:30:20If I go back to my actual browser here and close my developer tools and click
    • 1:30:24Reload, the page still says, like the HTML, "Visit Harvard."
    • 1:30:29And this is super-subtle, but if I hover over this link,
    • 1:30:32in the bottom corner of my browser now I'm
    • 1:30:35actually going to be led to yale.edu if I click this link.
    • 1:30:38In fact, if I actually do that, voila, now I'm actually at yale.edu.
    • 1:30:42So not a big deal in this case.
    • 1:30:44I'm just sending one student from one place to another.
    • 1:30:47But you could imagine making a website that
    • 1:30:50looks like a bank's website, that looks like Paypal's website, that
    • 1:30:53looks like something legitimate, such that when I click on a link--
    • 1:30:56no one's really looking in the bottom left-hand corner of their browser
    • 1:30:59all the time.
    • 1:30:59You could all too easily trick a user into visiting a page,
    • 1:31:03and maybe filling out a form on a page that they didn't actually intend.
    • 1:31:07And we say this not to empower you to do such things,
    • 1:31:10but the opposite-- to detect when such behavior is happening.
    • 1:31:13And frankly, getting into the habit of hovering
    • 1:31:15over links that you're a little suspicious about
    • 1:31:18is probably a good practice.
    • 1:31:20But for today, know just how easily these threats can be waged,
    • 1:31:24and why there are so many of these threats to us online.
    • 1:31:27It boils down to these basic fundamentals.
    • 1:31:31Now, all that said, we haven't even done anything dynamically.
    • 1:31:34Every web page we've made thus far has still been very static,
    • 1:31:38like content I have made in advance.
    • 1:31:40And you can reload, reload all you want.
    • 1:31:41It's always going to look the same from the server again and again.
    • 1:31:45But how about we revisit how URLs work, not just to serve up static content,
    • 1:31:51but dynamic content as well?
    • 1:31:53It turns out that, besides having folder names and file names at the end of URLs,
    • 1:31:57you can also have a question mark in URLs,
    • 1:32:01and then key value pairs literally with an equal sign in-between them.
    • 1:32:05We've seen key value pairs all over the place, most recently
    • 1:32:08in things like dictionaries, for instance.
    • 1:32:10But in this case here, we have a canonical format
    • 1:32:13for how you can actually provide input from a browser to a server.
    • 1:32:18Typically, that's typed in via form.
    • 1:32:20So for instance, let me actually open up a brand-new tab here.
    • 1:32:23Let me go to google.com, just the main page that doesn't come with my browser.
    • 1:32:27And I'm going to go ahead and type in something like cats--
    • 1:32:31C-A-T.
    • 1:32:31Now, ignoring the fact that there's a whole lot of autocomplete going on here,
    • 1:32:34let me hit Enter.
    • 1:32:35And let me emphasize what my URL--
    • 1:32:38we can be distracted for a moment by the cute cats on the top of the page.
    • 1:32:42But let's then zoom in on the top of the page
    • 1:32:45here, where we'll see a very long URL, most of which,
    • 1:32:48frankly, I don't understand.
    • 1:32:49And probably only Google employees want to understand
    • 1:32:51what everything is in this URL.
    • 1:32:53But let me delete most everything, except the essence of this URL.
    • 1:32:57And what I've left at the top of my browser
    • 1:32:59is only https://www.google.com/search, which is the path, question mark,
    • 1:33:06q equals cats.
    • 1:33:10It turns out, way back in 1999, when Larry and Sergey founded Google
    • 1:33:15and created their very first search page,
    • 1:33:17they had a text box, just like this one, but more simple in design.
    • 1:33:20And if you filled out that text box with one or more words and hit Enter,
    • 1:33:24you submitted a query to the server for which you want to search, Q for short.
    • 1:33:29And so all that form needs to do, when you hit Enter, is change the URL,
    • 1:33:35it would seem, to take that user input in a standard format.
    • 1:33:39Q equals cats, something equals something, something equals something.
    • 1:33:43In fact, if there's multiple such parameters
    • 1:33:46as these are called, just like in functions,
    • 1:33:48you can separate them with ampersands.
    • 1:33:49But the question mark just means to the server, hey, server, here come
    • 1:33:53some key value pairs, otherwise known as HTTP parameters.
    • 1:33:56When I hit Enter, the search results are actually going to be exactly the same.
    • 1:34:00Most of the other stuff in the URL is probably for tracking purposes,
    • 1:34:03so Google can keep track of what I'm searching for and what I'm clicking on.
    • 1:34:06But in essence, if we distill the URL to just question
    • 1:34:09mark q equals cats after search, we have provided user input to this here page.
    • 1:34:17And what's cool about that is the following.
    • 1:34:20Normally the canonical URL might be as simple as this.
    • 1:34:22Or it might actually have two key values in pairs, which indeed can
    • 1:34:25be separated by these here ampersands.
    • 1:34:27I think I can take advantage of this here feature and implement
    • 1:34:31my own version of Google.
    • 1:34:32Let me do this.
    • 1:34:33That's it for HTML.
    • 1:34:34Like, there's bunches of other tags and attributes out there.
    • 1:34:37But those are really for an online tutorial or book or reference,
    • 1:34:40or some other source, to just pick up what more vocabulary there is.
    • 1:34:44At the end of the day, it's just more tags and more attributes
    • 1:34:47following this shared structure.
    • 1:34:50So for now, I want to make things more dynamic,
    • 1:34:52leveraging my knowledge of just that.
    • 1:34:54Let me go back into my VS Code.
    • 1:34:56Let me create my own page called search.html, Enter.
    • 1:35:01Let me save a few keystrokes by copying and pasting my "hello, world"
    • 1:35:04code and changing the title to "search."
    • 1:35:06Let me get rid of the body here.
    • 1:35:08And let me begin to create my very own form, using literally a form tag--
    • 1:35:13F-O-R-M space, and then here I'm going to close the tag immediately.
    • 1:35:18Inside of this form element now, let me go ahead and create an input whose name
    • 1:35:22equals "q."
    • 1:35:24And inside of this form element, let me additionally
    • 1:35:27add an input whose type equals submit.
    • 1:35:30And we'll see what this gets us first.
    • 1:35:32Let me go back to my other tab.
    • 1:35:34Click back to see my directory listing of files.
    • 1:35:36Click on search.html.
    • 1:35:38And this is super-simple, but I seem to have
    • 1:35:41the beginnings of an interactive web form-- a big text box,
    • 1:35:44and a Submit button by default that seems to be a form.
    • 1:35:47Unfortunately, if I type in anything to this "cats," and then click Submit,
    • 1:35:51nothing actually happens.
    • 1:35:53But if I go to my own URL here at the top,
    • 1:35:56notice that I'm still on search.html.
    • 1:35:59But "cats" was automatically added for me by the browser as soon as I click
    • 1:36:06Submit.
    • 1:36:06So let me go back and add a little more detail in my editable file.
    • 1:36:10Let me specifically specify that the type of this text box is text,
    • 1:36:15but that, it turns out, is the default. So I'm actually
    • 1:36:18going to enhance that and make this a search box specifically.
    • 1:36:21Let me go back to my browser and reload.
    • 1:36:23And this is subtle, but if I now type in "cats,"
    • 1:36:26notice that I get this little X here, which is just a user-friendly feature,
    • 1:36:30which means now I can click on the X to clear that box.
    • 1:36:32That is simply because I changed the type of this box from generic text
    • 1:36:36to a search box for which that feature is useful.
    • 1:36:39I don't really like the idea of Submit.
    • 1:36:40I'd like my button to say something about Google.
    • 1:36:43So let me go back to my submit tag here and change the value of that input
    • 1:36:48to be, quote unquote, "Google search."
    • 1:36:51Then let me go back to the page, Reload.
    • 1:36:53And now things are getting a little more interesting,
    • 1:36:56whereby I have a Google search button.
    • 1:36:58It still doesn't do anything.
    • 1:36:59But let me be more specific.
    • 1:37:02When I submit this form, I want the method to be used, the verb to be,
    • 1:37:06quote unquote, "get."
    • 1:37:07Somewhat confusingly, the convention is to use lowercase here,
    • 1:37:10even though inside of the envelope, I've demonstrated
    • 1:37:13with curl that it tends to be capitalized in the actual HTTP protocol.
    • 1:37:17But so be it.
    • 1:37:18But get is actually the default.
    • 1:37:20So I don't strictly need that.
    • 1:37:21But what I do want to add here is an action.
    • 1:37:23What action do I want this form to take when submitted?
    • 1:37:26Well, I don't have a back end.
    • 1:37:28I don't have a database.
    • 1:37:29I have not searched the web ever with this here code space, but Google has.
    • 1:37:33So let me use Google's back end, their servers and database,
    • 1:37:37to search for whatever q is.
    • 1:37:39Let me change the action value here to be https://www.google.com/search,
    • 1:37:47so just the beginning of that URL without the question mark.
    • 1:37:51Now let me go back to my Search tab, reload.
    • 1:37:54And now nothing visually seems to have happened.
    • 1:37:56But if I type in "cats" now, and click on this new and improved Google search
    • 1:38:02button, watch what happens not only to my URL, but the contents of the page.
    • 1:38:08I have just searched from my own web page for cats on google.com.
    • 1:38:14In other words, by nature of how HTML forms work, specifically
    • 1:38:19using the get method and the action of Google's own URL,
    • 1:38:23my browser knows how to assemble all of those ingredients
    • 1:38:27into a brand-new URL that contains as the value of q whatever
    • 1:38:31I typed into that box.
    • 1:38:32And heck, I can do this manually now, even though no one searches like this,
    • 1:38:35I could just search for q equals dogs.
    • 1:38:37And now I get some adorable dogs as my search results here.
    • 1:38:40But that's just because I now understand what these URLs are doing for me
    • 1:38:44and how they are structured.
    • 1:38:46If I zoom out, and I go back to search.html,
    • 1:38:49I can actually make some improvements here to that same form.
    • 1:38:51You might have noticed that when I typed "cats" the second time,
    • 1:38:54I actually saw it autocompleting as "cats."
    • 1:38:56There was a little pop over there.
    • 1:38:58If I don't want any autocomplete, there's an attribute for that--
    • 1:39:00autocomplete equals, quote unquote "off."
    • 1:39:03This will now disable the browser from remembering things
    • 1:39:06that I've searched for before.
    • 1:39:08I can also do this.
    • 1:39:09Notice if I go back here to my search page and click Reload, notice that,
    • 1:39:14with no hands on the keyboard, the box is there, the button is there,
    • 1:39:17but my cursor isn't.
    • 1:39:19I have to manually focus my cursor on that box.
    • 1:39:22And then it gets highlighted in blue and I see the blinking cursor.
    • 1:39:25That's not the best user experience, or UX, so to speak.
    • 1:39:28Why are you going to make the user move their cursor
    • 1:39:31and put the cursor where you want it to be anyway?
    • 1:39:33So I can fix that.
    • 1:39:34Let me go back to this same search box.
    • 1:39:37And let me add autofocus.
    • 1:39:39And I don't actually need to give it a value.
    • 1:39:41But if I now go back to the page and reload--
    • 1:39:43watch.
    • 1:39:44Even without clicking on that text box, it's
    • 1:39:46already highlighted and blinking, because I've given focus,
    • 1:39:50so to speak, to that there text box.
    • 1:39:52Now, what is this text box?
    • 1:39:53It's just a big white box.
    • 1:39:54Well, if you read the documentation for--
    • 1:39:56or listen to what I'm here saying about, the input tag,
    • 1:40:00you can also have a placeholder attribute that can contain any text you
    • 1:40:04want, like "query," for instance, quote unquote.
    • 1:40:07If I now go back to this page, reload once more,
    • 1:40:10now you see in gray text inside of the box
    • 1:40:13explanatory instructions as to what I'm looking for.
    • 1:40:16And as soon as I start typing, C-A-T-S query goes away.
    • 1:40:20So that, too, is a feature you've probably seen in browsers.
    • 1:40:22That's just the result of someone having used the right HTML tags and attributes.
    • 1:40:28Now, I've been a little deliberate here.
    • 1:40:31I have alphabetized all of my attributes,
    • 1:40:33if only because it helps me personally skim things from left to right,
    • 1:40:36and know if I've missed something that I intended.
    • 1:40:39But strictly speaking, there is no official
    • 1:40:40ordering to any of these attributes.
    • 1:40:43You can put them left to right, right to left.
    • 1:40:45They don't need to be alphabetically sorted.
    • 1:40:47But stylistically, this is indeed what I myself tend to do here.
    • 1:40:50Let's take a look at one more use of forms
    • 1:40:53that will allow us to introduce another feature that's present
    • 1:40:55not only in HTML, but in other programming languages
    • 1:40:58as well, including, in fact, Python.
    • 1:41:00So let me go ahead and create a new file here called register.html.
    • 1:41:04And let's just imagine that we're trying to create
    • 1:41:06a web page via which someone can register for something--
    • 1:41:09a website, a sport, or anything else.
    • 1:41:11And what I'm going to do in register.html is save a few keystrokes
    • 1:41:14and copy my search code into register.html.
    • 1:41:18And I'm going to change the title to "register."
    • 1:41:20And I'm going to get rid of the form as a starting point here.
    • 1:41:23Let me close my terminal.
    • 1:41:24And inside of this form, let's just create
    • 1:41:26the beginnings of a registration form.
    • 1:41:27But unlike the Google example, I'm not going
    • 1:41:29to bother trying to submit this anywhere.
    • 1:41:31That will be a goal for another time.
    • 1:41:33But let me go ahead and, in this form, create
    • 1:41:35an input for which autocomplete is off, like before,
    • 1:41:39for which the field is autofocus.
    • 1:41:41And you should only have one autofocus field.
    • 1:41:43Otherwise, the cursor doesn't know where to go.
    • 1:41:45Let me specify that I want this input to be someone's email address,
    • 1:41:48because after all, I want this to be a registration page.
    • 1:41:51So the placeholder text I'm going to be using is "email,"
    • 1:41:53so they know what to type.
    • 1:41:55And then the type of this field for now is just going to be text.
    • 1:41:58And then I'm going to go ahead and have a Submit button.
    • 1:42:01But it turns out you can have different types of buttons.
    • 1:42:03And one other way to express a Submit button is literally with an HTML element
    • 1:42:07called "button," for which the label here will be Register.
    • 1:42:10So long story short, there's different ways to implement buttons.
    • 1:42:13Here is now a second way.
    • 1:42:15Let me now go back to my other tabs.
    • 1:42:17Let's close the tabs.
    • 1:42:18Let's hit Back to get to my directory index.
    • 1:42:21And let's now click on register.html.
    • 1:42:23So it's very similar in spirit to my search form,
    • 1:42:26but now I'm clearly asking for an email with the registration button.
    • 1:42:29However, I could try to register with anything here.
    • 1:42:32In fact, if I'm not paying attention, maybe I'll
    • 1:42:34just type my name like I always do in these examples and click Register.
    • 1:42:37And even though nothing technically happened, notice my URL did change.
    • 1:42:42So the form was submitted because question mark
    • 1:42:44email equals David is appearing there.
    • 1:42:46But that was not an email address.
    • 1:42:48And it would be nice if the browser says no, no, no, no, no, that's
    • 1:42:50not an email address.
    • 1:42:51You cannot submit that form yet.
    • 1:42:52But if this is just a text box, it's going to tolerate any kind of text.
    • 1:42:56But as you might know from Microsoft Office and Google Forms,
    • 1:43:00you can certainly validate forms in those kinds of software.
    • 1:43:04Certainly, we could do so in HTML.
    • 1:43:06Well, we can in a couple of ways.
    • 1:43:07Let me go back to my HTML.
    • 1:43:09And let me change the type of this input to be not text, not search, but email.
    • 1:43:15And it turns out that this is one of the officially supported types of inputs
    • 1:43:18nowadays, where the browser will now know that, OK,
    • 1:43:21before I can let the human submit this form,
    • 1:43:23I'd better check that they typed in an email.
    • 1:43:26So let me reload this page.
    • 1:43:28Let me again foolishly try to type in just my name, not my email, and click
    • 1:43:32Register.
    • 1:43:33And now notice, I'm getting admonished by the browser.
    • 1:43:35This is a default pop-up that's saying, please
    • 1:43:38include an @ in the email address.
    • 1:43:39David is missing an @.
    • 1:43:40So obviously, I've not typed an email address.
    • 1:43:43So let me fix this-- malan@harvard.edu.
    • 1:43:46Now the error has gone away.
    • 1:43:48I can click Register.
    • 1:43:49And even though nothing useful happens, again, the URL
    • 1:43:52changed, indicating that I did submit the form, just to know we're useful.
    • 1:43:56All right, so that's all fine and good.
    • 1:43:58But it turns out that email is one of the relatively few types of fields
    • 1:44:02that you can check for, in addition to search and text more generally,
    • 1:44:06and a few others as well.
    • 1:44:07But it turns out that browsers nowadays, in the context
    • 1:44:11of HTML, support what are called regular expressions to help solve this problem,
    • 1:44:16a regular expression is a pattern, otherwise known as a regex for short,
    • 1:44:21that allows you to validate input from users,
    • 1:44:25and make sure that input matches some pattern.
    • 1:44:28And this is a bit of a mouthful how you can do these.
    • 1:44:30There's a whole bunch of documentation online, not only at this URL,
    • 1:44:34but in Python's own documentation and in other locations as well.
    • 1:44:37But I just wanted to give you a taste of the possibilities
    • 1:44:39because these are really everywhere in high-level programming nowadays, as well
    • 1:44:43as in this context of HTML.
    • 1:44:45Here is the symbology of regular expressions.
    • 1:44:48We're not in a language.
    • 1:44:49It's just a way of representing patterns, if you will.
    • 1:44:52If you have a dot in a string of text, that's
    • 1:44:55a regular expression, that just means any character.
    • 1:44:58It's like a wildcard.
    • 1:44:59Any one character can be there.
    • 1:45:02A star actually means zero or more times.
    • 1:45:06So you can say, give me character zero or more times.
    • 1:45:09So there's either nothing there or there's one or there's two
    • 1:45:12or there's more.
    • 1:45:12You can use a plus, which means give me one or more characters.
    • 1:45:16So not zero, but one or more.
    • 1:45:18You can use a question mark, which means zero or one character, but that's it.
    • 1:45:22You can use curly braces unrelated to Python and say,
    • 1:45:25I want this many occurrences of a character.
    • 1:45:28And you can have a range inside of curly braces
    • 1:45:30give me minimally this many characters, maximally this one.
    • 1:45:33And you can do other things too.
    • 1:45:35In square brackets, you can say, give me any one of these digits--
    • 1:45:380 through 9 in this case.
    • 1:45:39But you could type anything in there that you want.
    • 1:45:41You could say 0-9 to specify a whole range without having to type them all
    • 1:45:46out.
    • 1:45:46You can type backslash D to indicate any digits,
    • 1:45:51so you don't have to type any of that out.
    • 1:45:52Or you can do the opposite, backslash capital
    • 1:45:55D, which means anything except a digit.
    • 1:45:59So long story short-- and I'm very much waving my hands at some of the details
    • 1:46:03here.
    • 1:46:03There's this whole symbology that humans have come up
    • 1:46:06with in different languages via which you can represent patterns.
    • 1:46:10So this is all to say that I could come up
    • 1:46:12with my own pattern for an email address,
    • 1:46:15even though it's not going to be as good as the browser's own.
    • 1:46:18Let me go back to VS Code here.
    • 1:46:20Instead of saying email type equals email, let me go back to type
    • 1:46:24equals text.
    • 1:46:25Or heck, I can go to the default and get rid of this altogether.
    • 1:46:28But I'm going to use one other attribute we haven't yet seen,
    • 1:46:30which is literally pattern equals, quote unquote.
    • 1:46:33Inside of this patterns value.
    • 1:46:35I can use a regular expression, a pattern that represents
    • 1:46:39what kinds of values I want to accept.
    • 1:46:41Now, I'm going to keep this simple, and therefore not very good.
    • 1:46:44But remember, that dot means any character.
    • 1:46:47Plus means one or more of any character.
    • 1:46:51An @ sign means literally an sign.
    • 1:46:54Another dot means any character.
    • 1:46:56Another plus means one or more of any character, then backslash .edu.
    • 1:47:04What's going on here?
    • 1:47:05Well, we haven't seen this yet.
    • 1:47:07But curiously, if I want to literally have a period in the user's input,
    • 1:47:12well, I can't use dot because that means any character.
    • 1:47:15It was a wild card.
    • 1:47:16So just like in C, just like in Python, I have to escape certain characters.
    • 1:47:20So in regular expressions, if I do backslash dot, that means,
    • 1:47:23give me a literal dot in the user's input, an actual period.
    • 1:47:26And then edu means make sure that the user's email address in this case ends
    • 1:47:31with .edu.
    • 1:47:33Now, this is a bit of a simplification because it is not the case in email
    • 1:47:36addresses that you can allow for any one or more characters than an @ sign,
    • 1:47:41and then any one or more characters, and then a .edu,
    • 1:47:46it's actually more formally defined than that.
    • 1:47:48So this is a very quick and dirty regular expression for an email address.
    • 1:47:51However, if I now go back to my register page and reload,
    • 1:47:54and I again try to type in David, and not an invalid email address,
    • 1:47:58that pattern will be checked.
    • 1:48:01And the browser will prevent the form from submitting at all.
    • 1:48:06So I can express different patterns of things.
    • 1:48:08Now, for email, that's not the best thing,
    • 1:48:10because in fact, if I actually look at the official definition of an email
    • 1:48:13address' regular expression, according to browsers,
    • 1:48:16it's actually this crazy, long sequence of text, using the symbols I showed you,
    • 1:48:21as well as some others.
    • 1:48:23But this just speaks to how complicated the definition of an email addresses
    • 1:48:28pattern is.
    • 1:48:29So using type equals, quote unquote, "email" is definitely the better bet.
    • 1:48:33But let me do something a little more reasonable.
    • 1:48:35If I go back to VS Code here, and let's suppose
    • 1:48:37that we want to ask the user not for an email address, but their phone number.
    • 1:48:41So let me change the placeholder to be Phone, for instance,
    • 1:48:44and then let me change the pattern to be that of a US phone number.
    • 1:48:48So here, I can do this in a bunch of ways.
    • 1:48:50But I'm going to use backslash D, which means any digit,
    • 1:48:53and then curly braces three times, then a hyphen, then a backslash D,
    • 1:48:58curly braces 3, then a hyphen, then backslash D, curly braces 4.
    • 1:49:02And this here represents a standard format for a US-based phone number--
    • 1:49:06three digits dash three digits dash four digits.
    • 1:49:10So this is how I can now ensure that the human types in not an email address,
    • 1:49:14and definitely not their name, but a phone number that at least
    • 1:49:17follows a certain pattern.
    • 1:49:18Maybe it's not very user friendly because do you really want
    • 1:49:21to require the user to type in dashes?
    • 1:49:23Wouldn't it be nice if they can skip those?
    • 1:49:25Maybe they want to use parentheses.
    • 1:49:26So there's better ways arguably still to do this.
    • 1:49:29The point here, though, is that web pages, and other programming languages
    • 1:49:33more broadly, do support these things called regular expressions, which are
    • 1:49:37wonderfully useful in the real world.
    • 1:49:40But there is a danger here.
    • 1:49:42Suppose that, even though this catches invalid phone numbers now-- register,
    • 1:49:47it's telling me to match the requested format.
    • 1:49:49Unfortunately, as great as all these features are-- these patterns
    • 1:49:53are that I just introduced you as web developers now
    • 1:49:56should never trust user's input.
    • 1:49:59Why?
    • 1:49:59The only thing stopping the user from typing in invalid data,
    • 1:50:03like their name instead of their email, or their name instead of a phone number,
    • 1:50:07or something else invalid, is the code that they've
    • 1:50:10downloaded to their browser.
    • 1:50:12But recall that, even though when they View Page Source,
    • 1:50:15they see exactly what came from your website.
    • 1:50:17They can open their own browser's developer tools via Inspect here.
    • 1:50:22They can go to those elements, and for instance,
    • 1:50:24expand the form by clicking this triangle.
    • 1:50:26And if they don't like the pattern you're imposing on them,
    • 1:50:29well, let me just go ahead in there.
    • 1:50:32Delete that.
    • 1:50:33Hit Enter.
    • 1:50:34OK, watch what happens now.
    • 1:50:36I have modified in memory version of the web page.
    • 1:50:40I can click Register now all I want.
    • 1:50:42And I have just submitted D-A-V-I-D instead of a phone number.
    • 1:50:46So this is to say, unfortunately, that to this week
    • 1:50:49alone we do not yet have enough skills or enough knowledge
    • 1:50:52to correctly validate user input.
    • 1:50:54We can make the experience more user-friendly.
    • 1:50:56We can tell them right away in the browser,
    • 1:50:58you're doing something wrong, please don't submit this form yet.
    • 1:51:01But we're also going to need, before long, a server side mechanism
    • 1:51:04for defending against that kind of attack, too.
    • 1:51:08So through phishing, and in this case through modification
    • 1:51:11of the actual DOM in memory, we've seen all too readily
    • 1:51:14how adversaries can try to infiltrate our sites in some way.
    • 1:51:19Now, in addition to the developer tools that come with your own browser,
    • 1:51:22it's worth noting that there is at least one official source via which
    • 1:51:25you can validate your actual HTML.
    • 1:51:28That is to say, make sure that it is well formed,
    • 1:51:31and that it actually adheres to the HTML spec.
    • 1:51:33validator.w3.org is a web-based tool that you
    • 1:51:37can use to copy-paste your HTML, even paste the URLs of web pages into.
    • 1:51:41And this is actually a tool that it will provide you with some feedback as to
    • 1:51:44whether or not you've made syntactic errors with your actual code.
    • 1:51:48All right, with that said, let's go ahead and take a five-minute break.
    • 1:51:51And when we come back, we'll introduce stylization of these pages, namely
    • 1:51:54through CSS.
    • 1:51:56All right, we are back.
    • 1:51:58And it's time now to start stylizing these web pages.
    • 1:52:00So that they're not just these boring black and white pages that have
    • 1:52:03structure to them, but really no style.
    • 1:52:06And so for this, what we're going to do is introduce another language
    • 1:52:08called CSS, or Cascading Style Sheets, which is another language,
    • 1:52:13but not a programming language, via which
    • 1:52:15you can specify how certain tags should be appearing on the screen.
    • 1:52:19For instance, we've already seen tags like H1, H2, H3.
    • 1:52:22And I described those as big and bold, and not quite as big and bold,
    • 1:52:25and not quite as big and bold.
    • 1:52:27But what do we mean by bold and big?
    • 1:52:30It would be nice if we could actually use font sizes or pixel sizes.
    • 1:52:34It would be nice if we could introduce colors and other aesthetics.
    • 1:52:36And indeed, CSS allows you to adorn the structure of your page
    • 1:52:40with the last mile of detail, so to speak--
    • 1:52:43the colors, the sizing, the spacing, the positioning, and so much more.
    • 1:52:47Now, in order to do this, we're going to need to introduce one other term of art,
    • 1:52:51namely "properties."
    • 1:52:51And frankly, at this point, we're just coming up
    • 1:52:53with different words for the same ideas in all of these various languages.
    • 1:52:57But properties are sets of, not surprisingly, key value pairs.
    • 1:53:02A property allows you to specify the color of something is this value,
    • 1:53:06or the margin for this something is this value, or the height of something
    • 1:53:10is this value.
    • 1:53:11So "properties" is just the term of art used in the CSS world to describe key
    • 1:53:15value pairs, just like "attributes" is the word used in the world of HTML
    • 1:53:19to describe their key value pairs-- same idea for as far back as the dictionaries
    • 1:53:26with which we introduced this here topic.
    • 1:53:28Now, where can you go about using properties?
    • 1:53:31And how can you go about using them?
    • 1:53:32Well, it turns out there's going to be different ways of applying properties
    • 1:53:36to elements inside of a web page.
    • 1:53:38And you're going to have to specify, as the developer,
    • 1:53:40how to select those there elements.
    • 1:53:42And with the wave of a hand, let me describe there
    • 1:53:44as being type selectors, class selectors, ID selectors, and attribute
    • 1:53:48selectors, some of which we will see over time.
    • 1:53:50And all this means is that we're going to use slightly different syntax when
    • 1:53:53we want to refer to different parts of a web page.
    • 1:53:56To do that, though, we're going to need to tell the browser that we
    • 1:53:59want to include some CSS in our page.
    • 1:54:02So here again is that sample HTML that represents really
    • 1:54:05the simplest canonical web page that we can create.
    • 1:54:08This one is just saying "hello, title" and "hello, body."
    • 1:54:11And if we make room in the head now, it turns out
    • 1:54:14that there can be more than just a title inside of the head of a web page.
    • 1:54:18In particular, you can have a tag called style,
    • 1:54:22which is wonderfully named, because inside of that tag,
    • 1:54:25you can put some of those CSS properties,
    • 1:54:27key value pairs targeting specific elements inside of a web page.
    • 1:54:33Alternatively, we're going to see that, instead of using a style tag,
    • 1:54:36you can actually use another tag up here,
    • 1:54:39namely a link tag, which unfortunately is poorly named,
    • 1:54:42insofar as it doesn't refer to a hyperlink in the way
    • 1:54:46that the anchor tag and the href attribute
    • 1:54:49does that we described earlier.
    • 1:54:51This one allows you to link in the contents of a .css file which contains
    • 1:54:55all of those same properties, the key value pairs.
    • 1:54:57But instead of typing them out in your actual web page,
    • 1:55:00you can actually put them in a separate file and include them more readily.
    • 1:55:05But it turns out there's yet another way to stylize web pages,
    • 1:55:09and that's with style attributes.
    • 1:55:10And we'll begin our story there, if only because it's the simplest way to begin.
    • 1:55:13But then, as we often do, we'll try to improve, improve, improve
    • 1:55:16the design thereof.
    • 1:55:18So let me go back to VS Code here.
    • 1:55:20Let me create a new file called home.html.
    • 1:55:23And pretend like we're creating a home page for someone,
    • 1:55:26like John Harvard here on campus.
    • 1:55:28Let me go ahead and save a few keystrokes, as often,
    • 1:55:30by copying and pasting my "hello, world" code into home.html.
    • 1:55:34I'll change the title of the page.
    • 1:55:36I'll get rid of "hello, body."
    • 1:55:37And I'll hide my terminal window so we can now
    • 1:55:39build a home page for John Harvard.
    • 1:55:41Let me imagine this home page as having three big sections,
    • 1:55:44like a sort of header for the page with John's name,
    • 1:55:47maybe a middle of the page that just welcomes people to his web page,
    • 1:55:50and then a footer with copyright information or things like that.
    • 1:55:54Pretty common format for a web page--
    • 1:55:55something up here, something down here, something down here.
    • 1:55:58We just need a generic structure with which to play with some HTML, and then
    • 1:56:03some CSS.
    • 1:56:04So let me do this.
    • 1:56:05Let me create a paragraph tag at the top of the page that
    • 1:56:08just has John Harvard's name.
    • 1:56:09Let me create a second paragraph below that says, "Welcome to my home page!"
    • 1:56:16And then below that, let me have a footer of sorts that's just "Copyright
    • 1:56:20John Harvard" in this way.
    • 1:56:23Now let's go about improving this in a few ways.
    • 1:56:26Well, one, this is a very quick and dirty copyright symbol.
    • 1:56:29It turns out, as an aside, that there's other ways
    • 1:56:31to express characters in HTML, one of which
    • 1:56:34is through what are called HTML entities.
    • 1:56:36Because it turns out, for some symbols that
    • 1:56:38aren't easily typed on your keyboard, you
    • 1:56:41can actually use some special syntax.
    • 1:56:43# And I'm going to use this-- & # 169 semicolon.
    • 1:56:50And here, VS Code is actually colorizing it
    • 1:56:53so I can see what's going on differently.
    • 1:56:55This is an HTML entity using code number 169, which
    • 1:56:59if you look it up in a book or a manual online,
    • 1:57:02you'll see that this means an actual copyright symbol, so a little C
    • 1:57:06with a circle around it.
    • 1:57:07It's useful and commonly used here in the US.
    • 1:57:09It's not as easy to type on the keyboard.
    • 1:57:11You could alternatively go Google it, highlight, copy it elsewhere,
    • 1:57:14and paste it in using Unicode.
    • 1:57:16But HTML entities are commonly used still
    • 1:57:18to represent certain symbols like these.
    • 1:57:21Now let's look at what this web page resembles.
    • 1:57:24Let me go back to VS Code in my directory index.
    • 1:57:26Let me click on home.html.
    • 1:57:29And here, we have John Harvard's web page.
    • 1:57:31But notice that there are indeed three paragraphs of text,
    • 1:57:34although it's not really appropriate to call these paragraphs because they're
    • 1:57:37really just different parts of the page or divisions of the page.
    • 1:57:41So we'll come back to that.
    • 1:57:42But all of the font sizes are the same.
    • 1:57:44Like, there's no making John Harvard big and bold here.
    • 1:57:47I don't really need to see the copyright as big as it is.
    • 1:57:49So you might want to start stylizing content like this.
    • 1:57:52But we have, with HTML alone, structured this web page.
    • 1:57:56So how can I add some style?
    • 1:57:58Well, first, I'm going to introduce a style
    • 1:58:00attribute before then taking it away.
    • 1:58:02I'm going to go to my paragraphs start tag here.
    • 1:58:05I'm going to add a style attribute.
    • 1:58:07And I'm going to change, for instance, the font size here.
    • 1:58:10So font-size: large, semicolon, close quotes.
    • 1:58:15Then on this tag here, I'm going to add another style attribute equals,
    • 1:58:19quote unquote, "font-size: medium," semi colon, close quote.
    • 1:58:23And then lastly, just to keep this going, style equals, quote unquote,
    • 1:58:26"font-size: small," semi colon, close quote.
    • 1:58:30Now, strictly speaking, I don't need the semicolons in this particular case.
    • 1:58:34I'm doing it just for uniformity, as we'll soon see.
    • 1:58:37But they're back, just as they were back when we introduced SQL
    • 1:58:42in the end of those statements.
    • 1:58:44But here now, I seem to have added some attributes,
    • 1:58:47the style attribute to each of these tags that's stylizing
    • 1:58:50the aesthetics of this here page.
    • 1:58:52So the structure is the same, but now the aesthetics are different.
    • 1:58:56In fact, let me go back to my other tab.
    • 1:58:57Let me reload the page, and I should see now these new styles.
    • 1:59:01And indeed-- it's a little subtle, but the top line is bigger,
    • 1:59:04the middle line is medium, and the bottom line is indeed smaller.
    • 1:59:08Well, it'd be nice to center everything.
    • 1:59:10So what else can we do with this page?
    • 1:59:11Well, let me go back to VS Code here.
    • 1:59:13And let me, after the semicolon, do something like this--
    • 1:59:16text-align: center, semicolon.
    • 1:59:20And just to save some time, let me go ahead and highlight everything
    • 1:59:23I just added, and paste it inside of those same quotes.
    • 1:59:27So now notice I have more properties.
    • 1:59:30And indeed, that's what we're looking at here.
    • 1:59:32This key, font size, has a value of large.
    • 1:59:35The whole thing therefore is a property.
    • 1:59:37And I've used it in three different ways with three different values-- large,
    • 1:59:40medium, and small.
    • 1:59:41This is another property over here-- text-align, whose value is center.
    • 1:59:45And I'm using that again and again and again,
    • 1:59:47separating them both again by semi colons.
    • 1:59:49Let me go back to my page here.
    • 1:59:51And you might imagine, as soon as I click Reload,
    • 1:59:53now everything is nicely centered.
    • 1:59:55So I've taken some baby steps toward improving the aesthetics of this page.
    • 1:59:59But I dare say I haven't really done this in the best way.
    • 2:00:02Let's chip away at this further.
    • 2:00:03So paragraph tags are fine.
    • 2:00:05But semantically, they're really meant to describe paragraphs.
    • 2:00:08And I'm hard-pressed to say that "John Harvard" is a paragraph and "copyright"
    • 2:00:13is a paragraph.
    • 2:00:14But these are different regions or areas of my page.
    • 2:00:18So I think what I'd like to do here is just be semantically
    • 2:00:21a little more appropriate.
    • 2:00:23So I'm going to change my p tag to be a little more generically div tags, which
    • 2:00:27stands for division, which is a generic rectangular region of the page, which
    • 2:00:32in some sense is adding less information.
    • 2:00:34But we're going to improve upon this further.
    • 2:00:36This is a very common way to structure pages.
    • 2:00:38In fact, when we glimpsed Harvard's HTML earlier,
    • 2:00:40there were lots of divs, divs, divs, divs in the page,
    • 2:00:42because someone who designed that page was laying things out
    • 2:00:45in rectangular regions.
    • 2:00:47And even though there's no visible rectangles, that's what's going on here.
    • 2:00:51It's one rectangular region on top of another, three of them in total.
    • 2:00:55But I don't think this is the best design still.
    • 2:00:59Why?
    • 2:01:00Well, let me go back to VS Code here.
    • 2:01:02And even if you're brand new to CSS, let alone HTML as well,
    • 2:01:07you might have noticed that I copied and pasted.
    • 2:01:11And that generally has not been a good practice.
    • 2:01:13It's just that I'm just doing something redundantly.
    • 2:01:16But what if I did this?
    • 2:01:17What if I factored out that redundancy, that commonality, the text-align:
    • 2:01:21center as follows?
    • 2:01:22Let me go ahead and delete it here, let me delete it here,
    • 2:01:26and let me delete it here.
    • 2:01:28And let me propose that all three of these divs
    • 2:01:30actually have a common parent from which they descend, so to speak,
    • 2:01:35namely the body tag.
    • 2:01:36So technically, I could go up here and do a style attribute
    • 2:01:39on the body tag equals, quote unquote, and then put
    • 2:01:42text-align: center, semicolon.
    • 2:01:45And the idea of, again, the document object model with CSS
    • 2:01:49is that text alignment, centering it, will cascade down
    • 2:01:53to the child elements which are div div, div-- three of them in this case,
    • 2:01:56so that all of them are still centered.
    • 2:01:58Let me go back to my other tab here and reload.
    • 2:02:01And even though nothing has changed visually underneath the hood,
    • 2:02:04I have factored out that commonality and applied text-align: center to all three
    • 2:02:08of those same elements.
    • 2:02:10Now, technically there's other ways to do this.
    • 2:02:12If I didn't want to stylize the whole body,
    • 2:02:14especially if this is a bigger page that has other elements inside of it,
    • 2:02:17I could actually introduce a parent of my own.
    • 2:02:20It is perfectly reasonable to create a parent div, which after all is
    • 2:02:23just a generic container there.
    • 2:02:25Let me close it all the way at the bottom here and indent it accordingly.
    • 2:02:29And then let me go ahead and indent all of these three divs inside
    • 2:02:32of that new div to make the point that, if I
    • 2:02:35don't want to apply a style to an entire body of the page, that's fine.
    • 2:02:38I can similarly just do text-align: center right here.
    • 2:02:42And that, too, would achieve the same result. And indeed, in Harvard's page,
    • 2:02:45you might have noticed, there were lots of divs, not only side by side,
    • 2:02:48but nested inside of each other, perhaps it would seem for similar reasons
    • 2:02:52as well.
    • 2:02:53Now, strictly speaking, I don't have to do it this way.
    • 2:02:56Let me go back to the body approach, just to keep it simple.
    • 2:02:59But let me propose that, as useful as these divs are,
    • 2:03:02as these containers, whereby each of them
    • 2:03:04describes a different region of the page,
    • 2:03:07I could probably help the internet, I could help search engines,
    • 2:03:11I could help AI, I could help screen readers, for accessibility's sake,
    • 2:03:14understand a bit more about what I mean for each of these divisions of the page
    • 2:03:18to be.
    • 2:03:19So instead of just generically saying div,
    • 2:03:22what I'm actually going to do instead is use three semantic tags.
    • 2:03:25And by semantic tags, I just mean HTML tags
    • 2:03:28that are not as generic as div or paragraph, or p for short.
    • 2:03:32I'm going to specify that "John Harvard" is actually in the header of this page,
    • 2:03:37and I'm going to close that tag accordingly.
    • 2:03:39That "Welcome to my home page" is in the main part of the page.
    • 2:03:43And I'm going to close that accordingly.
    • 2:03:44And the footer is actually in a tag called footer itself,
    • 2:03:48and I'll close that one as well.
    • 2:03:49Now, these are not tags I'm just making up.
    • 2:03:51These are officially in the HTML specification,
    • 2:03:53but they mean exactly what they say.
    • 2:03:55The header for the page is probably useful.
    • 2:03:57It's informational-- where you are, whose web page this is.
    • 2:04:00But the main part of the page is generally
    • 2:04:02the juicy part that has actual information that isn't
    • 2:04:05just logos and headings like that.
    • 2:04:07The footer, though, typically tends to be less important.
    • 2:04:10It's got useful stuff.
    • 2:04:11But it's probably not as important as the header
    • 2:04:13and/or the main part of the page.
    • 2:04:15So these tags capture those semantics.
    • 2:04:17And the upside is, when Google or Bing show you sample search results,
    • 2:04:21or when ChatGPT or some future technology
    • 2:04:23is learning about what this page is saying,
    • 2:04:26it could logically give a little more weight to the header and the main part,
    • 2:04:30and less weight to the footer.
    • 2:04:31So you don't see excerpts from the footer, which might not generally
    • 2:04:34be nearly as useful.
    • 2:04:36But what else can we do, now that we've introduced these tags?
    • 2:04:40Let's actually take a step toward improving the design of this page too.
    • 2:04:44Generally speaking, it's not the best practice
    • 2:04:46to combine the structure of your page with the aesthetics thereof.
    • 2:04:51In other words, it's not the best idea to combine HTML with CSS
    • 2:04:56all in the same place, because when I glance at this page,
    • 2:04:59it would be nice if my HTML really did just structure the page.
    • 2:05:02And then somewhere else-- maybe in a different file
    • 2:05:04altogether all of aesthetics are.
    • 2:05:06Why?
    • 2:05:07Because this way, maybe I could use different CSS properties for dark mode
    • 2:05:13and for light mode, so that depending on the time of day,
    • 2:05:15the colors of the website might be a little bit different.
    • 2:05:18I could maybe use different style sheets for different devices
    • 2:05:21or different types of browsers or the like.
    • 2:05:23So it would be nice to factor out the stylization from the web page itself.
    • 2:05:28That said, this is a swinging pendulum in industry.
    • 2:05:31There are technologies that actually do combine CSS with HTML, the argument
    • 2:05:36being that the closer they are, the easier it is to maintain the code
    • 2:05:39and understand what is affecting what.
    • 2:05:41So you'll find arguments in both directions
    • 2:05:43when it comes to the separation of HTML and CSS.
    • 2:05:47But let's take a step towards separating them,
    • 2:05:49at least for our desktop and laptop-based purposes here.
    • 2:05:52Let me do this.
    • 2:05:53I'm going to go ahead and delete all of these style attributes, which
    • 2:05:57is unfortunately going to ruin the aesthetics of the site
    • 2:06:00and make it very generic as before.
    • 2:06:02However, I'm going to reintroduce those properties in a different place.
    • 2:06:06As I proposed earlier, we can make room in the head for not just the title,
    • 2:06:10but a proper style tag--
    • 2:06:13so not an attribute, but a tag.
    • 2:06:15And inside of that style element, what I'm going to put
    • 2:06:18is a few different properties.
    • 2:06:19But the way I'm going to do this is by selecting parts of the web page
    • 2:06:23that I want these properties to apply to.
    • 2:06:25So when I said earlier, there's these different selectors in the world of CSS,
    • 2:06:29this is a fancy way of saying there's different syntax you
    • 2:06:32can use to apply automatically certain properties to certain tags
    • 2:06:37or certain types of tags.
    • 2:06:39So let me go back to VS Code here.
    • 2:06:41And what I'm going to do inside of my style element is this.
    • 2:06:45I'm going to specify that any tag called body,
    • 2:06:48which happens to be one and only one, should have all of its text-align
    • 2:06:53in the center, semicolon.
    • 2:06:55Unfortunately, curly braces are back when using CSS in this way,
    • 2:06:59not unlike C. But again, we're not programming.
    • 2:07:01We're really just defining key value pairs.
    • 2:07:04Any tag called header, I want to have some slightly different properties--
    • 2:07:08font-size: large.
    • 2:07:11Any tag that's called main, I want to have font-size: medium.
    • 2:07:16And then any tag that's called footer, I want to have font-size: small.
    • 2:07:22Now, even though this is taking up way more lines of code,
    • 2:07:26it is a step toward keeping my styles separate from the content of the page.
    • 2:07:31And eventually, if you are on the same page as me
    • 2:07:34here where this might be leading, we can probably
    • 2:07:36copy and paste all of those styles into a separate file.
    • 2:07:40Then two people can work on the same website at once.
    • 2:07:43One person can do structure.
    • 2:07:44One person can do style.
    • 2:07:45We can do the whole light mode, dark mode
    • 2:07:47thing by having different files for different times of day.
    • 2:07:49It feels like a design opportunity.
    • 2:07:52And all we've done, though, is select tags by way of their names
    • 2:07:56here in this particular case.
    • 2:07:58If I again go back to my other tab and reload the page,
    • 2:08:01it's actually not going to look any different.
    • 2:08:03But underneath the hood, it's indeed been structured and styled
    • 2:08:07slightly differently.
    • 2:08:09And here's where we have an opportunity to actually reintroduce those developer
    • 2:08:12tools for yet another reason.
    • 2:08:14Let me right-click or Control-click on the page.
    • 2:08:16Let me click Inspect.
    • 2:08:17And as before, you can see all of your HTML at left under elements.
    • 2:08:21But notice at right, all this time, even though I didn't mention it before,
    • 2:08:24you can also see styles for things as well.
    • 2:08:27So for instance, if I click on the body, watch what happens at right.
    • 2:08:31I will then see a summary from my browser of all of the CSS properties
    • 2:08:38that are being applied to the body of the page.
    • 2:08:40One of them is apparently text align center.
    • 2:08:43And then there's two others, even though I didn't type these
    • 2:08:45out-- display: block, margin: 8 pixels.
    • 2:08:50And that's the user agent stylesheet.
    • 2:08:51Long story short, there are certain default properties
    • 2:08:54that browsers have, be it Chrome or Edge or Safari or Firefox or the like.
    • 2:08:58And what I'm seeing in italics there for the body
    • 2:09:00are some of the default stylizations.
    • 2:09:02And this is why, therefore, some browsers will render the exact same HTML
    • 2:09:07slightly differently, unless you try to standardize it somehow
    • 2:09:10with your own CSS.
    • 2:09:12But what's nice about Chrome's developer tools, and any of these browsers
    • 2:09:16is here too, instead of going back and forth
    • 2:09:18and back and forth between VS Code and my browser tab,
    • 2:09:21and reloading each time I want to see a change,
    • 2:09:23I can change things in real time-- not permanently,
    • 2:09:26but in the browser's memory.
    • 2:09:27So if I'm just curious, and I want to see what this text would look like when
    • 2:09:31aligned to the left, I can type in "left."
    • 2:09:33And notice, it immediately jumps there.
    • 2:09:35If I delete that altogether, notice that Chrome actually
    • 2:09:38shows me a dropdown menu, a la autocomplete,
    • 2:09:41of all of the possible valid values for the CSS property.
    • 2:09:44So it's a great learning technique too.
    • 2:09:46I don't have to constantly look things up or watch a video online.
    • 2:09:49I can let the browser tell me what are the possible values, if I'm learning
    • 2:09:52or I just forget, I can possibly type there.
    • 2:09:55I can go ahead and undo that, go back to having things centered.
    • 2:09:59But I can actually play around a bit further here.
    • 2:10:02Suppose I want to change the font sizes.
    • 2:10:04Well, let me go down to header here and.
    • 2:10:05And notice what we meant was font-size: large for header.
    • 2:10:08Well, honestly, reasonable people are going
    • 2:10:10to disagree what small, medium, and large mean-- certainly
    • 2:10:13across Google and Microsoft and Apple and other companies.
    • 2:10:16So what does large actually mean?
    • 2:10:17Well, I could be more specific.
    • 2:10:19If I really want this to mean something, I
    • 2:10:21can say something like 18 point, with which you
    • 2:10:23might be familiar in the desktop publishing world.
    • 2:10:26I can change this to maybe 24 point to make it even bigger.
    • 2:10:29Or I can even deal in pixels.
    • 2:10:30I can say something like 36px for pixels.
    • 2:10:33And I can get really crazy, like 360.
    • 2:10:36And you see that now, it doesn't even fit on the screen.
    • 2:10:38But look how nice it looks because it's being dynamically sized.
    • 2:10:41So I can just play around with these various styles in the inspector itself.
    • 2:10:46So in short, within Google's developer tools--
    • 2:10:48and again, almost every browser has this nowadays,
    • 2:10:51the Network tab showed us the underlying HTTP stuff.
    • 2:10:55The Elements tab shows us the underlying HTML.
    • 2:10:58And now the Styles tab shows us the underlying CSS.
    • 2:11:01And there's so much more, but so wonderfully useful
    • 2:11:04when trying to modify or learn this here stuff.
    • 2:11:08Let me go back now to VS Code.
    • 2:11:10And let me propose to introduce another way of selecting elements.
    • 2:11:13Previously, I mentioned there was this whole list.
    • 2:11:15And what we've just done is select things by way of their type.
    • 2:11:18The type of the tag was body or header or main or footer.
    • 2:11:23But there's these things called classes in CSS too.
    • 2:11:25It's not really the same thing as classes in Python or Java
    • 2:11:28or other languages, if you're familiar.
    • 2:11:30But classes in CSS are our own keywords that we can invent, and associate
    • 2:11:36our own properties with those keywords.
    • 2:11:38So for instance, if I wanted to reuse styles,
    • 2:11:41like text-align: center and font-size: large and font-size: medium and small,
    • 2:11:45I don't have to associate them with specific tags.
    • 2:11:48I can create my own nicknames for these, if you will.
    • 2:11:52Let me say that any time I want to center something, no matter what
    • 2:11:56tag it is, I'm going to use a class called centered.
    • 2:12:00Any time I want to make something large, I'm going to use a class called large.
    • 2:12:04Any time medium, I'm going to make a class called medium.
    • 2:12:08And any time small, I'm going to make a class called small.
    • 2:12:11Now, why the dots?
    • 2:12:12The humans who invented CSS needed to come up
    • 2:12:14with some way to distinguish the types of tags or the names of tags
    • 2:12:19from classes.
    • 2:12:20And so you simply use a dot to indicate, hey, browser,
    • 2:12:23here comes a class whose name I'm making up on my own.
    • 2:12:27So anything with a dot represents the start of a class name.
    • 2:12:31How do I use these?
    • 2:12:32Well, let me scroll down to the bottom of the page.
    • 2:12:34And now there's no association yet with any of those class names with this HTML.
    • 2:12:40But what I can introduce now is a class attribute where I can specify, OK,
    • 2:12:46I want "John Harvard" to be large.
    • 2:12:48And I want the main part of my page to be medium.
    • 2:12:52And I want the footer of my page to be small.
    • 2:12:57And by the way, I want all of this to be centered.
    • 2:13:01So you can create these reusable words, and you
    • 2:13:04can invent the word subject to a few constraints on what characters
    • 2:13:07you can use.
    • 2:13:07But now you have a set of classes, so to speak,
    • 2:13:10that you can use on these tags, and maybe bunches of others.
    • 2:13:13They're not that useful at the moment because this web page
    • 2:13:15is so darn simplistic.
    • 2:13:17But you could certainly imagine, in Harvard's web page, in Yale's web page,
    • 2:13:20in Google's web page, where they have so many darn tags,
    • 2:13:22it might be very useful to use these classes,
    • 2:13:25and reuse them so you don't have to copy and paste any of that text
    • 2:13:29as we saw before.
    • 2:13:30And in fact, let's take this one step further.
    • 2:13:32It's a little silly that I keep scrolling up and down.
    • 2:13:35Let's just move all of this CSS to its own file.
    • 2:13:37So let me highlight that and cut it.
    • 2:13:39Let me get rid of my style tags altogether.
    • 2:13:43Let me create from my terminal window a file
    • 2:13:45called styles.css, though I could call it anything I want.
    • 2:13:49Let me paste those lines in there.
    • 2:13:51And VS Code nicely left aligned everything for me.
    • 2:13:54That's it, out of sight, out of mind.
    • 2:13:55Let me close that file.
    • 2:13:56And then inside of the head of this page, instead of a style tag,
    • 2:14:00let me do in link href equals styles.css.
    • 2:14:05And the rel tag for the relationship here is that of stylesheet.
    • 2:14:10It's generally the only one you'll use, and this
    • 2:14:12is the kind of thing you might have to look up or copy-paste.
    • 2:14:14But href refers to the file that you want
    • 2:14:17to link in-- essentially copy-paste, but automatically,
    • 2:14:20like an include in C or an import in Python.
    • 2:14:23And the relationship of that file to this one
    • 2:14:25is that of what's called a style sheet, a sheet or a page of properties.
    • 2:14:31So let's now perhaps use these techniques
    • 2:14:36to make things that are a little prettier now and a little more
    • 2:14:39visually interesting.
    • 2:14:41Let me go ahead and do this.
    • 2:14:42Let me close out this home page here.
    • 2:14:44Let me go ahead and open up our old file called
    • 2:14:47link.html, which previously looked like this when we left it at Yale.
    • 2:14:51Let's actually undo that phishing attack and change it back to harvard.edu
    • 2:14:55for consistency with before.
    • 2:14:56And let's try to bring this link to life in a slightly different, more colorful
    • 2:15:01way.
    • 2:15:01If I open this page, recall we did see the link if.
    • 2:15:04I close my developer tools, go back to link.html.
    • 2:15:08Notice it was underlined by default, which
    • 2:15:09is great, because it made it very visually clear that it
    • 2:15:12is a link, and not just text.
    • 2:15:13And it was purple, which is the default color in most browsers
    • 2:15:16to indicate, yes, it's a link, but it's one you've already visited.
    • 2:15:19So purple means you've visited it before.
    • 2:15:22And blue typically means it's a link, but you have not visited it before.
    • 2:15:27So that's a default. But suppose I want to override that and make
    • 2:15:30things more crimson or red in nature.
    • 2:15:32Well, let me go back to VS Code here.
    • 2:15:35And in VS Code, let me go ahead and, just for the sake of discussion,
    • 2:15:39let me take one step backward, just because it's easier and more efficient
    • 2:15:43during class, to reintroduce our style tag.
    • 2:15:45But if you're convinced, you could, and probably should,
    • 2:15:48move this stuff to a separate file.
    • 2:15:50That's indeed the best practice.
    • 2:15:51But I'm going to keep it simple in this same file.
    • 2:15:54Let's go ahead and start to stylize this anchor tag
    • 2:15:57as follows My anchor tag, abbreviated a, is
    • 2:16:00going to have the following property associated with it, a color of--
    • 2:16:04how about red, semicolon.
    • 2:16:07And now let me go back to the tag here.
    • 2:16:10Reload the page.
    • 2:16:12And indeed it's now red and underlined here.
    • 2:16:15If you want to get rid of the underlying, you can.
    • 2:16:17I could additionally, inside of these curly braces,
    • 2:16:20say text-decoration, which is another property we haven't yet seen,
    • 2:16:24whose value is now going to be none.
    • 2:16:26If I go back to my Browser tab, reload the page,
    • 2:16:29it's still red but not underlined.
    • 2:16:31And that's fine, and that's pretty common nowadays.
    • 2:16:33But here too, for accessibility sake, you should be mindful of the fact
    • 2:16:37that, depending on the quality of someone's vision,
    • 2:16:39they might not be able to distinguish red from black or red
    • 2:16:42from some other color.
    • 2:16:43So in terms of accessibility, you should make
    • 2:16:45sure that if you're removing telltale signs of links like underlines,
    • 2:16:49make sure they're sufficient contrast between the colors
    • 2:16:51that you're indeed using.
    • 2:16:53So, in fact, let me go ahead and leave that alone for now.
    • 2:16:56But let me propose that I'd like to at least show,
    • 2:16:59when a user on a laptop or desktop hovers over the link,
    • 2:17:02let me at least underline it then.
    • 2:17:04This is less useful on mobile, because on mobile, you don't really
    • 2:17:06hover as much as you do tap or not tap.
    • 2:17:09But just so you could see how in CSS this is done, I can do this too.
    • 2:17:14I can have a selector that says a:hover, which is a special keyword that
    • 2:17:19the browser knows about, which means when I'm hovering over with my cursor
    • 2:17:23an anchor tag, change the text decoration temporarily to actually being
    • 2:17:28underlined.
    • 2:17:29And if I go back to my browser tab, reload,
    • 2:17:32notice that I get now some interactive behavior.
    • 2:17:34Any time I hover, you can see the line appearing.
    • 2:17:37For better or for worse, this is how you can implement a bit more dynamism
    • 2:17:41then with your here content.
    • 2:17:43And the fact that it's an anchor tag means
    • 2:17:45that it's going to apply to any of the anchors, any
    • 2:17:48of the links in this here page.
    • 2:17:49If I don't want that to be the case, let me propose this.
    • 2:17:52Let me propose that, instead of doing this,
    • 2:17:55I want to define some properties as follows.
    • 2:17:59Let's go ahead and undo this.
    • 2:18:01And in this page, let's suppose that we have a visit to Harvard or a visit
    • 2:18:06to href equals https://www.yale.edu, close bracket, Yale.
    • 2:18:14So the page is a little longer now, but the sentence now reads.
    • 2:18:17"Visit Harvard or Yale," with two different links.
    • 2:18:20How can I now stylize these a bit differently?
    • 2:18:22Well, let me go ahead and do this.
    • 2:18:24Inside of my style attribute, let me specify
    • 2:18:27that I want the Harvard link to be red.
    • 2:18:31How do I do that?
    • 2:18:34I'm actually not sure I can just yet.
    • 2:18:36But what if I do this?
    • 2:18:37If I know I want to stylize this tag, let me actually
    • 2:18:39give it a unique identifier.
    • 2:18:41There's different ways to do this, but perhaps the most deliberate
    • 2:18:44would be to give this anchor tag a unique identifier called Harvard,
    • 2:18:50or whatever you might want to call it.
    • 2:18:52And let's do the same over here.
    • 2:18:53Let's add an ID to the second anchor tag that calls this tag Yale.
    • 2:18:58And I'm using lowercase by convention.
    • 2:19:00What this allows me to use is yet another type of CSS
    • 2:19:03selector-- not type or name, not class, but ID.
    • 2:19:08I can create a unique identifier that allows
    • 2:19:10me to say target the Harvard element.
    • 2:19:14How do I express that?
    • 2:19:15Well, instead of using a dot, I actually use a hash symbol here.
    • 2:19:18And I say #harvard.
    • 2:19:20And then inside of those curly braces, I can say color red.
    • 2:19:23And I can do #yale.
    • 2:19:25And then inside of those curly braces, I can say color blue.
    • 2:19:28And actually, just to bring back memories, for better or for worse,
    • 2:19:31of hexadecimal notation and Photoshop, as we discussed
    • 2:19:35when we discussed multimedia and representation thereof,
    • 2:19:37I can actually use hexadecimal codes.
    • 2:19:40So instead of saying red or blue or any other color,
    • 2:19:43I could say hash symbol here unrelated to the hash symbol
    • 2:19:47next to the class name.
    • 2:19:49Now we are combining color codes with CSS.
    • 2:19:52I can do this--
    • 2:19:53FF0000, which is a lot of red, no green, no blue.
    • 2:19:59Down here, I can say hash symbol, no red, no green, lots of blue.
    • 2:20:06And those represent essentially the same colors.
    • 2:20:09Down here, I still want to do--
    • 2:20:11I'm going to not bother actually with the text decoration anymore.
    • 2:20:14Let me go back to my page here.
    • 2:20:15Let me reload.
    • 2:20:17And now it's getting a little prettier-- a red Harvard,
    • 2:20:20a blue Yale with those two links targeted specifically.
    • 2:20:24Now, there's yet other ways too.
    • 2:20:26A third way would be to target a element based
    • 2:20:29on the value or presence of one of its attributes, a.k.a., an attribute
    • 2:20:33selector.
    • 2:20:33But I'll wave my hand at that, since surely, you'll
    • 2:20:35see eventually in documentation elsewhere,
    • 2:20:37if you go down this road with web design,
    • 2:20:39how you might target those as well.
    • 2:20:42But we don't have to do even these selectors.
    • 2:20:44IDs are meant to be unique.
    • 2:20:46So maybe it would be better to say anytime
    • 2:20:48I have something related to Harvard, let's use a class called Harvard.
    • 2:20:51Any time I have something Yale-related, let's use a class called Yale.
    • 2:20:55So here then, instead of saying ID, I can
    • 2:20:58say class equals Harvard and class equals Yale.
    • 2:21:02And now, even though it's not relevant for this simple example,
    • 2:21:05I can use that class on a different element again and again.
    • 2:21:10An ID is meant to be unique.
    • 2:21:12And it is a mistake on your part or my part if you use it in multiple places.
    • 2:21:18All right, so much like with HTML, which really
    • 2:21:21only had tags and attributes as its basic, similarly as CSS,
    • 2:21:25relatively simple in design with just these properties.
    • 2:21:27And it too has a much larger vocabulary of things and features
    • 2:21:31that you can use throughout your web page.
    • 2:21:33But we'll wave our hand at that, so that you pick up that vocabulary over time
    • 2:21:36via online references or the like.
    • 2:21:38But for now, let's just focus on how you can really
    • 2:21:41leverage CSS to take up a notch the aesthetics of your page,
    • 2:21:45and make things much prettier than I myself have been doing thus far.
    • 2:21:48Let me go back to VS Code.
    • 2:21:49And let me copy from the code I brought with me today,
    • 2:21:53phone book example, that gives us the simple form of a phone
    • 2:21:58book with three people.
    • 2:21:59Let me go ahead and open this file, as it's already been made.
    • 2:22:02And in this file here, after I close my terminal window, is this--
    • 2:22:05a phone book that is apparently made up of an HTML table.
    • 2:22:09Inside of that table is a couple of new tags
    • 2:22:11that I'm introducing for formality's sake here.
    • 2:22:14One is called thead for table head, inside
    • 2:22:17of which is the heading of the table with a table row,
    • 2:22:20tr, with two th tags-- table heading for short.
    • 2:22:24Long story short-- even though the table I made earlier
    • 2:22:26to mock up the visual of a phone keypad is perfectly correct structurally,
    • 2:22:31it turns out if you want to distinguish the header of your HTML table
    • 2:22:34from the rest of your HTML table, you can do so
    • 2:22:38by introducing thead up here and tbody down here.
    • 2:22:42So implicitly, what I was doing earlier was treating everything as the table
    • 2:22:45body with no fancy header up top.
    • 2:22:47But what is different here is that, by using th for the table heading here
    • 2:22:52instead of td, it's a clue to the browser
    • 2:22:54that this actually has some semantic meaning.
    • 2:22:56This is the heading of the table.
    • 2:22:58And maybe it, for instance, should be boldfaced by default.
    • 2:23:00But we've seen already, we can start to override that.
    • 2:23:03As for the body of this table, it seems like it's
    • 2:23:05a phone book with three people--
    • 2:23:06Yulia, David, and John with our now familiar numbers,
    • 2:23:09each implemented in a table row.
    • 2:23:12If I go back over to my directory index and reload, I'll now see phonebook.html.
    • 2:23:16And even though the data is there, honestly, it's
    • 2:23:18not particularly if you will.
    • 2:23:21In other words, within this file here, I've
    • 2:23:23got all of the data I care about, but certainly no CSS.
    • 2:23:26And while I could go in and start using some selectors
    • 2:23:29and adding some CSS, some key value pairs for properties
    • 2:23:32to make this prettier-- maybe with some borders and the like,
    • 2:23:36I bet I can do better by standing on the shoulders of someone else who's made
    • 2:23:39a third-party library, who's thought about what would be the prettiest way
    • 2:23:42to display an HTML table.
    • 2:23:44And this gives us an opportunity to discuss
    • 2:23:47what are called frameworks in the world of web development in particular.
    • 2:23:50A framework is really a library, written by some third party, that
    • 2:23:53just makes it easier to frame your own project, to structure your own project,
    • 2:23:59so that you don't have to implement a lot of basics, particularly aesthetic,
    • 2:24:03that so many other people have had to deal with as well.
    • 2:24:06Better to focus on the problem you actually care about,
    • 2:24:09the business you're building, the product you're creating,
    • 2:24:11rather than worry too much about the aesthetics thereof.
    • 2:24:14And among the more popular frameworks in the world of HTML and CSS
    • 2:24:18is something called bootstrap, which is a library that anyone
    • 2:24:21can use and incorporate into their websites,
    • 2:24:23really by just including one or more HTML tags.
    • 2:24:26And suddenly, everything would seem to look prettier.
    • 2:24:30And in fact, let me go ahead and do this.
    • 2:24:31Let me copy an example I brought with me as well--
    • 2:24:34this one, a second phone book example.
    • 2:24:36If we open this new and improved version of phonebook.html, notice a few things.
    • 2:24:41In the head of my page, I've included a link tag this time.
    • 2:24:44But it's not referring to a file of my own, like styles.css from before.
    • 2:24:49But rather, it's referring to an absolute URL
    • 2:24:51that ultimately, per the end of this URL, points to a file
    • 2:24:54somewhere in the cloud called bootstrap.min.css, where min is just
    • 2:24:59saying that this is a minified file, which means a lot of the whitespace
    • 2:25:02has been deleted from it, just to shrink the file's ultimate size.
    • 2:25:04But it is, in fact, a CSS file.
    • 2:25:07Meanwhile, lower down in this file, if I close my terminal window here,
    • 2:25:10we'll see in the table tag that I've used a class
    • 2:25:14attribute, the value of which is table.
    • 2:25:17Why is this?
    • 2:25:17Well, according to Bootstrap's own documentation,
    • 2:25:19they just told me, if I want to use their stylization, their stylesheet,
    • 2:25:23be sure to add a class of table to your own HTML table,
    • 2:25:27so that they don't presume to change the aesthetics of all of your tables--
    • 2:25:30just the one to which you've added this class.
    • 2:25:32Meanwhile, the documentation also advised
    • 2:25:34me to add scope equals column and scope equals column to two of these table
    • 2:25:38headings up here.
    • 2:25:39But otherwise, the data itself is exactly the same.
    • 2:25:43So let me go back to my browser tab here,
    • 2:25:46which previously looked like this with no CSS whatsoever.
    • 2:25:49And honestly, even if I'd added my own CSS,
    • 2:25:51you'd have probably been underwhelmed as to how pretty
    • 2:25:53my own pages look, and probably would not have looked much better.
    • 2:25:56But simply by including Bootstrap CSS file
    • 2:26:00and adding those attributes that I pointed out,
    • 2:26:04notice what happens when I now click Reload on this newly stylized phone
    • 2:26:08book.
    • 2:26:09Suddenly, it looks much better.
    • 2:26:11Still black and white, so if you were expecting even fancier,
    • 2:26:14you're not going to get it.
    • 2:26:15It's still black and white.
    • 2:26:16But notice, the font is no longer the default. It's no longer some serif font,
    • 2:26:20but it's some sans serif font with less decoration.
    • 2:26:23Notice that Name and Number have been automatically boldfaced.
    • 2:26:26Notice that clearly, there's more padding
    • 2:26:28or spacing among all of these values.
    • 2:26:30So arguably it's easier to read.
    • 2:26:31Notice that there's the gray line separating each of the rows
    • 2:26:34from each other.
    • 2:26:35And long story short, it's just prettier.
    • 2:26:38It's nicer to look at.
    • 2:26:39But you and I don't have to figure out how to adjust the white space,
    • 2:26:43how to adjust the boldfacing, how to adjust the font size, and all of that.
    • 2:26:47The library takes care of that for you.
    • 2:26:49Moreover, there's other features you can include here.
    • 2:26:52If I read the documentation, it turns out
    • 2:26:53that I can also add table-striped to the class attribute.
    • 2:26:58So we haven't seen this yet.
    • 2:27:00But it turns out that the class attribute's value
    • 2:27:02can be one word or two or three, so long as they're separated by spaces.
    • 2:27:07So if I read the documentation, it turns out
    • 2:27:09I can apply two classes to this table, the second one now being table-striped.
    • 2:27:13And watch what happens when I now reload the page.
    • 2:27:15I now see that every other row is very beautifully striped, slightly more
    • 2:27:19usable, slightly prettier to look at, and maybe more helpful
    • 2:27:23than to discern what data is on what row.
    • 2:27:26And let me wave my hands at the rest of this.
    • 2:27:28But suffice it to say that, by way of frameworks like bootstrap,
    • 2:27:31you can actually make your website faster and better and prettier
    • 2:27:36without having to reinvent lots of wheels yourself.
    • 2:27:39That said, if you're particularly artistically inclined
    • 2:27:41and want to fine tune things, you can create some, or even all, of the CSS
    • 2:27:45that you're using.
    • 2:27:46But for more on bootstrap, all of its documentation is at this URL here.
    • 2:27:50And in fact, in many of CS50's own projects do we
    • 2:27:52ourselves use bootstrap and its classes.
    • 2:27:55So we don't have to figure out all of the aesthetics thereof.
    • 2:27:59Now, with all that said, just one language
    • 2:28:01remains, this one a proper programming language, that for better or for worse
    • 2:28:05is going to bring back functions and arguments and loops and conditionals.
    • 2:28:09But before we get there, let's take a five-minute break.
    • 2:28:12And when we return for the final time, we'll dive into JavaScript.
    • 2:28:16All right, we are back.
    • 2:28:18And we now take a look at the third of our three languages today,
    • 2:28:22that of JavaScript, but specifically one that's a programming language.
    • 2:28:25And by programming language, I indeed mean
    • 2:28:27that we'll get functions and arguments and loops and conditionals and more
    • 2:28:31back.
    • 2:28:31But let's take a quick tour through JavaScript, just as we did Python--
    • 2:28:35much more quickly, because what's ultimately important to us today
    • 2:28:38is that you have a sense of what JavaScript can do.
    • 2:28:41But we will really only scratch the surface of this here language.
    • 2:28:44Not only can JavaScript be used in some of the ways we'll see today.
    • 2:28:47But it's also increasingly being used on the server as well
    • 2:28:51to generate entire websites and applications and more.
    • 2:28:53So we'll give you a sense, really, of some
    • 2:28:55of the basic syntax and basic capabilities.
    • 2:28:58But ultimately defer to your future endeavors,
    • 2:29:00your own final project perhaps, to apply JavaScript and explore it all the more.
    • 2:29:05So just as we did earlier, let's consider the simplest of web pages
    • 2:29:09here in HTML alongside its own DOM, or document
    • 2:29:12object model, which represents again how that HTML might be structured
    • 2:29:16in the computer's memory once the page has been downloaded and loaded
    • 2:29:19by the browser.
    • 2:29:21Unfortunately, what you're looking at here is a very static web page one that
    • 2:29:24simply says "hello title" and "hello body."
    • 2:29:26But wouldn't it be nice if that DOM could evolve over time?
    • 2:29:30After all, in C, and then in Python, we experimented
    • 2:29:33with data structures via which we can add and remove data dynamically based
    • 2:29:37on user input and more.
    • 2:29:38In fact, most any web page you've used nowadays
    • 2:29:40has some form of dynamism involved, such that it's rare for it
    • 2:29:43to be a static website.
    • 2:29:45Odds are something is changing.
    • 2:29:46Case in point-- if you open up your Gmail inbox or Outlook inbox,
    • 2:29:50and just sit there staring at it, odds are, for better or for worse, more email
    • 2:29:54will appear.
    • 2:29:55More email will appear.
    • 2:29:57And previously, we described those kinds of inboxes
    • 2:29:59as stacks, which they rather are underneath the hood.
    • 2:30:02But visually, how are those stacks of emails being implemented in HTML?
    • 2:30:07Well, we've seen already that it's probably some form of tabular data--
    • 2:30:10a bunch of tr's, tr's, tr's, one for each email that you might receive.
    • 2:30:15But if it's coming from the server once, how can you possibly get more emails.
    • 2:30:20So long story short, thanks to server-side technologies,
    • 2:30:23Python among them, and client-side languages like JavaScript among them,
    • 2:30:28can you actually, behind the scenes, get more and more data from the server
    • 2:30:33in order to update the web page, and in turn the underlying DOM?
    • 2:30:37So how can we go about doing this.
    • 2:30:38Well, let's see what some of the things are that JavaScript can do.
    • 2:30:41We have conditionals in JavaScript, whereby
    • 2:30:43such as in Scratch, when we had x less than y
    • 2:30:46is a Boolean expression, in JavaScript here at right, that kind of code
    • 2:30:50is now going to look like this.
    • 2:30:52Unfortunately, the parentheses are back.
    • 2:30:54The curly braces are sometimes back.
    • 2:30:56But this is perhaps the simplest way to think
    • 2:30:58about the structure of a JavaScript version of a conditional.
    • 2:31:01It actually looks, at a glance, exactly C.
    • 2:31:04If we consider an if else in Scratch here, right now in JavaScript
    • 2:31:08would be exactly the same, just as we saw, in fact, in C.
    • 2:31:12And similarly, if we have an if else if else
    • 2:31:14if that too might look exactly like this.
    • 2:31:17But unlike Python which rather abbreviated
    • 2:31:20else if in JavaScript and in C, it is else if with a space in-between.
    • 2:31:26All right, what about variables in JavaScript
    • 2:31:28if you actually want to be able to store something in your own variables?
    • 2:31:31Well, in Scratch, recall that we might have
    • 2:31:34set a counter equal to an initial value of 0 like this.
    • 2:31:37In JavaScript, there's a few ways to do it.
    • 2:31:39But the simplest way to describe this is by using a new keyword, "let,"
    • 2:31:42which is like a very polite way of asking the browser to give you
    • 2:31:45a variable.
    • 2:31:46"Let me have a variable called counter and initialize it to a value of 0."
    • 2:31:51Semicolons though, are now back.
    • 2:31:53Now, that's a bit of an overstatement because JavaScript can actually
    • 2:31:56tolerate the absence of semicolons, at least in many cases.
    • 2:32:00However, for consistency, we and I will continue to use them here.
    • 2:32:03How about if you want to increment that counter by a value of 1?
    • 2:32:07Well, in JavaScript, you can do this by setting
    • 2:32:09counter equals to counter plus 1, the equal sign being,
    • 2:32:12of course, our assignment operator from right to left.
    • 2:32:14You could also do counter plus equals 1, just as in C and in Python.
    • 2:32:18And if you like this in C, plus plus and minus minus are now back.
    • 2:32:23So in JavaScript, you can do that to increment
    • 2:32:25or decrement a variable, respectively.
    • 2:32:27What about loops?
    • 2:32:28Well, in Scratch we might have had something like this to repeat
    • 2:32:30three times.
    • 2:32:31In JavaScript, it similarly is going to be very similar to C.
    • 2:32:34But instead of saying something like int for integer in C,
    • 2:32:37we indeed say let in JavaScript to create a variable
    • 2:32:40like i do this say three times while incrementing
    • 2:32:43with plus plus i along the way.
    • 2:32:46What else might we now do?
    • 2:32:47Well, we might have a forever block here in Scratch that
    • 2:32:50does something, of course, forever.
    • 2:32:51In JavaScript, you can also say "while true,"
    • 2:32:55where true is back to being lowercase here.
    • 2:32:58And that will ensure that whatever is between those curly braces
    • 2:33:01will happen again and again.
    • 2:33:02Meanwhile, if we revisit the canonical form of this HTML, where can
    • 2:33:07we actually put JavaScript code?
    • 2:33:09It turns out there's a few different places,
    • 2:33:10and there's a few different reasons to use one place or another.
    • 2:33:13But just so that you see the range of possibilities, especially when you then
    • 2:33:17see suggestions in online documentation for JavaScript libraries,
    • 2:33:20you can put a script tag in the head of your page,
    • 2:33:24just like we put a style tag or a link tag up there, as well as the title.
    • 2:33:28And inside of that can go some raw JavaScript code typed out by you.
    • 2:33:33Of course, I've proposed that it tends not
    • 2:33:35to be ideal to co-mingle one language with another.
    • 2:33:37And so there's other ways to do this too.
    • 2:33:39You can actually have a script tag, this one with a source element
    • 2:33:43that will allow you to specify another file name,
    • 2:33:46or even another URL, from which you want the JavaScript itself to come.
    • 2:33:51What's a little weird, though, about the script tag here,
    • 2:33:54even when used with a source attribute, is that you'll see that I've closed
    • 2:33:58the tag nonetheless with an open bracket /script closed bracket tag at the end
    • 2:34:03of this line to make clear that there's no JavaScript inside of this element.
    • 2:34:09Indeed, it's only coming from that same source.
    • 2:34:12As an aside, you will also see-- and there are also reasons to,
    • 2:34:15sometimes put a script tag in the body of the page that
    • 2:34:19is below most everything else in the page,
    • 2:34:21or a script tag with a file reference therein, even at the bottom of the page,
    • 2:34:26just because order of operations can indeed matter.
    • 2:34:29But these are subtleties that we'll try to avoid for now,
    • 2:34:32simply focusing on really what JavaScript itself can do.
    • 2:34:36And in fact what's perhaps most powerful about JavaScript,
    • 2:34:39and what nicely brings us rather full circle back to where
    • 2:34:42we started the class in Scratch, JavaScript in the context of browsers
    • 2:34:47can be very much event-driven.
    • 2:34:49So just like in Scratch, when we actually had actual events-- and even
    • 2:34:53a block, if you discovered it, called broadcast,
    • 2:34:55where you could have one sprite somehow signal to another.
    • 2:34:59In JavaScript, and specifically in the context of browsers,
    • 2:35:02there's just so many events or things that can happen.
    • 2:35:05For instance, you might change the value of a field in a form.
    • 2:35:08You might give something focus by clicking on a text box.
    • 2:35:11You might drag something from one place to another.
    • 2:35:14You might put your mouse down or mouse over something.
    • 2:35:17On a mobile device, you might put a finger down, thereby
    • 2:35:19touching down on the device.
    • 2:35:21So long story short, all of these keywords that you see here
    • 2:35:24represent events that happen inside of a browser that JavaScript, as a language,
    • 2:35:31can be used to listen for and respond to.
    • 2:35:35And as such, you can use JavaScript to make very interactive and responsive web
    • 2:35:40pages, whether that's to go get more emails from the server,
    • 2:35:43or to grab more of a map if you're clicking and dragging
    • 2:35:46while using Google Maps or the like.
    • 2:35:48So let's begin to scratch the surface today only of what JavaScript can do.
    • 2:35:53Let me go back to VS Code here.
    • 2:35:55Let me create a new file here called hello.html.
    • 2:35:59And in that file, I'm going to go ahead and save a few steps by first copying,
    • 2:36:03as a starting point, some of my earlier code.
    • 2:36:05Let me close my terminal window, change my title as always to just "hello,"
    • 2:36:09and get rid of now that default body.
    • 2:36:11And let's go ahead and whip up a very simple interactive page that just says
    • 2:36:14"hello" to someone more interactively, ideally letting them type in their own
    • 2:36:18name, just as we've done in so many languages prior.
    • 2:36:21Let me go ahead and create a form tag in here.
    • 2:36:24And inside of that form, let's give myself an input.
    • 2:36:27And just to practice what I've been preaching,
    • 2:36:29let's turn autocomplete off as before.
    • 2:36:32Let's turn on autofocus, so I don't have to click in it manually.
    • 2:36:36Let's give this input a unique identifier for reasons that we'll soon
    • 2:36:39see, like "name," although I could call this thing anything I want.
    • 2:36:42But I do want the person's name.
    • 2:36:43Let me use the placeholder text of "name,"
    • 2:36:46so it's clear to the user what I'm prompting them for.
    • 2:36:48And the type of this text box, even though this is the default,
    • 2:36:51shall indeed be text.
    • 2:36:53What else do I want to do?
    • 2:36:54Well, let's keep it simple, and just have an input type
    • 2:36:57equals submit so that I get a button, which you've
    • 2:36:59seen in a couple of different ways.
    • 2:37:01Let me go back to my other tab.
    • 2:37:03Reload the page.
    • 2:37:04And I see now hello.html.
    • 2:37:07Inside of this file, I see a very simple form.
    • 2:37:10If I type in my name, though, and click Submit,
    • 2:37:13notice that my URL has changed if I zoom in up here.
    • 2:37:15And there's indeed a question mark, which
    • 2:37:17suggests that something was submitted from the browser to the server.
    • 2:37:21But there's nothing after that.
    • 2:37:22There's no something equals something.
    • 2:37:24And why is that?
    • 2:37:24Well, even though I gave the text box an ID of name,
    • 2:37:28I didn't give the text field a name itself.
    • 2:37:31In other words, I did not say, if confusingly, name equals, quote unquote,
    • 2:37:35"name," just as I did name equals, quote unquote, "q," or name equals,
    • 2:37:39quote unquote, "email."
    • 2:37:40And that's fine because we've certainly seen inputs before that don't actually
    • 2:37:44send anything to the server.
    • 2:37:45They just result, for instance, in the case of a button,
    • 2:37:48in the form itself being submitted.
    • 2:37:50So this is to say that, if an input in a form does not have a name,
    • 2:37:54it's simply not going to be submitted to the server.
    • 2:37:57But that's OK, because my goal at hand today, at least for this example,
    • 2:38:01is to say "hello" to the user, but not server-side.
    • 2:38:04We don't yet have the means yet until we reintroduce some Python to generate
    • 2:38:09content server-side.
    • 2:38:11I want to do everything client side.
    • 2:38:12And so just to be clear, just as HTML is downloaded from the server
    • 2:38:17to the browser, CSS is downloaded from the server to the browser,
    • 2:38:21JavaScript as we are currently using, it will also be downloaded from the server
    • 2:38:25to the browser, and executed client-side in your own Mac, your PC or your phone.
    • 2:38:31Which is to say that any of the data we get from the server
    • 2:38:34has to come all at the get-go.
    • 2:38:36Until then, it gets executed client-side.
    • 2:38:40So if I want to greet the user, based on what they type in their name
    • 2:38:43as I need my client-side JavaScript code to go grab that name from the form
    • 2:38:48and display it on the screen for me.
    • 2:38:51So how can I do this?
    • 2:38:52Well, it turns out that the form element can take another attribute
    • 2:38:57that we've not yet used that's actually reminiscent of those keywords
    • 2:39:00on this list here.
    • 2:39:02Indeed, notice on this list is a submit event.
    • 2:39:04And indeed in HTML, I can use an onsubmit attribute
    • 2:39:09in my code to do most anything I want.
    • 2:39:12For instance, suppose I want to call a function.
    • 2:39:14I'm going to call a function called greet.
    • 2:39:17However, I don't want this actual form to be submitted.
    • 2:39:20I actually want to return false here as well after a semicolon, just
    • 2:39:24to make clear that what I want this form to do
    • 2:39:26is no longer to submit to the server, but rather greet
    • 2:39:29the user by calling some function called greet, and then return false.
    • 2:39:33And returned false, per the documentation
    • 2:39:35for how browsers and JavaScript works, just means
    • 2:39:37that the form never goes to the server.
    • 2:39:39So how can I go about using this here code?
    • 2:39:45Now, this greet function doesn't actually come with JavaScript.
    • 2:39:48But I can create it myself, just as I could create functions
    • 2:39:50in Scratch, in C, and in Python.
    • 2:39:53In fact, let me go up to the head of the page and keep things simple.
    • 2:39:56Create a script tag in there above my title.
    • 2:39:58And then inside of that script tag, let's go
    • 2:40:01about defining a function in JavaScript.
    • 2:40:03It's a little different from C. It's a little different from Python.
    • 2:40:06But the end result is really the same.
    • 2:40:08In JavaScript, you literally write the keyword "function," which means, hey,
    • 2:40:11browser, here comes the new function.
    • 2:40:13You then give that function a name.
    • 2:40:15I'll call it greet.
    • 2:40:16You then specify in parentheses whether or not
    • 2:40:18that function takes any arguments.
    • 2:40:20And for now I'm going to say no, none.
    • 2:40:22And then inside of curly braces, I can implement the actual function.
    • 2:40:26Well, what do I want to actually greet the user with?
    • 2:40:29Anything for now.
    • 2:40:29Let's keep it simple.
    • 2:40:30Let's actually use JavaScript's built-in function called alert,
    • 2:40:34and just say something like, how about, "hello, world," close quote, semicolon.
    • 2:40:41So the alert function, unlike greet, does come with the language.
    • 2:40:45Here, I'm going to go back to my browser, reload the page,
    • 2:40:49type in D-A-V-I-D. And now I'm going to click Submit.
    • 2:40:51And notice what happens.
    • 2:40:53I now get a fairly ugly pop-up, which is built into the browser itself.
    • 2:40:57But toward the middle of it, it indeed says "hello, world."
    • 2:41:01Now, that has nothing to do with the name I typed in.
    • 2:41:04But we can fix that.
    • 2:41:05Let me click OK.
    • 2:41:06Go back to VS Code.
    • 2:41:07And before I say "hello, world," let's do this.
    • 2:41:11Let's create a variable called name and set it equal to the following function,
    • 2:41:15though it's admittedly a mouthful-- document.querySelector, quote unquote,
    • 2:41:22"#name" .value semicolon.
    • 2:41:26There's a lot to unpack here.
    • 2:41:28So what's going on?
    • 2:41:29Well, recall that from Python, you can chain certain things together.
    • 2:41:33And recall from CN Python, you can use the dot operator
    • 2:41:35to go inside of structures or objects.
    • 2:41:38So that's a lot of what's going on here.
    • 2:41:40So it turns out there's a special global variable when using JavaScript
    • 2:41:43in a browser called "document," which refers to the document itself-- the DOM,
    • 2:41:47if you will.
    • 2:41:48And if you go inside of the document, it comes with a method, a.k.a., function
    • 2:41:53called querySelector-- capital S lowercase q.
    • 2:41:56And what querySelector lets you use, funny enough,
    • 2:42:00is the exact same syntax that CSS uses to select elements.
    • 2:42:04So you can select elements in the page by way of their name or type,
    • 2:42:08like body or header, or main or footer.
    • 2:42:12You can select elements by way of classes or by way of their IDs,
    • 2:42:18or other techniques as well.
    • 2:42:20Now, recall earlier that I did give this HTML input an ID of, quote unquote,
    • 2:42:27"name."
    • 2:42:28And so if I want to refer to that ID, recall from CSS
    • 2:42:31that the symbol is the hash symbol, and then the name of that identifier.
    • 2:42:35So what's happening here is, I'm saying go into the document.
    • 2:42:38Use the query selector method.
    • 2:42:41Look for the element whose unique ID is "name," and please grab its value--
    • 2:42:46that is, whatever the human typed into that input.
    • 2:42:49And store it from right to left in a variable called name.
    • 2:42:53Now all I have to do is include it in my alert to the user.
    • 2:42:56And just as in Python, there's different ways to do this.
    • 2:42:59What I'm going to go ahead and do first is our old friend, the plus operator,
    • 2:43:03after a space inside quotes, and append to or concatenate to hello,
    • 2:43:07comma, space, that person's name.
    • 2:43:09Now notice too, what I've deliberately done here is the following.
    • 2:43:12In the world of C, double quotes are what you use for strings,
    • 2:43:15and single quotes are what you use for characters.
    • 2:43:17In the world of Python, double quotes or single quotes
    • 2:43:20can be used for strings otherwise known as STRS.
    • 2:43:23In JavaScript, the same thing is true.
    • 2:43:25Double quotes or single quotes--
    • 2:43:26I will say conventionally, probably most JavaScript programmers
    • 2:43:30use single quotes, for better or for worse, for strings.
    • 2:43:33So that's the habit I'm going to adopt here,
    • 2:43:34if only to be consistent with that.
    • 2:43:37Let me now go back to my other browser page, reload, type in again my name
    • 2:43:42David.
    • 2:43:42And notice now when I click Submit, ah, now I get, if I zoom in, "hello, David."
    • 2:43:48So I've created a string there dynamically.
    • 2:43:51Notice too, once I dismiss this by clicking OK,
    • 2:43:54if I go back up to the URL bar, notice that I have not actually
    • 2:43:57submitted the form.
    • 2:43:58No question mark, no key value pairs have appeared in the URL.
    • 2:44:02All of this is indeed happening client-side.
    • 2:44:05Now, what more can I do with this?
    • 2:44:08Well, this arguably is not the best design, because as before with CSS,
    • 2:44:11I'm co-mingling one language with another.
    • 2:44:14And I've baked into my HTML some very explicit JavaScript code.
    • 2:44:19Can I get rid of this?
    • 2:44:20Well, I can, in fact, do that in a couple of different ways.
    • 2:44:23Let's go ahead and do this.
    • 2:44:25Let me go ahead and get rid of the onSubmit stuff,
    • 2:44:27leaving therefore just the form and the two inputs inside of it
    • 2:44:31that I had previously.
    • 2:44:33Just to avoid a problem, let me go below this now and add a script tag
    • 2:44:38after getting rid of this one up here.
    • 2:44:41So I'm going to deliberately move everything
    • 2:44:43to the bottom of the page for now, just so that this
    • 2:44:45works without creating a problem.
    • 2:44:47And what am I now going to do?
    • 2:44:48Well, it turns out in JavaScript, you can actually
    • 2:44:51use JavaScript to query the DOM for specific elements.
    • 2:44:55And then listen to events that might happen with those elements.
    • 2:45:01You don't need an onsubmit attribute.
    • 2:45:03You can do all of this in code.
    • 2:45:05So how might I do this.
    • 2:45:06Well, let me do this.
    • 2:45:07Let me create a JavaScript variable called form.
    • 2:45:10Set it equal to document.querySelector.
    • 2:45:13And then let me go ahead and select the one and only form in my page with,
    • 2:45:17quote unquote, "form."
    • 2:45:18I don't need a hash symbol.
    • 2:45:20I don't need a dot because I'm selecting that element by its type or its name,
    • 2:45:25which in this case is "form."
    • 2:45:27All right, what can I now do with this variable.
    • 2:45:29I can now use form., and a new method that we haven't yet seen.
    • 2:45:33It turns out in a web page, once you have a variable or some other value that
    • 2:45:38represents an element on the page, you can
    • 2:45:40call a method called addEventListener.
    • 2:45:43And as the name implies, that allows you, after the page has been created,
    • 2:45:47to start listening for some special event
    • 2:45:50on that element, that event being drawn from a list like this one here,
    • 2:45:54including the Submit event.
    • 2:45:57So how can I do this?
    • 2:45:58Well, this function takes one argument, which is, quote unquote,
    • 2:46:00"the type of event that you want to listen for."
    • 2:46:03And I could listen for any number of things.
    • 2:46:05But the one that's relevant for a text box in this case,
    • 2:46:07or one that's relevant for a form with this text box, is going to be,
    • 2:46:10quote unquote, "submit."
    • 2:46:11And then I can call a function that actually gets
    • 2:46:15called whenever that form is submitted.
    • 2:46:18Now, greet, again, does not yet exist, because I deleted it earlier.
    • 2:46:22But notice what's happening here, which is not
    • 2:46:24something we've done much before, except a little bit in Python.
    • 2:46:27I am calling the form variables addEventListener
    • 2:46:31function, a.k.a., method.
    • 2:46:33I'm telling it to please add an event listener on the Submit event.
    • 2:46:36And whenever that event is fired or triggered,
    • 2:46:40please call this function "greet."
    • 2:46:42So I'm passing in the name of the function.
    • 2:46:44I am not using parentheses after the name of this function,
    • 2:46:47because I don't want to call greet now.
    • 2:46:49I want to register greet as an event listener, so to speak,
    • 2:46:53so it's called later by its name by the browser for me.
    • 2:46:58Now, how can I go about implementing greet?
    • 2:47:00I can do something as before.
    • 2:47:02So above this code, so before I use it, let's say function greet, open paren,
    • 2:47:06close paren.
    • 2:47:07Then inside of this function, let's do something similar to before.
    • 2:47:10# Let name equals document.queryselector, quote unquote, "#name"
    • 2:47:18to get at the element with that unique ID, .value.
    • 2:47:24And below that, let's go ahead and use our alert function, saying again
    • 2:47:27hello, comma, space, plus, to use the concatenation operator,
    • 2:47:31that particular name.
    • 2:47:32Now, there's one other thing I do want to do here,
    • 2:47:35because by default, when forms are submitted,
    • 2:47:37they indeed get submitted to the server.
    • 2:47:40But that's behavior that we wanted to preempt.
    • 2:47:42The way we prevented that last time was by adding return
    • 2:47:45false inside of the event handler.
    • 2:47:48But there's actually a better way to do that.
    • 2:47:49It turns out that when adding an event listener using a function called greet,
    • 2:47:53you're actually going to be passed in an argument, whether you want it
    • 2:47:56or not, that I can refer to as event, or e for short.
    • 2:48:00But I'll be more explicit with "event."
    • 2:48:01And it turns out that argument that gets automatically
    • 2:48:04passed in for you, whenever that event is triggered,
    • 2:48:08allows you to call event.preventdefault, which
    • 2:48:11is a more programmatic, less hackish way than
    • 2:48:13previously, whereby I just returned false.
    • 2:48:16This is literally telling the browser, when you get this event,
    • 2:48:19let me do my own thing by alerting the user "hello so-and-so,"
    • 2:48:24but prevent the default behavior, which we know now to be submitting the form
    • 2:48:28itself.
    • 2:48:29So if I haven't made any mistakes here, and I go back to my browser,
    • 2:48:32reload this page, type in D-A-V-I-D again, and click Submit,
    • 2:48:36there we have it again.
    • 2:48:37The browser has shown me "hello, David."
    • 2:48:41But this is getting a little verbose, honestly.
    • 2:48:42And in fact, there's more JavaScript-like ways
    • 2:48:45to do things like this.
    • 2:48:46And let me propose to do this.
    • 2:48:48Notice that I am, one, using a variable called name here,
    • 2:48:52and then only using it in one place.
    • 2:48:54That's totally fine and very reasonable.
    • 2:48:56But we know from C and Python, that's not strictly necessary.
    • 2:48:59So if you're more comfortable, you can get rid of that whole variable,
    • 2:49:03like such, and then just concatenate to hello, comma, space
    • 2:49:07the return value of that same function.
    • 2:49:10Now, this fits on the screen nicely.
    • 2:49:12It's still pretty readable.
    • 2:49:13I would wager that this is reasonably well-designed, but if this line of code
    • 2:49:17got much longer, we probably do want to go back
    • 2:49:19to the version with an actual variable.
    • 2:49:21But we still want to prevent the default.
    • 2:49:23But what about this line here?
    • 2:49:24Notice that I'm calling a function called greet,
    • 2:49:28even though I'm only doing that once.
    • 2:49:30So we can actually do something in JavaScript
    • 2:49:32that's neat that we can't quite do in the same way in C or in Python,
    • 2:49:37or at least not nearly as elegantly.
    • 2:49:40It turns out that if I'm only using the function "greet" once,
    • 2:49:44I don't really need to give this function a name.
    • 2:49:47In fact, let me just get rid of that there and get rid of this here.
    • 2:49:51And let me propose this.
    • 2:49:52This will look ugly at first.
    • 2:49:54But I'm going to grab this whole function,
    • 2:49:56and I'm going to literally copy and paste it as the second argument
    • 2:50:00to addEventListener.
    • 2:50:01I'm going to go ahead and clean it up a little bit
    • 2:50:03to be a little conventional here.
    • 2:50:05I'm going to move my curly brace to this line.
    • 2:50:07I'm going to get rid of this space.
    • 2:50:08But now this is actually pretty compact.
    • 2:50:10Let me get rid of some of the blank lines.
    • 2:50:12And notice what I'm now doing.
    • 2:50:14I'm still using a variable called form to get the one form in the page.
    • 2:50:18I'm then telling that form to add an event listener for the Submit event.
    • 2:50:21But because I want to tell it what function
    • 2:50:23to call, what you can do in JavaScript, which you can actually do in Python too,
    • 2:50:27is you can pass in an anonymous function, otherwise known
    • 2:50:31as a lambda function, that still might take an argument,
    • 2:50:34but does not need a name.
    • 2:50:35Why?
    • 2:50:35Because if you're using it only one place, why bother even giving it a name?
    • 2:50:41So the only thing I've done is deleted the name "greet"
    • 2:50:43and simply calling it "function," and then passing in and specifying
    • 2:50:47the argument it should take.
    • 2:50:49But the next two lines are exactly the same.
    • 2:50:51And the only thing you have to be careful about
    • 2:50:53is, notice I've got the close curly brace here, and then
    • 2:50:56the close parenthesis, the first of which
    • 2:50:58closes this curly brace, the second of which closes this first parenthesis.
    • 2:51:03And if you really want to tighten things up,
    • 2:51:05we don't really need the form variable.
    • 2:51:07Let me get rid of that line of code and change that variable
    • 2:51:09to be this one-liner.
    • 2:51:11And so even though this is getting a little complicated visually,
    • 2:51:14for those unfamiliar with JavaScript, this
    • 2:51:16is fairly conventional syntax for doing a whole lot of things at once
    • 2:51:20in this particular language without unnecessarily
    • 2:51:23using variables and the like.
    • 2:51:26Now, let me demonstrate that still this here works.
    • 2:51:30If I reload the page and type in my name, David, and submit,
    • 2:51:33we do get that pop-up.
    • 2:51:35But let me do what I did previously, which
    • 2:51:37was to put this whole script tag inside of my head tag at the top of the page.
    • 2:51:42So I'll make room for it up there.
    • 2:51:44Same exact code, but now the script tag is above the form tag.
    • 2:51:48Let me go back to my browser here.
    • 2:51:50Click reload.
    • 2:51:51Type in D-A-V-I-D, and click Submit.
    • 2:51:54And dang it, we're somehow back to the broken version,
    • 2:51:57where still my name-- because I added that name attribute earlier,
    • 2:52:00is getting submitted to the server.
    • 2:52:02But I don't want this getting submitted to the server.
    • 2:52:04What is now going wrong?
    • 2:52:06Well, let's see if we can't diagnose this.
    • 2:52:08Let me go back.
    • 2:52:08Let me right-click or Control-click and inspect,
    • 2:52:11and show you one final tab today, which is that of the JavaScript console.
    • 2:52:15It turns out that in the Console tab of your developer tools,
    • 2:52:19you can see error messages from languages like JavaScript.
    • 2:52:23And if you see anything red, like this, odds are, I'm afraid you messed up.
    • 2:52:28Or in this case, I messed up.
    • 2:52:29And let's see if we can infer what's wrong.
    • 2:52:31"Cannot read properties of null," reading addEventListener.
    • 2:52:35Unfortunately just like Clang, just like Python,
    • 2:52:37the error messages in the computer world are not always that clear,
    • 2:52:40especially for first-time programmers.
    • 2:52:42But it at least seems to relate to line 7, character 43 of hello.html.
    • 2:52:49So let's go back to this line here.
    • 2:52:51Ah, line 7 here is in place.
    • 2:52:53Why might the form be null?
    • 2:52:57Well, notice that this global variable here is referring to the whole document.
    • 2:53:01QuerySelector is selecting some element from that document.
    • 2:53:04But if that element doesn't yet exist, this function
    • 2:53:08call here, which I've highlighted, will return null.
    • 2:53:12So this is like saying null.addEventListener,
    • 2:53:15which just like our time from C makes no sense.
    • 2:53:18You can't dereference null.
    • 2:53:19You can't do anything with null.
    • 2:53:20So something has gone wrong.
    • 2:53:22Now, why is that?
    • 2:53:23Well, much like Python, much like C, these languages
    • 2:53:27are typically read top to bottom, left to right.
    • 2:53:29And unfortunately, if you define the form on line 16,
    • 2:53:33but you try to access the form on line 7, it's just not going to work.
    • 2:53:37And so what you're seeing in JavaScript console here
    • 2:53:40is that it's null because it hasn't yet been read.
    • 2:53:43Now previously, I avoided that problem by moving the whole script
    • 2:53:46tag to the bottom of the page, just avoiding the problem.
    • 2:53:49But there is another way to do it.
    • 2:53:51And you'll see in lots of libraries, even though it's a bit of a mouthful,
    • 2:53:55let me go into hello.html here and add one more event listener,
    • 2:53:58which I'll type out myself--
    • 2:54:00Document.addEventListener.
    • 2:54:03And I'm going to listen for a very special event
    • 2:54:05that you have to capitalize.
    • 2:54:07Just write DOMContentloaded quote unquote.
    • 2:54:11And then I'm going to go ahead and call another anonymous function that
    • 2:54:15simply does all of this stuff together.
    • 2:54:19At the very bottom of what I just added, I'm going to add another--
    • 2:54:22whoops.
    • 2:54:23I'm going to add the close curly brace and another close parentheses
    • 2:54:27to now close this curly brace up here that I just added and this parentheses
    • 2:54:32here that I just added.
    • 2:54:34So this too is more of a mouthful.
    • 2:54:35But what is DOMContentloaded?
    • 2:54:37I mean, it does what it says.
    • 2:54:40When the DOM content, the entirety of it has been loaded,
    • 2:54:44then can you go ahead and execute these lines of code.
    • 2:54:47How do you know what lines of code to execute.
    • 2:54:49Well, here too, I've defined an anonymous function
    • 2:54:51in JavaScript, which just allows me to contain,
    • 2:54:54inside of these curly braces, the lines of code that I want to execute, not now,
    • 2:54:59but eventually, when the DOM's content has loaded.
    • 2:55:03So this is to say that, even in these simplistic examples we've seen already,
    • 2:55:07JavaScript very heavily tends to use these anonymous functions.
    • 2:55:10Or really, people who write JavaScript code
    • 2:55:13tend to heavily use these anonymous functions, if only
    • 2:55:15because it tightens things up.
    • 2:55:17And typically, once you have some experience with programming
    • 2:55:20in this or other languages, you'll get more and more familiar with this,
    • 2:55:23even though at a glance for the first time,
    • 2:55:25this admittedly looks way more complicated than the problem
    • 2:55:29it's actually trying to solve.
    • 2:55:30Now, that said, just like with CSS, we can get rid of all of this stuff.
    • 2:55:34Let me highlight and cut that out.
    • 2:55:36Let me delete all these new lines.
    • 2:55:37Let me go into my script tag.
    • 2:55:39And let me pretend for the moment, with a source attribute,
    • 2:55:42that I have a file called scripts.js.
    • 2:55:44And I could imagine now going into a file called scripts.js,
    • 2:55:48pasting all of the code.
    • 2:55:50I just cut out of this file, and then just
    • 2:55:52like CSS allowing one file to refer to the other.
    • 2:55:57So in other words, you can ultimately go ahead
    • 2:55:59and implement that same paradigm of separating one language from another
    • 2:56:03in JavaScript as well.
    • 2:56:05All right, that was a lot.
    • 2:56:07But let's now focus not so much on writing as much code like this,
    • 2:56:10but looking at some examples that I brought
    • 2:56:12with me to demonstrate what more we can do with JavaScript and my terminal
    • 2:56:15window.
    • 2:56:16Let me go ahead and grab a fifth version of this file from my src8 directory.
    • 2:56:22That's going to look a little something like this.
    • 2:56:26In hello.html now, which I wrote in advance this time,
    • 2:56:30we have some very similar code, such that I'm listening for the DOM content
    • 2:56:34to be loaded.
    • 2:56:35I am defining a variable, in this case called input, because I
    • 2:56:38wanted to find a text box on the page.
    • 2:56:40And I'm using another event listener, and we've
    • 2:56:43seen it on this here list, not just submit, but for instance,
    • 2:56:46key up when the human's finger comes up from the keyboard,
    • 2:56:49just after having typed something.
    • 2:56:51Let's see for the moment, before we dive in further,
    • 2:56:53to how this event is being used, what this page now looks like.
    • 2:56:56If I close my developer tools and reload the page,
    • 2:56:59notice that the Submit button is gone.
    • 2:57:01But I still have a text box.
    • 2:57:03And watch what happens when I start typing, like, the letter C or A or T,
    • 2:57:09or if I delete, delete, delete, W-O-R-L-D, delete, delete, delete,
    • 2:57:13delete.
    • 2:57:14And then there's a default value here as well.
    • 2:57:16So notice now, it's automatically updating the DOM of the page
    • 2:57:20as I'm typing.
    • 2:57:21In fact, let me do this.
    • 2:57:22Let me reopen my developer tools with Inspect.
    • 2:57:25Let me go to the Elements page by default. And notice the p tag here.
    • 2:57:30At the moment, in the browser's memory, is the phrase hello, comma,
    • 2:57:33whoever you are.
    • 2:57:34Let me start to type my own name now, instead of cat or world or anything
    • 2:57:38else, D. And notice that, not only am I seeing "hello, D" on the screen,
    • 2:57:44notice that the DOM, as represented by the Elements tab,
    • 2:57:48has been dynamically updated as well.
    • 2:57:50If I type in now an A, notice what happens in both places too.
    • 2:57:54The DOM gets updated again.
    • 2:57:55V-I-D- notice that, and it's flashing to draw your eye to it,
    • 2:57:59I'm updating the DOM in memory.
    • 2:58:01Meanwhile, if I close this, and open up the page source,
    • 2:58:06recall that this is a static version in here.
    • 2:58:09There is no mention of D-A-V-I-D in the actual HTML.
    • 2:58:12That's coming from me, the user.
    • 2:58:15So if we go back now to VS Code, let's look at how this works.
    • 2:58:18Again, on line 10, I created a variable called
    • 2:58:20input that just uses querySelector to find the input element, the text box.
    • 2:58:25Then I registered an EventListener on that text box for keyup.
    • 2:58:30So this thing responds as soon as the finger comes off the key.
    • 2:58:34I want this function anonymously to be called
    • 2:58:37whenever that key goes up, I, inside of this function,
    • 2:58:41define a variable called name.
    • 2:58:42And I use the querySelector to get another element on the page called p.
    • 2:58:46Well, where did that come from?
    • 2:58:47Well, let me open the page source again.
    • 2:58:49And notice, at the bottom of the page is not
    • 2:58:52only the form, which is super simple-- no submit button even.
    • 2:58:55But there's also an empty paragraph tag that I just put there as a default
    • 2:59:00element to fill with my content.
    • 2:59:02Let me go back to VS Code here.
    • 2:59:04And notice that, once I've got that, I've got room for the person's name.
    • 2:59:09So what I'm going to do is this.
    • 2:59:10If the input has a value, if the text books box has something typed in,
    • 2:59:15I'm going to do this, I'm going to go inside
    • 2:59:17of that name, the so-called paragraph.
    • 2:59:20I'm going to change its inner HTML capitalization
    • 2:59:23is important here-- lowercase inner, all caps HTML.
    • 2:59:27And I'm going to change it to be hello, comma, something.
    • 2:59:30More on that in a moment.
    • 2:59:32Else-- if there is no input value, that is it's blank,
    • 2:59:35so this Boolean expression is false, let's just change the innerHTML to be
    • 2:59:39"hello, whoever you are."
    • 2:59:42That's the default value.
    • 2:59:44The last thing to tease apart then is, what is going on here?
    • 2:59:47This is horrible to look at, I will admit.
    • 2:59:50And it's the ugliest of the syntax we've seen.
    • 2:59:52But just like in Python, we have those format strings, or f strings,
    • 2:59:56where you can put the f, and then quote marks,
    • 2:59:58and then curly braces inside to interpolate the value of some variable.
    • 3:00:02JavaScript has something similar, except it's much more ugly to look at.
    • 3:00:06Specifically, you use backticks, which vary in their location,
    • 3:00:11based on whether you have a US English keyboard or something
    • 3:00:13else-- but a backtick at the beginning and a backtick at the end.
    • 3:00:17And inside of those backticks, if you want
    • 3:00:20to interpolate the value of some variable, you do use curly braces.
    • 3:00:24But you also use dollar sign.
    • 3:00:27So it's like Python syntax, but worse.
    • 3:00:29But it's the exact same idea.
    • 3:00:31There's nothing really complicated beyond that,
    • 3:00:33other than remembering or googling the syntax for that technique.
    • 3:00:37So at the end of the day, the result is that we get this automatically updating
    • 3:00:43page that updates one keystroke at a time, based on what the user typed in,
    • 3:00:47this time based specifically on the keyup event instead of submit.
    • 3:00:53Well, let's do one other.
    • 3:00:54Let me go back to VS Code here.
    • 3:00:56Open up my terminal after closing hello.html.
    • 3:00:59Let me copy from my source directory today something called background.HTML.
    • 3:01:03And now let's go back to my directory listing
    • 3:01:05here, reload, and see background.HTML and click it.
    • 3:01:08This is very simple, but let's see if we can infer how this works.
    • 3:01:13I've got three buttons.
    • 3:01:14And they're not rectangular as much as they are square.
    • 3:01:16But that's just because the labels, G and B, are so short.
    • 3:01:19But watch what happens.
    • 3:01:20R turns my background red.
    • 3:01:22Green turns it green, B turns it blue.
    • 3:01:25Well, how is that happening?
    • 3:01:27Well, let me go back to VS Code here.
    • 3:01:29And let me actually open now this file, background.HTML.
    • 3:01:33And notice what's going on here.
    • 3:01:35Inside of my body, I've got three buttons, each of which has unique ID--
    • 3:01:40red, green, or blue, and each of which has super-short labels--
    • 3:01:43R, G, and B in all caps.
    • 3:01:46But then I have a script tag.
    • 3:01:47Notice first I'm creating a variable called
    • 3:01:49body that's just grabbing the element from the page, the type of which
    • 3:01:54is body.
    • 3:01:54And there's only one of those.
    • 3:01:56And then notice this.
    • 3:01:57I've got three nearly identical lines of code starting here.
    • 3:02:00I'm going into the document using querySelector
    • 3:02:03to find whatever element has a unique ID of red per the hash symbol.
    • 3:02:08On that element, I'm adding an event listener
    • 3:02:11for the click event, which is again on our list of events
    • 3:02:15that you can listen for in JavaScript, in addition to submit
    • 3:02:18and in addition to keyup.
    • 3:02:20Here, then, I'm listening for click.
    • 3:02:22And I'm calling this anonymous function when that button is clicked.
    • 3:02:28And when it is, I execute one line of code.
    • 3:02:31And here is where today comes together full circle.
    • 3:02:35I can, inside of my web page using JavaScript, modify the CSS of my page
    • 3:02:41too.
    • 3:02:42I can go into that body element, access its style attribute, which
    • 3:02:48is a variable inside of the body--
    • 3:02:50and that exists because that's how browsers work.
    • 3:02:53And I can access the backgroundColor property inside of that body tag style.
    • 3:03:00It's like accessing its style attribute, if you will.
    • 3:03:03And I can set it equal to quote unquote, "red."
    • 3:03:05# Or I could do #FF0000, but I kept it simple with, quote unquote, "red."
    • 3:03:10The next three lines of code are the same thing, but for green.
    • 3:03:13The last three lines are the same thing, but for blue.
    • 3:03:16The only thing that's weird here is where did backgroundColor come from,
    • 3:03:19because it's lowercase b and capital C. Unfortunately,
    • 3:03:22this is maybe not the best design historically.
    • 3:03:24In CSS, we saw text-align.
    • 3:03:29We saw color.
    • 3:03:31We saw a couple of other properties as well.
    • 3:03:34Unfortunately, there is, in CSS, a CSS property called background-color.
    • 3:03:39I just didn't happen to use it just yet.
    • 3:03:41Unfortunately, CSS uses background-color.
    • 3:03:45JavaScript necessarily uses backgroundColor with capital C. Why?
    • 3:03:50Well, in JavaScript, you can do math, like in most languages.
    • 3:03:53And unfortunately, the dash is already used as a minus sign.
    • 3:03:56So unfortunately, in JavaScript, if you wrote this property as background-color,
    • 3:04:00this would be like trying to subtract color from background-- so background
    • 3:04:05minus color, which makes no sense.
    • 3:04:07So left hand and right hand weren't really communicating, it seems.
    • 3:04:10So the solution was just to use camel case,
    • 3:04:12so to speak, like a camel with a hump, and capitalize the C,
    • 3:04:15but get rid of the hyphen.
    • 3:04:17And there is a mapping therefore from CSS properties
    • 3:04:20to JavaScript attributes in this way.
    • 3:04:23So that's all that's happening.
    • 3:04:24And in fact, we can see this again in our inspector.
    • 3:04:26Let me reload the page to go back to white.
    • 3:04:28Let me, again, open up the developer tools.
    • 3:04:30Let me click on the body of the page, which currently has no attributes.
    • 3:04:33And at right, there's no styles being applied to it,
    • 3:04:36other than the defaults from the user agent stylesheet.
    • 3:04:39But watch what happens now under element.style and on the body
    • 3:04:43tag itself.
    • 3:04:44When I click R, a style attribute will suddenly
    • 3:04:48appear programmatically on the body tag with a value
    • 3:04:52corresponding to background-color: red.
    • 3:04:57Notice over at right here too, we see a summary in Chrome's developer tools
    • 3:05:00of exactly that.
    • 3:05:01If I click on G, if I click on B, I can see exactly the same thing
    • 3:05:06happening for each of those colors.
    • 3:05:08So here now, we have the ability with JavaScript
    • 3:05:10not only to alter the DOM of the page, the contents of it,
    • 3:05:13what the user is seeing, but also it would seem the CSS thereof.
    • 3:05:17What more can we do?
    • 3:05:18Well, let's look at one other example that evokes a tag from yesteryear.
    • 3:05:22Let me go into my source directory and grab an example called blink.html,
    • 3:05:26and show you in this code here in.
    • 3:05:29If I hide my terminal window, we've got a function
    • 3:05:32in this file inside of my script tag called
    • 3:05:36blink, which apparently toggles visibility of greeting.
    • 3:05:38But what does that mean?
    • 3:05:39Well, let's try to infer here.
    • 3:05:40There's a variable called body, which is set equal to the return
    • 3:05:43value of querySelector.
    • 3:05:45And we're checking this question.
    • 3:05:47If the visibility of that element is hidden,
    • 3:05:51then change the visibility to visible, else change the visibility to hidden.
    • 3:05:57Now, this too is one of these left hand and right hand were not
    • 3:06:00intercommunicating.
    • 3:06:01I have no idea why the opposite of visible is not invisible,
    • 3:06:05but the opposite of visible in CSS is hidden, for better or for worse.
    • 3:06:09So what's really happening here is we have a conditional,
    • 3:06:12an if else construct, that's saying if the visibility is hidden,
    • 3:06:15make it visible.
    • 3:06:16But if it's visible, make it hidden, back or forth.
    • 3:06:19How is this being used?
    • 3:06:21Well, here is another function that comes with JavaScript.
    • 3:06:24There's a global variable called window, which
    • 3:06:26refers to the browser window itself.
    • 3:06:28That comes with a method called setInterval-- capital
    • 3:06:31I. That function takes two arguments, the first of which
    • 3:06:34is the name of a function to call.
    • 3:06:36Notice again, not using parentheses, because I
    • 3:06:38don't want to call blink on line 22.
    • 3:06:41I want to pass the name of that blink function to the setInterval function.
    • 3:06:46And 500 is the second argument.
    • 3:06:48That refers to a number of milliseconds.
    • 3:06:50And what set interval does, as you might imagine,
    • 3:06:52is it will now call the blink function every 500 milliseconds,
    • 3:06:57or half a second.
    • 3:06:58So the effect, if I go back to my browser tab--
    • 3:07:00close my developer tools, and click now on blink.html,
    • 3:07:05is a resurrection of a tag that actually existed when I was growing up,
    • 3:07:09whereby you could literally do open bracket, blink, close bracket.
    • 3:07:12And you could make your web pages text blink like this.
    • 3:07:16Even worse, there was a tag called marquee
    • 3:07:18that would scroll your text across the screen, very hideously so.
    • 3:07:22And in fact, among all of the features of HTML--
    • 3:07:24among the few that have been removed over the years
    • 3:07:27are exactly those two tags.
    • 3:07:28But with JavaScript, we can bring them back now in this way.
    • 3:07:32The point really is to demonstrate again how much
    • 3:07:34control we now have over our DOM and our web pages, thanks to JavaScript.
    • 3:07:40Let's do one final example here.
    • 3:07:43Let's go back to VS Code here.
    • 3:07:45Open my terminal.
    • 3:07:46And let me copy in one last file from today's distribution code
    • 3:07:50called autocomplete.HTML.
    • 3:07:52And let's go ahead and open up autocomplete.HTML here in VS Code.
    • 3:07:58Well, what's going on here?
    • 3:08:00It turns out that there's a body of this page, which
    • 3:08:04just has a text input that's of type text with a placeholder of query.
    • 3:08:09Below that, there's this empty unordered list with nothing
    • 3:08:12initially, much like there was an empty paragraph tag previously.
    • 3:08:15So I could put "hello, so and so."
    • 3:08:17Then there's this file here, using a script tag, referencing large.js.
    • 3:08:22So I actually need that file too.
    • 3:08:23That's in today's distribution, too.
    • 3:08:25So let me grab large.js, which if we open that up,
    • 3:08:29might look somewhat familiar.
    • 3:08:30It is a JavaScript version of the dictionary from problem set 5,
    • 3:08:36wherein you implemented the fastest spell checker that you could.
    • 3:08:39So there's 100,000-plus words in this file.
    • 3:08:41But notice, they're structured as a JavaScript variable called
    • 3:08:44WORDS all caps, to make clear that I mean for it to be global.
    • 3:08:48It's using square brackets, as on line 1, because that it turns out,
    • 3:08:52much like Python, is how JavaScript indicates an array.
    • 3:08:55But in JavaScript, they're again called arrays instead of lists.
    • 3:08:58And then I just have this comma-separated list
    • 3:09:00of strings using double quotes.
    • 3:09:02But I could have used single quotes for all 100,000-plus of those words.
    • 3:09:06So by including this file, this means that my script down here
    • 3:09:10has access to that WORDS variable.
    • 3:09:12What am I doing?
    • 3:09:13Well, I create a variable called input, and set
    • 3:09:15it equal to querySelector's return value,
    • 3:09:17just so I can get a variable pointing to that text box.
    • 3:09:20Then I'm, again as before, adding an event listener, listening for keyup,
    • 3:09:24so the finger coming up.
    • 3:09:26And whenever that happens, I call this anonymous function.
    • 3:09:29I first, in that function, set an HTML variable to,
    • 3:09:33quote unquote, so the empty string-- nothing, because what I want to do
    • 3:09:37is build up a list of words that match whatever the human has typed in.
    • 3:09:42And you'll perhaps see where this is going in a moment.
    • 3:09:44If the user then has typed something in-- there's a value in that text box,
    • 3:09:48do this.
    • 3:09:49Iterate over that array of words, so for each word of words.
    • 3:09:53Here too is a JavaScript specific feature, but it's similar in spirit
    • 3:09:57to Python, sort of similar in spirit to C.
    • 3:10:00But the preposition I'm using is indeed of.
    • 3:10:02And I'm saying, for each of the words of this words array--
    • 3:10:06it's a little weird, the English.
    • 3:10:07But this is how you can iterate over every element in a JavaScript array.
    • 3:10:13If the current word that we're iterating over starts with capital W--
    • 3:10:18so this is a function that comes with strings in JavaScript, that input value.
    • 3:10:23So in other words, if the word we're looking at in the dictionary
    • 3:10:28starts with the same letters that the human has typed into the text box,
    • 3:10:32let's do this.
    • 3:10:33Let's concatenate onto the HTML variable, which is just an empty string
    • 3:10:37initially, the following HTML.
    • 3:10:40Now, this too looks weird.
    • 3:10:41But remember that the backticks mean that you can interpolate variables
    • 3:10:45inside of curly braces.
    • 3:10:47So this means add to that HTML variable another li tag and another close li
    • 3:10:53tag, inside of which, though, is the word that
    • 3:10:56has matched the first few characters.
    • 3:10:59And do that again and again and again.
    • 3:11:00And plus equals here just means concatenate, concatenate, concatenate.
    • 3:11:04So we're essentially building up, in JavaScript,
    • 3:11:06more and more and more and more HTML dynamically,
    • 3:11:10based on the human's keystrokes.
    • 3:11:11And the very last thing I do is this.
    • 3:11:13I ask the document to querySelect the ul element, which
    • 3:11:17previously was an empty unordered list.
    • 3:11:19But change its inner HTML to be equal to the li tags
    • 3:11:25that I've been creating, creating, creating in one big variable.
    • 3:11:29So if I go back over to VS Code here, if I go back to my Browser tab
    • 3:11:34here and click back, and I now go into autocomplete.HTML, as the name suggests,
    • 3:11:39this is the essence of how autocomplete exists
    • 3:11:42in Google, in Bing, and in applications more generally on the web,
    • 3:11:46and in some mobile devices.
    • 3:11:48If I type in C, I see now an unordered list of all of the words
    • 3:11:54that start with C in this dictionary.
    • 3:11:56If I type A, nothing seems to happen, but that's because the list is so long.
    • 3:11:59If I type C-A-T, now notice I get every word that starts with C-A-T.
    • 3:12:04If I type in S, now I get just four words, including catsup at the end,
    • 3:12:08that starts with C-A-T-S.
    • 3:12:10Meanwhile, if I open up the web pages source, notice that none of those words
    • 3:12:15are in there.
    • 3:12:16They're in the large.js file, but not in this page.
    • 3:12:19If I instead close that and open up the inspector again,
    • 3:12:23and I go to the Elements tab, and after having typed in "cats,"
    • 3:12:29notice there are indeed four li elements there.
    • 3:12:33But watch what happens.
    • 3:12:34As soon as I delete mention of cats here, all four of those li's disappear.
    • 3:12:39And now I'm back to the ul alone.
    • 3:12:41So this is to say with HTML, we can structure our web pages.
    • 3:12:46With CSS, we can stylize our web pages.
    • 3:12:49And with JavaScript, we can dynamically update and modify our web pages.
    • 3:12:53And via JavaScript can we therefore implement
    • 3:12:56applications like Gmail and Google itself and CS50.ai,
    • 3:13:01and so much more, because it makes what's
    • 3:13:02otherwise a very static experience in the browser suddenly dynamic.
    • 3:13:07And indeed what JavaScript can even do is make more HTTP calls
    • 3:13:11to the server to get more and more data, more and more tiles from a map,
    • 3:13:15more and more emails from the server.
    • 3:13:17But today, we've seen just the fundamentals.
    • 3:13:19Through your coming problem sets and perhaps final project will
    • 3:13:22you have an opportunity to apply all three of these technologies
    • 3:13:24together to build the web applications and the mobile applications
    • 3:13:28that you and I already use every day.
    • 3:13:31That's it for CS50.
    • 3:13:33We will see you next time.
    • 3:13:34[THEME MUSIC]
  • CS50.ai
Shortcuts
Before using a shortcut, click at least once on the video itself (to give it "focus") after closing this window.
Play/Pause spacebar or k
Rewind 10 seconds left arrow or j
Fast forward 10 seconds right arrow or l
Previous frame (while paused) ,
Next frame (while paused) .
Decrease playback rate <
Increase playback rate >
Toggle captions on/off c
Toggle mute m
Toggle full screen f or double-click video