Modular Applications
                       with Montage Components



                          Benoît Marchant



benoit@montagejs.org                             montagejs.org
TEAM CSS
         data-binding
                                                                 property change

       HTML5
                           workflow



template
                              serialization


           reusable                                       simplify                                  listener


                         component
separation of concerns   encapsulated                                                                            event

                                                                                                       MVC
                                          declarative


                                                                                                        framework

    BSD CommonJS
                                    composition
                                                        deferred drawing                textfield loader       substitution


                                                                                           widgets
                                                                                    toggle flow         repetition condition



modules
promises                                                                           radio                                button
                                                                                                                        slider
                                              applications
                                                                                     video
                                                                                                             progress text
                                                                                        checkbox slot



                                                                    mobile
                                                                                                   audio list input


          ECMAScript 5
package                            write once                        cpu gpu battery

                                                cross-platform
Mobile Applications
HTML5 vs Native
HTML5 vs Native

      Janky User Experience
HTML5 vs Native

      Janky User Experience

      Longer Development Time
HTML5 vs Native

      Janky User Experience

      Longer Development Time

      Higher Development Cost
HTML5 vs Native

      Janky User Experience

      Longer Development Time

      Higher Development Cost

      Harder to Iterate
Modular Applications
Simple Application
Large Application
Large Application
Montage Application




Refactor
Montage Application




Refactor
Popcorn Demo

montagejs.org/apps/popcorn/
Component

   Assigned one DOM Element
   MVC Structure
   From Widget to App Specific
   Deferred Drawing
   Template
Deferred Drawing

      Maximize Performance
      Orchestrate DOM Changes
      Third Party Components
      Degrade Gracefully
      willDraw() / draw() / didDraw()
Template

                Full HTML5 document
HTML JS CSS
                Resource Encapsulation

.reel           Object Serialization
                Great JS / CSS Team Work
                Automatic Dependencies Load
Identify Components
Main Component
       Loads data from Web Service
Relies on sub-components for presentation
Navigation




Movie Content
Movie Categories

Main                                         Navigation
               Event to change CategoryId




Selected CategoryId




    Components                              Movie Content
 establish their own
 API to accept data
 through properties
     or methods
Movie Categories

Main
               Event to change CategoryId




Selected CategoryId
Movie Categories

Main
               Event to change CategoryId




Selected CategoryId
Movie Content
Movie Content



           Flow Component




        Movie Detail Component
Movie Content   moviesController



           Flow Component


                        selectedMovie




        Movie Detail Component
Main.reel/Main.html
<html>
...
<body>
    <div data-montage-id="facade-flow" class="facade-flow">
        <div data-montage-id="flow" class="flow flow-fade-out">
            <div data-montage-id="image" class="Image"></div>
        </div>
        <div class="film"></div>
        <div data-montage-id="details"></div>
    </div>
</body>
</html>
Markup
   <div data-montage-id="facade-flow" class="facade-flow">
       <div data-montage-id="flow" class="flow flow-fade-out">
           <div data-montage-id="image" class="Image"></div>
       </div>
       <div class="film"></div>
       <div data-montage-id="details"></div>
   </div>




                  Object Serialization
