 You guys ready for the first tech talk of the day? Awesome. All right, so my name is Kevin Schauff. Like Matt said, I'm a software engineer. I work on the core of the Polymer library, so I implement a lot of the core Polymer features. And today, my talk is titled Thinking in Polymer. And really what we want to do is introduce the mindset that we, the Polymer team, want all of you who are using Polymer to be in when you're using Polymer to help solve problems in building your applications. And I'm going to try and introduce some concrete concepts and patterns that you can use to make the whole process of using these tools a little more concrete in your head. So first, if you've heard us give any talks in the past, and Taylor just drove the point home, you've probably caught onto this notion that Polymer is really all about leveraging the DOM, the document object model, as its framework. And when you first hear that, it might sound kind of strange, right, like the DOM, what? And maybe we don't mean it like 100% literally, but what we're really trying to say is that the DOM actually has a lot of framework type concepts just built into it, just sitting right there. And so really what we mean is that rather than inventing a whole set of new concepts that kind of ride on top of the platform, what we're going to do is look to the DOM and use all the good parts of the DOM, the kind of framework type parts of the DOM that are just sitting there before we invent anything new and ask you to learn those. So what are those good points? What are the good parts of the DOM that we like? So first of all, DOM comes with its own component model. This is something we typically think we need to go to a framework to get. And the component in the DOM is the element, right? So a lot of times we use the video tag as a good example of a really powerful element that's hiding a lot of complexity behind a really simple and easy to use interface. And that's what we mean by a component model. And the DOM has elements, this concept of an element with a standard interface just sitting there. And by dropping just a simple tag on the page, we can get a lot of functionality. It's like a whole application just sitting there hiding behind one tag. DOM also has a concept of Dataflow. And I think we kind of take this for granted. But if we go back to our video example, the way that we can think about Dataflow in terms of elements is we have attributes and properties. That's how we get data into our elements. And elements can tell us when they have data to send back to them through their events. So the video tag is going to fire a load event and a time update event to tell us when things change. So DOM kind of has concepts of how to flow data in and out of elements that we can think about leveraging. And then finally, elements, the component model in DOM elements come with their own declarative syntax. You guys know what it is? It's HTML, right? And it sounds like really silly to point out like HTML is some awesome thing because we take it for granted. We use it every day. But think about what HTML is actually doing. It allows us to encode a whole tree of preconfigured elements in a human-readable format, send it over the wire, and then a high-performance parser that's sitting there in the browser is going to slurp that up, inflate that into a bunch of live elements, our component, live working elements, without us having to write a line of script. So HTML is just sitting there. And if we're using elements as our component model, we can leverage all of these things together. But until recently, the DOM has been this walled fortress. It wasn't extensible. And so while the people who invented the DOM 20 years ago had all of these concepts sitting there, we just couldn't really take advantage of them until custom elements. So custom elements is the linchpin to us being able to return to the DOM as the framework. Because by allowing us to extend the vocabulary of HTML, we can really opt in to using all of those concepts that are just sitting there in DOM. And this has real tangible benefits to you, to all of us, web developers. It means we have fewer concepts to learn, right? I mean, everyone sitting here in the crowd knows how to write HTML. You know how to set attributes. You know how to set properties and listen to events. So you know how to use elements already. So when we're using elements as our component model, we don't have to carry around a whole other set of knowledge that we have to learn. And then custom elements become this interoperability layer. Because like any web library out there today knows how to work with HTML, knows how to set attributes, knows how to listen for events and set properties. The custom elements that we create are naturally going to be interoperable and reusable across a lot of different projects and technologies. And ultimately, this lowers the lock-in for you. By using an interoperable standard as our component model, we're not locked into one technology silo. OK, so if DOM is the framework and elements are our component model, what is Polymer exactly? So Polymer's primary mission is to help you build custom elements, full stop. So that's our mission in life. We want building new custom elements to be as elegant and productive an endeavor as possible. And when you're building and working with Polymer elements, they're really just DOM elements. And so you're going to be using all of the same DOM techniques and idioms that you're familiar with, things like attributes and query selector and event listeners and that sort of thing. And this is where we start as well on the Polymer team. But we find when you start building a lot of these, these primitives that you're using in the DOM can be a little tedious. It ends up being a lot of boilerplate code to do kind of simple things. And really, what we're trying to do is encode that into some shorthand that you can opt into using to really make building your own custom elements a lot more fun. And you end up writing a lot less boilerplate. So that's really a lot of what Polymer is trying to provide. So hopefully, you can see that we're like super psyched about custom elements, right? We actually think that this is going to become the de facto component model for you on the web, because it's an interoperable standard. And I think it's pretty easy for the casual observer to look at custom elements and go, yeah, so this is a nice new standard for building new drop-downs and new date pickers and new combo boxes and that sort of thing. But we actually see custom elements as a far more powerful tool. So the Polymer team, I mean, we actually started building element sets. You've probably seen the nice material design. So we actually have a whole team of engineers who work on just building elements, because HTML needs a lot more, a higher level of UI components for developers to start from. But we don't just stop there. We kind of had a radical idea. What if custom elements were the only tool that we needed to build applications, right? So that's kind of what the rest of this talk is going to focus on, is to look at how we can take custom elements as this really primary tool that we can use in our toolkit to build not just widgets and new date pickers and that sort of thing, but entire applications. All right, you with me? All right. So as we go through, what we're going to do today is build an app. And there's basically like three main concepts that we're going to kind of leverage as we're going through the app building process that will really kind of help coalesce how we put together custom elements into applications. So the first one is thinking locally. And there was a little confusion in the rehearsal yesterday. So if anyone looks at this picture and sees a guy with a giant mouth eating like a face-sized lollipop, that's not what this is. You're going to have to suppress that image from your mind. This is a guy holding a magnifying glass up to his face, OK? So just try and you're going to see it a lot. Just try and push it down. OK, so thinking locally, why is this guy holding a magnifying glass up to his face? Well, it's because when you're thinking about using elements to build an application, you're not going to try and hold the whole complexity of the application in your head. Instead, you're going to break the application down into a lot of little bite-sized pieces that each do one job really well and you're going to give it a really well-defined interface. And this is how we keep from getting overwhelmed when we're facing a really complex application. So next, when we're thinking locally, we're only going to kind of draw a box and look at one specific piece of the application at a time and let all the other details of the application fade away. Then inside of that element, we can actually leverage other elements to get the job of that element done. And this is where composition comes in. So as we're thinking locally about one element, we're thinking about, what could I go to the catalog? What could I go to the shelf to pull in even native HTML elements to get the job done? Those elements are going to go into the private implementation of our custom element, into the shadow DOM, kind of into this separate tree that's hidden from the user of the element. And we can compose them together. So we're thinking locally, we're using composition. And finally, the way that we're going to reason about all of the elements that are sitting in our private world of our custom element is through the mediator pattern. So if you're not familiar with the mediator pattern, this is kind of one of those classic Gang of Four software design patterns. The Wikipedia definition goes like this. So the essence of the mediator pattern is to define an object that encapsulates how a set of objects interact. Objects no longer communicate directly with each other, but instead communicate through the mediator. All right, so this is going to be a really central concept as we go through. So let's see what this actually means in process. So abstractly, we're going to break off one piece of the application, and we're just going to be thinking about that. So that's going to be our custom element, our lens of focus. Next, we're going to use composition. So we're going to go grab some children. We're going to put those in the private implementation of our element. And then we're going to use the mediator pattern to kind of mediate, to control the interaction of those elements in our private implementation. And what does the mediator pattern kind of mean in this context? So it means that the custom element, it's acting as the host of those elements. We often say these are the local DOM elements. So the host and the local DOM kind of have this relationship. And so all communication between any of the siblings in the local DOM will be mediated through the host. So concretely, this means that the host is going to be configuring its children with properties. It means it's going to be, say, using out-of-it listener to listen for events coming up for the children and then deciding what to do. Maybe it flows data back down to some of the other children. So this is going to be kind of our primary one, two, three step as we're going through building an application. And then finally, the last piece of the mediator pattern is that while the custom element is both kind of mediating the control of the children, he's also presenting a common simplified interface to the outside world for end users to use. I mean, it's very classic, object-oriented programming. You're hiding implementation details and then providing an API floor. OK, so these three pieces kind of work together. And by hiding the implementation, once we're done implementing the functionality of that custom element, all the details fade away. And we can just think about using that element as another element, just like the video tag. It's got a tag. It's got an API. It's got events that it sends. And we can just think about it as an element from there. And then we can use that, compose it into another custom element. And then that cycle is just going to keep repeating as we build the application. All right, so let's go ahead and do that. Let's build an app. We're going to go through this kind of quickly. It's not going to be like a full syntax tutorial. What we're really going to want to do is kind of try and focus on these three key concepts. So thinking locally as we're building an element, we're not thinking about anything else around it. We're going to be using composition and then using the mediator pattern to stitch those together. OK, so the app is going to look something like this. So it's going to be a little chat app. It's going to have some threads on the left that we can select. We can post some new messages. We have the message list. And it's got some non-trivial details like this. We can edit the title of the thread as we go. All right, so first we're going to think locally. Let's break off one small piece of this application. So I'm just going to think about this one piece up here, this toolbar that has the little pop-up that we can edit the title. So I'm just going to focus on that. And that's going to become our custom element. I'm going to call this an input header element. So thinking locally. Next I'm going to use composition. So what are the things inside of that guy's implementation that I need? So first we're going to make it fancier later, but we're just going to start with the key pieces. So there's a div that shows the label, the title of the toolbar, and then there's an input that allows the user to edit it. All right, so again, here we're using composition. All right, so let's start writing some code to codify this. So hopefully through the code labs and stuff, you guys have a basic handle on what some normal Polymer syntax looks like. It basically looks like this. In the template, I have the area where I'm putting my private elements. Those are going to go into the local DOM, the shadow DOM. And then I've got a script. This is going to become the prototype of the element. And I can add some things there. And then going forward, I'm just going to show this shorthand here. So we can just focus on the key bits. All right, so input header. So probably it's going to want to be able to set the initial value of the label as it comes in. So we'll think about the label as being part of its API. And then when the label changes, we're going to want to initialize the value of the input value and the label in the toolbar. OK, so first what we're going to do is build this piece up using some more basic techniques. And then we're going to introduce data binding towards the end to show how that data binding is really just codifying these techniques that we can do raw by hand. It's just going to do it in more of a shorthand way. All right, so let's see. OK, so first we're going to make the label part of our API. So this is a Polymer syntax for defining a label. And I'm making an observer for it. And one key thing to note is that in Polymer 1.0, defining an observer is just shorthand for creating a setter on the element for the label property and calling the label change the observer function that I put there. So that's all that's happening under the hood is that little bit of shorthand, some sugar, for helping you define a setter and calling a function. And then when the label changes, I'm just going to propagate that value to my local DOM. So if we look at this back in context, when the label changes, that observer is going to run from the setter. And we're just going to propagate the label to the children. So that's pretty straightforward. Again, we're using the mediator pattern here. The children in the local DOM are getting initialized from the parent's API. So mediator better. All right, next, we're going to allow the user to change the title. So we're going to want to catch an event coming up from the input. I'll use the input event. And then the host is going to mediate that. So the host is going to be listening for the custom element. The input header is going to be listening for the input event from the input. And then setting that value back to the host, which thing can propagate it back to the children. OK, so here I'm using Polymer's declarative event handler syntax. And again, this is just shorthand for calling addEventListener. Again, these are all the things that we kind of sugared. As we started building a lot of elements, we were like, man, it just stinks to write imperative code to call addEventListener and get a reference to the thing you want to listen to. Let's just make all that easy. So this is kind of the shorthand that we've added for doing that. So when the input event fires from the input, we're going to call handleInput. And then we're just going to set the value from the input back to the host. And again, that's going to trigger the observer. So when the input event comes up, we're going to set the value to the host, the host label property. So this is the host, the input header. And then that's going to trigger the observer to then send the data back down to the children. So this is kind of just the classic instantiation of the mediator pattern in Polymer. So we've got an API coming in, the label. And then the host, the custom element is responsible for getting that information to his children and then listening for events and doing what it needs to get this work done. OK, so again, for a pattern that we're going to be using over and over, this is pretty clear. It's very readable. But it can just be a lot of typing. So this is where we introduced Polymer's data binding shorthand. And the real key thing here, so data binding of late has gotten a bad rap. It's got a kind of a love-hate relationship with developers. Because while it's really convenient, it can hide a lot of the complexity of what's going on. And so the key thing to know is that in Polymer 1.0, the data binding system is 100% just codifying the thing that we just wrote here. So this notion that typically the host is going to have a property. It's going to want to send that down to his children. And then maybe when some events happen, it's going to want to send that data back up to the host. So the data binding system is really just codifying exactly what we wrote here. And we'll go through that. So first, we can use Polymer's curly, mustache type annotations in the template, similar to other libraries. And what this is doing is say, anytime the label changes on the host, set that to this property on the child. And so it's like almost literally just replacing this code that we did here. So by virtue of putting those mustaches up here, I can basically just eliminate this code out of here. But really, what's important to think is by putting those things there, you're acting as the mediator. You're the host acting as the mediator saying, when my label changes, I want to send it here. So it's one-to-one mapping. So then if we visualize that again, it's going to look exactly the same. It's the bindings that are making the data flow down rather than your own code. Again, the mediator pattern here. So finally, it would be nice if we can get rid of this event handler, too. So if you kind of look, what's interesting is that the information that we needed in the event handler is the same two pieces of information that are up in the binding. So we want to set the value back to the label. The only thing that's missing is what event should trigger it, right? And so this is where we introduce Polymer's double colon syntax in the binding. And it basically just allows you to tell what event should handle the reverse flow. We can put that right there in the binding. And that allows us to eliminate this code all together as well. So now we're back down to a very declarative, sorry, and then if we walk back through there, my purpose in showing this is that what's happening is exactly the same. The code that's running is almost identical. So when the event comes up, the event that we put in the binding is going to handle setting the value back to the host. And then the host through the binding is going to set the values back down to the children, right? So again, I just want to keep re-emphasizing that Polymer's data binding system is really just codifying this mediator pattern and making it really fun and easy to use. All right, so what if we want to end it? So I started out with a raw input here. But we have some fancier inputs in the catalog. So let's say we want to replace the raw input with a custom element, right? So I can go to the catalog and get this paper input, which is really fancy when you click in it. There's a little label that swoops up. It's a very nice input. It's a custom element built with Polymer. And you'll notice that the name of the event changed here. So again, yeah, using composition. The name of the event changed here. Instead of the input event, I'm listening for the value changed event. And that's because if we go to the API documentation for paper input, its value property fires an event called value changed when it changes. And this is actually another part of Polymer's shorthand. It's sugar for helping you do this really quickly, is if we look at the implementation of paper input, when it declares its value property, it can just put this notify true flag on. And that's just shorthand for saying when the value on the host changes, fire an event so that anyone who's using me knows that my value changed. And this helps reinforce the mediator pattern. And it helps give us a nice pattern for knowing when data on the children changes and the host above being able to do something about it. And when we're binding to Polymer elements, because they all notifying properties in Polymer use this same event syntax or event convention, the name of the event, we can just eliminate the event name from our binding. So throughout the rest of the day to day, you'll probably see a lot of code slides that are just jumping straight to this. Because it's very convenient. Once you understand how the underlying internals work, it's very convenient to just use the syntax, which is kind of codifying that mediator pattern, the way that we reason about data moving in the app. All right. So the last thing I'm going to do is go to the catalog and just sprinkle some more paper elements in here, because they look really good. And these aren't really affecting the data handling in the app at all. It's really mostly just for view and presentation and gives some nice effects. So I've got a paper toolbar. I've got some icon buttons. And then what's key here is that the paper menu button kind of gives you this really nice pop-up, accessible pop-up behavior for free. And so with that, with just what we have on the screen here, we've kind of completed this input header. So we've got our first element done. And it's got all that functionality that you see right there, really as a virtue of composition. So we're able to kind of pull in elements that other people have created that give us some really nice functionality. And then we've codified the data handling in our bindings using the mediator pattern. All right. So let's kind of review what we just did. So we started out thinking locally. So we broke off this one piece of the application. We made that into an element of itself. We used composition, right? So we went to the catalog and we found some elements that we could use in the private implementation to get this job done. So those went in there. And then we wired up the interactions using the mediator pattern and exposed itself to the outside world through its API. And the only API we need on the input header is the title. And so when we go to use the input header, all that complexity fades away. We can just think about using this as just a normal HTML element, normal element in the DOM, and it has a label property. And then we can compose this into the next element and so on. And this is really where the three concepts kind of loop back and repeat on each other. So by kind of hiding the implementation detail and just giving it a simple API, at the next level up, all we have to do is think locally about that element. What do I need to get done? I don't have to worry about input header anymore. That's already done. I just have to interface with it through my API and mediate the data handling for it. And then this cycle can just repeat over and over and over as we're building the app. It's a bit like Russian nesting dolls, right? So inside one doll, you can just put another one. Inside of that one can be more and more and more. Do you like my metaphor, Russian nesting doll? I thought it was kind of unfortunate that I googled Dutch nesting dolls, and apparently there's no such thing. So I tried to like, maybe I can make them look a little Dutch, and I was just like kind of stupid. So do we have, are there some Dutch people in the crowd? Got some? OK. So the Dutch masters there didn't really fit with the aesthetic of my slide, so I went for this. You get it? You get it? OK. That's, I'm going to pronounce it wrong. We call it Miffy in the rest of the world. It's Naintje. Naintje, yeah. OK. All right. It's a Dutch character for those watching on the live stream. OK. All right, so we've completed our input header here. And so we can move on to the next part of our app. So let's move to this element. We'll call this the chat thread view. And so when we start out, we'll think about kind of the data that might be backing this application. So we might have an array of threads. Each thread would have like a title and a messages array. And then each message might have some user and some text. So we'll think about kind of the thread being the API to our element here. So we'll define the thread on our API here. It's an object. It has the title and messages property like we just saw. And next, we're going to use composition. So we just built that input header. We're going to use it here. So we're going to compose that in here. Again, all we have to think about is the input header and its labels. So we're just going to go ahead and bind the thread title to our input header. And so basically, we're kind of done with that piece. So we can move on. Next, we've got the list of messages that are going to be in the chat thread. So again, here we're going to use composition. So someone has already gone through the hard work of creating a really high performance element that handles repeating templates of DOM and keeping them in sync with data. And that's called DOM-Repeat. And we shipped that just in the core of Polymer because it's such a useful element. So I'm going to use DOM-Repeat. I'm going to bind our messages array to the items array of DOM-Repeat. So again, just going straight to data binding here. So when the thread changes, we're going to propagate its messages property to DOM-Repeat's items. And then DOM-Repeat's going to be responsible for creating one instance of the template for each element in the array and then keeping that data in sync. And then inside each template, we can put stuff. So here, I'm just going to use a really simple paper item. I'm going to bind the text of the message, the chat message in there. I'm going to bind that just to the text content. And then we're kind of done with the top part and the message list. The last thing we need to add is the input that goes to the bottom. We're going to type in post new messages. So we'll make some room. So I'm going to go back to the catalog, grab that paper input again. It's pretty handy. But instead of using data binding here, because when we hit Enter as a new message, we're not really binding that to data. We need to take an action. We need to create a new message. And so here, I'm just going to use our normal DOM technique. So I'm going to add an event listener. So I'm going to listen for the key up event. Again, use our declarative event syntax. And in the handle input event handler, I'm going to kind of look for key code 13, the Enter key. And then I'm going to take an action based on that. So I'm going to basically create a new messages object and push that onto the threads messages array. And just a side note, here I'm using Polymer's structured data API. We provide some API in Polymer for allowing you kind of anywhere in an element to modify structured data, so objects in arrays, properties of objects in arrays. And ensure that any element that you've shared that with using the data binding will be notified of those changes. And that structured data system, although the details aren't as important, it really leverages the exact same event system that we use for normal property changes. All right, so with that, we've kind of completed the chat list really just by composing three things together. We've got all the functionality that we need. And again, even though all the code fits on the slide here, it's pretty compact. When we go to use the element, again, all that detail is just going to fade away. And we can just think about using this element as an element with a thread property on it. So that's pretty cool. OK, so we'll kind of round out the application here. By looking at the chat thread list, this thing over on the left. And I'm just going to skim through this, because by now you're probably getting sick of me saying, the mediator pattern and that sort of thing. But it's all going to be the same concept. So if we think about the API, we're going to take the threads array in, and then its job is going to be to show a list of those threads, have some selection for it. And we can actually go grab a paper menu. It's a nice thing that allows you to do really quick selection of some stuff that you repeated out. And then I'm going to use the array selector, which is another element that helps us do selection of an array and produce that back out as a selected thread. So again, the API of this element is just going to look like it takes a threads array in, and it produces a selected thread out. So that's pretty simple. And then we're going to go and kind of tile these things together. So we'll go kind of up one level. So we're going up the Dutch nesting dolls. And we're going to tie these together into an element called chat view. So it's going to look something like this. I'm going to take the chat thread list that we just made. We just skimmed through. We're going to put that next to the chat thread view. And then for the purposes of the app, we need to get some data in. So for now, we'll just use an IronAge Act. So this is another element that we have that allows you to do declarative Ajaxing. Just put it in as an element. And then that produces a property, a response property. I can bind that to the host, to the chat view's threads property, to bind that up to the host. And then the host can decide to pass that down into the chat thread list. The chat thread list is going to be responsible for selecting one of those. So that's going to come back up as a selected thread property on the chat thread view. And then I can bind that back into the thread. And so here, it's a very clear pattern in that. I'm really just composing some things together and then mediating how they hook up in this particular context. So we'll just go through the code really quick. It'll be really simple. We have an IronAge Act. It's going to produce a response property. I'm binding that to the thread's property, the host. Then the host is going to turn around and bind that thread's property into my chat thread list. The thread's property into the chat thread list threads. That's going to create a selected thread property. So I'm going to bind that back to the host. And then finally, I can bind that into the chat thread view as a selected thread. And with that, we've, oh, sorry. And then one last thing, just for the view, I can wrap this in a paper drawer panel, which gives us a nice left-to-right responsive kind of master detail view layout that's responsive down to mobile. And with that, we basically completed the application. And we've kind of done all this functionality. There's a little more detail in the thread list that I skipped over to kind of fit it in the time for the talk. So let's recap what we did. So we started out, we were thinking locally, right? We created that input header and then composed it into another element. And then we were just thinking locally about that element. We didn't need to worry about the input header. We composed that into the chat thread view. And then that chat thread view just got composed into another element, chat view, right? So by using this one tool, we just kind of keep doing the same pattern over and over. And we can get to increasing levels of complexity. And here, we kind of pose this as the app. But it doesn't really need to stop there. We could, because this isn't, although it's an app, it's not anything special. At the end of the day, this is just another element. And maybe if the requirements changed and we needed to say integrate this app into something more complex like Gmail, it would just be an element going into our bigger application. So really, if you think about it, once you learn this one tool, the custom element, how to use that tool, it's really the only tool that you need. You can just kind of keep using it over and over, just like the Russian nesting dolls or the dust nesting dolls. You can just keep leveraging the same tool, custom elements, over and over and over. All right, so that's the talk. The code for the app that we just built is up on GitHub. My name's Kevin. Thank you very much.