luca 0.8.599 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.rvmrc +1 -0
- data/CHANGELOG +51 -2
- data/README.md +10 -247
- data/ROADMAP +6 -2
- data/app.rb +16 -2
- data/assets/javascripts/dependencies/bootstrap.min.js +7 -1
- data/assets/javascripts/dependencies/codemirror-coffeescript.js +347 -0
- data/assets/javascripts/dependencies/codemirror-css.js +124 -0
- data/assets/javascripts/dependencies/codemirror-html.js +410 -0
- data/assets/javascripts/dependencies/codemirror-javascript.js +361 -0
- data/assets/javascripts/dependencies/codemirror-less.js +232 -0
- data/assets/javascripts/dependencies/codemirror-vim.js +500 -0
- data/assets/javascripts/dependencies/codemirror.js +3076 -0
- data/assets/javascripts/dependencies.coffee +0 -1
- data/assets/javascripts/luca-ui-base.coffee +10 -3
- data/assets/javascripts/luca-ui-bootstrap.js +1 -0
- data/assets/javascripts/luca-ui-development-tools.coffee +9 -0
- data/assets/javascripts/luca-ui.coffee +6 -1
- data/assets/javascripts/sandbox/application.coffee +51 -0
- data/assets/javascripts/sandbox/router.coffee +14 -0
- data/assets/javascripts/sandbox/templates/main.luca +33 -0
- data/assets/javascripts/sandbox/templates/sandbox/navigation.luca +1 -0
- data/assets/javascripts/sandbox/templates/sandbox.luca +1 -0
- data/assets/javascripts/sandbox/views/top_navigation.coffee +4 -0
- data/assets/javascripts/sandbox.coffee +2 -2
- data/assets/stylesheets/bootstrap.min.css +395 -297
- data/assets/stylesheets/codemirror-blackboard.css +25 -0
- data/assets/stylesheets/codemirror-monokai.css +33 -0
- data/assets/stylesheets/codemirror.css +126 -0
- data/assets/stylesheets/luca-ui-bootstrap.css +0 -1
- data/assets/stylesheets/luca-ui-development-tools.css +5 -0
- data/assets/stylesheets/sandbox/sandbox.scss +1 -3
- data/assets/stylesheets/themes/amelia-bootstrap.css +826 -0
- data/assets/stylesheets/themes/slate-bootstrap.css +797 -0
- data/assets/stylesheets/themes/superhero-bootstrap.css +830 -0
- data/lib/luca/code_browser.rb +55 -0
- data/lib/luca/rails/version.rb +1 -1
- data/lib/luca/rails.rb +1 -0
- data/spec/components/fields/checkbox_array_spec.coffee +46 -0
- data/spec/components/form_view_spec.coffee +10 -4
- data/spec/containers/card_view_spec.coffee +7 -0
- data/spec/core/collection_spec.coffee +58 -4
- data/spec/core/container_spec.coffee +6 -6
- data/spec/core/view_spec.coffee +93 -7
- data/spec/framework_spec.coffee +15 -12
- data/src/components/application.coffee +126 -18
- data/src/components/base_toolbar.coffee +2 -2
- data/src/components/collection_loader_view.coffee +1 -2
- data/src/components/collection_view.coffee +77 -0
- data/src/components/controller.coffee +1 -4
- data/src/components/fields/button_field.coffee +1 -1
- data/src/components/fields/checkbox_array.coffee +2 -2
- data/src/components/fields/checkbox_field.coffee +3 -1
- data/src/components/fields/file_upload_field.coffee +1 -1
- data/src/components/fields/hidden_field.coffee +1 -1
- data/src/components/fields/select_field.coffee +1 -1
- data/src/components/fields/text_area_field.coffee +1 -1
- data/src/components/fields/text_field.coffee +10 -6
- data/src/components/fields/type_ahead_field.coffee +18 -5
- data/src/components/form_button_toolbar.coffee +1 -2
- data/src/components/form_view.coffee +44 -62
- data/src/components/grid_view.coffee +27 -20
- data/src/components/load_mask.coffee +3 -0
- data/src/components/nav_bar.coffee +26 -0
- data/src/components/record_manager.coffee +1 -3
- data/src/components/router.coffee +1 -1
- data/src/components/template.coffee +3 -15
- data/src/components/toolbar_dialog.coffee +25 -0
- data/src/containers/card_view.coffee +22 -23
- data/src/containers/column_view.coffee +1 -6
- data/src/containers/modal_view.coffee +20 -71
- data/src/containers/panel_toolbar.coffee +156 -0
- data/src/containers/panel_view.coffee +1 -1
- data/src/containers/split_view.coffee +1 -3
- data/src/containers/tab_view.coffee +29 -29
- data/src/containers/viewport.coffee +38 -3
- data/src/core/collection.coffee +80 -48
- data/src/core/container.coffee +153 -72
- data/src/core/core.coffee +181 -0
- data/src/core/field.coffee +4 -2
- data/src/core/model.coffee +1 -1
- data/src/core/observer.coffee +3 -3
- data/src/core/panel.coffee +143 -0
- data/src/core/registry.coffee +104 -0
- data/src/core/util.coffee +82 -0
- data/src/core/view.coffee +158 -85
- data/src/framework.coffee +112 -178
- data/src/index.coffee +0 -255
- data/src/managers/collection_manager.coffee +1 -0
- data/src/samples/definition.coffee +49 -0
- data/src/stylesheets/base.scss +0 -78
- data/src/stylesheets/components/form_view.scss +8 -3
- data/src/stylesheets/components/grid_view.scss +3 -7
- data/src/stylesheets/components/load_mask.scss +14 -0
- data/src/stylesheets/components/toolbar.scss +0 -15
- data/src/stylesheets/containers/container.scss +14 -2
- data/src/stylesheets/containers/panels.scss +23 -0
- data/src/stylesheets/tools/class_browser.scss +32 -0
- data/src/stylesheets/tools/code_editor.scss +24 -0
- data/src/stylesheets/tools/component_tester.scss +8 -0
- data/src/stylesheets/tools/console.scss +26 -0
- data/src/templates/components/collection_loader_view.luca +1 -1
- data/src/templates/components/form_view.luca +2 -13
- data/src/templates/components/grid_view.luca +0 -2
- data/src/templates/components/load_mask.luca +3 -0
- data/src/templates/components/nav_bar.luca +2 -0
- data/src/templates/containers/tab_view.luca +1 -0
- data/src/templates/fields/text_field.luca +4 -1
- data/src/tools/class_browser.coffee +39 -0
- data/src/tools/code_editor.coffee +258 -0
- data/src/tools/code_mirror_field.coffee +57 -0
- data/src/tools/coffee_script_editor.coffee +60 -0
- data/src/tools/collection_inspector.coffee +4 -0
- data/src/tools/component_tester.coffee +472 -0
- data/src/tools/components/class_browser_detail.coffee +10 -0
- data/src/tools/components/class_browser_list.coffee +74 -0
- data/src/tools/console.coffee +147 -0
- data/src/tools/development_console.coffee +147 -0
- data/src/tools/models/components.coffee +63 -0
- data/src/tools/templates/component_tester/help.luca +14 -0
- data/vendor/assets/javascripts/luca-ui-base.js +1389 -611
- data/vendor/assets/javascripts/luca-ui-bootstrap.js +9 -0
- data/vendor/assets/javascripts/luca-ui-development-tools.js +18719 -0
- data/vendor/assets/javascripts/luca-ui-spec.js +2065 -878
- data/vendor/assets/javascripts/luca-ui.js +1759 -852
- data/vendor/assets/javascripts/luca-ui.min.js +3 -3
- data/vendor/assets/stylesheets/luca-ui-bootstrap.css +494 -440
- data/vendor/assets/stylesheets/luca-ui-development-tools.css +224 -0
- data/vendor/assets/stylesheets/luca-ui-spec.css +99 -140
- data/vendor/assets/stylesheets/luca-ui.css +99 -140
- data/views/index.erb +6 -3
- metadata +60 -18
- data/assets/javascripts/dependencies/jquery-console.js +0 -649
- data/assets/javascripts/development-console.coffee +0 -2
- data/assets/javascripts/sandbox/sandbox.coffee +0 -16
- data/assets/javascripts/sandbox/templates/features/collection_helpers.luca +0 -33
- data/assets/javascripts/sandbox/templates/features/form_demo_code.luca +0 -48
- data/assets/javascripts/sandbox/templates/features/grid_demo_code.luca +0 -24
- data/assets/javascripts/sandbox/templates/features/introduction.luca +0 -11
- data/assets/javascripts/sandbox/templates/features/view_helpers.luca +0 -43
- data/assets/javascripts/sandbox/templates/navigation.luca +0 -8
- data/assets/javascripts/sandbox/views/form_demo.coffee +0 -47
- data/assets/javascripts/sandbox/views/grid_demo.coffee +0 -23
- data/assets/javascripts/sandbox/views/pages/collection_events_sample.coffee +0 -1
- data/assets/javascripts/sandbox/views/pages/pages_controller.coffee +0 -38
- data/src/components/collection_inspector.coffee +0 -2
- data/src/components/development_console.coffee +0 -59
- data/src/stylesheets/components/development_console.scss +0 -47
data/src/core/view.coffee
CHANGED
@@ -1,6 +1,4 @@
|
|
1
1
|
#### Luca Base View
|
2
|
-
Luca.View = Backbone.View.extend
|
3
|
-
base: 'Luca.View'
|
4
2
|
|
5
3
|
# The Luca.View class adds some very commonly used patterns
|
6
4
|
# and functionality to the stock Backbone.View class. Features
|
@@ -8,82 +6,19 @@ Luca.View = Backbone.View.extend
|
|
8
6
|
# against a Backbone.Model or Backbone.Collection reset event, Caching
|
9
7
|
# views into a global Component Registry, and more.
|
10
8
|
|
11
|
-
Luca.View.
|
9
|
+
_.def("Luca.View").extends("Backbone.View").with
|
12
10
|
|
13
|
-
|
14
|
-
# some method definitions and add special behavior around them
|
15
|
-
# mostly related to render()
|
16
|
-
Luca.View.extend = (definition)->
|
17
|
-
#### Rendering
|
18
|
-
#
|
19
|
-
# Our base view class wraps the defined render() method
|
20
|
-
# of the views which inherit from it, and does things like
|
21
|
-
# trigger the before and after render events automatically.
|
22
|
-
# In addition, if the view has a deferrable property on it
|
23
|
-
# then it will make sure that the render method doesn't get called
|
24
|
-
# until.
|
25
|
-
|
26
|
-
_base = definition.render
|
27
|
-
|
28
|
-
_base ||= ()->
|
29
|
-
container = if _.isFunction(@container) then @container() else @container
|
30
|
-
|
31
|
-
return @ unless $(container) and @$el
|
32
|
-
|
33
|
-
$(container).append( @$el )
|
34
|
-
|
35
|
-
return @
|
36
|
-
|
37
|
-
definition.render = ()->
|
38
|
-
if @layoutTemplate?
|
39
|
-
@$el.html()
|
40
|
-
|
41
|
-
if @deferrable
|
42
|
-
@trigger "before:render", @
|
43
|
-
|
44
|
-
@deferrable.bind @deferrable_event, _.once ()=>
|
45
|
-
_base.apply(@, arguments)
|
46
|
-
@trigger "after:render", @
|
47
|
-
|
48
|
-
# we might not want to fetch immediately upon
|
49
|
-
# rendering, so we can pass a deferrable_trigger
|
50
|
-
# event and not fire the fetch until this event
|
51
|
-
# occurs
|
52
|
-
if !@deferrable_trigger
|
53
|
-
@immediate_trigger = true
|
54
|
-
|
55
|
-
if @immediate_trigger is true
|
56
|
-
@deferrable.fetch()
|
57
|
-
else
|
58
|
-
@bind @deferrable_trigger, _.once ()=>
|
59
|
-
@deferrable.fetch()
|
60
|
-
|
61
|
-
return @
|
62
|
-
|
63
|
-
else
|
64
|
-
@trigger "before:render", @
|
65
|
-
_base.apply(@, arguments)
|
66
|
-
@trigger "after:render", @
|
67
|
-
|
68
|
-
return @
|
69
|
-
|
70
|
-
Luca.View.originalExtend.call(@, definition)
|
71
|
-
|
72
|
-
_.extend Luca.View.prototype,
|
73
|
-
applyStyles: (styles={})->
|
74
|
-
for setting, value of styles
|
75
|
-
@$el.css(setting,value)
|
76
|
-
|
77
|
-
@
|
11
|
+
additionalClassNames:[]
|
78
12
|
|
79
13
|
debug: ()->
|
80
14
|
return unless @debugMode or window.LucaDebugMode?
|
81
15
|
console.log [(@name || @cid),message] for message in arguments
|
82
16
|
|
83
17
|
trigger: ()->
|
84
|
-
if Luca.enableGlobalObserver
|
85
|
-
Luca.
|
86
|
-
|
18
|
+
if Luca.enableGlobalObserver
|
19
|
+
if Luca.developmentMode is true or @observeEvents is true
|
20
|
+
Luca.ViewObserver ||= new Luca.Observer(type:"view")
|
21
|
+
Luca.ViewObserver.relay @, arguments
|
87
22
|
|
88
23
|
Backbone.View.prototype.trigger.apply @, arguments
|
89
24
|
|
@@ -96,17 +31,16 @@ _.extend Luca.View.prototype,
|
|
96
31
|
"deactivation"
|
97
32
|
]
|
98
33
|
|
99
|
-
# which event should we listen to on
|
100
|
-
# our deferrable property, before we
|
101
|
-
# trigger the actual rendering
|
102
|
-
deferrable_event: "reset"
|
103
|
-
|
104
34
|
initialize: (@options={})->
|
105
35
|
|
106
36
|
_.extend @, @options
|
107
37
|
|
108
38
|
@cid = _.uniqueId(@name) if @name?
|
109
39
|
|
40
|
+
if template = @bodyTemplate
|
41
|
+
@$el.empty()
|
42
|
+
Luca.View::$html.call(@, Luca.template(template, @) )
|
43
|
+
|
110
44
|
#### View Caching
|
111
45
|
#
|
112
46
|
# Luca.View(s) which get created get stored in a global cache by their
|
@@ -118,10 +52,11 @@ _.extend Luca.View.prototype,
|
|
118
52
|
@setupHooks( unique )
|
119
53
|
|
120
54
|
if @autoBindEventHandlers is true
|
121
|
-
|
122
|
-
if _.isString(handler)
|
123
|
-
_.bindAll @, handler
|
55
|
+
@bindAllEventHandlers()
|
124
56
|
|
57
|
+
if @additionalClassNames
|
58
|
+
@additionalClassNames = @additionalClassNames.split(" ") if _.isString(@additionalClassNames)
|
59
|
+
@$el.addClass( additional ) for additional in @additionalClassNames
|
125
60
|
|
126
61
|
@trigger "after:initialize", @
|
127
62
|
|
@@ -129,7 +64,36 @@ _.extend Luca.View.prototype,
|
|
129
64
|
|
130
65
|
@delegateEvents()
|
131
66
|
|
132
|
-
|
67
|
+
#### JQuery / DOM Selector Helpers
|
68
|
+
$wrap: (wrapper)->
|
69
|
+
if !wrapper.match(/[<>]/)
|
70
|
+
wrapper = @make("div",class:wrapper)
|
71
|
+
|
72
|
+
@$el.wrap( wrapper )
|
73
|
+
|
74
|
+
$template: (template, variables={})->
|
75
|
+
@$el.html( Luca.template(template,variables) )
|
76
|
+
|
77
|
+
$html: (content)->
|
78
|
+
@$el.html( content )
|
79
|
+
|
80
|
+
$append: (content)->
|
81
|
+
@$el.append( content )
|
82
|
+
|
83
|
+
#### Containers
|
84
|
+
#
|
85
|
+
# Luca is heavily reliant on the concept of Container views. Views which
|
86
|
+
# contain other views and handle inter-component communication between the
|
87
|
+
# component views. The default render() operation consists of building the
|
88
|
+
# view's content, and then attaching that view to its container.
|
89
|
+
#
|
90
|
+
# 99% of the time this would happen automatically
|
91
|
+
$attach: ()->
|
92
|
+
@$container().append( @el )
|
93
|
+
|
94
|
+
$container: ()->
|
95
|
+
$(@container)
|
96
|
+
|
133
97
|
#### Hooks or Auto Event Binding
|
134
98
|
#
|
135
99
|
# views which inherit from Luca.View can define hooks
|
@@ -147,13 +111,14 @@ _.extend Luca.View.prototype,
|
|
147
111
|
set ||= @hooks
|
148
112
|
|
149
113
|
_(set).each (eventId)=>
|
150
|
-
|
151
|
-
|
114
|
+
fn = Luca.util.hook( eventId )
|
115
|
+
|
116
|
+
callback = ()=>
|
117
|
+
@[fn]?.apply @, arguments
|
152
118
|
|
153
|
-
|
154
|
-
fn = prefix + parts.join('')
|
119
|
+
callback = _.once(callback) if eventId?.match(/once:/)
|
155
120
|
|
156
|
-
@bind eventId,
|
121
|
+
@bind eventId, callback
|
157
122
|
|
158
123
|
|
159
124
|
#### Luca.Collection and Luca.CollectionManager integration
|
@@ -207,3 +172,111 @@ _.extend Luca.View.prototype,
|
|
207
172
|
@events ||= {}
|
208
173
|
@events[ selector ] = handler
|
209
174
|
@delegateEvents()
|
175
|
+
|
176
|
+
bindAllEventHandlers: ()->
|
177
|
+
_( @events ).each (handler,event)=>
|
178
|
+
if _.isString(handler)
|
179
|
+
_.bindAll @, handler
|
180
|
+
|
181
|
+
definitionClass: ()->
|
182
|
+
Luca.util.resolve(@displayName, window)?.prototype
|
183
|
+
|
184
|
+
# refreshCode happens whenever the Luca.Framework extension
|
185
|
+
# system is run after there are running instances of a given component
|
186
|
+
|
187
|
+
# in the context of views, what this means is that each eventHandler which
|
188
|
+
# is bound to a specific object via _.bind or _.bindAll, or autoBindEventHandlers
|
189
|
+
# is refreshed with the prototype method of the component that it inherits from,
|
190
|
+
# and then delegateEvents is called to refresh any of the updated event handlers
|
191
|
+
|
192
|
+
# in addition to this, all properties of the instance of a given view which are
|
193
|
+
# also backbone views will have the same process run against them
|
194
|
+
refreshCode: ()->
|
195
|
+
view = @
|
196
|
+
|
197
|
+
_( @eventHandlerProperties() ).each (prop)->
|
198
|
+
view[ prop ] = view.definitionClass()[prop]
|
199
|
+
|
200
|
+
if @autoBindEventHandlers is true
|
201
|
+
@bindAllEventHandlers()
|
202
|
+
|
203
|
+
@delegateEvents()
|
204
|
+
|
205
|
+
eventHandlerProperties: ()->
|
206
|
+
handlerIds = _( @events ).values()
|
207
|
+
_( handlerIds ).select (v)->
|
208
|
+
_.isString(v)
|
209
|
+
|
210
|
+
eventHandlerFunctions: ()->
|
211
|
+
handlerIds = _( @events ).values()
|
212
|
+
_( handlerIds ).map (handlerId)=>
|
213
|
+
if _.isFunction(handlerId) then handlerId else @[handlerId]
|
214
|
+
|
215
|
+
collections: ()-> Luca.util.selectProperties( Luca.isBackboneCollection, @ )
|
216
|
+
models: ()-> Luca.util.selectProperties( Luca.isBackboneModel, @ )
|
217
|
+
views: ()-> Luca.util.selectProperties( Luca.isBackboneView, @ )
|
218
|
+
|
219
|
+
|
220
|
+
originalExtend = Backbone.View.extend
|
221
|
+
|
222
|
+
customizeRender = (definition)->
|
223
|
+
#### Rendering
|
224
|
+
#
|
225
|
+
# Our base view class wraps the defined render() method
|
226
|
+
# of the views which inherit from it, and does things like
|
227
|
+
# trigger the before and after render events automatically.
|
228
|
+
# In addition, if the view has a deferrable property on it
|
229
|
+
# then it will make sure that the render method doesn't get called
|
230
|
+
# until.
|
231
|
+
|
232
|
+
_base = definition.render
|
233
|
+
|
234
|
+
_base ||= Luca.View::$attach
|
235
|
+
|
236
|
+
|
237
|
+
definition.render = ()->
|
238
|
+
view = @
|
239
|
+
# if a view has a deferrable property set
|
240
|
+
|
241
|
+
if @deferrable
|
242
|
+
target = @deferrable_target
|
243
|
+
|
244
|
+
unless Luca.isBackboneCollection(@deferrable)
|
245
|
+
@deferrable = @collection
|
246
|
+
|
247
|
+
target ||= @deferrable
|
248
|
+
trigger = if @deferrable_event then @deferrable_event else "reset"
|
249
|
+
|
250
|
+
view.defer ()->
|
251
|
+
_base.call(view)
|
252
|
+
view.trigger "after:render", view
|
253
|
+
.until(target,trigger)
|
254
|
+
|
255
|
+
view.trigger "before:render", @
|
256
|
+
|
257
|
+
autoTrigger = @deferrable_trigger || @deferUntil
|
258
|
+
|
259
|
+
if !autoTrigger?
|
260
|
+
target[ (@deferrable_method||"fetch") ].call(target)
|
261
|
+
else
|
262
|
+
fn = _.once ()=> @deferrable[ (@deferrable_method||"fetch") ]?()
|
263
|
+
(@deferrable_target || @ ).bind(@deferrable_trigger, fn)
|
264
|
+
|
265
|
+
return @
|
266
|
+
|
267
|
+
else
|
268
|
+
@trigger "before:render", @
|
269
|
+
_base.apply(@, arguments)
|
270
|
+
@trigger "after:render", @
|
271
|
+
|
272
|
+
return @
|
273
|
+
|
274
|
+
definition
|
275
|
+
|
276
|
+
# By overriding Backbone.View.extend we are able to intercept
|
277
|
+
# some method definitions and add special behavior around them
|
278
|
+
# mostly related to render()
|
279
|
+
Luca.View.extend = (definition)->
|
280
|
+
definition = customizeRender( definition )
|
281
|
+
originalExtend.call(@, definition)
|
282
|
+
|
data/src/framework.coffee
CHANGED
@@ -1,18 +1,39 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# the Luca() browser utility function is meant to be a smart wrapper around various
|
2
|
+
# types of input which will return what the developer would expect given the
|
3
|
+
# context it is used.
|
4
|
+
(window || global).Luca = (payload, args...)->
|
5
|
+
if _.isString(payload) and result = Luca.cache(payload)
|
6
|
+
return result
|
7
|
+
|
8
|
+
if _.isString(payload) and result = Luca.find(payload)
|
9
|
+
return result
|
10
|
+
|
11
|
+
if _.isObject(payload) and payload.ctype?
|
12
|
+
return Luca.util.lazyComponent( payload )
|
13
|
+
|
14
|
+
if _.isObject(payload) and payload.defines and payload.extends
|
15
|
+
definition = payload.defines
|
16
|
+
inheritsFrom = payload.extends
|
17
|
+
|
18
|
+
|
19
|
+
if _.isFunction( fallback = _(args).last() )
|
20
|
+
return fallback()
|
21
|
+
|
22
|
+
_.extend Luca,
|
23
|
+
VERSION: "0.9.0"
|
3
24
|
core: {}
|
4
25
|
containers: {}
|
5
26
|
components: {}
|
6
27
|
modules: {}
|
7
28
|
util: {}
|
8
29
|
fields: {}
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
classes: {}
|
14
|
-
namespaces:["Luca.containers","Luca.components"]
|
30
|
+
registry:{}
|
31
|
+
|
32
|
+
# for triggering / binding to component definitions
|
33
|
+
_.extend Luca, Backbone.Events
|
15
34
|
|
35
|
+
# if developmentMode is true, you have access to some neat development tools
|
36
|
+
Luca.developmentMode = false
|
16
37
|
|
17
38
|
# The Global Observer is very helpful in development
|
18
39
|
# it observes every event triggered on every view, collection, model
|
@@ -25,6 +46,32 @@ Luca.enableGlobalObserver = false
|
|
25
46
|
# problem on our own!
|
26
47
|
Luca.enableBootstrap = true
|
27
48
|
|
49
|
+
Luca.keys =
|
50
|
+
ENTER: 13
|
51
|
+
ESCAPE: 27
|
52
|
+
KEYLEFT: 37
|
53
|
+
KEYUP: 38
|
54
|
+
KEYRIGHT: 39
|
55
|
+
KEYDOWN: 40
|
56
|
+
SPACEBAR: 32
|
57
|
+
FORWARDSLASH: 191
|
58
|
+
|
59
|
+
# build a reverse map
|
60
|
+
Luca.keyMap = _( Luca.keys ).inject (memo, value, symbol)->
|
61
|
+
memo[value] = symbol.toLowerCase()
|
62
|
+
memo
|
63
|
+
, {}
|
64
|
+
|
65
|
+
Luca.find = ()->
|
66
|
+
# TODO Implement
|
67
|
+
undefined
|
68
|
+
|
69
|
+
Luca.supportsEvents = Luca.supportsBackboneEvents = (obj)->
|
70
|
+
Luca.isComponent(obj) or (_.isFunction( obj?.trigger ) or _.isFunction(obj?.bind))
|
71
|
+
|
72
|
+
Luca.isComponent = (obj)->
|
73
|
+
Luca.isBackboneModel(obj) or Luca.isBackboneView(obj) or Luca.isBackboneCollection(obj)
|
74
|
+
|
28
75
|
Luca.isBackboneModel = (obj)->
|
29
76
|
_.isFunction(obj?.set) and _.isFunction(obj?.get) and _.isObject(obj?.attributes)
|
30
77
|
|
@@ -34,101 +81,6 @@ Luca.isBackboneView = (obj)->
|
|
34
81
|
Luca.isBackboneCollection = (obj)->
|
35
82
|
_.isFunction(obj?.fetch) and _.isFunction(obj?.reset)
|
36
83
|
|
37
|
-
# adds an additional namespace to look for luca ui
|
38
|
-
# components. useful for when you define a bunch of
|
39
|
-
# components in your own application's namespace
|
40
|
-
Luca.registry.addNamespace = (identifier)->
|
41
|
-
Luca.registry.namespaces.push( identifier )
|
42
|
-
Luca.registry.namespaces = _( Luca.registry.namespaces ).uniq()
|
43
|
-
|
44
|
-
# stores or looks up a component in the component cache
|
45
|
-
# by its backbone @cid or by its component_name
|
46
|
-
Luca.cache = (needle, component)->
|
47
|
-
Luca.component_cache.cid_index[ needle ] = component if component?
|
48
|
-
|
49
|
-
component = Luca.component_cache.cid_index[ needle ]
|
50
|
-
|
51
|
-
# optionally, cache it by tying its name to its cid for easier lookups
|
52
|
-
if component?.component_name?
|
53
|
-
Luca.component_cache.name_index[ component.component_name ] = component.cid
|
54
|
-
else if component?.name?
|
55
|
-
Luca.component_cache.name_index[ component.name ] = component.cid
|
56
|
-
|
57
|
-
return component if component?
|
58
|
-
|
59
|
-
# perform a lookup by name if the component_id didn't turn anything
|
60
|
-
lookup_id = Luca.component_cache.name_index[ needle ]
|
61
|
-
|
62
|
-
Luca.component_cache.cid_index[ lookup_id ]
|
63
|
-
|
64
|
-
# Takes an string like "deep.nested.value" and an object like window
|
65
|
-
# and returns the value of window.deep.nested.value. useful for defining
|
66
|
-
# references on objects which don't yet exist, as strings, which get
|
67
|
-
# evaluated at runtime when such references will be available
|
68
|
-
Luca.util.resolve = (accessor, source_object)->
|
69
|
-
_( accessor.split(/\./) ).inject (obj,key)->
|
70
|
-
obj = obj?[key]
|
71
|
-
, source_object
|
72
|
-
|
73
|
-
# A better name for Luca.util.nestedValue
|
74
|
-
Luca.util.nestedValue = Luca.util.resolve
|
75
|
-
|
76
|
-
# turns a word like form_view into FormView
|
77
|
-
Luca.util.classify = (string="")->
|
78
|
-
_.string.camelize( _.string.capitalize( string ) )
|
79
|
-
|
80
|
-
# Lookup a component in the Luca component registry
|
81
|
-
# by it's ctype identifier. If it doesn't exist,
|
82
|
-
# check any other registered namespace
|
83
|
-
Luca.registry.lookup = (ctype)->
|
84
|
-
c = Luca.registry.classes[ctype]
|
85
|
-
|
86
|
-
return c if c?
|
87
|
-
|
88
|
-
className = Luca.util.classify(ctype)
|
89
|
-
|
90
|
-
parents = _( Luca.registry.namespaces ).map (namespace)-> Luca.util.nestedValue(namespace, (window || global))
|
91
|
-
|
92
|
-
_( parents ).chain().map((parent)-> parent[className]).compact().value()?[0]
|
93
|
-
|
94
|
-
# one of the main benefits of Luca is the ability to structure your app as
|
95
|
-
# large blocks of JSON configuration. In order to convert an object into
|
96
|
-
# a Luca component, we lookup the object's class by converting its ctype / type
|
97
|
-
# property into a class that has been registered in the component registry
|
98
|
-
Luca.util.lazyComponent = (config)->
|
99
|
-
ctype = config.ctype || config.type
|
100
|
-
|
101
|
-
componentClass = Luca.registry.lookup( ctype )
|
102
|
-
|
103
|
-
throw "Invalid Component Type: #{ ctype }. Did you forget to register it?" unless componentClass
|
104
|
-
|
105
|
-
constructor = eval( componentClass )
|
106
|
-
|
107
|
-
new constructor(config)
|
108
|
-
|
109
|
-
# for lazy component creation
|
110
|
-
Luca.register = (component, constructor_class)->
|
111
|
-
exists = Luca.registry.classes[component]
|
112
|
-
|
113
|
-
if exists? and !window.TestRun?
|
114
|
-
console.log "Attempting to register component with the signature #{ component }. Already exists"
|
115
|
-
else
|
116
|
-
Luca.registry.classes[component] = constructor_class
|
117
|
-
|
118
|
-
Luca.available_templates = (filter="")->
|
119
|
-
available = _( Luca.templates ).keys()
|
120
|
-
|
121
|
-
if filter.length > 0
|
122
|
-
_( available ).select (tmpl)-> tmpl.match(filter)
|
123
|
-
else
|
124
|
-
available
|
125
|
-
|
126
|
-
Luca.util.isIE = ()->
|
127
|
-
try
|
128
|
-
Object.defineProperty({}, '', {})
|
129
|
-
return false
|
130
|
-
catch e
|
131
|
-
return true
|
132
84
|
|
133
85
|
# This is a convenience method for accessing the templates
|
134
86
|
# available to the client side app, either the ones which ship with Luca
|
@@ -140,6 +92,9 @@ Luca.util.isIE = ()->
|
|
140
92
|
Luca.template = (template_name, variables)->
|
141
93
|
window.JST ||= {}
|
142
94
|
|
95
|
+
if _.isFunction(template_name)
|
96
|
+
return template_name(variables)
|
97
|
+
|
143
98
|
luca = Luca.templates?[ template_name ]
|
144
99
|
jst = JST?[ template_name ]
|
145
100
|
|
@@ -152,7 +107,7 @@ Luca.template = (template_name, variables)->
|
|
152
107
|
jst = _( JST ).detect (fn,template_id)->
|
153
108
|
needle.exec( template_id )
|
154
109
|
|
155
|
-
throw "Could not find template
|
110
|
+
throw "Could not find template named #{ template_name }" unless luca || jst
|
156
111
|
|
157
112
|
template = luca || jst
|
158
113
|
|
@@ -160,77 +115,56 @@ Luca.template = (template_name, variables)->
|
|
160
115
|
|
161
116
|
template
|
162
117
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
Luca.extend = (superClassName, childName, properties={})->
|
218
|
-
superClass = Luca.util.resolve( superClassName, (window || global) )
|
219
|
-
|
220
|
-
unless _.isFunction(superClass?.extend)
|
221
|
-
throw "#{ superClassName } is not a valid component to extend from"
|
222
|
-
|
223
|
-
properties._className = childName
|
224
|
-
|
225
|
-
properties._superClass = ()->
|
226
|
-
superClass._className ||= superClassName
|
227
|
-
superClass
|
228
|
-
|
229
|
-
superClass.extend(properties)
|
230
|
-
|
231
|
-
_.mixin
|
232
|
-
component: Luca.define
|
233
|
-
|
234
|
-
#### Once We Are Ready To go....
|
235
|
-
$ do ->
|
236
|
-
$('body').addClass('luca-ui-enabled')
|
118
|
+
Luca.available_templates = (filter="")->
|
119
|
+
available = _( Luca.templates ).keys()
|
120
|
+
|
121
|
+
if filter.length > 0
|
122
|
+
_( available ).select (tmpl)-> tmpl.match(filter)
|
123
|
+
else
|
124
|
+
available
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
UnderscoreExtensions =
|
129
|
+
module: (base,module)->
|
130
|
+
_.extend base, module
|
131
|
+
if base.included and _(base.included).isFunction()
|
132
|
+
base.included.apply(base)
|
133
|
+
|
134
|
+
delete: (object, key)->
|
135
|
+
value = object[key]
|
136
|
+
delete object[key]
|
137
|
+
value
|
138
|
+
|
139
|
+
# this function will ensure a function gets called at least once
|
140
|
+
# afrer x delay. by setting defaults, we can use this on backbone
|
141
|
+
# view definitions
|
142
|
+
idle: (code, delay=1000)->
|
143
|
+
delay = 0 if window.DISABLE_IDLE
|
144
|
+
handle = undefined
|
145
|
+
()->
|
146
|
+
window.clearTimeout(handle) if handle
|
147
|
+
handle = window.setTimeout(_.bind(code, @), delay)
|
148
|
+
|
149
|
+
idleShort: (code, delay=100)->
|
150
|
+
delay = 0 if window.DISABLE_IDLE
|
151
|
+
handle = undefined
|
152
|
+
()->
|
153
|
+
window.clearTimeout(handle) if handle
|
154
|
+
handle = window.setTimeout(_.bind(code, @), delay)
|
155
|
+
|
156
|
+
idleMedium: (code, delay=2000)->
|
157
|
+
delay = 0 if window.DISABLE_IDLE
|
158
|
+
handle = undefined
|
159
|
+
()->
|
160
|
+
window.clearTimeout(handle) if handle
|
161
|
+
handle = window.setTimeout(_.bind(code, @), delay)
|
162
|
+
|
163
|
+
idleLong: (code, delay=5000)->
|
164
|
+
delay = 0 if window.DISABLE_IDLE
|
165
|
+
handle = undefined
|
166
|
+
()->
|
167
|
+
window.clearTimeout(handle) if handle
|
168
|
+
handle = window.setTimeout(_.bind(code, @), delay)
|
169
|
+
|
170
|
+
_.mixin(UnderscoreExtensions)
|