README.md in evil-blocks-rails-0.5.1 vs README.md in evil-blocks-rails-0.6.0
- old
+ new
@@ -13,11 +13,11 @@
can render all HTML on server and use client rendering only in few small
places. Without rendering we can incredibly clean code and architecture.
See also [Evil Front], a pack of helpers for Ruby on Rails and Evil Blocks.
-Sponsored by [Evil Martians]. Role aliases was taken from [Role.js].
+Sponsored by [Evil Martians]. Role aliases were taken from [Role.js].
[Role.js]: https://github.com/kossnocorp/role
[big price]: http://staal.io/blog/2014/02/05/2-way-data-binding-under-the-microscope/
[Evil Front]: https://github.com/ai/evil-front
[Evil Martians]: http://evilmartians.com/
@@ -83,11 +83,12 @@
</ul>
</div>
```
Evil Blocks extends Slim and jQuery, so you can use shortcuts for this
-attributes: `@@block` and `@role`:
+attributes: `@@block` and `@role`. For Haml you can use [Role Block Haml] gem
+to use same shortcuts.
```haml
@@todo
ul@tasks
```
@@ -104,10 +105,12 @@
```
Of course, Evil Block doesn’t force you to use only this selectors.
You can any attributes, that you like.
+[Role Block Haml]: https://github.com/vladson/role_block_haml
+
## Blocks
You should split your interface to independent controls and mark them
with `data-block`:
@@ -231,42 +234,44 @@
'hashchange on window': ->
@openPage(location.hash)
```
+Listener `load on window` will execute immediately, if window is already loaded.
+
[evil-front/links]: https://github.com/ai/evil-front/blob/master/evil-front/lib/assets/javascripts/evil-front/links.js
## Blocks Communications
Blocks should communicates by custom jQuery events. You can bind event listener
to block node by `"on events"` method:
```coffee
-evil.block '@@slideshow', ->
+evil.block '@@slideshow',
nextSlide: -> …
'on play': ->
@timer = setInterval(=> @nextSlide, 5000)
'on stop': ->
clearInterval(@timer)
-evil.block '@@video', ->
+evil.block '@@video',
'click on @fullscreenButton': ->
$('@@slideshow').trigger('stop')
```
If you want to use broadcast messages, you can use custom events on body:
```coffee
-evil.block '@@callUs', ->
+evil.block '@@callUs',
'change-city on body': (e, city) ->
@phoneNumber.text(city.phone)
-evil.block '@@cityChanger', ->
+evil.block '@@cityChanger',
getCurrentCity: -> …
'change on @citySelect': ->
$('body').trigger('change-city', @getCurrentCity())
```
@@ -316,10 +321,78 @@
@preview.html(html)
```
[big price]: http://staal.io/blog/2014/02/05/2-way-data-binding-under-the-microscope/
+## Debug
+
+Evil Blocks contains debug extension, which log every events inside blocks.
+To enable it, just load `evil-blocks.debug.js`. For example, in Rails:
+
+```haml
+- if Rails.env.development?
+ = javascript_include_tag 'evil-blocks.debug'
+```
+
+## Extensions
+
+Evil Blocks has tiny core. It only finds blocks by selectors, sets `@block`
+property and calls `init` method. Any others features (like event bindings
+or `@$()` method) was created by filters and can be disabled or replaced.
+
+Before calling `init`, Evil Blocks processes object throw the filters list in
+`evil.block.filters`. Filter accepts object as first argument and unique
+class ID as second. It can find some properties in object, work with block
+DOM nodes and add/remove some object properties. If filter will return `false`,
+Evil Blocks will stop block vitalizing and will not call `init` method.
+
+Default filters:
+
+1. **Don’t vitalize same DOM node twice.** It return `false` if block
+ was already initialized with this class ID.
+2. **Add `@$()` method.** It add shortcut find method to object.
+3. **Add shortcuts to `@element`.** It add properties for all children with
+ `data-role` attribute.
+4. **Bind block events.** Find, bind listeners and remove all methods with
+ name like `on event`.
+5. **Smarter window load listener.** Run `load on window` listener immediately,
+ if window is already loaded.
+6. **Bind window and body events.** Find, bind listeners and remove all methods
+ with name like `event on window` or `event on body`.
+7. **Bind elements events.** Find, bind listeners and remove all methods
+ with name like `event on child`.
+
+You can add you own filter to `evil.block.filters`. Most filters should be added
+after first filter to not been called on already initialized blocks.
+
+Let’s write filter, which will initialize blocks only when they become to be
+visible.
+
+```coffee
+filter = (obj) ->
+ if not obj.block.is(':visible')
+ # Check for visibility every 100 ms
+ # and recall vitalizing if block become visible
+ checking = ->
+ evil.block.vitalize(obj.block) if obj.block.is(':visible')
+ setTimeout(checking, 100);
+
+ # Disable block initializing
+ return false
+
+# Add filter to list
+evil.block.filters.splice(0, 0, filter)
+```
+
+With filters you can change Evil Blocks logic, add some new shortcuts or
+features like mixins.
+
+Also you can remove any default filters from `evil.block.filters`. For example,
+you can create properties for `data-role` children only from some white list.
+
+But Filters API is still unstable and you should be careful on major updates.
+
## Modules
If your blocks has same behavior, you can create module-block and set
multiple blocks on same tag:
@@ -327,16 +400,16 @@
@popup@@closable
a@closeLink href="#"
```
```coffee
-evil.block '@@closable', ->
+evil.block '@@closable',
'click on @closeLink': ->
@block.trigger('close')
-evil.block '@@popup', ->
+evil.block '@@popup',
'on close': ->
@clock.removeClass('is-open')
```
@@ -359,20 +432,10 @@
'click on @showExampleButton': ->
@openInFancybox(@example)
```
-## Debug
-
-Evil Blocks contains debug extension, which log every events inside blocks.
-To enable it, just load `evil-block.debug.js`. For example, in Rails:
-
-```haml
-- if Rails.env.development?
- = javascript_include_tag 'evil-block.debug'
-```
-
## Install
### Ruby on Rails
Add `evil-block-rails` gem to `Gemfile`:
@@ -384,9 +447,12 @@
Load `evil-blocks.js` in your script:
```js
//= require evil-blocks
```
+
+If you use Rails 3 on Heroku, you may need
+[some hack](https://github.com/ai/evil-blocks/issues/17).
### Ruby
If you use Sinatra or other non-Rails framework you can add Evil Blocks path
to Sprockets environment: