luca 0.9.65 → 0.9.76

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 (86) hide show
  1. data/CHANGELOG +30 -0
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +27 -0
  4. data/lib/luca/rails/version.rb +1 -1
  5. data/spec/components/controller_spec.coffee +58 -0
  6. data/spec/components/form_view_spec.coffee +4 -0
  7. data/spec/concerns/dom_helpers_spec.coffee +16 -0
  8. data/spec/{modules → concerns}/filterable_spec.coffee +0 -0
  9. data/spec/concerns/model_presenter_spec.coffee +31 -0
  10. data/spec/{modules → concerns}/paginatable_spec.coffee +0 -0
  11. data/spec/{modules → concerns}/state_model_spec.coffee +0 -0
  12. data/spec/concerns_spec.coffee +88 -0
  13. data/spec/core/container_spec.coffee +103 -6
  14. data/spec/core/field_spec.coffee +4 -0
  15. data/spec/core/model_spec.coffee +6 -1
  16. data/spec/define_spec.coffee +104 -7
  17. data/spec/framework_spec.coffee +30 -1
  18. data/spec/util_spec.coffee +24 -0
  19. data/src/components/application.coffee +62 -25
  20. data/src/components/base_toolbar.coffee +6 -4
  21. data/src/components/collection_loader_view.coffee +3 -1
  22. data/src/components/collection_view.coffee +36 -73
  23. data/src/components/controller.coffee +73 -35
  24. data/src/components/fields/button_field.coffee +20 -12
  25. data/src/components/fields/checkbox_array.coffee +8 -2
  26. data/src/components/fields/checkbox_field.coffee +18 -9
  27. data/src/components/fields/file_upload_field.coffee +5 -1
  28. data/src/components/fields/hidden_field.coffee +3 -1
  29. data/src/components/fields/label_field.coffee +4 -3
  30. data/src/components/fields/select_field.coffee +7 -8
  31. data/src/components/fields/text_area_field.coffee +3 -2
  32. data/src/components/fields/text_field.coffee +5 -4
  33. data/src/components/fields/type_ahead_field.coffee +4 -2
  34. data/src/components/form_button_toolbar.coffee +4 -1
  35. data/src/components/form_view.coffee +26 -24
  36. data/src/components/grid_view.coffee +3 -3
  37. data/src/components/multi_collection_view.coffee +6 -35
  38. data/src/components/pagination_control.coffee +1 -3
  39. data/src/components/router.coffee +2 -0
  40. data/src/components/table_view.coffee +7 -0
  41. data/src/concerns.coffee +70 -0
  42. data/src/{modules → concerns}/application_event_bindings.coffee +1 -1
  43. data/src/{modules → concerns}/collection_event_bindings.coffee +1 -1
  44. data/src/{modules → concerns}/deferrable.coffee +1 -1
  45. data/src/{modules → concerns}/dom_helpers.coffee +11 -2
  46. data/src/{modules → concerns}/enhanced_properties.coffee +1 -1
  47. data/src/{modules → concerns}/filterable.coffee +11 -11
  48. data/src/{modules → concerns}/grid_layout.coffee +1 -1
  49. data/src/{modules → concerns}/loadmaskable.coffee +1 -1
  50. data/src/{modules → concerns}/local_storage.coffee +0 -0
  51. data/src/{modules → concerns}/modal_view.coffee +1 -1
  52. data/src/concerns/model_presenter.coffee +23 -0
  53. data/src/{modules → concerns}/paginatable.coffee +9 -3
  54. data/src/concerns/query_collection_bindings.coffee +44 -0
  55. data/src/{modules → concerns}/state_model.coffee +1 -1
  56. data/src/{modules → concerns}/templating.coffee +1 -1
  57. data/src/containers/card_view.coffee +16 -9
  58. data/src/containers/tab_view.coffee +8 -11
  59. data/src/containers/viewport.coffee +3 -3
  60. data/src/core/collection.coffee +39 -28
  61. data/src/core/container.coffee +37 -15
  62. data/src/core/field.coffee +40 -39
  63. data/src/core/meta_data.coffee +93 -0
  64. data/src/core/model.coffee +18 -1
  65. data/src/core/registry.coffee +4 -3
  66. data/src/core/view.coffee +24 -30
  67. data/src/define.coffee +165 -79
  68. data/src/framework.coffee +97 -21
  69. data/src/index.coffee +4 -2
  70. data/src/managers/collection_manager.coffee +7 -3
  71. data/src/stylesheets/components/checkbox_array.scss +1 -1
  72. data/src/stylesheets/components/form_view.scss +5 -5
  73. data/src/stylesheets/components/viewport.scss +2 -1
  74. data/src/stylesheets/containers/container.scss +0 -5
  75. data/src/stylesheets/containers/tab_view.scss +5 -5
  76. data/src/templates/fields/text_area_field.jst.ejs +1 -1
  77. data/src/templates/fields/text_field.jst.ejs +1 -1
  78. data/src/util.coffee +47 -0
  79. data/vendor/assets/javascripts/luca-ui-full.js +1279 -494
  80. data/vendor/assets/javascripts/luca-ui-full.min.js +5 -5
  81. data/vendor/assets/javascripts/luca-ui-templates.js +2 -2
  82. data/vendor/assets/javascripts/luca-ui.js +1279 -494
  83. data/vendor/assets/javascripts/luca-ui.min.js +5 -4
  84. data/vendor/assets/stylesheets/luca-ui.css +15 -15
  85. metadata +27 -20
  86. data/spec/mixin_spec.coffee +0 -49
