luca 0.9.4 → 0.9.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.
- data/CHANGELOG +41 -1
- data/Gemfile +1 -0
- data/Gemfile.lock +2 -0
- data/README.md +5 -0
- data/Rakefile +4 -0
- data/assets/javascripts/dependencies/underscore-min.js +5 -31
- data/assets/javascripts/luca-templates.js +1 -0
- data/assets/javascripts/luca-ui-base.coffee +1 -1
- data/assets/javascripts/luca-ui-development-tools.coffee +1 -1
- data/assets/javascripts/luca-ui-full.js +1 -1
- data/assets/javascripts/luca-ui-spec.coffee +1 -1
- data/assets/javascripts/luca-ui.js +3 -0
- data/assets/javascripts/luca/index.coffee +1 -0
- data/lib/generators/luca/application/application_generator.rb +71 -0
- data/lib/generators/luca/application/templates/controller.rb +6 -0
- data/lib/generators/luca/application/templates/index.html.erb +7 -0
- data/lib/generators/luca/application/templates/index.html.haml +6 -0
- data/lib/generators/luca/application/templates/javascripts/application.js +28 -0
- data/lib/generators/luca/application/templates/javascripts/application.js.coffee +20 -0
- data/lib/generators/luca/application/templates/javascripts/config.js +15 -0
- data/lib/generators/luca/application/templates/javascripts/config.js.coffee +9 -0
- data/lib/generators/luca/application/templates/javascripts/dependencies.js +5 -0
- data/lib/generators/luca/application/templates/javascripts/dependencies.js.coffee +5 -0
- data/lib/generators/luca/application/templates/javascripts/index.js +9 -0
- data/lib/generators/luca/application/templates/javascripts/index.js.coffee +9 -0
- data/lib/generators/luca/application/templates/javascripts/main.js +8 -0
- data/lib/generators/luca/application/templates/javascripts/main.js.coffee +3 -0
- data/lib/generators/luca/application/templates/javascripts/main.jst.ejs +1 -0
- data/lib/generators/luca/application/templates/javascripts/router.js +12 -0
- data/lib/generators/luca/application/templates/javascripts/router.js.coffee +7 -0
- data/lib/luca/rails/version.rb +1 -1
- data/lib/luca/template.rb +1 -1
- data/spec/components/collection_view_spec.coffee +37 -0
- data/spec/components/multi_collection_view_spec.coffee +5 -0
- data/spec/components/table_view_spec.coffee +17 -0
- data/spec/core/container_spec.coffee +112 -5
- data/spec/core/model_spec.coffee +21 -3
- data/spec/define_spec.coffee +19 -0
- data/spec/mixin_spec.coffee +49 -0
- data/src/components/application.coffee +33 -19
- data/src/components/collection_view.coffee +109 -38
- data/src/components/fields/checkbox_field.coffee +2 -2
- data/src/components/fields/file_upload_field.coffee +0 -3
- data/src/components/fields/hidden_field.coffee +0 -3
- data/src/components/fields/label_field.coffee +1 -4
- data/src/components/fields/select_field.coffee +6 -6
- data/src/components/fields/text_area_field.coffee +1 -0
- data/src/components/fields/text_field.coffee +4 -0
- data/src/components/fields/type_ahead_field.coffee +5 -9
- data/src/components/form_view.coffee +2 -0
- data/src/components/index.coffee +1 -0
- data/src/components/multi_collection_view.coffee +94 -0
- data/src/components/pagination_control.coffee +100 -0
- data/src/components/table_view.coffee +62 -0
- data/src/containers/card_view.coffee +44 -11
- data/src/containers/panel_toolbar.coffee +88 -82
- data/src/containers/tab_view.coffee +3 -3
- data/src/containers/viewport.coffee +10 -4
- data/src/core/collection.coffee +11 -4
- data/src/core/container.coffee +189 -113
- data/src/core/field.coffee +13 -10
- data/src/core/model.coffee +23 -27
- data/src/core/registry.coffee +48 -35
- data/src/core/view.coffee +60 -140
- data/src/define.coffee +91 -19
- data/src/framework.coffee +10 -8
- data/src/index.coffee +23 -0
- data/src/managers/collection_manager.coffee +24 -8
- data/src/modules/application_event_bindings.coffee +19 -0
- data/src/modules/collection_event_bindings.coffee +26 -0
- data/src/modules/deferrable.coffee +3 -1
- data/src/modules/dom_helpers.coffee +49 -0
- data/src/modules/enhanced_properties.coffee +23 -0
- data/src/modules/filterable.coffee +60 -0
- data/src/modules/grid_layout.coffee +15 -0
- data/src/modules/{load_mask.coffee → loadmaskable.coffee} +10 -4
- data/src/modules/modal_view.coffee +38 -0
- data/src/modules/paginatable.coffee +79 -0
- data/src/modules/state_model.coffee +16 -0
- data/src/modules/templating.coffee +8 -0
- data/src/plugins/events.coffee +30 -2
- data/src/templates/components/bootstrap_form_controls.jst.ejs +10 -0
- data/src/templates/components/collection_loader_view.jst.ejs +6 -0
- data/src/templates/components/form_alert.jst.ejs +4 -0
- data/src/templates/components/grid_view.jst.ejs +11 -0
- data/src/templates/components/grid_view_empty_text.jst.ejs +3 -0
- data/src/templates/components/load_mask.jst.ejs +5 -0
- data/src/templates/components/nav_bar.jst.ejs +4 -0
- data/src/templates/components/pagination.jst.ejs +10 -0
- data/src/templates/containers/basic.jst.ejs +1 -0
- data/src/templates/containers/tab_selector_container.jst.ejs +12 -0
- data/src/templates/containers/tab_view.jst.ejs +2 -0
- data/src/templates/containers/toolbar_wrapper.jst.ejs +1 -0
- data/src/templates/fields/button_field.jst.ejs +2 -0
- data/src/templates/fields/button_field_link.jst.ejs +6 -0
- data/src/templates/fields/checkbox_array.jst.ejs +4 -0
- data/src/templates/fields/checkbox_array_item.jst.ejs +3 -0
- data/src/templates/fields/checkbox_field.jst.ejs +10 -0
- data/src/templates/fields/file_upload_field.jst.ejs +10 -0
- data/src/templates/fields/hidden_field.jst.ejs +1 -0
- data/src/templates/fields/select_field.jst.ejs +11 -0
- data/src/templates/fields/text_area_field.jst.ejs +11 -0
- data/src/templates/fields/text_field.jst.ejs +16 -0
- data/src/templates/table_view.jst.ejs +4 -0
- data/src/tools/console.coffee +51 -21
- data/src/util.coffee +17 -4
- data/vendor/assets/javascripts/luca-ui-base.js +3288 -613
- data/vendor/assets/javascripts/luca-ui-development-tools.js +49 -21
- data/vendor/assets/javascripts/luca-ui-development-tools.min.js +1 -1
- data/vendor/assets/javascripts/luca-ui-full.js +1704 -554
- data/vendor/assets/javascripts/luca-ui-full.min.js +7 -6
- data/vendor/assets/javascripts/luca-ui-spec.js +1783 -830
- data/vendor/assets/javascripts/luca-ui-templates.js +92 -0
- data/vendor/assets/javascripts/luca-ui.js +1694 -523
- data/vendor/assets/javascripts/luca-ui.min.js +4 -4
- metadata +69 -31
- data/assets/javascripts/luca-ui.coffee +0 -3
- data/src/luca.coffee +0 -22
- data/src/templates/components/bootstrap_form_controls.luca +0 -7
- data/src/templates/components/collection_loader_view.luca +0 -5
- data/src/templates/components/form_alert +0 -0
- data/src/templates/components/form_alert.luca +0 -3
- data/src/templates/components/grid_view.luca +0 -7
- data/src/templates/components/grid_view_empty_text.luca +0 -3
- data/src/templates/components/load_mask.luca +0 -3
- data/src/templates/components/nav_bar.luca +0 -2
- data/src/templates/containers/basic.luca +0 -1
- data/src/templates/containers/tab_selector_container.luca +0 -8
- data/src/templates/containers/tab_view.luca +0 -2
- data/src/templates/containers/toolbar_wrapper.luca +0 -1
- data/src/templates/fields/button_field.luca +0 -2
- data/src/templates/fields/button_field_link.luca +0 -5
- data/src/templates/fields/checkbox_array.luca +0 -4
- data/src/templates/fields/checkbox_array_item.luca +0 -4
- data/src/templates/fields/checkbox_field.luca +0 -9
- data/src/templates/fields/file_upload_field.luca +0 -8
- data/src/templates/fields/hidden_field.luca +0 -1
- data/src/templates/fields/select_field.luca +0 -8
- data/src/templates/fields/text_area_field.luca +0 -8
- data/src/templates/fields/text_field.luca +0 -17
- data/src/templates/sample/contents.luca +0 -1
- data/src/templates/sample/welcome.luca +0 -1
- data/vendor/assets/javascripts/luca-spec-dependencies.js +0 -6135
- data/vendor/assets/javascripts/luca-ui-development-dependencies.js +0 -12845
|
@@ -1,26 +1,95 @@
|
|
|
1
|
+
panelToolbar = Luca.register "Luca.components.PanelToolbar"
|
|
2
|
+
# The Panel Toolbar is a collection of buttons and / or dropdowns
|
|
3
|
+
# which are automatically created by BasicPanel classes, or can be
|
|
4
|
+
# added to any other view component.
|
|
5
|
+
panelToolbar.extends "Luca.View"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
panelToolbar.defines
|
|
9
|
+
# @buttons is an array of button config objects
|
|
10
|
+
# button config accepts the following paramters:
|
|
11
|
+
#
|
|
12
|
+
# label what should the button say
|
|
13
|
+
# eventId what event should the button trigger
|
|
14
|
+
# dropdown an array of arrays: [eventId, label]
|
|
15
|
+
# group an array of button configs
|
|
16
|
+
# wrapper a css class, in addition to btn-group
|
|
17
|
+
# icon which icon do you want to use on this button?
|
|
18
|
+
# white true or false: is it a white colored text?
|
|
19
|
+
# color options are primary, info, success, warning, danger, inverse
|
|
20
|
+
buttons:[]
|
|
21
|
+
|
|
22
|
+
className: "luca-ui-toolbar btn-toolbar"
|
|
23
|
+
|
|
24
|
+
well: true
|
|
25
|
+
|
|
26
|
+
orientation: 'top'
|
|
27
|
+
|
|
28
|
+
autoBindEventHandlers: true
|
|
29
|
+
|
|
30
|
+
events:
|
|
31
|
+
"click a.btn, click .dropdown-menu li" : "clickHandler"
|
|
32
|
+
|
|
33
|
+
initialize: (@options={})->
|
|
34
|
+
@_super("initialize", @, arguments)
|
|
35
|
+
|
|
36
|
+
# if the toolbar consists of a single button group
|
|
37
|
+
# don't make the developer specify buttons = {buttons:[group:true, buttons:[...]]}
|
|
38
|
+
if @group is true and @buttons?.length >= 0
|
|
39
|
+
@buttons = [
|
|
40
|
+
group: true
|
|
41
|
+
buttons: @buttons
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
# The Toolbar behaves by triggering events on the components which they
|
|
45
|
+
# belong to. Combined with Luca.View::setupHooks it is a clean way
|
|
46
|
+
# to organize actions
|
|
47
|
+
clickHandler: (e)->
|
|
48
|
+
me = my = $( e.target )
|
|
49
|
+
me = my = $( e.target ).parent() if me.is('i')
|
|
50
|
+
|
|
51
|
+
if @selectable is true
|
|
52
|
+
my.siblings().removeClass("is-selected")
|
|
53
|
+
me.addClass('is-selected')
|
|
54
|
+
|
|
55
|
+
return unless eventId = my.data('eventid')
|
|
56
|
+
|
|
57
|
+
hook = Luca.util.hook( eventId )
|
|
58
|
+
|
|
59
|
+
source = @parent || @
|
|
60
|
+
if _.isFunction( source[hook] )
|
|
61
|
+
source[ hook ].call(@, me, e)
|
|
62
|
+
else
|
|
63
|
+
source.trigger(eventId, me, e)
|
|
64
|
+
|
|
65
|
+
beforeRender:()->
|
|
66
|
+
@_super("beforeRender", @, arguments)
|
|
67
|
+
|
|
68
|
+
if @well is true
|
|
69
|
+
@$el.addClass 'well'
|
|
70
|
+
|
|
71
|
+
@$el.addClass 'btn-selectable' if @selectable is true
|
|
72
|
+
@$el.addClass "toolbar-#{ @orientation }"
|
|
73
|
+
@$el.addClass "pull-right" if @align is "right"
|
|
74
|
+
@$el.addClass "pull-left" if @align is "left"
|
|
75
|
+
|
|
76
|
+
render: ()->
|
|
77
|
+
@$el.empty()
|
|
78
|
+
@$el.append( element ) for element in prepareButtons(@buttons)
|
|
79
|
+
@
|
|
1
80
|
|
|
2
|
-
# button config accepts the following paramters:
|
|
3
|
-
#
|
|
4
|
-
# label what should the button say
|
|
5
|
-
# eventId what event should the button trigger
|
|
6
|
-
# dropdown an array of arrays: [eventId, label]
|
|
7
|
-
# group an array of button configs
|
|
8
|
-
# wrapper a css class, in addition to btn-group
|
|
9
|
-
# icon which icon do you want to use on this button?
|
|
10
|
-
# white true or false: is it a white colored text?
|
|
11
|
-
# color options are primary, info, success, warning, danger, inverse
|
|
12
81
|
|
|
13
82
|
make = Backbone.View::make
|
|
14
83
|
|
|
15
84
|
buildButton = (config, wrap=true)->
|
|
16
|
-
if config.ctype?
|
|
85
|
+
if config.ctype? or config.type?
|
|
17
86
|
config.className ||= ""
|
|
18
87
|
config.className += 'toolbar-component'
|
|
19
88
|
|
|
20
89
|
object = Luca(config).render()
|
|
90
|
+
|
|
21
91
|
if Luca.isBackboneView(object)
|
|
22
|
-
|
|
23
|
-
return object.el
|
|
92
|
+
return object.$el
|
|
24
93
|
|
|
25
94
|
if config.spacer
|
|
26
95
|
return make "div", class: "spacer #{ config.spacer }"
|
|
@@ -29,8 +98,9 @@ buildButton = (config, wrap=true)->
|
|
|
29
98
|
return make "div", {class: "toolbar-text"}, config.text
|
|
30
99
|
|
|
31
100
|
wrapper = 'btn-group'
|
|
32
|
-
wrapper += "
|
|
33
|
-
wrapper += " align-#{ config.align }" if config.align?
|
|
101
|
+
wrapper += "#{ config.wrapper }" if config.wrapper?
|
|
102
|
+
wrapper += "pull-#{ config.align } align-#{ config.align }" if config.align?
|
|
103
|
+
wrapper += 'btn-selectable' if config.selectable is true
|
|
34
104
|
|
|
35
105
|
# if we're passed a group, then we need to just
|
|
36
106
|
# wrap the contents of the buttons property in that group
|
|
@@ -57,6 +127,7 @@ buildButton = (config, wrap=true)->
|
|
|
57
127
|
title: config.title || config.description
|
|
58
128
|
|
|
59
129
|
buttonAttributes["class"] += " btn-#{ config.color }" if config.color?
|
|
130
|
+
buttonAttributes["class"] += " is-selected" if config.selected?
|
|
60
131
|
|
|
61
132
|
if config.dropdown
|
|
62
133
|
label = "#{ label } <span class='caret'></span>"
|
|
@@ -82,70 +153,5 @@ buildButton = (config, wrap=true)->
|
|
|
82
153
|
# for buttons which are already part f a group
|
|
83
154
|
buttonEl
|
|
84
155
|
|
|
85
|
-
prepareButtons = (buttons, wrap=true)->
|
|
86
|
-
|
|
87
|
-
buildButton(button, wrap)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
#### Panel Toolbar Component
|
|
91
|
-
#
|
|
92
|
-
# The Panel Toolbar is a collection of buttons and / or dropdowns
|
|
93
|
-
# which are automatically created by BasicPanel classes, or can be
|
|
94
|
-
# added to any other view component.
|
|
95
|
-
_.def("Luca.containers.PanelToolbar").extends("Luca.View").with
|
|
96
|
-
|
|
97
|
-
className: "luca-ui-toolbar btn-toolbar"
|
|
98
|
-
|
|
99
|
-
# @buttons is an array of button config objects
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
buttons:[]
|
|
103
|
-
|
|
104
|
-
well: true
|
|
105
|
-
|
|
106
|
-
orientation: 'top'
|
|
107
|
-
|
|
108
|
-
autoBindEventHandlers: true
|
|
109
|
-
|
|
110
|
-
events:
|
|
111
|
-
"click a.btn, click .dropdown-menu li" : "clickHandler"
|
|
112
|
-
|
|
113
|
-
#autoBindEventHandlers: true
|
|
114
|
-
|
|
115
|
-
# The Toolbar behaves by triggering events on the components which they
|
|
116
|
-
# belong to. Combined with Luca.View::setupHooks it is a clean way
|
|
117
|
-
# to organize actions
|
|
118
|
-
clickHandler: (e)->
|
|
119
|
-
me = my = $( e.target )
|
|
120
|
-
|
|
121
|
-
if me.is('i')
|
|
122
|
-
me = my = $( e.target ).parent()
|
|
123
|
-
|
|
124
|
-
eventId = my.data('eventid')
|
|
125
|
-
|
|
126
|
-
return unless eventId?
|
|
127
|
-
|
|
128
|
-
hook = Luca.util.hook( eventId )
|
|
129
|
-
|
|
130
|
-
source = @parent || @
|
|
131
|
-
if _.isFunction( source[hook] )
|
|
132
|
-
source[ hook ].call(@, me, e)
|
|
133
|
-
else
|
|
134
|
-
source.trigger(eventId, me, e)
|
|
135
|
-
|
|
136
|
-
beforeRender:()->
|
|
137
|
-
@_super("beforeRender", @, arguments)
|
|
138
|
-
|
|
139
|
-
if @well is true
|
|
140
|
-
@$el.addClass 'well'
|
|
141
|
-
|
|
142
|
-
@$el.addClass "toolbar-#{ @orientation }"
|
|
143
|
-
|
|
144
|
-
@applyStyles( @styles ) if @styles?
|
|
145
|
-
|
|
146
|
-
render: ()->
|
|
147
|
-
@$el.empty()
|
|
148
|
-
|
|
149
|
-
elements = prepareButtons(@buttons)
|
|
150
|
-
_( elements ).each (element)=>
|
|
151
|
-
@$el.append( element )
|
|
156
|
+
prepareButtons = (buttons=[], wrap=true)->
|
|
157
|
+
buildButton(button, wrap) for button in buttons
|
|
@@ -42,17 +42,17 @@ _.def('Luca.containers.TabView').extends('Luca.containers.CardView').with
|
|
|
42
42
|
|
|
43
43
|
afterRender: ()->
|
|
44
44
|
Luca.containers.CardView::afterRender?.apply @, arguments
|
|
45
|
-
|
|
45
|
+
tabContainerId = @tabContainer().attr("id")
|
|
46
|
+
@registerEvent("click ##{ tabContainerId } li a", "select")
|
|
46
47
|
|
|
47
48
|
if Luca.enableBootstrap and (@tab_position is "left" or @tab_position is "right")
|
|
48
49
|
@tabContainerWrapper().addClass("span2")
|
|
49
50
|
@tabContentWrapper().addClass("span9")
|
|
50
51
|
|
|
51
|
-
|
|
52
52
|
createTabSelectors: ()->
|
|
53
53
|
tabView = @
|
|
54
54
|
@each (component,index)->
|
|
55
|
-
icon = "<i class='icon-#{ component.tabIcon }" if component.tabIcon
|
|
55
|
+
icon = "<i class='icon-#{ component.tabIcon }'></i>" if component.tabIcon
|
|
56
56
|
link = "<a href='#'>#{ icon || ''} #{ component.title }</a>"
|
|
57
57
|
selector = tabView.make("li",{class:"tab-selector","data-target":index}, link)
|
|
58
58
|
tabView.tabContainer().append(selector)
|
|
@@ -19,11 +19,17 @@ _.def('Luca.containers.Viewport').extend('Luca.containers.CardView').with
|
|
|
19
19
|
|
|
20
20
|
@enableFullscreen() if @fullscreen is true
|
|
21
21
|
|
|
22
|
-
enableFluid: ()->
|
|
23
|
-
@$el.parent().addClass( @wrapperClass )
|
|
22
|
+
enableFluid: ()-> @enableWrapper()
|
|
24
23
|
|
|
25
|
-
disableFluid: ()->
|
|
26
|
-
|
|
24
|
+
disableFluid: ()-> @disableWrapper()
|
|
25
|
+
|
|
26
|
+
enableWrapper: ()->
|
|
27
|
+
if @wrapperClass?
|
|
28
|
+
@$el.parent().addClass( @wrapperClass )
|
|
29
|
+
|
|
30
|
+
disableWrapper: ()->
|
|
31
|
+
if @wrapperClass?
|
|
32
|
+
@$el.parent().removeClass( @wrapperClass )
|
|
27
33
|
|
|
28
34
|
enableFullscreen: ()->
|
|
29
35
|
$('html,body').addClass('luca-ui-fullscreen')
|
data/src/core/collection.coffee
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
source = 'Backbone.QueryCollection' if Backbone.QueryCollection?
|
|
1
|
+
collection = Luca.define 'Luca.Collection'
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
if Backbone.QueryCollection?
|
|
4
|
+
collection.extends 'Backbone.QueryCollection'
|
|
5
|
+
else
|
|
6
|
+
collection.extends 'Backbone.Collection'
|
|
7
|
+
|
|
8
|
+
collection.includes 'Luca.Events'
|
|
9
|
+
|
|
10
|
+
collection.defines
|
|
11
|
+
model: Luca.Model
|
|
6
12
|
# cachedMethods refers to a list of methods on the collection
|
|
7
13
|
# whose value gets cached once it is ran. the collection then
|
|
8
14
|
# binds to change, add, remove, and reset events and then expires
|
|
@@ -325,6 +331,7 @@ _.def("Luca.Collection").extends( source ).with
|
|
|
325
331
|
collection.bind "change:#{dependency}", ()->
|
|
326
332
|
collection.clearMethodCache(method: method)
|
|
327
333
|
|
|
334
|
+
|
|
328
335
|
# make sure the querying interface from backbone.query is present
|
|
329
336
|
# in the case backbone-query isn't loaded. without it, it will
|
|
330
337
|
# just return the models
|
data/src/core/container.coffee
CHANGED
|
@@ -1,90 +1,53 @@
|
|
|
1
|
-
|
|
2
|
-
#
|
|
3
|
-
# The Component Container is a nestable component
|
|
4
|
-
# which are responsible for handling communication between multiple
|
|
5
|
-
# nested views.
|
|
6
|
-
#
|
|
7
|
-
# One: Layout
|
|
8
|
-
#
|
|
9
|
-
# a container is responsible for laying out the nested views
|
|
10
|
-
# and rendering them in a special DOM element
|
|
11
|
-
doLayout = ()->
|
|
12
|
-
@trigger "before:layout", @
|
|
13
|
-
@prepareLayout()
|
|
14
|
-
@trigger "after:layout", @
|
|
15
|
-
|
|
16
|
-
# and displaying those elements in a way that is
|
|
17
|
-
# optimal for the desired user experience of that view
|
|
18
|
-
# ( i.e seeing only one of them at a time, seeing them side by side )
|
|
19
|
-
applyDOMConfig = (panel, panelIndex)->
|
|
20
|
-
style_declarations = []
|
|
21
|
-
|
|
22
|
-
style_declarations.push "height: #{ (if _.isNumber(panel.height) then panel.height + 'px' else panel.height ) }" if panel.height?
|
|
23
|
-
style_declarations.push "width: #{ (if _.isNumber(panel.width) then panel.width + 'px' else panel.width ) }" if panel.width?
|
|
24
|
-
style_declarations.push "float: #{ panel.float }" if panel.float
|
|
25
|
-
|
|
26
|
-
config =
|
|
27
|
-
class: panel?.classes || @componentClass
|
|
28
|
-
id: "#{ @cid }-#{ panelIndex }"
|
|
29
|
-
style: style_declarations.join(';')
|
|
30
|
-
"data-luca-owner" : @name || @cid
|
|
31
|
-
|
|
32
|
-
if @customizeContainerEl?
|
|
33
|
-
config = @customizeContainerEl( config, panel, panelIndex )
|
|
34
|
-
|
|
35
|
-
config
|
|
36
|
-
|
|
37
|
-
# Two: Component Creation
|
|
38
|
-
#
|
|
39
|
-
# A container is responsible for creating and storing references to the nested
|
|
40
|
-
# views that are required for its functioning.
|
|
41
|
-
doComponents = ()->
|
|
42
|
-
|
|
43
|
-
@trigger "before:components", @, @components
|
|
44
|
-
@prepareComponents()
|
|
45
|
-
@createComponents()
|
|
46
|
-
@trigger "before:render:components", @, @components
|
|
47
|
-
@renderComponents()
|
|
48
|
-
@trigger "after:components", @, @components
|
|
1
|
+
container = Luca.register "Luca.core.Container"
|
|
49
2
|
|
|
3
|
+
container.extends "Luca.components.Panel"
|
|
50
4
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
5
|
+
container.triggers "before:components",
|
|
6
|
+
"before:render:components",
|
|
7
|
+
"before:layout",
|
|
8
|
+
"after:components",
|
|
9
|
+
"after:layout",
|
|
10
|
+
"first:activation"
|
|
56
11
|
|
|
12
|
+
container.defines
|
|
57
13
|
className: 'luca-ui-container'
|
|
58
14
|
|
|
59
15
|
componentTag: 'div'
|
|
16
|
+
|
|
60
17
|
componentClass: 'luca-ui-panel'
|
|
61
18
|
|
|
62
19
|
isContainer: true
|
|
63
20
|
|
|
64
|
-
hooks:[
|
|
65
|
-
"before:components"
|
|
66
|
-
"before:render:components"
|
|
67
|
-
"before:layout"
|
|
68
|
-
"after:components"
|
|
69
|
-
"after:layout"
|
|
70
|
-
"first:activation"
|
|
71
|
-
]
|
|
72
|
-
|
|
73
21
|
rendered: false
|
|
74
22
|
|
|
75
23
|
components: []
|
|
76
24
|
|
|
25
|
+
# @componentEvents provides declarative syntax for responding to events on
|
|
26
|
+
# the components in this container. the format of the syntax is very similar
|
|
27
|
+
# to the other event binding helpers:
|
|
28
|
+
#
|
|
29
|
+
# component_accessor component:trigger
|
|
30
|
+
#
|
|
31
|
+
# where component_accessor is either the name of the role, or a method on the container
|
|
32
|
+
# which will find the component in question.
|
|
33
|
+
#
|
|
34
|
+
# myContainer = new Luca.core.Container
|
|
35
|
+
# componentEvents:
|
|
36
|
+
# "name component:trigger" : "handler"
|
|
37
|
+
# "role component:trigger" : "handler"
|
|
38
|
+
# "getter component:trigger" : "handler"
|
|
39
|
+
#
|
|
40
|
+
componentEvents: {}
|
|
41
|
+
|
|
77
42
|
initialize: (@options={})->
|
|
78
43
|
_.extend @, @options
|
|
79
44
|
|
|
80
|
-
@setupHooks
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
"first:activation"
|
|
87
|
-
]
|
|
45
|
+
@setupHooks( Luca.core.Container::hooks )
|
|
46
|
+
|
|
47
|
+
# aliases for the components property
|
|
48
|
+
@components ||= @fields ||= @pages ||= @cards ||= @views
|
|
49
|
+
|
|
50
|
+
validateContainerConfiguration(@)
|
|
88
51
|
|
|
89
52
|
Luca.View::initialize.apply @, arguments
|
|
90
53
|
|
|
@@ -183,6 +146,9 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
|
|
|
183
146
|
map = @componentIndex =
|
|
184
147
|
name_index: {}
|
|
185
148
|
cid_index: {}
|
|
149
|
+
role_index: {}
|
|
150
|
+
|
|
151
|
+
container = @
|
|
186
152
|
|
|
187
153
|
@components = _( @components ).map (object, index)=>
|
|
188
154
|
|
|
@@ -202,13 +168,12 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
|
|
|
202
168
|
else
|
|
203
169
|
object.type = object.ctype = Luca.defaultComponentType
|
|
204
170
|
|
|
205
|
-
|
|
171
|
+
# if the container defines a @defaults property
|
|
172
|
+
# then we should make sure our child components inherit
|
|
173
|
+
# these values unless specifically defined
|
|
174
|
+
object = _.defaults(object, (container.defaults || {}))
|
|
206
175
|
|
|
207
|
-
|
|
208
|
-
# we will create a function with that name on this container that
|
|
209
|
-
# allows you to access this component
|
|
210
|
-
if _.isString( component.getter )
|
|
211
|
-
@[ component.getter ] = (()-> component)
|
|
176
|
+
created = Luca.util.lazyComponent( object )
|
|
212
177
|
|
|
213
178
|
# if we're using base backbone views, then they don't extend themselves
|
|
214
179
|
# with their passed options, so this is a workaround to get them to
|
|
@@ -216,18 +181,12 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
|
|
|
216
181
|
if !component.container and component.options.container
|
|
217
182
|
component.container = component.options.container
|
|
218
183
|
|
|
219
|
-
|
|
220
|
-
map.cid_index[ component.cid ] = index
|
|
221
|
-
|
|
222
|
-
if map and component.name?
|
|
223
|
-
map.name_index[ component.name ] = index
|
|
184
|
+
indexComponent( component ).at(index).in( @componentIndex )
|
|
224
185
|
|
|
225
186
|
component
|
|
226
187
|
|
|
227
188
|
@componentsCreated = true
|
|
228
189
|
|
|
229
|
-
@registerComponentEvents() unless _.isEmpty(@componentEvents)
|
|
230
|
-
|
|
231
190
|
map
|
|
232
191
|
|
|
233
192
|
# Trigger the Rendering Pipeline process on all of the nested
|
|
@@ -271,32 +230,74 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
|
|
|
271
230
|
component.previously_activated = true
|
|
272
231
|
|
|
273
232
|
#### Underscore Methods For Working with Components
|
|
233
|
+
_: ()-> _( @components )
|
|
234
|
+
|
|
274
235
|
pluck: (attribute)->
|
|
275
|
-
_(
|
|
236
|
+
@_().pluck(attribute)
|
|
276
237
|
|
|
277
238
|
invoke: (method)->
|
|
278
|
-
_(
|
|
239
|
+
@_().invoke(method)
|
|
279
240
|
|
|
280
|
-
|
|
281
|
-
_(
|
|
282
|
-
|
|
283
|
-
# event binding sugar for nested components
|
|
284
|
-
#
|
|
285
|
-
# you can define events like:
|
|
241
|
+
select: (fn)->
|
|
242
|
+
@_().select(fn)
|
|
286
243
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
244
|
+
detect: (fn)->
|
|
245
|
+
@_().detect(attribute)
|
|
246
|
+
|
|
247
|
+
reject: (fn)->
|
|
248
|
+
@_().reject(fn)
|
|
249
|
+
|
|
250
|
+
map: (fn)->
|
|
251
|
+
@_().map(fn)
|
|
291
252
|
|
|
292
253
|
registerComponentEvents: ()->
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
254
|
+
container = @
|
|
255
|
+
|
|
256
|
+
for listener, handler of (@componentEvents||{})
|
|
257
|
+
[componentNameOrRole,eventId] = listener.split(' ')
|
|
258
|
+
|
|
259
|
+
unless _.isFunction( @[handler] )
|
|
260
|
+
console.log "Error registering component event", listener, componentNameOrRole, eventId
|
|
261
|
+
throw "Invalid component event definition #{ listener }. Specified handler is not a method on the container"
|
|
262
|
+
|
|
263
|
+
if componentNameOrRole is "*"
|
|
264
|
+
@eachComponent (component)=> component.on(eventId, @[handler], container)
|
|
265
|
+
else
|
|
266
|
+
component = @findComponentForEventBinding( componentNameOrRole )
|
|
267
|
+
|
|
268
|
+
unless component? and Luca.isComponent(component)
|
|
269
|
+
console.log "Error registering component event", listener, componentNameOrRole, eventId
|
|
270
|
+
throw "Invalid component event definition: #{ componentNameOrRole }"
|
|
271
|
+
|
|
272
|
+
component?.bind eventId, @[handler], container
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
subContainers: ()->
|
|
276
|
+
@select (component)->
|
|
277
|
+
component.isContainer is true
|
|
278
|
+
|
|
279
|
+
roles: ()->
|
|
280
|
+
_( @allChildren() ).pluck('role')
|
|
281
|
+
|
|
282
|
+
allChildren: ()->
|
|
283
|
+
children = @components
|
|
284
|
+
grandchildren = _( @subContainers() ).invoke('allChildren')
|
|
285
|
+
@_allChildren ||= _([children,grandchildren]).chain().compact().flatten().uniq().value()
|
|
286
|
+
|
|
287
|
+
findComponentForEventBinding: (nameRoleOrGetter, deep=false)->
|
|
288
|
+
@findComponentByName(nameRoleOrGetter, deep) || @findComponentByGetter( nameRoleOrGetter, deep ) || @findComponentByRole( nameRoleOrGetter, deep )
|
|
289
|
+
|
|
290
|
+
findComponentByGetter: (getter, deep=false)->
|
|
291
|
+
_( @allChildren() ).detect (component)->
|
|
292
|
+
component.getter is getter
|
|
293
|
+
|
|
294
|
+
findComponentByRole: (role,deep=false)->
|
|
295
|
+
_( @allChildren() ).detect (component)->
|
|
296
|
+
component.role is role
|
|
297
297
|
|
|
298
298
|
findComponentByName: (name, deep=false)->
|
|
299
|
-
@
|
|
299
|
+
_( @allChildren() ).detect (component)->
|
|
300
|
+
component.name is name
|
|
300
301
|
|
|
301
302
|
findComponentById: (id, deep=false)->
|
|
302
303
|
@findComponent(id, "cid_index", deep)
|
|
@@ -305,12 +306,14 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
|
|
|
305
306
|
@createComponents() unless @componentsCreated is true
|
|
306
307
|
|
|
307
308
|
position = @componentIndex?[ haystack ][ needle ]
|
|
308
|
-
component = @components
|
|
309
|
+
component = @components[ position ]
|
|
309
310
|
|
|
310
311
|
return component if component
|
|
311
312
|
|
|
312
313
|
if deep is true
|
|
313
|
-
sub_container = _( @components ).detect (component)->
|
|
314
|
+
sub_container = _( @components ).detect (component)->
|
|
315
|
+
component?.findComponent?(needle, haystack, true)
|
|
316
|
+
|
|
314
317
|
sub_container?.findComponent?(needle, haystack, true)
|
|
315
318
|
|
|
316
319
|
each: (fn)->
|
|
@@ -333,27 +336,24 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
|
|
|
333
336
|
return @components[ @activeItem ]
|
|
334
337
|
|
|
335
338
|
componentElements: ()->
|
|
336
|
-
@$("
|
|
339
|
+
@$("[data-luca-parent='#{ @name || @cid }']")
|
|
337
340
|
|
|
338
341
|
getComponent: (needle)->
|
|
339
342
|
@components[ needle ]
|
|
340
343
|
|
|
341
|
-
rootComponent: ()->
|
|
342
|
-
console.log "Calling rootComponent will be deprecated. use isRootComponent instead"
|
|
343
|
-
!@getParent?
|
|
344
|
-
|
|
345
344
|
isRootComponent:()->
|
|
346
345
|
!@getParent?
|
|
347
346
|
|
|
348
347
|
getRootComponent: ()->
|
|
349
|
-
if @
|
|
348
|
+
if @isRootComponent() then @ else @getParent().getRootComponent()
|
|
350
349
|
|
|
351
|
-
|
|
350
|
+
|
|
351
|
+
selectByAttribute: (attribute, value=undefined, deep=false)->
|
|
352
352
|
components = _( @components ).map (component)->
|
|
353
353
|
matches = []
|
|
354
354
|
test = component[ attribute ]
|
|
355
355
|
|
|
356
|
-
matches.push( component ) if test is value
|
|
356
|
+
matches.push( component ) if test is value or (not value? and test?)
|
|
357
357
|
|
|
358
358
|
# recursively traverse our components
|
|
359
359
|
matches.push component.selectByAttribute?(attribute, value, true) if deep is true
|
|
@@ -362,9 +362,6 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
|
|
|
362
362
|
|
|
363
363
|
_.flatten( components )
|
|
364
364
|
|
|
365
|
-
select: (attribute, value, deep=false)->
|
|
366
|
-
console.log "Container.select will be replaced by selectByAttribute in 1.0"
|
|
367
|
-
Luca.core.Container::selectByAttribute.apply(@, arguments)
|
|
368
365
|
|
|
369
366
|
# This is the method by which a container injects the rendered child views
|
|
370
367
|
# into the DOM. It will get passed the container object, and the component
|
|
@@ -372,3 +369,82 @@ _.def('Luca.core.Container').extends('Luca.components.Panel').with
|
|
|
372
369
|
Luca.core.Container.componentRenderer = (container, component)->
|
|
373
370
|
attachMethod = $( component.container )[ component.attachWith || "append" ]
|
|
374
371
|
attachMethod( component.render().el )
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
#### Private Helpers
|
|
375
|
+
|
|
376
|
+
doLayout = ()->
|
|
377
|
+
@trigger "before:layout", @
|
|
378
|
+
@prepareLayout()
|
|
379
|
+
@trigger "after:layout", @
|
|
380
|
+
|
|
381
|
+
applyDOMConfig = (panel, panelIndex)->
|
|
382
|
+
style_declarations = []
|
|
383
|
+
|
|
384
|
+
style_declarations.push "height: #{ (if _.isNumber(panel.height) then panel.height + 'px' else panel.height ) }" if panel.height?
|
|
385
|
+
style_declarations.push "width: #{ (if _.isNumber(panel.width) then panel.width + 'px' else panel.width ) }" if panel.width?
|
|
386
|
+
style_declarations.push "float: #{ panel.float }" if panel.float
|
|
387
|
+
|
|
388
|
+
config =
|
|
389
|
+
class: panel?.classes || @componentClass
|
|
390
|
+
id: "#{ @cid }-#{ panelIndex }"
|
|
391
|
+
style: style_declarations.join(';')
|
|
392
|
+
"data-luca-parent" : @name || @cid
|
|
393
|
+
|
|
394
|
+
if @customizeContainerEl?
|
|
395
|
+
config = @customizeContainerEl( config, panel, panelIndex )
|
|
396
|
+
|
|
397
|
+
config
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
createGetterMethods = ()->
|
|
402
|
+
container = @
|
|
403
|
+
|
|
404
|
+
childrenWithGetter = _( @allChildren() ).select (component)->
|
|
405
|
+
component.getter?
|
|
406
|
+
|
|
407
|
+
_( childrenWithGetter ).each (component)->
|
|
408
|
+
container[ component.getter ] ||= ()->
|
|
409
|
+
console.log "getter is being deprecated in favor of role"
|
|
410
|
+
console.log component.getter, component, container
|
|
411
|
+
component
|
|
412
|
+
|
|
413
|
+
createMethodsToGetComponentsByRole = ()->
|
|
414
|
+
container = @
|
|
415
|
+
|
|
416
|
+
childrenWithRole = _( @allChildren() ).select (component)->
|
|
417
|
+
component.role?
|
|
418
|
+
|
|
419
|
+
_( childrenWithRole ).each (component)->
|
|
420
|
+
getter = _.str.camelize( "get_" + component.role )
|
|
421
|
+
container[ getter ] ||= ()->
|
|
422
|
+
component
|
|
423
|
+
|
|
424
|
+
doComponents = ()->
|
|
425
|
+
@trigger "before:components", @, @components
|
|
426
|
+
@prepareComponents()
|
|
427
|
+
@createComponents()
|
|
428
|
+
@trigger "before:render:components", @, @components
|
|
429
|
+
@renderComponents()
|
|
430
|
+
@trigger "after:components", @, @components
|
|
431
|
+
createGetterMethods.call(@)
|
|
432
|
+
createMethodsToGetComponentsByRole.call(@)
|
|
433
|
+
@registerComponentEvents()
|
|
434
|
+
|
|
435
|
+
validateContainerConfiguration = ()->
|
|
436
|
+
true
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
# Private Helpers
|
|
440
|
+
#
|
|
441
|
+
# indexComponent( component ).at( index ).in( componentsInternalIndexMap )
|
|
442
|
+
indexComponent = (component)->
|
|
443
|
+
at: (index)->
|
|
444
|
+
in: (map)->
|
|
445
|
+
if component.cid?
|
|
446
|
+
map.cid_index[ component.cid ] = index
|
|
447
|
+
if component.role?
|
|
448
|
+
map.role_index[ component.role ] = index
|
|
449
|
+
if component.name?
|
|
450
|
+
map.name_index[ component.name ] = index
|