darwinjs-rails 1.0.1 → 1.1
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/README.md +117 -3
- data/app/assets/javascripts/darwin/controller.coffee +4 -1
- data/darwinjs-rails.gemspec +3 -3
- data/doc/introduction.md +1 -1
- data/lib/darwinjs/rails/version.rb +1 -1
- metadata +8 -8
data/README.md
CHANGED
|
@@ -26,7 +26,11 @@ Or install it yourself as:
|
|
|
26
26
|
First, as one time configuration, add autoloader in your
|
|
27
27
|
application.coffee file :
|
|
28
28
|
|
|
29
|
-
```
|
|
29
|
+
```coffee
|
|
30
|
+
#= require 'darwin'
|
|
31
|
+
#= require_tree ./views
|
|
32
|
+
#= require_tree ./controllers
|
|
33
|
+
|
|
30
34
|
$(->
|
|
31
35
|
Darwin.Loader.run()
|
|
32
36
|
)
|
|
@@ -69,7 +73,7 @@ A module is composed of two files :
|
|
|
69
73
|
Here is a typical view :
|
|
70
74
|
|
|
71
75
|
```coffee
|
|
72
|
-
class App.Views.Users.Index extends Darwin.
|
|
76
|
+
class App.Views.Users.Index extends Darwin.View
|
|
73
77
|
@options {
|
|
74
78
|
selectors:
|
|
75
79
|
show_users: 'a#show_users'
|
|
@@ -117,7 +121,7 @@ class App.Controllers.Users.Index extends Darwin.Controller
|
|
|
117
121
|
```
|
|
118
122
|
|
|
119
123
|
As you see, a view acts as single point of configuration for selectors.
|
|
120
|
-
Any change
|
|
124
|
+
Any change made then reflect to the whole javascript codebase.
|
|
121
125
|
|
|
122
126
|
In the same way, controller acts as a single point of configuration
|
|
123
127
|
for events. You can tell what a module does looking at the first
|
|
@@ -136,6 +140,116 @@ notice something got wrong.
|
|
|
136
140
|
|
|
137
141
|
Ready for more ? See [introduction](doc/introduction.md).
|
|
138
142
|
|
|
143
|
+
|
|
144
|
+
## Philosophy
|
|
145
|
+
|
|
146
|
+
If I had to choose a catchphrase for darwin, it probably would be :
|
|
147
|
+
|
|
148
|
+
Darwin knows client side isn't server side.
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
### You don't execute any code
|
|
152
|
+
|
|
153
|
+
There is something very cool with server generated pages : if it works for
|
|
154
|
+
you, it works for everyone. If something goes wrong, you probably receive
|
|
155
|
+
mail about the exception (you do, right ?). We have all of this for free,
|
|
156
|
+
because there is a single or a small set of machines doing the work.
|
|
157
|
+
|
|
158
|
+
Now, consider who is doing the work with a javascript codebase. It's your
|
|
159
|
+
visitors. That's really cool : charge on server is lowered and you don't
|
|
160
|
+
need to wait for the network to do stuff.
|
|
161
|
+
|
|
162
|
+
But you have as much execution environments as you have visitors. We could
|
|
163
|
+
even say you have as much execution environments as you have visits, because
|
|
164
|
+
you can't expect your visitor to have a stable and coherent environment.
|
|
165
|
+
What's the state of memory usage of your visitor ? Is his bandwith saturated
|
|
166
|
+
by multiple parallel downloads ? What extensions his browser is running ?
|
|
167
|
+
|
|
168
|
+
And now, the true question : what happens to your page when an error occurs ?
|
|
169
|
+
|
|
170
|
+
Links having "#" as href are a plea : if your javascript crashed, they will
|
|
171
|
+
simply do nothing. Think of what people do when they click a link that does
|
|
172
|
+
nothing. If you're a developer, you probably will instinctively reload the
|
|
173
|
+
page. If you're a lambda user, you probably get frustrated, yell "it doesn't
|
|
174
|
+
work !" and go somewhere else. How do we solve that ?
|
|
175
|
+
|
|
176
|
+
Darwin suggest that we do so through progessive enhancement and graceful
|
|
177
|
+
degradation. Your application should work perfectly without javascript. When
|
|
178
|
+
javascript runs, it enhances your interface to add all its cool features.
|
|
179
|
+
If something wrong occurs, interface is reverted back to its initial state,
|
|
180
|
+
and event callbacks are deactivated, so that feature works again and
|
|
181
|
+
promises made to user are fullfilled. I call that server side fallback.
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
### Your js application is an interactive presenter
|
|
185
|
+
|
|
186
|
+
On server side, we like to think about our application as a collection of
|
|
187
|
+
resources. Resources on the lower level are mapped to database tables.
|
|
188
|
+
Then we have model that abstracts operations on table data. Then we have
|
|
189
|
+
controllers that map requests on resources. And finally, we have views
|
|
190
|
+
that handles presenting our UI.
|
|
191
|
+
|
|
192
|
+
Should we use this same approach for client side ? In a previous version,
|
|
193
|
+
darwin did have a Model class. This turned out to be unintuitive and globally
|
|
194
|
+
useless : most operations on data (computation, translations, etc) are
|
|
195
|
+
already done by the server side. The model class was only called by
|
|
196
|
+
controllers to fire requests and then immediately pass data as callback.
|
|
197
|
+
Well, `$.getJSON` and `$.post` handle that pretty well. And since you conceived
|
|
198
|
+
your application through progressive enhancement and graceful degration,
|
|
199
|
+
chances are there's a form somewhere containing all the data and ready to
|
|
200
|
+
be serialized when lot of "model" data have to be saved.
|
|
201
|
+
|
|
202
|
+
But anyway, this does even not makes sense. Your server side app is built
|
|
203
|
+
around a database. Your client side app is built around html data. It's
|
|
204
|
+
a presenter that handles user feedback.
|
|
205
|
+
|
|
206
|
+
What we really need is a layer that handles DOM manipulation, and a layer
|
|
207
|
+
that handles interruptions (events and requests). They are the view layer
|
|
208
|
+
and the controller layer.
|
|
209
|
+
|
|
210
|
+
A view handles DOM manipulation. It abstracts selectors so that if anything
|
|
211
|
+
change in your HTML, you won't have to change it all over your codebase,
|
|
212
|
+
but just in one place. This acts as a single point of configuration for
|
|
213
|
+
retrieving DOM elements. In a view, you add all methods that do
|
|
214
|
+
special DOM manipulation, and especialy the setup (progressive enhancement)
|
|
215
|
+
and tear down (graceful degradation) code.
|
|
216
|
+
|
|
217
|
+
A controller handles events and requests. A configuration method is
|
|
218
|
+
used at the top of controller with descriptive comment keys, so that
|
|
219
|
+
you can see at a glance what controller does. Callback names are infered
|
|
220
|
+
from event descriptions, and they are all deactivated if a crash occurs.
|
|
221
|
+
|
|
222
|
+
Thus, view handles the presenter part, and controller handles interactivity.
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
### You may have several features on a page
|
|
226
|
+
|
|
227
|
+
Again, on server side, we love to think of application in terms of resources.
|
|
228
|
+
But on client side, it's difficult to stick to that pattern : we often
|
|
229
|
+
use a composition of resources to provide a feature. You may have a list
|
|
230
|
+
of users who you want to be able to create / edit / update / delete and
|
|
231
|
+
you can stick to single resource feature. But you may also want to display
|
|
232
|
+
a list of customer - a special kind of user - and to display for each their
|
|
233
|
+
last purchases. Now, you also want to do nifty javascript stuff on those
|
|
234
|
+
purchases, which are an other resource.
|
|
235
|
+
|
|
236
|
+
Instead of having a big javascript controller that handles things pretty
|
|
237
|
+
unrelated, darwin let you decompose a page in features with modules.
|
|
238
|
+
|
|
239
|
+
A module is a controller and a view bound to a subset of your html page.
|
|
240
|
+
The root element acts as a sandbox for your module : controller and view
|
|
241
|
+
can't access anything outside it. So you can have a module on the whole
|
|
242
|
+
page if it's a single feature page, or you can sandbox your module to a
|
|
243
|
+
given part of the DOM and have multiple modules, you can even have a
|
|
244
|
+
module sandboxed to a part of the DOM which is contained in the root element
|
|
245
|
+
of an other module. This ensures your modules respect single responsibility
|
|
246
|
+
principle.
|
|
247
|
+
|
|
248
|
+
And of course, modules are able to communicate with each other if needed,
|
|
249
|
+
through class events : any controller or view can fire and bind events,
|
|
250
|
+
just like you would do with a DOM element.
|
|
251
|
+
|
|
252
|
+
|
|
139
253
|
## Contributing
|
|
140
254
|
|
|
141
255
|
1. Fork it
|
|
@@ -56,7 +56,10 @@ class Darwin.Controller extends Darwin.Base
|
|
|
56
56
|
|
|
57
57
|
$target = $target.parents( sel ).first() unless $target.is( sel )
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
args = [ $target, event ]
|
|
60
|
+
args.push arguments[i] for i in [1..(arguments.length - 1)] if arguments.length > 1
|
|
61
|
+
|
|
62
|
+
callback( args... )
|
|
60
63
|
|
|
61
64
|
definition.stop = true if definition.type == 'click' and ! definition.stop?
|
|
62
65
|
|
data/darwinjs-rails.gemspec
CHANGED
|
@@ -18,9 +18,9 @@ Gem::Specification.new do |spec|
|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
19
|
spec.require_paths = ["lib"]
|
|
20
20
|
|
|
21
|
-
spec.add_dependency 'railties', '~>
|
|
22
|
-
spec.add_dependency 'coffee-rails', '~>
|
|
23
|
-
spec.add_dependency 'jquery-rails', '~>
|
|
21
|
+
spec.add_dependency 'railties', '~> 4.0'
|
|
22
|
+
spec.add_dependency 'coffee-rails', '~> 4.0'
|
|
23
|
+
spec.add_dependency 'jquery-rails', '~> 3.0'
|
|
24
24
|
spec.add_development_dependency "bundler", "~> 1.3"
|
|
25
25
|
spec.add_development_dependency "rake"
|
|
26
26
|
end
|
data/doc/introduction.md
CHANGED
|
@@ -46,7 +46,7 @@ controllers/, as controllers depend on views.
|
|
|
46
46
|
You can easily create a module using the generator provided :
|
|
47
47
|
|
|
48
48
|
```
|
|
49
|
-
$ rails generate
|
|
49
|
+
$ rails generate darwinjs:assets admin_area/users/index
|
|
50
50
|
|
|
51
51
|
create app/assets/javascripts/controllers/admin_area.coffee
|
|
52
52
|
create app/assets/javascripts/views/admin_area.coffee
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: darwinjs-rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: '1.1'
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2013-
|
|
12
|
+
date: 2013-08-03 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: railties
|
|
@@ -18,7 +18,7 @@ dependencies:
|
|
|
18
18
|
requirements:
|
|
19
19
|
- - ~>
|
|
20
20
|
- !ruby/object:Gem::Version
|
|
21
|
-
version: '
|
|
21
|
+
version: '4.0'
|
|
22
22
|
type: :runtime
|
|
23
23
|
prerelease: false
|
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -26,7 +26,7 @@ dependencies:
|
|
|
26
26
|
requirements:
|
|
27
27
|
- - ~>
|
|
28
28
|
- !ruby/object:Gem::Version
|
|
29
|
-
version: '
|
|
29
|
+
version: '4.0'
|
|
30
30
|
- !ruby/object:Gem::Dependency
|
|
31
31
|
name: coffee-rails
|
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -34,7 +34,7 @@ dependencies:
|
|
|
34
34
|
requirements:
|
|
35
35
|
- - ~>
|
|
36
36
|
- !ruby/object:Gem::Version
|
|
37
|
-
version: '
|
|
37
|
+
version: '4.0'
|
|
38
38
|
type: :runtime
|
|
39
39
|
prerelease: false
|
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -42,7 +42,7 @@ dependencies:
|
|
|
42
42
|
requirements:
|
|
43
43
|
- - ~>
|
|
44
44
|
- !ruby/object:Gem::Version
|
|
45
|
-
version: '
|
|
45
|
+
version: '4.0'
|
|
46
46
|
- !ruby/object:Gem::Dependency
|
|
47
47
|
name: jquery-rails
|
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -50,7 +50,7 @@ dependencies:
|
|
|
50
50
|
requirements:
|
|
51
51
|
- - ~>
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: '
|
|
53
|
+
version: '3.0'
|
|
54
54
|
type: :runtime
|
|
55
55
|
prerelease: false
|
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -58,7 +58,7 @@ dependencies:
|
|
|
58
58
|
requirements:
|
|
59
59
|
- - ~>
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
61
|
+
version: '3.0'
|
|
62
62
|
- !ruby/object:Gem::Dependency
|
|
63
63
|
name: bundler
|
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|