ultimate-base 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.
Files changed (58) hide show
  1. data/.gitignore +5 -0
  2. data/.rvmrc +2 -0
  3. data/.rvmrc.example +2 -0
  4. data/Gemfile +4 -0
  5. data/Gemfile.lock +14 -0
  6. data/LICENSE +5 -0
  7. data/README.md +1 -0
  8. data/Rakefile +1 -0
  9. data/app/assets/javascripts/backbone/backbone.js +1452 -0
  10. data/app/assets/javascripts/backbone/ultimate/app.js.coffee +25 -0
  11. data/app/assets/javascripts/backbone/ultimate/collection.js.coffee +12 -0
  12. data/app/assets/javascripts/backbone/ultimate/model.js.coffee +12 -0
  13. data/app/assets/javascripts/backbone/ultimate/router.js.coffee +13 -0
  14. data/app/assets/javascripts/backbone/ultimate/view.js.coffee +96 -0
  15. data/app/assets/javascripts/ultimate/base.js.coffee +103 -0
  16. data/app/assets/javascripts/ultimate/bus.js.coffee +57 -0
  17. data/app/assets/javascripts/ultimate/devise.js.coffee +18 -0
  18. data/app/assets/javascripts/ultimate/experimental/_inflections/dzone.inflections.js +154 -0
  19. data/app/assets/javascripts/ultimate/experimental/_inflections/inflections.js.coffee +2 -0
  20. data/app/assets/javascripts/ultimate/experimental/_inflections/plur.js +29 -0
  21. data/app/assets/javascripts/ultimate/experimental/_inflections/underscore.inflection.js +175 -0
  22. data/app/assets/javascripts/ultimate/experimental/fuzzy-json-generator.js.coffee +48 -0
  23. data/app/assets/javascripts/ultimate/helpers/array.js.coffee +63 -0
  24. data/app/assets/javascripts/ultimate/helpers/asset_tag.js.coffee +63 -0
  25. data/app/assets/javascripts/ultimate/helpers/decor.js.coffee +14 -0
  26. data/app/assets/javascripts/ultimate/helpers/forms.js.coffee +0 -0
  27. data/app/assets/javascripts/ultimate/helpers/tags.js.coffee +70 -0
  28. data/app/assets/javascripts/ultimate/helpers.js.coffee +149 -0
  29. data/app/assets/javascripts/ultimate/improves/datepicker.js.coffee +34 -0
  30. data/app/assets/javascripts/ultimate/improves/form-errors.js.coffee +146 -0
  31. data/app/assets/javascripts/ultimate/improves/form.js.coffee +155 -0
  32. data/app/assets/javascripts/ultimate/improves/magic-radios.js.coffee +41 -0
  33. data/app/assets/javascripts/ultimate/improves/tablesorter.js +59 -0
  34. data/app/assets/javascripts/ultimate/improves/typed-field.js.coffee +98 -0
  35. data/app/assets/javascripts/ultimate/underscore/underscore.js +1059 -0
  36. data/app/assets/javascripts/ultimate/underscore/underscore.string.js +480 -0
  37. data/app/assets/javascripts/ultimate/widgets/dock.js.coffee +70 -0
  38. data/app/assets/javascripts/ultimate/widgets/gear.js.coffee +84 -0
  39. data/app/assets/javascripts/ultimate/widgets/jquery-ext.js.coffee +104 -0
  40. data/app/assets/javascripts/ultimate/widgets/jquery.adapter.js.coffee +62 -0
  41. data/app/assets/javascripts/ultimate/widgets/widget.js.coffee +115 -0
  42. data/app/assets/stylesheets/polyfills/PIE.htc +96 -0
  43. data/app/assets/stylesheets/polyfills/boxsizing.htc +300 -0
  44. data/app/assets/stylesheets/ultimate/mixins/_routines.css.scss +95 -0
  45. data/app/assets/stylesheets/ultimate/mixins/_vendors.css.scss +34 -0
  46. data/app/assets/stylesheets/ultimate/mixins/css3/_text-shadow.scss +37 -0
  47. data/app/assets/stylesheets/ultimate/mixins/css3.css.scss +328 -0
  48. data/app/assets/stylesheets/ultimate/mixins/decor.css.scss +86 -0
  49. data/app/assets/stylesheets/ultimate/mixins/fonts.css.scss +100 -0
  50. data/app/assets/stylesheets/ultimate/mixins/microstructures.css.scss +188 -0
  51. data/app/assets/stylesheets/ultimate/structures/slider.css.scss +53 -0
  52. data/lib/ultimate-base/engine.rb +6 -0
  53. data/lib/ultimate-base/extensions/directive_processor.rb +64 -0
  54. data/lib/ultimate-base/extensions/sass_script_functions.rb +39 -0
  55. data/lib/ultimate-base/version.rb +5 -0
  56. data/lib/ultimate-base.rb +10 -0
  57. data/ultimate-base.gemspec +25 -0
  58. metadata +102 -0
