ultimate-base 0.6.0 → 0.6.2

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.
@@ -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
- @