ultimate-base 0.6.0 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,6 +4,8 @@ class Ultimate.Backbone.App
4
4
  @App: null
5
5
 
6
6
  name: null
7
+ warnOnMultibind: true
8
+ preventMultibind: false
7
9
 
8
10
  Models: {}
9
11
  Collections: {}
@@ -23,28 +25,48 @@ class Ultimate.Backbone.App
23
25
 
24
26
  start: ->
25
27
  @bindViews()
26
- @bindCustomElements()
28
+ @bindCustomElements(null, true)
27
29
 
28
30
  bindViews: (jRoot = $('html')) ->
29
31
  bindedViews = []
30
32
  for viewName, viewClass of @Views when viewClass::el
31
33
  #cout 'info', "Try bind #{viewName} [#{viewClass::el}]"
32
34
  jRoot.find(viewClass::el).each (index, el) =>
33
- view = new viewClass(el: el)
34
- cout 'info', "Binded view #{viewName}:", view
35
- @viewInstances.push view
36
- bindedViews.push view
35
+ if @canBind(el, viewClass)
36
+ view = new viewClass(el: el)
37
+ cout 'info', "Binded view #{viewName}:", view
38
+ @viewInstances.push view
39
+ bindedViews.push view
37
40
  bindedViews
38
41
 
42
+ canBind: (element, viewClass) ->
43
+ if @warnOnMultibind or @preventMultibind
44
+ views = @getViewsOnElement(element)
45
+ l = views.length
46
+ if l > 0
47
+ if @warnOnMultibind
48
+ cout 'warn', "Element already has binded #{l} view#{if l > 1 then 's' else ''}", element, viewClass, views
49
+ not @preventMultibind
50
+ else
51
+ true
52
+ else
53
+ true
54
+
55
+ getViewsOnElement: (element) ->
56
+ element = if element instanceof jQuery then element[0] else element
57
+ _.where @viewInstances, el: element
58
+
39
59
  unbindViews: (views) ->
40
- view.undelegateEvents() for view in views
60
+ for view in views
61
+ view.undelegateEvents()
62
+ view.leave?()
41
63
  @viewInstances = _.without(@viewInstances, views...)
42
64
 
43
65
  getFirstView: (viewClass) ->
44
66
  for view in @viewInstances
45
67
  if view.constructor is viewClass
46
68
  return view
47
- return null
69
+ null
48
70
 
49
71
  getAllViews: (viewClass) ->
50
72
  _.filter(@viewInstances, (view) -> view.constructor is viewClass)
@@ -56,12 +78,9 @@ class Ultimate.Backbone.App
56
78
  registerCustomElementBinder: (binder) ->
57
79
  @customElementBinders.push binder
58
80
 
59
- bindCustomElements: (jRoot = $('body')) ->
81
+ bindCustomElements: (jRoot = $('body'), initial = false) ->
60
82
  for binder in @customElementBinders
61
- if _.isFunction(binder)
62
- binder jRoot
63
- else
64
- jRoot.find(binder['selector'])[binder['method']] binder['arguments']...
83
+ binder arguments...
65
84
 
66
85
 
67
86
 
@@ -2,12 +2,29 @@
2
2
 
3
3
  class Ultimate.Backbone.View extends Backbone.View
4
4
 
5
- # Mixins support
6
- @include: (mixin) ->
5
+ @mixinNames: null
6
+
7
+ # Rest mixinNames
8
+ @mixinable: ->
9
+ @mixinNames = _.clone(@mixinNames)
10
+
11
+ # Mixins support
12
+ @include: (mixin, name = null) ->
13
+ @mixinNames ||= []
14
+ @mixinNames.push(name) if name?
7
15
  unless mixin?
8
- throw new Error('Mixin is undefined')
16
+ throw new Error("Mixin #{name} is undefined")
9
17
  _.extend @::, mixin
10
18
 