@@ -0,0 +1,175 @@
1
+ // Underscore.inflection.js
2
+ // (c) 2011 Jeremy Ruppel
3
+ // Underscore.inflection is freely distributable under the MIT license.
4
+ // Portions of Underscore.inflection are inspired or borrowed from ActiveSupport
5
+ // Version 1.0.0
6
+
7
+ ( function( _, undefined )
8
+ {
9
+ /**
10
+ * Inflector
11
+ */
12
+ var inflector = {
13
+
14
+ plurals : [ ],
15
+
16
+ singulars : [ ],
17
+
18
+ uncountables : [ ],
19
+
20
+ gsub : function( word, rule, replacement )
21
+ {
22
+ var pattern = new RegExp( rule.source || rule, 'gi' );
23
+
24
+ return pattern.test( word ) ? word.replace( pattern, replacement ) : null;
25
+ },
26
+
27
+ plural : function( rule, replacement )
28
+ {
29
+ this.plurals.unshift( [ rule, replacement ] );
30
+ },
31
+
32
+ pluralize : function( word, count, includeNumber )
33
+ {
34
+ var result;
35
+
36
+ if( count !== undefined )
37
+ {
38
+ result = ( count === 1 ) ? this.singularize( word ) : this.pluralize( word );
39
+ result = ( includeNumber ) ? [ count, result ].join( ' ' ) : result;
40
+ }
41
+ else
42
+ {
43
+ if( _( this.uncountables ).include( word ) )
44
+ {
45
+ return word;
46
+ }
47
+
48
+ result = word;
49
+
50
+ _( this.plurals ).detect( function( rule )
51
+ {
52
+ var gsub = this.gsub( word, rule[ 0 ], rule[ 1 ] );
53
+
54
+ return gsub ? ( result = gsub ) : false;
55
+ },
56
+ this );
57
+ }
58
+
59
+ return result;
60
+ },
61
+
62
+ singular : function( rule, replacement )
63
+ {
64
+ this.singulars.unshift( [ rule, replacement ] );
65
+ },
66
+
67
+ singularize : function( word )
68
+ {
69
+ if( _( this.uncountables ).include( word ) )
70
+ {
71
+ return word;
72
+ }
73
+
74
+ var result = word;
75
+
76
+ _( this.singulars ).detect( function( rule )
77
+ {
78
+ var gsub = this.gsub( word, rule[ 0 ], rule[ 1 ] );
79
+
80
+ return gsub ? ( result = gsub ) : false;
81
+ },
82
+ this );
83
+
84
+ return result;
85
+ },
86
+
87
+ irregular : function( singular, plural )
88
+ {
89
+ this.plural( singular, plural );
90
+ this.singular( plural, singular );
91
+ },
92
+
93
+ uncountable : function( word )
94
+ {
95
+ this.uncountables.unshift( word );
96
+ },
97
+
98
+ resetInflections : function( )
99
+ {
100
+ this.plurals = [ ];
101
+ this.singulars = [ ];
102
+ this.uncountables = [ ];
103
+
104
+ this.plural( /$/, 's' );
105
+ this.plural( /s$/, 's' );
106
+ this.plural( /(ax|test)is$/, '$1es' );
107
+ this.plural( /(octop|vir)us$/, '$1i' );
108
+ this.plural( /(octop|vir)i$/, '$1i' );
109
+ this.plural( /(alias|status)$/, '$1es' );
110
+ this.plural( /(bu)s$/, '$1ses' );
111
+ this.plural( /(buffal|tomat)o$/, '$1oes' );
112
+ this.plural( /([ti])um$/, '$1a' );
113
+ this.plural( /([ti])a$/, '$1a' );
114
+ this.plural( /sis$/, 'ses' );
115
+ this.plural( /(?:([^f])fe|([lr])f)$/, '$1$2ves' );
116
+ this.plural( /(hive)$/, '$1s' );
117
+ this.plural( /([^aeiouy]|qu)y$/, '$1ies' );
118
+ this.plural( /(x|ch|ss|sh)$/, '$1es' );
119
+ this.plural( /(matr|vert|ind)(?:ix|ex)$/, '$1ices' );
120
+ this.plural( /([m|l])ouse$/, '$1ice' );
121
+ this.plural( /([m|l])ice$/, '$1ice' );
122
+ this.plural( /^(ox)$/, '$1en' );
123
+ this.plural( /^(oxen)$/, '$1' );
124
+ this.plural( /(quiz)$/, '$1zes' );
125
+
126
+ this.singular( /s$/, '' );
127
+ this.singular( /(n)ews$/, '$1ews' );
128
+ this.singular( /([ti])a$/, '$1um' );
129
+ this.singular( /((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/, '$1$2sis' );
130
+ this.singular( /(^analy)ses$/, '$1sis' );
131
+ this.singular( /([^f])ves$/, '$1fe' );
132
+ this.singular( /(hive)s$/, '$1' );
133
+ this.singular( /(tive)s$/, '$1' );
134
+ this.singular( /([lr])ves$/, '$1f' );
135
+ this.singular( /([^aeiouy]|qu)ies$/, '$1y' );
136
+ this.singular( /(s)eries$/, '$1eries' );
137
+ this.singular( /(m)ovies$/, '$1ovie' );
138
+ this.singular( /(x|ch|ss|sh)es$/, '$1' );
139
+ this.singular( /([m|l])ice$/, '$1ouse' );
140
+ this.singular( /(bus)es$/, '$1' );
141
+ this.singular( /(o)es$/, '$1' );
142
+ this.singular( /(shoe)s$/, '$1' );
143
+ this.singular( /(cris|ax|test)es$/, '$1is' );
144
+ this.singular( /(octop|vir)i$/, '$1us' );
145
+ this.singular( /(alias|status)es$/, '$1' );
146
+ this.singular( /^(ox)en/, '$1' );
147
+ this.singular( /(vert|ind)ices$/, '$1ex' );
148
+ this.singular( /(matr)ices$/, '$1ix' );
149
+ this.singular( /(quiz)zes$/, '$1' );
150
+ this.singular( /(database)s$/, '$1' );
151
+
152
+ this.irregular( 'person', 'people' );
153
+ this.irregular( 'man', 'men' );
154
+ this.irregular( 'child', 'children' );
155
+ this.irregular( 'sex', 'sexes' );
156
+ this.irregular( 'move', 'moves' );
157
+ this.irregular( 'cow', 'kine' );
158
+
159
+ _( 'equipment information rice money species series fish sheep jeans'.split( /\s+/ ) ).each( function( word )
160
+ {
161
+ this.uncountable( word );
162
+ },
163
+ this );
164
+
165
+ return this;
166
+ }
167
+
168
+ };
169
+
170
+ /**
171
+ * Underscore integration
172
+ */
173
+ _.mixin( inflector.resetInflections( ) );
174
+
175
+ } )( _ );
@@ -0,0 +1,48 @@
1
+ class FuzzyJsonGenerator
2
+
3
+ @idCounter: 0
4
+
5
+ constructor: ->
6
+ # nop
7
+
8
+ nextId: ->
9
+ @constructor.idCounter++
10
+
11
+ # overload this method
12
+ generateOne: ->
13
+ id: @nextId()
14
+
15
+ generateMany: (count, base = 0) ->
16
+ count = @getRandom(count, base) if base > 0
17
+ @generateOne() for i in [0..count]
18
+
19
+ getRandom: (arrayOrCount, base = 0) ->
20
+ rand = Math.random()
21
+ if _.isArray arrayOrCount
22
+ arrayOrCount[Math.floor rand * arrayOrCount.length]
23
+ else if _.isNumber arrayOrCount
24
+ base + Math.floor rand * arrayOrCount
25
+ else
26
+ rand
27
+
28
+
29
+
30
+ @Generators ||= {}
31
+
32
+ class Generators.Offers extends FuzzyJsonGenerator
33
+
34
+ citiesFrom: ['Москва', 'Воронеж', 'Санкт-Петербург']
35
+ citiesTo: ['Хошимин', 'Брюссель', 'Лондон', 'Нью-Йорк', 'Париж', 'Мадрид', 'Берлин']
36
+
37
+ generateOne: ->
38
+ fromDate = new Date
39
+ fromDate.setTime(fromDate.getTime() + 1000 * 60 * 60 * 24 * @getRandom(30))
40
+ toDate = new Date
41
+ toDate.setTime(fromDate.getTime() + 1000 * 60 * 60 * 24 * @getRandom(30))
42
+ id: @nextId()
43
+ city_from : @getRandom(@citiesFrom)
44
+ city_to : @getRandom(@citiesTo)
45
+ date_from : Globalize.format(fromDate, "yyyy-MM-dd")
46
+ date_to : Globalize.format(toDate, "yyyy-MM-dd")
47
+ price : @getRandom(20000, 5000)
48
+ hot : @getRandom(2) is 1
@@ -0,0 +1,63 @@
1
+ @compact = (arr) ->
2
+ @deprecate 'compact(arr)', '_.compact arr'
3
+ r = []
4
+ for e in arr
5
+ r.push e if e?
6
+ r
7
+
8
+ @reverse = (arr) =>
9
+ @deprecate 'reverse(arr)', 'arr.reverse()'
10
+ _isString = _.isString arr
11
+ return arr unless _isString or $.isArray arr
12
+ if _isString then @warning 'reverse(someString)', 'STOP USE IT!' else arr.reverse()
13
+
14
+ ###
15
+ Split array into slices of <number> elements.
16
+ Map result by iterator if last given.
17
+
18
+ >>> eachSlice [1..10], 3, (a) -> cout a
19
+ [1, 2, 3]
20
+ [4, 5, 6]
21
+ [7, 8, 9]
22
+ [10]
23
+ ###
24
+ @eachSlice = (array, number, iterator = null) =>
25
+ size = array.length
26
+ index = 0
27
+ slices = []
28
+ while index < size
29
+ nextIndex = index + number
30
+ slices.push array.slice(index, nextIndex)
31
+ index = nextIndex
32
+ if _.isFunction iterator then _.map slices, iterator else slices
33
+
34
+ ###
35
+ Splits or iterates over the array in groups of size +number+,
36
+ padding any remaining slots with +fill_with+ unless it is +false+.
37
+
38
+ >>> inGroupsOf [1..7], 3, (group) -> cout group
39
+ [1, 2, 3]
40
+ [4, 5, 6]
41
+ [7, null, null]
42
+
43
+ >>> inGroupsOf [1..3], 2, '&nbsp;', (group) -> cout group
44
+ [1, 2]
45
+ [3, "&nbsp;"]
46
+
47
+ >>> inGroupsOf [1..3], 2, false, (group) -> cout group
48
+ [1, 2]
49
+ [3]
50
+ ###
51
+ @inGroupsOf = (array, number, fillWith = null) =>
52
+ return array if number < 1
53
+ iterator = @blockGiven arguments
54
+ unless fillWith is false
55
+ # size % number gives how many extra we have;
56
+ # subtracting from number gives how many to add;
57
+ # modulo number ensures we don't add group of just fill.
58
+ padding = (number - array.length % number) % number
59
+ if padding
60
+ fillWith = null if _.isFunction fillWith
61
+ array = array.slice()
62
+ array.push fillWith while padding-- > 0
63
+ @eachSlice array, number, iterator
@@ -0,0 +1,63 @@
1
+
2
+ @is_uri = (path) ->
3
+ /^[-a-z]+:\/\/|^cid:|^\/\//.test path
4
+
5
+ @without_extension = (source) ->
6
+ source.replace /^(.+)(\.\w+)$/, '$1'
7
+
8
+ @rewrite_extension = (source, ext) =>
9
+ "#{@without_extension source}.#{ext}"
10
+
11
+ @ASSET_ID = ''
12
+ @asset_ids_cache = {}
13
+ # Use the ASSET_ID inscope variable or the random hash as its cache-busting asset id.
14
+ @asset_id = (source) =>
15
+ if _.isString @ASSET_ID
16
+ @ASSET_ID
17
+ else
18
+ @asset_ids_cache[source] or (@asset_ids_cache[source] = 10000000 + Math.floor(Math.random() * 90000000))
19
+
20
+ # Break out the asset path rewrite in case plugins wish to put the asset id
21
+ # someplace other than the query string.
22
+ @rewrite_asset_path = (source, dir) =>
23
+ source = "/#{dir}/#{source}" unless source[0] is '/'
24
+ if id = @asset_id(source)
25
+ "#{source}?#{id}"
26
+ else
27
+ source
28
+
29
+ @rewrite_relative_url_root = (source, relative_url_root) ->
30
+ if relative_url_root and not _.startsWith(source, "#{relative_url_root}/")
31
+ "#{relative_url_root}#{source}"
32
+ else
33
+ source
34
+
35
+ @RELATIVE_URL_ROOT = ''
36
+
37
+ @compute_public_path = (source, dir, options = {}) =>
38
+ return source if is_uri(source)
39
+ source = @rewrite_extension(source, options['ext']) if options['ext']
40
+ source = @rewrite_asset_path(source, dir)
41
+ source = @rewrite_relative_url_root(source, @RELATIVE_URL_ROOT)
42
+ source
43
+
44
+ @image_path = (source) =>
45
+ @compute_public_path(source, 'images')
46
+
47
+ @path_to_image = @image_path # aliased to avoid conflicts with an image_path named route
48
+
49
+ @basename = (source) =>
50
+ source = matches[2] if matches = source.match /^(.*\/)?(.+)?$/
51
+
52
+ @image_alt = (src) =>
53
+ _.capitalize @without_extension(@basename(src))
54
+
55
+ @image_tag = (source, options = {}) =>
56
+ src = options['src'] = @path_to_image source
57
+ unless options['alt'] or /^cid:/.test src
58
+ options['alt'] = @image_alt(src)
59
+ if size = _delete(options, 'size')
60
+ if matches = size.match /^(\d+)x(\d+)$/
61
+ options['width'] = matches[1]
62
+ options['height'] = matches[2]
63
+ tag 'img', options
@@ -0,0 +1,14 @@
1
+ @g_decor_body = (tag, inner) =>
2
+ @content_tag(tag, '', class: 'left') +
3
+ @content_tag(tag, '', class: 'right') +
4
+ @content_tag(tag, inner, class: 'fill')
5
+
6
+ @g_star_decor_body = (tag, inner) =>
7
+ @content_tag(tag, inner, class: 'wrapper') +
8
+ @content_tag(tag, '', class: 'corner left top') +
9
+ @content_tag(tag, '', class: 'corner right top') +
10
+ @content_tag(tag, '', class: 'corner left bottom') +
11
+ @content_tag(tag, '', class: 'corner right bottom')
12
+
13
+ @g_wrapper_decor_body = (tag, inner) =>
14
+ @content_tag tag, inner, class: 'wrapper'
@@ -0,0 +1,70 @@
1
+ # The DOM class convention is to use the singular form of an object or class. Examples:
2
+ #
3
+ # dom_class(post) # => "post"
4
+ # dom_class(Person) # => "person"
5
+ #
6
+ # If you need to address multiple instances of the same class in the same view, you can prefix the dom_class:
7
+ #
8
+ # dom_class(post, :edit) # => "edit_post"
9
+ # dom_class(Person, :edit) # => "edit_person"
10
+ @dom_class = (record_or_class, prefix = "") ->
11
+ singular = _.singular(record_or_class)
12
+ if prefix then "#{prefix}_#{singular}" else singular
13
+
14
+ # The DOM id convention is to use the singular form of an object or class with the id following an underscore.
15
+ # If no id is found, prefix with "new_" instead. Examples:
16
+ #
17
+ # dom_id(Post.find(45)) # => "post_45"
18
+ # dom_id(Post.new) # => "new_post"
19
+ #
20
+ # If you need to address multiple instances of the same class in the same view, you can prefix the dom_id:
21
+ #
22
+ # dom_id(Post.find(45), :edit) # => "edit_post_45"
23
+ # TODO sync with rorId and ror_id
24
+ @dom_id = (record, prefix = "") =>
25
+ if record_id = @record_key_for_dom_id(record)
26
+ "#{@dom_class(record, prefix)}_#{record_id}"
27
+ else
28
+ @dom_class(record, prefix or "new")
29
+
30
+ @record_key_for_dom_id = (record) ->
31
+ record = record.to_model() if _.isFunction(record.to_model)
32
+ key = record.to_key()
33
+ if key then key.join("_") else key
34
+
35
+ # TODO more zen features: +, *x, {content}
36
+ # TODO cache
37
+ @selectorToHtml = (selector) =>
38
+ if matches = selector.match(/^[\s>]*([\w\.]+)(.*)$/)
39
+ selector = matches[1]
40
+ continuation = matches[2]
41
+ classes = selector.split(".")
42
+ tag_name = classes.shift() or "div"
43
+ html_options = {}
44
+ html_options["class"] = classes.join(" ") if classes.length
45
+ if continuation
46
+ @content_tag(tag_name, @selectorToHtml(continuation), html_options)
47
+ else
48
+ @tag(tag_name, html_options)
49
+ else
50
+ ""
51
+
52
+ @concat_class = =>
53
+ @warning "concat_class()", "refactoring with underscore"
54
+ @uniq(@compact(arguments).join(" ").split(/\s+/)).join(" ")
55
+
56
+ @html_options_to_s = (html_options) =>
57
+ if $.isPlainObject(html_options)
58
+ (" #{key}=\"#{value}\"" for key, value of html_options when typeof value isnt "undefined").join("")
59
+ else
60
+ ""
61
+
62
+ @tag = (tag_name, html_options = {}) =>
63
+ "<#{tag_name}#{@html_options_to_s html_options} />"
64
+
65
+ @content_tag = (tag_name, content, html_options) =>
66
+ "<#{tag_name}#{@html_options_to_s html_options}>#{content}</#{tag_name}>"
67
+
68
+ @link_to = (body, url, html_options = {}) =>
69
+ html_options["href"] = url
70
+ @content_tag("a", body, html_options)
@@ -0,0 +1,149 @@
1
+ ###
2
+ * front-end js helpers
3
+ * 0.3.3.alpha / 2010-2011
4
+ * Karpunin Dmitry / Evrone.com
5
+ * koderfunk_at_gmail_dot_com
6
+ ###
7
+
8
+ @DEBUG_MODE ?= false
9
+ @TEST_MODE ?= false
10
+ @WARNINGS ?= true
11
+
12
+ @cout = =>
13
+ args = @args arguments
14
+ method = if args[0] in ['log', 'info', 'warn', 'error', 'assert', 'clear'] then args.shift() else 'log'
15
+ if @DEBUG_MODE and console?
16
+ method = console[method]
17
+ if method.apply?
18
+ method.apply console, args
19
+ else
20
+ method args
21
+ return args[0]
22
+
23
+ @_cout = =>
24
+ console.log arguments if console?
25
+ arguments[0]
26
+
27
+ @deprecate = (subject, instead = null) =>
28
+ @cout 'warn', "\"#{subject}\" DEPRECATED!" + if instead then " Use instead: \"#{instead}\"" else ''
29
+ return
30
+
31
+ @warning = (subject, instead = null) =>
32
+ if @WARNINGS
33
+ @cout 'warn', "\"#{subject}\" WARNING!" + if instead then " Use instead: \"#{instead}\"" else ''
34
+ return
35
+
36
+ @args = (a) ->
37
+ r = []
38
+ Array::push.apply r, a if a.length > 0
39
+ r
40
+
41
+ @blockGiven = (args) =>
42
+ l = args.length
43
+ if l
44
+ l = args[l - 1]
45
+ if _.isFunction l then l else false
46
+ else
47
+ false
48
+
49
+ @_delete = (object, key) ->
50
+ value = object[key]
51
+ delete object[key]
52
+ value
53
+
54
+ # Helper function to get a value from a object as a property or as a function.
55
+ @getValue = (object, prop) ->
56
+ return null unless object and object[prop]
57
+ return if _.isFunction(object[prop]) then object[prop]() else object[prop]
58
+
59
+ @isset = (obj) =>
60
+ @deprecate 'isset(obj)', 'obj isnt undefined" OR "obj?'
61
+ obj isnt undefined
62
+
63
+ @isString = (v) =>
64
+ @deprecate 'isString(v)', '_.isString v'
65
+ _.isString v
66
+
67
+ @isNumber = (v) =>
68
+ @deprecate 'isNumber(v)', '_.isNumber v'
69
+ not isNaN parseInt v
70
+
71
+ @isJQ = (obj) ->
72
+ @deprecate 'isJQ(obj)', 'obj instanceof jQuery'
73
+ _.isObject(obj) and _.isString obj.jquery
74
+
75
+ @uniq = (arrOrString) ->
76
+ @deprecate 'uniq(a)', '_.uniq a'
77
+ isStr = _.isString arrOrString
78
+ return arrOrString unless isStr or _.isArray arrOrString
79
+ r = []
80
+ r.push e for e in arrOrString when not _.include r, e
81
+ if isStr then r.join '' else r
82
+
83
+ @logicalXOR = (a, b) ->
84
+ ( a and not b ) or ( not a and b )
85
+
86
+ @bound = (number, min, max) ->
87
+ Math.max min, Math.min number, max
88
+
89
+ @roundWithPrecision = (number, precision = 2) ->
90
+ precision = Math.pow 10, precision
91
+ Math.round(number * precision) / precision
92
+
93
+ @regexpSpace = new RegExp '^\\s*$'
94
+ @regexpTrim = new RegExp '^\\s*(.*?)\\s*$'
95
+
96
+ @strTrim = (s) =>
97
+ @deprecate "strTrim(s)", "$.trim(s)"
98
+ s.match(@regexpTrim)[1]
99
+
100
+ # !!!!!!!!!!! tags !!!!!!!!!!!!
101
+
102
+ @number_to_currency = (number, units) ->
103
+ precision = 2
104
+ s = parseFloat(number).toFixed precision
105
+ b = s.length - 1 - precision
106
+ r = s.substring b
107
+ while b > 0
108
+ a = b - 3
109
+ r = ' ' + s.substring(a, b) + r
110
+ b = a
111
+ "#{r.substring(1)} #{units}"
112
+
113
+
114
+
115
+ @getParams = ->
116
+ q = location.search.substring(1).split '&'
117
+ r = {}
118
+ for e in q
119
+ t = e.split '='
120
+ r[t[0]] = t[1]
121
+ r
122
+
123
+ @respondFormat = (url, format = null) ->
124
+ aq = url.split '?'
125
+ ah = aq[0].split '#'
126
+ ad = ah[0].split '.'
127
+ currentFormat = if ad.length > 1 and not /\//.test(ad[ad.length - 1]) then ad.pop() else ''
128
+ return currentFormat unless format?
129
+ return url if format is currentFormat
130
+ ad.push format if format
131
+ ah[0] = ad.join '.'
132
+ aq[0] = ah.join '#'
133
+ aq.join '?'
134
+
135
+
136
+
137
+ @rails_data = {}
138
+
139
+ @rails_scope = (controller_name, action_name, scopedCloasure = null, scopedCloasureArguments...) =>
140
+ return false if _.isString(controller_name) and controller_name isnt @rails_data['controller_name']
141
+ return false if _.isString(action_name) and action_name isnt @rails_data['action_name']
142
+ if _.isFunction scopedCloasure
143
+ arguments[2] scopedCloasureArguments...
144
+ true
145
+
146
+
147
+
148
+ $ =>
149
+ @rails_data = $('body').data()
@@ -0,0 +1,34 @@
1
+
2
+ @unlazy_datepickers = (jRoot) ->
3
+ jRoot.find('input.datepicker.lazy').removeClass('lazy').length
4
+
5
+ @bind_datepickers = (jRoot) ->
6
+ jRoot.find('input.datepicker:not(.lazy, .hasDatepicker)').each( ->
7
+ jThis = $ @
8
+ opts =
9
+ 'showAnim' : ''
10
+ 'showOn' : 'both'
11
+ 'buttonImage' : '/images/forms/datepicker__icon.png' # TODO forwarding assets path
12
+ 'buttonImageOnly': true
13
+ 'changeMonth' : true
14
+ 'changeYear' : true
15
+ 'onClose' : (dateText, inst) -> $(inst.input).change().focusout()
16
+ opts[_.camelize(k)] = d for k, d of jThis.data()
17
+ jThis.datepicker opts
18
+ ).length
19
+
20
+ $.fn.orig_datepicker = $.fn.datepicker
21
+
22
+ $.fn.datepicker = ->
23
+ return @ unless @length
24
+ @data('changed', true) if arguments.length and arguments[0] is 'setDate'
25
+ $.fn.orig_datepicker.apply @, arguments
26
+
27
+
28
+
29
+ $ ->
30
+
31
+ $('body').on 'keyup keydown', 'input.datepicker.hasDatepicker', ->
32
+ $(@).datepicker 'hide'
33
+
34
+ bind_datepickers $('body')