@@ -1,28 +1,87 @@
1
- _.def('Luca.components.Controller').extends('Luca.containers.CardView').with
1
+ controller = Luca.register "Luca.components.Controller"
2
+ controller.extends "Luca.containers.CardView"
2
3
 
3
- additionalClassNames:['luca-ui-controller']
4
+ controller.publicInterface
5
+ default: (callback)->
6
+ @navigate_to(@defaultPage || @defaultCard, callback)
7
+
8
+ activePage: ()->
9
+ @activeSection()
4
10
 
11
+ # switch the active card of this controller
12
+ # optionally passing an onActivation callback
13
+ # will fire this callback in the context of
14
+ # the currently active card
15
+ navigate_to: (section, callback)->
16
+ section ||= @defaultCard
17
+
18
+ # activate is a method on Luca.containers.CardView which
19
+ # selects a component and makes it visible, hiding any
20
+ # other component which may be monopolizing the view at that time.
21
+
22
+ # after activation it triggers a after:card:switch event
23
+ # and if it is the first time that view is being activated,
24
+ # it triggers a first:activation event which gets relayed to all
25
+ # child components in that view
26
+ @activate section, false, (activator, previous,current)=>
27
+ @state.set(active_section: current.name )
28
+ if _.isFunction( callback )
29
+ callback.apply(current)
30
+
31
+ # return the section we are navigating to
32
+ @find(section)
33
+
34
+ controller.classMethods
35
+ controllerPath: ()->
36
+ component = @
37
+
38
+ list = [component.name]
39
+ atBase = false
40
+
41
+ while component and not atBase
42
+ component = component.getParent?()
43
+ atBase = true if component?.role is "main_controller"
44
+ list.push( component.name ) if component? and not atBase
45
+
46
+ list.reverse()
47
+
48
+ controller.defines
49
+ additionalClassNames: 'luca-ui-controller'
5
50
  activeAttribute: "active-section"
51
+ stateful: true
6
52
 
7
53
  initialize: (@options)->
8
- Luca.containers.CardView::initialize.apply @, arguments
54
+ # let's phase out the 'card' terminology
55
+ # and 'section' while we're at it. page is the word.
56
+ @defaultCard ||= @defaultPage ||= @components[0]?.name || 0
57
+ @defaultPage ||= @defaultCard
9
58
 
10
- @defaultCard ||= @components[0]?.name
59
+ @defaultState ||=
60
+ active_section: @defaultPage
11
61
 
12
- throw "Controllers must specify a defaultCard property and/or the first component must have a name" unless @defaultCard
62
+ Luca.containers.CardView::initialize.apply @, arguments
63
+
64
+ throw "Controllers must specify a defaultCard property and/or the first component must have a name" unless @defaultCard?
13
65
 