19
+ mixinsEvents: (events = {}) ->
20
+ _.reduce( @constructor.mixinNames, ( (memo, name) -> _.extend(memo, _.result(@, _.string.camelize(name + 'Events'))) ), events, @ )
21
+
22
+ mixinsInitialize: ->
23
+ for name in @constructor.mixinNames
24
+ @[_.string.camelize(name + 'Initialize')]? arguments...
25
+ @
26
+
27
+ # TODO comment for this trick
11
28
  __super: (methodName, args) ->
12
29
  obj = @
13
30
  calledMethod = @[methodName]
@@ -2,9 +2,9 @@
2
2
  * global front-end js helpers
3
3
  ###
4
4
 
5
- @DEBUG_MODE ?= false
6
- @TEST_MODE ?= false
7
- @LOG_TODO ?= true
5
+ window.DEBUG_MODE ?= <%= Rails.env.development? %>
6
+ window.TEST_MODE ?= <%= Rails.env.test? %>
7
+ window.LOG_TODO ?= DEBUG_MODE
8
8
 
9
9
  @cout = =>
10
10
  args = _.toArray(arguments)
@@ -36,8 +36,8 @@
36
36
 
37
37
 
38
38
 
39
- @getParams = ->
40
- q = location.search.substring(1).split('&')
39
+ @getParams = (searchString = location.search) ->
40
+ q = searchString.replace(/^\?/, '').split('&')
41
41
  r = {}
42
42
  for e in q
43
43
  t = e.split('=')
@@ -99,7 +99,5 @@ class Ultimate.Plugin
99
99
  _.extend @options, options
100
100
  @_reflectOptions()
101
101
 
102
- _reflectOptions: (reflectableOptions = _.result(@, 'reflectableOptions'), options = @options) ->
103
- if _.isArray(reflectableOptions)
104
- @[attr] = options[attr] for attr in reflectableOptions when not _.isUndefined(options[attr])
102
+ _reflectOptions: (options = @options) ->
105
103
  @[attr] = value for attr, value of options when not _.isUndefined(@[attr])
@@ -1,10 +1,10 @@
1
1
  ###
2
2
  Underscore.outcasts
3
- (c) 2012 Dmitry Karpunin <koderfunk aet gmail dot com>
3
+ (c) 2012-2013 Dmitry Karpunin <koderfunk aet gmail dot com>
4
4
  Underscore.outcasts is freely distributable under the terms of the MIT license.
5
5
  Documentation: https://github.com/KODerFunk/underscore.outcasts
6
6
  Some code is borrowed from outcasts pull requests to Underscore.
7
- Version '0.1.4'
7
+ Version '0.1.5'
8
8
  ###
9
9
 
10
10
  'use strict'
@@ -15,7 +15,7 @@
15
15
 
16
16
  UnderscoreOutcasts =
17
17
 
18
- VERSION: '0.1.4'
18
+ VERSION: '0.1.5'
19
19
 
20
20
  delete: (object, key) ->
21
21
  value = object[key]
@@ -133,6 +133,51 @@ UnderscoreOutcasts =
133
133
  array.push(fillWith) while padding-- > 0
134
134
  @eachSlice array, number, @blockGiven(arguments)
135
135
 
