evil-blocks-rails 0.3.2 → 0.4.0
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/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
|