chr 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/README.md +29 -255
 - data/app/assets/javascripts/chr/core/chr.coffee +1 -1
 - data/app/assets/javascripts/chr/core/item.coffee +3 -3
 - data/app/assets/javascripts/chr/core/list.coffee +7 -14
 - data/app/assets/javascripts/chr/core/module.coffee +23 -30
 - data/app/assets/javascripts/chr/core/view.coffee +5 -18
 - data/app/assets/javascripts/chr/vendor/redactor.fixedtoolbar.js +10 -13
 - data/app/assets/javascripts/input-redactor.coffee +5 -10
 - data/bower.json +1 -1
 - data/dist/chr.js +33 -135
 - data/dist/input-redactor.js +17 -16
 - data/docs/bootstrap.md +23 -0
 - data/docs/rails.md +255 -0
 - data/lib/chr/version.rb +1 -1
 - data/package.json +1 -1
 - metadata +3 -2
 - data/docs/bootstrap-data.md +0 -0
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: bc38de2cb0b82aa71968cd48127d83146daa2bfd
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 9a373db5e5f9d4e1ce08ef020b8691b4b3c5d473
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: b13c5bdb285b264cd540f236b6c55aa8c5671c66122798a5c1f840b8055d18c1a775d60c7fb9305c10cb3e8e06d20c616ae1fe6d296739c198418929bf1f06ca
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 8223dd3c23d34d4da1cfbba9d22f7089e5ebe201a26ad6e58f6d08d482803c0613e794607f348a1e0ba7ef8dd587ce9e680bb6ce16ab1db72992f4920ea2dce3
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -3,283 +3,53 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            *Powerful responsive javascript CMS for apps.*
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
            ##  
     | 
| 
      
 6 
     | 
    
         
            +
            ## Quick Start
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
            #### Gems
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
            Add to following gems to ```Gemfile```:
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                gem "devise"
         
     | 
| 
       16 
     | 
    
         
            -
                gem "mongosteen"
         
     | 