136
+ ###
137
+ Splits or iterates over the array in +number+ of groups, padding any
138
+ remaining slots with +fill_with+ unless it is +false+.
139
+
140
+ %w(1 2 3 4 5 6 7 8 9 10).in_groups(3) {|group| p group}
141
+ ["1", "2", "3", "4"]
142
+ ["5", "6", "7", nil]
143
+ ["8", "9", "10", nil]
144
+
145
+ %w(1 2 3 4 5 6 7 8 9 10).in_groups(3, '&nbsp;') {|group| p group}
146
+ ["1", "2", "3", "4"]
147
+ ["5", "6", "7", "&nbsp;"]
148
+ ["8", "9", "10", "&nbsp;"]
149
+
150
+ %w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
151
+ ["1", "2", "3"]
152
+ ["4", "5"]
153
+ ["6", "7"]
154
+ ###
155
+ # TODO tests
156
+ inGroups: (array, number, fillWith = null) ->
157
+ # size / number gives minor group size;
158
+ # size % number gives how many objects need extra accommodation;
159
+ # each group hold either division or division + 1 items.
160
+ division = Math.floor(array.length / number)
161
+ modulo = array.length % number
162
+
163
+ # create a new array avoiding dup
164
+ groups = []
165
+ start = 0
166
+
167
+ for index in [0...number]
168
+ length = division + (if modulo > 0 and modulo > index then 1 else 0)
169
+ groups.push last_group = array.slice(start, start + length)
170
+ if fillWith isnt false and modulo > 0 and length is division
171
+ last_group.push fillWith
172
+ start += length
173
+
174
+ if block = @blockGiven(arguments)
175
+ _.map groups, block
176
+ else
177
+ groups
178
+
179
+
180
+
136
181
  exports: ->
137
182
  result = {}
138
183
  for prop of @
@@ -1,5 +1,5 @@
1
1
  module Ultimate
2
2
  module Base
3
- VERSION = '0.6.0'
3
+ VERSION = '0.6.2'
4
4
  end
5
5
  end
@@ -21,7 +21,6 @@ test "EmptyPlugin", ->
21
21
 
22
22
  class TestPlugin extends Ultimate.Plugin
23
23
  someOption: null
24
- reflectableOptions: -> ['thirdOption']
25
24
  @defaultLocales =
26
25
  en:
27
26
  someMessage: 'English message.'
@@ -36,12 +35,10 @@ test "TestPlugin", ->
36
35
  el: '.test-plugin'
37
36
  someOption: 'bingo!'
38
37
  otherOption: 'ringo!'
39
- thirdOption: 'dingo!'
40
38
  locale: 'de'
41
39
 
42
40
  equal plugin.someOption, 'bingo!'
43
41
  ok typeof plugin.otherOption is 'undefined'
44
- equal plugin.thirdOption, 'dingo!'
45
42
  equal plugin.locale, 'de'
46
43
  deepEqual plugin.translations, {}
47
44
  # equal plugin.t('someMessage'), 'Some message'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ultimate-base
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-15 00:00:00.000000000 Z
12
+ date: 2013-09-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -81,16 +81,14 @@ files:
81
81
  - app/assets/javascripts/ultimate/backbone/view-mixins/nodes.js.coffee
82
82
  - app/assets/javascripts/ultimate/backbone/view.js.coffee
83
83
  - app/assets/javascripts/ultimate/backbone/views/slider.js.coffee
84
- - app/assets/javascripts/ultimate/backbone/views/typed-fields.js.coffee
85
84
  - app/assets/javascripts/ultimate/base.js.coffee
86
85
  - app/assets/javascripts/ultimate/experimental/_inflections/inflections.js.coffee
87
86
  - app/assets/javascripts/ultimate/experimental/_inflections/plur.js
88
87
  - app/assets/javascripts/ultimate/experimental/fuzzy-json-generator.js.coffee
89
- - app/assets/javascripts/ultimate/helpers.js.coffee
88
+ - app/assets/javascripts/ultimate/helpers.js.coffee.erb
90
89
  - app/assets/javascripts/ultimate/improves/form.js.coffee
91
90
  - app/assets/javascripts/ultimate/improves/i18n-lite.js.coffee
92
91
  - app/assets/javascripts/ultimate/improves/magic-radios.js.coffee
93
- - app/assets/javascripts/ultimate/improves/typed-fields.js.coffee
94
92
  - app/assets/javascripts/ultimate/jquery-plugin-adapter.js.coffee
95
93
  - app/assets/javascripts/ultimate/jquery-plugin-class.js.coffee
96
94
  - app/assets/javascripts/ultimate/jquery.base.js.coffee
