luca 0.6.6

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.
Files changed (233) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +17 -0
  3. data/Gemfile.lock +77 -0
  4. data/Guardfile +22 -0
  5. data/README.md +291 -0
  6. data/Rakefile +28 -0
  7. data/app.rb +46 -0
  8. data/assets/images/glyphicons-halflings-white.png +0 -0
  9. data/assets/images/glyphicons-halflings.png +0 -0
  10. data/assets/javascripts/dependencies/backbone-min.js +37 -0
  11. data/assets/javascripts/dependencies/backbone-query.min.js +1 -0
  12. data/assets/javascripts/dependencies/bootstrap.min.js +1 -0
  13. data/assets/javascripts/dependencies/jasmine-html.js +190 -0
  14. data/assets/javascripts/dependencies/jasmine.js +2476 -0
  15. data/assets/javascripts/dependencies/jquery.js +4 -0
  16. data/assets/javascripts/dependencies/modal.js +698 -0
  17. data/assets/javascripts/dependencies/modernizr.min.js +30 -0
  18. data/assets/javascripts/dependencies/prettify.js +28 -0
  19. data/assets/javascripts/dependencies/sinon.js +3469 -0
  20. data/assets/javascripts/dependencies/spin-min.js +2 -0
  21. data/assets/javascripts/dependencies/underscore-min.js +31 -0
  22. data/assets/javascripts/dependencies/underscore-string.min.js +14 -0
  23. data/assets/javascripts/dependencies.coffee +7 -0
  24. data/assets/javascripts/luca-ui-base.coffee +12 -0
  25. data/assets/javascripts/luca-ui-spec.coffee +2 -0
  26. data/assets/javascripts/luca-ui.coffee +3 -0
  27. data/assets/javascripts/sandbox/collections/sample.coffee +0 -0
  28. data/assets/javascripts/sandbox/config.coffee +7 -0
  29. data/assets/javascripts/sandbox/sandbox.coffee +16 -0
  30. data/assets/javascripts/sandbox/templates/features/collection_helpers.luca +33 -0
  31. data/assets/javascripts/sandbox/templates/features/form_demo_code.luca +48 -0
  32. data/assets/javascripts/sandbox/templates/features/grid_demo_code.luca +24 -0
  33. data/assets/javascripts/sandbox/templates/features/introduction.luca +11 -0
  34. data/assets/javascripts/sandbox/templates/features/view_helpers.luca +43 -0
  35. data/assets/javascripts/sandbox/templates/navigation.luca +8 -0
  36. data/assets/javascripts/sandbox/views/form_demo.coffee +47 -0
  37. data/assets/javascripts/sandbox/views/grid_demo.coffee +23 -0
  38. data/assets/javascripts/sandbox/views/pages/collection_events_sample.coffee +1 -0
  39. data/assets/javascripts/sandbox/views/pages/pages_controller.coffee +28 -0
  40. data/assets/javascripts/sandbox.coffee +4 -0
  41. data/assets/javascripts/spec-dependencies.coffee +4 -0
  42. data/assets/stylesheets/bootstrap-responsive.min.css +3 -0
  43. data/assets/stylesheets/bootstrap.min.css +610 -0
  44. data/assets/stylesheets/jasmine.css +166 -0
  45. data/assets/stylesheets/luca-ui-bootstrap.css +5 -0
  46. data/assets/stylesheets/luca-ui-spec.css +3 -0
  47. data/assets/stylesheets/luca-ui.css +3 -0
  48. data/assets/stylesheets/prettify.css +40 -0
  49. data/assets/stylesheets/sandbox/sandbox.scss +4 -0
  50. data/assets/stylesheets/sandbox.css +3 -0
  51. data/config.ru +11 -0
  52. data/lib/luca/command_line.rb +69 -0
  53. data/lib/luca/rails/engine.rb +12 -0
  54. data/lib/luca/rails/version.rb +6 -0
  55. data/lib/luca/rails.rb +9 -0
  56. data/lib/luca/template.rb +51 -0
  57. data/lib/luca/test_harness.rb +106 -0
  58. data/lib/luca.rb +1 -0
  59. data/lib/sprockets/luca_template.rb +49 -0
  60. data/lib/templates/spec_manifest_javascripts.erb +7 -0
  61. data/lib/templates/spec_manifest_stylesheets.erb +11 -0
  62. data/luca.gemspec +26 -0
  63. data/public/jasmine/index.html +26 -0
  64. data/public/sandbox/api.js +1 -0
  65. data/spec/components/application_spec.coffee +0 -0
  66. data/spec/components/collection_loader_view_spec.coffee +0 -0
  67. data/spec/components/controller_spec.coffee +0 -0
  68. data/spec/components/form_view_spec.coffee +13 -0
  69. data/spec/components/grid_view_spec.coffee +0 -0
  70. data/spec/components/record_manager_spec.coffee +0 -0
  71. data/spec/components/template_spec.coffee +0 -0
  72. data/spec/containers/card_view_spec.coffee +1 -0
  73. data/spec/containers/column_view_spec.coffee +0 -0
  74. data/spec/containers/modal_view_spec.coffee +0 -0
  75. data/spec/containers/panel_view_spec.coffee +0 -0
  76. data/spec/containers/split_view_spec.coffee +0 -0
  77. data/spec/containers/tab_view_spec.coffee +0 -0
  78. data/spec/containers/viewport_spec.coffee +0 -0
  79. data/spec/core/collection_spec.coffee +215 -0
  80. data/spec/core/container_spec.coffee +0 -0
  81. data/spec/core/field_spec.coffee +0 -0
  82. data/spec/core/observer_spec.coffee +0 -0
  83. data/spec/core/view_spec.coffee +87 -0
  84. data/spec/framework_spec.coffee +48 -0
  85. data/spec/helper.coffee +120 -0
  86. data/spec/managers/collection_manager_spec.coffee +95 -0
  87. data/spec/managers/socket_manager_spec.coffee +0 -0
  88. data/src/components/application.coffee +83 -0
  89. data/src/components/base_toolbar.coffee +16 -0
  90. data/src/components/collection_loader_view.coffee +37 -0
  91. data/src/components/controller.coffee +41 -0
  92. data/src/components/fields/button_field.coffee +40 -0
  93. data/src/components/fields/checkbox_field.coffee +41 -0
  94. data/src/components/fields/file_upload_field.coffee +15 -0
  95. data/src/components/fields/hidden_field.coffee +18 -0
  96. data/src/components/fields/select_field.coffee +100 -0
  97. data/src/components/fields/text_area_field.coffee +43 -0
  98. data/src/components/fields/text_field.coffee +42 -0
  99. data/src/components/fields/type_ahead_field.coffee +10 -0
  100. data/src/components/form_button_toolbar.coffee +26 -0
  101. data/src/components/form_view.coffee +205 -0
  102. data/src/components/grid_view.coffee +208 -0
  103. data/src/components/record_manager.coffee +215 -0
  104. data/src/components/router.coffee +34 -0
  105. data/src/components/template.coffee +19 -0
  106. data/src/containers/card_view.coffee +89 -0
  107. data/src/containers/column_view.coffee +48 -0
  108. data/src/containers/modal_view.coffee +85 -0
  109. data/src/containers/panel_view.coffee +24 -0
  110. data/src/containers/split_view.coffee +12 -0
  111. data/src/containers/tab_view.coffee +77 -0
  112. data/src/containers/viewport.coffee +16 -0
  113. data/src/core/collection.coffee +319 -0
  114. data/src/core/container.coffee +256 -0
  115. data/src/core/field.coffee +68 -0
  116. data/src/core/observer.coffee +17 -0
  117. data/src/core/view.coffee +190 -0
  118. data/src/framework.coffee +110 -0
  119. data/src/index.coffee +255 -0
  120. data/src/managers/collection_manager.coffee +168 -0
  121. data/src/managers/socket_manager.coffee +54 -0
  122. data/src/modules/deferrable.coffee +18 -0
  123. data/src/modules/local_storage.coffee +50 -0
  124. data/src/stylesheets/base.scss +78 -0
  125. data/src/stylesheets/components/form_view.scss +54 -0
  126. data/src/stylesheets/components/grid_view.scss +111 -0
  127. data/src/stylesheets/components/toolbar.scss +15 -0
  128. data/src/stylesheets/containers/container.scss +7 -0
  129. data/src/stylesheets/containers/modal_view.scss +0 -0
  130. data/src/stylesheets/containers/tab_view.scss +33 -0
  131. data/src/stylesheets/normalize.scss +430 -0
  132. data/src/templates/components/bootstrap_form_controls.luca +7 -0
  133. data/src/templates/components/collection_loader_view.luca +5 -0
  134. data/src/templates/components/form_view.luca +15 -0
  135. data/src/templates/components/grid_view.luca +9 -0
  136. data/src/templates/components/grid_view_empty_text.luca +3 -0
  137. data/src/templates/containers/basic.luca +1 -0
  138. data/src/templates/containers/tab_selector_container.luca +8 -0
  139. data/src/templates/containers/tab_view.luca +1 -0
  140. data/src/templates/containers/toolbar_wrapper.luca +1 -0
  141. data/src/templates/fields/button_field.luca +2 -0
  142. data/src/templates/fields/button_field_link.luca +5 -0
  143. data/src/templates/fields/checkbox_field.luca +9 -0
  144. data/src/templates/fields/file_upload_field.luca +8 -0
  145. data/src/templates/fields/hidden_field.luca +1 -0
  146. data/src/templates/fields/select_field.luca +7 -0
  147. data/src/templates/fields/text_area_field.luca +8 -0
  148. data/src/templates/fields/text_field.luca +13 -0
  149. data/src/templates/sample/contents.luca +1 -0
  150. data/src/templates/sample/welcome.luca +1 -0
  151. data/vendor/assets/images/glyphicons-halflings-white.png +0 -0
  152. data/vendor/assets/images/glyphicons-halflings.png +0 -0
  153. data/vendor/assets/javascripts/luca-spec-dependencies.js +6135 -0
  154. data/vendor/assets/javascripts/luca-ui-base.js +1527 -0
  155. data/vendor/assets/javascripts/luca-ui-spec.js +3654 -0
  156. data/vendor/assets/javascripts/luca-ui.js +2763 -0
  157. data/vendor/assets/luca-ui/base.css +85 -0
  158. data/vendor/assets/luca-ui/components/application.js +91 -0
  159. data/vendor/assets/luca-ui/components/base_toolbar.js +23 -0
  160. data/vendor/assets/luca-ui/components/controller.js +38 -0
  161. data/vendor/assets/luca-ui/components/fields/button_field.js +45 -0
  162. data/vendor/assets/luca-ui/components/fields/checkbox_field.js +43 -0
  163. data/vendor/assets/luca-ui/components/fields/file_upload_field.js +20 -0
  164. data/vendor/assets/luca-ui/components/fields/hidden_field.js +20 -0
  165. data/vendor/assets/luca-ui/components/fields/select_field.js +97 -0
  166. data/vendor/assets/luca-ui/components/fields/text_area_field.js +48 -0
  167. data/vendor/assets/luca-ui/components/fields/text_field.js +46 -0
  168. data/vendor/assets/luca-ui/components/fields/type_ahead_field.js +13 -0
  169. data/vendor/assets/luca-ui/components/form_button_toolbar.js +32 -0
  170. data/vendor/assets/luca-ui/components/form_view.css +32 -0
  171. data/vendor/assets/luca-ui/components/form_view.js +207 -0
  172. data/vendor/assets/luca-ui/components/grid_view.css +76 -0
  173. data/vendor/assets/luca-ui/components/grid_view.js +202 -0
  174. data/vendor/assets/luca-ui/components/record_manager.js +207 -0
  175. data/vendor/assets/luca-ui/components/router.js +36 -0
  176. data/vendor/assets/luca-ui/components/template.js +26 -0
  177. data/vendor/assets/luca-ui/components/toolbar.css +11 -0
  178. data/vendor/assets/luca-ui/containers/card_view.js +98 -0
  179. data/vendor/assets/luca-ui/containers/column_view.js +52 -0
  180. data/vendor/assets/luca-ui/containers/container.css +3 -0
  181. data/vendor/assets/luca-ui/containers/modal_view.css +0 -0
  182. data/vendor/assets/luca-ui/containers/modal_view.js +87 -0
  183. data/vendor/assets/luca-ui/containers/panel_view.js +34 -0
  184. data/vendor/assets/luca-ui/containers/split_view.js +13 -0
  185. data/vendor/assets/luca-ui/containers/tab_view.css +16 -0
  186. data/vendor/assets/luca-ui/containers/tab_view.js +80 -0
  187. data/vendor/assets/luca-ui/containers/viewport.js +18 -0
  188. data/vendor/assets/luca-ui/core/collection.js +221 -0
  189. data/vendor/assets/luca-ui/core/container.js +205 -0
  190. data/vendor/assets/luca-ui/core/field.js +59 -0
  191. data/vendor/assets/luca-ui/core/observer.js +42 -0
  192. data/vendor/assets/luca-ui/core/view.js +127 -0
  193. data/vendor/assets/luca-ui/framework.js +110 -0
  194. data/vendor/assets/luca-ui/index.js +5 -0
  195. data/vendor/assets/luca-ui/managers/collection_manager.js +98 -0
  196. data/vendor/assets/luca-ui/managers/socket_manager.js +52 -0
  197. data/vendor/assets/luca-ui/modules/deferrable.js +21 -0
  198. data/vendor/assets/luca-ui/modules/local_storage.js +81 -0
  199. data/vendor/assets/luca-ui/normalize.css +359 -0
  200. data/vendor/assets/luca-ui/stylesheets/base.css +85 -0
  201. data/vendor/assets/luca-ui/stylesheets/components/form_view.css +32 -0
  202. data/vendor/assets/luca-ui/stylesheets/components/grid_view.css +76 -0
  203. data/vendor/assets/luca-ui/stylesheets/components/toolbar.css +11 -0
  204. data/vendor/assets/luca-ui/stylesheets/containers/container.css +3 -0
  205. data/vendor/assets/luca-ui/stylesheets/containers/modal_view.css +0 -0
  206. data/vendor/assets/luca-ui/stylesheets/containers/tab_view.css +16 -0
  207. data/vendor/assets/luca-ui/stylesheets/normalize.css +359 -0
  208. data/vendor/assets/luca-ui/templates/components/bootstrap_form_controls.js +4 -0
  209. data/vendor/assets/luca-ui/templates/components/form_view.js +4 -0
  210. data/vendor/assets/luca-ui/templates/components/grid_view.js +4 -0
  211. data/vendor/assets/luca-ui/templates/components/grid_view_empty_text.js +4 -0
  212. data/vendor/assets/luca-ui/templates/containers/basic.js +4 -0
  213. data/vendor/assets/luca-ui/templates/containers/tab_selector_container.js +4 -0
  214. data/vendor/assets/luca-ui/templates/containers/tab_view.js +4 -0
  215. data/vendor/assets/luca-ui/templates/containers/toolbar_wrapper.js +4 -0
  216. data/vendor/assets/luca-ui/templates/fields/button_field.js +4 -0
  217. data/vendor/assets/luca-ui/templates/fields/button_field_link.js +4 -0
  218. data/vendor/assets/luca-ui/templates/fields/checkbox_field.js +4 -0
  219. data/vendor/assets/luca-ui/templates/fields/file_upload_field.js +4 -0
  220. data/vendor/assets/luca-ui/templates/fields/hidden_field.js +4 -0
  221. data/vendor/assets/luca-ui/templates/fields/select_field.js +4 -0
  222. data/vendor/assets/luca-ui/templates/fields/text_area_field.js +4 -0
  223. data/vendor/assets/luca-ui/templates/fields/text_field.js +4 -0
  224. data/vendor/assets/luca-ui/templates/sample/contents.js +4 -0
  225. data/vendor/assets/luca-ui/templates/sample/welcome.js +4 -0
  226. data/vendor/assets/stylesheets/luca-spec-dependencies.css +166 -0
  227. data/vendor/assets/stylesheets/luca-ui-bootstrap.css +1201 -0
  228. data/vendor/assets/stylesheets/luca-ui-spec.css +586 -0
  229. data/vendor/assets/stylesheets/luca-ui.css +586 -0
  230. data/views/index.erb +20 -0
  231. data/views/jasmine.erb +22 -0
  232. data/views/spec_harness.erb +29 -0
  233. metadata +361 -0
