ultimate-helpers 0.1.0.1 → 0.2.0
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/.gitignore +1 -1
- data/Gemfile.lock +59 -57
- data/Rakefile +1 -1
- data/app/assets/javascripts/ultimate/base.js.coffee +1 -11
- data/app/assets/javascripts/ultimate/helpers.js.coffee +4 -69
- data/app/assets/javascripts/ultimate/helpers/base.js.coffee +18 -1
- data/app/assets/javascripts/ultimate/helpers/record_tag.js.coffee +1 -0
- data/app/assets/javascripts/ultimate/helpers/tag.js.coffee +0 -4
- data/app/assets/javascripts/ultimate/jquery.base.js.coffee +0 -21
- data/app/assets/javascripts/ultimate/underscore/underscore.inflection.js +4 -3
- data/app/assets/javascripts/ultimate/underscore/underscore.js +103 -80
- data/app/assets/javascripts/ultimate/underscore/underscore.string.js +71 -27
- data/lib/ultimate/helpers/version.rb +1 -1
- data/test/javascripts/tests/base_test.js.coffee +42 -0
- data/test/javascripts/tests/helpers/form_options_test.js.coffee +1 -1
- data/test/javascripts/tests/helpers/form_tag_test.js.coffee +1 -1
- data/test/javascripts/tests/helpers/number_test.js.coffee +1 -0
- data/test/javascripts/tests/helpers_test.js.coffee +47 -0
- metadata +77 -6
- data/.rvmrc +0 -1
- data/.rvmrc.example +0 -1
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,115 +1,117 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
ultimate-helpers (0.
|
|
4
|
+
ultimate-helpers (0.2.0)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: http://rubygems.org/
|
|
8
8
|
specs:
|
|
9
|
-
actionmailer (3.2.
|
|
10
|
-
actionpack (= 3.2.
|
|
11
|
-
mail (~> 2.
|
|
12
|
-
actionpack (3.2.
|
|
13
|
-
activemodel (= 3.2.
|
|
14
|
-
activesupport (= 3.2.
|
|
9
|
+
actionmailer (3.2.13)
|
|
10
|
+
actionpack (= 3.2.13)
|
|
11
|
+
mail (~> 2.5.3)
|
|
12
|
+
actionpack (3.2.13)
|
|
13
|
+
activemodel (= 3.2.13)
|
|
14
|
+
activesupport (= 3.2.13)
|
|
15
15
|
builder (~> 3.0.0)
|
|
16
16
|
erubis (~> 2.7.0)
|
|
17
17
|
journey (~> 1.0.4)
|
|
18
|
-
rack (~> 1.4.
|
|
18
|
+
rack (~> 1.4.5)
|
|
19
19
|
rack-cache (~> 1.2)
|
|
20
20
|
rack-test (~> 0.6.1)
|
|
21
|
-
sprockets (~> 2.1
|
|
22
|
-
activemodel (3.2.
|
|
23
|
-
activesupport (= 3.2.
|
|
21
|
+
sprockets (~> 2.2.1)
|
|
22
|
+
activemodel (3.2.13)
|
|
23
|
+
activesupport (= 3.2.13)
|
|
24
24
|
builder (~> 3.0.0)
|
|
25
|
-
activerecord (3.2.
|
|
26
|
-
activemodel (= 3.2.
|
|
27
|
-
activesupport (= 3.2.
|
|
25
|
+
activerecord (3.2.13)
|
|
26
|
+
activemodel (= 3.2.13)
|
|
27
|
+
activesupport (= 3.2.13)
|
|
28
28
|
arel (~> 3.0.2)
|
|
29
29
|
tzinfo (~> 0.3.29)
|
|
30
|
-
activeresource (3.2.
|
|
31
|
-
activemodel (= 3.2.
|
|
32
|
-
activesupport (= 3.2.
|
|
33
|
-
activesupport (3.2.
|
|
34
|
-
i18n (
|
|
30
|
+
activeresource (3.2.13)
|
|
31
|
+
activemodel (= 3.2.13)
|
|
32
|
+
activesupport (= 3.2.13)
|
|
33
|
+
activesupport (3.2.13)
|
|
34
|
+
i18n (= 0.6.1)
|
|
35
35
|
multi_json (~> 1.0)
|
|
36
36
|
arel (3.0.2)
|
|
37
|
-
builder (3.0.
|
|
37
|
+
builder (3.0.4)
|
|
38
38
|
coffee-rails (3.2.2)
|
|
39
39
|
coffee-script (>= 2.2.0)
|
|
40
40
|
railties (~> 3.2.0)
|
|
41
41
|
coffee-script (2.2.0)
|
|
42
42
|
coffee-script-source
|
|
43
43
|
execjs
|
|
44
|
-
coffee-script-source (1.
|
|
44
|
+
coffee-script-source (1.6.2)
|
|
45
45
|
erubis (2.7.0)
|
|
46
46
|
execjs (1.4.0)
|
|
47
47
|
multi_json (~> 1.0)
|
|
48
|
-
haml (
|
|
49
|
-
|
|
48
|
+
haml (4.0.1)
|
|
49
|
+
tilt
|
|
50
|
+
haml-rails (0.4)
|
|
50
51
|
actionpack (>= 3.1, < 4.1)
|
|
51
52
|
activesupport (>= 3.1, < 4.1)
|
|
52
|
-
haml (
|
|
53
|
+
haml (>= 3.1, < 4.1)
|
|
53
54
|
railties (>= 3.1, < 4.1)
|
|
54
55
|
hike (1.2.1)
|
|
55
56
|
i18n (0.6.1)
|
|
56
57
|
journey (1.0.4)
|
|
57
|
-
jquery-rails (2.1
|
|
58
|
-
railties (>= 3.
|
|
59
|
-
thor (
|
|
60
|
-
json (1.7.
|
|
61
|
-
mail (2.
|
|
58
|
+
jquery-rails (2.2.1)
|
|
59
|
+
railties (>= 3.0, < 5.0)
|
|
60
|
+
thor (>= 0.14, < 2.0)
|
|
61
|
+
json (1.7.7)
|
|
62
|
+
mail (2.5.3)
|
|
62
63
|
i18n (>= 0.4.0)
|
|
63
64
|
mime-types (~> 1.16)
|
|
64
65
|
treetop (~> 1.4.8)
|
|
65
|
-
mime-types (1.
|
|
66
|
-
multi_json (1.
|
|
66
|
+
mime-types (1.22)
|
|
67
|
+
multi_json (1.7.2)
|
|
67
68
|
polyglot (0.3.3)
|
|
68
|
-
quiet_assets (1.0.
|
|
69
|
-
railties (
|
|
70
|
-
qunit-rails (0.0.
|
|
71
|
-
railties (
|
|
72
|
-
rack (1.4.
|
|
69
|
+
quiet_assets (1.0.2)
|
|
70
|
+
railties (>= 3.1, < 5.0)
|
|
71
|
+
qunit-rails (0.0.3)
|
|
72
|
+
railties (>= 3.2.3)
|
|
73
|
+
rack (1.4.5)
|
|
73
74
|
rack-cache (1.2)
|
|
74
75
|
rack (>= 0.4)
|
|
75
|
-
rack-ssl (1.3.
|
|
76
|
+
rack-ssl (1.3.3)
|
|
76
77
|
rack
|
|
77
78
|
rack-test (0.6.2)
|
|
78
79
|
rack (>= 1.0)
|
|
79
|
-
rails (3.2.
|
|
80
|
-
actionmailer (= 3.2.
|
|
81
|
-
actionpack (= 3.2.
|
|
82
|
-
activerecord (= 3.2.
|
|
83
|
-
activeresource (= 3.2.
|
|
84
|
-
activesupport (= 3.2.
|
|
80
|
+
rails (3.2.13)
|
|
81
|
+
actionmailer (= 3.2.13)
|
|
82
|
+
actionpack (= 3.2.13)
|
|
83
|
+
activerecord (= 3.2.13)
|
|
84
|
+
activeresource (= 3.2.13)
|
|
85
|
+
activesupport (= 3.2.13)
|
|
85
86
|
bundler (~> 1.0)
|
|
86
|
-
railties (= 3.2.
|
|
87
|
-
railties (3.2.
|
|
88
|
-
actionpack (= 3.2.
|
|
89
|
-
activesupport (= 3.2.
|
|
87
|
+
railties (= 3.2.13)
|
|
88
|
+
railties (3.2.13)
|
|
89
|
+
actionpack (= 3.2.13)
|
|
90
|
+
activesupport (= 3.2.13)
|
|
90
91
|
rack-ssl (~> 1.3.2)
|
|
91
92
|
rake (>= 0.8.7)
|
|
92
93
|
rdoc (~> 3.4)
|
|
93
94
|
thor (>= 0.14.6, < 2.0)
|
|
94
|
-
rake (0.
|
|
95
|
-
rdoc (3.12)
|
|
95
|
+
rake (10.0.4)
|
|
96
|
+
rdoc (3.12.2)
|
|
96
97
|
json (~> 1.4)
|
|
97
|
-
sass (3.2.
|
|
98
|
-
sass-rails (3.2.
|
|
98
|
+
sass (3.2.7)
|
|
99
|
+
sass-rails (3.2.6)
|
|
99
100
|
railties (~> 3.2.0)
|
|
100
101
|
sass (>= 3.1.10)
|
|
101
102
|
tilt (~> 1.3)
|
|
102
|
-
sprockets (2.
|
|
103
|
+
sprockets (2.2.2)
|
|
103
104
|
hike (~> 1.2)
|
|
105
|
+
multi_json (~> 1.0)
|
|
104
106
|
rack (~> 1.0)
|
|
105
107
|
tilt (~> 1.1, != 1.3.0)
|
|
106
|
-
sqlite3 (1.3.
|
|
107
|
-
thor (0.
|
|
108
|
-
tilt (1.3.
|
|
109
|
-
treetop (1.4.
|
|
108
|
+
sqlite3 (1.3.7)
|
|
109
|
+
thor (0.18.1)
|
|
110
|
+
tilt (1.3.6)
|
|
111
|
+
treetop (1.4.12)
|
|
110
112
|
polyglot
|
|
111
113
|
polyglot (>= 0.3.1)
|
|
112
|
-
tzinfo (0.3.
|
|
114
|
+
tzinfo (0.3.37)
|
|
113
115
|
|
|
114
116
|
PLATFORMS
|
|
115
117
|
ruby
|
data/Rakefile
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
require
|
|
1
|
+
require 'bundler/gem_tasks'
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
###
|
|
2
|
-
* front-end js helpers
|
|
3
|
-
* 0.3.3.alpha / 2010-2011
|
|
4
|
-
* Karpunin Dmitry / Evrone.com
|
|
5
|
-
* koderfunk_at_gmail_dot_com
|
|
2
|
+
* global front-end js helpers
|
|
6
3
|
###
|
|
7
4
|
|
|
8
5
|
@DEBUG_MODE ?= false
|
|
@@ -31,12 +28,6 @@
|
|
|
31
28
|
if @LOG_TODO
|
|
32
29
|
@cout 'warn', "TODO: #{subject}#{if location then " ### #{location}" else ''}#{if numberOrString then (if _.isNumber(numberOrString) then ":#{numberOrString}" else " > #{numberOrString}") else ''}"
|
|
33
30
|
|
|
34
|
-
@args = (a) ->
|
|
35
|
-
@deprecate 'arg()', '_.toArray()'
|
|
36
|
-
r = []
|
|
37
|
-
Array::push.apply(r, a) if a.length > 0
|
|
38
|
-
r
|
|
39
|
-
|
|
40
31
|
@logicalXOR = (a, b) ->
|
|
41
32
|
( a and not b ) or ( not a and b )
|
|
42
33
|
|
|
@@ -45,12 +36,12 @@
|
|
|
45
36
|
|
|
46
37
|
|
|
47
38
|
|
|
48
|
-
@getParams = ->
|
|
49
|
-
q =
|
|
39
|
+
@getParams = (searchString = location.search) ->
|
|
40
|
+
q = searchString.replace(/^\?/, '').split('&')
|
|
50
41
|
r = {}
|
|
51
42
|
for e in q
|
|
52
43
|
t = e.split('=')
|
|
53
|
-
r[t[0]] = t[1]
|
|
44
|
+
r[decodeURIComponent(t[0])] = decodeURIComponent(t[1])
|
|
54
45
|
r
|
|
55
46
|
|
|
56
47
|
@respondFormat = (url, format = null) ->
|
|
@@ -64,59 +55,3 @@
|
|
|
64
55
|
ah[0] = ad.join('.')
|
|
65
56
|
aq[0] = ah.join('#')
|
|
66
57
|
aq.join('?')
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
########### Deprecated ###########
|
|
71
|
-
|
|
72
|
-
# Helper function to get a value from a object as a property or as a function.
|
|
73
|
-
@getValue = (object, prop) ->
|
|
74
|
-
@deprecate "getValue()", "_.result()"
|
|
75
|
-
return null unless object and object[prop]
|
|
76
|
-
return if _.isFunction(object[prop]) then object[prop]() else object[prop]
|
|
77
|
-
|
|
78
|
-
@isset = (obj) =>
|
|
79
|
-
@deprecate 'isset(obj)', '_.isUndefined(obj) OR "obj isnt undefined" OR "obj?'
|
|
80
|
-
obj isnt undefined
|
|
81
|
-
|
|
82
|
-
@isString = (v) =>
|
|
83
|
-
@deprecate 'isString(v)', '_.isString(v)'
|
|
84
|
-
_.isString v
|
|
85
|
-
|
|
86
|
-
@isNumber = (v) =>
|
|
87
|
-
@deprecate 'isNumber(v)', '_.isNumber(v)'
|
|
88
|
-
not isNaN(parseInt(v))
|
|
89
|
-
|
|
90
|
-
@isJQ = (obj) ->
|
|
91
|
-
@deprecate 'isJQ(obj)', 'obj instanceof jQuery'
|
|
92
|
-
_.isObject(obj) and _.isString(obj.jquery)
|
|
93
|
-
|
|
94
|
-
@uniq = (arrOrString) ->
|
|
95
|
-
@deprecate 'uniq(a)', '_.uniq(a)'
|
|
96
|
-
isStr = _.isString(arrOrString)
|
|
97
|
-
return arrOrString unless isStr or _.isArray(arrOrString)
|
|
98
|
-
r = []
|
|
99
|
-
r.push(e) for e in arrOrString when not _.include(r, e)
|
|
100
|
-
if isStr then r.join('') else r
|
|
101
|
-
|
|
102
|
-
@regexpSpace = /^\s*$/
|
|
103
|
-
@regexpTrim = /^\s*(.*?)\s*$/
|
|
104
|
-
|
|
105
|
-
@strTrim = (s) =>
|
|
106
|
-
@deprecate "strTrim(s)", "_.trim(s)"
|
|
107
|
-
s.match(@regexpTrim)[1]
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
@rails_data = {}
|
|
112
|
-
|
|
113
|
-
@rails_scope = (controller_name, action_name, scopedCloasure = null, scopedCloasureArguments...) =>
|
|
114
|
-
@deprecate 'rails_scope'
|
|
115
|
-
return false if _.isString(controller_name) and controller_name isnt @rails_data['controller_name']
|
|
116
|
-
return false if _.isString(action_name) and action_name isnt @rails_data['action_name']
|
|
117
|
-
if _.isFunction(scopedCloasure)
|
|
118
|
-
arguments[2] scopedCloasureArguments...
|
|
119
|
-
true
|
|
120
|
-
|
|
121
|
-
$ =>
|
|
122
|
-
@rails_data = $('body').data()
|
|
@@ -1,3 +1,20 @@
|
|
|
1
1
|
#= require ultimate/base
|
|
2
2
|
|
|
3
|
-
@Ultimate.Helpers ||=
|
|
3
|
+
@Ultimate.Helpers ||=
|
|
4
|
+
version: '0.2.0'
|
|
5
|
+
|
|
6
|
+
globalizeScopes: (include = false, exclude = false) ->
|
|
7
|
+
for scopeName, scope of @ when /^[A-Z]/.test(scopeName)
|
|
8
|
+
if (not include or scopeName in include) and not (exclude and scopeName in exclude)
|
|
9
|
+
_.extend window, scope
|
|
10
|
+
|
|
11
|
+
scopes: ->
|
|
12
|
+
_.filter( _.keys(@), (key) -> /^[A-Z]/.test(key) )
|
|
13
|
+
|
|
14
|
+
# underscored version
|
|
15
|
+
# globalizeScopes: (include = false, exclude = false) ->
|
|
16
|
+
# keys = _.filter( _.keys(@), (key) -> /^[A-Z]/.test(key) )
|
|
17
|
+
# keys = _.intersection(keys, include) if include
|
|
18
|
+
# keys = _.difference(keys, exclude) if exclude
|
|
19
|
+
# for scopeName in keys
|
|
20
|
+
# _.extend window, @[scopeName]
|
|
@@ -28,10 +28,6 @@
|
|
|
28
28
|
content = _.string.escapeHTML(content) if _escapeContent
|
|
29
29
|
"<#{name}#{@tag_options(options, escape)}>#{@PRE_CONTENT_STRINGS[name] ? ''}#{content}</#{name}>"
|
|
30
30
|
|
|
31
|
-
html_options_to_s: (html_options, escape = false, prefix = "") ->
|
|
32
|
-
deprecate 'html_options_to_s()', "tag_options()"
|
|
33
|
-
@tag_options arguments...
|
|
34
|
-
|
|
35
31
|
tag_options: (options, escape = true) ->
|
|
36
32
|
return "" if _.isEmpty(options)
|
|
37
33
|
attrs = []
|
|
@@ -62,24 +62,3 @@ do ($ = jQuery) =>
|
|
|
62
62
|
matches = content.match($.regexp.HTML)
|
|
63
63
|
return false unless matches?
|
|
64
64
|
not strong or matches[1] is matches[2]
|
|
65
|
-
|
|
66
|
-
# TODO replace usages to underscore methods and using distribution
|
|
67
|
-
unless $.isRegExp
|
|
68
|
-
$.isRegExp = (candidate) ->
|
|
69
|
-
deprecate '$.isRegExp', '_.isRegExp'
|
|
70
|
-
typeof candidate is "object" and typeof candidate.test is "function"
|
|
71
|
-
|
|
72
|
-
unless $.isBoolean
|
|
73
|
-
$.isBoolean = (v) ->
|
|
74
|
-
deprecate '$.isBoolean', '_.isBoolean'
|
|
75
|
-
typeof v is "boolean"
|
|
76
|
-
|
|
77
|
-
unless $.isString
|
|
78
|
-
$.isString = (v) ->
|
|
79
|
-
deprecate '$.isString', '_.isString'
|
|
80
|
-
typeof v is "string"
|
|
81
|
-
|
|
82
|
-
if typeof $.isEmptyString is "undefined"
|
|
83
|
-
$.isEmptyString = (v) ->
|
|
84
|
-
deprecate '$.isEmptyString', '_.isBlank'
|
|
85
|
-
regexpSpace.test v
|
|
@@ -33,9 +33,10 @@
|
|
|
33
33
|
pluralize : function( word, count, includeNumber )
|
|
34
34
|
{
|
|
35
35
|
var result;
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
if( count !== undefined )
|
|
38
38
|
{
|
|
39
|
+
count = Math.round(count);
|
|
39
40
|
result = ( count === 1 ) ? this.singularize( word ) : this.pluralize( word );
|
|
40
41
|
result = ( includeNumber ) ? [ count, result ].join( ' ' ) : result;
|
|
41
42
|
}
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
},
|
|
57
58
|
this );
|
|
58
59
|
}
|
|
59
|
-
|
|
60
|
+
|
|
60
61
|
return result;
|
|
61
62
|
},
|
|
62
63
|
|
|
@@ -172,5 +173,5 @@
|
|
|
172
173
|
* Underscore integration
|
|
173
174
|
*/
|
|
174
175
|
_.mixin( inflector.resetInflections( ) );
|
|
175
|
-
|
|
176
|
+
|
|
176
177
|
} )( _ );
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
|
|
4
|
-
// Underscore may be freely distributed under the MIT license.
|
|
1
|
+
// Underscore.js 1.4.4
|
|
2
|
+
// ===================
|
|
5
3
|
|
|
6
|
-
|
|
4
|
+
// > http://underscorejs.org
|
|
5
|
+
// > (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
|
|
6
|
+
// > Underscore may be freely distributed under the MIT license.
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
// Baseline setup
|
|
9
|
+
// --------------
|
|
10
|
+
(function() {
|
|
10
11
|
|
|
11
12
|
// Establish the root object, `window` in the browser, or `global` on the server.
|
|
12
13
|
var root = this;
|
|
@@ -24,7 +25,6 @@
|
|
|
24
25
|
var push = ArrayProto.push,
|
|
25
26
|
slice = ArrayProto.slice,
|
|
26
27
|
concat = ArrayProto.concat,
|
|
27
|
-
unshift = ArrayProto.unshift,
|
|
28
28
|
toString = ObjProto.toString,
|
|
29
29
|
hasOwnProperty = ObjProto.hasOwnProperty;
|
|
30
30
|
|
|
@@ -61,11 +61,11 @@
|
|
|
61
61
|
}
|
|
62
62
|
exports._ = _;
|
|
63
63
|
} else {
|
|
64
|
-
root
|
|
64
|
+
root._ = _;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
// Current version.
|
|
68
|
-
_.VERSION = '1.4.
|
|
68
|
+
_.VERSION = '1.4.4';
|
|
69
69
|
|
|
70
70
|
// Collection Functions
|
|
71
71
|
// --------------------
|
|
@@ -102,6 +102,8 @@
|
|
|
102
102
|
return results;
|
|
103
103
|
};
|
|
104
104
|
|
|
105
|
+
var reduceError = 'Reduce of empty array with no initial value';
|
|
106
|
+
|
|
105
107
|
// **Reduce** builds up a single result from a list of values, aka `inject`,
|
|
106
108
|
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
|
|
107
109
|
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
|
|
@@ -119,7 +121,7 @@
|
|
|
119
121
|
memo = iterator.call(context, memo, value, index, list);
|
|
120
122
|
}
|
|
121
123
|
});
|
|
122
|
-
if (!initial) throw new TypeError(
|
|
124
|
+
if (!initial) throw new TypeError(reduceError);
|
|
123
125
|
return memo;
|
|
124
126
|
};
|
|
125
127
|
|
|
@@ -130,7 +132,7 @@
|
|
|
130
132
|
if (obj == null) obj = [];
|
|
131
133
|
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
|
|
132
134
|
if (context) iterator = _.bind(iterator, context);
|
|
133
|
-
return
|
|
135
|
+
return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
|
|
134
136
|
}
|
|
135
137
|
var length = obj.length;
|
|
136
138
|
if (length !== +length) {
|
|
@@ -146,7 +148,7 @@
|
|
|
146
148
|
memo = iterator.call(context, memo, obj[index], index, list);
|
|
147
149
|
}
|
|
148
150
|
});
|
|
149
|
-
if (!initial) throw new TypeError(
|
|
151
|
+
if (!initial) throw new TypeError(reduceError);
|
|
150
152
|
return memo;
|
|
151
153
|
};
|
|
152
154
|
|
|
@@ -177,12 +179,9 @@
|
|
|
177
179
|
|
|
178
180
|
// Return all the elements for which a truth test fails.
|
|
179
181
|
_.reject = function(obj, iterator, context) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (!iterator.call(context, value, index, list)) results[results.length] = value;
|
|
184
|
-
});
|
|
185
|
-
return results;
|
|
182
|
+
return _.filter(obj, function(value, index, list) {
|
|
183
|
+
return !iterator.call(context, value, index, list);
|
|
184
|
+
}, context);
|
|
186
185
|
};
|
|
187
186
|
|
|
188
187
|
// Determine whether all of the elements match a truth test.
|
|
@@ -216,20 +215,19 @@
|
|
|
216
215
|
// Determine if the array or object contains a given value (using `===`).
|
|
217
216
|
// Aliased as `include`.
|
|
218
217
|
_.contains = _.include = function(obj, target) {
|
|
219
|
-
|
|
220
|
-
if (obj == null) return found;
|
|
218
|
+
if (obj == null) return false;
|
|
221
219
|
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
|
|
222
|
-
|
|
220
|
+
return any(obj, function(value) {
|
|
223
221
|
return value === target;
|
|
224
222
|
});
|
|
225
|
-
return found;
|
|
226
223
|
};
|
|
227
224
|
|
|
228
225
|
// Invoke a method (with arguments) on every item in a collection.
|
|
229
226
|
_.invoke = function(obj, method) {
|
|
230
227
|
var args = slice.call(arguments, 2);
|
|
228
|
+
var isFunc = _.isFunction(method);
|
|
231
229
|
return _.map(obj, function(value) {
|
|
232
|
-
return (
|
|
230
|
+
return (isFunc ? method : value[method]).apply(value, args);
|
|
233
231
|
});
|
|
234
232
|
};
|
|
235
233
|
|
|
@@ -239,10 +237,10 @@
|
|
|
239
237
|
};
|
|
240
238
|
|
|
241
239
|
// Convenience version of a common use case of `filter`: selecting only objects
|
|
242
|
-
//
|
|
243
|
-
_.where = function(obj, attrs) {
|
|
244
|
-
if (_.isEmpty(attrs)) return [];
|
|
245
|
-
return _
|
|
240
|
+
// containing specific `key:value` pairs.
|
|
241
|
+
_.where = function(obj, attrs, first) {
|
|
242
|
+
if (_.isEmpty(attrs)) return first ? null : [];
|
|
243
|
+
return _[first ? 'find' : 'filter'](obj, function(value) {
|
|
246
244
|
for (var key in attrs) {
|
|
247
245
|
if (attrs[key] !== value[key]) return false;
|
|
248
246
|
}
|
|
@@ -250,6 +248,12 @@
|
|
|
250
248
|
});
|
|
251
249
|
};
|
|
252
250
|
|
|
251
|
+
// Convenience version of a common use case of `find`: getting the first object
|
|
252
|
+
// containing specific `key:value` pairs.
|
|
253
|
+
_.findWhere = function(obj, attrs) {
|
|
254
|
+
return _.where(obj, attrs, true);
|
|
255
|
+
};
|
|
256
|
+
|
|
253
257
|
// Return the maximum element or (element-based computation).
|
|
254
258
|
// Can't optimize arrays of integers longer than 65,535 elements.
|
|
255
259
|
// See: https://bugs.webkit.org/show_bug.cgi?id=80797
|
|
@@ -258,7 +262,7 @@
|
|
|
258
262
|
return Math.max.apply(Math, obj);
|
|
259
263
|
}
|
|
260
264
|
if (!iterator && _.isEmpty(obj)) return -Infinity;
|
|
261
|
-
var result = {computed : -Infinity};
|
|
265
|
+
var result = {computed : -Infinity, value: -Infinity};
|
|
262
266
|
each(obj, function(value, index, list) {
|
|
263
267
|
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
|
264
268
|
computed >= result.computed && (result = {value : value, computed : computed});
|
|
@@ -272,7 +276,7 @@
|
|
|
272
276
|
return Math.min.apply(Math, obj);
|
|
273
277
|
}
|
|
274
278
|
if (!iterator && _.isEmpty(obj)) return Infinity;
|
|
275
|
-
var result = {computed : Infinity};
|
|
279
|
+
var result = {computed : Infinity, value: Infinity};
|
|
276
280
|
each(obj, function(value, index, list) {
|
|
277
281
|
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
|
278
282
|
computed < result.computed && (result = {value : value, computed : computed});
|
|
@@ -321,7 +325,7 @@
|
|
|
321
325
|
// An internal function used for aggregate "group by" operations.
|
|
322
326
|
var group = function(obj, value, context, behavior) {
|
|
323
327
|
var result = {};
|
|
324
|
-
var iterator = lookupIterator(value);
|
|
328
|
+
var iterator = lookupIterator(value || _.identity);
|
|
325
329
|
each(obj, function(value, index) {
|
|
326
330
|
var key = iterator.call(context, value, index, obj);
|
|
327
331
|
behavior(result, key, value);
|
|
@@ -341,7 +345,7 @@
|
|
|
341
345
|
// either a string attribute to count by, or a function that returns the
|
|
342
346
|
// criterion.
|
|
343
347
|
_.countBy = function(obj, value, context) {
|
|
344
|
-
return group(obj, value, context, function(result, key
|
|
348
|
+
return group(obj, value, context, function(result, key) {
|
|
345
349
|
if (!_.has(result, key)) result[key] = 0;
|
|
346
350
|
result[key]++;
|
|
347
351
|
});
|
|
@@ -363,7 +367,8 @@
|
|
|
363
367
|
// Safely convert anything iterable into a real, live array.
|
|
364
368
|
_.toArray = function(obj) {
|
|
365
369
|
if (!obj) return [];
|
|
366
|
-
if (
|
|
370
|
+
if (_.isArray(obj)) return slice.call(obj);
|
|
371
|
+
if (obj.length === +obj.length) return _.map(obj, _.identity);
|
|
367
372
|
return _.values(obj);
|
|
368
373
|
};
|
|
369
374
|
|
|
@@ -413,7 +418,7 @@
|
|
|
413
418
|
|
|
414
419
|
// Trim out all falsy values from an array.
|
|
415
420
|
_.compact = function(array) {
|
|
416
|
-
return _.filter(array,
|
|
421
|
+
return _.filter(array, _.identity);
|
|
417
422
|
};
|
|
418
423
|
|
|
419
424
|
// Internal implementation of a recursive `flatten` function.
|
|
@@ -442,6 +447,11 @@
|
|
|
442
447
|
// been sorted, you have the option of using a faster algorithm.
|
|
443
448
|
// Aliased as `unique`.
|
|
444
449
|
_.uniq = _.unique = function(array, isSorted, iterator, context) {
|
|
450
|
+
if (_.isFunction(isSorted)) {
|
|
451
|
+
context = iterator;
|
|
452
|
+
iterator = isSorted;
|
|
453
|
+
isSorted = false;
|
|
454
|
+
}
|
|
445
455
|
var initial = iterator ? _.map(array, iterator, context) : array;
|
|
446
456
|
var results = [];
|
|
447
457
|
var seen = [];
|
|
@@ -565,25 +575,23 @@
|
|
|
565
575
|
// Function (ahem) Functions
|
|
566
576
|
// ------------------
|
|
567
577
|
|
|
568
|
-
// Reusable constructor function for prototype setting.
|
|
569
|
-
var ctor = function(){};
|
|
570
|
-
|
|
571
578
|
// Create a function bound to a given object (assigning `this`, and arguments,
|
|
572
|
-
// optionally).
|
|
573
|
-
//
|
|
574
|
-
|
|
575
|
-
_.bind = function bind(func, context) {
|
|
576
|
-
var bound, args;
|
|
579
|
+
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
|
|
580
|
+
// available.
|
|
581
|
+
_.bind = function(func, context) {
|
|
577
582
|
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
583
|
+
var args = slice.call(arguments, 2);
|
|
584
|
+
return function() {
|
|
585
|
+
return func.apply(context, args.concat(slice.call(arguments)));
|
|
586
|
+
};
|
|
587
|
+
};
|
|
588
|
+
|
|
589
|
+
// Partially apply a function by creating a version that has had some of its
|
|
590
|
+
// arguments pre-filled, without changing its dynamic `this` context.
|
|
591
|
+
_.partial = function(func) {
|
|
592
|
+
var args = slice.call(arguments, 1);
|
|
593
|
+
return function() {
|
|
594
|
+
return func.apply(this, args.concat(slice.call(arguments)));
|
|
587
595
|
};
|
|
588
596
|
};
|
|
589
597
|
|
|
@@ -591,7 +599,7 @@
|
|
|
591
599
|
// all callbacks defined on an object belong to it.
|
|
592
600
|
_.bindAll = function(obj) {
|
|
593
601
|
var funcs = slice.call(arguments, 1);
|
|
594
|
-
if (funcs.length
|
|
602
|
+
if (funcs.length === 0) funcs = _.functions(obj);
|
|
595
603
|
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
|
|
596
604
|
return obj;
|
|
597
605
|
};
|
|
@@ -622,25 +630,26 @@
|
|
|
622
630
|
// Returns a function, that, when invoked, will only be triggered at most once
|
|
623
631
|
// during a given window of time.
|
|
624
632
|
_.throttle = function(func, wait) {
|
|
625
|
-
var context, args, timeout,
|
|
626
|
-
var
|
|
633
|
+
var context, args, timeout, result;
|
|
634
|
+
var previous = 0;
|
|
635
|
+
var later = function() {
|
|
636
|
+
previous = new Date;
|
|
637
|
+
timeout = null;
|
|
638
|
+
result = func.apply(context, args);
|
|
639
|
+
};
|
|
627
640
|
return function() {
|
|
628
|
-
|
|
629
|
-
var
|
|
641
|
+
var now = new Date;
|
|
642
|
+
var remaining = wait - (now - previous);
|
|
643
|
+
context = this;
|
|
644
|
+
args = arguments;
|
|
645
|
+
if (remaining <= 0) {
|
|
646
|
+
clearTimeout(timeout);
|
|
630
647
|
timeout = null;
|
|
631
|
-
|
|
632
|
-
result = func.apply(context, args);
|
|
633
|
-
}
|
|
634
|
-
whenDone();
|
|
635
|
-
};
|
|
636
|
-
if (!timeout) timeout = setTimeout(later, wait);
|
|
637
|
-
if (throttling) {
|
|
638
|
-
more = true;
|
|
639
|
-
} else {
|
|
640
|
-
throttling = true;
|
|
648
|
+
previous = now;
|
|
641
649
|
result = func.apply(context, args);
|
|
650
|
+
} else if (!timeout) {
|
|
651
|
+
timeout = setTimeout(later, remaining);
|
|
642
652
|
}
|
|
643
|
-
whenDone();
|
|
644
653
|
return result;
|
|
645
654
|
};
|
|
646
655
|
};
|
|
@@ -758,8 +767,10 @@
|
|
|
758
767
|
// Extend a given object with all the properties in passed-in object(s).
|
|
759
768
|
_.extend = function(obj) {
|
|
760
769
|
each(slice.call(arguments, 1), function(source) {
|
|
761
|
-
|
|
762
|
-
|
|
770
|
+
if (source) {
|
|
771
|
+
for (var prop in source) {
|
|
772
|
+
obj[prop] = source[prop];
|
|
773
|
+
}
|
|
763
774
|
}
|
|
764
775
|
});
|
|
765
776
|
return obj;
|
|
@@ -788,8 +799,10 @@
|
|
|
788
799
|
// Fill in a given object with default properties.
|
|
789
800
|
_.defaults = function(obj) {
|
|
790
801
|
each(slice.call(arguments, 1), function(source) {
|
|
791
|
-
|
|
792
|
-
|
|
802
|
+
if (source) {
|
|
803
|
+
for (var prop in source) {
|
|
804
|
+
if (obj[prop] == null) obj[prop] = source[prop];
|
|
805
|
+
}
|
|
793
806
|
}
|
|
794
807
|
});
|
|
795
808
|
return obj;
|
|
@@ -954,7 +967,7 @@
|
|
|
954
967
|
|
|
955
968
|
// Is a given object a finite number?
|
|
956
969
|
_.isFinite = function(obj) {
|
|
957
|
-
return
|
|
970
|
+
return isFinite(obj) && !isNaN(parseFloat(obj));
|
|
958
971
|
};
|
|
959
972
|
|
|
960
973
|
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
|
|
@@ -1000,7 +1013,9 @@
|
|
|
1000
1013
|
|
|
1001
1014
|
// Run a function **n** times.
|
|
1002
1015
|
_.times = function(n, iterator, context) {
|
|
1003
|
-
|
|
1016
|
+
var accum = Array(n);
|
|
1017
|
+
for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
|
|
1018
|
+
return accum;
|
|
1004
1019
|
};
|
|
1005
1020
|
|
|
1006
1021
|
// Return a random integer between min and max (inclusive).
|
|
@@ -1009,7 +1024,7 @@
|
|
|
1009
1024
|
max = min;
|
|
1010
1025
|
min = 0;
|
|
1011
1026
|
}
|
|
1012
|
-
return min + (
|
|
1027
|
+
return min + Math.floor(Math.random() * (max - min + 1));
|
|
1013
1028
|
};
|
|
1014
1029
|
|
|
1015
1030
|
// List of HTML entities for escaping.
|
|
@@ -1065,7 +1080,7 @@
|
|
|
1065
1080
|
// Useful for temporary DOM ids.
|
|
1066
1081
|
var idCounter = 0;
|
|
1067
1082
|
_.uniqueId = function(prefix) {
|
|
1068
|
-
var id = idCounter
|
|
1083
|
+
var id = ++idCounter + '';
|
|
1069
1084
|
return prefix ? prefix + id : id;
|
|
1070
1085
|
};
|
|
1071
1086
|
|
|
@@ -1100,6 +1115,7 @@
|
|
|
1100
1115
|
// Underscore templating handles arbitrary delimiters, preserves whitespace,
|
|
1101
1116
|
// and correctly escapes quotes within interpolated code.
|
|
1102
1117
|
_.template = function(text, data, settings) {
|
|
1118
|
+
var render;
|
|
1103
1119
|
settings = _.defaults({}, settings, _.templateSettings);
|
|
1104
1120
|
|
|
1105
1121
|
// Combine delimiters into one regular expression via alternation.
|
|
@@ -1115,11 +1131,18 @@
|
|
|
1115
1131
|
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
|
|
1116
1132
|
source += text.slice(index, offset)
|
|
1117
1133
|
.replace(escaper, function(match) { return '\\' + escapes[match]; });
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1134
|
+
|
|
1135
|
+
if (escape) {
|
|
1136
|
+
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
|
|
1137
|
+
}
|
|
1138
|
+
if (interpolate) {
|
|
1139
|
+
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
|
|
1140
|
+
}
|
|
1141
|
+
if (evaluate) {
|
|
1142
|
+
source += "';\n" + evaluate + "\n__p+='";
|
|
1143
|
+
}
|
|
1122
1144
|
index = offset + match.length;
|
|
1145
|
+
return match;
|
|
1123
1146
|
});
|
|
1124
1147
|
source += "';\n";
|
|
1125
1148
|
|
|
@@ -1131,7 +1154,7 @@
|
|
|
1131
1154
|
source + "return __p;\n";
|
|
1132
1155
|
|
|
1133
1156
|
try {
|
|
1134
|
-
|
|
1157
|
+
render = new Function(settings.variable || 'obj', '_', source);
|
|
1135
1158
|
} catch (e) {
|
|
1136
1159
|
e.source = source;
|
|
1137
1160
|
throw e;
|
|
@@ -41,12 +41,13 @@
|
|
|
41
41
|
lt: '<',
|
|
42
42
|
gt: '>',
|
|
43
43
|
quot: '"',
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
amp: '&',
|
|
45
|
+
apos: "'"
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
var reversedEscapeChars = {};
|
|
49
|
-
for(var key in escapeChars)
|
|
49
|
+
for(var key in escapeChars) reversedEscapeChars[escapeChars[key]] = key;
|
|
50
|
+
reversedEscapeChars["'"] = '#39';
|
|
50
51
|
|
|
51
52
|
// sprintf() for JavaScript 0.7-beta1
|
|
52
53
|
// http://www.diveintojavascript.com/projects/javascript-sprintf
|
|
@@ -206,7 +207,22 @@
|
|
|
206
207
|
|
|
207
208
|
count: function(str, substr){
|
|
208
209
|
if (str == null || substr == null) return 0;
|
|
209
|
-
|
|
210
|
+
|
|
211
|
+
str = String(str);
|
|
212
|
+
substr = String(substr);
|
|
213
|
+
|
|
214
|
+
var count = 0,
|
|
215
|
+
pos = 0,
|
|
216
|
+
length = substr.length;
|
|
217
|
+
|
|
218
|
+
while (true) {
|
|
219
|
+
pos = str.indexOf(substr, pos);
|
|
220
|
+
if (pos === -1) break;
|
|
221
|
+
count++;
|
|
222
|
+
pos += length;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return count;
|
|
210
226
|
},
|
|
211
227
|
|
|
212
228
|
chars: function(str) {
|
|
@@ -320,7 +336,7 @@
|
|
|
320
336
|
},
|
|
321
337
|
|
|
322
338
|
classify: function(str){
|
|
323
|
-
return _s.titleize(String(str).replace(/
|
|
339
|
+
return _s.titleize(String(str).replace(/[\W_]/g, ' ')).replace(/\s/g, '');
|
|
324
340
|
},
|
|
325
341
|
|
|
326
342
|
humanize: function(str){
|
|
@@ -429,17 +445,17 @@
|
|
|
429
445
|
},
|
|
430
446
|
|
|
431
447
|
toNumber: function(str, decimals) {
|
|
432
|
-
if (str
|
|
433
|
-
str =
|
|
434
|
-
|
|
435
|
-
return
|
|
448
|
+
if (!str) return 0;
|
|
449
|
+
str = _s.trim(str);
|
|
450
|
+
if (!str.match(/^-?\d+(?:\.\d+)?$/)) return NaN;
|
|
451
|
+
return parseNumber(parseNumber(str).toFixed(~~decimals));
|
|
436
452
|
},
|
|
437
453
|
|
|
438
454
|
numberFormat : function(number, dec, dsep, tsep) {
|
|
439
455
|
if (isNaN(number) || number == null) return '';
|
|
440
456
|
|
|
441
457
|
number = number.toFixed(~~dec);
|
|
442
|
-
tsep = tsep
|
|
458
|
+
tsep = typeof tsep == 'string' ? tsep : ',';
|
|
443
459
|
|
|
444
460
|
var parts = number.split('.'), fnums = parts[0],
|
|
445
461
|
decimals = parts[1] ? (dsep || '.') + parts[1] : '';
|
|
@@ -494,8 +510,8 @@
|
|
|
494
510
|
slugify: function(str) {
|
|
495
511
|
if (str == null) return '';
|
|
496
512
|
|
|
497
|
-
var from = "
|
|
498
|
-
to = "
|
|
513
|
+
var from = "ąàáäâãåæćęèéëêìíïîłńòóöôõøśùúüûñçżź",
|
|
514
|
+
to = "aaaaaaaaceeeeeiiiilnoooooosuuuunczz",
|
|
499
515
|
regex = new RegExp(defaultToWhiteSpace(from), 'g');
|
|
500
516
|
|
|
501
517
|
str = String(str).toLowerCase().replace(regex, function(c){
|
|
@@ -538,6 +554,36 @@
|
|
|
538
554
|
return repeat.join(separator);
|
|
539
555
|
},
|
|
540
556
|
|
|
557
|
+
naturalCmp: function(str1, str2){
|
|
558
|
+
if (str1 == str2) return 0;
|
|
559
|
+
if (!str1) return -1;
|
|
560
|
+
if (!str2) return 1;
|
|
561
|
+
|
|
562
|
+
var cmpRegex = /(\.\d+)|(\d+)|(\D+)/g,
|
|
563
|
+
tokens1 = String(str1).toLowerCase().match(cmpRegex),
|
|
564
|
+
tokens2 = String(str2).toLowerCase().match(cmpRegex),
|
|
565
|
+
count = Math.min(tokens1.length, tokens2.length);
|
|
566
|
+
|
|
567
|
+
for(var i = 0; i < count; i++) {
|
|
568
|
+
var a = tokens1[i], b = tokens2[i];
|
|
569
|
+
|
|
570
|
+
if (a !== b){
|
|
571
|
+
var num1 = parseInt(a, 10);
|
|
572
|
+
if (!isNaN(num1)){
|
|
573
|
+
var num2 = parseInt(b, 10);
|
|
574
|
+
if (!isNaN(num2) && num1 - num2)
|
|
575
|
+
return num1 - num2;
|
|
576
|
+
}
|
|
577
|
+
return a < b ? -1 : 1;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
if (tokens1.length === tokens2.length)
|
|
582
|
+
return tokens1.length - tokens2.length;
|
|
583
|
+
|
|
584
|
+
return str1 < str2 ? -1 : 1;
|
|
585
|
+
},
|
|
586
|
+
|
|
541
587
|
levenshtein: function(str1, str2) {
|
|
542
588
|
if (str1 == null && str2 == null) return 0;
|
|
543
589
|
if (str1 == null) return String(str2).length;
|
|
@@ -576,25 +622,23 @@
|
|
|
576
622
|
_s.contains = _s.include;
|
|
577
623
|
_s.q = _s.quote;
|
|
578
624
|
|
|
625
|
+
// Exporting
|
|
626
|
+
|
|
579
627
|
// CommonJS module is defined
|
|
580
628
|
if (typeof exports !== 'undefined') {
|
|
581
|
-
if (typeof module !== 'undefined' && module.exports)
|
|
582
|
-
// Export module
|
|
629
|
+
if (typeof module !== 'undefined' && module.exports)
|
|
583
630
|
module.exports = _s;
|
|
584
|
-
}
|
|
585
|
-
exports._s = _s;
|
|
586
631
|
|
|
587
|
-
|
|
588
|
-
// Register as a named module with AMD.
|
|
589
|
-
define('underscore.string', [], function() {
|
|
590
|
-
return _s;
|
|
591
|
-
});
|
|
592
|
-
|
|
593
|
-
} else {
|
|
594
|
-
// Integrate with Underscore.js if defined
|
|
595
|
-
// or create our own underscore object.
|
|
596
|
-
root._ = root._ || {};
|
|
597
|
-
root._.string = root._.str = _s;
|
|
632
|
+
exports._s = _s;
|
|
598
633
|
}
|
|
599
634
|
|
|
635
|
+
// Register as a named module with AMD.
|
|
636
|
+
if (typeof define === 'function' && define.amd)
|
|
637
|
+
define('underscore.string', [], function(){ return _s; });
|
|
638
|
+
|
|
639
|
+
|
|
640
|
+
// Integrate with Underscore.js if defined
|
|
641
|
+
// or create our own underscore object.
|
|
642
|
+
root._ = root._ || {};
|
|
643
|
+
root._.string = root._.str = _s;
|
|
600
644
|
}(this, String);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#= require ultimate/underscore/underscore
|
|
2
|
+
#= require ultimate/underscore/underscore.string
|
|
3
|
+
#= require ultimate/jquery.base
|
|
4
|
+
|
|
5
|
+
module "ultimate/jquery.base"
|
|
6
|
+
|
|
7
|
+
test "ror_id", ->
|
|
8
|
+
strictEqual ror_id("some_id_123"), "123"
|
|
9
|
+
strictEqual ror_id("some_id"), null
|
|
10
|
+
strictEqual ror_id($('')), null
|
|
11
|
+
strictEqual ror_id(), null
|
|
12
|
+
strictEqual ror_id($('<div></div>')), null
|
|
13
|
+
jObj = $('<div id="some_123"></div>')
|
|
14
|
+
strictEqual ror_id(jObj), "123"
|
|
15
|
+
strictEqual jObj.data("rorId"), "123"
|
|
16
|
+
|
|
17
|
+
test "$.fn.rorId", ->
|
|
18
|
+
jObj = $('<div></div>')
|
|
19
|
+
strictEqual jObj.rorId(), null
|
|
20
|
+
strictEqual jObj.rorId(123)[0], jObj[0]
|
|
21
|
+
strictEqual jObj.attr("id"), undefined
|
|
22
|
+
strictEqual jObj.rorId(), 123
|
|
23
|
+
strictEqual jObj.rorId(777, "book").attr("id"), "book_777"
|
|
24
|
+
strictEqual jObj.rorId(), 777
|
|
25
|
+
|
|
26
|
+
test "$.fn.getClasses", ->
|
|
27
|
+
jObj = $('<div class="apple banana coconut"></div>')
|
|
28
|
+
deepEqual jObj.getClasses(), ["apple", "banana", "coconut"]
|
|
29
|
+
deepEqual jObj.attr('class', '').getClasses(), []
|
|
30
|
+
|
|
31
|
+
test "$.fn.getAttributes", ->
|
|
32
|
+
deepEqual $("").getAttributes(), {}
|
|
33
|
+
deepEqual $("<div></div>").getAttributes(), {}
|
|
34
|
+
deepEqual $('<div id="some_id_123" class="apple" data-loading-text="Loading..."></div>').getAttributes(), {id: "some_id_123", class: "apple", "data-loading-text": "Loading..."}
|
|
35
|
+
|
|
36
|
+
test "$.isHTML", ->
|
|
37
|
+
strictEqual $.isHTML(''), false
|
|
38
|
+
strictEqual $.isHTML('Some plain text'), false
|
|
39
|
+
strictEqual $.isHTML('Some plain text with <html></html>'), false
|
|
40
|
+
strictEqual $.isHTML('<span></span><p></p>'), true
|
|
41
|
+
strictEqual $.isHTML('<span></span><p></p>', true), false
|
|
42
|
+
strictEqual $.isHTML('<p><span></span></p>', true), true
|
|
@@ -40,7 +40,7 @@ test "options_for_select", ->
|
|
|
40
40
|
equal options_for_select({ "$": "Dollar", "<DKR>": "<Kroner>" }, [ "Dollar", "<Kroner>" ]),
|
|
41
41
|
"<option selected=\"selected\" value=\"Dollar\">$</option>\n<option selected=\"selected\" value=\"<Kroner>\"><DKR></option>"
|
|
42
42
|
equal options_for_select([ [ "<Denmark>", { class: 'bold' } ], [ "USA", { onclick: "alert('Hello World');" } ], [ "Sweden" ], "Germany" ]),
|
|
43
|
-
"<option class=\"bold\" value=\"<Denmark>\"><Denmark></option>\n<option onclick=\"alert(
|
|
43
|
+
"<option class=\"bold\" value=\"<Denmark>\"><Denmark></option>\n<option onclick=\"alert('Hello World');\" value=\"USA\">USA</option>\n<option value=\"Sweden\">Sweden</option>\n<option value=\"Germany\">Germany</option>"
|
|
44
44
|
equal options_for_select([ [ "<Denmark>", { data: { test: 'bold' } } ] ]),
|
|
45
45
|
"<option data-test=\"bold\" value=\"<Denmark>\"><Denmark></option>"
|
|
46
46
|
equal options_for_select([ [ "<Denmark>", { data: { test: '<bold>' } } ] ]),
|
|
@@ -124,7 +124,7 @@ test "radio_button_tag", ->
|
|
|
124
124
|
|
|
125
125
|
test "submit_tag", ->
|
|
126
126
|
equal submit_tag("Save", onclick: "alert('hello!')", data: { disable_with: "Saving..." }),
|
|
127
|
-
'<input data-disable-with="Saving..." name="commit" onclick="alert(
|
|
127
|
+
'<input data-disable-with="Saving..." name="commit" onclick="alert('hello!')" type="submit" value="Save" />'
|
|
128
128
|
equal submit_tag("Save", data: { disable_with: "Saving..." }),
|
|
129
129
|
'<input data-disable-with="Saving..." name="commit" type="submit" value="Save" />'
|
|
130
130
|
equal submit_tag("Save", data: { confirm: "Are you sure?" }),
|
|
@@ -39,6 +39,7 @@ test "number_to_currency", ->
|
|
|
39
39
|
equal number_to_currency(1234567891.50, precision: 0), "$1,234,567,892"
|
|
40
40
|
equal number_to_currency(1234567890.50, precision: 1), "$1,234,567,890.5"
|
|
41
41
|
equal number_to_currency(1234567890.50, unit: "£", separator: ",", delimiter: ""), "£1234567890,50"
|
|
42
|
+
equal number_to_currency(1234567890.50, unit: '<span class="unit">Руб.</span>', format: "%n %u"), "1,234,567,890.50 <span class=\"unit\">Руб.</span>"
|
|
42
43
|
equal number_to_currency("1234567890.50"), "$1,234,567,890.50"
|
|
43
44
|
equal number_to_currency("1234567890.50", unit: "Kč", format: "%n %u"), "1,234,567,890.50 Kč"
|
|
44
45
|
equal number_to_currency("-1234567890.50", unit: "Kč", format: "%n %u", negative_format: "%n - %u"), "1,234,567,890.50 - Kč"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#= require ultimate/underscore/underscore
|
|
2
|
+
#= require ultimate/helpers
|
|
3
|
+
|
|
4
|
+
module "ultimate/helpers"
|
|
5
|
+
|
|
6
|
+
test "cout", ->
|
|
7
|
+
ok _.isBoolean(window.DEBUG_MODE), "global DEBUG_MODE is Boolean"
|
|
8
|
+
window.DEBUG_MODE = true
|
|
9
|
+
strictEqual cout(123), 123, "cout() must return first argument"
|
|
10
|
+
window.DEBUG_MODE = false
|
|
11
|
+
for method in ['log', 'info', 'warn', 'error', 'assert', 'clear']
|
|
12
|
+
strictEqual cout(method, 123), 123, "cout() must return second argument if first is `#{method}` as method"
|
|
13
|
+
window.DEBUG_MODE = true
|
|
14
|
+
|
|
15
|
+
test "_cout", ->
|
|
16
|
+
strictEqual _cout(123), 123, "_cout() must return first argument"
|
|
17
|
+
for method in ['log', 'info', 'warn', 'error', 'assert', 'clear']
|
|
18
|
+
strictEqual _cout(method, 123), method, "_cout() on so strong that it does not use the method `#{method}` as first argument, and return first argument always"
|
|
19
|
+
|
|
20
|
+
test "deprecate", ->
|
|
21
|
+
equal deprecate('first thing'), "`first thing` DEPRECATED!", "log and return message about deprecated function"
|
|
22
|
+
equal deprecate('first thing', 'second thing'), "`first thing` DEPRECATED! Use instead `second thing`", "log and return message about deprecated function, and hint about using instead"
|
|
23
|
+
|
|
24
|
+
test "todo", ->
|
|
25
|
+
ok _.isBoolean(window.LOG_TODO), "global LOG_TODO is Boolean"
|
|
26
|
+
window.LOG_TODO = true
|
|
27
|
+
equal todo('some todo'), "TODO: some todo", "log and return todo"
|
|
28
|
+
equal todo('some todo', "helpers_test.js.coffee"), "TODO: some todo ### helpers_test.js.coffee", "log and return todo with location string"
|
|
29
|
+
equal todo('some todo', "helpers_test.js.coffee", "test \"deprecate\""), "TODO: some todo ### helpers_test.js.coffee > test \"deprecate\"", "log and return todo with description of function"
|
|
30
|
+
equal todo('some todo', "helpers_test.js.coffee", 12), "TODO: some todo ### helpers_test.js.coffee:12", "log and return message with string number"
|
|
31
|
+
window.LOG_TODO = false
|
|
32
|
+
equal todo('some todo'), undefined, "don't log and return `undefined` if global LOG_TODO == false"
|
|
33
|
+
window.LOG_TODO = true
|
|
34
|
+
|
|
35
|
+
test "logicalXOR", ->
|
|
36
|
+
strictEqual logicalXOR(false, false), false, "false XOR false === false"
|
|
37
|
+
strictEqual logicalXOR(false, true), true, "false XOR true === true"
|
|
38
|
+
strictEqual logicalXOR(true, false), true, "true XOR false === true"
|
|
39
|
+
strictEqual logicalXOR(true, true), false, "true XOR true === false"
|
|
40
|
+
|
|
41
|
+
test "bound", ->
|
|
42
|
+
equal bound(0, 10, 100), 10
|
|
43
|
+
equal bound(100, 10, 100), 100
|
|
44
|
+
equal bound(50, 10, 100), 50
|
|
45
|
+
equal bound(-20, -10, 100), -10
|
|
46
|
+
equal bound(-20, 10, -10), 10
|
|
47
|
+
equal bound(20, 10, -10), 10
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ultimate-helpers
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
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:
|
|
12
|
+
date: 2013-05-16 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rails
|
|
@@ -67,8 +67,6 @@ extensions: []
|
|
|
67
67
|
extra_rdoc_files: []
|
|
68
68
|
files:
|
|
69
69
|
- .gitignore
|
|
70
|
-
- .rvmrc
|
|
71
|
-
- .rvmrc.example
|
|
72
70
|
- Gemfile
|
|
73
71
|
- Gemfile.lock
|
|
74
72
|
- LICENSE
|
|
@@ -147,6 +145,7 @@ files:
|
|
|
147
145
|
- test/dummy/script/rails
|
|
148
146
|
- test/javascripts/all_tests.js.coffee
|
|
149
147
|
- test/javascripts/test_helper.js.coffee
|
|
148
|
+
- test/javascripts/tests/base_test.js.coffee
|
|
150
149
|
- test/javascripts/tests/helpers/asset_tag_test.js.coffee
|
|
151
150
|
- test/javascripts/tests/helpers/form_options_test.js.coffee
|
|
152
151
|
- test/javascripts/tests/helpers/form_tag_test.js.coffee
|
|
@@ -155,6 +154,7 @@ files:
|
|
|
155
154
|
- test/javascripts/tests/helpers/record_tag_test.js.coffee
|
|
156
155
|
- test/javascripts/tests/helpers/tag_test.js.coffee
|
|
157
156
|
- test/javascripts/tests/helpers/url_test.js.coffee
|
|
157
|
+
- test/javascripts/tests/helpers_test.js.coffee
|
|
158
158
|
- test/javascripts/tests/underscore/underscore.outcasts.test.js.coffee
|
|
159
159
|
- test/javascripts/vendors/backbone.js
|
|
160
160
|
- test/javascripts/vendors/i18n-lite.js.coffee
|
|
@@ -186,8 +186,79 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
186
186
|
version: '0'
|
|
187
187
|
requirements: []
|
|
188
188
|
rubyforge_project: ultimate-helpers
|
|
189
|
-
rubygems_version: 1.8.
|
|
189
|
+
rubygems_version: 1.8.25
|
|
190
190
|
signing_key:
|
|
191
191
|
specification_version: 3
|
|
192
192
|
summary: Ultimate Helpers, Rails ActionView helpers ported to CoffeeScript
|
|
193
|
-
test_files:
|
|
193
|
+
test_files:
|
|
194
|
+
- test/dummy/Rakefile
|
|
195
|
+
- test/dummy/_emfile
|
|
196
|
+
- test/dummy/app/assets/images/.gitkeep
|
|
197
|
+
- test/dummy/app/assets/javascripts/application.js
|
|
198
|
+
- test/dummy/app/assets/stylesheets/application.css
|
|
199
|
+
- test/dummy/app/assets/stylesheets/global/forms.css.scss
|
|
200
|
+
- test/dummy/app/assets/stylesheets/global/layout.css.scss
|
|
201
|
+
- test/dummy/app/assets/stylesheets/global/layout/footer.scss
|
|
202
|
+
- test/dummy/app/assets/stylesheets/global/layout/header.scss
|
|
203
|
+
- test/dummy/app/assets/stylesheets/global/layout/main-menu.scss
|
|
204
|
+
- test/dummy/app/assets/stylesheets/global/reserved.css.scss
|
|
205
|
+
- test/dummy/app/assets/stylesheets/global/reset.css.scss
|
|
206
|
+
- test/dummy/app/assets/stylesheets/global/structures.css.scss
|
|
207
|
+
- test/dummy/app/assets/stylesheets/import/base.scss
|
|
208
|
+
- test/dummy/app/assets/stylesheets/plugins/qunit.css.scss
|
|
209
|
+
- test/dummy/app/controllers/application_controller.rb
|
|
210
|
+
- test/dummy/app/controllers/main_controller.rb
|
|
211
|
+
- test/dummy/app/helpers/application_helper.rb
|
|
212
|
+
- test/dummy/app/mailers/.gitkeep
|
|
213
|
+
- test/dummy/app/models/.gitkeep
|
|
214
|
+
- test/dummy/app/views/application/_footer.html.haml
|
|
215
|
+
- test/dummy/app/views/application/_header.html.haml
|
|
216
|
+
- test/dummy/app/views/application/_main_menu.html.haml
|
|
217
|
+
- test/dummy/app/views/layouts/application.html.haml
|
|
218
|
+
- test/dummy/app/views/main/index.html.haml
|
|
219
|
+
- test/dummy/app/views/main/qunit.html.haml
|
|
220
|
+
- test/dummy/config.ru
|
|
221
|
+
- test/dummy/config/application.rb
|
|
222
|
+
- test/dummy/config/boot.rb
|
|
223
|
+
- test/dummy/config/database.yml
|
|
224
|
+
- test/dummy/config/environment.rb
|
|
225
|
+
- test/dummy/config/environments/development.rb
|
|
226
|
+
- test/dummy/config/environments/production.rb
|
|
227
|
+
- test/dummy/config/environments/test.rb
|
|
228
|
+
- test/dummy/config/initializers/backtrace_silencers.rb
|
|
229
|
+
- test/dummy/config/initializers/inflections.rb
|
|
230
|
+
- test/dummy/config/initializers/mime_types.rb
|
|
231
|
+
- test/dummy/config/initializers/qunit-rails.rb
|
|
232
|
+
- test/dummy/config/initializers/secret_token.rb
|
|
233
|
+
- test/dummy/config/initializers/session_store.rb
|
|
234
|
+
- test/dummy/config/initializers/wrap_parameters.rb
|
|
235
|
+
- test/dummy/config/locales/en.yml
|
|
236
|
+
- test/dummy/config/routes.rb
|
|
237
|
+
- test/dummy/log/.gitkeep
|
|
238
|
+
- test/dummy/public/404.html
|
|
239
|
+
- test/dummy/public/422.html
|
|
240
|
+
- test/dummy/public/500.html
|
|
241
|
+
- test/dummy/public/favicon.ico
|
|
242
|
+
- test/dummy/script/rails
|
|
243
|
+
- test/javascripts/all_tests.js.coffee
|
|
244
|
+
- test/javascripts/test_helper.js.coffee
|
|
245
|
+
- test/javascripts/tests/base_test.js.coffee
|
|
246
|
+
- test/javascripts/tests/helpers/asset_tag_test.js.coffee
|
|
247
|
+
- test/javascripts/tests/helpers/form_options_test.js.coffee
|
|
248
|
+
- test/javascripts/tests/helpers/form_tag_test.js.coffee
|
|
249
|
+
- test/javascripts/tests/helpers/javascript_test.js.coffee
|
|
250
|
+
- test/javascripts/tests/helpers/number_test.js.coffee
|
|
251
|
+
- test/javascripts/tests/helpers/record_tag_test.js.coffee
|
|
252
|
+
- test/javascripts/tests/helpers/tag_test.js.coffee
|
|
253
|
+
- test/javascripts/tests/helpers/url_test.js.coffee
|
|
254
|
+
- test/javascripts/tests/helpers_test.js.coffee
|
|
255
|
+
- test/javascripts/tests/underscore/underscore.outcasts.test.js.coffee
|
|
256
|
+
- test/javascripts/vendors/backbone.js
|
|
257
|
+
- test/javascripts/vendors/i18n-lite.js.coffee
|
|
258
|
+
- test/stylesheets/test_helper.css
|
|
259
|
+
- test/stylesheets/vendors/ultimate/mixins/_routines.scss
|
|
260
|
+
- test/stylesheets/vendors/ultimate/mixins/_vendors.scss
|
|
261
|
+
- test/stylesheets/vendors/ultimate/mixins/css3.scss
|
|
262
|
+
- test/stylesheets/vendors/ultimate/mixins/css3/_text-shadow.scss
|
|
263
|
+
- test/stylesheets/vendors/ultimate/mixins/fonts.scss
|
|
264
|
+
- test/stylesheets/vendors/ultimate/mixins/microstructures.scss
|
data/.rvmrc
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
rvm 1.9.3@ultimate
|
data/.rvmrc.example
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
rvm 1.9.3@ultimate
|