NinjaScript and Mizugumo 2011-02-05

1,038 views
920 views

Published on

NinjaScript is a javascript framework for enriching web applications with unobtrusive, persistent JavaScript behavior.

Mizugumo is a ruby gem to making completely gracefully-degrading Rails applications. It uses the NinjaScript framework for rich behavior and integrates it tightly with Rails.

This presentation was given to LA RubyConf on February 5, 2011.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,038
On SlideShare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • NinjaScript and Mizugumo 2011-02-05

    1. 1. NinjaScriptJavaScript so unobtrusive, you’ll never see it coming. MizugumoMake your Rails app walk on water with NinjaScript.
    2. 2. Evan DornCEO and Lead Developer, Logical Reality Design
    3. 3. CreditsNinjaScript was invented and (almost) entirely coded by Judson Lester Co-owner and Senior Developer
    4. 4. NinjaScript
    5. 5. GOAL 1:CompletelyUnobtrusive
    6. 6. No<HTML> MarkupRequired
    7. 7. GOAL 2:Graceful Degradation
    8. 8. JavaScriptenrichesa fully functional website
    9. 9. Your site should work without JavaScript!
    10. 10. Why do I care?• Spiders & Automation• Accessibility: screen readers• NoScript users
    11. 11. Graceful degradation is a ROYAL PAIN
    12. 12. (Unless you use NinjaScript)
    13. 13. GOAL 3:Persistent Behavior
    14. 14. CSS: is_awesome$(JavaScript){ SUCKS }
    15. 15. JS should be like CSS•CSS styles always apply• Even if the DOM changes• Why aren’t JS behaviors the same?
    16. 16. DOM Reconstruction and Event Bindings
    17. 17. DOM Reconstruction and Event Bindings div#content a.has_tooltip a.has_tooltip
    18. 18. DOM Reconstruction and Event Bindings• Bind a tooltip behavior div#content to $(‘.has_tooltip’) a.has_tooltip a.has_tooltip
    19. 19. DOM Reconstruction and Event Bindings• Bind a tooltip behavior div#content to $(‘.has_tooltip’)• Dynamically add a new .tooltip element a.has_tooltip a.has_tooltip a.has_tooltip
    20. 20. DOM Reconstruction and Event Bindings• Bind a tooltip behavior div#content to $(‘.has_tooltip’)• Dynamically add a new .tooltip element a.has_tooltip a.has_tooltip• New element has no bound event handler! a.has_tooltip
    21. 21. DOM Reconstruction and Event Bindings• Bind a tooltip behavior div#content to $(‘.has_tooltip’)• Dynamically add a new .tooltip element a.has_tooltip a.has_tooltip• New element has no bound event handler! a.has_tooltip• This is really lame ...
    22. 22. What we want
    23. 23. What we want• Specify JS behaviors via CSS selectors
    24. 24. What we want• Specify JS behaviors via CSS selectors• Behaviors should always apply
    25. 25. What we want• Specify JS behaviors via CSS selectors• Behaviors should always apply• Easy for the developer
    26. 26. Solution 1:Event Delegation
    27. 27. Solution 1: Event Delegation• jQuery live() and similar
    28. 28. Solution 1: Event Delegation• jQuery live() and similar• Bind handlers to root element of the DOM
    29. 29. Solution 1: Event Delegation• jQuery live() and similar• Bind handlers to root element of the DOM• Since browsers bubble unhandled events up the DOM, the root handles all events
    30. 30. Solution 1: Event Delegation• jQuery live() and similar• Bind handlers to root element of the DOM• Since browsers bubble unhandled events up the DOM, the root handles all events This is pretty awesome.
    31. 31. The Problem withEvent Delegation
    32. 32. The Problem with Event Delegation• live() can’t handle element transformations
    33. 33. The Problem with Event Delegation• live() can’t handle element transformations• ... like giving <div>s rounded corners ...
    34. 34. The Problem with Event Delegation• live() can’t handle element transformations• ... like giving <div>s rounded corners ...• Because there’s no event to process when we insert new elements into the DOM
    35. 35. The Problem with Event Delegation• live() can’t handle element transformations• ... like giving <div>s rounded corners ...• Because there’s no event to process when we insert new elements into the DOM• DOM Level 2-compliant browsers are suppossed to send DOMSubtreeModified and DOMNodeInserted
    36. 36. The Problem with Event Delegation• live() can’t handle element transformations• ... like giving <div>s rounded corners ...• Because there’s no event to process when we insert new elements into the DOM• DOM Level 2-compliant browsers are suppossed to send DOMSubtreeModified and DOMNodeInserted ... bad IE. No Biscuit!
    37. 37. Solution 1I:Automatic Rebinding
    38. 38. Solution 1I: Automatic Rebinding• Bind to and/or transform the element, not the root.
    39. 39. Solution 1I: Automatic Rebinding• Bind to and/or transform the element, not the root.• NinjaScript examines new DOM elements to see if any known behaviors match.
    40. 40. Solution 1I: Automatic Rebinding• Bind to and/or transform the element, not the root.• NinjaScript examines new DOM elements to see if any known behaviors match.• NinjaScript fires its own event when the DOM is reconstructed so it works in IE.
    41. 41. So how do I use it?
    42. 42. NinjaScript“Behavior Sheet”
    43. 43. NinjaScript “Behavior Sheet”Ninja.behavior({ form#product: submitsAsAjax, ‘a.delete_product’: submitsAsAjax, ‘#login_form input’: isWatermarked, ‘flash.error’: decays, ‘li.has_tooltip’: showsTooltip})
    44. 44. Defining a BehaviorNinja.behavior({ .awesome: { transform: function(elem){... add to the DOM ...}, events: { click: function(event){... handle click ...}, mouseover: function(event){... pop tooltip ...} } }}) All awesome elements will get the transform applied, no matter when they’re added.
    45. 45. Defining a BehaviorShortcut: skip the ‘events:’ mapping if you’rejust handling an event.Ninja.behavior({ .awesome: { click: function(event){ ... handle click ...}, }})
    46. 46. Reusable BehaviorsYou can easily define and name behaviors forreuse.
    47. 47. Reusable BehaviorsYou can easily define and name behaviors forreuse. singsAndDances(){function return new ninja.does({ transform: function(elem) { elem.addATutu() }, click: function(event) { this.element.pirouette() }, mouseover: function(event) { this.element.singAnAria()} })}
    48. 48. Reusable BehaviorsYou can easily define and name behaviors forreuse. singsAndDances(){function return new ninja.does({ transform: function(elem) { elem.addATutu() }, click: function(event) { this.element.pirouette() }, mouseover: function(event) { this.element.singAnAria()} })}Ninja.behavior({ ‘#dhh’: Ninja.singsAndDances(), ‘#katz’: Ninja.singsAndDances(), ‘.code_monkey’: Ninja.singsAndDances()})
    49. 49. Pre-Defined BehaviorsThese work today - built into NinjaScript• submitsAsAjax (for forms or links)• becomesLink (for forms)• decays (fades away after 10 sec)• isWatermarked (for form inputs)
    50. 50. Planned Behaviors Coming Sometime!• popsTooltip • getsRoundCorners• validatesLocal • getsDropShadow• validatesViaAjax • replacedByImage• autocompletes • isSortable• hasAjaxObserver • isSortableViaAjax• editableViaAjax
    51. 51. CAVEAT!
    52. 52. CAVEAT! NinjaScript 0.8.x depends on jQuery-1.4.2DOES NOT SUPPORT jQuery-1.4.4 or jQuery-1.5
    53. 53. CAVEAT! NinjaScript 0.8.x depends on jQuery-1.4.2DOES NOT SUPPORT jQuery-1.4.4 or jQuery-1.5 (... fix is coming)
    54. 54. Future Plans for NinjaScript
    55. 55. Future Plans for NinjaScript• Lots more prepackaged behaviors
    56. 56. Future Plans for NinjaScript• Lots more prepackaged behaviors• Decouple from jQuery - build NinjaScript behaviors in any framework
    57. 57. Future Plans for NinjaScript• Lots more prepackaged behaviors• Decouple from jQuery - build NinjaScript behaviors in any framework• Handle JSON returns from AJAX calls, not just eval()
    58. 58. The internals are “complicated”.
    59. 59. The internals are “complicated”.But Judson is a ninja rockstar,
    60. 60. The internals are “complicated”.But Judson is a ninja rockstar, 4th dan.
    61. 61. MizugumoLet your Rails app walk on water with NinjaScript
    62. 62. gem install mizugumo
    63. 63. rails generatemizugumo:install
    64. 64. A Mizugumo app is:
    65. 65. A Mizugumo app is:• AJAX by default
    66. 66. A Mizugumo app is:•AJAX by default• Degrades gracefully by default
    67. 67. A Mizugumo app is:•AJAX by default• Degrades gracefully by default• No extra work!
    68. 68. The Rails 3 RESTfail
    69. 69. The Rails 3 RESTfail
    70. 70. The Rails 3 RESTfail• Simulate PUT and DELETE methods!
    71. 71. The Rails 3 RESTfail• Simulate PUT and DELETE methods!• link_to(:method => ‘delete’)
    72. 72. The Rails 3 RESTfail• Simulate PUT and DELETE methods!• link_to(:method => ‘delete’)• <a href=’/product/1’ data- method=‘delete‘>
    73. 73. The Rails 3 RESTfail• Simulate PUT and DELETE methods!• link_to(:method => ‘delete’)• <a href=’/product/1’ data- method=‘delete‘>• Without JS, it’s a show link!
    74. 74. The Rails 3 RESTfail• Simulate PUT and DELETE methods!• link_to(:method => ‘delete’)• <a href=’/product/1’ data- method=‘delete‘>• Without JS, it’s a show link!• ... oops!
    75. 75. The Mizugumo Way
    76. 76. The Mizugumo Waylink_to with :method => ‘delete’<%= link_to ‘click me’, ‘/foo’, :method => :delete %>
    77. 77. The Mizugumo Waylink_to with :method => ‘delete’<%= link_to ‘click me’, ‘/foo’, :method => :delete %>Generates a <form>!<form action=’/foo’ method=‘post’ class=‘mizugumo_graceful_form’> <input type=‘hidden’ name=‘_method’ value=‘delete’> <input type=‘submit’ value=’click me’></a>
    78. 78. The Mizugumo WayBut a default NinjaScript behavior:Ninja.behavior({ ‘.mizugumo_graceful_form’: becomesLink})
    79. 79. The Mizugumo WayBut a default NinjaScript behavior:Ninja.behavior({ ‘.mizugumo_graceful_form’: becomesLink})Converts it back!<a href=’/foo’>click me</a>
    80. 80. The Result
    81. 81. The Result• JavaScript users see a link
    82. 82. The Result•JavaScript users see a link• Non-JS users see a button
    83. 83. The Result•JavaScript users see a link• Non-JS users see a button• DELETE action works for both
    84. 84. The Result•JavaScript users see a link• Non-JS users see a button• DELETE action works for both
    85. 85. The Result•JavaScript users see a link• Non-JS users see a button• DELETE action works for both• ...Rails developer does nothing!
    86. 86. What about AJAX?
    87. 87. No need for markup:
    88. 88. No need for markup:Not this.<%= form_for(@product, :remote => true) do %>
    89. 89. No need for markup:Not this.<%= form_for(@product, :remote => true) do %>Just this:<%= form_for(@product) do %>
    90. 90. Use NinjaScript!Ninja.behavior({ ‘#my_form’: submitsAsAjax})
    91. 91. Ninja.submitsAsAjax
    92. 92. Ninja.submitsAsAjax• Same Data• Same URL• Same Method• Just write a format.js block in your controller, and a js.erb view.
    93. 93. The Mizugumoscaffold does this for you.
    94. 94. (demo)
    95. 95. Future Plans for Mizugumo
    96. 96. Future Plans for Mizugumo• Replace rails.js
    97. 97. Future Plans for Mizugumo•Replace rails.js• Improve generators
    98. 98. Future Plans for Mizugumo•Replace rails.js• Improve generators• Degradable :confirm
    99. 99. Future Plans for Mizugumo•Replace rails.js• Improve generators• Degradable :confirm• Automatic JS validations!
    100. 100. Please Contribute!
    101. 101. http://bit.ly/hFzoAG

    ×