inkwell_timelines 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +187 -0
  3. data/Rakefile +40 -0
  4. data/app/assets/images/inkwell_timelines/checkbox-checked.png +0 -0
  5. data/app/assets/images/inkwell_timelines/checkbox-unchecked.png +0 -0
  6. data/app/assets/images/inkwell_timelines/minus.png +0 -0
  7. data/app/assets/images/inkwell_timelines/plus.png +0 -0
  8. data/app/assets/images/inkwell_timelines/radiobutton_no.png +0 -0
  9. data/app/assets/images/inkwell_timelines/radiobutton_yes.png +0 -0
  10. data/app/assets/images/inkwell_timelines/up-down.png +0 -0
  11. data/app/assets/images/inkwell_timelines/wi-comment-hover.png +0 -0
  12. data/app/assets/images/inkwell_timelines/wi-comment.png +0 -0
  13. data/app/assets/images/inkwell_timelines/wi-favorite-active.png +0 -0
  14. data/app/assets/images/inkwell_timelines/wi-favorite-hover.png +0 -0
  15. data/app/assets/images/inkwell_timelines/wi-favorite.png +0 -0
  16. data/app/assets/images/inkwell_timelines/wi-reblog-active.png +0 -0
  17. data/app/assets/images/inkwell_timelines/wi-reblog-hover.png +0 -0
  18. data/app/assets/images/inkwell_timelines/wi-reblog.png +0 -0
  19. data/app/assets/javascripts/inkwell_timelines/index.js.erb +17 -0
  20. data/app/assets/javascripts/inkwell_timelines/inkwell_multi_selector.js +216 -0
  21. data/app/assets/javascripts/inkwell_timelines/inkwell_timeline.js.erb +149 -0
  22. data/app/assets/stylesheets/inkwell_timelines/index.css +30 -0
  23. data/app/assets/stylesheets/inkwell_timelines/multi_selector.css.erb +112 -0
  24. data/app/assets/stylesheets/inkwell_timelines/tab-menu.css +26 -0
  25. data/app/assets/stylesheets/inkwell_timelines/wall_item.css.erb +106 -0
  26. data/app/controllers/inkwell_timelines/application_controller.rb +4 -0
  27. data/app/helpers/inkwell_timelines/application_helper.rb +4 -0
  28. data/app/views/default_partials/_comment.html.erb +21 -0
  29. data/app/views/default_partials/_multi_selector.html.erb +15 -0
  30. data/app/views/default_partials/_multi_selector_items.html.erb +8 -0
  31. data/app/views/default_partials/_post.html.erb +22 -0
  32. data/app/views/default_partials/_tab_menu.html.erb +9 -0
  33. data/app/views/layouts/inkwell_timelines/application.html.erb +14 -0
  34. data/config/routes.rb +2 -0
  35. data/lib/inkwell_timelines.rb +6 -0
  36. data/lib/inkwell_timelines/engine.rb +5 -0
  37. data/lib/inkwell_timelines/version.rb +3 -0
  38. data/lib/main/to_controller.rb +22 -0
  39. data/lib/main/to_helpers.rb +93 -0
  40. data/lib/tasks/inkwell_timelines_tasks.rake +4 -0
  41. data/test/dummy/Rakefile +7 -0
  42. data/test/dummy/app/assets/javascripts/application.js +16 -0
  43. data/test/dummy/app/assets/javascripts/test.js +2 -0
  44. data/test/dummy/app/assets/stylesheets/application.css +14 -0
  45. data/test/dummy/app/assets/stylesheets/test.css +4 -0
  46. data/test/dummy/app/controllers/application_controller.rb +9 -0
  47. data/test/dummy/app/controllers/test_controller.rb +5 -0
  48. data/test/dummy/app/controllers/timeline_controller.rb +11 -0
  49. data/test/dummy/app/helpers/application_helper.rb +2 -0
  50. data/test/dummy/app/helpers/test_helper.rb +2 -0
  51. data/test/dummy/app/models/blogline.rb +3 -0
  52. data/test/dummy/app/models/bloglines_categories.rb +3 -0
  53. data/test/dummy/app/models/category.rb +7 -0
  54. data/test/dummy/app/models/comment.rb +16 -0
  55. data/test/dummy/app/models/favoriteline.rb +3 -0
  56. data/test/dummy/app/models/post.rb +16 -0
  57. data/test/dummy/app/models/user.rb +109 -0
  58. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  59. data/test/dummy/app/views/test/show.html.erb +1 -0
  60. data/test/dummy/app/views/timeline/show.html.erb +1 -0
  61. data/test/dummy/config.ru +4 -0
  62. data/test/dummy/config/application.rb +59 -0
  63. data/test/dummy/config/boot.rb +10 -0
  64. data/test/dummy/config/database.yml +25 -0
  65. data/test/dummy/config/environment.rb +5 -0
  66. data/test/dummy/config/environments/development.rb +37 -0
  67. data/test/dummy/config/environments/production.rb +67 -0
  68. data/test/dummy/config/environments/test.rb +37 -0
  69. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  70. data/test/dummy/config/initializers/inflections.rb +15 -0
  71. data/test/dummy/config/initializers/inkwell_timelines.rb +42 -0
  72. data/test/dummy/config/initializers/mime_types.rb +5 -0
  73. data/test/dummy/config/initializers/secret_token.rb +7 -0
  74. data/test/dummy/config/initializers/session_store.rb +8 -0
  75. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  76. data/test/dummy/config/locales/en.yml +5 -0
  77. data/test/dummy/config/routes.rb +5 -0
  78. data/test/dummy/db/development.sqlite3 +0 -0
  79. data/test/dummy/db/migrate/20130422111954_create_posts.rb +16 -0
  80. data/test/dummy/db/migrate/20130422112200_create_users.rb +10 -0
  81. data/test/dummy/db/migrate/20130422112350_create_comments.rb +16 -0
  82. data/test/dummy/db/migrate/20130422112504_create_bloglines.rb +13 -0
  83. data/test/dummy/db/migrate/20130422112804_create_favoritelines.rb +11 -0
  84. data/test/dummy/db/migrate/20130422112954_create_categories.rb +14 -0
  85. data/test/dummy/db/migrate/20130422113135_create_bloglines_categories.rb +12 -0
  86. data/test/dummy/db/schema.rb +92 -0
  87. data/test/dummy/db/seeds.rb +625 -0
  88. data/test/dummy/db/test.sqlite3 +0 -0
  89. data/test/dummy/log/development.log +104306 -0
  90. data/test/dummy/log/test.log +815 -0
  91. data/test/dummy/public/404.html +26 -0
  92. data/test/dummy/public/422.html +26 -0
  93. data/test/dummy/public/500.html +25 -0
  94. data/test/dummy/public/favicon.ico +0 -0
  95. data/test/dummy/script/rails +6 -0
  96. data/test/dummy/spec/helpers/test_helper_spec.rb +8 -0
  97. data/test/dummy/spec/spec_helper.rb +52 -0
  98. data/test/dummy/spec/watir/autoload_spec.rb +33 -0
  99. data/test/dummy/spec/watir/main_spec.rb +80 -0
  100. data/test/dummy/spec/watir/selector_spec.rb +103 -0
  101. data/test/dummy/spec/watir/tab_menu_spec.rb +36 -0
  102. data/test/dummy/tmp/cache/assets/C56/8F0/sprockets%2F1ad046fb9937420d5382984483fc8401 +0 -0
  103. data/test/dummy/tmp/cache/assets/C63/420/sprockets%2F5daa64d9601a1dd14726112003d08364 +0 -0
  104. data/test/dummy/tmp/cache/assets/C65/790/sprockets%2Feacce513669090988829f66e61634451 +0 -0
  105. data/test/dummy/tmp/cache/assets/C77/DD0/sprockets%2F055f9cd12326c5150492b8c584314fa3 +0 -0
  106. data/test/dummy/tmp/cache/assets/C84/E70/sprockets%2F0530f24346bbf970634035b6e55f886e +0 -0
  107. data/test/dummy/tmp/cache/assets/C85/420/sprockets%2F4734da42d41574596ab532629d0867ec +0 -0
  108. data/test/dummy/tmp/cache/assets/C87/A50/sprockets%2F667342f892546b573c52d11f814ae4f3 +0 -0
  109. data/test/dummy/tmp/cache/assets/CA1/750/sprockets%2Fa8471b3ea18986e7368e8273a95865e8 +0 -0
  110. data/test/dummy/tmp/cache/assets/CAC/DB0/sprockets%2Fc424393ee4e4f66aa4014619048753cb +0 -0
  111. data/test/dummy/tmp/cache/assets/CB2/170/sprockets%2F4479eb189646408ec3130b45153ebf7b +0 -0
  112. data/test/dummy/tmp/cache/assets/CB9/630/sprockets%2Fe5952cc2ece61727517547af4232892e +0 -0
  113. data/test/dummy/tmp/cache/assets/CBD/960/sprockets%2F5a35c922c979e889b0338374a9b3f4b0 +0 -0
  114. data/test/dummy/tmp/cache/assets/CC4/730/sprockets%2F78d0941e0543313bbb0a9f0cf630030d +0 -0
  115. data/test/dummy/tmp/cache/assets/CD1/F50/sprockets%2Fbf2261613d1c32c54a6e38a7673531fa +0 -0
  116. data/test/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  117. data/test/dummy/tmp/cache/assets/CD9/1E0/sprockets%2F293460f7bea2aea456231b769212f36f +0 -0
  118. data/test/dummy/tmp/cache/assets/CDC/EC0/sprockets%2Ff9a21d40846491577ab5ebe00de07077 +0 -0
  119. data/test/dummy/tmp/cache/assets/CE6/8D0/sprockets%2F9e823d2b49662dbb4389f2841a23e8c1 +0 -0
  120. data/test/dummy/tmp/cache/assets/CEE/110/sprockets%2Faf0654ff711843e082592cd70cf89a88 +0 -0
  121. data/test/dummy/tmp/cache/assets/CEE/490/sprockets%2F97139dc7ad35759531fc7fa572f0c761 +0 -0
  122. data/test/dummy/tmp/cache/assets/CF9/6F0/sprockets%2F952426cea414c6c2a04cc1216a1f36f5 +0 -0
  123. data/test/dummy/tmp/cache/assets/CFA/DE0/sprockets%2F25bf1e7766a300a4c37195df0cbb1107 +0 -0
  124. data/test/dummy/tmp/cache/assets/CFB/A10/sprockets%2F72699e3ed6f9c3984a718b62932ba66e +0 -0
  125. data/test/dummy/tmp/cache/assets/CFC/640/sprockets%2Fc7f89943cb904e76b2437e59348cc5c9 +0 -0
  126. data/test/dummy/tmp/cache/assets/D13/0C0/sprockets%2F218a6e24bfe5005a8a86798baa2585c8 +0 -0
  127. data/test/dummy/tmp/cache/assets/D13/3B0/sprockets%2F00cf5d507582a705af9694cde93ba186 +0 -0
  128. data/test/dummy/tmp/cache/assets/D13/6A0/sprockets%2F4819aa020210496ecf49ee70b78e8be6 +0 -0
  129. data/test/dummy/tmp/cache/assets/D15/560/sprockets%2Ff0007939832a29a27abe3a9579eed81c +0 -0
  130. data/test/dummy/tmp/cache/assets/D16/860/sprockets%2Fb45890d98668c132fee5cae4b15320d9 +0 -0
  131. data/test/dummy/tmp/cache/assets/D1A/150/sprockets%2F49ad9f8620b7712e6f2d4fc2e354e545 +0 -0
  132. data/test/dummy/tmp/cache/assets/D20/4F0/sprockets%2Fb15d3257899ad89007d1348eb9a5f5fe +0 -0
  133. data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  134. data/test/dummy/tmp/cache/assets/D36/810/sprockets%2Fb84416b6a4f5a39b0bc23ab72ad94279 +0 -0
  135. data/test/dummy/tmp/cache/assets/D39/390/sprockets%2F3c87a321da4296312f18efc704cd6d2f +0 -0
  136. data/test/dummy/tmp/cache/assets/D3A/260/sprockets%2F69551919ec05c0eb11e55bb59dc143ec +0 -0
  137. data/test/dummy/tmp/cache/assets/D41/350/sprockets%2F2111b16bc0081c14b803cfd350eb4baa +0 -0
  138. data/test/dummy/tmp/cache/assets/D43/D20/sprockets%2Fbcbf2f35591e507593ec6116eac6e924 +0 -0
  139. data/test/dummy/tmp/cache/assets/D48/3C0/sprockets%2F41be77d9f6b62168967ca14ccc6b51d6 +0 -0
  140. data/test/dummy/tmp/cache/assets/D4D/7C0/sprockets%2F5f4f24c2540cffe8b3c5e835756c35f7 +0 -0
  141. data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  142. data/test/dummy/tmp/cache/assets/D51/6A0/sprockets%2F80b05d6f75c78bdb1e450c898e47d97a +0 -0
  143. data/test/dummy/tmp/cache/assets/D56/4C0/sprockets%2F66059379b6c72ffe570f4ae394a89eda +0 -0
  144. data/test/dummy/tmp/cache/assets/D56/D30/sprockets%2Fe910c76d93fd4da6984d82e469f62f0c +0 -0
  145. data/test/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  146. data/test/dummy/tmp/cache/assets/D65/600/sprockets%2Fdaa0e3c217673cb0ebb89d97438a1b80 +0 -0
  147. data/test/dummy/tmp/cache/assets/D66/6C0/sprockets%2Fa06355ade2a095c01afd8c6f5e67019d +0 -0
  148. data/test/dummy/tmp/cache/assets/D6A/E70/sprockets%2Fc9f71142e4d4a807cb6be80451f74adb +0 -0
  149. data/test/dummy/tmp/cache/assets/D76/E50/sprockets%2F6289e3eb865565eab3fdfb4fae810702 +0 -0
  150. data/test/dummy/tmp/cache/assets/D86/6A0/sprockets%2Fac97d7e4e37faa819a833c7c52c9e687 +0 -0
  151. data/test/dummy/tmp/cache/assets/D91/C00/sprockets%2Fb1cf6c48f161db0a058d10817ddd5e5b +0 -0
  152. data/test/dummy/tmp/cache/assets/D9C/C90/sprockets%2Fa903431f8703bbaafcae42e4f4692ff8 +0 -0
  153. data/test/dummy/tmp/cache/assets/DA0/C60/sprockets%2F90d8e40e6baa19d6556ab9c6ac891a2e +0 -0
  154. data/test/dummy/tmp/cache/assets/DA1/F90/sprockets%2F3bd196480867f8e3c74b10dbcbbe1f9b +0 -0
  155. data/test/dummy/tmp/cache/assets/DA7/EE0/sprockets%2Ffced4a1e089dc82bf773475da4e53c46 +0 -0
  156. data/test/dummy/tmp/cache/assets/DA9/4D0/sprockets%2F3d68828b990fbfa9cdf51daa76c242d5 +0 -0
  157. data/test/dummy/tmp/cache/assets/DB5/4C0/sprockets%2F5e815df4827231fe949b2f9bffd0d9de +0 -0
  158. data/test/dummy/tmp/cache/assets/DB6/910/sprockets%2F3c19b64141a5ceeccf3a3baf4c452a06 +0 -0
  159. data/test/dummy/tmp/cache/assets/DC4/8D0/sprockets%2Fd8daccd2ece841a83a2a584c50e352d5 +0 -0
  160. data/test/dummy/tmp/cache/assets/DCC/6A0/sprockets%2Fa92fb625cc83fe72fc4115e2fb2ed61e +0 -0
  161. data/test/dummy/tmp/cache/assets/DCC/940/sprockets%2Fe7f0ee8bf122b8b72b8e3c7cd13a5d81 +0 -0
  162. data/test/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  163. data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  164. data/test/dummy/tmp/cache/assets/E08/E50/sprockets%2F22c72aded517c5cdf8cce6f4b58c76b8 +0 -0
  165. data/test/dummy/tmp/cache/assets/E24/740/sprockets%2F2ecee9c0ae221af87da9c5d034c8dd0c +0 -0
  166. data/test/dummy/tmp/cache/assets/E2D/160/sprockets%2Fdb479da69eeed6322f3b8dab3bf91bb0 +0 -0
  167. data/test/dummy/tmp/cache/assets/E4C/810/sprockets%2Fdaf244418a8cfda1aca3e32dbdf17fd2 +0 -0
  168. data/test/dummy/tmp/pids/server.pid +1 -0
  169. data/test/screen/main.png +0 -0
  170. data/test/test_helper.rb +15 -0
  171. 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
+ ![Inkwell Timelines](https://github.com/salkar/inkwell_timelines/blob/master/test/screen/main.png?raw=true)
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
@@ -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
+ });