14
- @state = new Backbone.Model
15
- active_section: @defaultCard
66
+ @_().each (component)->
67
+ component.controllerPath = Luca.components.Controller.controllerPath
16
68
 
17
69
  each: (fn)->
18
- _( @components ).each (component)=>
19
- fn.apply @, [component]
70
+ _( @components ).each (component)=> fn.call(@,component)
20
71
 
21
72
  activeSection: ()->
22
- @get("activeSection")
73
+ @get("active_section")
74
+
75
+ pageControllers: (deep=false)->
76
+ @controllers.apply(@, arguments)
23
77
 
24
78
  controllers:(deep=false)->
25
- @select 'ctype', 'controller', deep
79
+ @select (component)->
80
+ type = (component.type || component.ctype)
81
+ type is "controller" or type is "page_controller"
82
+
83
+ availablePages: ()->
84
+ @availableSections.apply(@, arguments)
26
85
 
27
86
  availableSections: ()->
28
87
  base = {}
@@ -33,31 +92,10 @@ _.def('Luca.components.Controller').extends('Luca.containers.CardView').with
33
92
  memo
34
93
  , base
35
94
 
95
+ pageNames: ()->
96
+ @sectionNames()
97
+
36
98
  sectionNames: (deep=false)->
37
99
  @pluck('name')
38
100
 
39
- default: (callback)->
40
- @navigate_to(@defaultCard, callback)
41
-
42
- # switch the active card of this controller
43
- # optionally passing an onActivation callback
44
- # will fire this callback in the context of
45
- # the currently active card
46
- navigate_to: (section, callback)->
47
- section ||= @defaultCard
48
-
49
- # activate is a method on Luca.containers.CardView which
50
- # selects a component and makes it visible, hiding any
51
- # other component which may be monopolizing the view at that time.
52
-
53
- # after activation it triggers a after:card:switch event
54
- # and if it is the first time that view is being activated,
55
- # it triggers a first:activation event which gets relayed to all
56
- # child components in that view
57
- @activate section, false, (activator, previous,current)=>
58
- @state.set(active_section: current.name )
59
- if _.isFunction( callback )
60
- callback.apply(current)
61
101
 
62
- # return the section we are navigating to
63
- @find(section)
@@ -1,18 +1,24 @@
1
- _.def('Luca.fields.ButtonField').extends('Luca.core.Field').with
1
+ buttonField = Luca.register "Luca.fields.ButtonField"
2
2
 
3
- readOnly: true
3
+ buttonField.extends "Luca.core.Field"
4
4
 
5
- events:
6
- "click input" : "click_handler"
7
-
8
- hooks:[
9
- "button:click"
10
- ]
5
+ buttonField.triggers "button:click"
11
6
 
12
- className: 'luca-ui-field luca-ui-button-field'
7
+ buttonField.publicConfiguration
8
+ readOnly: true
9
+ input_value: undefined
10
+ input_type: "button"
11
+ icon_class: undefined
12
+ input_name: undefined
13
+ white: undefined
13
14
 
14
- template: 'fields/button_field'
15
+ buttonField.privateConfiguration
16
+ isButton: true
17
+ template: "fields/button_field"
18
+ events:
19
+ "click input" : "click_handler"
15
20
 
21
+ buttonField.privateInterface
16
22
  click_handler: (e)->
17
23
  me = my = $( e.currentTarget )
18
24
  @trigger "button:click"
@@ -29,10 +35,12 @@ _.def('Luca.fields.ButtonField').extends('Luca.core.Field').with
29
35
  @input_id ||= _.uniqueId('button')
30
36
  @input_name ||= @name ||= @input_id
31
37
  @input_value ||= @label ||= @text
32
- @input_type ||= "button"
33
38
  @input_class ||= @class
34
39
  @icon_class ||= ""
35
40
  @icon_class = "icon-#{ @icon_class }" if @icon_class.length and !@icon_class.match(/^icon-/)
