darwinjs-rails 1.1 → 1.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.
- checksums.yaml +7 -0
- data/README.md +108 -31
- data/app/assets/javascripts/darwin/base.coffee +1 -1
- data/app/assets/javascripts/darwin/controller.coffee +5 -2
- data/app/assets/javascripts/darwin/loader.coffee +17 -11
- data/lib/darwinjs/rails/version.rb +1 -1
- metadata +9 -21
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7bd0c876edd561b19225af8ae36ccc113c469ee1
|
4
|
+
data.tar.gz: 5f343991cd9087f3b576447814be7adf2fe4971f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d9f4f59df36f7e34893245fefbd42ccf4e1faee5378c51884774c6e972471f9a94dd9327ba4d40872a02ce6b52d282d09e031cc988f56ee5188d06d549291211
|
7
|
+
data.tar.gz: d5dc3e60ca31e95052a011dd28d5d8203fa3a29ffc2be155a5a9fd54610e3eb25a5ae9952894cef9bf616699c91914f8176f748ee3775c7d718667e2ede044ab
|
data/README.md
CHANGED
@@ -23,6 +23,8 @@ Or install it yourself as:
|
|
23
23
|
|
24
24
|
## Getting Started
|
25
25
|
|
26
|
+
### Autoloader
|
27
|
+
|
26
28
|
First, as one time configuration, add autoloader in your
|
27
29
|
application.coffee file :
|
28
30
|
|
@@ -36,11 +38,14 @@ $(->
|
|
36
38
|
)
|
37
39
|
```
|
38
40
|
|
41
|
+
|
42
|
+
### Generator
|
43
|
+
|
39
44
|
You can now generate a javascript module using the provided
|
40
45
|
generator :
|
41
46
|
|
42
47
|
```
|
43
|
-
$ rails generate
|
48
|
+
$ rails generate darwinjs:assets users/index
|
44
49
|
|
45
50
|
create app/assets/javascripts/controllers/users.coffee
|
46
51
|
create app/assets/javascripts/views/users.coffee
|
@@ -70,28 +75,34 @@ A module is composed of two files :
|
|
70
75
|
* a controller that handles events
|
71
76
|
* a view that handles DOM manipulation
|
72
77
|
|
73
|
-
|
78
|
+
|
79
|
+
### Controller
|
80
|
+
|
81
|
+
The minimal controller you could write is as this :
|
74
82
|
|
75
83
|
```coffee
|
76
|
-
class App.
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
user_block: '#users'
|
81
|
-
user:
|
82
|
-
'sel': '.user'
|
83
|
-
more: '.more a'
|
84
|
-
delete: 'a[data-method="delete"]'
|
85
|
-
}
|
84
|
+
class App.Controllers.MyModule extends Darwin.Controller
|
85
|
+
run: ->
|
86
|
+
alert( 'hello' )
|
87
|
+
```
|
86
88
|
|
87
|
-
|
88
|
-
$link.next( '.info' ).show()
|
89
|
+
And bind it to your html file :
|
89
90
|
|
90
|
-
|
91
|
-
|
91
|
+
```html
|
92
|
+
<div id="my-block" data-module="MyModule"></div>
|
92
93
|
```
|
93
94
|
|
94
|
-
|
95
|
+
With just that, you've already leveraged an important performance tweak from
|
96
|
+
Darwin over `if $('#my_block').length then alert( 'hello' )` : instead of
|
97
|
+
querying the dom on every page of your application to find `#my_block`, a
|
98
|
+
single query will be issued to retrieve `*[data-module]` and initialize their
|
99
|
+
module. Just think of how many DOM queries that returns nothing you fire on
|
100
|
+
your typical page. `$('#not-existing')` does not do nothing, it browses the
|
101
|
+
whole DOM to retrieve a non-existing element. That's a performance issue.
|
102
|
+
|
103
|
+
But a controller can do way more than that. Its whole purpose is to encapsulate
|
104
|
+
interruptions - events and requests.
|
105
|
+
|
95
106
|
|
96
107
|
```coffee
|
97
108
|
class App.Controllers.Users.Index extends Darwin.Controller
|
@@ -120,23 +131,89 @@ class App.Controllers.Users.Index extends Darwin.Controller
|
|
120
131
|
)
|
121
132
|
```
|
122
133
|
|
123
|
-
|
124
|
-
|
134
|
+
Events declaration are grouped in the option hash, with a human readable
|
135
|
+
description, so that any developer can understand at a glance what the
|
136
|
+
controller is doing. An event declaration is typically made of a descriptive
|
137
|
+
string and of configuration object :
|
138
|
+
|
139
|
+
```coffee
|
140
|
+
'Description': { el: 'element_name', type: 'event_type' }
|
141
|
+
```
|
142
|
+
|
143
|
+
The callback method name is inferred from event configuration, using
|
144
|
+
`<element_name>_<event_type>(ed|d)`. The element (extended with jQuery) is
|
145
|
+
passed as first argument, and the raw event is passed as second.
|
146
|
+
|
147
|
+
Beside that, declaring events that way rather than directly with jQuery has a
|
148
|
+
massive advantage : all callback functions are wrapped in a function that will
|
149
|
+
prevent them to run if a crash occurs. It means that if you have a `<a
|
150
|
+
href="/foo"></a>` with a click event on it and a crash occurs, clicking it
|
151
|
+
again will not trigger event, and link will be followed. This ensure you can
|
152
|
+
have fallback features to handle javascript errors and reload the page.
|
153
|
+
|
154
|
+
|
155
|
+
### View
|
156
|
+
|
157
|
+
Finally, views are meant for all DOM manipulation and acts as a single point of
|
158
|
+
configuration for selectors. In previous controller example, we've used element
|
159
|
+
names "show_user", "user_more", "user_delete", "user_block", etc. Very often in
|
160
|
+
a module, you will refer an element more than one time. It means that if your
|
161
|
+
html change, you've got to track all selectors used to find what you have to
|
162
|
+
change.
|
125
163
|
|
126
|
-
|
127
|
-
|
128
|
-
lines of the controller file.
|
164
|
+
This is not a problem with Darwin, as selectors are all configured in the same
|
165
|
+
place, without any repeatition :
|
129
166
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
167
|
+
```coffee
|
168
|
+
class App.Views.Users.Index extends Darwin.View
|
169
|
+
@options {
|
170
|
+
selectors:
|
171
|
+
show_users: 'a#show_users'
|
172
|
+
user_block: '#users'
|
173
|
+
user:
|
174
|
+
'sel': '.user'
|
175
|
+
more: '.more a'
|
176
|
+
delete: 'a[data-method="delete"]'
|
177
|
+
}
|
178
|
+
|
179
|
+
show_info_for( $link ) ->
|
180
|
+
$link.next( '.info' ).show()
|
181
|
+
|
182
|
+
remove_user_for( $link ) ->
|
183
|
+
$link.parent().remove()
|
184
|
+
```
|
185
|
+
|
186
|
+
The `selectors` options hash list all selectors used by module. They can be
|
187
|
+
declared right away or through a 'sel' key, which then allow to use nested
|
188
|
+
selectors. This system also offer a performance bonus : all elements retrieved
|
189
|
+
with these selectors are cached by default, because it's the desired behavior,
|
190
|
+
most of the time (you can pass option `cache: false` to a specific selector not
|
191
|
+
to cache its result). Selectors can be used with `get()` view method :
|
192
|
+
`@get('user_more')`.
|
193
|
+
|
194
|
+
Beside selectors configuration, views are responsible for DOM manipulation. It
|
195
|
+
means that controllers call views upon interuptions to alter page content (like
|
196
|
+
the two methods in previous view, used by previous controller). It also means
|
197
|
+
that views are responsible for setting up and tearing down the page, reflecting
|
198
|
+
progressive enhancement and graceful degradation :
|
199
|
+
|
200
|
+
```coffee
|
201
|
+
class App.Views.MyModule extends Darwin.View
|
202
|
+
@options {
|
203
|
+
selectors:
|
204
|
+
submit: 'input[type="submit"]'
|
205
|
+
}
|
206
|
+
|
207
|
+
run: ->
|
208
|
+
@get( 'submit' ).hide()
|
209
|
+
|
210
|
+
|
211
|
+
destructor: ->
|
212
|
+
@get( 'submit' ).show()
|
213
|
+
```
|
134
214
|
|
135
|
-
|
136
|
-
|
137
|
-
deactivated and any link is followed, reloading the page and letting
|
138
|
-
server side handle what has to be done, so your user doesn't even
|
139
|
-
notice something got wrong.
|
215
|
+
As you would expect, `run()` is called on dom ready event, and `destructor()`
|
216
|
+
is called when a crash occurs.
|
140
217
|
|
141
218
|
Ready for more ? See [introduction](doc/introduction.md).
|
142
219
|
|
@@ -52,9 +52,12 @@ class Darwin.Controller extends Darwin.Base
|
|
52
52
|
if el == 'root'
|
53
53
|
sel = 'root'
|
54
54
|
else
|
55
|
-
sel = ( @view.selectors[ el ] or @view._find_alternate_name( el ) )
|
55
|
+
sel = ( @view.selectors[ el ] or @view._find_alternate_name( el ) )?.sel
|
56
56
|
|
57
|
-
|
57
|
+
if sel
|
58
|
+
$target = $target.parents( sel ).first() unless $target.is( sel )
|
59
|
+
else
|
60
|
+
$target = @view.get( el )
|
58
61
|
|
59
62
|
args = [ $target, event ]
|
60
63
|
args.push arguments[i] for i in [1..(arguments.length - 1)] if arguments.length > 1
|
@@ -6,20 +6,26 @@ errors_got = 0
|
|
6
6
|
loader = Darwin.Loader =
|
7
7
|
run: ->
|
8
8
|
loader.module_roots().each( ( i, $module ) =>
|
9
|
-
$module
|
10
|
-
|
11
|
-
path = $module.attr( 'data-module' ).split( '.' )
|
12
|
-
module = App.Controllers
|
13
|
-
module = module[ path.shift() ] while path.length
|
14
|
-
|
15
|
-
if module
|
16
|
-
controllers[ module_name ] = new module( $module )
|
17
|
-
controllers[ module_name ].id = module_name
|
18
|
-
else
|
19
|
-
throw new Error( "Can't find module #{$module.attr( 'data-module' )}" )
|
9
|
+
$module = $( $module )
|
10
|
+
loader.load_module( $module.attr( 'data-module' ), $module )
|
20
11
|
)
|
21
12
|
|
22
13
|
|
14
|
+
load_module: ( pathname, $root ) ->
|
15
|
+
module_name = loader.compute_name( pathname )
|
16
|
+
path = pathname.split( '.' )
|
17
|
+
module = App.Controllers
|
18
|
+
module = module[ path.shift() ] while path.length
|
19
|
+
|
20
|
+
if module
|
21
|
+
controllers[ module_name ] = new module( $root )
|
22
|
+
controllers[ module_name ].id = module_name
|
23
|
+
else
|
24
|
+
throw new Error( "Can't find module #{pathname}" )
|
25
|
+
|
26
|
+
controllers[ module_name ]
|
27
|
+
|
28
|
+
|
23
29
|
module_roots: ->
|
24
30
|
$( '*[data-module]' )
|
25
31
|
|
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: darwinjs-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '1.
|
5
|
-
prerelease:
|
4
|
+
version: '1.2'
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Olivier El Mekki
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-11-16 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: railties
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ~>
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -30,7 +27,6 @@ dependencies:
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: coffee-rails
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - ~>
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - ~>
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -46,7 +41,6 @@ dependencies:
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: jquery-rails
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
45
|
- - ~>
|
52
46
|
- !ruby/object:Gem::Version
|
@@ -54,7 +48,6 @@ dependencies:
|
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
52
|
- - ~>
|
60
53
|
- !ruby/object:Gem::Version
|
@@ -62,7 +55,6 @@ dependencies:
|
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: bundler
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
59
|
- - ~>
|
68
60
|
- !ruby/object:Gem::Version
|
@@ -70,7 +62,6 @@ dependencies:
|
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
66
|
- - ~>
|
76
67
|
- !ruby/object:Gem::Version
|
@@ -78,17 +69,15 @@ dependencies:
|
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: rake
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - '>='
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: '0'
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - '>='
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: '0'
|
94
83
|
description: Javascript framework with progressive enhancement in mind.
|
@@ -126,27 +115,26 @@ files:
|
|
126
115
|
homepage: https://github.com/oelmekki/darwinjs-rails
|
127
116
|
licenses:
|
128
117
|
- MIT
|
118
|
+
metadata: {}
|
129
119
|
post_install_message:
|
130
120
|
rdoc_options: []
|
131
121
|
require_paths:
|
132
122
|
- lib
|
133
123
|
required_ruby_version: !ruby/object:Gem::Requirement
|
134
|
-
none: false
|
135
124
|
requirements:
|
136
|
-
- -
|
125
|
+
- - '>='
|
137
126
|
- !ruby/object:Gem::Version
|
138
127
|
version: '0'
|
139
128
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
-
none: false
|
141
129
|
requirements:
|
142
|
-
- -
|
130
|
+
- - '>='
|
143
131
|
- !ruby/object:Gem::Version
|
144
132
|
version: '0'
|
145
133
|
requirements: []
|
146
134
|
rubyforge_project:
|
147
|
-
rubygems_version:
|
135
|
+
rubygems_version: 2.0.10
|
148
136
|
signing_key:
|
149
|
-
specification_version:
|
137
|
+
specification_version: 4
|
150
138
|
summary: Darwin lets create complex javascript interfaces that do not expect they
|
151
139
|
own the application and that degrade gracefully when an error occurs
|
152
140
|
test_files: []
|