@@ -1,41 +0,0 @@
1
- #= require ../view
2
- #= require ultimate/improves/typed-fields
3
-
4
- Ultimate.Backbone.Observers ||= {}
5
-
6
- class Ultimate.Backbone.Observers.TypedFields extends Ultimate.Backbone.View
7
-
8
- selector: "input:text[data-data-type], input:text[data-regexp-mask]"
9
-
10
- events: ->
11
- "keypress selector": "onKeyPress"
12
- "change selector": "onChange"
13
- "paste selector": "onPasteOrDrop"
14
- "drop selector": "onPasteOrDrop"
15
-
16
- viewOptions: ["selector"]
17
-
18
- onKeyPress: (event) ->
19
- if event.metaKey
20
- @onPasteOrDrop event
21
- return true
22
- return true unless event.charCode
23
- jField = $(event.currentTarget)
24
- oldValue = jField.val()
25
- newValue = oldValue.substring(0, @selectionStart) + String.fromCharCode(event.charCode) + oldValue.substring(@selectionEnd)
26
- return false unless jField.getRegExpMask().test(newValue)
27
- jField.data "value", newValue
28
-
29
- onChange: (event) ->
30
- jField = $(event.currentTarget)
31
- if jField.getRegExpMask().test(jField.val())
32
- jField.data "value", jField.val()
33
- else
34
- jField.val jField.data("value")
35
-
36
- onPasteOrDrop: (event) ->
37
- setTimeout ( -> $(event.currentTarget).trigger "change", arguments ), 100
38
-
39
-
40
-
41
- Ultimate.createJQueryPlugin? "typedFields", Ultimate.Backbone.Observers.TypedFields
@@ -1,72 +0,0 @@
1
- do ($ = jQuery) ->
2
-
3
- # ========= max & min =========
4
- $('input:text[data-gte], input:text[data-lte]').live 'change focusout blur', ->
5
- jField = $(@)
6
- realValue = jField.val()
7
- if realValue isnt ''
8
- # TODO refactor this
9
- min = parseFloat(jField.data('gte'))
10
- max = parseFloat(jField.data('lte'))
11
- oldValue = parseFloat(realValue)
12
- v = oldValue
13
- v = 0 if isNaN(v)
14
- v = min if not isNaN(min) and v < min
15
- v = max if not isNaN(max) and v > max
16
- jField.val(v).change() unless v is oldValue
17
-
18
- $.fn.setFieldBounds = (min, max) ->
19
- @filter('input:text')
20
- .attr
21
- 'data-gte': min
22
- 'data-lte': max
23
- .data
24
- 'gte': min
25
- 'lte': max
26
-
27
- # ========= regexpMask =========
28
-
29
- $.regexp = {} unless $.regexp
30
- $.regexp.typedField =
31
- 'integer' : /^$|^\d+$/
32
- 'float' : /^$|^\d+(\.\d*)?$/
33
- 'currency' : /^$|^\d+(\.\d{0,2})?$/
34
- 'text' : /^.*$/
35
-
36
- $.fn.getRegExpMask = ->
37
- mask = @data('regexpMask')
38
- if _.isString(mask)
39
- try
40
- mask = new RegExp(mask)
41
- @data 'regexpMask', mask
42
- catch e
43
- # nop
44
- else
45
- dataType = @data('dataType')
46
- mask = $.regexp.typedField[dataType] if dataType
47
- unless mask
48
- @val 'unknown dataType'
49
- mask = $.regexp.typedField['text']
50
- mask
51
-
52
- $.fn.dropRegExpMask = ->
53
- @
54
- .removeAttr('data-regexp-mask')
55
- .removeData('regexpMask')
56
- .removeData('value')
57
-
58
- $.fn.setRegExpMask = (mask) ->
59
- stringMask = 'true'
60
- if _.isString(mask)
61
- stringMask = mask
62
- try
63
- mask = new RegExp(mask)
64
- catch e
65
- # nop
66
- if _.isRegExp(mask)
67
- @
68
- .dropRegExpMask()
69
- .attr('data-regexp-mask', stringMask)
70
- .data('regexpMask', mask)
71
- .change()
72
- @