| 
       17 
     | 
    
         
            -
                gem "chr"
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
            This example uses ```devise``` for admins authentication.
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
            #### Admin authentication
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
            Start with running [devise](https://github.com/plataformatec/devise) generator:
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                rails generate devise:install
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
            Setup ```Admin``` model with devise generator:
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                rails generate devise admin
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
            Here is an example of basic ```app/models/admin.rb``` model that provides email/password authentication:
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       35 
     | 
    
         
            -
            class Admin
         
     | 
| 
       36 
     | 
    
         
            -
              include Mongoid::Document
         
     | 
| 
       37 
     | 
    
         
            -
              include Mongoid::Timestamps
         
     | 
| 
       38 
     | 
    
         
            -
              include Mongoid::SerializableId
         
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
              devise :database_authenticatable,
         
     | 
| 
       41 
     | 
    
         
            -
                     :rememberable,
         
     | 
| 
       42 
     | 
    
         
            -
                     :authentication_keys => [ :email ]
         
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
              ## Database authenticatable
         
     | 
| 
       45 
     | 
    
         
            -
              field :email,              type: String, default: ""
         
     | 
| 
       46 
     | 
    
         
            -
              field :encrypted_password, type: String, default: ""
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
              ## Rememberable
         
     | 
| 
       49 
     | 
    
         
            -
              field :remember_created_at, type: Time
         
     | 
| 
       50 
     | 
    
         
            -
            end
         
     | 
| 
       51 
     | 
    
         
            -
            ```
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
            When models are ready, setup controllers, views and configure routes.
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
            Base admin controller ```app/controllers/admin/base_controller.rb``` looks like this:
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       58 
     | 
    
         
            -
            class Admin::BaseController < ActionController::Base
         
     | 
| 
       59 
     | 
    
         
            -
              protect_from_forgery
         
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
              if Rails.env.production?
         
     | 
| 
       62 
     | 
    
         
            -
                before_action :authenticate_admin!
         
     | 
| 
       63 
     | 
    
         
            -
              end
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
              def index
         
     | 
| 
       66 
     | 
    
         
            -
                render '/admin/index', layout: 'admin'
         
     | 
| 
       67 
     | 
    
         
            -
              end
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
              def bootstrap_data
         
     | 
| 
       70 
     | 
    
         
            -
                render json: {}
         
     | 
| 
       71 
     | 
    
         
            -
              end
         
     | 
| 
       72 
     | 
    
         
            -
            end
         
     | 
| 
       73 
     | 
    
         
            -
            ```
         
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
            Notes on code above:
         
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
              1. Authentication is not required when running in development or testing environment;
         
     | 
| 
       78 
     | 
    
         
            -
              2. Need to setup ```index``` view and ```admin``` layout to render admin app;
         
     | 
| 
       79 
     | 
    
         
            -
              3. ```bootstrap_data``` is a placeholder for objects that might be required to be loaded when app starts.
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
            Devise would require a custom ```SessionController``` implementation in ```app/controllers/admin/devise_overrides/session_controller.rb```. ```SessionController``` sets ```admin``` layout to be used for devise views rendering and enables login by email (*looks like workaround*).
         
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       84 
     | 
    
         
            -
            class Admin::DeviseOverrides::SessionsController < Devise::SessionsController
         
     | 
| 
       85 
     | 
    
         
            -
              layout 'admin'
         
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
              protected
         
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
                def configure_permitted_parameters
         
     | 
| 
       90 
     | 
    
         
            -
                  devise_parameter_sanitizer.for(:sign_in) << :email
         
     | 
| 
       91 
     | 
    
         
            -
                end
         
     | 
| 
       92 
     | 
    
         
            -
            end
         
     | 
| 
       93 
     | 
    
         
            -
            ```
         
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
            Admin app layout ```app/views/layouts/admin.html.erb```:
         
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
     | 
    
         
            -
            ```erb
         
     | 
| 
       98 
     | 
    
         
            -
            <!doctype html>
         
     | 
| 
       99 
     | 
    
         
            -
            <html>
         
     | 
| 
       100 
     | 
    
         
            -
              <head>
         
     | 
| 
       101 
     | 
    
         
            -
                <meta charset="utf-8">
         
     | 
| 
       102 
     | 
    
         
            -
                <meta http-equiv="X-UA-Compatible" content="IE=edge">
         
     | 
| 
       103 
     | 
    
         
            -
                <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
         
     | 
| 
       104 
     | 
    
         
            -
                <meta name="apple-mobile-web-app-capable" content="yes">
         
     | 
| 
       105 
     | 
    
         
            -
                <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
         
     | 
| 
       106 
     | 
    
         
            -
                <title>Admin</title>
         
     | 
| 
       107 
     | 
    
         
            -
                <%= csrf_meta_tags %>
         
     | 
| 
       108 
     | 
    
         
            -
                <%= stylesheet_link_tag    :admin, media: "all" %>
         
     | 
| 
       109 
     | 
    
         
            -
                <%= javascript_include_tag :admin %>
         
     | 
| 
       110 
     | 
    
         
            -
              </head>
         
     | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
       112 
     | 
    
         
            -
              <%= yield %>
         
     | 
| 
       113 
     | 
    
         
            -
            </html>
         
     | 
| 
       114 
     | 
    
         
            -
            ```
         
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
       116 
     | 
    
         
            -
            Admin index view ```app/views/admin/index.html.erb```:
         
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
            ```erb
         
     | 
| 
       119 
     | 
    
         
            -
            <body class='loading'>
         
     | 
| 
       120 
     | 
    
         
            -
              <%= link_to 'Sign Out', destroy_admin_session_path, method: :delete, style: 'display:none;' %>
         
     | 
| 
       121 
     | 
    
         
            -
            </body>
         
     | 
| 
       122 
     | 
    
         
            -
            ```
         
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
            New session view for devise ```app/views/admin/devise_overrides/sessions/new.html.erb```:
         
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
            ```erb
         
     | 
| 
       127 
     | 
    
         
            -
            <body class='sign-in'>
         
     | 
| 
       128 
     | 
    
         
            -
              <h2>Sign In</h2>
         
     | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
       130 
     | 
    
         
            -
              <%= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
         
     | 
| 
       131 
     | 
    
         
            -
                <% if alert %>
         
     | 
| 
       132 
     | 
    
         
            -
                  <p class="error"><%= alert.gsub('username', 'email').gsub('or sign up', '') %></p>
         
     | 
| 
       133 
     | 
    
         
            -
                <% end %>
         
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
                <div class="form-inputs">
         
     | 
| 
       136 
     | 
    
         
            -
                  <%= f.input :email,    required: true, autofocus: true %>
         
     | 
| 
       137 
     | 
    
         
            -
                  <%= f.input :password, required: true %>
         
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
                  <%= f.input :remember_me, as: :boolean if devise_mapping.rememberable? %>
         
     | 
| 
       140 
     | 
    
         
            -
                </div>
         
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
                <div class="form-actions">
         
     | 
| 
       143 
     | 
    
         
            -
                  <%= f.button :submit, "Sign In" %>
         
     | 
| 
       144 
     | 
    
         
            -
                </div>
         
     | 
| 
       145 
     | 
    
         
            -
              <% end %>
         
     | 
| 
       146 
     | 
    
         
            -
            </body>
         
     | 
| 
       147 
     | 
    
         
            -
            ```
         
     | 
| 
       148 
     | 
    
         
            -
             
     | 
| 
       149 
     | 
    
         
            -
            Now connect admin and devise in ```config/routes.rb``` with:
         
     | 
| 
       150 
     | 
    
         
            -
             
     | 
| 
       151 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       152 
     | 
    
         
            -
            devise_for :admins, path: "admin", controllers: { sessions: "admin/devise_overrides/sessions" }
         
     | 
| 
       153 
     | 
    
         
            -
            namespace :admin do
         
     | 
| 
       154 
     | 
    
         
            -
              get '/'               => 'base#index'
         
     | 
| 
       155 
     | 
    
         
            -
              get '/bootstrap.json' => 'base#bootstrap_data'
         
     | 
| 
       156 
     | 
    
         
            -
            end
         
     | 
| 
       157 
     | 
    
         
            -
            ```
         
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
            #### Character setup
         
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
       162 
     | 
    
         
            -
            Three pieces to be configured here.
         
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
            **First**: create ```app/assets/javascripts/admin.coffee``` with empty ```modules``` configuration:
         
     | 
| 
      
 8 
     | 
    
         
            +
            Application setup:
         
     | 
| 
       165 
9 
     | 
    
         | 
| 
       166 
10 
     | 
    
         
             
            ```coffee
         
     | 
| 
       167 
11 
     | 
    
         
             
            #= require jquery
         
     | 
| 
       168 
     | 
    
         
            -
            #= require jquery_ujs
         
     | 
| 
       169 
12 
     | 
    
         
             
            #= require chr
         
     | 
| 
       170 
13 
     | 
    
         | 
| 
      
 14 
     | 
    
         
            +
            postsConfig = (data) ->
         
     | 
| 
      
 15 
     | 
    
         
            +
              itemTitleField: 'title'
         
     | 
| 
      
 16 
     | 
    
         
            +
              arrayStore: new RestArrayStore({
         
     | 
| 
      
 17 
     | 
    
         
            +
                resource: 'post'
         
     | 
| 
      
 18 
     | 
    
         
            +
                path:     '/admin/posts'
         
     | 
| 
      
 19 
     | 
    
         
            +
                sortBy:   'title'
         
     | 
| 
      
 20 
     | 
    
         
            +
              })
         
     | 
| 
      
 21 
     | 
    
         
            +
              formSchema:
         
     | 
| 
      
 22 
     | 
    
         
            +
                title { type: 'string' }
         
     | 
| 
      
 23 
     | 
    
         
            +
                body: { type: 'text' }
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
       171 
25 
     | 
    
         
             
            $ ->
         
     | 
| 
       172 
     | 
    
         
            -
               
     | 
| 
       173 
     | 
    
         
            -
                 
     | 
| 
       174 
     | 
    
         
            -
                   
     | 
| 
      
 26 
     | 
    
         
            +
              config =
         
     | 
| 
      
 27 
     | 
    
         
            +
                modules:
         
     | 
| 
      
 28 
     | 
    
         
            +
                  posts: postsConfig()
         
     | 
| 
       175 
29 
     | 
    
         | 
| 
       176 
     | 
    
         
            -
                $('body').removeClass('loading')
         
     | 
| 
       177 
30 
     | 
    
         
             
                chr.start(config)
         
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
       179 
     | 
    
         
            -
                # append signout button to the end of sidebar menu
         
     | 
| 
       180 
     | 
    
         
            -
                $('a[data-method=delete]').appendTo(".sidebar .menu").show()
         
     | 
| 
       181 
31 
     | 
    
         
             
            ```
         
     | 
| 
       182 
32 
     | 
    
         | 
| 
       183 
     | 
    
         
            -
             
     | 
| 
      
 33 
     | 
    
         
            +
            Styles setup:
         
     | 
| 
       184 
34 
     | 
    
         | 
| 
       185 
35 
     | 
    
         
             
            ```scss
         
     | 
| 
       186 
     | 
    
         
            -
            @charset "utf-8";
         
     | 
| 
       187 
     | 
    
         
            -
             
     | 
| 
       188 
36 
     | 
    
         
             
            @import "normalize-rails";
         
     | 
| 
       189 
37 
     | 
    
         
             
            @import "chr";
         
     | 
| 
       190 
     | 
    
         
            -
            @import "admin/signin";
         
     | 
| 
       191 
38 
     | 
    
         
             
            ```
         
     | 
| 
       192 
39 
     | 
    
         | 
| 
       193 
     | 
    
         
            -
            Last import in the code above is optional. But here is a default source for it as well ```app/assets/stylesheets/admin/chr/_signin.scss```:
         
     | 
| 
       194 
     | 
    
         
            -
             
     | 
| 
       195 
     | 
    
         
            -
            ```scss
         
     | 
| 
       196 
     | 
    
         
            -
            .sign-in {
         
     | 
| 
       197 
     | 
    
         
            -
              font-size: 14px;
         
     | 
| 
       198 
     | 
    
         
            -
              color: #555;
         
     | 
| 
       199 
     | 
    
         
            -
              margin: 3em 0 0 3em;
         
     | 
| 
       200 
40 
     | 
    
         | 
| 
       201 
     | 
    
         
            -
             
     | 
| 
       202 
     | 
    
         
            -
                text-transform: uppercase;
         
     | 
| 
       203 
     | 
    
         
            -
                font-size: 1em;
         
     | 
| 
       204 
     | 
    
         
            -
                font-size: 16px;
         
     | 
| 
       205 
     | 
    
         
            -
                color: $black;
         
     | 
| 
       206 
     | 
    
         
            -
                margin-bottom: 1.5em;
         
     | 
| 
       207 
     | 
    
         
            -
              }
         
     | 
| 
      
 41 
     | 
    
         
            +
            ## Documentation
         
     | 
| 
       208 
42 
     | 
    
         | 
| 
       209 
     | 
    
         
            -
             
     | 
| 
       210 
     | 
    
         
            -
             
     | 
| 
       211 
     | 
    
         
            -
                color: $positiveColor;
         
     | 
| 
       212 
     | 
    
         
            -
              }
         
     | 
| 
      
 43 
     | 
    
         
            +
            * [Start with Rails](docs/rails.md)
         
     | 
| 
      
 44 
     | 
    
         
            +
            * [Bootstrap Data](docs/bootstrap.md)
         
     | 
| 
       213 
45 
     | 
    
         | 
| 
       214 
     | 
    
         
            -
             
     | 
| 
       215 
     | 
    
         
            -
                max-width: 280px;
         
     | 
| 
       216 
     | 
    
         
            -
              }
         
     | 
| 
      
 46 
     | 
    
         
            +
            More documentation and samples comming soon...
         
     | 
| 
       217 
47 
     | 
    
         | 
| 
       218 
     | 
    
         
            -
              .input {
         
     | 
| 
       219 
     | 
    
         
            -
                margin-bottom: 1.5em;
         
     | 
| 
       220 
     | 
    
         
            -
              }
         
     | 
| 
       221 
48 
     | 
    
         | 
| 
       222 
     | 
    
         
            -
             
     | 
| 
       223 
     | 
    
         
            -
                float: right;
         
     | 
| 
       224 
     | 
    
         
            -
                margin-top: -.45em;
         
     | 
| 
       225 
     | 
    
         
            -
                padding: .25em .5em;
         
     | 
| 
       226 
     | 
    
         
            -
                width: 13.5em;
         
     | 
| 
       227 
     | 
    
         
            -
              }
         
     | 
| 
      
 49 
     | 
    
         
            +
            ## Character family:
         
     | 
| 
       228 
50 
     | 
    
         | 
| 
       229 
     | 
    
         
            -
             
     | 
| 
       230 
     | 
    
         
            -
             
     | 
| 
       231 
     | 
    
         
            -
              }
         
     | 
| 
       232 
     | 
    
         
            -
             
     | 
| 
       233 
     | 
    
         
            -
              .form-actions input {
         
     | 
| 
       234 
     | 
    
         
            -
                width: 100%;
         
     | 
| 
       235 
     | 
    
         
            -
                padding: 1em 2em;
         
     | 
| 
       236 
     | 
    
         
            -
                background-color: $positiveColor;
         
     | 
| 
       237 
     | 
    
         
            -
                border: 0;
         
     | 
| 
       238 
     | 
    
         
            -
                color: $white;
         
     | 
| 
       239 
     | 
    
         
            -
              }
         
     | 
| 
       240 
     | 
    
         
            -
            }
         
     | 
| 
       241 
     | 
    
         
            -
            ```
         
     | 
| 
       242 
     | 
    
         
            -
             
     | 
| 
       243 
     | 
    
         
            -
            **Third**: make sure admin assets are precompiled on production, include ```admin.js``` and ```admin.css``` in ```config/initializers/assets.rb```:
         
     | 
| 
       244 
     | 
    
         
            -
             
     | 
| 
       245 
     | 
    
         
            -
            ```ruby
         
     | 
| 
       246 
     | 
    
         
            -
            Rails.application.config.assets.precompile += %w( admin.js admin.css )
         
     | 
| 
       247 
     | 
    
         
            -
            ```
         
     | 
| 
       248 
     | 
    
         
            -
             
     | 
| 
       249 
     | 
    
         
            -
            At this point initial setup for admin app is finished and it could be accessed via: ```localhost:3000/admin```.
         
     | 
| 
       250 
     | 
    
         
            -
             
     | 
| 
       251 
     | 
    
         
            -
             
     | 
| 
       252 
     | 
    
         
            -
            #### Add models
         
     | 
| 
       253 
     | 
    
         
            -
             
     | 
| 
       254 
     | 
    
         
            -
            To be continued...
         
     | 
| 
       255 
     | 
    
         
            -
             
     | 
| 
       256 
     | 
    
         
            -
             
     | 
| 
       257 
     | 
    
         
            -
            #### Bootstrap data
         
     | 
| 
       258 
     | 
    
         
            -
             
     | 
| 
       259 
     | 
    
         
            -
            Bootstrapped data configuration example with disabled item updates and pagination:
         
     | 
| 
       260 
     | 
    
         
            -
             
     | 
| 
       261 
     | 
    
         
            -
            ```coffee
         
     | 
| 
       262 
     | 
    
         
            -
            postsConfig = (data) ->
         
     | 
| 
       263 
     | 
    
         
            -
              itemTitleField:     'title'
         
     | 
| 
       264 
     | 
    
         
            -
              disableUpdateItems: true
         
     | 
| 
       265 
     | 
    
         
            -
              objects:            data.posts
         
     | 
| 
       266 
     | 
    
         
            -
              arrayStore: new MongosteenArrayStore({
         
     | 
| 
       267 
     | 
    
         
            -
                resource:    'post'
         
     | 
| 
       268 
     | 
    
         
            -
                path:        '/admin/posts'
         
     | 
| 
       269 
     | 
    
         
            -
                sortBy:      'title'
         
     | 
| 
       270 
     | 
    
         
            -
                pagination:  false
         
     | 
| 
       271 
     | 
    
         
            -
              })
         
     | 
| 
       272 
     | 
    
         
            -
              formSchema:
         
     | 
| 
       273 
     | 
    
         
            -
                title: { type: 'string' }
         
     | 
| 
       274 
     | 
    
         
            -
                body:  { type: 'text'   }
         
     | 
| 
       275 
     | 
    
         
            -
            ```
         
     | 
| 
       276 
     | 
    
         
            -
             
     | 
| 
       277 
     | 
    
         
            -
            ```disableUpdateItems``` — do not update items in the list while navigation, ```objects``` — provides initial (bootstrapped) array of objects to be added to the list, ```pagination``` — disable pagination for list. If attached as modules root list, you can access store data with: ```chr.modules.posts.arrayStore.data()```.
         
     | 
| 
       278 
     | 
    
         
            -
             
     | 
| 
       279 
     | 
    
         
            -
             
     | 
| 
       280 
     | 
    
         
            -
            ## Character tastes better with:
         
     | 
| 
       281 
     | 
    
         
            -
             
     | 
| 
       282 
     | 
    
         
            -
            - [Mongosteen](https://github.com/slate-studio/mongosteen): An easy way to add restful actions for Mongoid models
         
     | 
| 
      
 51 
     | 
    
         
            +
            - [Character](https://github.com/slate-studio/chr): Powerful responsive javascript CMS for apps
         
     | 
| 
      
 52 
     | 
    
         
            +
            - [Mongosteen](https://github.com/slate-studio/mongosteen): An easy way to add RESTful actions for Mongoid models
         
     | 
| 
       283 
53 
     | 
    
         
             
            - [Inverter](https://github.com/slate-studio/inverter): An easy way to connect Rails templates content to Character CMS
         
     | 
| 
       284 
54 
     | 
    
         
             
            - [Loft](https://github.com/slate-studio/loft): Media assets manager for Character CMS
         
     | 
| 
       285 
55 
     | 
    
         | 
| 
         @@ -293,4 +63,8 @@ Copyright © 2015 [Slate Studio, LLC](http://slatestudio.com). Character is free 
     | 
|
| 
       293 
63 
     | 
    
         | 
| 
       294 
64 
     | 
    
         
             
            [](http://slatestudio.com)
         
     | 
| 
       295 
65 
     | 
    
         | 
| 
       296 
     | 
    
         
            -
            Character is maintained and funded by [Slate Studio, LLC](http://slatestudio.com). Tweet your questions or suggestions to [@slatestudio](https://twitter.com/slatestudio) and while you’re at it follow us too.
         
     | 
| 
      
 66 
     | 
    
         
            +
            Character is maintained and funded by [Slate Studio, LLC](http://slatestudio.com). Tweet your questions or suggestions to [@slatestudio](https://twitter.com/slatestudio) and while you’re at it follow us too.
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
         @@ -74,12 +74,12 @@ class @Item 
     | 
|
| 
       74 
74 
     | 
    
         | 
| 
       75 
75 
     | 
    
         
             
                # show view for a arrayStore item
         
     | 
| 
       76 
76 
     | 
    
         
             
                if crumbs[crumbs.length - 2] == 'view'
         
     | 
| 
       77 
     | 
    
         
            -
                  return @module.showViewByObjectId(id, @config, title 
     | 
| 
      
 77 
     | 
    
         
            +
                  return @module.showViewByObjectId(id, @config, title)
         
     | 
| 
       78 
78 
     | 
    
         
             
                # show objectStore item view
         
     | 
| 
       79 
79 
     | 
    
         
             
                if @config.objectStore
         
     | 
| 
       80 
     | 
    
         
            -
                  return @module.showViewByObjectId('', @config, title 
     | 
| 
      
 80 
     | 
    
         
            +
                  return @module.showViewByObjectId('', @config, title)
         
     | 
| 
       81 
81 
     | 
    
         
             
                # show nested list
         
     | 
| 
       82 
     | 
    
         
            -
                @module.showNestedList(_last(crumbs) 
     | 
| 
      
 82 
     | 
    
         
            +
                @module.showNestedList(_last(crumbs))
         
     | 
| 
       83 
83 
     | 
    
         | 
| 
       84 
84 
     | 
    
         | 
| 
       85 
85 
     | 
    
         
             
              # PUBLIC ================================================
         
     | 
| 
         @@ -149,35 +149,28 @@ class @List 
     | 
|
| 
       149 
149 
     | 
    
         
             
                @module.destroyView()
         
     | 
| 
       150 
150 
     | 
    
         | 
| 
       151 
151 
     | 
    
         
             
                if @showWithParent
         
     | 
| 
       152 
     | 
    
         
            -
                  @hide( 
     | 
| 
      
 152 
     | 
    
         
            +
                  @hide()
         
     | 
| 
       153 
153 
     | 
    
         
             
                else
         
     | 
| 
       154 
     | 
    
         
            -
                  @module.hideActiveList( 
     | 
| 
      
 154 
     | 
    
         
            +
                  @module.hideActiveList()
         
     | 
| 
       155 
155 
     | 
    
         | 
| 
       156 
156 
     | 
    
         | 
| 
       157 
157 
     | 
    
         
             
              _new: (e) ->
         
     | 
| 
       158 
158 
     | 
    
         
             
                chr.updateHash($(e.currentTarget).attr('href'), true)
         
     | 
| 
       159 
     | 
    
         
            -
                @module.showView(null, @config, 'New' 
     | 
| 
      
 159 
     | 
    
         
            +
                @module.showView(null, @config, 'New')
         
     | 
| 
       160 
160 
     | 
    
         | 
| 
       161 
161 
     | 
    
         | 
| 
       162 
162 
     | 
    
         
             
              # PUBLIC ================================================
         
     | 
| 
       163 
163 
     | 
    
         | 
| 
       164 
     | 
    
         
            -
              hide:  
     | 
| 
       165 
     | 
    
         
            -
                 
     | 
| 
      
 164 
     | 
    
         
            +
              hide: ->
         
     | 
| 
      
 165 
     | 
    
         
            +
                @$el.hide()
         
     | 
| 
       166 
166 
     | 
    
         | 
| 
       167 
167 
     | 
    
         | 
| 
       168 
     | 
    
         
            -
              show: ( 
     | 
| 
       169 
     | 
    
         
            -
                 
     | 
| 
      
 168 
     | 
    
         
            +
              show: (callback) ->
         
     | 
| 
      
 169 
     | 
    
         
            +
                @$el.show 0, =>
         
     | 
| 
       170 
170 
     | 
    
         
             
                  @$items.scrollTop(0)
         
     | 
| 
       171 
171 
     | 
    
         
             
                  @config.onListShow?(@)
         
     | 
| 
       172 
172 
     | 
    
         
             
                  callback?()
         
     | 
| 
       173 
173 
     | 
    
         | 
| 
       174 
     | 
    
         
            -
                if animate
         
     | 
| 
       175 
     | 
    
         
            -
                  # z-index workaround to remove blink effect
         
     | 
| 
       176 
     | 
    
         
            -
                  @$el.css({ 'z-index': 1, 'box-shadow': 'none' })
         
     | 
| 
       177 
     | 
    
         
            -
                  @$el.fadeIn $.fx.speeds._default, => @$el.css({ 'z-index': '', 'box-shadow': '' }) ; onShow()
         
     | 
| 
       178 
     | 
    
         
            -
                else
         
     | 
| 
       179 
     | 
    
         
            -
                  @$el.show() ; onShow()
         
     | 
| 
       180 
     | 
    
         
            -
             
     | 
| 
       181 
174 
     | 
    
         | 
| 
       182 
175 
     | 
    
         
             
              updateItems: ->
         
     | 
| 
       183 
176 
     | 
    
         
             
                if not @config.disableUpdateItems
         
     | 
| 
         @@ -16,16 +16,16 @@ 
     | 
|
| 
       16 
16 
     | 
    
         
             
            #
         
     | 
| 
       17 
17 
     | 
    
         
             
            # Public methods:
         
     | 
| 
       18 
18 
     | 
    
         
             
            #   addNestedList (listName, config, parentList)
         
     | 
| 
       19 
     | 
    
         
            -
            #   showNestedList (listName 
     | 
| 
      
 19 
     | 
    
         
            +
            #   showNestedList (listName)
         
     | 
| 
       20 
20 
     | 
    
         
             
            #   hideNestedLists (exceptList)
         
     | 
| 
       21 
21 
     | 
    
         
             
            #   visibleNestedListShownWithParent ()
         
     | 
| 
       22 
     | 
    
         
            -
            #   showRootList()
         
     | 
| 
       23 
     | 
    
         
            -
            #   hideActiveList ( 
     | 
| 
       24 
     | 
    
         
            -
            #   showView (object, config, title 
     | 
| 
       25 
     | 
    
         
            -
            #   showViewByObjectId (objectId, config, title 
     | 
| 
      
 22 
     | 
    
         
            +
            #   showRootList ()
         
     | 
| 
      
 23 
     | 
    
         
            +
            #   hideActiveList ()
         
     | 
| 
      
 24 
     | 
    
         
            +
            #   showView (object, config, title)
         
     | 
| 
      
 25 
     | 
    
         
            +
            #   showViewByObjectId (objectId, config, title)
         
     | 
| 
       26 
26 
     | 
    
         
             
            #   destroyView ()
         
     | 
| 
       27 
27 
     | 
    
         
             
            #   show ()
         
     | 
| 
       28 
     | 
    
         
            -
            #   hide ( 
     | 
| 
      
 28 
     | 
    
         
            +
            #   hide ()
         
     | 
| 
       29 
29 
     | 
    
         
             
            #
         
     | 
| 
       30 
30 
     | 
    
         
             
            # -----------------------------------------------------------------------------
         
     | 
| 
       31 
31 
     | 
    
         
             
            class @Module
         
     | 
| 
         @@ -77,22 +77,21 @@ class @Module 
     | 
|
| 
       77 
77 
     | 
    
         
             
                @nestedLists[listName] = new List(this, listName, config, parentList)
         
     | 
| 
       78 
78 
     | 
    
         | 
| 
       79 
79 
     | 
    
         | 
| 
       80 
     | 
    
         
            -
              # shows one of nested lists 
     | 
| 
       81 
     | 
    
         
            -
              showNestedList: (listName 
     | 
| 
      
 80 
     | 
    
         
            +
              # shows one of nested lists
         
     | 
| 
      
 81 
     | 
    
         
            +
              showNestedList: (listName) ->
         
     | 
| 
       82 
82 
     | 
    
         
             
                listToShow = @nestedLists[listName]
         
     | 
| 
       83 
83 
     | 
    
         | 
| 
       84 
84 
     | 
    
         
             
                if listToShow.showWithParent
         
     | 
| 
       85 
85 
     | 
    
         
             
                  # list works as view, never becomes active
         
     | 
| 
       86 
86 
     | 
    
         
             
                  listToShow.updateItems()
         
     | 
| 
       87 
     | 
    
         
            -
                  listToShow.show  
     | 
| 
      
 87 
     | 
    
         
            +
                  listToShow.show => @hideNestedLists(exceptList=listName)
         
     | 
| 
       88 
88 
     | 
    
         | 
| 
       89 
89 
     | 
    
         
             
                else
         
     | 
| 
       90 
90 
     | 
    
         
             
                  @activeList = listToShow
         
     | 
| 
       91 
91 
     | 
    
         
             
                  @_update_active_list_items()
         
     | 
| 
       92 
     | 
    
         
            -
                  @activeList.show( 
     | 
| 
      
 92 
     | 
    
         
            +
                  @activeList.show()
         
     | 
| 
       93 
93 
     | 
    
         | 
| 
       94 
     | 
    
         
            -
                 
     | 
| 
       95 
     | 
    
         
            -
                if animate and @view then @view.$el.fadeOut $.fx.speeds._default, => @destroyView()
         
     | 
| 
      
 94 
     | 
    
         
            +
                @destroyView()
         
     | 
| 
       96 
95 
     | 
    
         | 
| 
       97 
96 
     | 
    
         | 
| 
       98 
97 
     | 
    
         
             
              hideNestedLists: (exceptList) ->
         
     | 
| 
         @@ -105,28 +104,28 @@ class @Module 
     | 
|
| 
       105 
104 
     | 
    
         
             
                  if list.isVisible() && list.showWithParent then return list
         
     | 
| 
       106 
105 
     | 
    
         | 
| 
       107 
106 
     | 
    
         | 
| 
       108 
     | 
    
         
            -
              showRootList:  
     | 
| 
      
 107 
     | 
    
         
            +
              showRootList: ->
         
     | 
| 
       109 
108 
     | 
    
         
             
                @destroyView()
         
     | 
| 
       110 
109 
     | 
    
         
             
                while @activeList != @rootList
         
     | 
| 
       111 
     | 
    
         
            -
                  @hideActiveList( 
     | 
| 
      
 110 
     | 
    
         
            +
                  @hideActiveList()
         
     | 
| 
       112 
111 
     | 
    
         | 
| 
       113 
112 
     | 
    
         | 
| 
       114 
     | 
    
         
            -
              hideActiveList:  
     | 
| 
       115 
     | 
    
         
            -
                 
     | 
| 
      
 113 
     | 
    
         
            +
              hideActiveList: ->
         
     | 
| 
      
 114 
     | 
    
         
            +
                @activeList.$el.hide()
         
     | 
| 
       116 
115 
     | 
    
         
             
                @activeList = @activeList.parentList
         
     | 
| 
       117 
116 
     | 
    
         | 
| 
       118 
117 
     | 
    
         | 
| 
       119 
     | 
    
         
            -
              showView: (object, config, title 
     | 
| 
      
 118 
     | 
    
         
            +
              showView: (object, config, title) ->
         
     | 
| 
       120 
119 
     | 
    
         
             
                newView = new View(this, config, @_view_path(), object, title)
         
     | 
| 
       121 
120 
     | 
    
         
             
                @chr.$el.append(newView.$el)
         
     | 
| 
       122 
121 
     | 
    
         | 
| 
       123 
     | 
    
         
            -
                newView.show  
     | 
| 
      
 122 
     | 
    
         
            +
                newView.show =>
         
     | 
| 
       124 
123 
     | 
    
         
             
                  @destroyView()
         
     | 
| 
       125 
124 
     | 
    
         
             
                  @view = newView
         
     | 
| 
       126 
125 
     | 
    
         | 
| 
       127 
126 
     | 
    
         | 
| 
       128 
     | 
    
         
            -
              showViewByObjectId: (objectId, config, title 
     | 
| 
       129 
     | 
    
         
            -
                onSuccess = (object) => @showView(object, config, title 
     | 
| 
      
 127 
     | 
    
         
            +
              showViewByObjectId: (objectId, config, title) ->
         
     | 
| 
      
 128 
     | 
    
         
            +
                onSuccess = (object) => @showView(object, config, title)
         
     | 
| 
       130 
129 
     | 
    
         
             
                onError   = -> chr.showError("can\'t show view for requested object")
         
     | 
| 
       131 
130 
     | 
    
         | 
| 
       132 
131 
     | 
    
         
             
                if objectId == ''
         
     | 
| 
         @@ -142,19 +141,13 @@ class @Module 
     | 
|
| 
       142 
141 
     | 
    
         
             
              show: ->
         
     | 
| 
       143 
142 
     | 
    
         
             
                @_update_active_list_items()
         
     | 
| 
       144 
143 
     | 
    
         
             
                @$el.show()
         
     | 
| 
       145 
     | 
    
         
            -
                @activeList.show( 
     | 
| 
      
 144 
     | 
    
         
            +
                @activeList.show()
         
     | 
| 
       146 
145 
     | 
    
         | 
| 
       147 
146 
     | 
    
         | 
| 
       148 
     | 
    
         
            -
              hide:  
     | 
| 
      
 147 
     | 
    
         
            +
              hide: ->
         
     | 
| 
       149 
148 
     | 
    
         
             
                @hideNestedLists()
         
     | 
| 
       150 
     | 
    
         
            -
             
     | 
| 
       151 
     | 
    
         
            -
                 
     | 
| 
       152 
     | 
    
         
            -
                  # TODO: move animation to the view class
         
     | 
| 
       153 
     | 
    
         
            -
                  if @view then @view.$el.fadeOut $.fx.speeds._default, => @destroyView()
         
     | 
| 
       154 
     | 
    
         
            -
                  @$el.fadeOut()
         
     | 
| 
       155 
     | 
    
         
            -
                else
         
     | 
| 
       156 
     | 
    
         
            -
                  @destroyView()
         
     | 
| 
       157 
     | 
    
         
            -
                  @$el.hide()
         
     | 
| 
      
 149 
     | 
    
         
            +
                @destroyView()
         
     | 
| 
      
 150 
     | 
    
         
            +
                @$el.hide()
         
     | 
| 
       158 
151 
     | 
    
         | 
| 
       159 
152 
     | 
    
         | 
| 
       160 
153 
     | 
    
         | 
| 
         @@ -16,11 +16,9 @@ 
     | 
|
| 
       16 
16 
     | 
    
         
             
            #   disableSave      - do not add save button in header
         
     | 
| 
       17 
17 
     | 
    
         
             
            #   fullsizeView     — use fullsize layout in desktop mode
         
     | 
| 
       18 
18 
     | 
    
         
             
            #   onViewShow       - on show callback
         
     | 
| 
       19 
     | 
    
         
            -
            #   onShowAnimation  - animation method to be used on show
         
     | 
| 
       20 
     | 
    
         
            -
            #   onCloseAnimation - animation method to be used on close
         
     | 
| 
       21 
19 
     | 
    
         
             
            #
         
     | 
| 
       22 
20 
     | 
    
         
             
            # public methods:
         
     | 
| 
       23 
     | 
    
         
            -
            #   show( 
     | 
| 
      
 21 
     | 
    
         
            +
            #   show(callback)
         
     | 
| 
       24 
22 
     | 
    
         
             
            #   destroy()
         
     | 
| 
       25 
23 
     | 
    
         
             
            #
         
     | 
| 
       26 
24 
     | 
    
         
             
            # -----------------------------------------------------------------------------
         
     | 
| 
         @@ -34,12 +32,6 @@ class @View 
     | 
|
| 
       34 
32 
     | 
    
         
             
                if @config.fullsizeView
         
     | 
| 
       35 
33 
     | 
    
         
             
                  @$el.addClass 'fullsize'
         
     | 
| 
       36 
34 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
                # animations
         
     | 
| 
       38 
     | 
    
         
            -
                @onShowAnimation   = @config.onShowAnimation
         
     | 
| 
       39 
     | 
    
         
            -
                @onCloseAnimation  = @config.onCloseAnimation
         
     | 
| 
       40 
     | 
    
         
            -
                @onShowAnimation  ?= (callback) => @$el.fadeIn  $.fx.speeds._default, -> callback()
         
     | 
| 
       41 
     | 
    
         
            -
                @onCloseAnimation ?= (callback) => @$el.fadeOut $.fx.speeds._default, -> callback()
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
35 
     | 
    
         
             
                # header
         
     | 
| 
       44 
36 
     | 
    
         
             
                @$header =$ "<header></header>"
         
     | 
| 
       45 
37 
     | 
    
         
             
                @$title  =$ "<div class='title'></div>"
         
     | 
| 
         @@ -96,7 +88,7 @@ class @View 
     | 
|
| 
       96 
88 
     | 
    
         
             
              # EVENTS ================================================
         
     | 
| 
       97 
89 
     | 
    
         | 
| 
       98 
90 
     | 
    
         
             
              _close: (e) ->
         
     | 
| 
       99 
     | 
    
         
            -
                @ 
     | 
| 
      
 91 
     | 
    
         
            +
                @destroy()
         
     | 
| 
       100 
92 
     | 
    
         | 
| 
       101 
93 
     | 
    
         | 
| 
       102 
94 
     | 
    
         
             
              _save: (e) ->
         
     | 
| 
         @@ -122,23 +114,18 @@ class @View 
     | 
|
| 
       122 
114 
     | 
    
         
             
                e.preventDefault()
         
     | 
| 
       123 
115 
     | 
    
         
             
                if confirm("Are you sure?")
         
     | 
| 
       124 
116 
     | 
    
         
             
                  @store.remove @object._id,
         
     | 
| 
       125 
     | 
    
         
            -
                    onSuccess: =>  
     | 
| 
      
 117 
     | 
    
         
            +
                    onSuccess: => chr.updateHash("#/#{ @closePath }", true) ; @destroy()
         
     | 
| 
       126 
118 
     | 
    
         
             
                    onError:   -> chr.showError('Can\'t delete object.')
         
     | 
| 
       127 
119 
     | 
    
         | 
| 
       128 
120 
     | 
    
         | 
| 
       129 
121 
     | 
    
         
             
              # PUBLIC ================================================
         
     | 
| 
       130 
122 
     | 
    
         | 
| 
       131 
     | 
    
         
            -
              show: ( 
     | 
| 
       132 
     | 
    
         
            -
                 
     | 
| 
      
 123 
     | 
    
         
            +
              show: (callback) ->
         
     | 
| 
      
 124 
     | 
    
         
            +
                @$el.show 0, =>
         
     | 
| 
       133 
125 
     | 
    
         
             
                  callback?()
         
     | 
| 
       134 
126 
     | 
    
         
             
                  @form.initializePlugins()
         
     | 
| 
       135 
127 
     | 
    
         
             
                  @config.onViewShow?(@)
         
     | 
| 
       136 
128 
     | 
    
         | 
| 
       137 
     | 
    
         
            -
                if animate
         
     | 
| 
       138 
     | 
    
         
            -
                  @onShowAnimation(=> after_show())
         
     | 
| 
       139 
     | 
    
         
            -
                else
         
     | 
| 
       140 
     | 
    
         
            -
                  @$el.show(0, => after_show())
         
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
129 
     | 
    
         | 
| 
       143 
130 
     | 
    
         
             
              destroy: ->
         
     | 
| 
       144 
131 
     | 
    
         
             
                @form.destroy()
         
     | 
| 
         @@ -31,19 +31,16 @@ 
     | 
|
| 
       31 
31 
     | 
    
         
             
                isFocused: false,
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
       33 
33 
     | 
    
         
             
                checkOffset: function () {
         
     | 
| 
       34 
     | 
    
         
            -
                   
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                    } else {
         
     | 
| 
       45 
     | 
    
         
            -
                      this.unfix();
         
     | 
| 
       46 
     | 
    
         
            -
                    }
         
     | 
| 
      
 34 
     | 
    
         
            +
                  var boxOffset = this.redactor.$box.offset();
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  var isBelowBoxTop = boxOffset.top - this.viewHeaderHeight <= 0;
         
     | 
| 
      
 37 
     | 
    
         
            +
                  //var isAboveBoxBottom = boxOffset.top + this.redactor.$box.outerHeight() - this.redactor.$toolbar.outerHeight() - this.$window.scrollTop() >= 0;
         
     | 
| 
      
 38 
     | 
    
         
            +
                  var isAboveBoxBottom = this.redactor.$box.outerHeight() + boxOffset.top - this.viewHeaderHeight - this.redactor.$toolbar.outerHeight() >= 0;
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  if (isBelowBoxTop && isAboveBoxBottom) {
         
     | 
| 
      
 41 
     | 
    
         
            +
                    this.fix();
         
     | 
| 
      
 42 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 43 
     | 
    
         
            +
                    this.unfix();
         
     | 
| 
       47 
44 
     | 
    
         
             
                  }
         
     | 
| 
       48 
45 
     | 
    
         
             
                },
         
     | 
| 
       49 
46 
     | 
    
         | 
| 
         @@ -29,21 +29,16 @@ class @InputRedactor extends InputString 
     | 
|
| 
       29 
29 
     | 
    
         
             
              # PUBLIC ================================================
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         
             
              initialize: ->
         
     | 
| 
      
 32 
     | 
    
         
            +
                plugins = [ 'fixedtoolbar' ]
         
     | 
| 
      
 33 
     | 
    
         
            +
                if Loft then plugins.push('loft')
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
       32 
35 
     | 
    
         
             
                redactor_options =
         
     | 
| 
       33 
36 
     | 
    
         
             
                  focus:            false
         
     | 
| 
       34 
37 
     | 
    
         
             
                  imageFloatMargin: '20px'
         
     | 
| 
       35 
38 
     | 
    
         
             
                  buttonSource:     true
         
     | 
| 
       36 
39 
     | 
    
         
             
                  pastePlainText:   true
         
     | 
| 
       37 
     | 
    
         
            -
                  plugins: 
     | 
| 
       38 
     | 
    
         
            -
                  buttons: 
     | 
| 
       39 
     | 
    
         
            -
                                      'formatting',
         
     | 
| 
       40 
     | 
    
         
            -
                                      'bold',
         
     | 
| 
       41 
     | 
    
         
            -
                                      'italic',
         
     | 
| 
       42 
     | 
    
         
            -
                                      'deleted',
         
     | 
| 
       43 
     | 
    
         
            -
                                      'alignment',
         
     | 
| 
       44 
     | 
    
         
            -
                                      'unorderedlist',
         
     | 
| 
       45 
     | 
    
         
            -
                                      'orderedlist',
         
     | 
| 
       46 
     | 
    
         
            -
                                      'link' ]
         
     | 
| 
      
 40 
     | 
    
         
            +
                  plugins: plugins
         
     | 
| 
      
 41 
     | 
    
         
            +
                  buttons: [ 'html', 'formatting', 'bold', 'italic', 'deleted', 'unorderedlist', 'orderedlist', 'link' ]
         
     | 
| 
       47 
42 
     | 
    
         | 
| 
       48 
43 
     | 
    
         
             
                @config.redactorOptions ?= {}
         
     | 
| 
       49 
44 
     | 
    
         
             
                $.extend(redactor_options, @config.redactorOptions)
         
     | 
    
        data/bower.json
    CHANGED
    
    
    
        data/dist/chr.js
    CHANGED
    
    | 
         @@ -2762,7 +2762,7 @@ this.Chr = (function() { 
     | 
|
| 
       2762 
2762 
     | 
    
         
             
                crumbs = path.split('/');
         
     | 
| 
       2763 
2763 
     | 
    
         
             
                if (this.module !== this.modules[crumbs[1]]) {
         
     | 
| 
       2764 
2764 
     | 
    
         
             
                  if ((ref = this.module) != null) {
         
     | 
| 
       2765 
     | 
    
         
            -
                    ref.hide( 
     | 
| 
      
 2765 
     | 
    
         
            +
                    ref.hide();
         
     | 
| 
       2766 
2766 
     | 
    
         
             
                  }
         
     | 
| 
       2767 
2767 
     | 
    
         
             
                }
         
     | 
| 
       2768 
2768 
     | 
    
         
             
                this.module = this.modules[crumbs[1]];
         
     | 
| 
         @@ -2912,15 +2912,12 @@ this.Module = (function() { 
     | 
|
| 
       2912 
2912 
     | 
    
         
             
                return this.nestedLists[listName] = new List(this, listName, config, parentList);
         
     | 
| 
       2913 
2913 
     | 
    
         
             
              };
         
     | 
| 
       2914 
2914 
     | 
    
         | 
| 
       2915 
     | 
    
         
            -
              Module.prototype.showNestedList = function(listName 
     | 
| 
      
 2915 
     | 
    
         
            +
              Module.prototype.showNestedList = function(listName) {
         
     | 
| 
       2916 
2916 
     | 
    
         
             
                var listToShow;
         
     | 
| 
       2917 
     | 
    
         
            -
                if (animate == null) {
         
     | 
| 
       2918 
     | 
    
         
            -
                  animate = false;
         
     | 
| 
       2919 
     | 
    
         
            -
                }
         
     | 
| 
       2920 
2917 
     | 
    
         
             
                listToShow = this.nestedLists[listName];
         
     | 
| 
       2921 
2918 
     | 
    
         
             
                if (listToShow.showWithParent) {
         
     | 
| 
       2922 
2919 
     | 
    
         
             
                  listToShow.updateItems();
         
     | 
| 
       2923 
     | 
    
         
            -
                  listToShow.show( 
     | 
| 
      
 2920 
     | 
    
         
            +
                  listToShow.show((function(_this) {
         
     | 
| 
       2924 
2921 
     | 
    
         
             
                    return function() {
         
     | 
| 
       2925 
2922 
     | 
    
         
             
                      var exceptList;
         
     | 
| 
       2926 
2923 
     | 
    
         
             
                      return _this.hideNestedLists(exceptList = listName);
         
     | 
| 
         @@ -2929,15 +2926,9 @@ this.Module = (function() { 
     | 
|
| 
       2929 
2926 
     | 
    
         
             
                } else {
         
     | 
| 
       2930 
2927 
     | 
    
         
             
                  this.activeList = listToShow;
         
     | 
| 
       2931 
2928 
     | 
    
         
             
                  this._update_active_list_items();
         
     | 
| 
       2932 
     | 
    
         
            -
                  this.activeList.show( 
     | 
| 
       2933 
     | 
    
         
            -
                }
         
     | 
| 
       2934 
     | 
    
         
            -
                if (animate && this.view) {
         
     | 
| 
       2935 
     | 
    
         
            -
                  return this.view.$el.fadeOut($.fx.speeds._default, (function(_this) {
         
     | 
| 
       2936 
     | 
    
         
            -
                    return function() {
         
     | 
| 
       2937 
     | 
    
         
            -
                      return _this.destroyView();
         
     | 
| 
       2938 
     | 
    
         
            -
                    };
         
     | 
| 
       2939 
     | 
    
         
            -
                  })(this));
         
     | 
| 
      
 2929 
     | 
    
         
            +
                  this.activeList.show();
         
     | 
| 
       2940 
2930 
     | 
    
         
             
                }
         
     | 
| 
      
 2931 
     | 
    
         
            +
                return this.destroyView();
         
     | 
| 
       2941 
2932 
     | 
    
         
             
              };
         
     | 
| 
       2942 
2933 
     | 
    
         | 
| 
       2943 
2934 
     | 
    
         
             
              Module.prototype.hideNestedLists = function(exceptList) {
         
     | 
| 
         @@ -2970,31 +2961,21 @@ this.Module = (function() { 
     | 
|
| 
       2970 
2961 
     | 
    
         
             
                this.destroyView();
         
     | 
| 
       2971 
2962 
     | 
    
         
             
                results = [];
         
     | 
| 
       2972 
2963 
     | 
    
         
             
                while (this.activeList !== this.rootList) {
         
     | 
| 
       2973 
     | 
    
         
            -
                  results.push(this.hideActiveList( 
     | 
| 
      
 2964 
     | 
    
         
            +
                  results.push(this.hideActiveList());
         
     | 
| 
       2974 
2965 
     | 
    
         
             
                }
         
     | 
| 
       2975 
2966 
     | 
    
         
             
                return results;
         
     | 
| 
       2976 
2967 
     | 
    
         
             
              };
         
     | 
| 
       2977 
2968 
     | 
    
         | 
| 
       2978 
     | 
    
         
            -
              Module.prototype.hideActiveList = function( 
     | 
| 
       2979 
     | 
    
         
            -
                 
     | 
| 
       2980 
     | 
    
         
            -
                  animate = false;
         
     | 
| 
       2981 
     | 
    
         
            -
                }
         
     | 
| 
       2982 
     | 
    
         
            -
                if (animate) {
         
     | 
| 
       2983 
     | 
    
         
            -
                  this.activeList.$el.fadeOut();
         
     | 
| 
       2984 
     | 
    
         
            -
                } else {
         
     | 
| 
       2985 
     | 
    
         
            -
                  this.activeList.$el.hide();
         
     | 
| 
       2986 
     | 
    
         
            -
                }
         
     | 
| 
      
 2969 
     | 
    
         
            +
              Module.prototype.hideActiveList = function() {
         
     | 
| 
      
 2970 
     | 
    
         
            +
                this.activeList.$el.hide();
         
     | 
| 
       2987 
2971 
     | 
    
         
             
                return this.activeList = this.activeList.parentList;
         
     | 
| 
       2988 
2972 
     | 
    
         
             
              };
         
     | 
| 
       2989 
2973 
     | 
    
         | 
| 
       2990 
     | 
    
         
            -
              Module.prototype.showView = function(object, config, title 
     | 
| 
      
 2974 
     | 
    
         
            +
              Module.prototype.showView = function(object, config, title) {
         
     | 
| 
       2991 
2975 
     | 
    
         
             
                var newView;
         
     | 
| 
       2992 
     | 
    
         
            -
                if (animate == null) {
         
     | 
| 
       2993 
     | 
    
         
            -
                  animate = false;
         
     | 
| 
       2994 
     | 
    
         
            -
                }
         
     | 
| 
       2995 
2976 
     | 
    
         
             
                newView = new View(this, config, this._view_path(), object, title);
         
     | 
| 
       2996 
2977 
     | 
    
         
             
                this.chr.$el.append(newView.$el);
         
     | 
| 
       2997 
     | 
    
         
            -
                return newView.show( 
     | 
| 
      
 2978 
     | 
    
         
            +
                return newView.show((function(_this) {
         
     | 
| 
       2998 
2979 
     | 
    
         
             
                  return function() {
         
     | 
| 
       2999 
2980 
     | 
    
         
             
                    _this.destroyView();
         
     | 
| 
       3000 
2981 
     | 
    
         
             
                    return _this.view = newView;
         
     | 
| 
         @@ -3002,14 +2983,11 @@ this.Module = (function() { 
     | 
|
| 
       3002 
2983 
     | 
    
         
             
                })(this));
         
     | 
| 
       3003 
2984 
     | 
    
         
             
              };
         
     | 
| 
       3004 
2985 
     | 
    
         | 
| 
       3005 
     | 
    
         
            -
              Module.prototype.showViewByObjectId = function(objectId, config, title 
     | 
| 
      
 2986 
     | 
    
         
            +
              Module.prototype.showViewByObjectId = function(objectId, config, title) {
         
     | 
| 
       3006 
2987 
     | 
    
         
             
                var onError, onSuccess;
         
     | 
| 
       3007 
     | 
    
         
            -
                if (animate == null) {
         
     | 
| 
       3008 
     | 
    
         
            -
                  animate = false;
         
     | 
| 
       3009 
     | 
    
         
            -
                }
         
     | 
| 
       3010 
2988 
     | 
    
         
             
                onSuccess = (function(_this) {
         
     | 
| 
       3011 
2989 
     | 
    
         
             
                  return function(object) {
         
     | 
| 
       3012 
     | 
    
         
            -
                    return _this.showView(object, config, title 
     | 
| 
      
 2990 
     | 
    
         
            +
                    return _this.showView(object, config, title);
         
     | 
| 
       3013 
2991 
     | 
    
         
             
                  };
         
     | 
| 
       3014 
2992 
     | 
    
         
             
                })(this);
         
     | 
| 
       3015 
2993 
     | 
    
         
             
                onError = function() {
         
     | 
| 
         @@ -3036,27 +3014,13 @@ this.Module = (function() { 
     | 
|
| 
       3036 
3014 
     | 
    
         
             
              Module.prototype.show = function() {
         
     | 
| 
       3037 
3015 
     | 
    
         
             
                this._update_active_list_items();
         
     | 
| 
       3038 
3016 
     | 
    
         
             
                this.$el.show();
         
     | 
| 
       3039 
     | 
    
         
            -
                return this.activeList.show( 
     | 
| 
      
 3017 
     | 
    
         
            +
                return this.activeList.show();
         
     | 
| 
       3040 
3018 
     | 
    
         
             
              };
         
     | 
| 
       3041 
3019 
     | 
    
         | 
| 
       3042 
     | 
    
         
            -
              Module.prototype.hide = function( 
     | 
| 
       3043 
     | 
    
         
            -
                if (animate == null) {
         
     | 
| 
       3044 
     | 
    
         
            -
                  animate = false;
         
     | 
| 
       3045 
     | 
    
         
            -
                }
         
     | 
| 
      
 3020 
     | 
    
         
            +
              Module.prototype.hide = function() {
         
     | 
| 
       3046 
3021 
     | 
    
         
             
                this.hideNestedLists();
         
     | 
| 
       3047 
     | 
    
         
            -
                 
     | 
| 
       3048 
     | 
    
         
            -
             
     | 
| 
       3049 
     | 
    
         
            -
                    this.view.$el.fadeOut($.fx.speeds._default, (function(_this) {
         
     | 
| 
       3050 
     | 
    
         
            -
                      return function() {
         
     | 
| 
       3051 
     | 
    
         
            -
                        return _this.destroyView();
         
     | 
| 
       3052 
     | 
    
         
            -
                      };
         
     | 
| 
       3053 
     | 
    
         
            -
                    })(this));
         
     | 
| 
       3054 
     | 
    
         
            -
                  }
         
     | 
| 
       3055 
     | 
    
         
            -
                  return this.$el.fadeOut();
         
     | 
| 
       3056 
     | 
    
         
            -
                } else {
         
     | 
| 
       3057 
     | 
    
         
            -
                  this.destroyView();
         
     | 
| 
       3058 
     | 
    
         
            -
                  return this.$el.hide();
         
     | 
| 
       3059 
     | 
    
         
            -
                }
         
     | 
| 
      
 3022 
     | 
    
         
            +
                this.destroyView();
         
     | 
| 
      
 3023 
     | 
    
         
            +
                return this.$el.hide();
         
     | 
| 
       3060 
3024 
     | 
    
         
             
              };
         
     | 
| 
       3061 
3025 
     | 
    
         | 
| 
       3062 
3026 
     | 
    
         
             
              return Module;
         
     | 
| 
         @@ -3392,31 +3356,23 @@ this.List = (function() { 
     | 
|
| 
       3392 
3356 
     | 
    
         
             
                this.module.chr.unsetActiveListItems();
         
     | 
| 
       3393 
3357 
     | 
    
         
             
                this.module.destroyView();
         
     | 
| 
       3394 
3358 
     | 
    
         
             
                if (this.showWithParent) {
         
     | 
| 
       3395 
     | 
    
         
            -
                  return this.hide( 
     | 
| 
      
 3359 
     | 
    
         
            +
                  return this.hide();
         
     | 
| 
       3396 
3360 
     | 
    
         
             
                } else {
         
     | 
| 
       3397 
     | 
    
         
            -
                  return this.module.hideActiveList( 
     | 
| 
      
 3361 
     | 
    
         
            +
                  return this.module.hideActiveList();
         
     | 
| 
       3398 
3362 
     | 
    
         
             
                }
         
     | 
| 
       3399 
3363 
     | 
    
         
             
              };
         
     | 
| 
       3400 
3364 
     | 
    
         | 
| 
       3401 
3365 
     | 
    
         
             
              List.prototype._new = function(e) {
         
     | 
| 
       3402 
3366 
     | 
    
         
             
                chr.updateHash($(e.currentTarget).attr('href'), true);
         
     | 
| 
       3403 
     | 
    
         
            -
                return this.module.showView(null, this.config, 'New' 
     | 
| 
      
 3367 
     | 
    
         
            +
                return this.module.showView(null, this.config, 'New');
         
     | 
| 
       3404 
3368 
     | 
    
         
             
              };
         
     | 
| 
       3405 
3369 
     | 
    
         | 
| 
       3406 
     | 
    
         
            -
              List.prototype.hide = function( 
     | 
| 
       3407 
     | 
    
         
            -
                 
     | 
| 
       3408 
     | 
    
         
            -
                  return this.$el.fadeOut();
         
     | 
| 
       3409 
     | 
    
         
            -
                } else {
         
     | 
| 
       3410 
     | 
    
         
            -
                  return this.$el.hide();
         
     | 
| 
       3411 
     | 
    
         
            -
                }
         
     | 
| 
      
 3370 
     | 
    
         
            +
              List.prototype.hide = function() {
         
     | 
| 
      
 3371 
     | 
    
         
            +
                return this.$el.hide();
         
     | 
| 
       3412 
3372 
     | 
    
         
             
              };
         
     | 
| 
       3413 
3373 
     | 
    
         | 
| 
       3414 
     | 
    
         
            -
              List.prototype.show = function( 
     | 
| 
       3415 
     | 
    
         
            -
                 
     | 
| 
       3416 
     | 
    
         
            -
                if (animate == null) {
         
     | 
| 
       3417 
     | 
    
         
            -
                  animate = false;
         
     | 
| 
       3418 
     | 
    
         
            -
                }
         
     | 
| 
       3419 
     | 
    
         
            -
                onShow = (function(_this) {
         
     | 
| 
      
 3374 
     | 
    
         
            +
              List.prototype.show = function(callback) {
         
     | 
| 
      
 3375 
     | 
    
         
            +
                return this.$el.show(0, (function(_this) {
         
     | 
| 
       3420 
3376 
     | 
    
         
             
                  return function() {
         
     | 
| 
       3421 
3377 
     | 
    
         
             
                    var base;
         
     | 
| 
       3422 
3378 
     | 
    
         
             
                    _this.$items.scrollTop(0);
         
     | 
| 
         @@ -3425,25 +3381,7 @@ this.List = (function() { 
     | 
|
| 
       3425 
3381 
     | 
    
         
             
                    }
         
     | 
| 
       3426 
3382 
     | 
    
         
             
                    return typeof callback === "function" ? callback() : void 0;
         
     | 
| 
       3427 
3383 
     | 
    
         
             
                  };
         
     | 
| 
       3428 
     | 
    
         
            -
                })(this);
         
     | 
| 
       3429 
     | 
    
         
            -
                if (animate) {
         
     | 
| 
       3430 
     | 
    
         
            -
                  this.$el.css({
         
     | 
| 
       3431 
     | 
    
         
            -
                    'z-index': 1,
         
     | 
| 
       3432 
     | 
    
         
            -
                    'box-shadow': 'none'
         
     | 
| 
       3433 
     | 
    
         
            -
                  });
         
     | 
| 
       3434 
     | 
    
         
            -
                  return this.$el.fadeIn($.fx.speeds._default, (function(_this) {
         
     | 
| 
       3435 
     | 
    
         
            -
                    return function() {
         
     | 
| 
       3436 
     | 
    
         
            -
                      _this.$el.css({
         
     | 
| 
       3437 
     | 
    
         
            -
                        'z-index': '',
         
     | 
| 
       3438 
     | 
    
         
            -
                        'box-shadow': ''
         
     | 
| 
       3439 
     | 
    
         
            -
                      });
         
     | 
| 
       3440 
     | 
    
         
            -
                      return onShow();
         
     | 
| 
       3441 
     | 
    
         
            -
                    };
         
     | 
| 
       3442 
     | 
    
         
            -
                  })(this));
         
     | 
| 
       3443 
     | 
    
         
            -
                } else {
         
     | 
| 
       3444 
     | 
    
         
            -
                  this.$el.show();
         
     | 
| 
       3445 
     | 
    
         
            -
                  return onShow();
         
     | 
| 
       3446 
     | 
    
         
            -
                }
         
     | 
| 
      
 3384 
     | 
    
         
            +
                })(this));
         
     | 
| 
       3447 
3385 
     | 
    
         
             
              };
         
     | 
| 
       3448 
3386 
     | 
    
         | 
| 
       3449 
3387 
     | 
    
         
             
              List.prototype.updateItems = function() {
         
     | 
| 
         @@ -3548,12 +3486,12 @@ this.Item = (function() { 
     | 
|
| 
       3548 
3486 
     | 
    
         
             
                id = $(e.currentTarget).attr('data-id');
         
     | 
| 
       3549 
3487 
     | 
    
         
             
                chr.updateHash(hash, true);
         
     | 
| 
       3550 
3488 
     | 
    
         
             
                if (crumbs[crumbs.length - 2] === 'view') {
         
     | 
| 
       3551 
     | 
    
         
            -
                  return this.module.showViewByObjectId(id, this.config, title 
     | 
| 
      
 3489 
     | 
    
         
            +
                  return this.module.showViewByObjectId(id, this.config, title);
         
     | 
| 
       3552 
3490 
     | 
    
         
             
                }
         
     | 
| 
       3553 
3491 
     | 
    
         
             
                if (this.config.objectStore) {
         
     | 
| 
       3554 
     | 
    
         
            -
                  return this.module.showViewByObjectId('', this.config, title 
     | 
| 
      
 3492 
     | 
    
         
            +
                  return this.module.showViewByObjectId('', this.config, title);
         
     | 
| 
       3555 
3493 
     | 
    
         
             
                }
         
     | 
| 
       3556 
     | 
    
         
            -
                return this.module.showNestedList(_last(crumbs) 
     | 
| 
      
 3494 
     | 
    
         
            +
                return this.module.showNestedList(_last(crumbs));
         
     | 
| 
       3557 
3495 
     | 
    
         
             
              };
         
     | 
| 
       3558 
3496 
     | 
    
         | 
| 
       3559 
3497 
     | 
    
         
             
              Item.prototype.render = function() {
         
     | 
| 
         @@ -3599,26 +3537,6 @@ this.View = (function() { 
     | 
|
| 
       3599 
3537 
     | 
    
         
             
                if (this.config.fullsizeView) {
         
     | 
| 
       3600 
3538 
     | 
    
         
             
                  this.$el.addClass('fullsize');
         
     | 
| 
       3601 
3539 
     | 
    
         
             
                }
         
     | 
| 
       3602 
     | 
    
         
            -
                this.onShowAnimation = this.config.onShowAnimation;
         
     | 
| 
       3603 
     | 
    
         
            -
                this.onCloseAnimation = this.config.onCloseAnimation;
         
     | 
| 
       3604 
     | 
    
         
            -
                if (this.onShowAnimation == null) {
         
     | 
| 
       3605 
     | 
    
         
            -
                  this.onShowAnimation = (function(_this) {
         
     | 
| 
       3606 
     | 
    
         
            -
                    return function(callback) {
         
     | 
| 
       3607 
     | 
    
         
            -
                      return _this.$el.fadeIn($.fx.speeds._default, function() {
         
     | 
| 
       3608 
     | 
    
         
            -
                        return callback();
         
     | 
| 
       3609 
     | 
    
         
            -
                      });
         
     | 
| 
       3610 
     | 
    
         
            -
                    };
         
     | 
| 
       3611 
     | 
    
         
            -
                  })(this);
         
     | 
| 
       3612 
     | 
    
         
            -
                }
         
     | 
| 
       3613 
     | 
    
         
            -
                if (this.onCloseAnimation == null) {
         
     | 
| 
       3614 
     | 
    
         
            -
                  this.onCloseAnimation = (function(_this) {
         
     | 
| 
       3615 
     | 
    
         
            -
                    return function(callback) {
         
     | 
| 
       3616 
     | 
    
         
            -
                      return _this.$el.fadeOut($.fx.speeds._default, function() {
         
     | 
| 
       3617 
     | 
    
         
            -
                        return callback();
         
     | 
| 
       3618 
     | 
    
         
            -
                      });
         
     | 
| 
       3619 
     | 
    
         
            -
                    };
         
     | 
| 
       3620 
     | 
    
         
            -
                  })(this);
         
     | 
| 
       3621 
     | 
    
         
            -
                }
         
     | 
| 
       3622 
3540 
     | 
    
         
             
                this.$header = $("<header></header>");
         
     | 
| 
       3623 
3541 
     | 
    
         
             
                this.$title = $("<div class='title'></div>");
         
     | 
| 
       3624 
3542 
     | 
    
         
             
                this.$header.append(this.$title);
         
     | 
| 
         @@ -3690,11 +3608,7 @@ this.View = (function() { 
     | 
|
| 
       3690 
3608 
     | 
    
         
             
              };
         
     | 
| 
       3691 
3609 
     | 
    
         | 
| 
       3692 
3610 
     | 
    
         
             
              View.prototype._close = function(e) {
         
     | 
| 
       3693 
     | 
    
         
            -
                return this. 
     | 
| 
       3694 
     | 
    
         
            -
                  return function() {
         
     | 
| 
       3695 
     | 
    
         
            -
                    return _this.destroy();
         
     | 
| 
       3696 
     | 
    
         
            -
                  };
         
     | 
| 
       3697 
     | 
    
         
            -
                })(this));
         
     | 
| 
      
 3611 
     | 
    
         
            +
                return this.destroy();
         
     | 
| 
       3698 
3612 
     | 
    
         
             
              };
         
     | 
| 
       3699 
3613 
     | 
    
         | 
| 
       3700 
3614 
     | 
    
         
             
              View.prototype._save = function(e) {
         
     | 
| 
         @@ -3741,10 +3655,8 @@ this.View = (function() { 
     | 
|
| 
       3741 
3655 
     | 
    
         
             
                  return this.store.remove(this.object._id, {
         
     | 
| 
       3742 
3656 
     | 
    
         
             
                    onSuccess: (function(_this) {
         
     | 
| 
       3743 
3657 
     | 
    
         
             
                      return function() {
         
     | 
| 
       3744 
     | 
    
         
            -
                         
     | 
| 
       3745 
     | 
    
         
            -
             
     | 
| 
       3746 
     | 
    
         
            -
                          return _this.destroy();
         
     | 
| 
       3747 
     | 
    
         
            -
                        });
         
     | 
| 
      
 3658 
     | 
    
         
            +
                        chr.updateHash("#/" + _this.closePath, true);
         
     | 
| 
      
 3659 
     | 
    
         
            +
                        return _this.destroy();
         
     | 
| 
       3748 
3660 
     | 
    
         
             
                      };
         
     | 
| 
       3749 
3661 
     | 
    
         
             
                    })(this),
         
     | 
| 
       3750 
3662 
     | 
    
         
             
                    onError: function() {
         
     | 
| 
         @@ -3754,9 +3666,8 @@ this.View = (function() { 
     | 
|
| 
       3754 
3666 
     | 
    
         
             
                }
         
     | 
| 
       3755 
3667 
     | 
    
         
             
              };
         
     | 
| 
       3756 
3668 
     | 
    
         | 
| 
       3757 
     | 
    
         
            -
              View.prototype.show = function( 
     | 
| 
       3758 
     | 
    
         
            -
                 
     | 
| 
       3759 
     | 
    
         
            -
                after_show = (function(_this) {
         
     | 
| 
      
 3669 
     | 
    
         
            +
              View.prototype.show = function(callback) {
         
     | 
| 
      
 3670 
     | 
    
         
            +
                return this.$el.show(0, (function(_this) {
         
     | 
| 
       3760 
3671 
     | 
    
         
             
                  return function() {
         
     | 
| 
       3761 
3672 
     | 
    
         
             
                    var base;
         
     | 
| 
       3762 
3673 
     | 
    
         
             
                    if (typeof callback === "function") {
         
     | 
| 
         @@ -3765,20 +3676,7 @@ this.View = (function() { 
     | 
|
| 
       3765 
3676 
     | 
    
         
             
                    _this.form.initializePlugins();
         
     | 
| 
       3766 
3677 
     | 
    
         
             
                    return typeof (base = _this.config).onViewShow === "function" ? base.onViewShow(_this) : void 0;
         
     | 
| 
       3767 
3678 
     | 
    
         
             
                  };
         
     | 
| 
       3768 
     | 
    
         
            -
                })(this);
         
     | 
| 
       3769 
     | 
    
         
            -
                if (animate) {
         
     | 
| 
       3770 
     | 
    
         
            -
                  return this.onShowAnimation((function(_this) {
         
     | 
| 
       3771 
     | 
    
         
            -
                    return function() {
         
     | 
| 
       3772 
     | 
    
         
            -
                      return after_show();
         
     | 
| 
       3773 
     | 
    
         
            -
                    };
         
     | 
| 
       3774 
     | 
    
         
            -
                  })(this));
         
     | 
| 
       3775 
     | 
    
         
            -
                } else {
         
     | 
| 
       3776 
     | 
    
         
            -
                  return this.$el.show(0, (function(_this) {
         
     | 
| 
       3777 
     | 
    
         
            -
                    return function() {
         
     | 
| 
       3778 
     | 
    
         
            -
                      return after_show();
         
     | 
| 
       3779 
     | 
    
         
            -
                    };
         
     | 
| 
       3780 
     | 
    
         
            -
                  })(this));
         
     | 
| 
       3781 
     | 
    
         
            -
                }
         
     | 
| 
      
 3679 
     | 
    
         
            +
                })(this));
         
     | 
| 
       3782 
3680 
     | 
    
         
             
              };
         
     | 
| 
       3783 
3681 
     | 
    
         | 
| 
       3784 
3682 
     | 
    
         
             
              View.prototype.destroy = function() {
         
     | 
    
        data/dist/input-redactor.js
    CHANGED
    
    | 
         @@ -31,19 +31,16 @@ 
     | 
|
| 
       31 
31 
     | 
    
         
             
                isFocused: false,
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
       33 
33 
     | 
    
         
             
                checkOffset: function () {
         
     | 
| 
       34 
     | 
    
         
            -
                   
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
                    } else {
         
     | 
| 
       45 
     | 
    
         
            -
                      this.unfix();
         
     | 
| 
       46 
     | 
    
         
            -
                    }
         
     | 
| 
      
 34 
     | 
    
         
            +
                  var boxOffset = this.redactor.$box.offset();
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  var isBelowBoxTop = boxOffset.top - this.viewHeaderHeight <= 0;
         
     | 
| 
      
 37 
     | 
    
         
            +
                  //var isAboveBoxBottom = boxOffset.top + this.redactor.$box.outerHeight() - this.redactor.$toolbar.outerHeight() - this.$window.scrollTop() >= 0;
         
     | 
| 
      
 38 
     | 
    
         
            +
                  var isAboveBoxBottom = this.redactor.$box.outerHeight() + boxOffset.top - this.viewHeaderHeight - this.redactor.$toolbar.outerHeight() >= 0;
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  if (isBelowBoxTop && isAboveBoxBottom) {
         
     | 
| 
      
 41 
     | 
    
         
            +
                    this.fix();
         
     | 
| 
      
 42 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 43 
     | 
    
         
            +
                    this.unfix();
         
     | 
| 
       47 
44 
     | 
    
         
             
                  }
         
     | 
| 
       48 
45 
     | 
    
         
             
                },
         
     | 
| 
       49 
46 
     | 
    
         | 
| 
         @@ -126,14 +123,18 @@ this.InputRedactor = (function(superClass) { 
     | 
|
| 
       126 
123 
     | 
    
         
             
              };
         
     | 
| 
       127 
124 
     | 
    
         | 
| 
       128 
125 
     | 
    
         
             
              InputRedactor.prototype.initialize = function() {
         
     | 
| 
       129 
     | 
    
         
            -
                var base, base1, redactor_options;
         
     | 
| 
      
 126 
     | 
    
         
            +
                var base, base1, plugins, redactor_options;
         
     | 
| 
      
 127 
     | 
    
         
            +
                plugins = ['fixedtoolbar'];
         
     | 
| 
      
 128 
     | 
    
         
            +
                if (Loft) {
         
     | 
| 
      
 129 
     | 
    
         
            +
                  plugins.push('loft');
         
     | 
| 
      
 130 
     | 
    
         
            +
                }
         
     | 
| 
       130 
131 
     | 
    
         
             
                redactor_options = {
         
     | 
| 
       131 
132 
     | 
    
         
             
                  focus: false,
         
     | 
| 
       132 
133 
     | 
    
         
             
                  imageFloatMargin: '20px',
         
     | 
| 
       133 
134 
     | 
    
         
             
                  buttonSource: true,
         
     | 
| 
       134 
135 
     | 
    
         
             
                  pastePlainText: true,
         
     | 
| 
       135 
     | 
    
         
            -
                  plugins:  
     | 
| 
       136 
     | 
    
         
            -
                  buttons: ['html', 'formatting', 'bold', 'italic', 'deleted', ' 
     | 
| 
      
 136 
     | 
    
         
            +
                  plugins: plugins,
         
     | 
| 
      
 137 
     | 
    
         
            +
                  buttons: ['html', 'formatting', 'bold', 'italic', 'deleted', 'unorderedlist', 'orderedlist', 'link']
         
     | 
| 
       137 
138 
     | 
    
         
             
                };
         
     | 
| 
       138 
139 
     | 
    
         
             
                if ((base = this.config).redactorOptions == null) {
         
     | 
| 
       139 
140 
     | 
    
         
             
                  base.redactorOptions = {};
         
     | 
    
        data/docs/bootstrap.md
    ADDED
    
    | 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Character
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            ## Bootstrap Data
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            Bootstrapped data configuration example with disabled item updates and pagination:
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            ```coffee
         
     | 
| 
      
 8 
     | 
    
         
            +
            postsConfig = (data) ->
         
     | 
| 
      
 9 
     | 
    
         
            +
              itemTitleField:     'title'
         
     | 
| 
      
 10 
     | 
    
         
            +
              disableUpdateItems: true
         
     | 
| 
      
 11 
     | 
    
         
            +
              objects:            data.posts
         
     | 
| 
      
 12 
     | 
    
         
            +
              arrayStore: new MongosteenArrayStore({
         
     | 
| 
      
 13 
     | 
    
         
            +
                resource:    'post'
         
     | 
| 
      
 14 
     | 
    
         
            +
                path:        '/admin/posts'
         
     | 
| 
      
 15 
     | 
    
         
            +
                sortBy:      'title'
         
     | 
| 
      
 16 
     | 
    
         
            +
                pagination:  false
         
     | 
| 
      
 17 
     | 
    
         
            +
              })
         
     | 
| 
      
 18 
     | 
    
         
            +
              formSchema:
         
     | 
| 
      
 19 
     | 
    
         
            +
                title: { type: 'string' }
         
     | 
| 
      
 20 
     | 
    
         
            +
                body:  { type: 'text'   }
         
     | 
| 
      
 21 
     | 
    
         
            +
            ```
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            ```disableUpdateItems``` — do not update items in the list while navigation, ```objects``` — provides initial (bootstrapped) array of objects to be added to the list, ```pagination``` — disable pagination for list. If attached as modules root list, you can access store data with: ```chr.modules.posts.arrayStore.data()```.
         
     | 
    
        data/docs/rails.md
    ADDED
    
    | 
         @@ -0,0 +1,255 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Character
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            ## Rails
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            An example of admin implementation setup for [Rails](https://github.com/rails/rails) app that uses [Mongoid](https://github.com/mongoid/mongoid) stack.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            ### Gems
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            Add to following gems to ```Gemfile```:
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                gem "devise"
         
     | 
| 
      
 13 
     | 
    
         
            +
                gem "mongosteen"
         
     | 
| 
      
 14 
     | 
    
         
            +
                gem "chr"
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            This example uses ```devise``` for admins authentication.
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            ### Admin authentication
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            Start with running [devise](https://github.com/plataformatec/devise) generator:
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                rails generate devise:install
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            Setup ```Admin``` model with devise generator:
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                rails generate devise admin
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            Here is an example of basic ```app/models/admin.rb``` model that provides email/password authentication:
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 32 
     | 
    
         
            +
            class Admin
         
     | 
| 
      
 33 
     | 
    
         
            +
              include Mongoid::Document
         
     | 
| 
      
 34 
     | 
    
         
            +
              include Mongoid::Timestamps
         
     | 
| 
      
 35 
     | 
    
         
            +
              include Mongoid::SerializableId
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              devise :database_authenticatable,
         
     | 
| 
      
 38 
     | 
    
         
            +
                     :rememberable,
         
     | 
| 
      
 39 
     | 
    
         
            +
                     :authentication_keys => [ :email ]
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              ## Database authenticatable
         
     | 
| 
      
 42 
     | 
    
         
            +
              field :email,              type: String, default: ""
         
     | 
| 
      
 43 
     | 
    
         
            +
              field :encrypted_password, type: String, default: ""
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
              ## Rememberable
         
     | 
| 
      
 46 
     | 
    
         
            +
              field :remember_created_at, type: Time
         
     | 
| 
      
 47 
     | 
    
         
            +
            end
         
     | 
| 
      
 48 
     | 
    
         
            +
            ```
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            When models are ready, setup controllers, views and configure routes.
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            Base admin controller ```app/controllers/admin/base_controller.rb``` looks like this:
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 55 
     | 
    
         
            +
            class Admin::BaseController < ActionController::Base
         
     | 
| 
      
 56 
     | 
    
         
            +
              protect_from_forgery
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
              if Rails.env.production?
         
     | 
| 
      
 59 
     | 
    
         
            +
                before_action :authenticate_admin!
         
     | 
| 
      
 60 
     | 
    
         
            +
              end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
              def index
         
     | 
| 
      
 63 
     | 
    
         
            +
                render '/admin/index', layout: 'admin'
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
              def bootstrap_data
         
     | 
| 
      
 67 
     | 
    
         
            +
                render json: {}
         
     | 
| 
      
 68 
     | 
    
         
            +
              end
         
     | 
| 
      
 69 
     | 
    
         
            +
            end
         
     | 
| 
      
 70 
     | 
    
         
            +
            ```
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            Notes on code above:
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
              1. Authentication is not required when running in development or testing environment;
         
     | 
| 
      
 75 
     | 
    
         
            +
              2. Need to setup ```index``` view and ```admin``` layout to render admin app;
         
     | 
| 
      
 76 
     | 
    
         
            +
              3. ```bootstrap_data``` is a placeholder for objects that might be required to be loaded when app starts.
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            Devise would require a custom ```SessionController``` implementation in ```app/controllers/admin/devise_overrides/session_controller.rb```. ```SessionController``` sets ```admin``` layout to be used for devise views rendering and enables login by email (*looks like workaround*).
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 81 
     | 
    
         
            +
            class Admin::DeviseOverrides::SessionsController < Devise::SessionsController
         
     | 
| 
      
 82 
     | 
    
         
            +
              layout 'admin'
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
              protected
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                def configure_permitted_parameters
         
     | 
| 
      
 87 
     | 
    
         
            +
                  devise_parameter_sanitizer.for(:sign_in) << :email
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
            end
         
     | 
| 
      
 90 
     | 
    
         
            +
            ```
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            Admin app layout ```app/views/layouts/admin.html.erb```:
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            ```erb
         
     | 
| 
      
 95 
     | 
    
         
            +
            <!doctype html>
         
     | 
| 
      
 96 
     | 
    
         
            +
            <html>
         
     | 
| 
      
 97 
     | 
    
         
            +
              <head>
         
     | 
| 
      
 98 
     | 
    
         
            +
                <meta charset="utf-8">
         
     | 
| 
      
 99 
     | 
    
         
            +
                <meta http-equiv="X-UA-Compatible" content="IE=edge">
         
     | 
| 
      
 100 
     | 
    
         
            +
                <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
         
     | 
| 
      
 101 
     | 
    
         
            +
                <meta name="apple-mobile-web-app-capable" content="yes">
         
     | 
| 
      
 102 
     | 
    
         
            +
                <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
         
     | 
| 
      
 103 
     | 
    
         
            +
                <title>Admin</title>
         
     | 
| 
      
 104 
     | 
    
         
            +
                <%= csrf_meta_tags %>
         
     | 
| 
      
 105 
     | 
    
         
            +
                <%= stylesheet_link_tag    :admin, media: "all" %>
         
     | 
| 
      
 106 
     | 
    
         
            +
                <%= javascript_include_tag :admin %>
         
     | 
| 
      
 107 
     | 
    
         
            +
              </head>
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
              <%= yield %>
         
     | 
| 
      
 110 
     | 
    
         
            +
            </html>
         
     | 
| 
      
 111 
     | 
    
         
            +
            ```
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
            Admin index view ```app/views/admin/index.html.erb```:
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
            ```erb
         
     | 
| 
      
 116 
     | 
    
         
            +
            <body class='loading'>
         
     | 
| 
      
 117 
     | 
    
         
            +
              <%= link_to 'Sign Out', destroy_admin_session_path, method: :delete, style: 'display:none;' %>
         
     | 
| 
      
 118 
     | 
    
         
            +
            </body>
         
     | 
| 
      
 119 
     | 
    
         
            +
            ```
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
            New session view for devise ```app/views/admin/devise_overrides/sessions/new.html.erb```:
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
            ```erb
         
     | 
| 
      
 124 
     | 
    
         
            +
            <body class='sign-in'>
         
     | 
| 
      
 125 
     | 
    
         
            +
              <h2>Sign In</h2>
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
              <%= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
         
     | 
| 
      
 128 
     | 
    
         
            +
                <% if alert %>
         
     | 
| 
      
 129 
     | 
    
         
            +
                  <p class="error"><%= alert.gsub('username', 'email').gsub('or sign up', '') %></p>
         
     | 
| 
      
 130 
     | 
    
         
            +
                <% end %>
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                <div class="form-inputs">
         
     | 
| 
      
 133 
     | 
    
         
            +
                  <%= f.input :email,    required: true, autofocus: true %>
         
     | 
| 
      
 134 
     | 
    
         
            +
                  <%= f.input :password, required: true %>
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                  <%= f.input :remember_me, as: :boolean if devise_mapping.rememberable? %>
         
     | 
| 
      
 137 
     | 
    
         
            +
                </div>
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                <div class="form-actions">
         
     | 
| 
      
 140 
     | 
    
         
            +
                  <%= f.button :submit, "Sign In" %>
         
     | 
| 
      
 141 
     | 
    
         
            +
                </div>
         
     | 
| 
      
 142 
     | 
    
         
            +
              <% end %>
         
     | 
| 
      
 143 
     | 
    
         
            +
            </body>
         
     | 
| 
      
 144 
     | 
    
         
            +
            ```
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
            Now connect admin and devise in ```config/routes.rb``` with:
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 149 
     | 
    
         
            +
            devise_for :admins, path: "admin", controllers: { sessions: "admin/devise_overrides/sessions" }
         
     | 
| 
      
 150 
     | 
    
         
            +
            namespace :admin do
         
     | 
| 
      
 151 
     | 
    
         
            +
              get '/'               => 'base#index'
         
     | 
| 
      
 152 
     | 
    
         
            +
              get '/bootstrap.json' => 'base#bootstrap_data'
         
     | 
| 
      
 153 
     | 
    
         
            +
            end
         
     | 
| 
      
 154 
     | 
    
         
            +
            ```
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
            ### Character setup
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
            Three pieces to be configured here.
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
            **First**: create ```app/assets/javascripts/admin.coffee``` with empty ```modules``` configuration:
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
            ```coffee
         
     | 
| 
      
 164 
     | 
    
         
            +
            #= require jquery
         
     | 
| 
      
 165 
     | 
    
         
            +
            #= require jquery_ujs
         
     | 
| 
      
 166 
     | 
    
         
            +
            #= require chr
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
            $ ->
         
     | 
| 
      
 169 
     | 
    
         
            +
              $.get '/admin/bootstrap.json', (response) ->
         
     | 
| 
      
 170 
     | 
    
         
            +
                config =
         
     | 
| 
      
 171 
     | 
    
         
            +
                  modules: {}
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
                $('body').removeClass('loading')
         
     | 
| 
      
 174 
     | 
    
         
            +
                chr.start(config)
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                # append signout button to the end of sidebar menu
         
     | 
| 
      
 177 
     | 
    
         
            +
                $('a[data-method=delete]').appendTo(".sidebar .menu").show()
         
     | 
| 
      
 178 
     | 
    
         
            +
            ```
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
            **Second**: create foundation for style customization in ```app/assets/stylesheets/admin.scss```:
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
            ```scss
         
     | 
| 
      
 183 
     | 
    
         
            +
            @charset "utf-8";
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
            @import "normalize-rails";
         
     | 
| 
      
 186 
     | 
    
         
            +
            @import "chr";
         
     | 
| 
      
 187 
     | 
    
         
            +
            @import "admin/signin";
         
     | 
| 
      
 188 
     | 
    
         
            +
            ```
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
            Last import in the code above is optional. But here is a default source for it as well ```app/assets/stylesheets/admin/chr/_signin.scss```:
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
            ```scss
         
     | 
| 
      
 193 
     | 
    
         
            +
            .sign-in {
         
     | 
| 
      
 194 
     | 
    
         
            +
              font-size: 14px;
         
     | 
| 
      
 195 
     | 
    
         
            +
              color: #555;
         
     | 
| 
      
 196 
     | 
    
         
            +
              margin: 3em 0 0 3em;
         
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
      
 198 
     | 
    
         
            +
              h2 {
         
     | 
| 
      
 199 
     | 
    
         
            +
                text-transform: uppercase;
         
     | 
| 
      
 200 
     | 
    
         
            +
                font-size: 1em;
         
     | 
| 
      
 201 
     | 
    
         
            +
                font-size: 16px;
         
     | 
| 
      
 202 
     | 
    
         
            +
                color: $black;
         
     | 
| 
      
 203 
     | 
    
         
            +
                margin-bottom: 1.5em;
         
     | 
| 
      
 204 
     | 
    
         
            +
              }
         
     | 
| 
      
 205 
     | 
    
         
            +
             
     | 
| 
      
 206 
     | 
    
         
            +
              p {
         
     | 
| 
      
 207 
     | 
    
         
            +
                margin: -1.5em 0 2em;
         
     | 
| 
      
 208 
     | 
    
         
            +
                color: $positiveColor;
         
     | 
| 
      
 209 
     | 
    
         
            +
              }
         
     | 
| 
      
 210 
     | 
    
         
            +
             
     | 
| 
      
 211 
     | 
    
         
            +
              .form-actions, .form-inputs {
         
     | 
| 
      
 212 
     | 
    
         
            +
                max-width: 280px;
         
     | 
| 
      
 213 
     | 
    
         
            +
              }
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
              .input {
         
     | 
| 
      
 216 
     | 
    
         
            +
                margin-bottom: 1.5em;
         
     | 
| 
      
 217 
     | 
    
         
            +
              }
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
              input.string, input.password {
         
     | 
| 
      
 220 
     | 
    
         
            +
                float: right;
         
     | 
| 
      
 221 
     | 
    
         
            +
                margin-top: -.45em;
         
     | 
| 
      
 222 
     | 
    
         
            +
                padding: .25em .5em;
         
     | 
| 
      
 223 
     | 
    
         
            +
                width: 13.5em;
         
     | 
| 
      
 224 
     | 
    
         
            +
              }
         
     | 
| 
      
 225 
     | 
    
         
            +
             
     | 
| 
      
 226 
     | 
    
         
            +
              label.boolean input {
         
     | 
| 
      
 227 
     | 
    
         
            +
                margin-right: .25em;
         
     | 
| 
      
 228 
     | 
    
         
            +
              }
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
              .form-actions input {
         
     | 
| 
      
 231 
     | 
    
         
            +
                width: 100%;
         
     | 
| 
      
 232 
     | 
    
         
            +
                padding: 1em 2em;
         
     | 
| 
      
 233 
     | 
    
         
            +
                background-color: $positiveColor;
         
     | 
| 
      
 234 
     | 
    
         
            +
                border: 0;
         
     | 
| 
      
 235 
     | 
    
         
            +
                color: $white;
         
     | 
| 
      
 236 
     | 
    
         
            +
              }
         
     | 
| 
      
 237 
     | 
    
         
            +
            }
         
     | 
| 
      
 238 
     | 
    
         
            +
            ```
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
      
 240 
     | 
    
         
            +
            **Third**: make sure admin assets are precompiled on production, include ```admin.js``` and ```admin.css``` in ```config/initializers/assets.rb```:
         
     | 
| 
      
 241 
     | 
    
         
            +
             
     | 
| 
      
 242 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 243 
     | 
    
         
            +
            Rails.application.config.assets.precompile += %w( admin.js admin.css )
         
     | 
| 
      
 244 
     | 
    
         
            +
            ```
         
     | 
| 
      
 245 
     | 
    
         
            +
             
     | 
| 
      
 246 
     | 
    
         
            +
            At this point initial setup for admin app is finished and it could be accessed via: ```localhost:3000/admin```.
         
     | 
| 
      
 247 
     | 
    
         
            +
             
     | 
| 
      
 248 
     | 
    
         
            +
             
     | 
| 
      
 249 
     | 
    
         
            +
            ### Add models
         
     | 
| 
      
 250 
     | 
    
         
            +
             
     | 
| 
      
 251 
     | 
    
         
            +
            To be continued...
         
     | 
| 
      
 252 
     | 
    
         
            +
             
     | 
| 
      
 253 
     | 
    
         
            +
             
     | 
| 
      
 254 
     | 
    
         
            +
             
     | 
| 
      
 255 
     | 
    
         
            +
             
     | 
    
        data/lib/chr/version.rb
    CHANGED
    
    
    
        data/package.json
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: chr
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.2. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.2.5
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Alexander Kravets
         
     | 
| 
         @@ -133,11 +133,12 @@ files: 
     | 
|
| 
       133 
133 
     | 
    
         
             
            - dist/input-redactor.js
         
     | 
| 
       134 
134 
     | 
    
         
             
            - docs/assets.md
         
     | 
| 
       135 
135 
     | 
    
         
             
            - docs/basics.md
         
     | 
| 
       136 
     | 
    
         
            -
            - docs/bootstrap 
     | 
| 
      
 136 
     | 
    
         
            +
            - docs/bootstrap.md
         
     | 
| 
       137 
137 
     | 
    
         
             
            - docs/custom-inputs.md
         
     | 
| 
       138 
138 
     | 
    
         
             
            - docs/form.md
         
     | 
| 
       139 
139 
     | 
    
         
             
            - docs/internals.md
         
     | 
| 
       140 
140 
     | 
    
         
             
            - docs/nested-forms.md
         
     | 
| 
      
 141 
     | 
    
         
            +
            - docs/rails.md
         
     | 
| 
       141 
142 
     | 
    
         
             
            - docs/redactor-js.md
         
     | 
| 
       142 
143 
     | 
    
         
             
            - docs/scopes.md
         
     | 
| 
       143 
144 
     | 
    
         
             
            - lib/chr.rb
         
     | 
    
        data/docs/bootstrap-data.md
    DELETED
    
    | 
         
            File without changes
         
     |