inkwell_timelines 1.0.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/MIT-LICENSE +20 -0
- data/README.md +187 -0
- data/Rakefile +40 -0
- data/app/assets/images/inkwell_timelines/checkbox-checked.png +0 -0
- data/app/assets/images/inkwell_timelines/checkbox-unchecked.png +0 -0
- data/app/assets/images/inkwell_timelines/minus.png +0 -0
- data/app/assets/images/inkwell_timelines/plus.png +0 -0
- data/app/assets/images/inkwell_timelines/radiobutton_no.png +0 -0
- data/app/assets/images/inkwell_timelines/radiobutton_yes.png +0 -0
- data/app/assets/images/inkwell_timelines/up-down.png +0 -0
- data/app/assets/images/inkwell_timelines/wi-comment-hover.png +0 -0
- data/app/assets/images/inkwell_timelines/wi-comment.png +0 -0
- data/app/assets/images/inkwell_timelines/wi-favorite-active.png +0 -0
- data/app/assets/images/inkwell_timelines/wi-favorite-hover.png +0 -0
- data/app/assets/images/inkwell_timelines/wi-favorite.png +0 -0
- data/app/assets/images/inkwell_timelines/wi-reblog-active.png +0 -0
- data/app/assets/images/inkwell_timelines/wi-reblog-hover.png +0 -0
- data/app/assets/images/inkwell_timelines/wi-reblog.png +0 -0
- data/app/assets/javascripts/inkwell_timelines/index.js.erb +17 -0
- data/app/assets/javascripts/inkwell_timelines/inkwell_multi_selector.js +216 -0
- data/app/assets/javascripts/inkwell_timelines/inkwell_timeline.js.erb +149 -0
- data/app/assets/stylesheets/inkwell_timelines/index.css +30 -0
- data/app/assets/stylesheets/inkwell_timelines/multi_selector.css.erb +112 -0
- data/app/assets/stylesheets/inkwell_timelines/tab-menu.css +26 -0
- data/app/assets/stylesheets/inkwell_timelines/wall_item.css.erb +106 -0
- data/app/controllers/inkwell_timelines/application_controller.rb +4 -0
- data/app/helpers/inkwell_timelines/application_helper.rb +4 -0
- data/app/views/default_partials/_comment.html.erb +21 -0
- data/app/views/default_partials/_multi_selector.html.erb +15 -0
- data/app/views/default_partials/_multi_selector_items.html.erb +8 -0
- data/app/views/default_partials/_post.html.erb +22 -0
- data/app/views/default_partials/_tab_menu.html.erb +9 -0
- data/app/views/layouts/inkwell_timelines/application.html.erb +14 -0
- data/config/routes.rb +2 -0
- data/lib/inkwell_timelines.rb +6 -0
- data/lib/inkwell_timelines/engine.rb +5 -0
- data/lib/inkwell_timelines/version.rb +3 -0
- data/lib/main/to_controller.rb +22 -0
- data/lib/main/to_helpers.rb +93 -0
- data/lib/tasks/inkwell_timelines_tasks.rake +4 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +16 -0
- data/test/dummy/app/assets/javascripts/test.js +2 -0
- data/test/dummy/app/assets/stylesheets/application.css +14 -0
- data/test/dummy/app/assets/stylesheets/test.css +4 -0
- data/test/dummy/app/controllers/application_controller.rb +9 -0
- data/test/dummy/app/controllers/test_controller.rb +5 -0
- data/test/dummy/app/controllers/timeline_controller.rb +11 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/helpers/test_helper.rb +2 -0
- data/test/dummy/app/models/blogline.rb +3 -0
- data/test/dummy/app/models/bloglines_categories.rb +3 -0
- data/test/dummy/app/models/category.rb +7 -0
- data/test/dummy/app/models/comment.rb +16 -0
- data/test/dummy/app/models/favoriteline.rb +3 -0
- data/test/dummy/app/models/post.rb +16 -0
- data/test/dummy/app/models/user.rb +109 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/test/show.html.erb +1 -0
- data/test/dummy/app/views/timeline/show.html.erb +1 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/inkwell_timelines.rb +42 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +5 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20130422111954_create_posts.rb +16 -0
- data/test/dummy/db/migrate/20130422112200_create_users.rb +10 -0
- data/test/dummy/db/migrate/20130422112350_create_comments.rb +16 -0
- data/test/dummy/db/migrate/20130422112504_create_bloglines.rb +13 -0
- data/test/dummy/db/migrate/20130422112804_create_favoritelines.rb +11 -0
- data/test/dummy/db/migrate/20130422112954_create_categories.rb +14 -0
- data/test/dummy/db/migrate/20130422113135_create_bloglines_categories.rb +12 -0
- data/test/dummy/db/schema.rb +92 -0
- data/test/dummy/db/seeds.rb +625 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +104306 -0
- data/test/dummy/log/test.log +815 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/spec/helpers/test_helper_spec.rb +8 -0
- data/test/dummy/spec/spec_helper.rb +52 -0
- data/test/dummy/spec/watir/autoload_spec.rb +33 -0
- data/test/dummy/spec/watir/main_spec.rb +80 -0
- data/test/dummy/spec/watir/selector_spec.rb +103 -0
- data/test/dummy/spec/watir/tab_menu_spec.rb +36 -0
- data/test/dummy/tmp/cache/assets/C56/8F0/sprockets%2F1ad046fb9937420d5382984483fc8401 +0 -0
- data/test/dummy/tmp/cache/assets/C63/420/sprockets%2F5daa64d9601a1dd14726112003d08364 +0 -0
- data/test/dummy/tmp/cache/assets/C65/790/sprockets%2Feacce513669090988829f66e61634451 +0 -0
- data/test/dummy/tmp/cache/assets/C77/DD0/sprockets%2F055f9cd12326c5150492b8c584314fa3 +0 -0
- data/test/dummy/tmp/cache/assets/C84/E70/sprockets%2F0530f24346bbf970634035b6e55f886e +0 -0
- data/test/dummy/tmp/cache/assets/C85/420/sprockets%2F4734da42d41574596ab532629d0867ec +0 -0
- data/test/dummy/tmp/cache/assets/C87/A50/sprockets%2F667342f892546b573c52d11f814ae4f3 +0 -0
- data/test/dummy/tmp/cache/assets/CA1/750/sprockets%2Fa8471b3ea18986e7368e8273a95865e8 +0 -0
- data/test/dummy/tmp/cache/assets/CAC/DB0/sprockets%2Fc424393ee4e4f66aa4014619048753cb +0 -0
- data/test/dummy/tmp/cache/assets/CB2/170/sprockets%2F4479eb189646408ec3130b45153ebf7b +0 -0
- data/test/dummy/tmp/cache/assets/CB9/630/sprockets%2Fe5952cc2ece61727517547af4232892e +0 -0
- data/test/dummy/tmp/cache/assets/CBD/960/sprockets%2F5a35c922c979e889b0338374a9b3f4b0 +0 -0
- data/test/dummy/tmp/cache/assets/CC4/730/sprockets%2F78d0941e0543313bbb0a9f0cf630030d +0 -0
- data/test/dummy/tmp/cache/assets/CD1/F50/sprockets%2Fbf2261613d1c32c54a6e38a7673531fa +0 -0
- data/test/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/CD9/1E0/sprockets%2F293460f7bea2aea456231b769212f36f +0 -0
- data/test/dummy/tmp/cache/assets/CDC/EC0/sprockets%2Ff9a21d40846491577ab5ebe00de07077 +0 -0
- data/test/dummy/tmp/cache/assets/CE6/8D0/sprockets%2F9e823d2b49662dbb4389f2841a23e8c1 +0 -0
- data/test/dummy/tmp/cache/assets/CEE/110/sprockets%2Faf0654ff711843e082592cd70cf89a88 +0 -0
- data/test/dummy/tmp/cache/assets/CEE/490/sprockets%2F97139dc7ad35759531fc7fa572f0c761 +0 -0
- data/test/dummy/tmp/cache/assets/CF9/6F0/sprockets%2F952426cea414c6c2a04cc1216a1f36f5 +0 -0
- data/test/dummy/tmp/cache/assets/CFA/DE0/sprockets%2F25bf1e7766a300a4c37195df0cbb1107 +0 -0
- data/test/dummy/tmp/cache/assets/CFB/A10/sprockets%2F72699e3ed6f9c3984a718b62932ba66e +0 -0
- data/test/dummy/tmp/cache/assets/CFC/640/sprockets%2Fc7f89943cb904e76b2437e59348cc5c9 +0 -0
- data/test/dummy/tmp/cache/assets/D13/0C0/sprockets%2F218a6e24bfe5005a8a86798baa2585c8 +0 -0
- data/test/dummy/tmp/cache/assets/D13/3B0/sprockets%2F00cf5d507582a705af9694cde93ba186 +0 -0
- data/test/dummy/tmp/cache/assets/D13/6A0/sprockets%2F4819aa020210496ecf49ee70b78e8be6 +0 -0
- data/test/dummy/tmp/cache/assets/D15/560/sprockets%2Ff0007939832a29a27abe3a9579eed81c +0 -0
- data/test/dummy/tmp/cache/assets/D16/860/sprockets%2Fb45890d98668c132fee5cae4b15320d9 +0 -0
- data/test/dummy/tmp/cache/assets/D1A/150/sprockets%2F49ad9f8620b7712e6f2d4fc2e354e545 +0 -0
- data/test/dummy/tmp/cache/assets/D20/4F0/sprockets%2Fb15d3257899ad89007d1348eb9a5f5fe +0 -0
- data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/D36/810/sprockets%2Fb84416b6a4f5a39b0bc23ab72ad94279 +0 -0
- data/test/dummy/tmp/cache/assets/D39/390/sprockets%2F3c87a321da4296312f18efc704cd6d2f +0 -0
- data/test/dummy/tmp/cache/assets/D3A/260/sprockets%2F69551919ec05c0eb11e55bb59dc143ec +0 -0
- data/test/dummy/tmp/cache/assets/D41/350/sprockets%2F2111b16bc0081c14b803cfd350eb4baa +0 -0
- data/test/dummy/tmp/cache/assets/D43/D20/sprockets%2Fbcbf2f35591e507593ec6116eac6e924 +0 -0
- data/test/dummy/tmp/cache/assets/D48/3C0/sprockets%2F41be77d9f6b62168967ca14ccc6b51d6 +0 -0
- data/test/dummy/tmp/cache/assets/D4D/7C0/sprockets%2F5f4f24c2540cffe8b3c5e835756c35f7 +0 -0
- data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/dummy/tmp/cache/assets/D51/6A0/sprockets%2F80b05d6f75c78bdb1e450c898e47d97a +0 -0
- data/test/dummy/tmp/cache/assets/D56/4C0/sprockets%2F66059379b6c72ffe570f4ae394a89eda +0 -0
- data/test/dummy/tmp/cache/assets/D56/D30/sprockets%2Fe910c76d93fd4da6984d82e469f62f0c +0 -0
- data/test/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/D65/600/sprockets%2Fdaa0e3c217673cb0ebb89d97438a1b80 +0 -0
- data/test/dummy/tmp/cache/assets/D66/6C0/sprockets%2Fa06355ade2a095c01afd8c6f5e67019d +0 -0
- data/test/dummy/tmp/cache/assets/D6A/E70/sprockets%2Fc9f71142e4d4a807cb6be80451f74adb +0 -0
- data/test/dummy/tmp/cache/assets/D76/E50/sprockets%2F6289e3eb865565eab3fdfb4fae810702 +0 -0
- data/test/dummy/tmp/cache/assets/D86/6A0/sprockets%2Fac97d7e4e37faa819a833c7c52c9e687 +0 -0
- data/test/dummy/tmp/cache/assets/D91/C00/sprockets%2Fb1cf6c48f161db0a058d10817ddd5e5b +0 -0
- data/test/dummy/tmp/cache/assets/D9C/C90/sprockets%2Fa903431f8703bbaafcae42e4f4692ff8 +0 -0
- data/test/dummy/tmp/cache/assets/DA0/C60/sprockets%2F90d8e40e6baa19d6556ab9c6ac891a2e +0 -0
- data/test/dummy/tmp/cache/assets/DA1/F90/sprockets%2F3bd196480867f8e3c74b10dbcbbe1f9b +0 -0
- data/test/dummy/tmp/cache/assets/DA7/EE0/sprockets%2Ffced4a1e089dc82bf773475da4e53c46 +0 -0
- data/test/dummy/tmp/cache/assets/DA9/4D0/sprockets%2F3d68828b990fbfa9cdf51daa76c242d5 +0 -0
- data/test/dummy/tmp/cache/assets/DB5/4C0/sprockets%2F5e815df4827231fe949b2f9bffd0d9de +0 -0
- data/test/dummy/tmp/cache/assets/DB6/910/sprockets%2F3c19b64141a5ceeccf3a3baf4c452a06 +0 -0
- data/test/dummy/tmp/cache/assets/DC4/8D0/sprockets%2Fd8daccd2ece841a83a2a584c50e352d5 +0 -0
- data/test/dummy/tmp/cache/assets/DCC/6A0/sprockets%2Fa92fb625cc83fe72fc4115e2fb2ed61e +0 -0
- data/test/dummy/tmp/cache/assets/DCC/940/sprockets%2Fe7f0ee8bf122b8b72b8e3c7cd13a5d81 +0 -0
- data/test/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/E08/E50/sprockets%2F22c72aded517c5cdf8cce6f4b58c76b8 +0 -0
- data/test/dummy/tmp/cache/assets/E24/740/sprockets%2F2ecee9c0ae221af87da9c5d034c8dd0c +0 -0
- data/test/dummy/tmp/cache/assets/E2D/160/sprockets%2Fdb479da69eeed6322f3b8dab3bf91bb0 +0 -0
- data/test/dummy/tmp/cache/assets/E4C/810/sprockets%2Fdaf244418a8cfda1aca3e32dbdf17fd2 +0 -0
- data/test/dummy/tmp/pids/server.pid +1 -0
- data/test/screen/main.png +0 -0
- data/test/test_helper.rb +15 -0
- metadata +413 -0
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright 2013 Sergey Sokolov
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# Inkwell Timelines
|
|
2
|
+
|
|
3
|
+
Inkwell Timelines provides simple way to create timelines with autoload content while scrolling with ability to transmit the additional parameters.
|
|
4
|
+
It allows you to place timeline blocks on the pages - one block per page.
|
|
5
|
+
|
|
6
|
+
Each block can consist of several timelines (Blog and Favorite timelines on the screenshot).
|
|
7
|
+
|
|
8
|
+
Each timeline can consist of several types objects (Posts and Comments on the screenshot) with different templates to form them.
|
|
9
|
+
|
|
10
|
+
Timeline can consist of selectors ( category selector on the screenshot) to customize received data (for example, you can get timeline with only one category's items).
|
|
11
|
+
|
|
12
|
+
Timelines autoload next items when it is scrolled to the end.
|
|
13
|
+
|
|
14
|
+

|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
Put in `Gemfile`:
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
gem 'inkwell_timelines', :git => 'https://github.com/salkar/inkwell_timelines.git'
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
After it do `bundle install`
|
|
25
|
+
|
|
26
|
+
Create `inkwell_timelines.rb` file in `config/initializers` and put in it your settings:
|
|
27
|
+
|
|
28
|
+
```ruby
|
|
29
|
+
module InkwellTimelines
|
|
30
|
+
class Engine < Rails::Engine
|
|
31
|
+
# Pixels count between current scroll position and page's end at which the autoload start
|
|
32
|
+
config.load_distance = 150
|
|
33
|
+
config.autoload_path = 'timeline/get/' # Autoload controller path
|
|
34
|
+
# Optional. If defined all partials will be searched here
|
|
35
|
+
config.partials_dir = 'your path to partials'
|
|
36
|
+
config.timeline_blocks = [
|
|
37
|
+
{ # First timelines block
|
|
38
|
+
:id => 'timelines_block', # Block id
|
|
39
|
+
:timelines => [
|
|
40
|
+
{
|
|
41
|
+
:id => 'blogline', # First timeline id
|
|
42
|
+
:name => 'Blog', # First timeline displayed name
|
|
43
|
+
:active => true, # Defines which timeline is active at first load
|
|
44
|
+
:data_get => ->(options = {}) { # Lambda which get data for form this timeline
|
|
45
|
+
user = User.find options[:user_id]
|
|
46
|
+
# Function that return array of objects (for example - posts and comments in dummy app)
|
|
47
|
+
user.blogline options
|
|
48
|
+
},
|
|
49
|
+
# Array of params (of options in :data_get) saved on client side and sent to server on autoload
|
|
50
|
+
:transferred_params => [:user_id],
|
|
51
|
+
# Add selector to customize received data (sampling by Category on the screenshot)
|
|
52
|
+
:multi_selectors => [
|
|
53
|
+
{
|
|
54
|
+
:id => 'category', # Selector id
|
|
55
|
+
:name => 'Category', # Selector displayed name (see screenshot)
|
|
56
|
+
:data_get => ->(options = {}) { # Lambda which get objects for form selector
|
|
57
|
+
Category.where(:owner_id => options[:user_id], :owner_type => 'u')
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
:id => 'favoriteline', # Second timeline id
|
|
65
|
+
:name => 'Favorite', # Second timeline displayed name
|
|
66
|
+
:data_get => ->(options = {}) { # Lambda which get data for form this timeline
|
|
67
|
+
user = User.find options[:user_id]
|
|
68
|
+
user.favoriteline options
|
|
69
|
+
},
|
|
70
|
+
# Transferred through client params (timeline owner in this case)
|
|
71
|
+
:transferred_params => [:user_id]
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Next, add ` //= require inkwell_timelines` to your js assets (for example - to application.js) and `*= require inkwell_timelines` to your stylesheets assets (for example - to application.css).
|
|
81
|
+
|
|
82
|
+
*Notice: if you want to modify CSS or JS you can add your modified files and not add default styles/js*
|
|
83
|
+
|
|
84
|
+
Default partials are located inside the gem - [here](https://github.com/salkar/inkwell_timelines/tree/master/app/views/default_partials).
|
|
85
|
+
You can change this directory to your adding `config.partials_dir = 'your path to partials'` parameter in your `inkwell_timelines.rb` file.
|
|
86
|
+
|
|
87
|
+
By default, there are 5 partials in this gem (you can change all of them):
|
|
88
|
+
|
|
89
|
+
```ruby
|
|
90
|
+
_comment.html.erb # Partial for timeline item for comment object
|
|
91
|
+
_multi_selector.html.erb # Partial for selector
|
|
92
|
+
_multi_selector_items.html.erb # Support partial for selector
|
|
93
|
+
_post.html.erb # Partial for post item for comment object
|
|
94
|
+
_tab_menu.html.erb # Partial for timelines block menu
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If there are other objects except posts and comments - add partials for them.
|
|
98
|
+
|
|
99
|
+
## Usage
|
|
100
|
+
|
|
101
|
+
To form the timeline block for the first showing add into your view:
|
|
102
|
+
```ruby
|
|
103
|
+
<%= inkwell_timelines_tag(block_id, options = {} %>
|
|
104
|
+
```
|
|
105
|
+
For example:
|
|
106
|
+
```ruby
|
|
107
|
+
<%= inkwell_timelines_tag('timelines_block',
|
|
108
|
+
:user_id => User.where(:nick => 'Pushkin').first.id,
|
|
109
|
+
:for_user => current_user) %>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
*Notice: config for this block should be*
|
|
113
|
+
|
|
114
|
+
To on autoload feature create controller for it, add it in the `routes`, add its route to timeline config. For example:
|
|
115
|
+
|
|
116
|
+
* add `controllers/timeline_controller.rb`
|
|
117
|
+
```ruby
|
|
118
|
+
class TimelineController < ApplicationController
|
|
119
|
+
def show
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
* add route for it -
|
|
125
|
+
```ruby
|
|
126
|
+
match "/timeline/get" => "timeline#show"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
* add its route to timelines config:
|
|
130
|
+
```ruby
|
|
131
|
+
config.autoload_path = 'timeline/get/'
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Next, add to created controller:
|
|
135
|
+
```ruby
|
|
136
|
+
@options = inkwell_timelines_get_params(request.body, :additional options => {})
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`inkwell_timelines_get_params` forms options for autoload timeline part generation.
|
|
140
|
+
Additional options needs to merge stored on the server with transferred from client options.
|
|
141
|
+
You may want to save some options on the server for security reasons (for example - `current_user` should not be sent to the client because there it can be changed).
|
|
142
|
+
|
|
143
|
+
Here you can check the options that came with the client.
|
|
144
|
+
|
|
145
|
+
At the end of autoload controller method add
|
|
146
|
+
```ruby
|
|
147
|
+
render :layout => false
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Example:
|
|
151
|
+
|
|
152
|
+
```ruby
|
|
153
|
+
class TimelineController < ApplicationController
|
|
154
|
+
def show
|
|
155
|
+
@options = inkwell_timelines_get_params(request.body, :for_user => current_user)
|
|
156
|
+
|
|
157
|
+
#Here you can check came from js options. For exapmle:
|
|
158
|
+
user = User.find @options[:user_id]
|
|
159
|
+
raise "current user has no permissions to see #{user.nick} timeline" unless current_user.can_see_timeline user
|
|
160
|
+
|
|
161
|
+
render :layout => false
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
After it create view file for autoload method in controller (in our cases - `views/timeline/show.html.erb`) and add to it
|
|
167
|
+
```ruby
|
|
168
|
+
<%= inkwell_timelines_autoload_tag(@options) %>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Sample
|
|
172
|
+
|
|
173
|
+
Sample located [here](https://github.com/salkar/inkwell_timelines/tree/master/test/dummy).
|
|
174
|
+
To run it:
|
|
175
|
+
```bash
|
|
176
|
+
$ cd inkwell_timelines/test/dummy
|
|
177
|
+
$ bundle install
|
|
178
|
+
$ rake db:create
|
|
179
|
+
$ rake db:migrate
|
|
180
|
+
$ rake db:seed
|
|
181
|
+
$ rails s
|
|
182
|
+
```
|
|
183
|
+
And go to `http://0.0.0.0:3000/` in your browser after it.
|
|
184
|
+
|
|
185
|
+
## License
|
|
186
|
+
|
|
187
|
+
Inkwell is Copyright © 2013 Sergey Sokolov. It is free software, and may be redistributed under the terms specified in the MIT-LICENSE file.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env rake
|
|
2
|
+
begin
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
rescue LoadError
|
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
6
|
+
end
|
|
7
|
+
begin
|
|
8
|
+
require 'rdoc/task'
|
|
9
|
+
rescue LoadError
|
|
10
|
+
require 'rdoc/rdoc'
|
|
11
|
+
require 'rake/rdoctask'
|
|
12
|
+
RDoc::Task = Rake::RDocTask
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
17
|
+
rdoc.title = 'InkwellTimelines'
|
|
18
|
+
rdoc.options << '--line-numbers'
|
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
|
24
|
+
load 'rails/tasks/engine.rake'
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
Bundler::GemHelper.install_tasks
|
|
29
|
+
|
|
30
|
+
require 'rake/testtask'
|
|
31
|
+
|
|
32
|
+
Rake::TestTask.new(:test) do |t|
|
|
33
|
+
t.libs << 'lib'
|
|
34
|
+
t.libs << 'test'
|
|
35
|
+
t.pattern = 'test/**/*_test.rb'
|
|
36
|
+
t.verbose = false
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
task :default => :test
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
|
2
|
+
// listed below.
|
|
3
|
+
//
|
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
|
6
|
+
//
|
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
|
8
|
+
// the compiled file.
|
|
9
|
+
//
|
|
10
|
+
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
|
11
|
+
// GO AFTER THE REQUIRES BELOW.
|
|
12
|
+
//
|
|
13
|
+
//= require jquery
|
|
14
|
+
//= require jquery_ujs
|
|
15
|
+
//= require_tree .
|
|
16
|
+
|
|
17
|
+
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
var inkwell_multi_selector = {
|
|
2
|
+
popup_shown: false,
|
|
3
|
+
current_state: null,
|
|
4
|
+
|
|
5
|
+
state_changed: $.Event('state_changed'),
|
|
6
|
+
|
|
7
|
+
show_popup: function (action_obj) {
|
|
8
|
+
this.popup_shown = true;
|
|
9
|
+
this.current_state = $(action_obj.parent().children('.current_state')[0]).children().text();
|
|
10
|
+
action_obj.addClass('on');
|
|
11
|
+
action_obj.find('.dropdown').show();
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
hide_popup: function (action_obj) {
|
|
15
|
+
if (this.popup_shown) {
|
|
16
|
+
if (!action_obj) {
|
|
17
|
+
var dropdown = $('.inkwell_multi_selector .dropdown:visible');
|
|
18
|
+
action_obj = dropdown.closest('.inkwell_multi_selector .action');
|
|
19
|
+
}
|
|
20
|
+
this.popup_shown = false;
|
|
21
|
+
action_obj.removeClass('on');
|
|
22
|
+
action_obj.find('.dropdown').hide();
|
|
23
|
+
if (inkwell_multi_selector.has_changes(action_obj)) {
|
|
24
|
+
$($(action_obj).closest('.inkwell_multi_selector')).trigger(this.state_changed);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
has_changes: function (action_obj) {
|
|
30
|
+
result = ($(action_obj.parent().children('.current_state')[0]).children().text() != this.current_state);
|
|
31
|
+
current_state = null;
|
|
32
|
+
return result;
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
uncheck_upper_checkboxes: function (next_parent, state_panel, selector_name) {
|
|
36
|
+
var checkboxes = $(next_parent).children('.checked.checkbox_with_label');
|
|
37
|
+
if (checkboxes.length == 0) return;
|
|
38
|
+
$(checkboxes).each(function () {
|
|
39
|
+
$(state_panel).children('#inkwell_' + selector_name + '_state_' + inkwell_multi_selector.get_id_from_attr_id($(this).attr('id'))).remove();
|
|
40
|
+
});
|
|
41
|
+
$(checkboxes).removeClass('checked');
|
|
42
|
+
|
|
43
|
+
if (next_parent.hasClass('nested')) {
|
|
44
|
+
var same_level_divs = next_parent.parent().children('.nested');
|
|
45
|
+
$(same_level_divs).each(function () {
|
|
46
|
+
var checked_checkbox = $(this).children('.checked');
|
|
47
|
+
if (checked_checkbox.length != 0) {
|
|
48
|
+
var id = inkwell_multi_selector.get_id_from_attr_id($(checked_checkbox).attr('id'));
|
|
49
|
+
inkwell_multi_selector.add_state(state_panel, selector_name, id, checked_checkbox.text());
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
inkwell_multi_selector.uncheck_upper_checkboxes(next_parent.parent(), state_panel, selector_name);
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
uncheck_tree: function (checkbox) {
|
|
59
|
+
checkbox.parent().find('.checked').removeClass('checked');
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
action_click_handler: function (action, event) {
|
|
63
|
+
if ($(event.target).hasClass('dropdown') || $(event.target).closest('.inkwell_multi_selector .dropdown').length != 0) return;
|
|
64
|
+
inkwell_multi_selector.popup_shown ?
|
|
65
|
+
inkwell_multi_selector.hide_popup(action) :
|
|
66
|
+
inkwell_multi_selector.show_popup(action);
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
get_children_checkboxes: function (checkbox, all_levels) {
|
|
70
|
+
var result = [];
|
|
71
|
+
var child_divs = checkbox.parent().children('.nested');
|
|
72
|
+
child_divs.each(function () {
|
|
73
|
+
if (all_levels) result = $.merge(result, $(this).find('.checkbox_with_label'))
|
|
74
|
+
else result.push($(this).children('.checkbox_with_label')[0]);
|
|
75
|
+
});
|
|
76
|
+
return result;
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
uncheck_checkbox: function (checkbox) {
|
|
80
|
+
var selector = checkbox.closest('.inkwell_multi_selector');
|
|
81
|
+
var state_panel = selector.children('.current_state')[0];
|
|
82
|
+
var selector_name = inkwell_multi_selector.get_selector_name(selector);
|
|
83
|
+
|
|
84
|
+
$(checkbox).removeClass('checked');
|
|
85
|
+
inkwell_multi_selector.change_state_on_uncheck($(checkbox), state_panel, selector_name);
|
|
86
|
+
inkwell_multi_selector.uncheck_upper_checkboxes($(checkbox).parents(':eq(1)'), state_panel, selector_name);
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
add_state: function (state_panel, selector_name, id, text) {
|
|
90
|
+
$(state_panel).append(' <span id="inkwell_' + selector_name + '_state_' + id + '">' + text + '</span>');
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
change_state_on_uncheck: function (checkbox, state_panel, selector_name) {
|
|
94
|
+
var id = inkwell_multi_selector.get_id_from_attr_id(checkbox.attr('id'));
|
|
95
|
+
|
|
96
|
+
$(state_panel).children('#inkwell_' + selector_name + '_state_' + id).remove();
|
|
97
|
+
|
|
98
|
+
var child_checkboxes = inkwell_multi_selector.get_children_checkboxes(checkbox, false);
|
|
99
|
+
$(child_checkboxes).each(function () {
|
|
100
|
+
$(state_panel).append(' <span id="inkwell_' + selector_name + '_state_' + inkwell_multi_selector.get_id_from_attr_id($(this).attr('id')) + '">' + $(this).text() + '</span>');
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
var same_level_divs = checkbox.parents(':eq(1)').children('.nested');
|
|
104
|
+
$(same_level_divs).each(function () {
|
|
105
|
+
var checked_checkbox = $(this).children('.checked');
|
|
106
|
+
if (checked_checkbox.length != 0) {
|
|
107
|
+
var id = inkwell_multi_selector.get_id_from_attr_id($(checked_checkbox).attr('id'));
|
|
108
|
+
inkwell_multi_selector.add_state(state_panel, selector_name, id, checked_checkbox.text());
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
});
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
top_checked_checkboxes_ids: function (selector) {
|
|
115
|
+
var result = [];
|
|
116
|
+
selector.children('.current_state').children('span').each(function () {
|
|
117
|
+
var splitted_id = $(this).attr('id').split('_');
|
|
118
|
+
result.push(splitted_id[splitted_id.length - 1]);
|
|
119
|
+
});
|
|
120
|
+
return result;
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
is_all_checked: function (selector) {
|
|
124
|
+
var first_level_divs = selector.find('.dropdown').children('div');
|
|
125
|
+
var result = true;
|
|
126
|
+
first_level_divs.each(function () {
|
|
127
|
+
if (!result) return;
|
|
128
|
+
if (!$(this).children('.checkbox_with_label').hasClass('checked')) {
|
|
129
|
+
result = false;
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
return result;
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
change_state_on_check: function (checkbox) {
|
|
136
|
+
var selector = checkbox.closest('.inkwell_multi_selector');
|
|
137
|
+
var state_panel = selector.children('.current_state')[0];
|
|
138
|
+
var selector_name = inkwell_multi_selector.get_selector_name(selector);
|
|
139
|
+
|
|
140
|
+
var child_checkboxes = inkwell_multi_selector.get_children_checkboxes(checkbox, true);
|
|
141
|
+
$(child_checkboxes).each(function () {
|
|
142
|
+
$(state_panel).children('#inkwell_' + selector_name + '_state_' + inkwell_multi_selector.get_id_from_attr_id($(this).attr('id'))).remove();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
var id = inkwell_multi_selector.get_id_from_attr_id(checkbox.attr('id'));
|
|
146
|
+
$(state_panel).append(' <span id="inkwell_' + selector_name + '_state_' + id + '">' + checkbox.text() + '</span>');
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
get_id_from_attr_id: function (attr_id) {
|
|
150
|
+
var splitted_id = attr_id.split('_');
|
|
151
|
+
return splitted_id[splitted_id.length - 1];
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
get_selector_name: function (selector) {
|
|
155
|
+
return selector.attr('id').replace('inkwell_', '');
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
state_click_handler: function (state_item) {
|
|
159
|
+
this.current_state = $(state_item).parent().children().text();
|
|
160
|
+
var selector = state_item.closest('.inkwell_multi_selector');
|
|
161
|
+
var dropdown = selector.find('.dropdown');
|
|
162
|
+
var selector_name = inkwell_multi_selector.get_selector_name(selector);
|
|
163
|
+
|
|
164
|
+
var state_items = state_item.parent().children('span');
|
|
165
|
+
$(state_items).each(function () {
|
|
166
|
+
var attr_id = $(this).attr('id');
|
|
167
|
+
if (attr_id != state_item.attr('id')) {
|
|
168
|
+
var id = inkwell_multi_selector.get_id_from_attr_id(attr_id);
|
|
169
|
+
var checkbox = dropdown.find('#inkwell_' + selector_name + '_checkbox_' + id);
|
|
170
|
+
inkwell_multi_selector.uncheck_tree(checkbox);
|
|
171
|
+
$(this).remove();
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
if ($(state_item).parent().children().text() != this.current_state) {
|
|
176
|
+
|
|
177
|
+
$(selector).trigger(this.state_changed);
|
|
178
|
+
}
|
|
179
|
+
current_state = null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
$(document).ready(function () {
|
|
185
|
+
$('.inkwell_timelines').on('click', '.inkwell_multi_selector .action', function (event) {
|
|
186
|
+
inkwell_multi_selector.action_click_handler($(this), event);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
$(document).on('click', function (event) {
|
|
190
|
+
if (!inkwell_multi_selector.popup_shown) return;
|
|
191
|
+
if ($(event.target).closest('.inkwell_multi_selector .action').length == 0) inkwell_multi_selector.hide_popup();
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
$('.inkwell_timelines').on('click', '.inkwell_multi_selector .checkbox_with_label', function () {
|
|
195
|
+
if ($(this).hasClass('checked')) {
|
|
196
|
+
inkwell_multi_selector.uncheck_checkbox($(this));
|
|
197
|
+
} else {
|
|
198
|
+
inkwell_multi_selector.change_state_on_check($(this));
|
|
199
|
+
$(this).parent().find('.checkbox_with_label').addClass('checked');
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
$('.inkwell_timelines').on('click', '.inkwell_multi_selector .collapsed', function () {
|
|
204
|
+
$(this).removeClass('collapsed').addClass('expanded');
|
|
205
|
+
$(this).parent().children('.nested').show();
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
$('.inkwell_timelines').on('click', '.inkwell_multi_selector .expanded', function () {
|
|
209
|
+
$(this).removeClass('expanded').addClass('collapsed');
|
|
210
|
+
$(this).parent().children('.nested').hide();
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
$('.inkwell_timelines').on('click', '.inkwell_multi_selector .current_state span', function() {
|
|
214
|
+
inkwell_multi_selector.state_click_handler($(this));
|
|
215
|
+
});
|
|
216
|
+
});
|