evil-blocks-rails 0.5.1 → 0.6.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.
- checksums.yaml +4 -4
- data/ChangeLog.md +5 -0
- data/README.md +84 -18
- data/lib/evil-blocks.debug.js +23 -11
- data/lib/evil-blocks.js +204 -148
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3218d628224ba9091d719cc07bc71d08197753f
|
4
|
+
data.tar.gz: b7bf21a51deba749a22b9a11e6f13d1d705d682e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 09eb8985c804ca37642f418375554dd9f0cde07ba7d55d9ef2586becbe6de5af7a25948cd61d1bef365f5d7c3e6553419545774d1e924470543c4cb496b905f9
|
7
|
+
data.tar.gz: 13cc2cd3cce7438aee98f2e66078f7448a9cbed49318e37253b7fed9b3087753cbaa80b8a44351e420a0777abc648a6c89c628af52883e34ad73ff92a01eb1c7
|
data/ChangeLog.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## 0.6 (Ranger Able, 27th January 1951)
|
2
|
+
* Add filters, which process block object before init was called.
|
3
|
+
* Most build-in features was moved to filter to be disableable.
|
4
|
+
* Listener `load on window` will call immediately, if page was already loaded.
|
5
|
+
|
1
6
|
## 0.5.1
|
2
7
|
* Fix block vitalizing, when multiple blocks was binded to same DOM node.
|
3
8
|
|
data/README.md
CHANGED
@@ -15,7 +15,7 @@ Evil Block is a tiny JS framework for web pages. It is based on 4 ideas:
|
|
15
15
|
|
16
16
|
See also [Evil Front], a pack of helpers for Ruby on Rails and Evil Blocks.
|
17
17
|
|
18
|
-
Sponsored by [Evil Martians]. Role aliases
|
18
|
+
Sponsored by [Evil Martians]. Role aliases were taken from [Role.js].
|
19
19
|
|
20
20
|
[Role.js]: https://github.com/kossnocorp/role
|
21
21
|
[big price]: http://staal.io/blog/2014/02/05/2-way-data-binding-under-the-microscope/
|
@@ -85,7 +85,8 @@ and `data-role` (to define elements inside block).
|
|
85
85
|
```
|
86
86
|
|
87
87
|
Evil Blocks extends Slim and jQuery, so you can use shortcuts for this
|
88
|
-
attributes: `@@block` and `@role
|
88
|
+
attributes: `@@block` and `@role`. For Haml you can use [Role Block Haml] gem
|
89
|
+
to use same shortcuts.
|
89
90
|
|
90
91
|
```haml
|
91
92
|
@@todo
|
@@ -106,6 +107,8 @@ and be sure in scripts:
|
|
106
107
|
Of course, Evil Block doesn’t force you to use only this selectors.
|
107
108
|
You can any attributes, that you like.
|
108
109
|
|
110
|
+
[Role Block Haml]: https://github.com/vladson/role_block_haml
|
111
|
+
|
109
112
|
## Blocks
|
110
113
|
|
111
114
|
You should split your interface to independent controls and mark them
|
@@ -233,6 +236,8 @@ evil.blocks '@@docs',
|
|
233
236
|
@openPage(location.hash)
|
234
237
|
```
|
235
238
|
|
239
|
+
Listener `load on window` will execute immediately, if window is already loaded.
|
240
|
+
|
236
241
|
[evil-front/links]: https://github.com/ai/evil-front/blob/master/evil-front/lib/assets/javascripts/evil-front/links.js
|
237
242
|
|
238
243
|
## Blocks Communications
|
@@ -241,7 +246,7 @@ Blocks should communicates by custom jQuery events. You can bind event listener
|
|
241
246
|
to block node by `"on events"` method:
|
242
247
|
|
243
248
|
```coffee
|
244
|
-
evil.block '@@slideshow',
|
249
|
+
evil.block '@@slideshow',
|
245
250
|
nextSlide: -> …
|
246
251
|
|
247
252
|
'on play': ->
|
@@ -250,7 +255,7 @@ evil.block '@@slideshow', ->
|
|
250
255
|
'on stop': ->
|
251
256
|
clearInterval(@timer)
|
252
257
|
|
253
|
-
evil.block '@@video',
|
258
|
+
evil.block '@@video',
|
254
259
|
|
255
260
|
'click on @fullscreenButton': ->
|
256
261
|
$('@@slideshow').trigger('stop')
|
@@ -259,12 +264,12 @@ evil.block '@@video', ->
|
|
259
264
|
If you want to use broadcast messages, you can use custom events on body:
|
260
265
|
|
261
266
|
```coffee
|
262
|
-
evil.block '@@callUs',
|
267
|
+
evil.block '@@callUs',
|
263
268
|
|
264
269
|
'change-city on body': (e, city) ->
|
265
270
|
@phoneNumber.text(city.phone)
|
266
271
|
|
267
|
-
evil.block '@@cityChanger',
|
272
|
+
evil.block '@@cityChanger',
|
268
273
|
getCurrentCity: -> …
|
269
274
|
|
270
275
|
'change on @citySelect': ->
|
@@ -318,6 +323,74 @@ evil.block '@@comment',
|
|
318
323
|
|
319
324
|
[big price]: http://staal.io/blog/2014/02/05/2-way-data-binding-under-the-microscope/
|
320
325
|
|
326
|
+
## Debug
|
327
|
+
|
328
|
+
Evil Blocks contains debug extension, which log every events inside blocks.
|
329
|
+
To enable it, just load `evil-blocks.debug.js`. For example, in Rails:
|
330
|
+
|
331
|
+
```haml
|
332
|
+
- if Rails.env.development?
|
333
|
+
= javascript_include_tag 'evil-blocks.debug'
|
334
|
+
```
|
335
|
+
|
336
|
+
## Extensions
|
337
|
+
|
338
|
+
Evil Blocks has tiny core. It only finds blocks by selectors, sets `@block`
|
339
|
+
property and calls `init` method. Any others features (like event bindings
|
340
|
+
or `@$()` method) was created by filters and can be disabled or replaced.
|
341
|
+
|
342
|
+
Before calling `init`, Evil Blocks processes object throw the filters list in
|
343
|
+
`evil.block.filters`. Filter accepts object as first argument and unique
|
344
|
+
class ID as second. It can find some properties in object, work with block
|
345
|
+
DOM nodes and add/remove some object properties. If filter will return `false`,
|
346
|
+
Evil Blocks will stop block vitalizing and will not call `init` method.
|
347
|
+
|
348
|
+
Default filters:
|
349
|
+
|
350
|
+
1. **Don’t vitalize same DOM node twice.** It return `false` if block
|
351
|
+
was already initialized with this class ID.
|
352
|
+
2. **Add `@$()` method.** It add shortcut find method to object.
|
353
|
+
3. **Add shortcuts to `@element`.** It add properties for all children with
|
354
|
+
`data-role` attribute.
|
355
|
+
4. **Bind block events.** Find, bind listeners and remove all methods with
|
356
|
+
name like `on event`.
|
357
|
+
5. **Smarter window load listener.** Run `load on window` listener immediately,
|
358
|
+
if window is already loaded.
|
359
|
+
6. **Bind window and body events.** Find, bind listeners and remove all methods
|
360
|
+
with name like `event on window` or `event on body`.
|
361
|
+
7. **Bind elements events.** Find, bind listeners and remove all methods
|
362
|
+
with name like `event on child`.
|
363
|
+
|
364
|
+
You can add you own filter to `evil.block.filters`. Most filters should be added
|
365
|
+
after first filter to not been called on already initialized blocks.
|
366
|
+
|
367
|
+
Let’s write filter, which will initialize blocks only when they become to be
|
368
|
+
visible.
|
369
|
+
|
370
|
+
```coffee
|
371
|
+
filter = (obj) ->
|
372
|
+
if not obj.block.is(':visible')
|
373
|
+
# Check for visibility every 100 ms
|
374
|
+
# and recall vitalizing if block become visible
|
375
|
+
checking = ->
|
376
|
+
evil.block.vitalize(obj.block) if obj.block.is(':visible')
|
377
|
+
setTimeout(checking, 100);
|
378
|
+
|
379
|
+
# Disable block initializing
|
380
|
+
return false
|
381
|
+
|
382
|
+
# Add filter to list
|
383
|
+
evil.block.filters.splice(0, 0, filter)
|
384
|
+
```
|
385
|
+
|
386
|
+
With filters you can change Evil Blocks logic, add some new shortcuts or
|
387
|
+
features like mixins.
|
388
|
+
|
389
|
+
Also you can remove any default filters from `evil.block.filters`. For example,
|
390
|
+
you can create properties for `data-role` children only from some white list.
|
391
|
+
|
392
|
+
But Filters API is still unstable and you should be careful on major updates.
|
393
|
+
|
321
394
|
## Modules
|
322
395
|
|
323
396
|
If your blocks has same behavior, you can create module-block and set
|
@@ -329,12 +402,12 @@ multiple blocks on same tag:
|
|
329
402
|
```
|
330
403
|
|
331
404
|
```coffee
|
332
|
-
evil.block '@@closable',
|
405
|
+
evil.block '@@closable',
|
333
406
|
|
334
407
|
'click on @closeLink': ->
|
335
408
|
@block.trigger('close')
|
336
409
|
|
337
|
-
evil.block '@@popup',
|
410
|
+
evil.block '@@popup',
|
338
411
|
|
339
412
|
'on close': ->
|
340
413
|
@clock.removeClass('is-open')
|
@@ -361,16 +434,6 @@ evil.block '@@docs',
|
|
361
434
|
@openInFancybox(@example)
|
362
435
|
```
|
363
436
|
|
364
|
-
## Debug
|
365
|
-
|
366
|
-
Evil Blocks contains debug extension, which log every events inside blocks.
|
367
|
-
To enable it, just load `evil-block.debug.js`. For example, in Rails:
|
368
|
-
|
369
|
-
```haml
|
370
|
-
- if Rails.env.development?
|
371
|
-
= javascript_include_tag 'evil-block.debug'
|
372
|
-
```
|
373
|
-
|
374
437
|
## Install
|
375
438
|
|
376
439
|
### Ruby on Rails
|
@@ -387,6 +450,9 @@ Load `evil-blocks.js` in your script:
|
|
387
450
|
//= require evil-blocks
|
388
451
|
```
|
389
452
|
|
453
|
+
If you use Rails 3 on Heroku, you may need
|
454
|
+
[some hack](https://github.com/ai/evil-blocks/issues/17).
|
455
|
+
|
390
456
|
### Ruby
|
391
457
|
|
392
458
|
If you use Sinatra or other non-Rails framework you can add Evil Blocks path
|
data/lib/evil-blocks.debug.js
CHANGED
@@ -13,17 +13,29 @@
|
|
13
13
|
return;
|
14
14
|
}
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
16
|
+
var logger = function (obj) {
|
17
|
+
for ( var name in obj ) {
|
18
|
+
if ( name.indexOf('on ') == -1 ) continue;
|
19
|
+
|
20
|
+
var parts = name.split('on ');
|
21
|
+
var event = parts[0] ? parts[0] : parts[1];
|
22
|
+
|
23
|
+
var callback = obj[name];
|
24
|
+
obj[name] = function (e) {
|
25
|
+
var source = e.el ? e.el[0] : this.block[0];
|
26
|
+
var messages = ['Event "' + event + '" on', source];
|
27
|
+
|
28
|
+
var params = Array.prototype.slice.call(arguments, 1);
|
29
|
+
if ( params.length > 0 ) {
|
30
|
+
messages.push('with params');
|
31
|
+
messages = messages.concat(params);
|
32
|
+
}
|
33
|
+
|
34
|
+
log.apply(this, messages);
|
35
|
+
callback.apply(this, arguments);
|
23
36
|
}
|
24
|
-
|
37
|
+
}
|
38
|
+
};
|
25
39
|
|
26
|
-
|
27
|
-
};
|
28
|
-
}
|
40
|
+
evil.block.filters.splice(2, 0, logger);
|
29
41
|
})();
|
data/lib/evil-blocks.js
CHANGED
@@ -1,6 +1,23 @@
|
|
1
|
-
;(function (
|
1
|
+
;(function ($, window) {
|
2
2
|
"use strict";
|
3
3
|
|
4
|
+
// Helpers
|
5
|
+
var $window = $(window);
|
6
|
+
|
7
|
+
// Clone object
|
8
|
+
var clone = function (origin) {
|
9
|
+
var cloned = { };
|
10
|
+
for ( var name in origin ) {
|
11
|
+
cloned[name] = origin[name];
|
12
|
+
}
|
13
|
+
return cloned;
|
14
|
+
};
|
15
|
+
|
16
|
+
// Is string ends with substring.
|
17
|
+
var endsWith = function (string, substring) {
|
18
|
+
return string.substr(-substring.length) === substring;
|
19
|
+
};
|
20
|
+
|
4
21
|
/*
|
5
22
|
* Add `@data-role` alias to jQuery.
|
6
23
|
*
|
@@ -9,9 +26,7 @@
|
|
9
26
|
|
10
27
|
var rewriteSelector = function (context, name, pos) {
|
11
28
|
var original = context[name];
|
12
|
-
if ( !original )
|
13
|
-
return;
|
14
|
-
}
|
29
|
+
if ( !original ) return;
|
15
30
|
|
16
31
|
context[name] = function () {
|
17
32
|
arguments[pos] = arguments[pos].replace(
|
@@ -35,138 +50,47 @@
|
|
35
50
|
if ( !window.evil ) {
|
36
51
|
window.evil = { };
|
37
52
|
}
|
53
|
+
var evil = window.evil;
|
38
54
|
|
39
|
-
|
40
|
-
|
41
|
-
*/
|
42
|
-
var ready = false;
|
43
|
-
|
44
|
-
var callbacks = {
|
45
|
-
/**
|
46
|
-
* Create callback wrapper for block listener.
|
47
|
-
*/
|
48
|
-
block: function (self, func) {
|
49
|
-
return function (e) {
|
50
|
-
if ( e.currentTarget == e.target ) {
|
51
|
-
func.apply(self, arguments);
|
52
|
-
}
|
53
|
-
}
|
54
|
-
},
|
55
|
-
|
56
|
-
/**
|
57
|
-
* Create callback wrapper for body/document listener.
|
58
|
-
*/
|
59
|
-
global: function (self, func) {
|
60
|
-
return function () {
|
61
|
-
func.apply(self, arguments);
|
62
|
-
}
|
63
|
-
},
|
64
|
-
|
65
|
-
/**
|
66
|
-
* Create callback wrapper for element listener.
|
67
|
-
*/
|
68
|
-
elem: function (self, func) {
|
69
|
-
return function () {
|
70
|
-
var event = arguments[0];
|
71
|
-
event.el = $(this);
|
72
|
-
func.apply(self, arguments);
|
73
|
-
}
|
74
|
-
}
|
75
|
-
};
|
76
|
-
|
77
|
-
/**
|
78
|
-
* Execute `callback` on every finded `selector` inside `base`.
|
79
|
-
*/
|
80
|
-
var vitalize = function (base, id, selector, klass) {
|
55
|
+
// Find selector inside base DOM node and cretae class for it.
|
56
|
+
var find = function (base, id, selector, klass) {
|
81
57
|
var blocks = $().add( base.filter(selector) ).
|
82
58
|
add( base.find(selector) );
|
83
59
|
|
84
|
-
if ( blocks.length == 0 )
|
85
|
-
return;
|
86
|
-
}
|
60
|
+
if ( blocks.length == 0 ) return;
|
87
61
|
|
88
|
-
var
|
89
|
-
|
90
|
-
for ( var i = 0; i < blocks.length; i++ ) {
|
91
|
-
var block = $(blocks[i]);
|
62
|
+
var objects = [];
|
92
63
|
|
93
|
-
|
94
|
-
|
95
|
-
vitalized = [];
|
96
|
-
} else if ( vitalized.indexOf(id) != -1 ) {
|
97
|
-
continue;
|
98
|
-
}
|
99
|
-
vitalized.push(id);
|
100
|
-
block.data('evil-vitalized', vitalized);
|
101
|
-
|
102
|
-
var obj = { };
|
103
|
-
|
104
|
-
obj.$ = (function (block) {
|
105
|
-
return function (subselector) {
|
106
|
-
return $(subselector, block);
|
107
|
-
};
|
108
|
-
})(block);
|
109
|
-
|
110
|
-
var actives = { };
|
111
|
-
block.find('[data-role]').each(function (_, el) {
|
112
|
-
var roles = el.attributes['data-role'].value.split(' ');
|
113
|
-
for ( var i = 0; i < roles.length; i++ ) {
|
114
|
-
var role = roles[i];
|
115
|
-
if ( !obj[role] ) {
|
116
|
-
obj[role] = $();
|
117
|
-
}
|
118
|
-
obj[role].push(el);
|
119
|
-
}
|
120
|
-
});
|
64
|
+
blocks.each(function (_, node) {
|
65
|
+
var block = $(node);
|
121
66
|
|
67
|
+
var obj = clone(klass);
|
122
68
|
obj.block = block;
|
123
69
|
|
124
|
-
var
|
125
|
-
var
|
126
|
-
if (
|
127
|
-
result = window.evil.block.eventFilter(result, obj, name);
|
128
|
-
}
|
129
|
-
return result;
|
130
|
-
};
|
131
|
-
|
132
|
-
for ( var name in klass ) {
|
133
|
-
var prop = klass[name];
|
134
|
-
|
135
|
-
if ( name.indexOf('on ') == -1 ) {
|
136
|
-
obj[name] = prop;
|
137
|
-
continue;
|
138
|
-
}
|
139
|
-
|
140
|
-
(function (name, prop) {
|
141
|
-
var parts = name.split(' on ');
|
142
|
-
|
143
|
-
if ( parts[1] == 'body' ) {
|
144
|
-
$('body').on(parts[0], event('global', name, prop));
|
145
|
-
|
146
|
-
} else if ( parts[1] == 'window' ) {
|
147
|
-
$(window).on(parts[0], event('global', name, prop));
|
148
|
-
|
149
|
-
} else if ( parts[1] ) {
|
150
|
-
block.on(parts[0], parts[1], event('elem', name, prop));
|
151
|
-
|
152
|
-
} else {
|
153
|
-
block.on(parts[0], event('block', name, prop));
|
154
|
-
}
|
155
|
-
})(name, prop);
|
70
|
+
for ( var i = 0; i < evil.block.filters.length; i++ ) {
|
71
|
+
var stop = evil.block.filters[i](obj, id);
|
72
|
+
if ( stop === false ) return;
|
156
73
|
}
|
157
74
|
|
158
|
-
|
159
|
-
}
|
75
|
+
objects.push(obj)
|
76
|
+
});
|
160
77
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
};
|
167
|
-
}
|
78
|
+
return function () {
|
79
|
+
objects.forEach(function (obj) {
|
80
|
+
if (obj.init) obj.init();
|
81
|
+
})
|
82
|
+
};
|
168
83
|
};
|
169
84
|
|
85
|
+
// If onready event was already happend.
|
86
|
+
var ready = false;
|
87
|
+
|
88
|
+
// If onload event was already happend.
|
89
|
+
var loaded = false;
|
90
|
+
$window.load(function (event) {
|
91
|
+
loaded = event;
|
92
|
+
});
|
93
|
+
|
170
94
|
// Latest block ID
|
171
95
|
var lastBlock = 0;
|
172
96
|
|
@@ -205,29 +129,22 @@
|
|
205
129
|
* evil.block '.block', ->
|
206
130
|
* # init method
|
207
131
|
*/
|
208
|
-
|
132
|
+
evil.block = function (selector, klass) {
|
209
133
|
lastBlock += 1;
|
210
134
|
var id = lastBlock;
|
211
135
|
|
212
|
-
if ( typeof(
|
213
|
-
|
136
|
+
if ( typeof(klass) == 'function' ) {
|
137
|
+
klass = { init: klass };
|
214
138
|
}
|
215
139
|
|
216
|
-
|
140
|
+
evil.block.defined.push([id, selector, klass]);
|
217
141
|
|
218
142
|
if ( ready ) {
|
219
|
-
var init =
|
220
|
-
if ( init )
|
221
|
-
init();
|
222
|
-
}
|
143
|
+
var init = find($(document), id, selector, klass);
|
144
|
+
if ( init ) init();
|
223
145
|
}
|
224
146
|
};
|
225
147
|
|
226
|
-
/**
|
227
|
-
* Evil blocks list.
|
228
|
-
*/
|
229
|
-
window.evil.block.vitalizers = [];
|
230
|
-
|
231
148
|
/**
|
232
149
|
* Vitalize all current blocks inside base. You must call it on every
|
233
150
|
* new content from AJAX.
|
@@ -236,7 +153,7 @@
|
|
236
153
|
* $.get '/comments', (comments) =>
|
237
154
|
* evil.block.vitalize $(comments).applyTo(@comments)
|
238
155
|
*/
|
239
|
-
|
156
|
+
evil.block.vitalize = function (base) {
|
240
157
|
if ( base ) {
|
241
158
|
base = $(base);
|
242
159
|
} else {
|
@@ -244,26 +161,165 @@
|
|
244
161
|
}
|
245
162
|
|
246
163
|
var inits = [];
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
}
|
164
|
+
evil.block.defined.forEach(function (define) {
|
165
|
+
inits.push( find(base, define[0], define[1], define[2]) );
|
166
|
+
});
|
251
167
|
|
252
168
|
for ( var i = 0; i < inits.length; i++ ) {
|
253
|
-
if ( inits[i] )
|
254
|
-
inits[i]();
|
255
|
-
}
|
169
|
+
if ( inits[i] ) inits[i]();
|
256
170
|
}
|
257
171
|
};
|
258
172
|
|
173
|
+
/**
|
174
|
+
* Evil blocks list.
|
175
|
+
*/
|
176
|
+
evil.block.defined = [];
|
177
|
+
|
178
|
+
/**
|
179
|
+
* Filters to process block object and add some extra functions
|
180
|
+
* to Evil Blocks. For example, allow to write listeners.
|
181
|
+
*
|
182
|
+
* Filter will receive block object and unique class ID.
|
183
|
+
* If filter return `false`, block will not be created.
|
184
|
+
*/
|
185
|
+
evil.block.filters = [];
|
186
|
+
|
187
|
+
var filters = evil.block.filters;
|
188
|
+
|
189
|
+
/**
|
190
|
+
* Don’t vitalize already vitalized block.
|
191
|
+
*
|
192
|
+
* For better perfomance, it should be last filter.
|
193
|
+
*/
|
194
|
+
filters.push(function (obj, id) {
|
195
|
+
var ids = obj.block.data('evil-blocks');
|
196
|
+
if ( !ids ) {
|
197
|
+
ids = [];
|
198
|
+
} else if ( ids.indexOf(id) != -1 ) {
|
199
|
+
return false;
|
200
|
+
}
|
201
|
+
ids.push(id);
|
202
|
+
obj.block.data('evil-blocks', ids);
|
203
|
+
});
|
204
|
+
|
205
|
+
/**
|
206
|
+
* Create `this.$()` as alias for `this.block.find()`
|
207
|
+
*/
|
208
|
+
filters.push(function (obj) {
|
209
|
+
obj.$ = function (subselector) {
|
210
|
+
return obj.block.find(subselector);
|
211
|
+
};
|
212
|
+
});
|
213
|
+
|
214
|
+
/**
|
215
|
+
* Create properties for each element with `data-role`.
|
216
|
+
*/
|
217
|
+
filters.push(function (obj) {
|
218
|
+
obj.block.find('[data-role]').each(function (_, el) {
|
219
|
+
var roles = el.attributes['data-role'].value.split(' ');
|
220
|
+
for ( var i = 0; i < roles.length; i++ ) {
|
221
|
+
var role = roles[i];
|
222
|
+
if ( !obj[role] ) obj[role] = $();
|
223
|
+
if ( obj[role].jquery ) obj[role].push(el);
|
224
|
+
}
|
225
|
+
});
|
226
|
+
});
|
227
|
+
|
228
|
+
/**
|
229
|
+
* Syntax sugar to listen block events.
|
230
|
+
*/
|
231
|
+
filters.push(function (obj) {
|
232
|
+
for ( var name in obj ) {
|
233
|
+
if ( name.substr(0, 3) != 'on ' ) continue;
|
234
|
+
|
235
|
+
var events = name.substr(3);
|
236
|
+
var callback = obj[name];
|
237
|
+
delete obj[name];
|
238
|
+
|
239
|
+
(function (events, callback) {
|
240
|
+
obj.block.on(events, function (e) {
|
241
|
+
if ( e.currentTarget == e.target ) {
|
242
|
+
callback.apply(obj, arguments);
|
243
|
+
}
|
244
|
+
});
|
245
|
+
})(events, callback);
|
246
|
+
}
|
247
|
+
});
|
248
|
+
|
249
|
+
/**
|
250
|
+
* Smart `load on window` listener, which fire immediately
|
251
|
+
* if page was already loaded.
|
252
|
+
*/
|
253
|
+
filters.push(function (obj) {
|
254
|
+
var name = 'load on window';
|
255
|
+
var callback = obj[name];
|
256
|
+
|
257
|
+
if ( !callback ) return;
|
258
|
+
delete obj[name];
|
259
|
+
|
260
|
+
if ( loaded ) {
|
261
|
+
setTimeout(function () {
|
262
|
+
callback.call(obj, loaded);
|
263
|
+
}, 1);
|
264
|
+
} else {
|
265
|
+
$window.load(function (event) {
|
266
|
+
callback.call(obj, event);
|
267
|
+
});
|
268
|
+
}
|
269
|
+
});
|
270
|
+
|
271
|
+
/**
|
272
|
+
* Syntax sugar to listen window and body events.
|
273
|
+
*/
|
274
|
+
filters.push(function (obj) {
|
275
|
+
for ( var name in obj ) {
|
276
|
+
var elem = false;
|
277
|
+
if ( endsWith(name, 'on body') ) {
|
278
|
+
elem = $('body');
|
279
|
+
} else if ( endsWith(name, 'on window') ) {
|
280
|
+
elem = $window;
|
281
|
+
}
|
282
|
+
|
283
|
+
if ( !elem ) continue;
|
284
|
+
|
285
|
+
var event = name.split(' on ')[0];
|
286
|
+
var callback = obj[name];
|
287
|
+
delete obj[name];
|
288
|
+
|
289
|
+
(function (elem, event, callback) {
|
290
|
+
elem.on(event, function () {
|
291
|
+
callback.apply(obj, arguments);
|
292
|
+
});
|
293
|
+
})(elem, event, callback);
|
294
|
+
}
|
295
|
+
});
|
296
|
+
|
297
|
+
/**
|
298
|
+
* Syntax sugar to listen element events.
|
299
|
+
*/
|
300
|
+
filters.push(function (obj) {
|
301
|
+
for ( var name in obj ) {
|
302
|
+
var parts = name.split(' on ');
|
303
|
+
if ( !parts[1] ) continue;
|
304
|
+
|
305
|
+
var callback = obj[name];
|
306
|
+
delete obj[name];
|
307
|
+
|
308
|
+
(function (parts, callback) {
|
309
|
+
obj.block.on(parts[0], parts[1], function (e) {
|
310
|
+
e.el = $(this);
|
311
|
+
callback.apply(obj, arguments);
|
312
|
+
});
|
313
|
+
})(parts, callback);
|
314
|
+
}
|
315
|
+
});
|
316
|
+
|
259
317
|
/*
|
260
318
|
* Run all blocks on load.
|
261
319
|
*/
|
262
320
|
$(document).ready(function () {
|
263
|
-
|
264
|
-
|
265
|
-
evil.block.vitalize();
|
266
|
-
}, 1);
|
321
|
+
ready = true;
|
322
|
+
evil.block.vitalize();
|
267
323
|
});
|
268
324
|
|
269
|
-
})(jQuery);
|
325
|
+
})(jQuery, window);
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrey Sitnik
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sprockets
|