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.
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
+ });