my_forum 0.0.1 → 0.0.2

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 (203) hide show
  1. checksums.yaml +4 -4
  2. data/README.rdoc +12 -1
  3. data/Rakefile +4 -3
  4. data/{test/dummy/public/favicon.ico → app/assets/javascripts/my_forum/admin/categories.js.coffee} +0 -0
  5. data/app/assets/javascripts/my_forum/admin/dashboard.js.coffee +0 -0
  6. data/app/assets/javascripts/my_forum/admin/forums.js.coffee +0 -0
  7. data/app/assets/javascripts/my_forum/admin/roles.js +2 -0
  8. data/app/assets/javascripts/my_forum/admin/users.js +2 -0
  9. data/app/assets/javascripts/my_forum/application.js +6 -0
  10. data/app/assets/javascripts/my_forum/forums.js.coffee +0 -0
  11. data/app/assets/javascripts/my_forum/jquery.scrollTo.min.js +7 -0
  12. data/app/assets/javascripts/my_forum/jquery.selection.js +354 -0
  13. data/app/assets/javascripts/my_forum/my_forum.js.coffee +118 -0
  14. data/app/assets/javascripts/my_forum/posts.js.coffee +20 -0
  15. data/app/assets/javascripts/my_forum/topics.js.coffee +0 -0
  16. data/app/assets/javascripts/my_forum/users.js.coffee +0 -0
  17. data/app/assets/javascripts/my_forum/welcome.js.coffee +0 -0
  18. data/app/assets/stylesheets/my_forum/admin/categories.css.scss +0 -0
  19. data/app/assets/stylesheets/my_forum/admin/dashboard.css.scss +3 -0
  20. data/app/assets/stylesheets/my_forum/admin/forums.css.scss +7 -0
  21. data/app/assets/stylesheets/my_forum/admin/roles.css +4 -0
  22. data/app/assets/stylesheets/my_forum/admin/users.css +4 -0
  23. data/app/assets/stylesheets/my_forum/application.css.scss +80 -0
  24. data/app/assets/stylesheets/my_forum/forums.css.scss +31 -0
  25. data/app/assets/stylesheets/my_forum/posts.css.scss +138 -0
  26. data/app/assets/stylesheets/my_forum/private_messages.css.scss +11 -0
  27. data/app/assets/stylesheets/my_forum/topics.css.scss +16 -0
  28. data/app/assets/stylesheets/my_forum/users.css.scss +3 -0
  29. data/app/assets/stylesheets/my_forum/welcome.css.scss +73 -0
  30. data/app/controllers/my_forum/admin/categories_controller.rb +36 -0
  31. data/app/controllers/my_forum/admin/dashboard_controller.rb +13 -0
  32. data/app/controllers/my_forum/admin/emoticons_controller.rb +65 -0
  33. data/app/controllers/my_forum/admin/forums_controller.rb +35 -0
  34. data/app/controllers/my_forum/admin/mail_controller.rb +31 -0
  35. data/app/controllers/my_forum/admin/roles_controller.rb +38 -0
  36. data/app/controllers/my_forum/admin/users_controller.rb +14 -0
  37. data/app/controllers/my_forum/application_controller.rb +81 -0
  38. data/app/controllers/my_forum/attachments_controller.rb +30 -0
  39. data/app/controllers/my_forum/forums_controller.rb +39 -0
  40. data/app/controllers/my_forum/images_controller.rb +7 -0
  41. data/app/controllers/my_forum/posts_controller.rb +96 -0
  42. data/app/controllers/my_forum/private_messages_controller.rb +73 -0
  43. data/app/controllers/my_forum/topics_controller.rb +96 -0
  44. data/app/controllers/my_forum/users_controller.rb +145 -0
  45. data/app/controllers/my_forum/welcome_controller.rb +30 -0
  46. data/app/helpers/my_forum/admin/dashboard_helper.rb +4 -0
  47. data/app/helpers/my_forum/admin/forums_helper.rb +4 -0
  48. data/app/helpers/my_forum/admin/roles_helper.rb +4 -0
  49. data/app/helpers/my_forum/admin/users_helper.rb +4 -0
  50. data/app/helpers/my_forum/application_helper.rb +43 -0
  51. data/app/helpers/my_forum/emoticons_helper.rb +7 -0
  52. data/app/helpers/my_forum/forums_helper.rb +44 -0
  53. data/app/helpers/my_forum/posts_helper.rb +76 -0
  54. data/app/helpers/my_forum/private_messages_helper.rb +25 -0
  55. data/app/helpers/my_forum/topics_helper.rb +18 -0
  56. data/app/helpers/my_forum/users_helper.rb +33 -0
  57. data/app/helpers/my_forum/welcome_helper.rb +4 -0
  58. data/app/mailers/application_mailer.rb +4 -0
  59. data/app/mailers/my_forum/user_mailer.rb +31 -0
  60. data/app/models/my_forum/attachment.rb +12 -0
  61. data/app/models/my_forum/avatar.rb +11 -0
  62. data/app/models/my_forum/category.rb +7 -0
  63. data/app/models/my_forum/category_permission.rb +6 -0
  64. data/app/models/my_forum/emoticon.rb +6 -0
  65. data/app/models/my_forum/forum.rb +50 -0
  66. data/app/models/my_forum/image.rb +5 -0
  67. data/app/models/my_forum/log_read_mark.rb +4 -0
  68. data/app/models/my_forum/post.rb +26 -0
  69. data/app/models/my_forum/private_message.rb +8 -0
  70. data/app/models/my_forum/role.rb +6 -0
  71. data/app/models/my_forum/topic.rb +41 -0
  72. data/app/models/my_forum/user.rb +71 -0
  73. data/app/models/my_forum/user_group.rb +13 -0
  74. data/app/models/my_forum/user_group_link.rb +6 -0
  75. data/app/models/my_forum/user_roles.rb +6 -0
  76. data/app/views/layouts/mailer.html.erb +5 -0
  77. data/app/views/layouts/mailer.text.erb +1 -0
  78. data/app/views/layouts/my_forum/_guest_navbar.html.haml +4 -0
  79. data/app/views/layouts/my_forum/_user_navbar.html.haml +19 -0
  80. data/app/views/layouts/my_forum/admin_application.haml +29 -0
  81. data/app/views/layouts/my_forum/application.haml +23 -0
  82. data/app/views/my_forum/admin/categories/edit.haml +9 -0
  83. data/app/views/my_forum/admin/categories/new.haml +5 -0
  84. data/app/views/my_forum/admin/dashboard/index.haml +0 -0
  85. data/app/views/my_forum/admin/emoticons/edit.haml +4 -0
  86. data/app/views/my_forum/admin/emoticons/index.haml +15 -0
  87. data/app/views/my_forum/admin/emoticons/new.haml +5 -0
  88. data/app/views/my_forum/admin/forums/index.haml +47 -0
  89. data/app/views/my_forum/admin/forums/new.haml +6 -0
  90. data/app/views/my_forum/admin/mail/index.haml +9 -0
  91. data/app/views/my_forum/admin/roles/index.haml +12 -0
  92. data/app/views/my_forum/admin/roles/new.haml +22 -0
  93. data/app/views/my_forum/admin/users/index.haml +10 -0
  94. data/app/views/my_forum/forums/_topic_subject.html.haml +16 -0
  95. data/app/views/my_forum/forums/show.haml +29 -0
  96. data/app/views/my_forum/posts/edit.html.haml +31 -0
  97. data/app/views/my_forum/private_messages/_sidebar.haml +10 -0
  98. data/app/views/my_forum/private_messages/inbox.haml +26 -0
  99. data/app/views/my_forum/private_messages/new.haml +21 -0
  100. data/app/views/my_forum/private_messages/show.haml +10 -0
  101. data/app/views/my_forum/shared/_post_preview.haml +15 -0
  102. data/app/views/my_forum/shared/_upload_photo.haml +45 -0
  103. data/app/views/my_forum/shared/post_preview.js.coffee +4 -0
  104. data/app/views/my_forum/topics/_post.haml +29 -0
  105. data/app/views/my_forum/topics/_profile_popover.haml +47 -0
  106. data/app/views/my_forum/topics/_quick_answer.haml +34 -0
  107. data/app/views/my_forum/topics/_topic_header.haml +4 -0
  108. data/app/views/my_forum/topics/_user_info.haml +9 -0
  109. data/app/views/my_forum/topics/new.haml +38 -0
  110. data/app/views/my_forum/topics/show.haml +60 -0
  111. data/app/views/my_forum/user_mailer/custom_email.text.erb +1 -0
  112. data/app/views/my_forum/user_mailer/ping_from_post.haml +8 -0
  113. data/app/views/my_forum/user_mailer/ping_from_post.text.erb +6 -0
  114. data/app/views/my_forum/user_mailer/pm_notification.text.erb +6 -0
  115. data/app/views/my_forum/user_mailer/reset_password_email.haml +1 -0
  116. data/app/views/my_forum/user_mailer/reset_password_email.text.erb +1 -0
  117. data/app/views/my_forum/users/edit.haml +36 -0
  118. data/app/views/my_forum/users/forgot_password.haml +10 -0
  119. data/app/views/my_forum/users/new.haml +14 -0
  120. data/app/views/my_forum/users/signin.haml +14 -0
  121. data/app/views/my_forum/users/signout.haml +0 -0
  122. data/app/views/my_forum/welcome/index.haml +37 -0
  123. data/config/initializers/will_paginate.rb +24 -0
  124. data/config/locales/en.yml +68 -0
  125. data/config/locales/ru.yml +198 -0
  126. data/config/routes.rb +48 -0
  127. data/db/migrate/20141117122725_create_my_forum_forums.rb +12 -0
  128. data/db/migrate/20141117122742_create_my_forum_topics.rb +17 -0
  129. data/db/migrate/20141117122751_create_my_forum_posts.rb +11 -0
  130. data/db/migrate/20141118081021_create_my_forum_categories.rb +8 -0
  131. data/db/migrate/20141118131215_create_my_forum_users.rb +34 -0
  132. data/db/migrate/20141222094522_create_my_forum_roles.rb +10 -0
  133. data/db/migrate/20141222094538_create_my_forum_user_roles.rb +9 -0
  134. data/db/migrate/20150202115250_create_my_forum_log_read_marks.rb +10 -0
  135. data/db/migrate/20150215200453_create_my_forum_user_groups.rb +15 -0
  136. data/db/migrate/20150215204852_create_my_forum_user_group_links.rb +9 -0
  137. data/db/migrate/20150215212443_create_my_forum_category_permissions.rb +9 -0
  138. data/db/migrate/20150227210814_create_my_forum_private_messages.rb +16 -0
  139. data/db/migrate/20151012095554_create_my_forum_images.rb +12 -0
  140. data/db/migrate/20151218135729_add_is_deleted.rb +6 -0
  141. data/db/migrate/20151220121140_create_my_forum_emoticons.rb +10 -0
  142. data/db/migrate/20151221203243_my_forum_rename_user_avatar.rb +5 -0
  143. data/db/migrate/20151221205045_my_forum_change_user_avatar.rb +5 -0
  144. data/db/migrate/20160122202142_add_latest_post_info_for_topic.rb +24 -0
  145. data/db/migrate/20160210130805_add_indexes_for_topics.rb +7 -0
  146. data/db/migrate/20160214085201_add_edited_by_for_post.rb +5 -0
  147. data/lib/my_forum/engine.rb +31 -0
  148. data/lib/my_forum/version.rb +1 -1
  149. data/lib/tasks/my_forum_tasks.rake +155 -4
  150. data/spec/controllers/my_forum/admin/emoticons_controller_spec.rb +7 -0
  151. data/spec/controllers/my_forum/admin/mail_controller_spec.rb +7 -0
  152. data/spec/controllers/my_forum/private_messages_controller_spec.rb +7 -0
  153. data/spec/controllers/my_forum/users_controller_spec.rb +76 -0
  154. data/{test → spec}/dummy/README.rdoc +0 -0
  155. data/{test → spec}/dummy/Rakefile +0 -0
  156. data/{test → spec}/dummy/app/assets/javascripts/application.js +1 -1
  157. data/{app/assets/stylesheets/my_forum → spec/dummy/app/assets/stylesheets}/application.css +1 -1
  158. data/{test → spec}/dummy/app/controllers/application_controller.rb +0 -0
  159. data/{test → spec}/dummy/app/helpers/application_helper.rb +0 -0
  160. data/{test → spec}/dummy/app/views/layouts/application.html.erb +0 -0
  161. data/{test → spec}/dummy/bin/bundle +0 -0
  162. data/{test → spec}/dummy/bin/rails +0 -0
  163. data/{test → spec}/dummy/bin/rake +0 -0
  164. data/{test → spec}/dummy/config/application.rb +0 -0
  165. data/{test → spec}/dummy/config/boot.rb +0 -0
  166. data/{test → spec}/dummy/config/database.yml +0 -0
  167. data/{test → spec}/dummy/config/environment.rb +0 -0
  168. data/{test → spec}/dummy/config/environments/development.rb +0 -0
  169. data/{test → spec}/dummy/config/environments/production.rb +1 -1
  170. data/{test → spec}/dummy/config/environments/test.rb +1 -1
  171. data/{test → spec}/dummy/config/initializers/assets.rb +0 -0
  172. data/{test → spec}/dummy/config/initializers/backtrace_silencers.rb +0 -0
  173. data/{test → spec}/dummy/config/initializers/cookies_serializer.rb +0 -0
  174. data/{test → spec}/dummy/config/initializers/filter_parameter_logging.rb +0 -0
  175. data/{test → spec}/dummy/config/initializers/inflections.rb +0 -0
  176. data/{test → spec}/dummy/config/initializers/mime_types.rb +0 -0
  177. data/{test → spec}/dummy/config/initializers/session_store.rb +0 -0
  178. data/{test → spec}/dummy/config/initializers/wrap_parameters.rb +0 -0
  179. data/{test → spec}/dummy/config/locales/en.yml +0 -0
  180. data/{test → spec}/dummy/config/routes.rb +0 -0
  181. data/{test → spec}/dummy/config/secrets.yml +0 -0
  182. data/{test → spec}/dummy/config.ru +0 -0
  183. data/spec/dummy/db/development.sqlite3 +0 -0
  184. data/spec/dummy/db/schema.rb +159 -0
  185. data/spec/dummy/db/test.sqlite3 +0 -0
  186. data/spec/dummy/log/development.log +12 -0
  187. data/{test → spec}/dummy/public/404.html +0 -0
  188. data/{test → spec}/dummy/public/422.html +0 -0
  189. data/{test → spec}/dummy/public/500.html +0 -0
  190. data/spec/dummy/public/favicon.ico +0 -0
  191. data/spec/helpers/my_forum/posts_helper_spec.rb +24 -0
  192. data/spec/helpers/my_forum/private_messages_helper_spec.rb +17 -0
  193. data/spec/models/my_forum/emoticon_spec.rb +7 -0
  194. data/spec/models/my_forum/private_message_spec.rb +7 -0
  195. data/spec/models/my_forum/user_spec.rb +13 -0
  196. data/spec/rails_helper.rb +52 -0
  197. data/spec/spec_helper.rb +87 -0
  198. metadata +356 -83
  199. data/app/views/layouts/my_forum/application.html.erb +0 -14
  200. data/test/dummy/app/assets/stylesheets/application.css +0 -15
  201. data/test/integration/navigation_test.rb +0 -10
  202. data/test/my_forum_test.rb +0 -7
  203. data/test/test_helper.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2ec79af48419743a46cb08ceacde067a36d5c658
