 It's our exciting new project. I'm not talking about a tool you already use every day. Ninja Script is a tool that was written by Judson. Judson, raise your hand. Everybody give a round of applause to Judson. This is me, said I'm the CEO and lead developer of logical reality design. But as I said, the tool is written by Judson, almost completely coded by him. So Ninja Script is a JavaScript framework that has three goals. The first goal is to be completely unobtrusive. So when you're working in Rails, Rails 3 is a big improvement in unobtrusive JavaScript over Rails 2, but with Ninja Script, you can make it better. You can do completely semantic HTML sites with no markup required for all of your JavaScript behaviors. Our second goal is to make all of our websites degrade gracefully. What do I mean by degrading gracefully? I mean you should have a functioning, fully functional website, and you use JavaScript to enrich the behavior of that website. More specifically, your website should work without JavaScript. Now, how many of you have written websites that don't work when JavaScript is turned off? Yeah, so pretty much everybody. Let's all admit the Rails world is terrible about this. It's not just our fault. Certainly this is a very hard problem and Rails does not make it any easier for us. But there are reasons why we care. We really do want graceful degradation because, for example, Google, Spiders, and other automation tools are gonna use your website without JavaScript turned on. You'd like to accurately represent the functionality of your website to your search engines and other automation tools. Blind and people with poor vision use screen readers to access your website and they generally use your website without JavaScript. And also, there's security. We are having trouble with the microphone, aren't we? There are security conscious users. People who run NoScript or people who just turned JavaScript off who are gonna browse your website and if it doesn't work without JavaScript then you've lost a significant second of your population. But we have to admit it's for Royal pain in the body to make something great without JavaScript. It feels like duplicating all of your work, especially if you're writing AJAX controllers, right? You have to write everything twice. It wants to do the AJAX operations, wants to do the regular HTML operations, but the goal is to make it easy and NinjaScript is here to help you with that. The third goal of NinjaScript is persistent behavior. And this is something that is a little less obvious for all so used to the way that JavaScript works that we don't realize that JavaScript doesn't give us persistent behavior. So the metaphor I like to give for this is that CSS is awesome, but JavaScript sucks. What do I mean by that? In CSS, you use selectors to apply styles and those styles always apply to the DOM nodes that the selectors apply to. So even if you change your DOM, if you've got, say, a certain class has a background of yellow, you can add something to the DOM later that has that CSS class and the background stays yellow. JavaScript doesn't behave this way because it's a scripting environment that has a state. To give you an example, let's suppose that we have this DOM here. So we've got to deal with the idea of content and two links with the tooltip class. If we then come along, and this is using a little jQuery code, to find some behavior to things with that class, then we have enriched these two DOM nodes with that behavior. But if another widget comes along later, say, an Ajax behavior and adds another dot has tooltip link, then that was going to get our bound event handler. So all of a sudden, we've got consistent behavior in our app. And it's because of the time at which we ran the JavaScript that bound these behaviors. We're also used to this that we don't realize how annoying that is. But the goal of NinjaScript is to solve this for you. Now, a lot of you may be thinking, so what we'd like is for this to happen for you and we'd like it to be easy. A lot of you may be thinking we already have event delegation. So we've got jQuery live. This allows us to run all of our event binders. The way this works is we bind all of our handlers to the root of the DOM rather than to the elements themselves that we care about. Since our browsers bubble up all of our unhandled events up through the DOM until somebody handles it, this means they always get to the root of the DOM which is unchanged. And that can handle all of the events and that's really pretty cool. Unfortunately, there's a problem. Event delegation can't handle transformations to things that are on the page. What do I mean by transformations? As an example, you might want to give all of your divs of a certain class of rounded corners and this might mean adding new HTML structure to the page. The trouble with that is that if you were to have the div that you need to add the rounded corners come to the page late, there's no event to handle that. You can't count on the browser telling you that something has been added to the DOM. We should be able to. We should be able to do this with event delegation because DOM level two specifies these mutation events. DOM subtree modified and DOM node inserted and there are a few related ones that are supposed to get fired whenever something gets added to the DOM. Then we could use jQuery live to catch that and transform our element as soon as it gets the page. But of course, IE never implemented it. And in fact, as a result of IE's developers and some of the other developers whining that this is really hard, these events have actually been deprecated in DOM level three. But it's kind of a frustrating situation because they're deprecated with no replacement in sight and the DOM is not supposed to deprecate events for any other behaviors until there's a replacement. So instead, we have to do some other approach. The other approach that we use in an industry is called automatic rebinding. So we go back to binding things directly to the element that we care about. But then we're going to continually examine the DOM to see if new things have been added to the DOM that our behaviors should bind to. We actually use those deprecated events where they're available and we use other approaches like firing our own events in some of the browsers that deal with them. And this ends up working pretty well. So the question is, how do I use NinjaScript? Well, in NinjaScript, we've tried to make life easier for you than all the complexity you normally have to do with JavaScript, which is we define what looks like a CSS sheet. We're going to call it a behavior sheet. So in your application JS, say, your Rails project, you're going to have some code that looks like this. You open up a behavior block, you identify CSS selectors, and you specify which behavior they get. These particular ones are predefined behaviors that we supply in NinjaScript. So this, for example, takes a form with an ID of product and turns it into an HX form. Nothing is needed whatsoever in your HTML. Likewise, you can do that with links. You can take form inputs and watermark them. You can set chunks of the page to decay after a few seconds. Here you can pop up a tooltip. Although we don't actually have this behavior yet, but this one is coming soon. You can also, this is just showing the predefined behaviors, but you can also define your own behavior. After the selector where you would pass a behavior, you can pass a behavior object. So this is something with the class of .awesome, gets a behavior block that has a transformation. So whenever a .awesome anything is added to the page, doesn't matter if it's earlier or late, this code is going to get run to transform it. That could add things to it. That could completely replace it with another element, whatever we'd like to do. And then we've got an events block. So all the .awesome's will have this click handler or will have this mouseover handler, et cetera. And this is great because of the internal structure of NinjaScript. You don't ever have to worry about when things are added to the page. This will happen immediately to the things that were already on the page when your JavaScript was loaded, and it will happen later to anything that is added to the page now in the line. There's also some shortcuts. So back on this one, you can see we've got an events block that has click and mouseover. In a lot of cases, you're just going to have a single event handler. You don't want all of this extra structure. So to make it simple, you can just specify that .awesome has a click handler, et cetera. You can also define your own reusable prepackage behaviors, much like the Subvinces AJAX and is a watermark behaviors that we've given you. Doing so looks like this. I've got a little overlap in my slides. This has to be wrapped in a little boilerplate to give you the right context to use NinjaScript, but that boilerplate is in the NinjaScript documentation. And it should just be a cotton paste. But then you define a function that's going to return a NinjaBehavior. Return to this behavior that has elements just like you've seen before. The transform is this behavior, click and mouseover have these behaviors, et cetera. And once you've done that, you can just reuse them. So this would go lower down in your application, JS. You can make DHH and cats sing and dance and you can make all the code monkeys sing and dance because NinjaScript is so awesome. Okay, oops. So these are the predefined behaviors that we have today. Submits as Ajax, which convert existing forms and links into Ajax forms and links. This behavior uses all of your defaults and so it's important for graceful degradation. You write a form that works, then you just go back in your behavior sheet and say it should also behave as an Ajax form. Since the form is the same, all the defaults are the same it reduces the amount of extra work that you have to do. You can take forms and convert them into links. This is also really useful for graceful degradation because there are a lot of things that you might want a link to do, like delete a resource in a Rails application or do something else that needs a method other than get. If you're using a method other than get, you can't do it with a link and have it work with JavaScript off. So the solution is you write a form with a button that says delete this item. And then you run becomes link, which converts that into a link that says delete this item, does the same thing. You've got decays, which fades away after 10 seconds. You can also pass it configurations to change the, pardon me, to change the amount of time it takes to decay. And you've got this watermarked, which takes your forms, which have labels next to all the text fields and converts them into watermarked forms where the text of the label becomes the watermark in the input. So everybody know what I mean by watermarked input? Placeholder. Yeah, so that's where you've got placeholder text and you click and that blanks out. And if anybody's ever written this in JavaScript yourself, it's a royal hand in the box. So that's why Judson is doing this offering so that you don't have to. And it just takes it straight out of your label from the HTML page, which makes it, again, degrade gracefully. When JavaScript is off, people see a label so they know what field they're typing it to. When it's on, the label is gone and you just get the text inside the field. We have a bunch of other behaviors planned. We're in the middle of working on these. They'll come out in future versions of Ninjastrip. There are a couple of caveats. The big one is, right now, Ninjastrip depends on jQuery 142. There's some technical reasons. I can get into that in the question and answer period afterwards if you're concerned. But it does not support the two current versions of jQuery. There's a fix coming for this. Our future plans are to complete those pre-packaged behaviors. To decouple the entire thing from jQuery, right now, Ninjastrip functions as a jQuery plugin. In the next major version, it's just going to be its own environment and you can write your behaviors in Mootools, your behaviors in Prototype, whatever you'd like and use the jQuery persistence framework to keep them working, or the Ninjastrip persistence framework. And at the moment, it handles all Ajax calls by just dialing the return, sort of the Rails default, but we're going to build frameworks so that you can write Ajax behaviors that return things in JSON, maybe even XML, and define the return behavior as part of the Ninjastrip Ajax processor. The internals are kind of complicated, but Judson's is a rockstar. In fact, he's a fourth-daner rockstar. He's worked incredibly hard on this for months and while it seems simple from the outside, there are actually some incredibly complicated technical internals like, particularly what happens when you compose behaviors. You have two different behaviors on different selectors that happen to hit the same object in the DOM. What happens if they both transform the object? And he's built all sorts of sensible defaults and configuration options for controlling the order in which these happen, et cetera, and an awful lot of work has gone into it. Okay, so now let's talk about the second half, which is Mizu Umo. Mizu Umo is a gem designed to help you use Ninjastrip in your Rails application and make your Rails application work really awesomely with Ajax and JavaScript behaviors. You run a little generator after you've installed Mizu Umo and you get an application that is Ajax by default, degrades gracefully by default, and is no extra work for the developer. So let's talk about the most important thing that Mizu Umo gives you. And it's what Mizu Umo gives you as a solution to the Rails, what I call the Rails 3 REST fail. So we all know how REST works in Rails. We simulate quit and delete methods because, of course, browsers only support get and post. And so we simulate quit and delete methods in forms by putting a little hidden variable that tells us what method to treat it has. In Rails, we can do it with a link by specifying method, which Rails does by putting data method attribute in our link and using the Rails JavaScript, Rails.js, which shoots its Rails, to make that work. But the problem is with JavaScript turned off, it just links to our URL, which ends up acting like a show link. So now you've got a link on your page that says delete this product. And with JavaScript off, you click on it and you get a view of the product you have just failed to delete. This is really, really awful. And the primary goal of Mizu Umo in its first version is to solve this problem for you. So with Mizu Umo, you call link to exactly the same way, but what it outputs is a form. If you haven't passed a method here, Mizu Umo ignores your call and just passes it to the normal Rails helper. But if you have passed method delete or method put or method post, it generates a form with a button that's the value of your click. As I mentioned in NinjaScript, this is a situation that we'd expect. But Mizu Umo does it for you here. And then we've got a default NinjaScript behavior that goes in your application.js that looks for this class that we add and converts that to a link. So you can get this when JavaScript is on. So the result, JavaScript users see a link. Non-JavaScript users see a button, but the leap works in both cases and you as a developer haven't had to do anything other than install the gem. But what about Ajax? So as I said, Ajax can be a lot of extra work. You have to do everything twice. But with Mizu Umo installed, you don't need to do any markup. So you can make a form. You don't have to say remote is true. You can just make a form. Add this to your JavaScript. Use the same data, the same URL, the same post delete or click method. And all you have to do is write a format.js walk in your controller and the js.erv view. Of course, that already sounds like a lot of work. So fortunately, Mizu Umo ships with a scaffold that does this for you. So let's look at a demonstration of that in absent. You have to do this without seeing it on the screen in front of me. So I'm gonna generate a new Rails project here. That I've been text made. This is gonna be hard because I have to type. Oh, excellent. You guys hear me? Yeah, okay. Sorry about that. All right, so let's open our gem file. So once we've got a project, all we have to do is come in here. That's probably pretty hard to see. All right, thank you very much. That's really helpful. All right, just add the gem. Run the Mizu Umo installer, which is just gonna copy in a bunch of files for us. You'll notice here that it's overriding our Rails.js. That's because Mizu Umo and NinjaScript depend on jQuery. And so it won't work with the normal default prototype Rails.js. So this is just a jQuery compatible Rails.js written by somebody else. I'm actually not remembering the author at the moment, but we just need to let that overwrite. And then it gives us some defaults that we need to paste into our application files. This and those. Just style sheets and JavaScripts. Edition file. Here I'm just going to configure the scaffold generators. Here we have to make a decision. I can do this demonstration either in ERB or in Hamel. I'm gonna be able to prefer to see it in ERB. How many people on ERB or in Hamel, rather? Oh, I see a lot more hands for Hamel. We'll do Hamel then. That's good, I like Hamel anyway. But the gen does ship with both scaffold templates that you can do it either way, like. Did I save that file? All right, so now we're just gonna generate a simple scaffold. We'll do recipes here. I've got a name, a cook time, and instructions. Not doing anything different than a normal, a normal scaffold generation. Agreed the database. So that's all you need to do. I'm going to add one more little tidbit just so that we can see it's happening in Ajax. This is the index file that we've just generated. I'm gonna go to the top and insert, that's myself. Okay, so I'm gonna put the timestamp at the top of the file just so we can see when the page is loading and not. Load the application we just wrote. That's for space, yeah. So watch these last two digits here instead. So you'll see, we're not gonna be reloading the page here. Let's make some new cookies. You can see we still haven't reloaded the page. You can edit these, it's got some cool styling here. All still on the same page. Delete one, but here's the money. I was hiding this from you. Okay, so if I turn off JavaScript, same application, continues to work, but now it loads a new page. And you notice that our delete links are now buttons. Delete them and it's gone. Reloading the page each time. Did this fill my employees' name? There we go. How much time do I have left? Seven minutes. Seven minutes? Oh, fantastic. Okay, so that's the scaffold generator. Works in AJAX, works without AJAX, works with JavaScript off. You as a developer haven't had to do anything. But let's look at a few other things that Mizugumo and NinjaScript can do for you. So this is a demo app we've written. You can find it online at this location. I'm running a local copy here. Code is available online. It's got a scaffold demo. This is effectively what you've just seen. List of products. Let's turn JavaScript back on. But we've also tried to put sensible defaults into all the NinjaScript behaviors. So one example is often if you have a behavior, in fact we kind of saw it there, in AJAX the user doesn't normally get an indication that anything is going on. And you as a developer have to go out of your way to put a spinner on the screen or something like that. So what we've done is taken the submits as AJAX behavior and added the automatic application of a spinner to the logical element on the screen. You can pass the configuration to control which element. This scaffold is exactly the same as the previous one we've seen, except there's a sleep 2 to put two seconds of sleep every time we create or edit an object. So I'm gonna bring up a new form here. We're just gonna simulate the browser or the server rather taking a while to get back to us. And it's just gonna automatically pop up a spinner for us. You haven't had to do anything. Submits as AJAX does that for you by default. You can have it place the overlay anywhere you want, but by default it does it on top of the form. Same with that. It's another example. The graceful degradation of forms that I showed you. So these are all these links that do puts, shows, deletes. Let's go into the code for this. These are all again just linked tos. To delete product with method is delete. We've got confirms, et cetera. And we've even got some down here that link with an image tag. You can see they all look roughly like what we'd expect. But if we turn Joe's script off, they'll all work in a degradable way. It buttons when we need them. And we get forms with image submits in the places where we hide image links. Now this will just do plain text and it'll do images. It's not gonna do really complicated. If you pass HTML structure with text and images and other tags in it to your link to method, this isn't going to be able to replicate all that. So you wanna bypass it as we do in that case. There's another example. So the watermark informs all of here. With Javascript on, it takes the labels and automatically sticks them in here. Work with password fields also? We are working on getting it to work with password fields. There's a bit of a challenge in that you wanna be able to obviously not see what you're typing in the password field but see what the watermark is. In order to do that, we have to switch the type of the field between a text field and a password field and IE's Javascript engine does not allow you to change the type of a form. So we're working on pulling it out and replacing it completely but that's the link. The moment this just works with text fields. So you do that. This also has the decays behavior. It should go away in a few seconds. Again, turn Javascript off and you get a sensible behavior that still works. You can see, I don't know if you can read that. It's a little small on the screen but it's just labels and inputs. You don't have to do anything in your markup to get the watermarking and the labels show up for regular JavaScript or for non-Javascript users. So, that's the end of that part of the demo. Thank you very much, Sharon. Thank you. So we have a few future plans for Mizugumo. The first is to replace Rails.js completely. We'd like when you install Mizugumo to get a completely ninja script version of all of the default Rails behaviors so you only have one Javascript engine to depend on. We wanna improve the generators a little bit. At the moment, they don't produce any tests or specs. So it uses the Rails default ones which will test your non-AJAX behaviors but we'd like to put some generators in that will test both the AJAX and the non-AJAX behaviors. We'd like to make a confirmed degree. Right now, confirmed does degrade in the sense that your delete links will still work but you won't get the confirmed popup. We're looking at providing an extra controller behavior automatically so that anything that has a confirm attached to it will submit a pull of a page that wants to confirm then you resubmit and it will actually delete and doing that without any extra work with the developer. And finally, we're looking at doing automatic Javascript validations so that when you set up your model validations in Rails it will automatically take those produce Javascript equivalents and do the validation in the browser so you don't ever even get invalid data submitted back to your server. And again, with no extra work aside from defining the validations. We'd like you all to contribute. This is an open source project. Please, can I get up? Please help us out. And do you have any questions? Exclude CSS from the developer shop because if you get a link in some cases and it puts it inside the form of the cases you have a block element or an inline element once a button, once a text. So it requires double the style. That's right. And in the scaffold generator, ultimately it's no extra work up through the scaffold. Right, because you get sensible styling for those things. But once you want to go beyond the scaffold you probably will have to edit both the HTML and the JavaScript views to get your behavior on both. And obviously there's no way we can do all of your app for you but we want to minimize the impact by giving you a starting place. You can make do this all of the app but you charge for that part. Oh yes, that's true. We would be happy to write all of your app for you. Yeah. Can I ask you if there's a new in HTML? In this version it does not. We'll probably add that in the next version but at the moment we're trying to make a completely universal back to HTML for a version. I'd like to submit a bug and a lot of members should call the placeholder. That's not a bad idea. Go ahead and submit the bug and we'll look at it in the next version. Yes. First of all this is very cool. Thank you. Is there a 30 second blurb on how the van finding works? The live van finding? Or is it just complicated? It's complicated but the 30 second version at the time that it loads your Ninjascript behaviors it lines much like a regular event handler although we wrap all our event handlers in a Ninjascript event handler to give them the behavior so that they know how to compose with things later. It's not just a simple like a jQuery or a regular DOM event handler. And then it uses the effectively watching the DOM to go back and bind new things later when they appear in the DOM but for the most part it functions like you'd expect. Do you have any test coverage for the JavaScript AJAX? We do. Ninjascript is completely tested in Jasmine. You can just load that. In fact you can load it I think straight out of the Git repository and just run the HTML file on the load. Modes all of the test framework off of our server so you can download the Git repository and open the HTML file will test. And there are tests for the output of those and the Mizugumo behaviors in the Mizugumo demo project. So if you are working on Mizugumo itself you can also download the demo project and run its tests to make sure that all of that still works. Yes. What percentage of the browsing public really doesn't have access to running JavaScript and is that a rising or a falling number? Well I would suppose the site-impaired percentage is going to stay about the same. It's pretty small but they're there. I think the no-script percentage is probably falling some but I browse with no-script on most of the time and this has been a continuous frustration for me as I hit the major Rails sites, everything from working with rails.com to Lighthouse, et cetera and I find that these things don't work at all or have really unexpected behavior when JavaScript is turned off. So certainly they're out there because I'm one of them. I don't know that we know for sure what the exact percentage is. I certainly, phone-based browsers don't do that. Well some of them do but yes you can't. You can't always count on JavaScript in phone-based browsers. Yes. What does Mizugumo mean? Mizugumo literally means water spider. Mythologically Mizugumo are the wooden shoes that ninjas used to walk on water in order to approach targets in an unobstructed and invisible way. They don't apparently work. The Mythbusters tested it and they weren't very impressed. Exactly, in reality they probably were just used to walk like snow shoes on marshy terrain at best. Yes. What's the first rule about ninjas? The first rule about ninjas? You can't see them. Nobody talks about ninjas. Yes. Yes, sir, how bad is it? It is annoying as long as we are keeping jQuery as our primary engine and running effectively as jQuery plug-in. Once we decouple from jQuery, the problem should go away. Are you guys interested in the technical details of the problem? Yeah, yeah. Do you want to do these short versions? Yeah, the crap. Okay, so the issue is that, Johnson remind me the name of the method, the select method. The query select all. The query select all. When jQuery runs query select all in order to find the element that you are trying to bind something to or trying to operate on, in order to fix some quirks between different browsers, it actually temporarily modifies the ID of every DOM element that it goes past in an attempt to mark that it has been visited and then it reverts those changes later. What happens is this means that it fires a DOM subtree modified event for every single noted visits while we are trying to do a select ourselves and this results in an infinite feedback loop in Ninja Script. What we're going to do in the next version is we're going to not use Ninja Script or not use jQuery during our select behavior and just use Sizzle, which is the selector library that jQuery is built on, to do the selects and let jQuery run outside of it so that you can either use jQuery or whatever other framework you'd like to write your behaviors. Once we do that, it won't matter what jQuery does while it's selecting, because we're not using it while we're doing selects. Yeah. So as a follow up, but if you're using jQuery, it won't be an issue, I mean outside of Ninja Script, if I include jQuery on five, won't it still be doing that behavior and firing off all these DOM events or that won't affect me? It won't because it won't happen inside of our select loop. At least Judson assures me that it won't. I would encourage you to talk to him during the lunch break or something because he's the fourth and JavaScript programmer and I'm just kind of about 10 for Q, maybe. Yeah. Does it work in all major versions of IE? It definitely works in seven and eight. Does it work in six? I don't know if we've even tested it in six, but it definitely works in seven and eight. Anyone else? Yeah, back there. Can you unbind events? I'm not sure. Can you unbind events, Judson? Not currently. Not currently. Thank you very much.