joosy 0.1.0.RC2 → 0.1.0.RC3
Sign up to get free protection for your applications and to get access to all the features.
- data/.codoopts +5 -0
- data/.gitignore +2 -0
- data/Gemfile.lock +4 -2
- data/README.md +10 -4
- data/app/assets/javascripts/joosy/core/application.js.coffee +3 -1
- data/app/assets/javascripts/joosy/core/form.js.coffee +69 -42
- data/app/assets/javascripts/joosy/core/helpers/view.js.coffee +30 -0
- data/app/assets/javascripts/joosy/core/joosy.js.coffee +125 -66
- data/app/assets/javascripts/joosy/core/layout.js.coffee +106 -1
- data/app/assets/javascripts/joosy/core/modules/container.js.coffee +41 -0
- data/app/assets/javascripts/joosy/core/modules/events.js.coffee +88 -1
- data/app/assets/javascripts/joosy/core/modules/filters.js.coffee +24 -0
- data/app/assets/javascripts/joosy/core/modules/log.js.coffee +18 -0
- data/app/assets/javascripts/joosy/core/modules/module.js.coffee +53 -1
- data/app/assets/javascripts/joosy/core/modules/renderer.js.coffee +22 -6
- data/app/assets/javascripts/joosy/core/modules/time_manager.js.coffee +21 -0
- data/app/assets/javascripts/joosy/core/modules/widgets_manager.js.coffee +26 -0
- data/app/assets/javascripts/joosy/core/page.js.coffee +225 -16
- data/app/assets/javascripts/joosy/core/preloader.js.coffee +8 -0
- data/app/assets/javascripts/joosy/core/resource/collection.js.coffee +52 -15
- data/app/assets/javascripts/joosy/core/resource/generic.js.coffee +78 -50
- data/app/assets/javascripts/joosy/core/resource/rest.js.coffee +39 -41
- data/app/assets/javascripts/joosy/core/resource/rest_collection.js.coffee +36 -27
- data/app/assets/javascripts/joosy/core/router.js.coffee +95 -19
- data/app/assets/javascripts/joosy/core/widget.js.coffee +42 -1
- data/app/assets/javascripts/joosy/preloaders/caching.js.coffee +39 -24
- data/app/assets/javascripts/joosy/preloaders/inline.js.coffee +9 -7
- data/app/helpers/joosy/sprockets_helper.rb +4 -1
- data/lib/joosy/rails/version.rb +1 -1
- data/spec/javascripts/joosy/core/application_spec.js.coffee +3 -3
- data/spec/javascripts/joosy/core/resource/rest_spec.js.coffee +0 -2
- data/spec/javascripts/joosy/core/router_spec.js.coffee +24 -24
- data/vendor/assets/javascripts/jquery.form.js +978 -963
- data/vendor/assets/javascripts/sugar.js +1 -1
- metadata +20 -20
- data/app/assets/javascripts/joosy/core/helpers.js.coffee +0 -16
- data/vendor/assets/javascripts/base64.js +0 -135
data/.codoopts
ADDED
data/Gemfile.lock
CHANGED
@@ -19,7 +19,7 @@ GIT
|
|
19
19
|
PATH
|
20
20
|
remote: .
|
21
21
|
specs:
|
22
|
-
joosy (0.1.0.
|
22
|
+
joosy (0.1.0.RC2)
|
23
23
|
coffee-rails
|
24
24
|
haml_coffee_assets
|
25
25
|
jquery-rails
|
@@ -70,6 +70,7 @@ GEM
|
|
70
70
|
diff-lcs (1.1.3)
|
71
71
|
erubis (2.7.0)
|
72
72
|
eventmachine (0.12.10)
|
73
|
+
eventmachine (0.12.10-java)
|
73
74
|
execjs (1.3.0)
|
74
75
|
multi_json (~> 1.0)
|
75
76
|
ffi (1.0.11)
|
@@ -80,7 +81,7 @@ GEM
|
|
80
81
|
guard-coffeescript (0.5.4)
|
81
82
|
coffee-script (>= 2.2.0)
|
82
83
|
guard (>= 0.8.3)
|
83
|
-
haml_coffee_assets (0.
|
84
|
+
haml_coffee_assets (0.8.2)
|
84
85
|
execjs (>= 1.2.9)
|
85
86
|
sprockets (>= 2.0.3)
|
86
87
|
tilt (>= 1.3.3)
|
@@ -92,6 +93,7 @@ GEM
|
|
92
93
|
railties (>= 3.2.0.beta, < 5.0)
|
93
94
|
thor (~> 0.14)
|
94
95
|
json (1.6.5)
|
96
|
+
json (1.6.5-java)
|
95
97
|
mail (2.4.1)
|
96
98
|
i18n (>= 0.4.0)
|
97
99
|
mime-types (~> 1.16)
|
data/README.md
CHANGED
@@ -38,13 +38,13 @@ Unlike server-side, client-side has a state. At server-side you only have incomi
|
|
38
38
|
|
39
39
|
They are:
|
40
40
|
|
41
|
-
|
41
|
+
###### Pages
|
42
42
|
Pages are the heart of the entire application. They are used to fetch data, bind events, setup widgets, trig visual effects, and pass the data to the templates.
|
43
43
|
|
44
|
-
|
44
|
+
###### Layouts
|
45
45
|
Layouts are mainly used to set a part of your page that won't be reloaded often. Pages are wrapped into Layouts. Just like pages Layouts can bind events and setup widgets. Consider layouts as a bit extended version of what you have in Rails.
|
46
46
|
|
47
|
-
|
47
|
+
###### Widgets
|
48
48
|
Widgets are needed to keep your code DRY. They help you organize it in reusable modules.
|
49
49
|
|
50
50
|
#### Models
|
@@ -73,10 +73,14 @@ Compare Joosy to Backbone like Rails to Sinatra. While Rails engine is much more
|
|
73
73
|
|
74
74
|
## What's next?
|
75
75
|
|
76
|
-
We have a set of guidelines showing you, step-by-step, how to create a Joosy application.
|
76
|
+
We have a set of guidelines showing you, step-by-step, how to create a Joosy application. Follow them at our [Guides site](http://guides.joosy.ws/).
|
77
77
|
|
78
78
|
### Hello world app
|
79
79
|
|
80
|
+
Add Joosy gem to your Gemfile:
|
81
|
+
|
82
|
+
gem 'joosy'
|
83
|
+
|
80
84
|
Using built-in generators you can quickly generate small app inside your Rails app to see Joosy application from inside a bit.
|
81
85
|
|
82
86
|
rails g joosy:application dummy
|
@@ -84,6 +88,8 @@ Using built-in generators you can quickly generate small app inside your Rails a
|
|
84
88
|
|
85
89
|
Now you can `rails s` and see Joosy placeholder at [localhost:3000/dummy](http://localhost:3000/dummy)
|
86
90
|
|
91
|
+
Generated application will consist of one `Layout` and one `Page` both including very basic practices of Joosy.
|
92
|
+
|
87
93
|
# License
|
88
94
|
|
89
95
|
Joosy is licensed under MIT: [www.opensource.org/licenses/MIT](www.opensource.org/licenses/MIT)
|
@@ -7,6 +7,8 @@ Joosy.Application =
|
|
7
7
|
Pages: {}
|
8
8
|
Layouts: {}
|
9
9
|
Controls: {}
|
10
|
+
|
11
|
+
loading: true
|
10
12
|
|
11
13
|
#
|
12
14
|
# Starts Joosy application by binding to element and bootstraping routes
|
@@ -19,7 +21,7 @@ Joosy.Application =
|
|
19
21
|
@[key] = value for key, value of options
|
20
22
|
@templater = new Joosy.Templaters.RailsJST @name
|
21
23
|
|
22
|
-
Joosy.Router.
|
24
|
+
Joosy.Router.__setupRoutes()
|
23
25
|
|
24
26
|
@sandboxSelector = Joosy.uuid()
|
25
27
|
@content().after "<div id='#{@sandboxSelector}' style='display:none'></div>"
|
@@ -5,20 +5,19 @@
|
|
5
5
|
#= require joosy/core/modules/container
|
6
6
|
|
7
7
|
#
|
8
|
-
# AJAXifies form including file uploads and stuff. Built on top of jQuery.Form
|
8
|
+
# AJAXifies form including file uploads and stuff. Built on top of jQuery.Form.
|
9
9
|
#
|
10
10
|
# Joosy.Form automatically cares of form validation hihglights. It can
|
11
11
|
# read common server error responses and add .field_with_errors class to proper
|
12
12
|
# field.
|
13
13
|
#
|
14
|
-
# If you don't have resource associated (#fill)
|
14
|
+
# If you don't have resource associated with form (#fill), it will try to find fields
|
15
15
|
# by exact keywords from response. Otherwise it will search for resource_name[field].
|
16
16
|
#
|
17
|
-
#
|
18
|
-
# Example
|
17
|
+
# @example Joosy.Form usage
|
19
18
|
# form = new Joosy.Form, -> (response)
|
20
19
|
# console.log "Saved and got some: #{response}"
|
21
|
-
#
|
20
|
+
#
|
22
21
|
# form.progress = (percent) -> console.log "Uploaded by #{percent}%"
|
23
22
|
# form.fill @resource
|
24
23
|
#
|
@@ -47,10 +46,12 @@ class Joosy.Form extends Joosy.Module
|
|
47
46
|
'fields': 'input,select,textarea'
|
48
47
|
|
49
48
|
#
|
50
|
-
#
|
49
|
+
# Makes one AJAX request with form data without binding
|
50
|
+
#
|
51
|
+
# @see #constructor
|
51
52
|
#
|
52
53
|
# @param [Element] form Instance of HTML form element
|
53
|
-
# @param [
|
54
|
+
# @param [Hash] opts Options
|
54
55
|
#
|
55
56
|
@submit: (form, opts={}) ->
|
56
57
|
form = new @(form, opts)
|
@@ -61,30 +62,30 @@ class Joosy.Form extends Joosy.Module
|
|
61
62
|
#
|
62
63
|
# During initialization replaces your basic form submit with AJAX request
|
63
64
|
#
|
64
|
-
# If method of form differs from POST or GET it will simulate it
|
65
|
+
# @note If method of form differs from POST or GET it will simulate it
|
65
66
|
# by adding hidden _method input. In this cases the method itself will be
|
66
67
|
# set to POST.
|
67
68
|
#
|
68
|
-
# For browsers having no support of HTML5 Forms it may do an iframe requests
|
69
|
+
# @note For browsers having no support of HTML5 Forms it may do an iframe requests
|
69
70
|
# to handle file uploading.
|
70
71
|
#
|
71
|
-
#
|
72
|
+
# @param [jQuery] form Form element instance
|
73
|
+
# @param [Hash] opts Options
|
72
74
|
#
|
73
|
-
#
|
75
|
+
# @option opts [Function] before `(XHR) -> Bollean` to trigger right before submit.
|
74
76
|
# By default will run form invalidation cleanup. This behavior can be canceled
|
75
77
|
# by returning false from your own before callback. Both of callbacks will run if
|
76
78
|
# you return true.
|
77
79
|
#
|
78
|
-
#
|
79
|
-
# in the parsed JSON.
|
80
|
+
# @option opts [Function] success `(Object) -> null` triggers on 200 HTTP code from server.
|
81
|
+
# Pases in the parsed JSON.
|
80
82
|
#
|
81
|
-
#
|
83
|
+
# @option opts [Function] progress `(Float) -> null` runs periodically while form is uploading
|
82
84
|
#
|
83
|
-
#
|
85
|
+
# @option opts [Function] error `(Object) -> Boolean` triggers if server responded with anything but 200.
|
84
86
|
# By default will run form invalidation routine. This behavior can be canceled
|
85
87
|
# by returning false from your own error callback. Both of callbacks will run if
|
86
88
|
# you return true.
|
87
|
-
#
|
88
89
|
#
|
89
90
|
constructor: (form, opts={}) ->
|
90
91
|
if Object.isFunction opts
|
@@ -119,15 +120,14 @@ class Joosy.Form extends Joosy.Module
|
|
119
120
|
xhr
|
120
121
|
|
121
122
|
#
|
122
|
-
# Resets form submit behavior
|
123
|
+
# Resets form submit behavior to default
|
123
124
|
#
|
124
125
|
unbind: ->
|
125
126
|
@container.unbind('submit').find('input:submit,input:image,button:submit').unbind('click');
|
126
127
|
|
127
128
|
#
|
128
|
-
#
|
129
|
-
# Form will
|
130
|
-
# invalidation routine.
|
129
|
+
# Links current form with given resource and sets values of form inputs from with it.
|
130
|
+
# Form will use give resource while doing invalidation routine.
|
131
131
|
#
|
132
132
|
# @param [Resource] resource Resource to fill fields with
|
133
133
|
# @param [Function] decorator Decoration callback
|
@@ -155,7 +155,26 @@ class Joosy.Form extends Joosy.Module
|
|
155
155
|
@container.attr 'method', 'POST'
|
156
156
|
|
157
157
|
#
|
158
|
-
#
|
158
|
+
# Submit the HTML Form
|
159
|
+
#
|
160
|
+
submit: ->
|
161
|
+
@container.submit()
|
162
|
+
|
163
|
+
#
|
164
|
+
# Serializes form into query string.
|
165
|
+
#
|
166
|
+
# @param [Boolean] skipMethod Determines if we should skip magical _method field
|
167
|
+
#
|
168
|
+
# @return [String]
|
169
|
+
#
|
170
|
+
serialize: (skipMethod=true) ->
|
171
|
+
data = @container.serialize()
|
172
|
+
data = data.replace /\&?\_method\=put/i, '' if skipMethod
|
173
|
+
|
174
|
+
data
|
175
|
+
|
176
|
+
#
|
177
|
+
# Inner success callback.
|
159
178
|
#
|
160
179
|
__success: (response, status, xhr) ->
|
161
180
|
if xhr
|
@@ -166,16 +185,16 @@ class Joosy.Form extends Joosy.Module
|
|
166
185
|
@__error response.json
|
167
186
|
|
168
187
|
#
|
169
|
-
# Inner before callback
|
170
|
-
# By default will clean invalidation
|
188
|
+
# Inner before callback.
|
189
|
+
# By default will clean invalidation.
|
171
190
|
#
|
172
191
|
__before: (xhr, settings) ->
|
173
192
|
if !@before? || @before(arguments...) is true
|
174
193
|
@fields.removeClass @invalidationClass
|
175
194
|
|
176
195
|
#
|
177
|
-
# Inner error callback
|
178
|
-
# By default will trigger basic invalidation
|
196
|
+
# Inner error callback.
|
197
|
+
# By default will trigger basic invalidation.
|
179
198
|
#
|
180
199
|
__error: (data) ->
|
181
200
|
errors = if data.responseText
|
@@ -190,8 +209,18 @@ class Joosy.Form extends Joosy.Module
|
|
190
209
|
errors = @__stringifyErrors(errors)
|
191
210
|
|
192
211
|
Object.each errors, (field, notifications) =>
|
193
|
-
input = @
|
212
|
+
input = @__findField(field).addClass @invalidationClass
|
194
213
|
@notification? input, notifications
|
214
|
+
|
215
|
+
#
|
216
|
+
# Finds field by field name.
|
217
|
+
# This is not inlined since we want to override
|
218
|
+
# or monkeypatch it from time to time
|
219
|
+
#
|
220
|
+
# @param [String] field Name of field to find
|
221
|
+
#
|
222
|
+
__findField: (field) ->
|
223
|
+
@fields.filter("[name='#{field}']")
|
195
224
|
|
196
225
|
#
|
197
226
|
# Simulates REST methods by adding hidden _method input with real method
|
@@ -212,24 +241,20 @@ class Joosy.Form extends Joosy.Module
|
|
212
241
|
# Turns all possible response notations into form notation (foo[bar])
|
213
242
|
# Every direct field of incoming data will be decorated by @substitutions
|
214
243
|
#
|
215
|
-
#
|
216
|
-
#
|
217
|
-
#
|
218
|
-
# #
|
219
|
-
# { field1: ['error'] }
|
220
|
-
# # if form was not associated with @__resource (see #fill)
|
221
|
-
# { "field1": ['error'] }
|
222
|
-
# # if form was associated with resource (named fluffy)
|
223
|
-
# { "fluffy[field1]": ['error']}
|
244
|
+
# @example Flat validation result
|
245
|
+
# { field1: ['error'] } # input
|
246
|
+
# { field1: ['error'] } # if form was not associated with Resource by {#fill}
|
247
|
+
# { "fluffy[field1]": ['error']} # if form was associated with Resource (named fluffy)
|
224
248
|
#
|
225
|
-
#
|
226
|
-
# # input
|
227
|
-
# { foo
|
228
|
-
# # output
|
229
|
-
# { "foo[bar][bar]": ['error'] }
|
249
|
+
# @example Complex validation result
|
250
|
+
# { foo: { bar: { baz: ['error'] } } } # input
|
251
|
+
# { "foo[bar][bar]": ['error'] } # output
|
230
252
|
#
|
231
253
|
# @param [Object] errors Data to prepare
|
232
254
|
#
|
255
|
+
# @return [Hash<String, Array>] Flat hash with field names in keys and arrays
|
256
|
+
# of errors in values
|
257
|
+
#
|
233
258
|
__stringifyErrors: (errors) ->
|
234
259
|
result = {}
|
235
260
|
|
@@ -257,16 +282,18 @@ class Joosy.Form extends Joosy.Module
|
|
257
282
|
#
|
258
283
|
# Flattens complex inline structures into form notation
|
259
284
|
#
|
260
|
-
#
|
285
|
+
# @example Basic flattening
|
261
286
|
# data = foo: { bar: { baz: [] } }
|
262
287
|
# inner = @__foldInlineEntities(data.foo, 'foo')
|
263
|
-
#
|
288
|
+
#
|
264
289
|
# inner # { "foo[bar][baz]": [] }
|
265
290
|
#
|
266
291
|
# @param [Object] hash Structure to fold
|
267
292
|
# @param [String] scope Prefix for resulting scopes
|
268
293
|
# @param [Object] result Context of result for recursion
|
269
294
|
#
|
295
|
+
# @return [Hash]
|
296
|
+
#
|
270
297
|
__foldInlineEntities: (hash, scope="", result={}) ->
|
271
298
|
Object.each hash, (key, value) =>
|
272
299
|
if Object.isObject(value)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#= require joosy/core/joosy
|
2
|
+
|
3
|
+
#
|
4
|
+
# Rendering and string representation helpers
|
5
|
+
#
|
6
|
+
Joosy.helpers 'Application', ->
|
7
|
+
|
8
|
+
#
|
9
|
+
# Converts \n into <br/> in your text
|
10
|
+
#
|
11
|
+
# @param [String] text Text to convert
|
12
|
+
#
|
13
|
+
@nl2br = (text) ->
|
14
|
+
text.toString().replace /\n/g, '<br/>'
|
15
|
+
|
16
|
+
#
|
17
|
+
# Wraps the inline block into given template
|
18
|
+
# Request template will receive the inline block as @yield parameter
|
19
|
+
#
|
20
|
+
# Example
|
21
|
+
# -# foo/baz template
|
22
|
+
# != @renderWrapped 'foo/bar', ->
|
23
|
+
# %b This string will be passed to 'foo/bar'
|
24
|
+
#
|
25
|
+
# -# foo/bar template
|
26
|
+
# %h1 I'm the wrapper here!
|
27
|
+
# != @yield
|
28
|
+
#
|
29
|
+
@renderWrapped = (template, lambda) ->
|
30
|
+
@render template, Joosy.Module.merge(this, yield: lambda())
|
@@ -1,70 +1,129 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
#
|
2
|
+
# All the tiny core stuff
|
3
|
+
#
|
4
|
+
# @module
|
5
|
+
#
|
6
|
+
@Joosy =
|
7
|
+
#
|
8
|
+
# Core modules container
|
9
|
+
#
|
3
10
|
Modules: {}
|
11
|
+
|
12
|
+
#
|
13
|
+
# Resources container
|
14
|
+
#
|
4
15
|
Resource: {}
|
16
|
+
|
17
|
+
#
|
18
|
+
# Templaters container
|
19
|
+
#
|
5
20
|
Templaters: {}
|
6
21
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
22
|
+
#
|
23
|
+
# If enabled Joosy will log to console a lot of 'in progress' stuff
|
24
|
+
#
|
25
|
+
debug: false
|
26
|
+
|
27
|
+
#
|
28
|
+
# Registeres anything inside specified namespace (objects chain starting from `window`)
|
29
|
+
#
|
30
|
+
# @example Basic usage
|
31
|
+
# Joosy.namespace 'foobar', ->
|
32
|
+
# class @RealThing
|
33
|
+
#
|
34
|
+
# foo = new foobar.RealThing
|
35
|
+
#
|
36
|
+
# @param [String] name Namespace keyword
|
37
|
+
# @param [Boolean] generator Namespace content
|
38
|
+
#
|
39
|
+
namespace: (name, generator=false) ->
|
40
|
+
name = name.split '.'
|
41
|
+
space = window
|
42
|
+
for part in name
|
43
|
+
space = space[part] ?= {}
|
44
|
+
|
45
|
+
if generator
|
46
|
+
generator = generator.apply space
|
47
|
+
for key, klass of space
|
48
|
+
if space.hasOwnProperty(key) &&
|
49
|
+
Joosy.Module.hasAncestor klass, Joosy.Module
|
50
|
+
klass.__namespace__ = name
|
51
|
+
|
52
|
+
#
|
53
|
+
# Registeres given methods as a helpers inside a given set
|
54
|
+
#
|
55
|
+
# @param [String] name Helpers set keyword
|
56
|
+
# @param [Boolean] generator Helpers content
|
57
|
+
#
|
58
|
+
helpers: (name, generator) ->
|
59
|
+
Joosy.namespace "Joosy.Helpers.#{name}", generator
|
60
|
+
|
61
|
+
#
|
62
|
+
# Scary `hello world`
|
63
|
+
#
|
64
|
+
test: ->
|
65
|
+
text = "Hi :). I'm Joosy. And everything is just fine!"
|
66
|
+
|
67
|
+
if console
|
68
|
+
console.log text
|
69
|
+
else
|
70
|
+
alert text
|
71
|
+
|
72
|
+
#
|
73
|
+
# Generates UUID
|
74
|
+
#
|
75
|
+
uuid: ->
|
76
|
+
'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace /[xy]/g, (c) ->
|
77
|
+
r = Math.random() * 16 | 0
|
78
|
+
v = if c is 'x' then r else r & 3 | 8
|
79
|
+
v.toString 16
|
80
|
+
.toUpperCase()
|
81
|
+
|
82
|
+
#
|
83
|
+
# Preloads sets of images then runs callback
|
84
|
+
#
|
85
|
+
# @param [Array<String>] images Images paths
|
86
|
+
# @param [Function] callback Action to run when every picture was loaded (or triggered an error)
|
87
|
+
#
|
88
|
+
preloadImages: (images, callback) ->
|
89
|
+
unless Object.isArray(images)
|
90
|
+
images = [images]
|
91
|
+
if images.length == 0
|
92
|
+
callback()
|
93
|
+
|
94
|
+
ticks = images.length
|
95
|
+
result = []
|
96
|
+
checker = ->
|
97
|
+
if (ticks -= 1) == 0
|
98
|
+
callback?()
|
99
|
+
|
100
|
+
for p in images
|
101
|
+
result.push $('<img/>').load(checker).error(checker).attr('src', p)
|
102
|
+
|
103
|
+
result
|
104
|
+
|
105
|
+
#
|
106
|
+
# Basic URI builder. Joins base path with params hash
|
107
|
+
#
|
108
|
+
# @param [String] url Base url
|
109
|
+
# @param [Hash] params Parameters to join
|
110
|
+
#
|
111
|
+
# @example Basic usage
|
112
|
+
# Joosy.buildUrl 'http://joosy.ws/#!/test', {foo: 'bar'} # http://joosy.ws/?foo=bar#!/test
|
113
|
+
#
|
114
|
+
buildUrl: (url, params) ->
|
115
|
+
paramsString = []
|
116
|
+
|
117
|
+
Object.each params, (key, value) ->
|
118
|
+
paramsString.push "#{key}=#{value}"
|
119
|
+
|
120
|
+
hash = url.match(/(\#.*)?$/)[0]
|
121
|
+
url = url.replace /\#.*$/, ''
|
122
|
+
if !paramsString.isEmpty() && !url.has(/\?/)
|
123
|
+
url = url + "?"
|
124
|
+
|
125
|
+
paramsString = paramsString.join '&'
|
126
|
+
if !paramsString.isBlank() && url.last() != '?'
|
127
|
+
paramsString = '&' + paramsString
|
128
|
+
|
129
|
+
url + paramsString + hash
|