36
41
  @icon_class += " icon-white" if @white
37
42
 
38
- setValue: ()-> true
43
+ setValue: ()-> true
44
+
45
+ buttonField.defines
46
+ version: 1
@@ -1,6 +1,9 @@
1
1
  make = Luca.View::make
2
2
 
3
- _.def('Luca.fields.CheckboxArray').extends('Luca.core.Field').with
3
+ checkboxArray = Luca.register "Luca.fields.CheckboxArray"
4
+ checkboxArray.extends "Luca.core.Field"
5
+
6
+ checkboxArray.defines
4
7
  version: 2
5
8
 
6
9
  template: "fields/checkbox_array"
@@ -14,7 +17,7 @@ _.def('Luca.fields.CheckboxArray').extends('Luca.core.Field').with
14
17
 
15
18
  initialize: (@options={})->
16
19
  _.extend @, @options
17
- _.extend @, Luca.modules.Deferrable
20
+ _.extend @, Luca.concerns.Deferrable
18
21
  _.bindAll @, "renderCheckboxes", "clickHandler", "checkSelected"
19
22
 
20
23
  Luca.core.Field::initialize.apply @, arguments
@@ -33,6 +36,9 @@ _.def('Luca.fields.CheckboxArray').extends('Luca.core.Field').with
33
36
 
34
37
  cbArray = @
35
38
 
39
+ unless Luca.isBackboneCollection(@collection)
40
+ throw "Checkbox Array Fields must specify a @collection property"
41
+
36
42
  if @collection.length > 0
37
43
  @renderCheckboxes()
38
44
  else
@@ -1,13 +1,20 @@
1
- _.def('Luca.fields.CheckboxField').extends('Luca.core.Field').with
1
+ checkboxField = Luca.register "Luca.fields.CheckboxField"
2
2
 
3
- events:
4
- "change input" : "change_handler"
3
+ checkboxField.extends "Luca.core.Field"
5
4
 
6
- className: 'luca-ui-checkbox-field luca-ui-field'
7
- template: 'fields/checkbox_field'
8
- hooks: ["checked","unchecked"]
5
+ checkboxField.triggers "checked",
6
+ "unchecked"
7
+
8
+ checkboxField.publicConfiguration
9
9
  send_blanks: true
10
+ input_value: 1
10
11
 
12
+ checkboxField.privateConfiguration
13
+ template: 'fields/checkbox_field'
14
+ events:
15
+ "change input" : "change_handler"
16
+
17
+ checkboxField.privateInterface
11
18
  change_handler: (e)->
12
19
  me = my = $(e.target)
13
20
 
@@ -24,14 +31,16 @@ _.def('Luca.fields.CheckboxField').extends('Luca.core.Field').with
24
31
 
25
32
  Luca.core.Field::initialize.apply @, arguments
26
33
 
27
- afterInitialize: ()->
28
34
  @input_id ||= _.uniqueId('field')
29
35
  @input_name ||= @name
30
- @input_value ||= 1
31
36
  @label ||= @name
32
37
 
38
+ checkboxField.publicInterface
33
39
  setValue: (checked)->
34
40
  @getInputElement().attr('checked', checked)
35
41
 
36
42
  getValue:()->
37
- @getInputElement().is(":checked")
43
+ @getInputElement().is(":checked")
44
+
45
+ checkboxField.defines
46
+ version: 1
@@ -1,4 +1,8 @@
1
- _.def('Luca.fields.FileUploadField').extends('Luca.core.Field').with
1
+ fileUpload = Luca.register "Luca.fields.FileUploadField"
2
+ fileUpload.extends "Luca.core.Field"
3
+
4
+ fileUpload.defines
5
+ version: 1
2
6
 
3
7
  template: 'fields/file_upload_field'
4
8
 
@@ -1,5 +1,7 @@
1
- _.def('Luca.fields.HiddenField').extends('Luca.core.Field').with
1
+ hiddenField = Luca.register "Luca.fields.HiddenField"
2
+ hiddenField.extends "Luca.core.Field"
2
3
 
4
+ hiddenField.defines
3
5
  template: 'fields/hidden_field'