<script type="text/montage-serialization">
{
    "owner": {
        "properties": {
            "element": {"#": "facade-flow"}
        }
    },

    ...
<div data-montage-id="facade-flow" class="facade-flow">
       <div data-montage-id="flow" class="flow flow-fade-out">
           <div data-montage-id="image" class="Image"></div>
       </div>
       <div class="film"></div>
       <div data-montage-id="details"></div>
   </div>




<script type="text/montage-serialization">
{
    "owner": {
        "properties": {
            "element": {"#": "facade-flow"}
        }
    },

    ...
<div data-montage-id="facade-flow" class="facade-flow">
     <div data-montage-id="flow" class="flow flow-fade-out">
         <div data-montage-id="image" class="Image"></div>
     </div>
     <div class="film"></div>
     <div data-montage-id="details"></div>
 </div>




"flow": {
    "prototype": "montage/ui/flow.reel",      Module Id
    "properties": {
        "element": {"#": "flow"},
        "cameraFov": 36.99,
        "cameraTargetPoint": [0, 0, 0],
        "stride": 1
    },
    "bindings": {
        "contentController": {"<-": "@owner.moviesController"}
    }
},
<div data-montage-id="facade-flow" class="facade-flow">
     <div data-montage-id="flow" class="flow flow-fade-out">
         <div data-montage-id="image" class="Image"></div>
     </div>
     <div class="film"></div>
     <div data-montage-id="details"></div>
 </div>




"flow": {
    "prototype": "montage/ui/flow.reel",
    "properties": {
        "element": {"#": "flow"},
        "cameraFov": 36.99,                       Setting
        "cameraTargetPoint": [0, 0, 0],
        "stride": 1
                                              Property Values
    },
    "bindings": {
        "contentController": {"<-": "@owner.moviesController"}
    }
},
<div data-montage-id="facade-flow" class="facade-flow">
     <div data-montage-id="flow" class="flow flow-fade-out">
         <div data-montage-id="image" class="Image"></div>
     </div>
     <div class="film"></div>
     <div data-montage-id="details"></div>
 </div>




"flow": {
    "prototype": "montage/ui/flow.reel",
    "properties": {
        "element": {"#": "flow"},
        "cameraFov": 36.99,                   data binding
        "cameraTargetPoint": [0, 0, 0],
        "stride": 1
    },
    "bindings": {
        "contentController": {"<-": "@owner.moviesController"}
    }
},
<div data-montage-id="facade-flow" class="facade-flow">
     <div data-montage-id="flow" class="flow flow-fade-out">
         <div data-montage-id="image" class="Image"></div>
     </div>
     <div class="film"></div>
     <div data-montage-id="details"></div>
 </div>




"details": {
    "prototype": "ui/details.reel",
    "properties": {
        "element": {"#": "details"}
    },
    "bindings": {
        "data": {"<-": "@owner.selectedMovie" }
    }
},
Movie Detail
Movie Detail



                   Title
 Release Date   Runtime    Audience   Critics

                                                Trailer Button

                Synopsis                        Rent Button
Movie Detail Components



               DynamicText
 DynamicText   DynamicText   Dynamic Text   Dynamic Text

                                                           Button

               DynamicText                                 Button
Movie Detail
                                                        Title
                       data.title

                                     data.criticScore
data.date
                                                  Critics
             data.runtime
                                    data.audienceScore                  actionEvent
      Date          Runtime               Audience
                                                            Trailer Button
  data.synopsis

                                                                        actionEvent


                  Description                                Rent Button
action event


Trailer Button
<button data-montage-id="trailer-button">Trailer</button>




"trailerButton": {
    "prototype": "montage/ui/button.reel",
    "properties": {
        "element": {"#": "trailer-button"}
    },
    "listeners": [
        {
            "type": "action",
            "listener": {"@": "owner"}       Listeners
        }
    ]
},
<button data-montage-id="trailer-button">Trailer</button>




"trailerButton": {
    "prototype": "montage/ui/button.reel",
    "properties": {
        "element": {"#": "trailer-button"}
    },
    "listeners": [
        {
            "type": "action",
            "listener": {"@": "owner"}
                                              Object
        }                                    Reference
    ]
},
"trailerButton": {
    "prototype": "montage/ui/button.reel",
    "properties": {
        "element": {"#": "trailer-button"}
    },
    "listeners": [
        {
            "type": "action",
            "listener": {"@": "owner"}
        }
    ]
},




                       handleTrailerButtonAction: {
       Owner              value: function(event) {
                            ...
 EventHandling           }
       Method          }
                       handleAction
   Precedence
                       handleEvent
Mop it!
Modular Applications

        Encapsulated Components
        HTML5 Templates
        Scale Larger Team/Projects
        Shorter Development Time
        Easier to Refactor
Q&A
Fo
                                                   rk
                                                    me
                                                       on
                                                        Gi
                                                         tH
                                                            ub
                   A modern HTML5 framework




benoit@montagejs.org     Benoît Marchant      montagejs.org

Modular applications with montage components

  • 1.
    Modular Applications with Montage Components Benoît Marchant benoit@montagejs.org montagejs.org
  • 3.
    TEAM CSS data-binding property change HTML5 workflow template serialization reusable simplify listener component separation of concerns encapsulated event MVC declarative framework BSD CommonJS composition deferred drawing textfield loader substitution widgets toggle flow repetition condition modules promises radio button slider applications video progress text checkbox slot mobile audio list input ECMAScript 5 package write once cpu gpu battery cross-platform
  • 4.
  • 7.
  • 8.
    HTML5 vs Native Janky User Experience
  • 9.
    HTML5 vs Native Janky User Experience Longer Development Time
  • 10.
    HTML5 vs Native Janky User Experience Longer Development Time Higher Development Cost
  • 11.
    HTML5 vs Native Janky User Experience Longer Development Time Higher Development Cost Harder to Iterate
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
    Component Assigned one DOM Element MVC Structure From Widget to App Specific Deferred Drawing Template
  • 20.
    Deferred Drawing Maximize Performance Orchestrate DOM Changes Third Party Components Degrade Gracefully willDraw() / draw() / didDraw()
  • 21.
    Template Full HTML5 document HTML JS CSS Resource Encapsulation .reel Object Serialization Great JS / CSS Team Work Automatic Dependencies Load
  • 23.
  • 24.
    Main Component Loads data from Web Service Relies on sub-components for presentation
  • 25.
  • 26.
    Movie Categories Main Navigation Event to change CategoryId Selected CategoryId Components Movie Content establish their own API to accept data through properties or methods
  • 27.
    Movie Categories Main Event to change CategoryId Selected CategoryId
  • 28.
    Movie Categories Main Event to change CategoryId Selected CategoryId
  • 29.
  • 30.
    Movie Content Flow Component Movie Detail Component
  • 31.
    Movie Content moviesController Flow Component selectedMovie Movie Detail Component
  • 32.
    Main.reel/Main.html <html> ... <body> <div data-montage-id="facade-flow" class="facade-flow"> <div data-montage-id="flow" class="flow flow-fade-out"> <div data-montage-id="image" class="Image"></div> </div> <div class="film"></div> <div data-montage-id="details"></div> </div> </body> </html>
  • 33.
    Markup <div data-montage-id="facade-flow" class="facade-flow"> <div data-montage-id="flow" class="flow flow-fade-out"> <div data-montage-id="image" class="Image"></div> </div> <div class="film"></div> <div data-montage-id="details"></div> </div> Object Serialization <script type="text/montage-serialization"> { "owner": { "properties": { "element": {"#": "facade-flow"} } }, ...
  • 34.
    <div data-montage-id="facade-flow" class="facade-flow"> <div data-montage-id="flow" class="flow flow-fade-out"> <div data-montage-id="image" class="Image"></div> </div> <div class="film"></div> <div data-montage-id="details"></div> </div> <script type="text/montage-serialization"> { "owner": { "properties": { "element": {"#": "facade-flow"} } }, ...
  • 35.
    <div data-montage-id="facade-flow" class="facade-flow"> <div data-montage-id="flow" class="flow flow-fade-out"> <div data-montage-id="image" class="Image"></div> </div> <div class="film"></div> <div data-montage-id="details"></div> </div> "flow": { "prototype": "montage/ui/flow.reel", Module Id "properties": { "element": {"#": "flow"}, "cameraFov": 36.99, "cameraTargetPoint": [0, 0, 0], "stride": 1 }, "bindings": { "contentController": {"<-": "@owner.moviesController"} } },
  • 36.
    <div data-montage-id="facade-flow" class="facade-flow"> <div data-montage-id="flow" class="flow flow-fade-out"> <div data-montage-id="image" class="Image"></div> </div> <div class="film"></div> <div data-montage-id="details"></div> </div> "flow": { "prototype": "montage/ui/flow.reel", "properties": { "element": {"#": "flow"}, "cameraFov": 36.99, Setting "cameraTargetPoint": [0, 0, 0], "stride": 1 Property Values }, "bindings": { "contentController": {"<-": "@owner.moviesController"} } },
  • 37.
    <div data-montage-id="facade-flow" class="facade-flow"> <div data-montage-id="flow" class="flow flow-fade-out"> <div data-montage-id="image" class="Image"></div> </div> <div class="film"></div> <div data-montage-id="details"></div> </div> "flow": { "prototype": "montage/ui/flow.reel", "properties": { "element": {"#": "flow"}, "cameraFov": 36.99, data binding "cameraTargetPoint": [0, 0, 0], "stride": 1 }, "bindings": { "contentController": {"<-": "@owner.moviesController"} } },
  • 38.
    <div data-montage-id="facade-flow" class="facade-flow"> <div data-montage-id="flow" class="flow flow-fade-out"> <div data-montage-id="image" class="Image"></div> </div> <div class="film"></div> <div data-montage-id="details"></div> </div> "details": { "prototype": "ui/details.reel", "properties": { "element": {"#": "details"} }, "bindings": { "data": {"<-": "@owner.selectedMovie" } } },
  • 39.
  • 40.
    Movie Detail Title Release Date Runtime Audience Critics Trailer Button Synopsis Rent Button
  • 41.
    Movie Detail Components DynamicText DynamicText DynamicText Dynamic Text Dynamic Text Button DynamicText Button
  • 42.
    Movie Detail Title data.title data.criticScore data.date Critics data.runtime data.audienceScore actionEvent Date Runtime Audience Trailer Button data.synopsis actionEvent Description Rent Button
  • 43.
  • 44.
    <button data-montage-id="trailer-button">Trailer</button> "trailerButton": { "prototype": "montage/ui/button.reel", "properties": { "element": {"#": "trailer-button"} }, "listeners": [ { "type": "action", "listener": {"@": "owner"} Listeners } ] },
  • 45.
    <button data-montage-id="trailer-button">Trailer</button> "trailerButton": { "prototype": "montage/ui/button.reel", "properties": { "element": {"#": "trailer-button"} }, "listeners": [ { "type": "action", "listener": {"@": "owner"} Object } Reference ] },
  • 46.
    "trailerButton": { "prototype": "montage/ui/button.reel", "properties": { "element": {"#": "trailer-button"} }, "listeners": [ { "type": "action", "listener": {"@": "owner"} } ] }, handleTrailerButtonAction: { Owner value: function(event) { ... EventHandling } Method } handleAction Precedence handleEvent
  • 48.
  • 49.
    Modular Applications Encapsulated Components HTML5 Templates Scale Larger Team/Projects Shorter Development Time Easier to Refactor
  • 50.
  • 51.
    Fo rk me on Gi tH ub A modern HTML5 framework benoit@montagejs.org Benoît Marchant montagejs.org