ninjs 0.13.1 → 0.13.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -3
- data/Gemfile.lock +1 -67
- data/README.md +348 -0
- data/Rakefile +2 -4
- data/VERSION +1 -1
- data/bin/ninjs +196 -39
- data/lib/ninjs/command.rb +23 -64
- data/lib/ninjs/configuration.rb +16 -38
- data/lib/ninjs/generator.rb +23 -12
- data/lib/ninjs/project.rb +7 -6
- data/ninjs.gemspec +9 -33
- data/repository/ninjs/core/module.js +32 -105
- data/repository/ninjs/docs/Data/ClassHierarchy.nd +0 -0
- data/repository/ninjs/docs/Data/ConfigFileInfo.nd +0 -0
- data/repository/ninjs/docs/Data/IndexInfo.nd +0 -0
- data/repository/ninjs/docs/Data/SymbolTable.nd +0 -0
- data/repository/ninjs/extensions/ninjs.jquery.js +67 -0
- metadata +74 -100
- data/README.textile +0 -287
- data/tmp/metric_fu/output/churn.html +0 -692
- data/tmp/metric_fu/output/flay.html +0 -566
- data/tmp/metric_fu/output/flay.js +0 -11
- data/tmp/metric_fu/output/flog.html +0 -2392
- data/tmp/metric_fu/output/flog.js +0 -12
- data/tmp/metric_fu/output/hotspots.html +0 -3607
- data/tmp/metric_fu/output/index.html +0 -572
- data/tmp/metric_fu/output/lib_ninjs.rb.html +0 -49
- data/tmp/metric_fu/output/lib_ninjs_command.rb.html +0 -137
- data/tmp/metric_fu/output/lib_ninjs_configuration.rb.html +0 -107
- data/tmp/metric_fu/output/lib_ninjs_project.rb.html +0 -236
- data/tmp/metric_fu/output/rcov.html +0 -566
- data/tmp/metric_fu/output/rcov.js +0 -11
- data/tmp/metric_fu/output/reek.html +0 -1294
- data/tmp/metric_fu/output/reek.js +0 -20
- data/tmp/metric_fu/output/roodi.html +0 -599
- data/tmp/metric_fu/output/roodi.js +0 -11
- data/tmp/metric_fu/report.yml +0 -1548
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ninjs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 47
|
5
|
+
prerelease:
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 13
|
8
|
-
-
|
9
|
-
version: 0.13.
|
9
|
+
- 2
|
10
|
+
version: 0.13.2
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Dayton Nolan
|
@@ -14,208 +15,197 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2011-04
|
18
|
+
date: 2011-05-04 00:00:00 -05:00
|
18
19
|
default_executable: ninjs
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
|
-
|
22
|
+
type: :runtime
|
22
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
23
24
|
none: false
|
24
25
|
requirements:
|
25
26
|
- - ">="
|
26
27
|
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
27
29
|
segments:
|
28
30
|
- 0
|
29
31
|
version: "0"
|
30
|
-
|
31
|
-
prerelease: false
|
32
|
+
name: fssm
|
32
33
|
version_requirements: *id001
|
34
|
+
prerelease: false
|
33
35
|
- !ruby/object:Gem::Dependency
|
34
|
-
|
36
|
+
type: :runtime
|
35
37
|
requirement: &id002 !ruby/object:Gem::Requirement
|
36
38
|
none: false
|
37
39
|
requirements:
|
38
40
|
- - ">="
|
39
41
|
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
40
43
|
segments:
|
41
44
|
- 0
|
42
45
|
version: "0"
|
43
|
-
|
44
|
-
prerelease: false
|
46
|
+
name: jsmin
|
45
47
|
version_requirements: *id002
|
48
|
+
prerelease: false
|
46
49
|
- !ruby/object:Gem::Dependency
|
47
|
-
|
50
|
+
type: :runtime
|
48
51
|
requirement: &id003 !ruby/object:Gem::Requirement
|
49
52
|
none: false
|
50
53
|
requirements:
|
51
|
-
- - "
|
54
|
+
- - "="
|
52
55
|
- !ruby/object:Gem::Version
|
56
|
+
hash: 19
|
53
57
|
segments:
|
58
|
+
- 1
|
54
59
|
- 0
|
55
|
-
|
56
|
-
|
57
|
-
|
60
|
+
- 2
|
61
|
+
version: 1.0.2
|
62
|
+
name: sprockets
|
58
63
|
version_requirements: *id003
|
64
|
+
prerelease: false
|
59
65
|
- !ruby/object:Gem::Dependency
|
60
|
-
|
66
|
+
type: :development
|
61
67
|
requirement: &id004 !ruby/object:Gem::Requirement
|
62
68
|
none: false
|
63
69
|
requirements:
|
64
70
|
- - ">="
|
65
71
|
- !ruby/object:Gem::Version
|
72
|
+
hash: 3
|
66
73
|
segments:
|
67
74
|
- 0
|
68
75
|
version: "0"
|
69
|
-
|
70
|
-
prerelease: false
|
76
|
+
name: shoulda
|
71
77
|
version_requirements: *id004
|
72
|
-
- !ruby/object:Gem::Dependency
|
73
|
-
name: metric_fu
|
74
|
-
requirement: &id005 !ruby/object:Gem::Requirement
|
75
|
-
none: false
|
76
|
-
requirements:
|
77
|
-
- - ">="
|
78
|
-
- !ruby/object:Gem::Version
|
79
|
-
segments:
|
80
|
-
- 0
|
81
|
-
version: "0"
|
82
|
-
type: :development
|
83
78
|
prerelease: false
|
84
|
-
version_requirements: *id005
|
85
79
|
- !ruby/object:Gem::Dependency
|
86
|
-
name: shoulda
|
87
|
-
requirement: &id006 !ruby/object:Gem::Requirement
|
88
|
-
none: false
|
89
|
-
requirements:
|
90
|
-
- - ">="
|
91
|
-
- !ruby/object:Gem::Version
|
92
|
-
segments:
|
93
|
-
- 0
|
94
|
-
version: "0"
|
95
80
|
type: :development
|
96
|
-
|
97
|
-
version_requirements: *id006
|
98
|
-
- !ruby/object:Gem::Dependency
|
99
|
-
name: bundler
|
100
|
-
requirement: &id007 !ruby/object:Gem::Requirement
|
81
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
101
82
|
none: false
|
102
83
|
requirements:
|
103
84
|
- - ~>
|
104
85
|
- !ruby/object:Gem::Version
|
86
|
+
hash: 23
|
105
87
|
segments:
|
106
88
|
- 1
|
107
89
|
- 0
|
108
90
|
- 0
|
109
91
|
version: 1.0.0
|
110
|
-
|
92
|
+
name: bundler
|
93
|
+
version_requirements: *id005
|
111
94
|
prerelease: false
|
112
|
-
version_requirements: *id007
|
113
95
|
- !ruby/object:Gem::Dependency
|
114
|
-
|
115
|
-
requirement: &
|
96
|
+
type: :development
|
97
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
116
98
|
none: false
|
117
99
|
requirements:
|
118
100
|
- - ~>
|
119
101
|
- !ruby/object:Gem::Version
|
102
|
+
hash: 7
|
120
103
|
segments:
|
121
104
|
- 1
|
122
105
|
- 5
|
123
106
|
- 2
|
124
107
|
version: 1.5.2
|
125
|
-
|
108
|
+
name: jeweler
|
109
|
+
version_requirements: *id006
|
126
110
|
prerelease: false
|
127
|
-
version_requirements: *id008
|
128
111
|
- !ruby/object:Gem::Dependency
|
129
|
-
|
130
|
-
requirement: &
|
112
|
+
type: :development
|
113
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
131
114
|
none: false
|
132
115
|
requirements:
|
133
116
|
- - ">="
|
134
117
|
- !ruby/object:Gem::Version
|
118
|
+
hash: 3
|
135
119
|
segments:
|
136
120
|
- 0
|
137
121
|
version: "0"
|
138
|
-
|
122
|
+
name: rcov
|
123
|
+
version_requirements: *id007
|
139
124
|
prerelease: false
|
140
|
-
version_requirements: *id009
|
141
125
|
- !ruby/object:Gem::Dependency
|
142
|
-
|
143
|
-
requirement: &
|
126
|
+
type: :development
|
127
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
144
128
|
none: false
|
145
129
|
requirements:
|
146
130
|
- - ">="
|
147
131
|
- !ruby/object:Gem::Version
|
132
|
+
hash: 3
|
148
133
|
segments:
|
149
134
|
- 0
|
150
135
|
version: "0"
|
151
|
-
|
136
|
+
name: rspec
|
137
|
+
version_requirements: *id008
|
152
138
|
prerelease: false
|
153
|
-
version_requirements: *id010
|
154
139
|
- !ruby/object:Gem::Dependency
|
155
|
-
|
156
|
-
requirement: &
|
140
|
+
type: :runtime
|
141
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
157
142
|
none: false
|
158
143
|
requirements:
|
159
144
|
- - ">="
|
160
145
|
- !ruby/object:Gem::Version
|
146
|
+
hash: 3
|
161
147
|
segments:
|
162
148
|
- 0
|
163
149
|
version: "0"
|
164
|
-
|
150
|
+
name: rubikon
|
151
|
+
version_requirements: *id009
|
165
152
|
prerelease: false
|
166
|
-
version_requirements: *id011
|
167
153
|
- !ruby/object:Gem::Dependency
|
168
|
-
|
169
|
-
requirement: &
|
154
|
+
type: :runtime
|
155
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
170
156
|
none: false
|
171
157
|
requirements:
|
172
158
|
- - ">="
|
173
159
|
- !ruby/object:Gem::Version
|
160
|
+
hash: 3
|
174
161
|
segments:
|
175
162
|
- 0
|
176
163
|
version: "0"
|
177
|
-
|
164
|
+
name: fssm
|
165
|
+
version_requirements: *id010
|
178
166
|
prerelease: false
|
179
|
-
version_requirements: *id012
|
180
167
|
- !ruby/object:Gem::Dependency
|
181
|
-
|
182
|
-
requirement: &
|
168
|
+
type: :runtime
|
169
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
183
170
|
none: false
|
184
171
|
requirements:
|
185
172
|
- - ">="
|
186
173
|
- !ruby/object:Gem::Version
|
174
|
+
hash: 3
|
187
175
|
segments:
|
188
176
|
- 0
|
189
177
|
version: "0"
|
190
|
-
|
178
|
+
name: jsmin
|
179
|
+
version_requirements: *id011
|
191
180
|
prerelease: false
|
192
|
-
version_requirements: *id013
|
193
181
|
- !ruby/object:Gem::Dependency
|
194
|
-
|
195
|
-
requirement: &
|
182
|
+
type: :runtime
|
183
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
196
184
|
none: false
|
197
185
|
requirements:
|
198
186
|
- - ">="
|
199
187
|
- !ruby/object:Gem::Version
|
188
|
+
hash: 3
|
200
189
|
segments:
|
201
190
|
- 0
|
202
191
|
version: "0"
|
203
|
-
|
192
|
+
name: sprockets
|
193
|
+
version_requirements: *id012
|
204
194
|
prerelease: false
|
205
|
-
version_requirements: *id014
|
206
195
|
- !ruby/object:Gem::Dependency
|
207
|
-
|
208
|
-
requirement: &
|
196
|
+
type: :development
|
197
|
+
requirement: &id013 !ruby/object:Gem::Requirement
|
209
198
|
none: false
|
210
199
|
requirements:
|
211
200
|
- - ">="
|
212
201
|
- !ruby/object:Gem::Version
|
202
|
+
hash: 3
|
213
203
|
segments:
|
214
204
|
- 0
|
215
205
|
version: "0"
|
216
|
-
|
206
|
+
name: rspec
|
207
|
+
version_requirements: *id013
|
217
208
|
prerelease: false
|
218
|
-
version_requirements: *id015
|
219
209
|
description: Ninjs is a ruby application and small javascript framework that helps you build clean, modular javascript applications. Ninjs encourages "Good Parts" best practices and the Crockford school Module pattern (http://www.crockford.com/). The ninjs command line application is an automatic compiler, written in ruby, and based on the Sprockets library (http://getsprockets.org/).
|
220
210
|
email: daytonn@gmail.com
|
221
211
|
executables:
|
@@ -224,14 +214,14 @@ extensions: []
|
|
224
214
|
|
225
215
|
extra_rdoc_files:
|
226
216
|
- LICENSE
|
227
|
-
- README.
|
217
|
+
- README.md
|
228
218
|
files:
|
229
219
|
- .bundle/config
|
230
220
|
- CNAME
|
231
221
|
- Gemfile
|
232
222
|
- Gemfile.lock
|
233
223
|
- LICENSE
|
234
|
-
- README.
|
224
|
+
- README.md
|
235
225
|
- Rakefile
|
236
226
|
- VERSION
|
237
227
|
- bin/ninjs
|
@@ -393,6 +383,7 @@ files:
|
|
393
383
|
- repository/ninjs/docs/search/VariablesR.html
|
394
384
|
- repository/ninjs/docs/search/VariablesT.html
|
395
385
|
- repository/ninjs/docs/styles/main.css
|
386
|
+
- repository/ninjs/extensions/ninjs.jquery.js
|
396
387
|
- repository/ninjs/tests/index.html
|
397
388
|
- repository/ninjs/tests/ninjs.test.js
|
398
389
|
- repository/ninjs/tests/ninjs.utilities.test.js
|
@@ -489,30 +480,12 @@ files:
|
|
489
480
|
- tmp/ff9e83aa019b712b90200b8d1b8fa0c7e14576af.json
|
490
481
|
- tmp/metric_fu/_data/20110305.yml
|
491
482
|
- tmp/metric_fu/output/bluff-min.js
|
492
|
-
- tmp/metric_fu/output/churn.html
|
493
483
|
- tmp/metric_fu/output/excanvas.js
|
494
|
-
- tmp/metric_fu/output/flay.html
|
495
|
-
- tmp/metric_fu/output/flay.js
|
496
|
-
- tmp/metric_fu/output/flog.html
|
497
|
-
- tmp/metric_fu/output/flog.js
|
498
|
-
- tmp/metric_fu/output/hotspots.html
|
499
|
-
- tmp/metric_fu/output/index.html
|
500
484
|
- tmp/metric_fu/output/js-class.js
|
501
|
-
- tmp/metric_fu/output/lib_ninjs.rb.html
|
502
|
-
- tmp/metric_fu/output/lib_ninjs_command.rb.html
|
503
|
-
- tmp/metric_fu/output/lib_ninjs_configuration.rb.html
|
504
485
|
- tmp/metric_fu/output/lib_ninjs_dependencies.rb.html
|
505
486
|
- tmp/metric_fu/output/lib_ninjs_helpers.rb.html
|
506
487
|
- tmp/metric_fu/output/lib_ninjs_manifest.rb.html
|
507
|
-
- tmp/metric_fu/output/lib_ninjs_project.rb.html
|
508
488
|
- tmp/metric_fu/output/rails_best_practices.js
|
509
|
-
- tmp/metric_fu/output/rcov.html
|
510
|
-
- tmp/metric_fu/output/rcov.js
|
511
|
-
- tmp/metric_fu/output/reek.html
|
512
|
-
- tmp/metric_fu/output/reek.js
|
513
|
-
- tmp/metric_fu/output/roodi.html
|
514
|
-
- tmp/metric_fu/output/roodi.js
|
515
|
-
- tmp/metric_fu/report.yml
|
516
489
|
- tmp/metric_fu/scratch/rcov/rcov.txt
|
517
490
|
has_rdoc: true
|
518
491
|
homepage: http://github.com/textnotspeech/ninjs
|
@@ -528,7 +501,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
528
501
|
requirements:
|
529
502
|
- - ">="
|
530
503
|
- !ruby/object:Gem::Version
|
531
|
-
hash:
|
504
|
+
hash: 3
|
532
505
|
segments:
|
533
506
|
- 0
|
534
507
|
version: "0"
|
@@ -537,13 +510,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
537
510
|
requirements:
|
538
511
|
- - ">="
|
539
512
|
- !ruby/object:Gem::Version
|
513
|
+
hash: 3
|
540
514
|
segments:
|
541
515
|
- 0
|
542
516
|
version: "0"
|
543
517
|
requirements: []
|
544
518
|
|
545
519
|
rubyforge_project: nowarning
|
546
|
-
rubygems_version: 1.
|
520
|
+
rubygems_version: 1.5.2
|
547
521
|
signing_key:
|
548
522
|
specification_version: 3
|
549
523
|
summary: ninjs is a command line application to help you write clean, modular javascript applications.
|
data/README.textile
DELETED
@@ -1,287 +0,0 @@
|
|
1
|
-
h1. Readme
|
2
|
-
|
3
|
-
h2. About
|
4
|
-
|
5
|
-
Ninjs is a command line application written in ruby that leverages the "Sprockets":http://getsprockets.org JavaScript compiler to create modular javascript applications without having to compile your scripts manually. Ninjs also contains a "'Good Parts'":http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742/ref=sr_1_1?ie=UTF8&qid=1294628522&sr=8-1 JavaScript framework to encourage best practices like name-spacing and modular separation.
|
6
|
-
|
7
|
-
h2. Installation
|
8
|
-
|
9
|
-
You can install Ninjs using RubyGems. This is the easiest way of installing and recommended for most users.
|
10
|
-
<pre name="code" class="brush: sh;">$ gem install ninjs</pre>
|
11
|
-
|
12
|
-
For development you should clone the Git repository and add the application to your path:
|
13
|
-
<pre name="code" class="brush: sh">
|
14
|
-
$ git clone git://github.com/textnotspeech/ninjs.git
|
15
|
-
$ export PATH=/path/to/ninjs/bin:$PATH
|
16
|
-
</pre>
|
17
|
-
|
18
|
-
h1. Create a Ninjs application
|
19
|
-
|
20
|
-
<pre name="code" class="brush: sh;">$ ninjs create myapplication</pre>
|
21
|
-
|
22
|
-
This will create a Ninjs application in the current working directory. Now we can create Ninjs modules by adding them in the modules directory.
|
23
|
-
|
24
|
-
h1. Create a Ninjs module
|
25
|
-
|
26
|
-
Using the generate command we can create a module stub. The generate command takes two argument, the first is the type of file you'd like to generate and the second is the name of the file/module.
|
27
|
-
|
28
|
-
<pre name="code" class="brush: sh;">
|
29
|
-
$ ninjs generate module mymodule
|
30
|
-
// creates /modules/mymodule.module.js
|
31
|
-
</pre>
|
32
|
-
|
33
|
-
Create a module file in the /modules directory. By convention, we'll name the file with a suffix of .module. An example of a module named hello would look like this:
|
34
|
-
|
35
|
-
/modules/hello.module.js
|
36
|
-
|
37
|
-
The basic functionality of a module is to encapsulate specific logic into a container. Think of a module as a class in the sense that it allows to name-space properties and methods. A Ninjs module is an extremely lightweight object that contains a very simple api which helps you write clear, concise code. The following is the bare minimum you need to have a working module a.k.a Ninjs' "Hello World":
|
38
|
-
|
39
|
-
<pre name="code" class="brush: js;">
|
40
|
-
myapplication.add_module('hello');
|
41
|
-
|
42
|
-
myapplication.hello.actions = function() {
|
43
|
-
this.say_hello();
|
44
|
-
};
|
45
|
-
|
46
|
-
myapplication.hello.say_hello = function() {
|
47
|
-
alert('Hello World');
|
48
|
-
};
|
49
|
-
|
50
|
-
myapplication.hello.run();
|
51
|
-
</pre>
|
52
|
-
|
53
|
-
The run method will execute the actions method. Please note that the "run" method will wait for the DOM to be ready before it is executed. If you wish the actions to be executed immediately, you may call the execute method like so:
|
54
|
-
|
55
|
-
<pre name="code" class="brush: js;">
|
56
|
-
myapplication.hello.execute();
|
57
|
-
</pre>
|
58
|
-
|
59
|
-
This pattern allows you to write in a literate style while making your intentions clear and methods succinct. However, if you prefer a shorter syntax or make your module completely protable (transplant to any application), Ninjs defines an application alias to make your module code cleaner and your modules portable. Your application object will be aliased as "app". With the app alias we can write the previous module like so:
|
60
|
-
|
61
|
-
<pre name="code" class="brush: js;">
|
62
|
-
app.add_module('hello');
|
63
|
-
|
64
|
-
app.hello.actions = function() {
|
65
|
-
this.say_hello();
|
66
|
-
};
|
67
|
-
|
68
|
-
app.hello.say_hello = function() {
|
69
|
-
alert('Hello World');
|
70
|
-
};
|
71
|
-
|
72
|
-
app.hello.run();
|
73
|
-
</pre>
|
74
|
-
|
75
|
-
This not only makes the module less cumbersome to write, it also allows you to port modules directly into other Ninjs application's and run them without any renaming.
|
76
|
-
|
77
|
-
You may ask why we are calling say_hello() in the actions method instead of just alerting the string in actions itself. Let's set aside the fact that this is a trivial example and assume we will be adding many more methods to the module. If we simply added all of our module code inside actions, we'd quickly have a soup of code in there which would be difficult to follow. The Ninjs javascript framework encourages syntactic clarity. It's preferable for the actions method to be a list of methods called in the module. This let's my module tell a consistent story from top to bottom. The actions method serves as a table of contents. Consider a slightly more sophisticated hello module:
|
78
|
-
|
79
|
-
<pre name="code" class="brush: js;">
|
80
|
-
myapplication.add_module('hello');
|
81
|
-
|
82
|
-
myapplication.hello.actions = function() {
|
83
|
-
this.define_properties();
|
84
|
-
this.say_hello();
|
85
|
-
};
|
86
|
-
|
87
|
-
myapplication.hello.define_properties() = function() {
|
88
|
-
this.greeting = 'Hello';
|
89
|
-
this.name = 'World';
|
90
|
-
}
|
91
|
-
|
92
|
-
myapplication.hello.say_hello = function() {
|
93
|
-
var message = this.greeting_string();
|
94
|
-
alert(message);
|
95
|
-
};
|
96
|
-
|
97
|
-
myapplication.hello.greeting_string = function() {
|
98
|
-
return this.greeting + ' ' + this.name + '!';
|
99
|
-
};
|
100
|
-
|
101
|
-
myapplication.hello.run();
|
102
|
-
</pre>
|
103
|
-
|
104
|
-
We can see what this module does by simply glancing at the actions method. From there, if methods are kept short and follow the "single responsibiliy principle":http://en.wikipedia.org/wiki/Single_responsibility_principle, it will be easy to follow and test.
|
105
|
-
|
106
|
-
h2. Create module elements
|
107
|
-
|
108
|
-
Another common best practice that Ninjs encourages is cacheing your element selectors. For example, when using jQuery to select a DOM element, it's best practice to assign the result of the selection to a variable in case you need it again. Here's what it looks like in practice:
|
109
|
-
|
110
|
-
<pre name="code" class="brush: js;">
|
111
|
-
// Bad no-caching
|
112
|
-
$('#some-element').css({ 'background-color': '#FF0000' });
|
113
|
-
$('#some-element').html("I turned red");
|
114
|
-
|
115
|
-
// Good caching
|
116
|
-
var some_element = $('#some-element);
|
117
|
-
some_element.css({ 'background-color': '#FF0000' });
|
118
|
-
some_element.html("I turned red");
|
119
|
-
</pre>
|
120
|
-
|
121
|
-
When we cache our selections, we only have to search the DOM once, improving performance.
|
122
|
-
|
123
|
-
The only problem with this is that we tend to manipulate a lot of selections and our code can become littered with them. At worst, they're strewn about the file wherever they are first used, making it easy to accidentally "re-cache" them. At best, all selections are cached in one place and easy to see, which prevents us from accidentally caching them twice. Ninjs goes a step further by putting these cached selectors in their own file in the elements folder.
|
124
|
-
|
125
|
-
Elements belong to a module and can be added using the elements method. To add elements to the hello module, let's add a hello.elements.js file in the elements folder. Next add the elements to the module with the elements method:
|
126
|
-
|
127
|
-
<pre name="code" class="brush: js;">
|
128
|
-
myapplication.hello.elements(function() {
|
129
|
-
this.message_box = $('#message-box');
|
130
|
-
});
|
131
|
-
</pre>
|
132
|
-
|
133
|
-
And that's it for the elements code. We've added a cached element with the id of "message-box" to our module. All there is left is to add the elements to the module using the "Sprockets require directive":http://getsprockets.org/installation_and_usage#specifying_dependencies_with_the_require_directive
|
134
|
-
|
135
|
-
<pre name="code" class="brush: js;">
|
136
|
-
myapplication.add_module('hello');
|
137
|
-
|
138
|
-
//= require '../elements/hello.elements.js'
|
139
|
-
|
140
|
-
...
|
141
|
-
</pre>
|
142
|
-
|
143
|
-
Be sure to require the elements file after the "add_module" method is called. Now all elements defined in the elements method will be available to the module. Let's take our hello example and instead of alerting the greeting, let's put it in the message_box element (assuming an html page with this element):
|
144
|
-
|
145
|
-
<pre name="code" class="brush: js;">
|
146
|
-
...
|
147
|
-
|
148
|
-
myapplication.hello.say_hello = function() {
|
149
|
-
var message = this.greeting_string();
|
150
|
-
this.message_box.html(message);
|
151
|
-
};
|
152
|
-
|
153
|
-
...
|
154
|
-
</pre>
|
155
|
-
|
156
|
-
Again, this pattern keeps the logic very clear and our code very concise. It's easy to read, test, and refactor. Be careful when naming your cached elements, be sure you're not overwriting another property of the module. With time you'll develop your own naming conventions and standards. The important thing is to focus on good semantic names that accurately describe the properties and behavior of your application.
|
157
|
-
|
158
|
-
Most modules will be exactly like the one we just created, only with more methods. However, there is one more piece that helps you achieve greater modularity, which is Ninjs models.
|
159
|
-
|
160
|
-
h2. Create a Ninjs model
|
161
|
-
|
162
|
-
Ninjs models are simply files in the models directory that define a data structure. By convention models are simply object literals that are useful for reusing inside your modules and throughout your application.
|
163
|
-
|
164
|
-
Let's suppose I have multiple "jQueryUI dialog windows":http://jqueryui.com/demos/dialog/ that I want to share a certain default configuration. Instead of creating an options object each time I call dialog on an element, I can use a model. Let's see how this might look in our hello example. Let's create the model in /models/hello.model.js:
|
165
|
-
|
166
|
-
<pre name="code" class="brush: js;">
|
167
|
-
myapplication.hello.set_data('dialog_settings', {
|
168
|
-
width: 300,
|
169
|
-
height: 150,
|
170
|
-
autoOpen: false
|
171
|
-
});
|
172
|
-
</pre>
|
173
|
-
|
174
|
-
The set_data method will add the dialog_settings object to the module's data property (one of the only default module properties). You could add objects directly to the data property, but the set_data method has more syntactic clarity. You can think of this method as setting the modules "instance" variables.
|
175
|
-
|
176
|
-
Next we include the model in the module:
|
177
|
-
|
178
|
-
<pre name="code" class="brush: js;">
|
179
|
-
myapplication.add_module('hello');
|
180
|
-
|
181
|
-
//= require '../elements/hello.model.js'
|
182
|
-
//= require '../elements/hello.elements.js'
|
183
|
-
|
184
|
-
...
|
185
|
-
</pre>
|
186
|
-
|
187
|
-
Now whenever I create a dialog in my module, I can use the dialog_settings object like so:
|
188
|
-
|
189
|
-
<pre name="code" class="brush: js;">
|
190
|
-
// assumes we have elements "error_dialog" and "notice_dialog"
|
191
|
-
// defined in the elements file
|
192
|
-
|
193
|
-
myapplication.hello.create_dialogs = function() {
|
194
|
-
this.error_dialog.dialog(this.data.dialog_settings);
|
195
|
-
this.notice_dialog.dialog(this.data.dialog_settings);
|
196
|
-
}
|
197
|
-
</pre>
|
198
|
-
|
199
|
-
This way we don't have to keep redefining the same properties each time we call dialog. If we want to modify the defaults, we can use jquery's merge method
|
200
|
-
|
201
|
-
<pre name="code" class="brush: js;">
|
202
|
-
// assumes we have elements "error_dialog" and "notice_dialog"
|
203
|
-
// defined in the elements file
|
204
|
-
|
205
|
-
myapplication.hello.create_dialogs = function() {
|
206
|
-
this.error_dialog.dialog(this.data.dialog_settings);
|
207
|
-
this.notice_dialog.dialog($.extend(myapplication.hello.data.dialog_settings, {
|
208
|
-
height: 300,
|
209
|
-
autoOpen: true
|
210
|
-
}));
|
211
|
-
}
|
212
|
-
</pre>
|
213
|
-
|
214
|
-
The model provides a default base that we can build from, helping use to keep our code DRY.
|
215
|
-
|
216
|
-
|
217
|
-
h1. Reference and Style
|
218
|
-
|
219
|
-
Notice the "this" variable used in the module methods. In this context "this" refers to the module itself. You need to be careful here because "this" in javascript is a fickle thing. Once you're inside another function, "this" no longer refers to the module, it refers to the current function. We need a way to refer to the modules without using the full namespace to access our module but that is quite a mouthful and tends to clutter up the methods, making them harder to read. The best way to get a local, private alias to our module is to wrap it in a closure like so:
|
220
|
-
|
221
|
-
<pre name="code" class="brush: js;">
|
222
|
-
(function(){
|
223
|
-
var self = myapplication.add_module('mymodule);
|
224
|
-
|
225
|
-
myapplication.mymodule.actions = function() {
|
226
|
-
self.observe_some_element_click();
|
227
|
-
};
|
228
|
-
|
229
|
-
myapplication.mymodule.observe_some_element_click = function() {
|
230
|
-
self.some_element.click(function() {
|
231
|
-
self.make_something_happen();
|
232
|
-
});
|
233
|
-
};
|
234
|
-
|
235
|
-
myapplication.mymodule.make_something_happen = function() {
|
236
|
-
alert('something happened');
|
237
|
-
};
|
238
|
-
|
239
|
-
...
|
240
|
-
})();
|
241
|
-
</pre>
|
242
|
-
|
243
|
-
Because the add_module method returns the module it just created, we can assign it to "self". This gives us a clear, consistent way to refer to the module. Although the framework is flexible in how you access your application and module objects, my preferred method looks something like this:
|
244
|
-
|
245
|
-
<pre name="code" class="brush: js;">
|
246
|
-
(function(){
|
247
|
-
var self = app.add_module('mymodule);
|
248
|
-
|
249
|
-
app.mymodule.actions = function() {
|
250
|
-
app.setup_some_plugin();
|
251
|
-
};
|
252
|
-
|
253
|
-
app.mymodule.setup_some_plugin = function() {
|
254
|
-
self.some_element.some_plugin(self.data.some_plugin_config);
|
255
|
-
};
|
256
|
-
|
257
|
-
app.mymodule.observe_some_element_click = function() {
|
258
|
-
self.some_element.click(function() {
|
259
|
-
self.make_something_happen();
|
260
|
-
});
|
261
|
-
};
|
262
|
-
|
263
|
-
app.mymodule.make_something_happen = function() {
|
264
|
-
alert('something happened');
|
265
|
-
};
|
266
|
-
|
267
|
-
app.mymodule.run();
|
268
|
-
})();
|
269
|
-
</pre>
|
270
|
-
|
271
|
-
Using the app alias makes your module copy-paste compatible with other ninjs applications, and it also cuts down on the typing. I like to define the methods using the app.module namespace because it helps me remember where I am when I'm in the middle of the file. Inside the methods I only refer to the module as self to be clear.
|
272
|
-
|
273
|
-
h1. Compiling the application
|
274
|
-
|
275
|
-
Now that we have a complete module including elements and a model, we need to compile these files into one coherent file to use in our html. To do so we have 2 options. Open a terminal window (command prompt) and navigate to the root of your Ninjs application. We can compile our application with one of 2 commands. The first choice is the compile command. From the root of your Ninjs application type:
|
276
|
-
|
277
|
-
<pre name="code" class="brush: bash;">
|
278
|
-
$ ninjs compile
|
279
|
-
</pre>
|
280
|
-
|
281
|
-
This will compile all the files in the modules folder, resolving all dependencies using the Sprockets engine, and finally outputting them into the application directory with the .module suffix removed. Our hello example module would compile into the application folder as hello.js. Now we can include the hello.js file (along with the myapplication.js) in our html document. Since running compile every time we make a change to any one of our module source files would quickly become a tedious chore, Ninjs also provides a watch command which will watch your root directory for changes and automatically compile when a file is changed. This speeds up development considerably and frankly makes Ninjs usable in a daily development context. To watch a Ninjs project simply navigate to the project root and issue the watch command:
|
282
|
-
|
283
|
-
<pre name="code" class="brush: bash;">
|
284
|
-
$ ninjs watch
|
285
|
-
</pre>
|
286
|
-
|
287
|
-
That's the basics of creating a Ninjs application!
|