evil-blocks-rails 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +3 -0
- data/README.md +33 -37
- data/lib/assets/javascripts/evil-blocks.js +151 -53
- metadata +2 -2
data/ChangeLog
CHANGED
data/README.md
CHANGED
@@ -17,8 +17,8 @@ and [role-rails](https://github.com/kossnocorp/role-rails) by Sasha Koss.
|
|
17
17
|
.gallery-control.is-big
|
18
18
|
// Evil Blocks add @data-role alias to Slim
|
19
19
|
// .class to bind styles, @data-role to bind JavaScript
|
20
|
-
a.gallery-left@
|
21
|
-
a.gallery-right@
|
20
|
+
a.gallery-left@nextPhoto href="#"
|
21
|
+
a.gallery-right@prevPhoto href="#"
|
22
22
|
img src="photos/1.jpg"
|
23
23
|
img src="photos/2.jpg"
|
24
24
|
img src="photos/3.jpg"
|
@@ -46,32 +46,29 @@ and [role-rails](https://github.com/kossnocorp/role-rails) by Sasha Koss.
|
|
46
46
|
### CoffeeScript
|
47
47
|
|
48
48
|
```coffee
|
49
|
-
# Will execute
|
50
|
-
evil.block '.gallery-control',
|
51
|
-
current
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
showPhoto(current)
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
slideShow: ->
|
49
|
+
# Will execute init only if .gallery-control is in current page
|
50
|
+
evil.block '.gallery-control',
|
51
|
+
current: 0
|
52
|
+
|
53
|
+
showPhoto: (num) ->
|
54
|
+
@('img').hide().
|
55
|
+
filter("eql(#{ num })").show()
|
56
|
+
|
57
|
+
init: ->
|
58
|
+
@showPhoto(@current)
|
59
|
+
|
60
|
+
'click on @nextPhoto', (link, event) ->
|
61
|
+
@showPhoto(current += 1)
|
62
|
+
|
63
|
+
'on start-slideshow', ->
|
66
64
|
# You can communicate between blocks by simple events
|
67
|
-
|
68
|
-
setTimeout( -> b.nextPhoto.click() , 5000)
|
65
|
+
setTimeout( => @nextPhoto.click() , 5000)
|
69
66
|
|
70
|
-
# Will execute
|
71
|
-
evil.block '.user-page',
|
67
|
+
# Will execute init only on user page, where .user-page exists
|
68
|
+
evil.block '.user-page',
|
72
69
|
|
73
|
-
|
74
|
-
|
70
|
+
init: ->
|
71
|
+
@('.gallery-control').trigger('start-slideshow')
|
75
72
|
```
|
76
73
|
|
77
74
|
## Styles
|
@@ -96,20 +93,19 @@ evil.block '.user-page', ($, b, block) ->
|
|
96
93
|
* Unobtrusive JavaScript.
|
97
94
|
* Write animation and states in CSS. JavaScript just changes CSS classes.
|
98
95
|
* Avoid rendering. Send from server HTML, not JSON.
|
99
|
-
*
|
100
|
-
It will
|
101
|
-
So you can be free to join all JS files in one.
|
102
|
-
*
|
103
|
-
`
|
104
|
-
|
105
|
-
(alias `b('a') = $('a', selector)`).
|
96
|
+
* Split JS by widgets. Describe widget class in `evil.block(selector, klass)`.
|
97
|
+
It will create `klass` instance and call `init` method for each selectors,
|
98
|
+
which exist in current page. So you can be free to join all JS files in one.
|
99
|
+
* Describe events by `EVENTS on SELECTORS` methods
|
100
|
+
(like `keyup submit on @name, @family`). This methods save this and
|
101
|
+
receive jQuery node in first argument and event in second.
|
106
102
|
* Bind JavaScript to `data-role` attribute to be free to change styles
|
107
103
|
and classes without dangeros of breaking scripts.
|
108
|
-
*
|
109
|
-
|
110
|
-
* If
|
111
|
-
|
112
|
-
|
104
|
+
* Every tag with `data-role` will by as property in object with jQuery node.
|
105
|
+
* If you need to find elements inside block, use `@(selector)` function.
|
106
|
+
* If you need to communicate between blocks, use custom events and create
|
107
|
+
block events listeners by `on EVENTS` method. It will receive events object
|
108
|
+
as first argument and event parameters as next arguments.
|
113
109
|
|
114
110
|
## Install
|
115
111
|
|
@@ -53,68 +53,166 @@
|
|
53
53
|
}
|
54
54
|
|
55
55
|
/**
|
56
|
-
*
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
56
|
+
* Evil blocks list.
|
57
|
+
*/
|
58
|
+
var vitalizers = [];
|
59
|
+
|
60
|
+
/**
|
61
|
+
* If onready event is already happend.
|
62
|
+
*/
|
63
|
+
var ready = false;
|
64
|
+
|
65
|
+
/**
|
66
|
+
* Execute `callback` on every finded `selector` inside `base`.
|
67
|
+
*/
|
68
|
+
var vitalize = function (base, selector, callback) {
|
69
|
+
var blocks = $().add( base.filter(selector) ).
|
70
|
+
add( base.find(selector) );
|
71
|
+
|
72
|
+
if ( blocks.length == 0 ) {
|
73
|
+
return;
|
74
|
+
}
|
75
|
+
|
76
|
+
for ( var i = 0; i < blocks.length; i++ ) {
|
77
|
+
var block = $(blocks[i]);
|
78
|
+
|
79
|
+
var b = (function (block) {
|
80
|
+
return function (subselector) {
|
81
|
+
return $(subselector, block);
|
82
|
+
};
|
83
|
+
})(block);
|
84
|
+
|
85
|
+
var actives = { };
|
86
|
+
block.find('[data-role]').each(function (_, el) {
|
87
|
+
var roles = el.attributes['data-role'].value.split(' ');
|
88
|
+
for ( var i = 0; i < roles.length; i++ ) {
|
89
|
+
var role = roles[i].replace(/-\w/g, function (s) {
|
90
|
+
return s[1].toUpperCase();
|
91
|
+
});
|
92
|
+
if ( !actives[role] ) {
|
93
|
+
actives[role] = [];
|
94
|
+
}
|
95
|
+
actives[role].push(el);
|
96
|
+
}
|
97
|
+
});
|
98
|
+
|
99
|
+
for ( var role in actives ) {
|
100
|
+
b[role] = b(actives[role]);
|
101
|
+
}
|
102
|
+
|
103
|
+
var inits = callback($, b, block);
|
104
|
+
if ( typeof(inits) == 'object' ) {
|
105
|
+
for ( var init in inits ) {
|
106
|
+
inits[init]($, b, block);
|
107
|
+
}
|
108
|
+
}
|
109
|
+
}
|
110
|
+
};
|
111
|
+
|
112
|
+
/**
|
113
|
+
* Convert block class to callback.
|
114
|
+
*/
|
115
|
+
var convert = function (klass) {
|
116
|
+
return function ($, obj, block) {
|
117
|
+
obj.block = block;
|
118
|
+
|
119
|
+
for ( var prop in klass ) {
|
120
|
+
(function (prop) {
|
121
|
+
if ( prop.indexOf('on ') != -1 ) {
|
122
|
+
var parts = prop.split(' on ');
|
123
|
+
if ( parts[1] ) {
|
124
|
+
block.on(parts[0], parts[1], function () {
|
125
|
+
var arg = Array.prototype.slice.call(arguments);
|
126
|
+
var el = $(this);
|
127
|
+
arg.unshift(el);
|
128
|
+
klass[prop].apply(obj, arg);
|
129
|
+
});
|
130
|
+
} else {
|
131
|
+
block.on(parts[0], function () {
|
132
|
+
klass[prop].apply(obj, arguments);
|
133
|
+
});
|
134
|
+
}
|
135
|
+
} else {
|
136
|
+
obj[prop] = klass[prop];
|
137
|
+
}
|
138
|
+
})(prop);
|
139
|
+
}
|
140
|
+
|
141
|
+
if ( typeof(obj.init) == 'function' ) {
|
142
|
+
obj.init();
|
143
|
+
}
|
144
|
+
}
|
145
|
+
}
|
146
|
+
|
147
|
+
/**
|
148
|
+
* Create object for every `selector` finded in page and call their
|
149
|
+
* `init` method.
|
150
|
+
*
|
151
|
+
* evil.block '.user-page .buttons',
|
152
|
+
* init: ->
|
153
|
+
* @gallery.fotorama()
|
154
|
+
* delete: ->
|
155
|
+
* @deleteForm.submit ->
|
156
|
+
* $('user-status').trigger('deleted')
|
157
|
+
* 'click on @deleleLink': (link) ->
|
158
|
+
* link.addClass('is-loading')
|
159
|
+
* delete()
|
160
|
+
* 'on update': ->
|
161
|
+
* location.reload()
|
61
162
|
*
|
62
|
-
*
|
163
|
+
* Every `data-role="aName"` in HTML will create in object `aName` property
|
164
|
+
* with jQuery node.
|
63
165
|
*
|
64
|
-
*
|
65
|
-
*
|
66
|
-
*
|
166
|
+
* To bind delegate listener just create `on EVENT on SELECTOR` method.
|
167
|
+
* In first argument it will receive jQuery node of `e.currentTarget`,
|
168
|
+
* second will be event object and others will be parameters.
|
67
169
|
*
|
68
|
-
*
|
170
|
+
* To communicate between blocks, just trigget custom events. To receive
|
171
|
+
* events from another blocks, create `on EVENT` method. Event object will
|
172
|
+
* be on first argument here.
|
69
173
|
*
|
70
|
-
*
|
71
|
-
*
|
72
|
-
* b.edit.click ->
|
73
|
-
* b('.edit-form').show()
|
174
|
+
* Block node will be in `@block` property and you can search only inside
|
175
|
+
* block by `@(selector)` method.
|
74
176
|
*
|
75
|
-
*
|
76
|
-
* b.del.click -> b('.delete-form').submit()
|
177
|
+
* If your block contrain only `init` method, you can use shortcut:
|
77
178
|
*
|
78
|
-
*
|
79
|
-
*
|
179
|
+
* evil.block '.block', ->
|
180
|
+
* # init method
|
80
181
|
*/
|
81
|
-
window.evil.block = function (selector,
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
var b = (function (block) {
|
88
|
-
return function (subselector) {
|
89
|
-
return $(subselector, block);
|
90
|
-
};
|
91
|
-
})(block);
|
92
|
-
var actives = { };
|
93
|
-
block.find('[data-role]').each(function (_, el) {
|
94
|
-
var roles = el.attributes['data-role'].value.split(' ');
|
95
|
-
for ( var i = 0; i < roles.length; i++ ) {
|
96
|
-
var role = roles[i].replace(/-\w/g, function (s) {
|
97
|
-
return s[1].toUpperCase();
|
98
|
-
});
|
99
|
-
if ( !actives[role] ) {
|
100
|
-
actives[role] = [];
|
101
|
-
}
|
102
|
-
actives[role].push(el);
|
103
|
-
}
|
104
|
-
});
|
182
|
+
window.evil.block = function (selector, vitalizer) {
|
183
|
+
if ( typeof(vitalizer) != 'function' ) {
|
184
|
+
vitalizer = convert(vitalizer)
|
185
|
+
}
|
186
|
+
vitalizers.push([selector, vitalizer]);
|
105
187
|
|
106
|
-
|
107
|
-
|
108
|
-
|
188
|
+
if ( ready ) {
|
189
|
+
vitalize($(document), selector, vitalizer);
|
190
|
+
}
|
191
|
+
};
|
109
192
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
193
|
+
/**
|
194
|
+
* Vitalize all current blocks inside base. You must call it on every
|
195
|
+
* new content from AJAX.
|
196
|
+
*
|
197
|
+
* 'on click on @load': ->
|
198
|
+
* $.get '/comments', (comments) =>
|
199
|
+
* evil.block.vitalize $(comments).applyTo(@comments)
|
200
|
+
*/
|
201
|
+
window.evil.block.vitalize = function (base) {
|
202
|
+
base = $(base);
|
203
|
+
|
204
|
+
for ( var i = 0; i < vitalizers.length; i++ ) {
|
205
|
+
var vitalizer = vitalizers[i];
|
206
|
+
vitalize(base, vitalizer[0], vitalizer[1]);
|
207
|
+
}
|
118
208
|
};
|
119
209
|
|
210
|
+
/*
|
211
|
+
* Run all blocks on load.
|
212
|
+
*/
|
213
|
+
$(document).ready(function () {
|
214
|
+
ready = true;
|
215
|
+
evil.block.vitalize(document);
|
216
|
+
});
|
217
|
+
|
120
218
|
})(jQuery);
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: evil-blocks-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
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-09-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sprockets
|