appjs 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +80 -2
- data/Rakefile +2 -0
- data/Teafile +22 -0
- data/appjs.gemspec +3 -2
- data/lib/appjs/version.rb +1 -1
- data/lib/assets/javascripts/app.js +42 -0
- data/lib/assets/javascripts/app/mediators/backbone.js +13 -0
- data/lib/assets/javascripts/app/mediators/jquery.js +17 -0
- data/lib/assets/javascripts/app/mediators/underscore.js +13 -0
- data/test/javascripts/app_test.js +127 -0
- data/test/javascripts/test_helper.js +3 -0
- data/test/mediators.html +42 -0
- metadata +30 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b399779bbccc64c399ce46c171c2a68478933ad
|
4
|
+
data.tar.gz: 1e3d0c3748d22447c779dff5e3651a90bc3739f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 68111d5c705c5ec8b70c845b50dc833991c1d7721fa20f6dc9f3387dab7e10adb1f10319a280fe65bc3547940c148541f66d0de5e49c7c1b6dcf4019c99eb3f9
|
7
|
+
data.tar.gz: 9fa9aa2233a18750828e861677029e1f3926d52cb44e1ede93eb2c5680774bd313bf0cb2d2907fe23c15c1b5c6fb1d330019aa881696c2ee909c65a0ac5e48e0
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,79 @@
|
|
1
1
|
# Appjs
|
2
2
|
|
3
|
-
|
3
|
+
Since repetition is the killer of all productivity, we decided to define a
|
4
|
+
generic way, for handling stuff like modularization and dependency-handling/-injection.
|
5
|
+
|
6
|
+
## Concepts
|
7
|
+
|
8
|
+
### Modularization
|
9
|
+
|
10
|
+
It's all about the modules you are creating or you want to reuse on a later
|
11
|
+
project. We follow a similar approach as [require.js](http://requirejs.org/):
|
12
|
+
|
13
|
+
```javascript
|
14
|
+
app.define('views.TodoList', function () {
|
15
|
+
var Backbone = app.require('Backbone'),
|
16
|
+
$ = app.require('jQuery'),
|
17
|
+
U = app.require('Underscore');
|
18
|
+
view,
|
19
|
+
render_helper;
|
20
|
+
|
21
|
+
render_helper = function () {
|
22
|
+
// ...
|
23
|
+
};
|
24
|
+
|
25
|
+
|
26
|
+
view = Backbone.View.extend({
|
27
|
+
render: render_helper
|
28
|
+
});
|
29
|
+
|
30
|
+
return view;
|
31
|
+
});
|
32
|
+
```
|
33
|
+
|
34
|
+
Effectively, this creates an Object `TodoList` in the Namespace `views`.
|
35
|
+
|
36
|
+
Main advantage is the lazy definition of this helper. The function is not
|
37
|
+
called, until somewhere a call in the later application demands this specific
|
38
|
+
Object:
|
39
|
+
|
40
|
+
```javascript
|
41
|
+
var TodoList = app.require('views.TodoList'),
|
42
|
+
$ = app.require('jQuery'),
|
43
|
+
my_list;
|
44
|
+
|
45
|
+
my_list = new TodoList({
|
46
|
+
el: $('.todo-list')
|
47
|
+
});
|
48
|
+
```
|
49
|
+
|
50
|
+
### Predefined mediators
|
51
|
+
|
52
|
+
Since most of the libraries you can use pollute somehow the global namespace; we
|
53
|
+
where searching for a way, to integrate those tools into our
|
54
|
+
define-require-schema.
|
55
|
+
|
56
|
+
Luckily, most of them provide a no-conflict mode. This lead us to some helper
|
57
|
+
for common libraries. An `application.js` could look as following:
|
58
|
+
|
59
|
+
```javascript
|
60
|
+
|
61
|
+
//= require underscore
|
62
|
+
//= require jquery
|
63
|
+
//= require backbone
|
64
|
+
//
|
65
|
+
//= require app
|
66
|
+
//= require app/mediators/underscore
|
67
|
+
//= require app/mediators/jquery
|
68
|
+
//= require app/mediators/backbone
|
69
|
+
```
|
70
|
+
|
71
|
+
The mediators automatically invoke no-conflict calls and store the main
|
72
|
+
constant(s) of the libraries into a app-definition:
|
73
|
+
|
74
|
+
* `mediators/underscore` provides `app.require('Underscore')`
|
75
|
+
* `mediators/jquery` provides `app.require('jQuery')`
|
76
|
+
* `mediators/backbone` provides `app.require('Backbone')`
|
4
77
|
|
5
78
|
## Installation
|
6
79
|
|
@@ -18,7 +91,12 @@ Or install it yourself as:
|
|
18
91
|
|
19
92
|
## Usage
|
20
93
|
|
21
|
-
|
94
|
+
First step would be to add
|
95
|
+
|
96
|
+
//= require app
|
97
|
+
|
98
|
+
to your application.js. This should be followed by the appropiate mediators, to
|
99
|
+
clean-up your global namespace.
|
22
100
|
|
23
101
|
## Contributing
|
24
102
|
|
data/Rakefile
CHANGED
data/Teafile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Teatime do |config|
|
2
|
+
# root dir of all requireable lib files
|
3
|
+
# config.lib_dir = 'lib'
|
4
|
+
config.lib_dir = 'lib/assets/javascripts'
|
5
|
+
|
6
|
+
|
7
|
+
# pattern to determine relevant lib files
|
8
|
+
config.lib_files = '**/*.js'
|
9
|
+
|
10
|
+
|
11
|
+
# root dir of all the test files
|
12
|
+
config.test_dir = 'test/javascripts'
|
13
|
+
|
14
|
+
# test helpers will be included in the
|
15
|
+
# provided order
|
16
|
+
config.test_helpers = [ 'test_helper.js' ]
|
17
|
+
|
18
|
+
# pattern to determine relevant testfiles
|
19
|
+
config.test_files = '**/*_test.js'
|
20
|
+
end
|
21
|
+
|
22
|
+
# vim: set ft=ruby:
|
data/appjs.gemspec
CHANGED
@@ -7,8 +7,8 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "appjs"
|
8
8
|
spec.version = Appjs::VERSION
|
9
9
|
spec.authors = ["Jakob Holderbaum"]
|
10
|
-
spec.email = ["
|
11
|
-
spec.summary = %q{
|
10
|
+
spec.email = ["gems@techfolio.de"]
|
11
|
+
spec.summary = %q{That's how we structure the JS in our Rails-apps.}
|
12
12
|
spec.homepage = "http://www.featurefabrik.com/"
|
13
13
|
spec.license = "MIT"
|
14
14
|
|
@@ -19,4 +19,5 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
spec.add_development_dependency "bundler", "~> 1.3"
|
21
21
|
spec.add_development_dependency "rake"
|
22
|
+
spec.add_development_dependency "teatime"
|
22
23
|
end
|
data/lib/appjs/version.rb
CHANGED
@@ -0,0 +1,42 @@
|
|
1
|
+
var App = function () {
|
2
|
+
var app_instance;
|
3
|
+
|
4
|
+
app_instance = function () {
|
5
|
+
var app = {},
|
6
|
+
definitions = {},
|
7
|
+
constants = {};
|
8
|
+
|
9
|
+
app.define = function (constant, definition) {
|
10
|
+
if (definitions[constant] !== undefined) {
|
11
|
+
throw "Constant '" + constant + "' already defined."
|
12
|
+
}
|
13
|
+
if (typeof definition !== 'function') {
|
14
|
+
throw "Definition has to be a function."
|
15
|
+
}
|
16
|
+
|
17
|
+
definitions[constant] = definition;
|
18
|
+
};
|
19
|
+
|
20
|
+
app.require = function (constant) {
|
21
|
+
if (constants[constant] === undefined) {
|
22
|
+
if (definitions[constant] === undefined) {
|
23
|
+
throw "Constant '" + constant + "' not defined."
|
24
|
+
}
|
25
|
+
constants[constant] = definitions[constant]();
|
26
|
+
}
|
27
|
+
|
28
|
+
return constants[constant];
|
29
|
+
};
|
30
|
+
|
31
|
+
return app;
|
32
|
+
}
|
33
|
+
|
34
|
+
return {
|
35
|
+
Mediators: {},
|
36
|
+
induce: function (scope) {
|
37
|
+
scope.app = app_instance();
|
38
|
+
}
|
39
|
+
};
|
40
|
+
}();
|
41
|
+
|
42
|
+
App.induce(window);
|
@@ -0,0 +1,17 @@
|
|
1
|
+
(function () {
|
2
|
+
var cache;
|
3
|
+
|
4
|
+
if (typeof $ !== 'undefined') {
|
5
|
+
cache = $.noConflict();
|
6
|
+
} else if (typeof jQuery !== 'undefined') {
|
7
|
+
cache = jQuery;
|
8
|
+
delete jQuery;
|
9
|
+
}
|
10
|
+
|
11
|
+
|
12
|
+
if (cache) {
|
13
|
+
app.define('jQuery', function () {
|
14
|
+
return cache;
|
15
|
+
});
|
16
|
+
}
|
17
|
+
}());
|
@@ -0,0 +1,127 @@
|
|
1
|
+
describe('app', function () {
|
2
|
+
|
3
|
+
describe('induce', function () {
|
4
|
+
|
5
|
+
it('enhances namespace with app', function () {
|
6
|
+
var namespace = {};
|
7
|
+
|
8
|
+
App.induce(namespace);
|
9
|
+
|
10
|
+
assert.ok(namespace.app);
|
11
|
+
});
|
12
|
+
|
13
|
+
it('creates separated instances', function () {
|
14
|
+
var namespace1 = {},
|
15
|
+
namespace2 = {};
|
16
|
+
|
17
|
+
App.induce(namespace1);
|
18
|
+
App.induce(namespace2);
|
19
|
+
|
20
|
+
namespace1.app.test = 23;
|
21
|
+
|
22
|
+
assert.isUndefined(namespace2.app.test);
|
23
|
+
});
|
24
|
+
|
25
|
+
it('is already called on window', function () {
|
26
|
+
assert.ok(window.app);
|
27
|
+
})
|
28
|
+
|
29
|
+
});
|
30
|
+
|
31
|
+
describe('define', function () {
|
32
|
+
var namespace;
|
33
|
+
|
34
|
+
beforeEach(function () {
|
35
|
+
namespace = {};
|
36
|
+
App.induce(namespace);
|
37
|
+
});
|
38
|
+
|
39
|
+
it('is no evaluated initially', function () {
|
40
|
+
var counter = 0;
|
41
|
+
|
42
|
+
namespace.app.define('module.Object', function () {
|
43
|
+
counter += 1;
|
44
|
+
|
45
|
+
return {
|
46
|
+
attr: 12
|
47
|
+
};
|
48
|
+
});
|
49
|
+
|
50
|
+
assert.equal(counter, 0);
|
51
|
+
});
|
52
|
+
|
53
|
+
it('can not be called twice with identical constant', function () {
|
54
|
+
namespace.app.define('const', function () {});
|
55
|
+
|
56
|
+
assert.throws(function () {
|
57
|
+
namespace.app.define('const', function () {});
|
58
|
+
}, /already defined/i)
|
59
|
+
});
|
60
|
+
|
61
|
+
it('accepts only a function', function () {
|
62
|
+
assert.throws(function () {
|
63
|
+
namespace.app.define('const', {});
|
64
|
+
}, /definition has to be a function/i);
|
65
|
+
})
|
66
|
+
});
|
67
|
+
|
68
|
+
describe('require', function () {
|
69
|
+
var namespace;
|
70
|
+
|
71
|
+
beforeEach(function () {
|
72
|
+
namespace = {};
|
73
|
+
App.induce(namespace);
|
74
|
+
});
|
75
|
+
|
76
|
+
it('invokes the definition', function () {
|
77
|
+
var counter = 0,
|
78
|
+
car;
|
79
|
+
|
80
|
+
namespace.app.define('Car', function () {
|
81
|
+
counter += 1;
|
82
|
+
|
83
|
+
return {
|
84
|
+
hasTires: true
|
85
|
+
};
|
86
|
+
});
|
87
|
+
|
88
|
+
assert.equal(counter, 0);
|
89
|
+
|
90
|
+
car = namespace.app.require('Car');
|
91
|
+
|
92
|
+
assert.equal(counter, 1);
|
93
|
+
assert.ok(car.hasTires)
|
94
|
+
});
|
95
|
+
|
96
|
+
it('invokes the definition only the first time', function () {
|
97
|
+
var counter = 0,
|
98
|
+
car;
|
99
|
+
|
100
|
+
namespace.app.define('Car', function () {
|
101
|
+
counter += 1;
|
102
|
+
|
103
|
+
return {
|
104
|
+
hasTires: true
|
105
|
+
};
|
106
|
+
});
|
107
|
+
|
108
|
+
car = namespace.app.require('Car');
|
109
|
+
|
110
|
+
assert.equal(counter, 1);
|
111
|
+
assert.ok(car.hasTires)
|
112
|
+
|
113
|
+
car = namespace.app.require('Car');
|
114
|
+
|
115
|
+
assert.equal(counter, 1);
|
116
|
+
assert.ok(car.hasTires)
|
117
|
+
});
|
118
|
+
|
119
|
+
it('throws if definition is not found', function () {
|
120
|
+
assert.throws(function () {
|
121
|
+
namespace.app.require('MyConst');
|
122
|
+
}, /not defined/i);
|
123
|
+
});
|
124
|
+
|
125
|
+
});
|
126
|
+
|
127
|
+
});
|
data/test/mediators.html
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
2
|
+
"http://www.w3.org/TR/html4/strict.dtd">
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
6
|
+
<title>Jquery mediator</title>
|
7
|
+
<script type="text/javascript" charset="utf-8">
|
8
|
+
window.$ = {
|
9
|
+
noConflict: function () {
|
10
|
+
return 123;
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
window._ = {
|
15
|
+
noConflict: function () {
|
16
|
+
return 456;
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
window.Backbone = {
|
21
|
+
noConflict: function () {
|
22
|
+
return 789;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
</script>
|
26
|
+
|
27
|
+
<script type="text/javascript" charset="utf-8" src="../../lib/assets/javascripts/app.js"></script>
|
28
|
+
<script type="text/javascript" charset="utf-8" src="../../lib/assets/javascripts/app/mediators/jquery.js"></script>
|
29
|
+
<script type="text/javascript" charset="utf-8" src="../../lib/assets/javascripts/app/mediators/underscore.js"></script>
|
30
|
+
<script type="text/javascript" charset="utf-8" src="../../lib/assets/javascripts/app/mediators/backbone.js"></script>
|
31
|
+
|
32
|
+
<script type="text/javascript" charset="utf-8">
|
33
|
+
document.write("jQuery: " + (app.require('jQuery') === 123) + '<br/>')
|
34
|
+
document.write("underscore: " + (app.require('underscore') === 456) + '<br/>')
|
35
|
+
document.write("backbone: " + (app.require('Backbone') === 789) + '<br/>')
|
36
|
+
</script>
|
37
|
+
|
38
|
+
|
39
|
+
</head>
|
40
|
+
<body>
|
41
|
+
</body>
|
42
|
+
</html>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appjs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jakob Holderbaum
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-05-
|
11
|
+
date: 2013-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,9 +38,23 @@ dependencies:
|
|
38
38
|
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: teatime
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
description:
|
42
56
|
email:
|
43
|
-
-
|
57
|
+
- gems@techfolio.de
|
44
58
|
executables: []
|
45
59
|
extensions: []
|
46
60
|
extra_rdoc_files: []
|
@@ -50,9 +64,17 @@ files:
|
|
50
64
|
- LICENSE.txt
|
51
65
|
- README.md
|
52
66
|
- Rakefile
|
67
|
+
- Teafile
|
53
68
|
- appjs.gemspec
|
54
69
|
- lib/appjs.rb
|
55
70
|
- lib/appjs/version.rb
|
71
|
+
- lib/assets/javascripts/app.js
|
72
|
+
- lib/assets/javascripts/app/mediators/backbone.js
|
73
|
+
- lib/assets/javascripts/app/mediators/jquery.js
|
74
|
+
- lib/assets/javascripts/app/mediators/underscore.js
|
75
|
+
- test/javascripts/app_test.js
|
76
|
+
- test/javascripts/test_helper.js
|
77
|
+
- test/mediators.html
|
56
78
|
homepage: http://www.featurefabrik.com/
|
57
79
|
licenses:
|
58
80
|
- MIT
|
@@ -76,5 +98,8 @@ rubyforge_project:
|
|
76
98
|
rubygems_version: 2.0.3
|
77
99
|
signing_key:
|
78
100
|
specification_version: 4
|
79
|
-
summary:
|
80
|
-
test_files:
|
101
|
+
summary: That's how we structure the JS in our Rails-apps.
|
102
|
+
test_files:
|
103
|
+
- test/javascripts/app_test.js
|
104
|
+
- test/javascripts/test_helper.js
|
105
|
+
- test/mediators.html
|