@@ -0,0 +1,89 @@
1
+ Luca.containers.CardView = Luca.core.Container.extend
2
+ componentType: 'card_view'
3
+
4
+ className: 'luca-ui-card-view-wrapper'
5
+
6
+ activeCard: 0
7
+
8
+ components: []
9
+
10
+ hooks:[
11
+ 'before:card:switch',
12
+ 'after:card:switch'
13
+ ]
14
+
15
+ initialize: (@options)->
16
+ Luca.core.Container::initialize.apply @,arguments
17
+ @setupHooks(@hooks)
18
+
19
+ componentClass: 'luca-ui-card'
20
+
21
+ beforeLayout: ()->
22
+ @cards = _(@components).map (card,cardIndex) =>
23
+ classes: @componentClass
24
+ style: "display:#{ (if cardIndex is @activeCard then 'block' else 'none' )}"
25
+ id: "#{ @cid }-#{ cardIndex }"
26
+
27
+ prepareLayout: ()->
28
+ @card_containers = _( @cards ).map (card, index)=>
29
+ @$el.append Luca.templates["containers/basic"](card)
30
+ $("##{ card.id }")
31
+
32
+ prepareComponents: ()->
33
+ @components = _( @components ).map (object,index)=>
34
+ card = @cards[index]
35
+ object.container = "##{ card.id }"
36
+ object
37
+
38
+ activeComponent: ()->
39
+ @getComponent( @activeCard )
40
+
41
+ cycle: ()->
42
+ nextIndex = if @activeCard < @components.length - 1 then @activeCard + 1 else 0
43
+ @activate( nextIndex )
44
+
45
+ find: (name)->
46
+ @findComponentByName(name,true)
47
+
48
+ firstActivation: ()->
49
+ @activeComponent().trigger "first:activation", @, @activeComponent()
50
+
51
+ activate: (index, silent=false, callback)->
52
+ if _.isFunction(silent)
53
+ silent = false
54
+ callback = silent
55
+
56
+ return if index is @activeCard
57
+
58
+ previous = @activeComponent()
59
+ current = @getComponent(index)
60
+
61
+ if !current
62
+ index = @indexOf(index)
63
+ current = @getComponent( index )
64
+
65
+ return unless current
66
+
67
+ @trigger "before:card:switch", previous, current unless silent
68
+
69
+ _( @card_containers ).each (container)->
70
+ container.trigger?.apply(container, ["deactivation", @, previous, current])
71
+ container.hide()
72
+
73
+ unless current.previously_activated
74
+ current.trigger "first:activation"
75
+ current.previously_activated = true
76
+
77
+ $( current.container ).show()
78
+
79
+ @activeCard = index
80
+
81
+ unless silent
82
+ @trigger "after:card:switch", previous, current
83
+ current.trigger?.apply(current, ["activation", @, previous, current])
84
+
85
+
86
+ if _.isFunction(callback)
87
+ callback.apply @, [@,previous,current]
88
+
89
+ Luca.register 'card_view', "Luca.containers.CardView"
@@ -0,0 +1,48 @@
1
+ Luca.containers.ColumnView = Luca.core.Container.extend
2
+ componentType: 'column_view'
3
+
4
+ className: 'luca-ui-column-view'
5
+
6
+ components: []
7
+
8
+ initialize: (@options={})->
9
+ Luca.core.Container::initialize.apply @, arguments
10
+ @setColumnWidths()
11
+
12
+ componentClass: 'luca-ui-column'
13
+
14
+ containerTemplate: "containers/basic"
15
+
16
+ appendContainers: true
17
+
18
+ autoColumnWidths: ()->
19
+ widths = []
20
+
21
+ _( @components.length ).times ()=>
22
+ widths.push( parseInt( 100 / @components.length ) )
23
+
24
+ widths
25
+
26
+ setColumnWidths: ()->
27
+ @columnWidths = if @layout?
28
+ _( @layout.split('/') ).map((v)-> parseInt(v) )
29
+ else
30
+ @autoColumnWidths()
31
+
32
+ @columnWidths = _( @columnWidths ).map (val)-> "#{ val }%"
33
+
34
+ beforeComponents: ()->
35
+ @debug "column_view before components"
36
+ _( @components ).each (component)->
37
+ component.ctype ||= "panel_view"
38
+
39
+ beforeLayout: ()->
40
+ @debug "column_view before layout"
41
+
42
+ _(@columnWidths).each (width,index) =>
43
+ @components[index].float = "left"
44
+ @components[index].width = width
45
+
46
+ Luca.core.Container::beforeLayout?.apply @, arguments
47
+
48
+ Luca.register 'column_view', "Luca.containers.ColumnView"
@@ -0,0 +1,85 @@
1
+ Luca.containers.ModalView = Luca.core.Container.extend
2
+ componentType: 'modal_view'
3
+
4
+ className: 'luca-ui-modal-view'
5
+
6
+ components:[]
7
+
8
+ renderOnInitialize: true
9
+
10
+ showOnRender: false
11
+
12
+ hooks:[
13
+ 'before:show',
14
+ 'before:hide'
15
+ ]
16
+
17
+ defaultModalOptions:
18
+ minWidth: 375
19
+ maxWidth: 375
20
+ minHeight: 550
21
+ maxHeight: 550
22
+ opacity: 80
23
+ onOpen: (modal)->
24
+ @onOpen.apply @
25
+ @onModalOpen.apply modal, [modal, @]
26
+ onClose: (modal)->
27
+ @onClose.apply @
28
+ @onModalClose.apply modal, [modal, @]
29
+
30
+ modalOptions: {}
31
+
32
+ initialize: (@options={})->
33
+ Luca.core.Container::initialize.apply @,arguments
34
+ @setupHooks(@hooks)
35
+
36
+ _( @defaultModalOptions ).each (value,setting) => @modalOptions[ setting ] ||= value
37
+
38
+ @modalOptions.onOpen = _.bind( @modalOptions.onOpen, @)
39
+ @modalOptions.onClose = _.bind( @modalOptions.onClose, @)
40
+
41
+ # this will get called within the context of the modal view
42
+ onOpen: ()-> true
43
+
44
+ # this will get called within the context of the modal view
45
+ onClose: ()-> true
46
+
47
+ getModal: ()-> @modal
48
+
49
+ # this will be called within the context of the simple modal object
50
+ onModalOpen: (modal, view)->
51
+ view.modal = modal
52
+
53
+ modal.overlay.show()
54
+ modal.container.show()
55
+ modal.data.show()
56
+
57
+ # this will be called within the context of the simple modal object
58
+ onModalClose: (modal, view)->
59
+ $.modal.close()
60
+
61
+ prepareLayout: ()->
62
+ $('body').append( @$el )
63
+
64
+ prepareComponents: ()->
65
+ @components = _(@components).map (object,index) =>
66
+ object.container = @el
67
+ object
68
+
69
+ afterInitialize: ()->
70
+ @$el.hide()
71
+ @render() if @renderOnInitialize
72
+
73
+ afterRender: ()->
74
+ @show() if @showOnRender
75
+
76
+ wrapper: ()-> $( @$el.parent() )
77
+
78
+ show: ()->
79
+ @trigger "before:show", @
80
+ @$el.modal( @modalOptions )
81
+
82
+ hide: ()->
83
+ @trigger "before:hide", @
84
+
85
+ Luca.register "modal_view","Luca.containers.ModalView"
@@ -0,0 +1,24 @@
1
+ Luca.containers.PanelView = Luca.core.Container.extend
2
+ className: 'luca-ui-panel'
3
+
4
+ initialize: (@options={})->
5
+ Luca.core.Container::initialize.apply @, arguments
6
+
7
+ afterLayout: ()->
8
+ if @template
9
+ contents = ( Luca.templates || JST )[ @template ]( @ )
10
+ @$el.html(contents)
11
+
12
+ render: ()->
13
+ $(@container).append @$el
14
+
15
+ afterRender: ()->
16
+ Luca.core.Container::afterRender?.apply @, arguments
17
+ if @css
18
+ console.log "Yes Yes Yall", @css, @$el
19
+ _( @css ).each (value,property)=>
20
+ @$el.css(property,value)
21
+
22
+
23
+
24
+
@@ -0,0 +1,12 @@
1
+ Luca.containers.SplitView = Luca.core.Container.extend
2
+ layout: '100'
3
+
4
+ componentType: 'split_view'
5
+
6
+ containerTemplate: 'containers/basic'
7
+
8
+ className: 'luca-ui-split-view'
9
+
10
+ componentClass: 'luca-ui-panel'
11
+
12
+ Luca.register 'split_view', "Luca.containers.SplitView"
@@ -0,0 +1,77 @@
1
+ Luca.containers.TabView = Luca.containers.CardView.extend
2
+ events:
3
+ "click ul.nav-tabs li" : "select"
4
+
5
+ hooks:[
6
+ "before:select"
7
+ "after:select"
8
+ ]
9
+
10
+ componentType: 'tab_view'
11
+
12
+ className: 'luca-ui-tab-view tabbable'
13
+
14
+ tab_position: 'top'
15
+
16
+ tabVerticalOffset: '50px'
17
+
18
+ initialize: (@options={})->
19
+ Luca.containers.CardView::initialize.apply @, arguments
20
+ _.bindAll @, "select", "highlightSelectedTab"
21
+ @setupHooks( @hooks )
22
+
23
+ @bind "after:card:switch", @highlightSelectedTab
24
+
25
+ activeTabSelector: ()->
26
+ @tabSelectors().eq( @activeCard )
27
+
28
+ prepareLayout: ()->
29
+ @card_containers = _( @cards ).map (card, index)=>
30
+ @$('.tab-content').append Luca.templates["containers/basic"](card)
31
+ $("##{ card.id }")
32
+
33
+ beforeLayout: ()->
34
+ @$el.addClass("tabs-#{ @tab_position }")
35
+
36
+ if @tab_position is "below"
37
+ @$el.append Luca.templates["containers/tab_view"](@)
38
+ @$el.append Luca.templates["containers/tab_selector_container"](@)
39
+ else
40
+ @$el.append Luca.templates["containers/tab_selector_container"](@)
41
+ @$el.append Luca.templates["containers/tab_view"](@)
42
+
43
+ Luca.containers.CardView::beforeLayout.apply @, arguments
44
+
45
+ beforeRender: ()->
46
+ Luca.containers.CardView::beforeRender?.apply @, arguments
47
+ @activeTabSelector().addClass('active')
48
+
49
+ if Luca.enableBootstrap and @tab_position is "left" or @tab_position is "right"
50
+ @$el.addClass('grid-12')
51
+ @tabContainerWrapper().addClass('grid-3')
52
+ @tabContentWrapper().addClass('grid-9')
53
+
54
+ if @tabVerticalOffset
55
+ @tabContainerWrapper().css('padding-top', @tabVerticalOffset )
56
+
57
+ highlightSelectedTab: ()->
58
+ @tabSelectors().removeClass('active')
59
+ @activeTabSelector().addClass('active')
60
+
61
+ select: (e)->
62
+ me = my = $( e.currentTarget )
63
+ @trigger "before:select", @
64
+ @activate my.data('target')
65
+ @trigger "after:select", @
66
+
67
+ tabContentWrapper: ()->
68
+ $("##{ @cid }-tab-view-content")
69
+
70
+ tabContainerWrapper: ()->
71
+ $("##{ @cid }-tabs-selector")
72
+
73
+ tabContainer: ()->
74
+ $("ul##{ @cid }-tabs-nav")
75
+
76
+ tabSelectors: ()->
77
+ $( 'li.tab-selector', @tabContainer() )
@@ -0,0 +1,16 @@
1
+ Luca.containers.Viewport = Luca.containers.CardView.extend
2
+ activeItem: 0
3
+
4
+ className: 'luca-ui-viewport'
5
+
6
+ fullscreen: true
7
+
8
+ initialize: (@options={})->
9
+ Luca.core.Container::initialize.apply(@, arguments)
10
+
11
+ $('html,body').addClass('luca-ui-fullscreen') if @fullscreen
12
+
13
+ render: ()->
14
+ console.log "Rendering Viewport"
15
+ @$el.addClass('luca-ui-viewport')
16
+
@@ -0,0 +1,319 @@
1
+ # Luca.Collection
2
+ #
3
+ # Luca.Collection is an extenstion of Backbone.Collection which provides
4
+ # a bunch of commonly used patterns for doing things like:
5
+ #
6
+ # - setting base parameters used on every request to your REST API
7
+ #
8
+ # - bootstrapping a collection of objects which are
9
+ # rendered in your markup on page load
10
+ #
11
+ # - filtering with query string parameters against your API
12
+ #
13
+ # - automatic interaction with your Luca.CollectionManager class
14
+ #
15
+ # - make it easier to parse Rails style responses which include the root
16
+ # by specifying a @root parameter
17
+ #
18
+ # - use backbone-query if available
19
+ #
20
+ # - onceLoaded: run a callback once if there are models present, otherwise wait until
21
+ # the collection fetches
22
+ #
23
+ # - ifLoaded: run a callback any time the model gets reset, or if there are already models
24
+ #
25
+ Luca.Collection = (Backbone.QueryCollection || Backbone.Collection).extend
26
+
27
+ initialize: (models=[], @options)->
28
+ _.extend @, @options
29
+
30
+ # By specifying a @cached property or method, you can instruct
31
+ # Luca.Collection instances where to pull an array of model attributes
32
+ # usually done with the bootstrap functionality provided.
33
+ if @cached
34
+ @bootstrap_cache_key = if _.isFunction( @cached ) then @cached() else @cached
35
+
36
+ if @registerAs or @registerWith
37
+ console.log "This configuration API is deprecated. use @name and @manager properties instead"
38
+
39
+ # support the older configuration API
40
+ @name ||= @registerAs
41
+ @manager ||= @registerWith
42
+
43
+
44
+ # if they specify a
45
+ if @name and not @manager
46
+ @manager = Luca.CollectionManager.get()
47
+
48
+ # If we are going to be registering this collection with the CollectionManager
49
+ # class, then we need to specify a key to register ourselves under. @registerAs can be
50
+ # as simple as something as "books", or if you are using collections which need
51
+ # to be scoped with some sort of unique id, as say some sort of belongsTo relationship
52
+ # then you can specify @registerAs as a method()
53
+ if @manager
54
+ @name ||= @cached()
55
+ @name = if _.isFunction( @name ) then @name() else @name
56
+
57
+ unless @private or @anonymous
58
+ @bind "after:initialize", ()=>
59
+ @register( @manager, @name, @)
60
+
61
+ # by passing useLocalStorage = true to your collection definition
62
+ # you will bypass the RESTful persistence layer and just persist everything
63
+ # locally in localStorage
64
+ if @useLocalStorage is true and window.localStorage?
65
+ table = @bootstrap_cache_key || @name
66
+ throw "Must specify either a cached or registerAs property to use localStorage"
67
+ @localStorage = new Luca.LocalStore( table )
68
+
69
+ # Populating a collection with local data
70
+ #
71
+ # by specifying a @data property which is an array
72
+ # then you can set the collection to be a @memoryCollection
73
+ # which never interacts with a persistence layer at all.
74
+ #
75
+ # this is mainly used by the Luca.fields.SelectField class for
76
+ # generating simple select fields with static data
77
+ if _.isArray(@data) and @data.length > 0
78
+ @memoryCollection = true
79
+
80
+ @__wrapUrl() unless @useNormalUrl is true
81
+
82
+ Backbone.Collection.prototype.initialize.apply @, [models, @options]
83
+
84
+ @trigger "after:initialize"
85
+
86
+ #### Automatic Query String Generation
87
+ #
88
+ # Luca.Collections will append a query string to the URL
89
+ # and will automatically do this for you without you having
90
+ # to write a special url handler. If you want to use a normal
91
+ # url without this feature, just set @useNormalUrl = true
92
+ __wrapUrl: ()->
93
+ if _.isFunction(@url)
94
+ @url = _.wrap @url, (fn)=>
95
+ val = fn.apply @
96
+ parts = val.split('?')
97
+
98
+ existing_params = _.last(parts) if parts.length > 1
99
+
100
+ queryString = @queryString()
101
+
102
+ if existing_params and val.match(existing_params)
103
+ queryString = queryString.replace( existing_params, '')
104
+
105
+ new_val = "#{ val }?#{ queryString }"
106
+ new_val = new_val.replace(/\?$/,'') if new_val.match(/\?$/)
107
+
108
+ new_val
109
+ else
110
+ url = @url
111
+ params = @queryString()
112
+
113
+ @url = _([url,params]).compact().join("?")
114
+
115
+ queryString: ()->
116
+ parts = _( @base_params ||= Luca.Collection.baseParams() ).inject (memo, value, key)=>
117
+ str = "#{ key }=#{ value }"
118
+ memo.push(str)
119
+ memo
120
+ , []
121
+
122
+ _.uniq(parts).join("&")
123
+
124
+ resetFilter: ()->
125
+ @base_params = Luca.Collection.baseParams()
126
+ @
127
+
128
+ # Applying a filter to a collection, will automatically apply
129
+ # the filter parameters and then call fetch. passing an additional
130
+ # options hash will pass these options to the call to @fetch()
131
+ # setting refresh to true, forcing a remote call to the REST API
132
+ applyFilter: (filter={}, options={})->
133
+ @applyParams(filter)
134
+ @fetch _.extend(options,refresh:true)
135
+
136
+ # You can apply params to a collection, so that any upcoming requests
137
+ # made to the REST API are made with the key values specified
138
+ applyParams: (params)->
139
+ @base_params ||= Luca.Collection.baseParams()
140
+ _.extend @base_params, params
141
+
142
+ # Collection Manager Registry
143
+ #
144
+ # If this collection is to be registered with some global collection
145
+ # tracker such as new Luca.CollectionManager() then we will register
146
+ # ourselves automatically
147
+ #
148
+ # To automatically register a collection with the registry, instantiate
149
+ # it with the registerWith property, which can either be a reference to
150
+ # the manager itself, or a string in case the manager isn't available
151
+ # at compile time
152
+ register: (collectionManager=Luca.CollectionManager.get(), key="", collection)->
153
+ throw "Can not register with a collection manager without a key" unless key.length >= 1
154
+ throw "Can not register with a collection manager without a valid collection manager" unless collectionManager?
155
+
156
+ # by passing a string instead of a reference to an object, we can look up
157
+ # that object only when necessary. this prevents us from having to create
158
+ # the manager instance before we can define our collections
159
+ if _.isString( collectionManager )
160
+ collectionManager = Luca.util.nestedValue( collectionManager, (window || global) )
161
+
162
+ throw "Could not register with collection manager" unless collectionManager
163
+
164
+ if _.isFunction( collectionManager.add )
165
+ return collectionManager.add(key, collection)
166
+
167
+ if _.isObject( collectionManager )
168
+ collectionManager[ key ] = collection
169
+
170
+ # A Luca.Collection will load models from the in memory model store
171
+ # returned from Luca.Collection.cache, where the key returned from
172
+ # the @cached attribute or method matches the key of the model cache
173
+ loadFromBootstrap: ()->
174
+ return unless @bootstrap_cache_key
175
+ @reset @cached_models()
176
+ @trigger "bootstrapped", @
177
+
178
+ # an alias for loadFromBootstrap which is a bit more descriptive
179
+ bootstrap: ()->
180
+ @loadFromBootstrap()
181
+
182
+ # cached_models is a reference to the Luca.Collection.cache object
183
+ # key'd on whatever this collection's bootstrap_cache_key is set to be
184
+ # via the @cached() interface
185
+ cached_models: ()->
186
+ Luca.Collection.cache( @bootstrap_cache_key )
187
+
188
+ # Luca.Collection overrides the default Backbone.Collection.fetch method
189
+ # and triggers an event "before:fetch" which gives you additional control
190
+ # over the process
191
+ #
192
+ # in addition, it loads models directly from the bootstrap cache instead
193
+ # of going directly to the API
194
+ fetch: (options={})->
195
+ @trigger "before:fetch", @
196
+
197
+ return @reset(@data) if @memoryCollection is true
198
+
199
+ # fetch will try to pull from the bootstrap if it is setup to do so
200
+ # you can actually make the roundtrip to the server anyway if you pass
201
+ # refresh = true in the options hash
202
+ return @bootstrap() if @cached_models().length and not options.refresh
203
+
204
+ url = if _.isFunction(@url) then @url() else @url
205
+
206
+ return true unless ((url and url.length > 1) or @localStorage)
207
+
208
+ @fetching = true
209
+
210
+ try
211
+ Backbone.Collection.prototype.fetch.apply @, arguments
212
+ catch e
213
+ console.log "Error in Collection.fetch", e
214
+
215
+ throw e
216
+
217
+ # onceLoaded is equivalent to binding to the
218
+ # reset trigger with a function wrapped in _.once
219
+ # so that it only gets run...ahem...once.
220
+ #
221
+ # that being said, if the collection already has models
222
+ # it won't even bother fetching it it will just run
223
+ # as if reset was already triggered
224
+ onceLoaded: (fn, options={autoFetch:true})->
225
+ if @length > 0 and not @fetching
226
+ fn.apply @, [@]
227
+ return
228
+
229
+ wrapped = ()=> fn.apply @,[@]
230
+
231
+ @bind "reset", ()->
232
+ wrapped()
233
+ @unbind "reset", @
234
+
235
+ unless @fetching or not options.autoFetch
236
+ @fetch()
237
+
238
+ # ifLoaded is equivalent to binding to the reset trigger with
239
+ # a function, if the collection already has models it will just
240
+ # run automatically. similar to onceLoaded except the binding
241
+ # stays in place
242
+ ifLoaded: (fn, options={scope:@,autoFetch:true})->
243
+ scope = options.scope || @
244
+
245
+ if @length > 0 and not @fetching
246
+ fn.apply scope, [@]
247
+
248
+ @bind "reset", (collection)=> fn.apply scope, [collection]
249
+
250
+ unless @fetching is true or !options.autoFetch or @length > 0
251
+ @fetch()
252
+
253
+ # parse is very close to the stock Backbone.Collection parse, which
254
+ # just returns the response. However, it also triggers a callback
255
+ # after:response, and automatically parses responses which contain
256
+ # a JSON root like you would see in rails, if you specify the @root
257
+ # property.
258
+ #
259
+ # it will also update the Luca.Collection.cache with the models from
260
+ # the response, so that any subsequent calls to fetch() on a bootstrapped
261
+ # collection, will have updated models from the server. Really only
262
+ # useful if you call fetch(refresh:true) manually on any bootstrapped
263
+ # collection
264
+ parse: (response)->
265
+ @fetching = false
266
+ @trigger "after:response", response
267
+ models = if @root? then response[ @root ] else response
268
+
269
+ if @bootstrap_cache_key
270
+ Luca.Collection.cache( @bootstrap_cache_key, models)
271
+
272
+ models
273
+
274
+
275
+ # Global Collection Observer
276
+ _.extend Luca.Collection.prototype,
277
+ trigger: ()->
278
+ if Luca.enableGlobalObserver
279
+ Luca.CollectionObserver ||= new Luca.Observer(type:"collection")
280
+ Luca.CollectionObserver.relay(@, arguments)
281
+
282
+ Backbone.View.prototype.trigger.apply @, arguments
283
+
284
+ #### Base Parameters
285
+ #
286
+ # Always include these parameters in every request to your REST API.
287
+ #
288
+ # either specify a function which returns a hash, or just a normal hash
289
+ Luca.Collection.baseParams = (obj)->
290
+ return Luca.Collection._baseParams = obj if obj
291
+
292
+ if _.isFunction( Luca.Collection._baseParams )
293
+ return Luca.Collection._baseParams.call()
294
+
295
+ if _.isObject( Luca.Collection._baseParams )
296
+ Luca.Collection._baseParams
297
+
298
+ #### Bootstrapped Models ( stuff loaded on page load )
299
+ #
300
+ # In order to make our Backbone Apps super fast it is a good practice
301
+ # to pre-populate your collections by what is referred to as bootstrapping
302
+ #
303
+ # Luca.Collections make it easier for you to do this cleanly and automatically
304
+ #
305
+ # by specifying a @cached property or method in your collection definition
306
+ # Luca.Collections will automatically look in this space to find models
307
+ # and avoid a roundtrip to your API unless explicitly told to.
308
+ Luca.Collection._bootstrapped_models = {}
309
+
310
+ # In order to do this, just load an object whose keys
311
+ Luca.Collection.bootstrap = (obj)->
312
+ _.extend Luca.Collection._bootstrapped_models, obj
313
+
314
+ # Lookup cached() or bootstrappable models. This is used by the
315
+ # augmented version of Backbone.Collection.fetch() in order to avoid
316
+ # roundtrips to the API
317
+ Luca.Collection.cache = (key, models)->
318
+ return Luca.Collection._bootstrapped_models[ key ] = models if models
319
+ Luca.Collection._bootstrapped_models[ key ] || []