4
- data.tar.gz: 1b16082b7f8f5cd4ca953c80ecbfc7453a8bd642
3
+ metadata.gz: ee1ba421dcc871ea818bc90b35ad0ec9c0c0e74b
4
+ data.tar.gz: f08beb05ab8c50fe16c9a0fb40cd793a426a679d
5
5
  SHA512:
6
- metadata.gz: 69de62c7ab134078ab86b43becd29403e4df93687d1c5b474055b74c7d84dc998d671301ab98c448581593faeefb53e4c0e111024cd79442cbca458fca56e294
7
- data.tar.gz: b9603bae08aceb948915a1bf2f00f60386447eb4beb11d2b42fce1fa2c82fb051948d391ab2524d5263f20fa09c10c20ad64de2b5613740c0f34e1c6b302aa82
6
+ metadata.gz: 2c3b1e5edb986c2cb9247315cd3edf131776d1b7ffb242a674fb3040d028fee1e04a3b6307b6e39021c8e85ccb40a25f699a776a777b38ed8475f8f86dd7b05e
7
+ data.tar.gz: c54770fa9defa218db1581bf133b9ccb384615444ded4a803119edfb8e981b2842782f168adfbe3834a78d0a0f6fe62fdf5e11b588b599268f74e653d62bbd98
data/README.rdoc CHANGED
@@ -1,3 +1,14 @@
1
+ {<img src="https://travis-ci.org/vintyara/my_forum.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/vintyara/my_forum]
2
+
1
3
  = MyForum
2
4
 
3
- This project rocks and uses MIT-LICENSE.
5
+ This project rocks and uses MIT-LICENSE.
6
+
7
+ INSTALLATION
8
+ rake my_forum:install:migrations
9
+
10
+ For using existing User model, use somethink like this:
11
+
12
+ Create config/initializers/my_forum.rb with next content:
13
+ MyForum::Engine.use_custom_user_model = true
14
+ ...
data/Rakefile CHANGED
@@ -14,19 +14,20 @@ RDoc::Task.new(:rdoc) do |rdoc|
14
14
  rdoc.rdoc_files.include('lib/**/*.rb')
15
15
  end
16
16
 
17
- APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
17
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
18
18
  load 'rails/tasks/engine.rake'
19
19
 
20
20
 
21
21
 
22
22
  Bundler::GemHelper.install_tasks
23
23
 
24
- require 'rake/testtask'
24
+ require 'rspec/core'
25
+ require 'rspec/core/rake_task'
25
26
 
26
27
  Rake::TestTask.new(:test) do |t|
27
28
  t.libs << 'lib'
28
29
  t.libs << 'test'
29
- t.pattern = 'test/**/*_test.rb'
30
+ t.pattern = 'spec/**/*_spec.rb'
30
31
  t.verbose = false
31
32
  end
32
33
 
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -10,4 +10,10 @@
10
10
  // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
11
  // about supported directives.
12
12
  //
13
+ //= require jquery
14
+ //= require jquery_ujs
15
+ //= require bootstrap-sprockets
16
+ //= require bootstrap
17
+ //= jquery.selection.js
18
+ //= jquery.scrollTo.min.js
13
19
  //= require_tree .
File without changes
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Copyright (c) 2007-2015 Ariel Flesler - aflesler<a>gmail<d>com | http://flesler.blogspot.com
3
+ * Licensed under MIT
4
+ * @author Ariel Flesler
5
+ * @version 2.1.2
6
+ */
7
+ ;(function(f){"use strict";"function"===typeof define&&define.amd?define(["jquery"],f):"undefined"!==typeof module&&module.exports?module.exports=f(require("jquery")):f(jQuery)})(function($){"use strict";function n(a){return!a.nodeName||-1!==$.inArray(a.nodeName.toLowerCase(),["iframe","#document","html","body"])}function h(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}var p=$.scrollTo=function(a,d,b){return $(window).scrollTo(a,d,b)};p.defaults={axis:"xy",duration:0,limit:!0};$.fn.scrollTo=function(a,d,b){"object"=== typeof d&&(b=d,d=0);"function"===typeof b&&(b={onAfter:b});"max"===a&&(a=9E9);b=$.extend({},p.defaults,b);d=d||b.duration;var u=b.queue&&1<b.axis.length;u&&(d/=2);b.offset=h(b.offset);b.over=h(b.over);return this.each(function(){function k(a){var k=$.extend({},b,{queue:!0,duration:d,complete:a&&function(){a.call(q,e,b)}});r.animate(f,k)}if(null!==a){var l=n(this),q=l?this.contentWindow||window:this,r=$(q),e=a,f={},t;switch(typeof e){case "number":case "string":if(/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(e)){e= h(e);break}e=l?$(e):$(e,q);case "object":if(e.length===0)return;if(e.is||e.style)t=(e=$(e)).offset()}var v=$.isFunction(b.offset)&&b.offset(q,e)||b.offset;$.each(b.axis.split(""),function(a,c){var d="x"===c?"Left":"Top",m=d.toLowerCase(),g="scroll"+d,h=r[g](),n=p.max(q,c);t?(f[g]=t[m]+(l?0:h-r.offset()[m]),b.margin&&(f[g]-=parseInt(e.css("margin"+d),10)||0,f[g]-=parseInt(e.css("border"+d+"Width"),10)||0),f[g]+=v[m]||0,b.over[m]&&(f[g]+=e["x"===c?"width":"height"]()*b.over[m])):(d=e[m],f[g]=d.slice&& "%"===d.slice(-1)?parseFloat(d)/100*n:d);b.limit&&/^\d+$/.test(f[g])&&(f[g]=0>=f[g]?0:Math.min(f[g],n));!a&&1<b.axis.length&&(h===f[g]?f={}:u&&(k(b.onAfterFirst),f={}))});k(b.onAfter)}})};p.max=function(a,d){var b="x"===d?"Width":"Height",h="scroll"+b;if(!n(a))return a[h]-$(a)[b.toLowerCase()]();var b="client"+b,k=a.ownerDocument||a.document,l=k.documentElement,k=k.body;return Math.max(l[h],k[h])-Math.min(l[b],k[b])};$.Tween.propHooks.scrollLeft=$.Tween.propHooks.scrollTop={get:function(a){return $(a.elem)[a.prop]()}, set:function(a){var d=this.get(a);if(a.options.interrupt&&a._last&&a._last!==d)return $(a.elem).stop();var b=Math.round(a.now);d!==b&&($(a.elem)[a.prop](b),a._last=this.get(a))}};return p});
@@ -0,0 +1,354 @@
1
+ /*!
2
+ * jQuery.selection - jQuery Plugin
3
+ *
4
+ * Copyright (c) 2010-2014 IWASAKI Koji (@madapaja).
5
+ * http://blog.madapaja.net/
6
+ * Under The MIT License
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining
9
+ * a copy of this software and associated documentation files (the
10
+ * "Software"), to deal in the Software without restriction, including
11
+ * without limitation the rights to use, copy, modify, merge, publish,
12
+ * distribute, sublicense, and/or sell copies of the Software, and to
13
+ * permit persons to whom the Software is furnished to do so, subject to
14
+ * the following conditions:
15
+ *
16
+ * The above copyright notice and this permission notice shall be
17
+ * included in all copies or substantial portions of the Software.
18
+ *
19
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+ (function($, win, doc) {
28
+ /**
29
+ * get caret status of the selection of the element
30
+ *
31
+ * @param {Element} element target DOM element
32
+ * @return {Object} return
33
+ * @return {String} return.text selected text
34
+ * @return {Number} return.start start position of the selection
35
+ * @return {Number} return.end end position of the selection
36
+ */
37
+ var _getCaretInfo = function(element){
38
+ var res = {
39
+ text: '',
40
+ start: 0,
41
+ end: 0
42
+ };
43
+
44
+ if (!element.value) {
45
+ /* no value or empty string */
46
+ return res;
47
+ }
48
+
49
+ try {
50
+ if (win.getSelection) {
51
+ /* except IE */
52
+ res.start = element.selectionStart;
53
+ res.end = element.selectionEnd;
54
+ res.text = element.value.slice(res.start, res.end);
55
+ } else if (doc.selection) {
56
+ /* for IE */
57
+ element.focus();
58
+
59
+ var range = doc.selection.createRange(),
60
+ range2 = doc.body.createTextRange();
61
+
62
+ res.text = range.text;
63
+
64
+ try {
65
+ range2.moveToElementText(element);
66
+ range2.setEndPoint('StartToStart', range);
67
+ } catch (e) {
68
+ range2 = element.createTextRange();
69
+ range2.setEndPoint('StartToStart', range);
70
+ }
71
+
72
+ res.start = element.value.length - range2.text.length;
73
+ res.end = res.start + range.text.length;
74
+ }
75
+ } catch (e) {
76
+ /* give up */
77
+ }
78
+
79
+ return res;
80
+ };
81
+
82
+ /**
83
+ * caret operation for the element
84
+ * @type {Object}
85
+ */
86
+ var _CaretOperation = {
87
+ /**
88
+ * get caret position
89
+ *
90
+ * @param {Element} element target element
91
+ * @return {Object} return
92
+ * @return {Number} return.start start position for the selection
93
+ * @return {Number} return.end end position for the selection
94
+ */
95
+ getPos: function(element) {
96
+ var tmp = _getCaretInfo(element);
97
+ return {start: tmp.start, end: tmp.end};
98
+ },
99
+
100
+ /**
101
+ * set caret position
102
+ *
103
+ * @param {Element} element target element
104
+ * @param {Object} toRange caret position
105
+ * @param {Number} toRange.start start position for the selection
106
+ * @param {Number} toRange.end end position for the selection
107
+ * @param {String} caret caret mode: any of the following: "keep" | "start" | "end"
108
+ */
109
+ setPos: function(element, toRange, caret) {
110
+ caret = this._caretMode(caret);
111
+
112
+ if (caret === 'start') {
113
+ toRange.end = toRange.start;
114
+ } else if (caret === 'end') {
115
+ toRange.start = toRange.end;
116
+ }
117
+
118
+ element.focus();
119
+ try {
120
+ if (element.createTextRange) {
121
+ var range = element.createTextRange();
122
+
123
+ if (win.navigator.userAgent.toLowerCase().indexOf("msie") >= 0) {
124
+ toRange.start = element.value.substr(0, toRange.start).replace(/\r/g, '').length;
125
+ toRange.end = element.value.substr(0, toRange.end).replace(/\r/g, '').length;
126
+ }
127
+
128
+ range.collapse(true);
129
+ range.moveStart('character', toRange.start);
130
+ range.moveEnd('character', toRange.end - toRange.start);
131
+
132
+ range.select();
133
+ } else if (element.setSelectionRange) {
134
+ element.setSelectionRange(toRange.start, toRange.end);
135
+ }
136
+ } catch (e) {
137
+ /* give up */
138
+ }
139
+ },
140
+
141
+ /**
142
+ * get selected text
143
+ *
144
+ * @param {Element} element target element
145
+ * @return {String} return selected text
146
+ */
147
+ getText: function(element) {
148
+ return _getCaretInfo(element).text;
149
+ },
150
+
151
+ /**
152
+ * get caret mode
153
+ *
154
+ * @param {String} caret caret mode
155
+ * @return {String} return any of the following: "keep" | "start" | "end"
156
+ */
157
+ _caretMode: function(caret) {
158
+ caret = caret || "keep";
159
+ if (caret === false) {
160
+ caret = 'end';
161
+ }
162
+
163
+ switch (caret) {
164
+ case 'keep':
165
+ case 'start':
166
+ case 'end':
167
+ break;
168
+
169
+ default:
170
+ caret = 'keep';
171
+ }
172
+
173
+ return caret;
174
+ },
175
+
176
+ /**
177
+ * replace selected text
178
+ *
179
+ * @param {Element} element target element
180
+ * @param {String} text replacement text
181
+ * @param {String} caret caret mode: any of the following: "keep" | "start" | "end"
182
+ */
183
+ replace: function(element, text, caret) {
184
+ var tmp = _getCaretInfo(element),
185
+ orig = element.value,
186
+ pos = $(element).scrollTop(),
187
+ range = {start: tmp.start, end: tmp.start + text.length};
188
+
189
+ element.value = orig.substr(0, tmp.start) + text + orig.substr(tmp.end);
190
+
191
+ $(element).scrollTop(pos);
192
+ this.setPos(element, range, caret);
193
+ },
194
+
195
+ /**
196
+ * insert before the selected text
197
+ *
198
+ * @param {Element} element target element
199
+ * @param {String} text insertion text
200
+ * @param {String} caret caret mode: any of the following: "keep" | "start" | "end"
201
+ */
202
+ insertBefore: function(element, text, caret) {
203
+ var tmp = _getCaretInfo(element),
204
+ orig = element.value,
205
+ pos = $(element).scrollTop(),
206
+ range = {start: tmp.start + text.length, end: tmp.end + text.length};
207
+
208
+ element.value = orig.substr(0, tmp.start) + text + orig.substr(tmp.start);
209
+
210
+ $(element).scrollTop(pos);
211
+ this.setPos(element, range, caret);
212
+ },
213
+
214
+ /**
215
+ * insert after the selected text
216
+ *
217
+ * @param {Element} element target element
218
+ * @param {String} text insertion text
219
+ * @param {String} caret caret mode: any of the following: "keep" | "start" | "end"
220
+ */
221
+ insertAfter: function(element, text, caret) {
222
+ var tmp = _getCaretInfo(element),
223
+ orig = element.value,
224
+ pos = $(element).scrollTop(),
225
+ range = {start: tmp.start, end: tmp.end};
226
+
227
+ element.value = orig.substr(0, tmp.end) + text + orig.substr(tmp.end);
228
+
229
+ $(element).scrollTop(pos);
230
+ this.setPos(element, range, caret);
231
+ }
232
+ };
233
+
234
+ /* add jQuery.selection */
235
+ $.extend({
236
+ /**
237
+ * get selected text on the window
238
+ *
239
+ * @param {String} mode selection mode: any of the following: "text" | "html"
240
+ * @return {String} return
241
+ */
242
+ selection: function(mode) {
243
+ var getText = ((mode || 'text').toLowerCase() === 'text');
244
+
245
+ try {
246
+ if (win.getSelection) {
247
+ if (getText) {
248
+ // get text
249
+ return win.getSelection().toString();
250
+ } else {
251
+ // get html
252
+ var sel = win.getSelection(), range;
253
+
254
+ if (sel.getRangeAt) {
255
+ range = sel.getRangeAt(0);
256
+ } else {
257
+ range = doc.createRange();
258
+ range.setStart(sel.anchorNode, sel.anchorOffset);
259
+ range.setEnd(sel.focusNode, sel.focusOffset);
260
+ }
261
+
262
+ return $('<div></div>').append(range.cloneContents()).html();
263
+ }
264
+ } else if (doc.selection) {
265
+ if (getText) {
266
+ // get text
267
+ return doc.selection.createRange().text;
268
+ } else {
269
+ // get html
270
+ return doc.selection.createRange().htmlText;
271
+ }
272
+ }
273
+ } catch (e) {
274
+ /* give up */
275
+ }
276
+
277
+ return '';
278
+ }
279
+ });
280
+
281
+ /* add selection */
282
+ $.fn.extend({
283
+ selection: function(mode, opts) {
284
+ opts = opts || {};
285
+
286
+ switch (mode) {
287
+ /**
288
+ * selection('getPos')
289
+ * get caret position
290
+ *
291
+ * @return {Object} return
292
+ * @return {Number} return.start start position for the selection
293
+ * @return {Number} return.end end position for the selection
294
+ */
295
+ case 'getPos':
296
+ return _CaretOperation.getPos(this[0]);
297
+
298
+ /**
299
+ * selection('setPos', opts)
300
+ * set caret position
301
+ *
302
+ * @param {Number} opts.start start position for the selection
303
+ * @param {Number} opts.end end position for the selection
304
+ */
305
+ case 'setPos':
306
+ return this.each(function() {
307
+ _CaretOperation.setPos(this, opts);
308
+ });
309
+
310
+ /**
311
+ * selection('replace', opts)
312
+ * replace the selected text
313
+ *
314
+ * @param {String} opts.text replacement text
315
+ * @param {String} opts.caret caret mode: any of the following: "keep" | "start" | "end"
316
+ */
317
+ case 'replace':
318
+ return this.each(function() {
319
+ _CaretOperation.replace(this, opts.text, opts.caret);
320
+ });
321
+
322
+ /**
323
+ * selection('insert', opts)
324
+ * insert before/after the selected text
325
+ *
326
+ * @param {String} opts.text insertion text
327
+ * @param {String} opts.caret caret mode: any of the following: "keep" | "start" | "end"
328
+ * @param {String} opts.mode insertion mode: any of the following: "before" | "after"
329
+ */
330
+ case 'insert':
331
+ return this.each(function() {
332
+ if (opts.mode === 'before') {
333
+ _CaretOperation.insertBefore(this, opts.text, opts.caret);
334
+ } else {
335
+ _CaretOperation.insertAfter(this, opts.text, opts.caret);
336
+ }
337
+ });
338
+
339
+ /**
340
+ * selection('get')
341
+ * get selected text
342
+ *
343
+ * @return {String} return
344
+ */
345
+ case 'get':
346
+ /* falls through */
347
+ default:
348
+ return _CaretOperation.getText(this[0]);
349
+ }
350
+
351
+ return this;
352
+ }
353
+ });
354
+ })(jQuery, window, window.document);
@@ -0,0 +1,118 @@
1
+ ready = ->
2
+ # Quote button
3
+ $('.quote-post').click (event) ->
4
+ quoute_post_id = $(event.target).data('post-id')
5
+
6
+ $.ajax
7
+ url: '/post/' + quoute_post_id
8
+ type: "GET"
9
+ dataType: "json"
10
+ success: (response) ->
11
+ quote = $('#quick_answer_textarea').val()
12
+ quote += '\n[quote author=' + response.author+ ']'
13
+ quote += response.text
14
+ quote += '[/quote]\n\n'
15
+
16
+ $('#quick_answer_textarea').val(quote)
17
+ $('body').scrollTo($('#quick_answer_textarea'))
18
+
19
+
20
+ # BBCode editor
21
+ $('.text-editor-buttons').click (event) ->
22
+ event.preventDefault()
23
+
24
+ apply_to = $('.text-editor-buttons').data('apply-to')
25
+ apply_to = $('#' + apply_to)
26
+
27
+ # Smiles
28
+ if $(event.target).attr('class').search('smile') >= 0
29
+ smile_code = $(event.target).data('code') || $(event.target).find('[data-code]').data('code')
30
+
31
+ if smile_code
32
+ text = apply_to.val()
33
+ apply_to.val(text + smile_code + ' ')
34
+
35
+ return false
36
+
37
+
38
+ # Text formatting
39
+ return false if !$(event.target).is('a') and !$(event.target).is('i')
40
+
41
+ button = if $(event.target).is('a') then $(event.target).find('i') else $(event.target)
42
+ html_class = button.attr('class')
43
+
44
+ action = if html_class then html_class.replace('fa fa-', '') else ''
45
+ text = apply_to.val()
46
+
47
+ switch action
48
+ when 'bold'
49
+ bbcode = '[b] [/b]'
50
+ when 'italic'
51
+ bbcode = '[i] [/i]'
52
+ when 'strikethrough'
53
+ bbcode = '[s] [/s]'
54
+ when 'underline'
55
+ bbcode = '[u] [/u]'
56
+ when 'link', 'video-camera', 'camera-retro'
57
+ $('#add_photo').modal()
58
+ else
59
+ bbcode = ''
60
+ console.log 'Unknown tag'
61
+
62
+ if bbcode
63
+ if (selected_text = apply_to.selection()).length > 0
64
+ open_tag = bbcode.split(' ')[0]
65
+ close_tag = bbcode.split(' ')[1]
66
+ apply_to.selection('replace', { text: open_tag + selected_text + close_tag })
67
+ else
68
+ apply_to.val(text + bbcode + ' ')
69
+
70
+ # Autocomplete
71
+ $('.autocomplete').keyup (elm) ->
72
+ ajax_url = $(@).data('autocomplete-path')
73
+ return unless ajax_url
74
+
75
+ $.ajax
76
+ url: ajax_url
77
+ type: "GET"
78
+ dataType: "json"
79
+ data: str: $(elm.target).val()
80
+ success: (response) ->
81
+ autocomplete_popup(response, elm.target)
82
+
83
+ autocomplete_popup = (autocomplete_list, object) ->
84
+ popup_id = 'autocomplete_popup'
85
+
86
+ # Create or use existing Popup Window
87
+ if $('#' + popup_id).length > 0
88
+ popup_container = $('#' + popup_id)
89
+ else
90
+ popup_container = $("<div id='#{popup_id}'></div>")
91
+ $(object).after(popup_container)
92
+
93
+ $('body').click ->
94
+ popup_container.remove()
95
+
96
+ # Show lists
97
+ html_list = $('<ul/>')
98
+ $.map autocomplete_list, (item) ->
99
+ li = $('<li/>')
100
+ .addClass('ui-menu-item')
101
+ .attr('role', 'menuitem')
102
+ .appendTo(html_list)
103
+
104
+ a = $('<a/>')
105
+ .addClass('ui-all')
106
+ .text(item)
107
+ .appendTo(li)
108
+
109
+ li.click ->
110
+ $(object).val(item)
111
+
112
+ # Destroy popup after select tag
113
+ popup_container.remove()
114
+
115
+ popup_container.html(html_list)
116
+
117
+ $(document).ready(ready)
118
+ $(document).on('page:load', ready)
@@ -0,0 +1,20 @@
1
+ ready = ->
2
+ $('#post_preview').click (event) ->
3
+ event.preventDefault()
4
+
5
+ elm_id = $(event.target).data('elm-preview')
6
+ elm = $('#' + elm_id)
7
+
8
+ return unless elm
9
+
10
+ data = elm.val()
11
+
12
+ $.ajax
13
+ url: '/post/preview'
14
+ type: 'POST'
15
+ dataType: 'script'
16
+ data:
17
+ text: data
18
+
19
+ $(document).ready(ready)
20
+ $(document).on('page:load', ready)
File without changes
File without changes
File without changes
@@ -0,0 +1,3 @@
1
+ #admin-content {
2
+ margin-top: 52px;
3
+ }
@@ -0,0 +1,7 @@
1
+ .category_box {
2
+ border: 1px solid #DEDEDE;
3
+
4
+ .category_name {
5
+ background-color: darkgrey;
6
+ }
7
+ }
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */