00:00:08.880
Hello everyone.
00:00:30.880
I'm here to talk about NinjaScript. This is our exciting new project. I'm not talking about a tool you already use every day; NinjaScript is a tool that was created by Judson. Judson, could you raise your hand? Let's give a round of applause to Judson.
00:00:50.239
As I mentioned, I am the CEO and lead developer of Logical Reality Design. However, this tool has been almost completely coded by Judson.
00:01:01.039
NinjaScript is a JavaScript framework with three main goals. The first goal is to be completely unobtrusive. When you're using Rails, Rails 3 has made significant improvements in unobtrusive JavaScript compared to Rails 2. However, with NinjaScript, you can enhance this further. You can create completely semantic HTML sites with no additional markup needed for any of your JavaScript behaviors.
00:01:24.159
The second goal is to ensure that our websites degrade gracefully. What does this mean? It means that you should have a fully functional website that uses JavaScript to enrich the experience. More specifically, your website should still work without JavaScript.
00:01:36.479
How many of you have written websites that fail to function when JavaScript is turned off? Quite a few, I see. Let's admit it, the Rails world has significant challenges in this regard. It's not entirely our fault, as this is a difficult problem, and Rails doesn't make it any easier.
00:01:59.200
However, we should care about graceful degradation for several reasons. For example, Google spiders and various automation tools will access your website with JavaScript turned off. You want to accurately represent your website's functionality to your search engines and other automation tools. Additionally, individuals who are blind or have poor vision rely on screen readers that typically function without JavaScript.
00:02:16.879
Furthermore, there are security concerns. Users who run NoScript or disable JavaScript will browse your website, and if it doesn't function without JavaScript, you lose a significant portion of your potential audience. It’s important to recognize that creating something effective without JavaScript can feel like duplicating your work, especially if you are writing AJAX controllers.
00:02:41.120
However, the goal of NinjaScript is to make this easier for you. The third goal of NinjaScript is to provide persistent behavior. This concept may be less obvious. We're used to how JavaScript works, but we often overlook that JavaScript does not provide persistent behavior. The metaphor I like is that CSS is fantastic, but JavaScript has its limitations.
00:03:06.159
In CSS, you use selectors to apply styles, and these styles consistently apply to the DOM nodes that meet the selectors' criteria. If you change your DOM, for example, by having a certain class with a yellow background, any new element added with that class will keep that background as yellow. Unfortunately, JavaScript doesn't operate this way because it has state.
00:03:18.640
Let’s imagine you have a DOM structure with a div containing the id 'content' and two links with the 'tooltip' class. If you use a little jQuery code to assign behaviors to those elements, you can enhance them. But if another widget comes along later and adds another element with '.tooltip', it won't have your bound event handlers, leading to inconsistent behavior in your app. This inconsistency is frustrating and stems from when JavaScript initially binds these behaviors.
00:03:40.880
Now, many of you might be thinking we could use event delegation. jQuery provides the live method, which allows us to bind handlers to the root of the DOM instead of individual elements. As unhandled events bubble up, they reach the root, which can handle all events. This is indeed a useful feature.
00:03:51.840
Unfortunately, event delegation struggles with transformations of elements that are dynamically added to the page. For instance, you may want to make all your divs of a certain class have rounded corners by adding new structure to the HTML. However, if the div meant to get rounded corners is added late in the process, there won't be an event to trigger that behavior.
00:04:11.120
We should be able to catch this with event delegation, as DOM Level 2 specifies mutation events for things like subtree modifications. However, Internet Explorer never implemented these events. As a result, DOM Level 3 has deprecated these events, which is a frustrating situation, especially since they have not provided replacements.
00:04:40.800
Consequently, we have employed a different approach known as automatic rebinding. Instead of binding directly to elements at initialization, we examine the DOM continuously to identify new elements to which our behaviors should bind.
00:05:04.320
We utilize deprecated events where applicable, and also implement other approaches like firing our own events in browsers that require additional help. This method works most effectively.
00:05:14.560
So how do you use NinjaScript? We aim to simplify your experience compared to the typical complexities associated with JavaScript. We define something resembling a CSS sheet, which we call a behavior sheet.
00:05:45.440
In your application.js file within your Rails project, you will notice some code that opens a behavior block, identifies CSS selectors, and specifies relevant behaviors. These behaviors are predefined in NinjaScript. For example, you can take a form with the id 'product' and convert it into an AJAX form with no additional HTML required.
00:06:21.440
Similarly, you can apply behavior to links and form inputs, such as watermarking them or setting sections of the page to disappear after a specified time period. Although we don’t currently have a tooltip behavior ready, it is in the works.
00:06:29.120
In addition to predefined behaviors, you can define your own. Following the selector in your behavior definitions allows you to create a behavior object, so that any new element with the class '.awesome' added to the page, regardless of timing, will have this behavior applied.
00:06:38.480
You can also define event handlers that will be applied to these '.awesome' elements, such as click handlers and mouseover handlers. This is great because NinjaScript’s internal structure means you won’t need to worry about when elements are added to the page.
00:06:51.120
Any behaviors will take effect for elements already on the page when the JavaScript loads, and likewise, they will also apply to any elements added afterwards.
00:07:01.919
We also provide shortcuts for convenience. In many cases where you have just a single event handler, you can simply specify the event directly after your selector, like '.awesome click'.
00:07:18.560
You can define your own reusable behaviors similar to how we have prepackaged behaviors, such as turning form submissions into AJAX requests. This involves wrapping code in boilerplate, which can be found in the documentation, allowing you to define a function that returns a Ninja behavior.
00:07:26.560
This behavior will manage transformations, clicks, mouseovers, and so on. Once defined, you can reuse this behavior freely throughout your application.
00:07:38.240
We aim to simplify the experience for developers, allowing you to focus on building your applications without worrying about the intricacies of JavaScript workflows.
00:08:05.440
Here are some of the predefined behaviors we currently have available: 'submits as AJAX', which converts existing forms and links into AJAX-compatible versions. This behavior retains all defaults for graceful degradation. If you create a form that functions properly, you can later adjust it to also work as an AJAX form.
00:08:29.040
You can also convert forms into links. This is particularly useful for situations like deleting a resource in a Rails application, or executing non-GET methods. By writing a form with a delete button, 'run becomes link' converts it into a link that still performs as expected.
00:08:37.920
We also have decay behaviors that fade elements away after a specified period, and you can customize the time it takes for that decay. Additionally, 'is watermarked' converts forms with labels into watermarked inputs where the label text acts as placeholder text.
00:09:09.680
Turning off JavaScript still allows an effective experience, as non-JavaScript users see the label and can understand the text field. When JavaScript is enabled, the label disappears, leaving only the text in the input field.
00:09:34.560
We have additional behaviors planned for future versions of NinjaScript. However, it’s important to note that NinjaScript currently depends on jQuery version 1.4.2. There are technical reasons for this, which I can discuss during the Q&A if you have concerns. This means that it does not support more current versions of jQuery, but a fix is on its way.
00:09:49.760
Our future plans involve completing the prepackaged behaviors and decoupling NinjaScript entirely from jQuery. Currently, NinjaScript functions as a jQuery plug-in, but in the upcoming major version, it will operate as its own environment. You’ll be able to write behaviors in MooTools, Prototype, or any framework you prefer while utilizing either Ninja’s or jQuery’s persistence framework.
00:10:04.480
For now, it handles all AJAX calls by defaulting to Rails' return formats, but we plan to establish frameworks that enable you to write AJAX behaviors returning data in JSON or even XML formats, aligning with NinjaScript’s AJAX processor.
00:10:33.200
Judson has dedicated significant effort to this project, and while it may seem straightforward from the outside, the internal complexities are quite intricate. For instance, what occurs when multiple behaviors affect the same DOM object? Judson has established sensible defaults and configuration options to manage behaviors' execution order.
00:10:48.280
Moving on to the second half, we discuss Mizugumo. Mizugumo is a gem designed to assist you in using NinjaScript within your Rails applications, enhancing them to work seamlessly with AJAX and JavaScript behaviors. After installing Mizugumo, you run a generator, which sets up an application that is AJAX-friendly by default.
00:11:13.360
Mizugumo addresses what I refer to as the 'Rails 3 REST fail.' We know that REST works in Rails by simulating PUT and DELETE methods since browsers only support GET and POST. This is achieved by adding a hidden variable to forms that indicates the intended method.
00:11:22.560
Similarly, Rails allows specifying methods in links by adding a data-method attribute using Rails' JavaScript. However, if JavaScript is disabled, this results in linking that acts like a show link, failing the intended delete action and creating a frustrating experience.
00:11:38.960
Mizugumo solves this by transforming the link into a form if you specify a method argument. It generates a button with the labeled action, like 'delete this item.' If you haven’t passed a method, Mizugumo defaults to using the standard Rails helper.
00:11:51.360
Additionally, there’s a default NinjaScript behavior included in your application.js, looking for this specific class to convert it into a link. This means JavaScript users see a link, while non-JavaScript users see a button, ensuring full functionality without requiring additional developer effort.
00:12:05.200
Now, as with AJAX, creating forms in Mizugumo requires no additional markup. You can create forms, combine them with data, and specify methods without having to declare them as remote. You simply need to implement a respond-to block in your controller with a corresponding js.erb view.
00:12:14.080
Fortunately, Mizugumo includes scaffolding support to handle this efficiently. Let’s look at a demonstration.
00:12:19.920
I'm going to generate a new Rails project here, although I can't see it on the screen in front of me.
00:12:27.600
Let's proceed with creating a scaffold. We'll work with recipes, including attributes like name, cook time, and instructions. This is just a typical scaffold generation—nothing different from the usual process.
00:12:51.520
After generating the scaffold, we’ll migrate the database and launch the server to see how it functions. Yet, I want to add an extra touch, so we can observe how it operates with AJAX.
00:13:04.640
Let’s open the newly created index file, and I’ll insert a timestamp at the top of the page, so we can track when it loads.
00:13:12.640
Watch the last two digits here.
00:13:28.480
With JavaScript enabled, we can seamlessly create new entries and modify the page without needing to reload. The application will respond to user actions, all done dynamically here.
00:13:38.960
Notice the delete operation; even with JavaScript disabled, the application continues to function, albeit with complete page reloads.
00:13:45.120
Turning off JavaScript shows we receive the familiar button interface without losing functionality. This allows for graceful degradation.
00:14:00.160
Yet, let’s explore a few additional features that Mizugumo and NinjaScript bring to the table. This demo showcases a variety of behaviors we've incorporated into our application.
00:14:15.440
We’ve implemented sensible defaults across NinjaScript functionalities. For example, with AJAX requests, users typically receive little indication of processing, meaning you would need to implement your own spinner or loading indicator.
00:14:34.560
Hence, we modified the 'submits as AJAX' behavior to automatically apply a spinner overlay when a request is being handled. It takes very little effort to customize the placement of the spinner, and by default, it overlays above the form.
00:14:44.640
During testing, I’ll simulate longer server responses, just as you might observe in real-world applications. I’ll showcase how easily it handles these interactions.
00:15:00.640
What’s interesting is how the system responds to async behavior while maintaining clear readable indicators to users.
00:15:06.480
The above behavior greatly enhances user experience during potentially long operations.
00:15:12.879
Moreover, we have confirmation behaviors that allow users to receive deletion prompts before proceeding to remove an item. This integrates straightforwardly within the default action states, ensuring transparency in the process.
00:15:21.200
Therefore, even if JavaScript is disabled, users still receive graceful, intuitive interactions through straightforward forms.
00:15:44.920
In the future, we anticipate enhancements to completely replace Rails.js with a bespoke NinjaScript version of the default Rails behaviors—allowing development with only one JavaScript engine.
00:15:58.080
Also, we intend to refine our scaffolding generators, enabling them to produce tests or specifications right from the outset. This will ensure both AJAX and non-AJAX behaviors are adequately updated.
00:16:06.880
Our aim for user-confirmed actions like deletions is to foster prevention strategies while preserving the existing structure and functionalities.
00:16:15.460
Furthermore, we are focused on automatic JavaScript validations to align with Rails validations, ensuring no invalid input can be submitted without alarming the users.
00:16:23.040
Contributions are always welcome, as this is an open-source project. We encourage you to follow our progress on GitHub and to assist us in improving NinjaScript.
00:16:30.320
Do you have any questions?