4
6
 
5
7
  afterInitialize: ()->
@@ -1,6 +1,7 @@
1
- _.def("Luca.components.LabelField").extends("Luca.core.Field").with
2
- className: "luca-ui-field luca-ui-label-field"
3
-
1
+ labelField = Luca.register "Luca.components.LabelField"
2
+ labelField.extends "Luca.core.Field"
3
+
4
+ labelField.defines
4
5
  formatter: (value)->
5
6
  value ||= @getValue()
6
7
  _.str.titleize( value )
@@ -1,13 +1,12 @@
1
- _.def('Luca.fields.SelectField').extends('Luca.core.Field').with
1
+ selectField = Luca.register "Luca.fields.SelectField"
2
2
 
3
- events:
4
- "change select" : "change_handler"
3
+ selectField.extends "Luca.core.Field"
5
4
 
6
- hooks:[
7
- "after:select"
8
- ]
5
+ selectField.triggers "after:select"
9
6
 
10
- className: 'luca-ui-select-field luca-ui-field'
7
+ selectField.defines
8
+ events:
9
+ "change select" : "change_handler"
11
10
 
12
11
  template: "fields/select_field"
13
12
 
@@ -19,7 +18,7 @@ _.def('Luca.fields.SelectField').extends('Luca.core.Field').with
19
18
 
20
19
  initialize: (@options={})->
21
20
  _.extend @, @options
22
- _.extend @, Luca.modules.Deferrable
21
+ _.extend @, Luca.concerns.Deferrable
23
22
  _.bindAll @, "change_handler", "populateOptions", "beforeFetch"
24
23
 
25
24
  Luca.core.Field::initialize.apply @, arguments
@@ -13,14 +13,15 @@ _.def('Luca.fields.TextAreaField').extends('Luca.core.Field').with
13
13
  initialize: (@options={})->
14
14
  _.bindAll @, "keydown_handler"
15
15
 
16
- Luca.core.Field::initialize.apply @, arguments
17
-
18
16
  @input_id ||= _.uniqueId('field')
19
17
  @input_name ||= @name
20
18
  @label ||= @name
21
19
  @input_class ||= @class
22
20
  @input_value ||= ""
23
21
  @inputStyles ||= "height:#{ @height };width:#{ @width }"
22
+ @placeHolder ||= ""
23
+
24
+ Luca.core.Field::initialize.apply @, arguments
24
25
 
25
26
  setValue: (value)->
26
27
  $( @field() ).val(value)
@@ -1,5 +1,7 @@
1
+ textField = Luca.register 'Luca.fields.TextField'
2
+ textField.extends 'Luca.core.Field'
1
3
 
2
- _.def('Luca.fields.TextField').extends('Luca.core.Field').with
4
+ textField.defines
3
5
  events:
4
6
  "blur input" : "blur_handler"
5
7
  "focus input" : "focus_handler"
@@ -22,9 +24,6 @@ _.def('Luca.fields.TextField').extends('Luca.core.Field').with
22
24
  @label ||= @name
23
25
  @input_class ||= @class
24
26
  @input_value ||= @value || ""
25
-
26
- # TODO
27
- # Placeholder?
28
27
 
29
28
  if @prepend
30
29
  @$el.addClass('input-prepend')
@@ -34,6 +33,8 @@ _.def('Luca.fields.TextField').extends('Luca.core.Field').with
34
33
  @$el.addClass('input-append')
35
34
  @addOn = @append
36
35
 
36
+ @placeHolder ||= ""
37
+
37
38
  Luca.core.Field::initialize.apply @, arguments
38
39
 
39
40
  keyup_handler: (e)->
@@ -1,6 +1,8 @@
1
- _.def('Luca.fields.TypeAheadField').extends('Luca.fields.TextField').with
2
- className: 'luca-ui-field'
1
+ typeAheadField = Luca.register "Luca.fields.TypeAheadField"
2
+ typeAheadField.extends "Luca.fields.TextField"
3
3
 
4
+
5
+ typeAheadField.defines
4
6
  getSource: ()->
5
7
  Luca.util.read(@source) || []
