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.
- data/app/assets/javascripts/ultimate/backbone/app.js.coffee +31 -12
- data/app/assets/javascripts/ultimate/backbone/view.js.coffee +20 -3
- data/app/assets/javascripts/ultimate/{helpers.js.coffee → helpers.js.coffee.erb} +5 -5
- data/app/assets/javascripts/ultimate/jquery-plugin-class.js.coffee +1 -3
- data/app/assets/javascripts/ultimate/underscore/underscore.outcasts.js.coffee +48 -3
- data/lib/ultimate/base/version.rb +1 -1
- data/test/javascripts/tests/jquery-plugin-class_test.js.coffee +0 -3
- metadata +3 -5
- data/app/assets/javascripts/ultimate/backbone/views/typed-fields.js.coffee +0 -41
- data/app/assets/javascripts/ultimate/improves/typed-fields.js.coffee +0 -72
@@ -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
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
6
|
-
|
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(
|
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
|
-
|
6
|
-
|
7
|
-
|
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 =
|
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: (
|
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.
|
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.
|
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, ' ') {|group| p group}
|
146
|
+
["1", "2", "3", "4"]
|
147
|
+
["5", "6", "7", " "]
|
148
|
+
["8", "9", "10", " "]
|
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 @
|
@@ -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.
|
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-
|
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
|
-
@
|