6
8
 
@@ -1,5 +1,7 @@
1
- _.def('Luca.components.FormButtonToolbar').extends('Luca.components.Toolbar').with
1
+ toolbar = Luca.register "Luca.components.FormButtonToolbar"
2
+ toolbar.extends "Luca.components.Toolbar"
2
3
 
4
+ toolbar.defines
3
5
  className: 'luca-ui-form-toolbar form-actions'
4
6
 
5
7
  position: 'bottom'
@@ -8,6 +10,7 @@ _.def('Luca.components.FormButtonToolbar').extends('Luca.components.Toolbar').wi
8
10
 
9
11
  render: ()->
10
12
  $(@container).append(@el)
13
+ @
11
14
 
12
15
  initialize: (@options={})->
13
16
  Luca.components.Toolbar.prototype.initialize.apply @, arguments
@@ -1,25 +1,28 @@
1
- _.def("Luca.components.FormView").extends('Luca.core.Container').with
2
-
1
+ #_.def("Luca.components.FormView").extends('Luca.core.Container').with
2
+
3
+ formView = Luca.register "Luca.components.FormView"
4
+ formView.extends "Luca.core.Container"
5
+
6
+ formView.triggers "before:submit",
7
+ "before:reset",
8
+ "before:load",
9
+ "before:load:new",
10
+ "before:load:existing",
11
+ "after:submit",
12
+ "after:reset",
13
+ "after:load",
14
+ "after:load:new",
15
+ "after:load:existing",
16
+ "after:submit:success",
17
+ "after:submit:fatal_error",
18
+ "after:submit:error"
19
+
20
+
21
+ formView.defines
3
22
  tagName: 'form'
4
23
 
5
24
  className: 'luca-ui-form-view'
6
25
 
7
- hooks:[
8
- "before:submit"
9
- "before:reset"
10
- "before:load"
11
- "before:load:new"
12
- "before:load:existing"
13
- "after:submit"
14
- "after:reset"
15
- "after:load"
16
- "after:load:new"
17
- "after:load:existing"
18
- "after:submit:success"
19
- "after:submit:fatal_error"
20
- "after:submit:error"
21
- ]
22
-
23
26
  events:
24
27
  "click .submit-button" : "submitHandler"
25
28
  "click .reset-button" : "resetHandler"
@@ -30,17 +33,16 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
30
33
 
31
34
  bodyClassName: "form-view-body"
32
35
 
33
- version: "0.9.33333333"
36
+ version: 1
34
37
 
35
38
  initialize: (@options={})->
36
- @loadMask = Luca.enableBootstrap unless @loadMask?
39
+ @loadMask = Luca.config.enableBoostrap unless @loadMask?
37
40
 
38
41
  Luca.core.Container::initialize.apply @, arguments
39
42
 
40
43
  @components ||= @fields
41
44
 
42
- _.bindAll @, "submitHandler", "resetHandler", "renderToolbars", "applyLoadMask"
43
-
45
+ _.bindAll @, "submitHandler", "resetHandler", "renderToolbars"
44
46
  @state ||= new Backbone.Model
45
47
 
46
48
  @setupHooks( @hooks )
@@ -55,7 +57,7 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
55
57
  Luca.components.FormView.defaultFormViewToolbar
56
58
 
57
59
  applyStyleClasses: ()->
58
- if Luca.enableBootstrap
60
+ if Luca.config.enableBoostrap
59
61
  @applyBootstrapStyleClasses()
60
62
 
61
63
  @$el.addClass( "label-align-#{ @labelAlign }") if @labelAlign
@@ -181,7 +183,7 @@ _.def("Luca.components.FormView").extends('Luca.core.Container').with
181
183
  if options.debug
182
184
  console.log "#{ key } Options", options, "Value", value, "Value Is Blank?", valueIsBlank, "Allow Blanks?", allowBlankValues
183
185
 
184
- if options.skip_buttons and field.ctype is "button_field"
186
+ if options.skip_buttons and field.isButton
185
187
  skip = true
186
188
  else
187
189
  if valueIsBlank and allowBlankValues is false