revelry_content 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (307) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +177 -6
  3. data/Rakefile +34 -0
  4. data/app/assets/fonts/icomoon.eot +0 -0
  5. data/app/assets/fonts/icomoon.svg +20 -0
  6. data/app/assets/fonts/icomoon.ttf +0 -0
  7. data/app/assets/fonts/icomoon.woff +0 -0
  8. data/app/assets/javascripts/revelry_content.js.coffee +21 -0
  9. data/app/assets/javascripts/revelry_content/components/Admin.js.cjsx +90 -0
  10. data/app/assets/javascripts/revelry_content/components/EditModeButton.js.cjsx +16 -0
  11. data/app/assets/javascripts/revelry_content/components/Loader.js.cjsx +10 -0
  12. data/app/assets/javascripts/revelry_content/components/Time.js.cjsx +15 -0
  13. data/app/assets/javascripts/revelry_content/components/TopBar.js.cjsx +20 -0
  14. data/app/assets/javascripts/revelry_content/components/editor.js.coffee +295 -0
  15. data/app/assets/javascripts/revelry_content/components/versions.js.coffee +170 -0
  16. data/app/assets/javascripts/revelry_content/config.js.coffee.erb +2 -0
  17. data/app/assets/javascripts/revelry_content/mixins/EditModeListener.coffee +9 -0
  18. data/app/assets/javascripts/revelry_content/models/Content.js.coffee +16 -0
  19. data/app/assets/javascripts/revelry_content/models/Version.js.coffee +8 -0
  20. data/app/assets/javascripts/revelry_content/server_side.js.coffee +10 -0
  21. data/app/assets/javascripts/revelry_content/utilities.js +69 -0
  22. data/app/assets/javascripts/vendor/react_ujs.js +64 -0
  23. data/app/assets/stylesheets/revelry_content/application.scss +22 -0
  24. data/app/assets/stylesheets/revelry_content/components/EditableList.scss +42 -0
  25. data/app/assets/stylesheets/revelry_content/components/buttons.scss +137 -0
  26. data/app/assets/stylesheets/revelry_content/components/editors.scss +62 -0
  27. data/app/assets/stylesheets/revelry_content/components/loader.scss +53 -0
  28. data/app/assets/stylesheets/revelry_content/components/topBar.scss +42 -0
  29. data/app/assets/stylesheets/revelry_content/components/version.scss +72 -0
  30. data/app/assets/stylesheets/revelry_content/layout.scss +36 -0
  31. data/app/assets/stylesheets/revelry_content/modules/base.scss +3 -0
  32. data/app/assets/stylesheets/revelry_content/modules/colors.scss +14 -0
  33. data/app/assets/stylesheets/revelry_content/modules/mixins.scss +0 -0
  34. data/app/assets/stylesheets/revelry_content/modules/vars.scss +46 -0
  35. data/app/assets/stylesheets/revelry_content/partials/iconStyle.scss +91 -0
  36. data/app/assets/stylesheets/revelry_content/partials/utilities.scss +10 -0
  37. data/app/assets/stylesheets/revelry_content/reset.scss +21 -0
  38. data/app/controllers/revelry_content/application_controller.rb +4 -0
  39. data/app/controllers/revelry_content/contents_controller.rb +63 -0
  40. data/app/controllers/revelry_content/versions_controller.rb +36 -0
  41. data/app/helpers/revelry_content/application_helper.rb +4 -0
  42. data/app/helpers/revelry_content/contents_helper.rb +29 -0
  43. data/app/models/revelry_content/content.rb +167 -0
  44. data/app/models/revelry_content/content_version.rb +21 -0
  45. data/app/uploaders/src_uploader.rb +48 -0
  46. data/app/views/layouts/revelry_content/application.html.erb +14 -0
  47. data/app/views/revelry_content/contents/_menus.html.erb +2 -0
  48. data/app/views/revelry_content/contents/index.html.erb +1 -0
  49. data/config/routes.rb +14 -0
  50. data/lib/generators/revelry_content/install_generator.rb +25 -0
  51. data/lib/generators/revelry_content/templates/create_revelry_content_contents.rb +12 -0
  52. data/lib/generators/revelry_content/templates/create_versions.rb +14 -0
  53. data/lib/revelry_content.rb +38 -0
  54. data/lib/revelry_content/configuration.rb +69 -0
  55. data/lib/revelry_content/controller_concern.rb +11 -0
  56. data/lib/revelry_content/engine.rb +22 -0
  57. data/lib/revelry_content/js_exporter.rb +15 -0
  58. data/lib/revelry_content/model_concern.rb +11 -0
  59. data/lib/revelry_content/railtie.rb +7 -0
  60. data/lib/revelry_content/version.rb +3 -0
  61. data/lib/tasks/revelry_content_tasks.rake +6 -0
  62. data/test/controllers/revelry_content/contents_controller_test.rb +9 -0
  63. data/test/dummy/README.rdoc +28 -0
  64. data/test/dummy/Rakefile +6 -0
  65. data/test/dummy/app/assets/javascripts/application.js +1 -0
  66. data/test/dummy/app/assets/javascripts/home.js +2 -0
  67. data/test/dummy/app/assets/stylesheets/application.scss +14 -0
  68. data/test/dummy/app/controllers/application_controller.rb +10 -0
  69. data/test/dummy/app/controllers/home_controller.rb +4 -0
  70. data/test/dummy/app/helpers/application_helper.rb +2 -0
  71. data/test/dummy/app/helpers/home_helper.rb +2 -0
  72. data/test/dummy/app/models/fake_user.rb +5 -0
  73. data/test/dummy/app/views/home/index.html.erb +16 -0
  74. data/test/dummy/app/views/layouts/application.html.erb +16 -0
  75. data/test/dummy/bin/bundle +3 -0
  76. data/test/dummy/bin/rails +4 -0
  77. data/test/dummy/bin/rake +4 -0
  78. data/test/dummy/config.ru +4 -0
  79. data/test/dummy/config/application.rb +23 -0
  80. data/test/dummy/config/boot.rb +5 -0
  81. data/test/dummy/config/database.yml +25 -0
  82. data/test/dummy/config/environment.rb +5 -0
  83. data/test/dummy/config/environments/development.rb +32 -0
  84. data/test/dummy/config/environments/production.rb +80 -0
  85. data/test/dummy/config/environments/test.rb +39 -0
  86. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  87. data/test/dummy/config/initializers/carrierwave.rb +5 -0
  88. data/test/dummy/config/initializers/content.rb +3 -0
  89. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  90. data/test/dummy/config/initializers/inflections.rb +16 -0
  91. data/test/dummy/config/initializers/mime_types.rb +5 -0
  92. data/test/dummy/config/initializers/revelry_content.rb +2 -0
  93. data/test/dummy/config/initializers/secret_token.rb +12 -0
  94. data/test/dummy/config/initializers/session_store.rb +3 -0
  95. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  96. data/test/dummy/config/locales/en.yml +23 -0
  97. data/test/dummy/config/papertrail.rb +1 -0
  98. data/test/dummy/config/routes.rb +4 -0
  99. data/test/dummy/db/development.sqlite3 +0 -0
  100. data/test/dummy/db/migrate/20150427211438_create_revelry_content_contents.rb +12 -0
  101. data/test/dummy/db/migrate/20150427212126_create_versions.rb +14 -0
  102. data/test/dummy/db/schema.rb +38 -0
  103. data/test/dummy/log/development.log +1415 -0
  104. data/test/dummy/public/404.html +58 -0
  105. data/test/dummy/public/422.html +58 -0
  106. data/test/dummy/public/500.html +57 -0
  107. data/test/dummy/public/favicon.ico +0 -0
  108. data/test/dummy/test/controllers/home_controller_test.rb +7 -0
  109. data/test/dummy/test/helpers/home_helper_test.rb +4 -0
  110. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/-I_fh6Ob3TV3ynXTvv2TsuKA8cQq62L1tKIrIuNXWjA.cache +1 -0
  111. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/-YnOULGJdPpgh539S1Ms1ELd5--WkKXQZL4yYylOy-0.cache +1 -0
  112. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/01i3BQNbZnC6BxmgguLy4xMYU2RnsNjDy_lEOEdzhxY.cache +1 -0
  113. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/0CsApXQBjT34U567rgWiQGYOFwIpgM1ZcV3ZvrXPAXg.cache +1 -0
  114. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/0LnMwfkPx0KckDudP0t_qfcIfrUx2JEt9_W28i5ota8.cache +0 -0
  115. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/0Soh65Z50qGQ79OzRV5ywJzksbLPZ9Y7Xukmqyr6k5E.cache +1 -0
  116. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/0XbuhYD4hx4ktBwomnPqrp-8ofGrK18w0XFrKr9A0TQ.cache +0 -0
  117. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/1aGcEQlzCZqj47bR8b18bidGhSM2TCoUF8PH47DmsLU.cache +0 -0
  118. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/1k4qrvfTSqyZpqJotrEJvryNYKwAYhcPYDr762tOceA.cache +1 -0
  119. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/1qAjZK81hSd2VjC4whKNDW4X7SdJpLItpFtUW5R2vUU.cache +0 -0
  120. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/1tgQBRMWbVAGLWkDo0fO1_ePFLz60fDuTdCKwp-LIJU.cache +1 -0
  121. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/22e58P_cEp6-Pu5wgZqEMEpiJGooGJ2dI6gfNXacBaw.cache +1 -0
  122. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/2ZbqEyDxBgh2_LtnR16sYKThwIziSqlASeCjQjkwL7Q.cache +0 -0
  123. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/2t8ZjvFIs5Qg2owTTr20k8NqE0dCrbY5mHTjJGQd2To.cache +0 -0
  124. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/4cBcXkgJSg0A9kNtcagSpP-C7RpYMO7GIYMiIdC0K48.cache +0 -0
  125. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/4eWrs3PFkK1uDMlHgGflFhNtKLF63kY4nMqArSbZBpY.cache +0 -0
  126. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/5-_j0ZY9kq3RzZvSq8dpYirIlmqsRJUSBNkE97ZcqWY.cache +0 -0
  127. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/55ea_CKRYg4qGN5pyZy2H1oKxEnbQuJzgGyrVQ1ZE-k.cache +1 -0
  128. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/5PZzqc1OeigG9XRqgCM3SCT9fLVn6wTm6awQx74XAD0.cache +1 -0
  129. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/5WUZd0B2PMhhtp-V7XsX5zFLOPXl9z2WpIVdT8rW5AE.cache +0 -0
  130. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/5cWdZIkyqWp1hyfiXzGiMnuqZ_4SlHG0DmWpUkQYuS8.cache +1 -0
  131. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/5wFIFg4lQ-rd1ZWBhlRi9J56-EqjP61WWYq0jOA7bek.cache +1 -0
  132. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/6COX4oqZCCZnmoes6ehqGZqIr2xtXv5HVYqJzRnccnU.cache +2 -0
  133. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/6Ck5oeyDTZNctS2vkmtYRv6UU5SCv8DW_cqAumQHEW4.cache +1 -0
  134. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/6W7Zp0ylWiCA_3Z-Hese0EPiWLITfAv2OViiC3GHvzU.cache +0 -0
  135. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/6ajykKpm3QojPPBBJIx6vRImRgKpc_V_zX68dF-yV1Q.cache +1 -0
  136. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/75Qu5KXpoOg--ZIa5yMWG0sQS_OoZiF0og8GEfCKodI.cache +0 -0
  137. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/78FVepsCcIAm-tqmhFYO4eaDkF1BHiAwzZjoc1W6XrI.cache +1 -0
  138. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/7OzH_p-6ZYmSIl-UNVwWQfD6PJHalPe5Y01jCP_MF1w.cache +1 -0
  139. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/856F5ONTmAq3bpS5lqrZAzppRy4gwhAkugo9inM3EEU.cache +1 -0
  140. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/8AVC27x21kixmECkHeOm4sR-mSbzhJO320NRwrW6B38.cache +0 -0
  141. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/8KCGLeeBgsHpq-GGsxAKvONGThHONpkBhLmQv5x-5i8.cache +0 -0
  142. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/8cyMCW5yogfK5gPFpci4rPtVb8pVIiZmF5DpOH8F07Y.cache +1 -0
  143. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/9EThCCo9tuqXzBz-afDke-GvEyM_NG0dxw7dSdkzINw.cache +2 -0
  144. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/9NoeClumq19p-VmRk5PPOHLvDXN_Jr6BCYnczJWWfv4.cache +0 -0
  145. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/9YD7CWCBCkOdAYp-yB8nGhaNDiiUWsP7fzRWPmHbzKI.cache +2 -0
  146. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/AY9mbclr0zMOzxzP4BYRTYyvBOlpLFHHQAimzs6dSDI.cache +38 -0
  147. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/AqkMYZH-ERTqi-15YvdhRVtysLKqim5CV7-GILZNras.cache +0 -0
  148. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Au8GVVKkzmp8TySAWMgFJQObozIt4Mr-RW5BolO8J2k.cache +2 -0
  149. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/BBPtOTznDSAhX5tIqbw_JRw9Cppz2SVtSFsJ1CpC37k.cache +2 -0
  150. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/CC0dQuHqBjWqdKsRp2Ntw6nn3M1nC5lUY-dd8lMzJ6Y.cache +1 -0
  151. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/CWYN7KxLVsU-N9FbSIrHgO979x5b6AeyckCfZ892Y7k.cache +2 -0
  152. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/C_Sjupfz09XcSquDwczKxSTxWrEUrjaf49VmA5x68CQ.cache +1 -0
  153. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/CcJCtip5hherUpH0eiHdJI5Stl08Txl1AU8NxDLKtro.cache +0 -0
  154. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Clf7dMHxXwzeU3tZ2yxP8d3xr0HRWHFMdqjBuSceJZ0.cache +0 -0
  155. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Cnkk4N8ysSWHH6ujQDBGzEiLuGa0dVNDL5Zq53tJq-M.cache +0 -0
  156. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/D0USxWIEUAxLvX9bhYdtB_SXMXAJ9nQr9vewnyqrk5k.cache +0 -0
  157. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Dy0AC2wVM0afv2MB-u7UGGLsb_2ExNZ8S6w7SGE-djg.cache +1 -0
  158. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Ee1BFKugxHkzKUuAsIqQc60hV47E4VSUMZwBOThvSeY.cache +1 -0
  159. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/EghXS1aAsnoopkxb4Fv0S21wqJGL59ryH5HV9-30KI8.cache +2 -0
  160. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Eq8I8ukRZZ9BZ2SQxzSNc8mOoyKksxtzwtDh2FRZ1FE.cache +0 -0
  161. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Eu26_D_tZu1dr7mVRA4F2--NUZ2UMM4QRXv9JcqO2TY.cache +0 -0
  162. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/FEfkZdxv5MUSvLMUUWoC3lif13VZBbiaUYPNv8uizgM.cache +0 -0
  163. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/FF9LKRGOPVZl03UeeMXbHRXBFwG4SkAdOfcDClwXXx8.cache +1 -0
  164. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/F_NOlk6iL-Gonygn5tsU_AaDA69HBxeExwCiAa6Ezi4.cache +2 -0
  165. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/FuMG_mCkNUt0OV_qrahX3ne-LN8Y3J-17T-I5BwYT_U.cache +2 -0
  166. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/FzIl4k5FDcnN8SbzckzMXWXsj2DwBv_tGvZZky8_cvk.cache +0 -0
  167. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/GBe9GA2qATaLqF7GTbxcZ8sWcPJ2zWeT8PFE8Cynb4U.cache +1 -0
  168. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/GUcaNDg0KOqTIS7ltde6vWEZy4eTkdPuecVr52xaqY4.cache +4 -0
  169. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/GWveyzQul11IW7JP-MFTH1p2O-FAiSldGQCixPtBWZc.cache +1 -0
  170. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/H8Py9_cLtmjiNd1zVjVpr-60bPm8OKt1NzBdYpuRoSg.cache +2 -0
  171. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/HIOnKEwfKW9leZhYm8hw2zTPcTC7Lhr9QO3pGkpVUC0.cache +1 -0
  172. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/IUOCPt0S05lp6-q_7CuqTJjuySoP7ZTTe1srP_Sgdag.cache +0 -0
  173. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/IlxQ_nfFkpBhgHXJ9EL7TgHKTrQYX_1ockXtSOHH_1Q.cache +1 -0
  174. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Intu4bn50Zl1tGpuw8N2VhNjvLeG367yEoPjIxYkYxA.cache +49 -0
  175. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/J3EzfF5t_RDdiaU-svpP2DBjb8gnlHHHCQjjpPvzvpk.cache +0 -0
  176. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/J5rhZ_6c58sjOvHqDBBBBTvsLDbUGfHatkjiF1M-Fys.cache +1 -0
  177. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/JP9pt25R98BIDqvwjp_DgmdNj4U1wLrVUhOnoDtekS8.cache +1 -0
  178. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/K2yr6YhOBxRdaqrHViPlAYUKVTWMlI24INQctCW0rWQ.cache +0 -0
  179. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/LT9baTsZAaEEgS5raUZGGsP2vTnlzW9LzvyCfQgqLLs.cache +2 -0
  180. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/LW03HTHDvMz6l4ReQ29sJeZqRg3QLrcVdAutCg9ROyU.cache +0 -0
  181. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/LcZdIStJUZnaKHh7vs-yLld_jzO3MSU4gCJaORFrjYk.cache +7 -0
  182. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/LruVN3C21yeFX4pfE6ZQw7z2CzkYXY5b8PXOTfz2o1E.cache +1 -0
  183. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/M2tXWSvBjMhGoQLT8CaoVYULKWDVirToNVLYqstyW-g.cache +0 -0
  184. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/MJxRV2KlWMJ5KrraeWvC4yp7N4-aMpktlzqBpoLhft8.cache +0 -0
  185. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/NGgP2dkovkWF23p4ypqAUEO3kldLkAA7E9hERHoxJ_M.cache +2 -0
  186. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/NX-xwAHuCC7QChZD4MSpX9fgCXgl532SBhXfSsIxG4k.cache +0 -0
  187. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/OQdV6HhyTI5Otzo9cwR6IY-8eX0eip8x561B8hXKikY.cache +0 -0
  188. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/OSmr2Sj9749HFHCMkGsJP2YGkQxIztofCliXs0urGE8.cache +0 -0
  189. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/P73ImcSy1BYWt27ZGM-JKdkbzyIm2063NZr-dn-ygPE.cache +1 -0
  190. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/PVxgcRUvLL0uRj6ScbeM7YyccWyjP2O2kvs2640MHck.cache +1 -0
  191. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/PmcUgH3Y4bLndb9k4NAJlxdFPTXl3T8-jEskNYv7T9M.cache +15 -0
  192. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/PmrPSezdyM_8N-tzxdbn62XyY_l-YJPz7Tm7Qi1z2_M.cache +0 -0
  193. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/QAr8mslUFMN0vPkEEQAZEbAUGes7lnpEtfFtKSK8lCc.cache +1 -0
  194. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/QFioo2rOp-ljy1-PIoxzqOTmxmc6HFAft-qNbbQvfkQ.cache +0 -0
  195. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/QPGkAA8L-cs-AO80ws0mqld73EIG2HCd8hzkga35Ydc.cache +1 -0
  196. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/QaJhvzKs8vkSfWT534wn8jNcxfcnMDp4i8cDbwWESbs.cache +0 -0
  197. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/RICRLw8IGgYZrEFYgyA-MY8-o_kXcmcY1gCavTvwW64.cache +2 -0
  198. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/RgyohxMtV3OKNhuwrAaDjfXMV7SsjprKrEVgZ6NhwzE.cache +0 -0
  199. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/RsbxexS-d0Msc_BIthGWINzE8v7aFHiWQVqTbifUHp4.cache +1 -0
  200. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/SZlNp_5FFT99-2Qs5TFLbTZ4ZOG2UFO6sExA-aa-9Xc.cache +0 -0
  201. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/T5Z3oNqbaal-reBCFzxyo8yxV-drGVwQjIC1O_pkHNI.cache +0 -0
  202. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/T6Ft0zMwwCntps471lA0_0aXo1KaOp-ZFeptSt9SRks.cache +2 -0
  203. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/TQ7i9C1sBaWIfDFYnQo4TqjBOMYbOVxm6f4Qhl0Uf6M.cache +1 -0
  204. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/TR10mW2AT2rabnCmUhSF2tBx-ZpQJZfpoezdescBWxg.cache +0 -0
  205. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/TSR9oCO5WIJZHL855zPdgj-pvzkWlz0vlnIPSMRudy4.cache +0 -0
  206. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/V9W2dbEVRrR0tD27e8bft0flt50g1HHugzTd7lFVoMY.cache +2 -0
  207. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/VHnCzqYhXqo4PNpfO5rhh1rxxllOWMQWrJ_1an8CxJ8.cache +0 -0
  208. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Vs4mCFlsskLe0HvAg_ODhYRP8lNofUxZ45d6sOzUfC0.cache +1 -0
  209. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/VsHDpo2bcpN87OPpULfpEIuC7ArNRDa4RgDTqYSgbbc.cache +1 -0
  210. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/W1XNy0_UmGwk7xmb-0QiIdkD_gx_tjV351xE8X5LCPY.cache +1 -0
  211. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/WEPPUYRJVm2CgPjW9cTdBuuFhadPuO7qPEqvqecfKjg.cache +1 -0
  212. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/WIwRcAEBsLT7LSFw8071ukLJbJlwFoX_JaHD9w7fEAc.cache +16 -0
  213. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/WSR5PdIRaA9ix0LLhrUegJL8ztgPoIgZHdaq1d3Jm7k.cache +2 -0
  214. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/WxVFbgL4Oty9vrd1AD37P2KqOGjwvcH5o_LSGrMI_do.cache +1 -0
  215. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/XSXbBZ-YPcBvmUp0fzcIUcTwqNvYHvUU7xfLa38qYvg.cache +1 -0
  216. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/YB9oCB5SEQMC6OwASUsvmD1GE90Ul31VfE2ZRo1Hd2k.cache +1 -0
  217. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Yf6ZOsV9gRVVFTsRNcQPGxKgCQ63L3JprFkpZMD0slI.cache +1 -0
  218. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/YjXlZUeBr9ONZpMKis8Beab3ld-NdnlSKXm2oZOsysc.cache +0 -0
  219. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/ZBbRPnK9QPeL_bLmZNttUrL0MMH6DtrYDpD4f1DbYtc.cache +0 -0
  220. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/_7w_iwIfp6xsakWz0Ww-HrRNserrl5q6WzSq1iYZGaQ.cache +0 -0
  221. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/_k6iDcm-RS6SK8ChV7hlp56ZM2bVtgzaDCrpSHIDFZ4.cache +0 -0
  222. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/_tne4TjP6WhsfK-a0TBVts5lr-lr-sDxyQiKIugRPhM.cache +1 -0
  223. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/_zOYmE_ymvMvcRhHFdH2JutNJimhiytkMAhh4Oq6mkk.cache +0 -0
  224. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/aDjgtkQ97t1Rcjxv5nZUTSSYXea5orrfkCeCNrlNNao.cache +0 -0
  225. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/aKAjc-eEaECxCE89czdDC52Kqkw11EBSF9vk7QorxPA.cache +0 -0
  226. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/auLKIVQfT6ZcV9nSxkDD4xMrcIRtB_1-hO1qKXOcwxo.cache +2 -0
  227. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/axJrczuMPd6m4cWaLl9wfSWgg5SWjyHvv1N0d8e7cas.cache +1 -0
  228. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/cWuWB7O6uRomqwh3IemLWVclp4_ioPR7TBAF7yrPpV0.cache +1 -0
  229. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/ciEBvpxWzLqer60DBJkr319p1iKyYHZxfCm3tIPMqcI.cache +0 -0
  230. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/ct5UmPAxknsInqDq17r9u_NbuFw8F6w4ZLKNU05xZ_Q.cache +1 -0
  231. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/cxW0sGi1l_Lc7eCBF8kxQo4kNtHw27K5H-Ngpiixm2A.cache +0 -0
  232. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/d7lXJjCfvSvwTWSI3x4kn3TQzzYG0DGvqTOJL3avl6Y.cache +0 -0
  233. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/dW3LJvt2E0gKdWoqZTSTWtntGqxhTENv8_-mbT_kfn0.cache +0 -0
  234. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/dfT6vHCtyIBci9lpNUVgyqepSYt55BCo8MDzrPXxUEw.cache +2 -0
  235. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/e7OkNhH6RmnQjEY0ZEO597J545crZH0qZdVDYz71KT4.cache +2 -0
  236. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/ea-3NiBlut0EOdCVqVGn-RwNm0CiwA8YVBRqfRqhgLg.cache +1 -0
  237. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/eqpR2RCSOj4T0wmrPGJDb_td3gtOdiyLwD02BpzuBkg.cache +1 -0
  238. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/eqrwo9jjG9uZiNQCUMkdkvT40JGz2uvrufAv-l00X1k.cache +2 -0
  239. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/fG1WmTPapxY9EMQ5D8HQw8E2MpudT32v--jD6VgazTU.cache +2 -0
  240. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/fLosOyYOiUc-ZJIEAtgmz68UfDVlAVCVMAxtAlML-nQ.cache +1 -0
  241. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/faEE1R7Sb00wgGFfL9FC9IqAGSkEHNY7rLPURjZVFv0.cache +1 -0
  242. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/fgmBwPUcbsTKyMd7bxMbzh9YFF7GkD269KSZbCOpe54.cache +1 -0
  243. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/g4m06tmSxrOnDxGpUyYkIEY8hi0ymUoUzYMAh06YkGc.cache +0 -0
  244. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/gP9Pm0rpnz4IvvhguI8VxK8xhDKU8WisGwfm5ox97RY.cache +0 -0
  245. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/gtka4cvnxw2bm_SnkE-5LxtRYKxD-MvM_T7lYxdLAug.cache +0 -0
  246. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/hQFzaNvvDOyvg2U4FZcg-xUjctMTLEdb7tK-RYIziz8.cache +0 -0
  247. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/hcS2HARtyE_tpJmmwUqYO-9e-Tshg3TF6W6XL29_cwM.cache +1 -0
  248. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/hdMwJqicGzH0qHgBqMVfxHB8u3-zdirRgb1zpnRfb6w.cache +2 -0
  249. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/hfIPOqDhaIk7vhQa4hLyWEIQasPwJSn3H-i2egLuFvQ.cache +2 -0
  250. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/i3Mr4BCaCS865aFe9brU973ERtfoSONrUQhX5FW509w.cache +0 -0
  251. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/jBOiy_uvOKOoBovFao2qEf6xVkGYRFmw-CR_I756N5g.cache +1 -0
  252. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/jZZQUkAYSpxGGWp7Vb_vs2S3Clde8_XKFWwjwHaBmU0.cache +0 -0
  253. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/jiUvf7zJxbsJ9a9IiZOy06PqL6dOOfprzyXci5p8vMM.cache +0 -0
  254. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/kd10Jyu0ZXLelGbmQo03cFEKpR0qQRw-QyPPMlnY-FQ.cache +0 -0
  255. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/ksZL57FCLWVpXdOSIHVytq_XIsGz78TdArP4aWt7uQA.cache +1 -0
  256. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/l4Mb7Zqpi9HWWa67ftgd_ZkPTvGuhxm--tpHlgu4Eyc.cache +0 -0
  257. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/m3gQ2mqyaWT0r9UVJriOzT0qkFiL4aZ5mhMgbbyLmyw.cache +1 -0
  258. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/n6NcZJQK0j-WDDTq_7wksLUZBBYhGRPaW38Cua19t4E.cache +0 -0
  259. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/nKs1V_XYWUW2uG9E7WQPaiVIvYx2I5ttwdMZ9bRsUVY.cache +2 -0
  260. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/oB34rjWhV_SBgt62MMSw20hEYuiVTjLMILeSBjagbDo.cache +0 -0
  261. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/oydOGeF22N2dttfBS68MA5PK4ofniHzd-LgBwVmJvI4.cache +0 -0
  262. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/pA1evykc28UE2mszGRw015uHbbmBCU9gFZIcU8Hrwls.cache +1 -0
  263. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/pBYZnqSsUmggXeAPQXcQrZSfrScDOEsZQdeXOIqfHaA.cache +1 -0
  264. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/pENTpYJeZrQ-P80SXbbHVaXcEd7kaOm1bZRItPVK7OE.cache +0 -0
  265. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/pYKIN2HEVMsGLDogjm8iDQ_4W8iGEq98NsJbOdA822o.cache +1 -0
  266. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/pb5zODtFDJpqFTtbh09cOhwG1mZowQW1EZ-54eauNTc.cache +1 -0
  267. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/pnDWkMT2Wf6v8kCepJzn9oEGWrxNOY-H9MlCq85zTlU.cache +0 -0
  268. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/qJ6pwEWoy3oUs_aPayRv5D5d_F7oEyNIzxrJCaEpcpM.cache +0 -0
  269. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/rJ88KtO5aBXvyE9sef5emc-MsAJaTna76vG5TNayYa4.cache +0 -0
  270. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/rPyv5XauOpu-aOgB95w5ZSl6jCFUGvS8YE1h1eZZID0.cache +2 -0
  271. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/rcp1tSuAgctt1BdAdUoGgD_UtZeD7w3rLuANXg8YU58.cache +0 -0
  272. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/rfYNZtDWV3PCq5a57xTyj0-_iC1Psq1TaxWG86fXR2A.cache +1 -0
  273. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/smmkAgu4NNfatz7vllczgMFH_tckzDUAmeV3WvmmsRE.cache +0 -0
  274. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/szDR2M9t_osfhsE_agd1lcIjKrl5nwRmORMlyoWxTus.cache +0 -0
  275. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/t4fruk986h623vtFPEW2sALWc3kl3ayPfBbgOzRm6Cs.cache +0 -0
  276. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/tJDIhl16K_HokIK8UZx1y9hy-Ne6lk9ie2kMbsHVxdY.cache +1 -0
  277. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/tSDhvZZY2gcpUHWppbAMQYQL0iNPOc3Vo2HHrnqKlDw.cache +1 -0
  278. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/tYYAXLHGMIYQ1Ls-jw8thSBIzdixEpeQC2kg6irmEy0.cache +0 -0
  279. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/tgFK--mLRPBU9bZUb6lc4kt6Qq9-Ux6AAfG7mDQBpu8.cache +1 -0
  280. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/tpBLVkgP9PSqHqSHfPf9ZLar0vHGOTCOUl0FKOqGN54.cache +1 -0
  281. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/u0B5U9yc20iANkRJi6-SiyL9U5RMrThVGmgnWSR2Rew.cache +1 -0
  282. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/vtTvV-oGMOMD-l4YDTQRNHPiFRebBjqEfL9IoavTSGE.cache +0 -0
  283. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/w3rjuVGSs9xUdab61H5KOFtoRsLH5abeNs9uloC2b94.cache +0 -0
  284. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/w9RM9nORoFIx66Xb5PwygnSIR3922sjAkZkXvyeykgE.cache +1 -0
  285. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/wK-n2sVphfsiv5g-IV404qJkdw6Skfo5wk55Yf8IHfs.cache +0 -0
  286. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/wbSRRkjts6z6OP0o88ZwLIz6Za9iMMeF8F1FMAubBxc.cache +1 -0
  287. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/xE9HS1AxUe2VZv8zzVYALc75Yhv53_LPpQNxurm0oSI.cache +1 -0
  288. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/xX3QhVOxSxG9HjrdSvjeQoK1iBpYJX3Kw-yjea2vSuo.cache +0 -0
  289. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/xa4ZU0nFS4WqDtDriIXMlwNURqkpUm_djZVqiz0ZynA.cache +2 -0
  290. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/xzsnr6Bgr0MP4j4FZVUcYBADfkQCUHoShH_9hGp0ckk.cache +0 -0
  291. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/y6xgU0dR6b-1_hjgAZAhFFq1T9zGZ8yjUQzOefGpcu8.cache +0 -0
  292. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/yJ9qoQ6ZeEPmm4ttulT9hdYPemgTF4VUSdmFjmr9Vpw.cache +0 -0
  293. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/yJuZz8Lopwyvmy-rto8ycJ0nOLWeWSobCY8z-421Bec.cache +0 -0
  294. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/yLZAaEFOlOcJfmo3pRpRpTiQMzBcqSRTrZYb_pJpTBs.cache +2 -0
  295. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/yV9yGvP4CDMeEbb4ff4n_Hzu-GuBbM-S39cIE1WQy6Y.cache +1 -0
  296. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/y_4IIBYH_ItxQoEeXjWm9Igwn6hAkl669CNtYfo0fyI.cache +1 -0
  297. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/zF_lfa7oUNjRgtepm9Ufi0DCzN_IXCJTDHRrH-JHu7Q.cache +2 -0
  298. data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/zeqXKQA7lKQnvEaJsDO404ZaYCV0dk57z-SXUkfmz24.cache +1 -0
  299. data/test/dummy/tmp/pids/server.pid +1 -0
  300. data/test/dummy/vendor/assets/javascripts/revelry_content/content.js +4 -0
  301. data/test/fixtures/rev_content/contents.yml +11 -0
  302. data/test/helpers/rev_content/contents_helper_test.rb +6 -0
  303. data/test/integration/navigation_test.rb +10 -0
  304. data/test/models/rev_content/content_test.rb +9 -0
  305. data/test/revelry_content_test.rb +7 -0
  306. data/test/test_helper.rb +15 -0
  307. metadata +605 -42
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4b28bbdb1b876e965e7386637ba544914f6b2948
4
- data.tar.gz: c2564163d4f6cc415cb3895e1696f5ee6eb4eaae
3
+ metadata.gz: 830867e74bccfaedb121caa8eb50834cdfe0ac3f
4
+ data.tar.gz: 6e72cba8c5a34636bf5c2749eb51511b968e0194
5
5
  SHA512:
6
- metadata.gz: 055dabf42c5bb78e7667d45103ab8af9ed50a0b8d9bd31c22703e6a3668995510ecfe304f6a38fe46806650291e9442ead95df40aa34cc474e0a8884621849ca
7
- data.tar.gz: 722f2c12753be4cd5ab2f6ece678f64255e51b0cba7f289b4329c091d5ce6d3245d9ddaa58e8f10240fd145a115467f9d2f8a637ef717e2b2b0dcc7c27f1f12d
6
+ metadata.gz: b61dc71cfb12d9bada0ff92a6aed69f171d7f919a186e8c3b9c741045d492acfaafe60a56259d697a970b98909049e3fe1a8d09e3333e9d9f6175e64afd0ba6e
7
+ data.tar.gz: 01722e991c6198cde3568cc3f9e07507ca765be7f143d51e9e2f81c915880fb8605813382cbf24881f8cd5f1068b6cdf34a8d307f143abf97a65d3b81756635c
data/README.md CHANGED
@@ -1,7 +1,178 @@
1
- # revelry_content
1
+ RevelryContent
2
+ ===
2
3
 
3
- Coming soon.
4
- Not in that way that people say "coming soon" as some sort of teaser.
5
- Coming soon as in the code exists already.
6
- We're actively prepping it to go in this repo.
7
- Something substantive should show up here within a few days, maybe a couple weeks at most.
4
+ RevelryContent is a gem for managing admin-editable content within Rails applications.
5
+
6
+ # Installation
7
+
8
+ Add it to your gemfile.
9
+
10
+ Then run:
11
+
12
+ ```bash
13
+ bundle install
14
+ rails g revelry_content:install
15
+ rake db:migrate
16
+ ```
17
+
18
+ Mount the engine in your routes.rb file:
19
+
20
+ ```ruby
21
+ mount RevelryContent::Engine => "/revelry_content"
22
+ ```
23
+
24
+ Include RevelryContent::WithRevelryContent in any controllers which need to show editable
25
+ content. You probably want to include it in ApplicationController like so:
26
+
27
+ ```ruby
28
+ class ApplicationController
29
+ include RevelryContent::WithRevelryContent
30
+ def index; end
31
+ end
32
+ ```
33
+
34
+ And include the editor javascript:
35
+ ```javascript
36
+ //= require revelry_content
37
+ ```
38
+
39
+ Add include the editor stylesheet:
40
+ ```css
41
+ /*
42
+ *= require revelry_content/application
43
+ */
44
+ ```
45
+
46
+
47
+ # Configuration
48
+
49
+ ## Configuring authentication
50
+
51
+ ```ruby
52
+ RevelryContent.configure do |config|
53
+ config.user_for_content do |controller|
54
+ # Your authentication logic here
55
+ controller.current_user
56
+ end
57
+ end
58
+ ```
59
+
60
+ ## Configuring authorization
61
+
62
+ You can set a block which takes two params `user` and `content` to handle authorization.
63
+ True is authorized, false is unauthorized.
64
+
65
+ ```ruby
66
+ RevelryContent.configure do |config|
67
+ config.authorization_policy do |user|
68
+ # Your authorization logic here
69
+ user.admin?
70
+ end
71
+ end
72
+ ```
73
+
74
+ ## Configuring file uploads
75
+
76
+ RevelryContent uses [carrierwave](https://github.com/carrierwaveuploader/carrierwave) to store image uploads. You'll want to configure carrierwave appropriately for your app.
77
+
78
+ # Use in ERB Templates
79
+
80
+ RevelryContent provides helpers for setting up edit controls:
81
+
82
+ ### Adding the RevelryContent menus and edit mode button
83
+
84
+ Add the `revelry_content/contents/menus` partial to the page to place the edit button and top bar on the page. The top bar will be invisible unless we are in edit mode.
85
+
86
+ ```erb
87
+ <%= render 'revelry_content/contents/menus' %>
88
+ ```
89
+
90
+ ### Editable text
91
+
92
+ ```erb
93
+ <%= editable_text(lookup, t, user) %>
94
+ ```
95
+
96
+ `lookup` is a lookup hash of the available content. If you have included `RevelryContent::WithRevelryContent` in your controller, `@revelry_content_contents` is the default lookup with all content.
97
+
98
+ `t` is the content key of the content, which is just a unique string for each piece of changeable content.
99
+
100
+ `user` is the user to give to the authorization policy. With devise, this is often `current_user`.
101
+
102
+ So for, an editable homepage headline, with the standard lookup and
103
+ `current_user` as the user, you would invoke the helper like this:
104
+
105
+ ```erb
106
+ <%= editable_text(@revelry_contents_content, 'home.headline', current_user, default_text: 'Lorem ipsum') %>
107
+ ```
108
+
109
+ ### Editable images
110
+
111
+ Editable images work in a similar manner to editable text:
112
+
113
+ ```erb
114
+ <%= editable_image(@revelry_contents_content, 'home.image', current_user, default_url: 'http://placehold.it/200x200') %>
115
+ ```
116
+
117
+ # Using in javascript (including React)
118
+
119
+ ## Making content available to javascript
120
+
121
+ You can configure RevelryContent to export all of your content into javascript.
122
+
123
+ ```ruby
124
+ RevelryContent.configure do |config|
125
+ config.js_export = true
126
+ end
127
+ ```
128
+
129
+ Then run the export task:
130
+
131
+ ```shell
132
+ rake revelry_content:export_js
133
+ ```
134
+
135
+ And include the exported js in your application.js:
136
+
137
+ ```javascript
138
+ //= require revelry_content/content
139
+ ```
140
+
141
+ and access it like this:
142
+
143
+ ```javascript
144
+ RevelryContent.Content.home.headline
145
+ ```
146
+
147
+ The javascript export will automatically update whenever content is updated.
148
+
149
+ ## Adding Editable Sections with React
150
+
151
+ RevelryContent is built on React, so you can also directly invoke the React components:
152
+
153
+ ```coffeescript
154
+ <RevelryContent.EditableText canEdit={ true } content={ RevelryContent.Content.home.headline } />
155
+ ```
156
+
157
+ or
158
+
159
+ ```coffeescript
160
+ <RevelryContent.EditableImage canEdit={ true } content={ RevelryContent.Content.home.image } />
161
+ ```
162
+
163
+ [More details are availble here](https://github.com/revelrylabs/revelry_content/blob/master/react-components.md)
164
+
165
+
166
+ ## Adding the top bar and buttons with React
167
+
168
+ ```coffeescript
169
+ <RevelryContent.TopBar />
170
+ ```
171
+
172
+ and
173
+
174
+ ```coffeescript
175
+ <RevelryContent.EditModeButton />
176
+ ```
177
+
178
+ These do not require any props.
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'RevelryContent'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
Binary file
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3
+ <svg xmlns="http://www.w3.org/2000/svg">
4
+ <metadata>Generated by IcoMoon</metadata>
5
+ <defs>
6
+ <font id="icomoon" horiz-adv-x="1024">
7
+ <font-face units-per-em="1024" ascent="960" descent="-64" />
8
+ <missing-glyph horiz-adv-x="1024" />
9
+ <glyph unicode="&#x20;" d="" horiz-adv-x="512" />
10
+ <glyph unicode="&#xe600;" d="M512 951.294c-277.975 0-503.294-225.322-503.294-503.294s225.322-503.294 503.294-503.294 503.294 225.322 503.294 503.294-225.322 503.294-503.294 503.294zM590.941 262.825c-37.98-57.027-76.617-100.969-141.62-100.969-44.367 7.239-62.602 39.026-53.001 71.429l83.626 276.968c2.051 6.775-1.354 14.015-7.549 16.222-6.155 2.17-18.235-5.846-28.687-17.306l-50.563-60.822c-1.354 10.22-0.155 27.101-0.155 33.915 37.98 57.027 100.388 102.014 142.703 102.014 40.226-4.103 59.271-36.276 52.266-71.623l-84.205-278.322c-1.123-6.272 2.208-12.66 7.898-14.673 6.195-2.17 19.203 5.846 29.695 17.306l50.524 60.783c1.354-10.22-0.929-28.107-0.929-34.92zM579.675 624.58c-31.979 0-57.917 23.305-57.917 57.609s25.94 57.569 57.917 57.569 57.917-23.305 57.917-57.569c0-34.341-25.94-57.609-57.917-57.609z" />
11
+ <glyph unicode="&#xe601;" d="M512 948.069c-276.288 0-500.069-223.781-500.069-500.069s223.781-500.069 500.069-500.069 500.069 223.781 500.069 500.069-223.781 500.069-500.069 500.069zM762.035 268.726l-70.759-70.759-179.274 179.274-179.274-179.274-70.759 70.759 179.274 179.274-179.274 179.274 70.759 70.759 179.274-179.274 179.274 179.274 70.759-70.759-179.274-179.274 179.274-179.274z" />
12
+ <glyph unicode="&#xe602;" d="M992.785 143.476l-413.531 708.079c-34.486 34.486-90.442 34.486-124.928 0l-413.564-708.079c-34.486-34.453-34.486-90.376 0-124.895h951.99c34.552 34.519 34.552 90.442 0.033 124.895zM478.703 597.372c0 27.384 22.198 49.548 49.548 49.548s49.548-22.165 49.548-49.548v-231.226c0-27.351-22.198-49.548-49.548-49.548s-49.548 22.198-49.548 49.548v231.226zM528.549 151.172c-27.351 0-49.548 22.132-49.548 49.548 0 27.351 22.198 49.548 49.548 49.548s49.548-22.198 49.548-49.548c0-27.417-22.198-49.548-49.548-49.548z" />
13
+ <glyph unicode="&#xe603;" d="M512 955.375c-280.218 0-507.375-227.157-507.375-507.375s227.157-507.375 507.375-507.375c280.166 0 507.375 227.157 507.375 507.428 0 280.166-227.209 507.323-507.375 507.323zM504.020 152.084h-2.695c-41.33 1.216-70.505 31.712-69.288 72.459 1.162 40.062 31.023 69.183 70.981 69.183l2.431-0.105c42.493-1.216 71.351-31.394 70.134-73.306-1.216-40.167-30.55-68.232-71.561-68.232zM677.954 497.257c-9.725-13.741-31.077-30.971-58.031-51.954l-29.701-20.453c-16.278-12.684-26.109-24.681-29.756-36.362-2.959-9.196-4.333-11.68-4.598-30.442v-4.756h-113.367l0.317 9.619c1.427 39.322 2.378 62.578 18.71 81.761 25.634 30.020 82.184 66.488 84.564 68.019 8.139 6.078 14.957 13.001 20.031 20.453 11.892 16.437 17.124 29.333 17.124 41.912 0 17.653-5.18 33.985-15.486 48.412-9.935 14.058-28.804 21.035-56.075 21.035-27.060 0-45.611-8.562-56.657-26.214-11.416-18.020-17.177-36.996-17.177-56.392v-4.862h-116.855l0.212 5.074c3.012 71.509 28.593 123.039 75.842 153.111 29.756 19.079 66.805 28.751 109.984 28.751 56.446 0 104.223-13.741 141.748-40.801 38.106-27.43 57.397-68.548 57.397-122.14-0.053-29.966-9.513-58.137-28.224-83.77z" />
14
+ <glyph unicode="&#xe604;" d="M576 0c0 35.376-28.656 64-64 64h-384v768h384c35.344 0 64 28.624 64 64s-28.656 64-64 64h-448c-35.344 0-64-28.624-64-64v-896c0-35.376 28.656-64 64-64h448c35.344 0 64 28.624 64 64zM384 512c-35.344 0-64-28.624-64-64s28.656-64 64-64h384v-192l256 256-256 256v-192h-384z" />
15
+ <glyph unicode="&#xe605;" d="M512 948.069c-276.037 0-500.069-224.031-500.069-500.069s224.031-500.069 500.069-500.069 500.069 224.031 500.069 500.069-224.031 500.069-500.069 500.069zM512 47.944c-221.030 0-400.056 179.025-400.056 400.056s179.025 400.056 400.056 400.056 400.056-179.025 400.056-400.056-179.025-400.056-400.056-400.056z" />
16
+ <glyph unicode="&#xe606;" d="M512 698.035c-138.019 0-250.035-112.014-250.035-250.035s112.014-250.035 250.035-250.035 250.035 112.014 250.035 250.035-112.014 250.035-250.035 250.035zM512 948.069c-276.037 0-500.069-224.031-500.069-500.069s224.031-500.069 500.069-500.069 500.069 224.031 500.069 500.069-224.031 500.069-500.069 500.069zM512 47.944c-221.030 0-400.056 179.025-400.056 400.056s179.025 400.056 400.056 400.056 400.056-179.025 400.056-400.056-179.025-400.056-400.056-400.056z" />
17
+ <glyph unicode="&#xe607;" d="M1020.194 448h-129.408v11.185c-5.892 241.903-203.169 436.233-445.672 436.233-246.323 0-445.945-200.331-445.945-447.418s199.622-447.309 445.945-447.309c103.549 0 198.858 35.462 274.584 94.82l-76.706 82.053c-55.429-40.808-123.843-65.086-197.876-65.086-184.728 0-334.486 150.249-334.486 335.522s149.758 335.522 334.486 335.522c180.963 0 328.321-144.193 334.158-324.339v-11.185h-145.774l190.621-212.443 196.076 212.443z" />
18
+ <glyph unicode="&#xea2e;" d="M889.68 793.68c-93.608 102.216-228.154 166.32-377.68 166.32-282.77 0-512-229.23-512-512h96c0 229.75 186.25 416 416 416 123.020 0 233.542-53.418 309.696-138.306l-149.696-149.694h352v352l-134.32-134.32zM928 448c0-229.75-186.25-416-416-416-123.020 0-233.542 53.418-309.694 138.306l149.694 149.694h-352v-352l134.32 134.32c93.608-102.216 228.154-166.32 377.68-166.32 282.77 0 512 229.23 512 512h-96z" />
19
+ <glyph unicode="&#xea7d;" d="M256 320c0 0 58.824 192 384 192v-192l384 256-384 256v-192c-256 0-384-159.672-384-320zM704 192h-576v384h125.876c10.094 11.918 20.912 23.334 32.488 34.18 43.964 41.19 96.562 72.652 156.114 93.82h-442.478v-640h832v268.624l-128-85.334v-55.29z" />
20
+ </font></defs></svg>
Binary file
Binary file
@@ -0,0 +1,21 @@
1
+ # @cjsx
2
+ #= require ./revelry_content/utilities
3
+ #= require ./revelry_content/config
4
+ #= require ./vendor/react_ujs
5
+ #= require jquery
6
+ #= require underscore
7
+ #= require backbone
8
+ #= require moment
9
+ #= require moment-timezone-with-data-2010-2020
10
+ #= require_tree ./revelry_content/mixins
11
+ #= require_tree ./revelry_content/models
12
+ #= require_tree ./revelry_content/components
13
+
14
+ RevelryContent.dispatcher = new Backbone.Model();
15
+
16
+ $ ->
17
+ RevelryContent.Utilities.rev_script_loader React?, 'https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/react-with-addons.js', =>
18
+ RevelryContent.Utilities.exportLazyComponents()
19
+ RevelryContent.load_react_ujs()
20
+
21
+ window.RevelryContent = RevelryContent
@@ -0,0 +1,90 @@
1
+ RevelryContent.Utilities.lazyComponentDefinition ->
2
+ RevelryContent.AdminTopBar = React.createClass
3
+ render: ->
4
+ <nav className="topBar">
5
+ <ul className="inline-list right">
6
+ <li onClick={ @makePageButton('history') }>
7
+ <span className="icon-loop2"></span>
8
+ History
9
+ </li>
10
+ <a href={ RevelryContent.base_path + 'contents/export.json' }>
11
+ <li>
12
+ Export
13
+ </li>
14
+ </a>
15
+ <li onClick={ @makePageButton('import') }>
16
+ Import
17
+ </li>
18
+ </ul>
19
+ <div className="topBar-container">
20
+ <div className="topBar-items">
21
+ Content Admin
22
+ </div>
23
+ </div>
24
+ </nav>
25
+
26
+ makePageButton: (page)->
27
+ return (e)->
28
+ RevelryContent.dispatcher.trigger 'pageChange', page
29
+
30
+ RevelryContent.AdminTabbedArea = React.createClass
31
+ getInitialState: ->
32
+ state =
33
+ page: @firstChildPage()
34
+
35
+ render: ->
36
+ @findChildByPage(@state.page)
37
+
38
+ findChildByPage: (page)->
39
+ return null unless @props.children
40
+ if React.Children.count == 1
41
+ if React.Children.only.props.adminTabPage == page
42
+ return React.Children.only
43
+ else
44
+ return null
45
+ else
46
+ for child in @props.children
47
+ if child.props.adminTabPage == page
48
+ return child
49
+ return null
50
+
51
+ firstChildPage: ->
52
+ return null unless @props.children
53
+ if React.Children.count == 1
54
+ return React.Children.only.props.adminTabPage
55
+ else
56
+ return @props.children[0].props.adminTabPage
57
+
58
+ componentDidMount: ->
59
+ RevelryContent.dispatcher.on 'pageChange', @onPageChange
60
+
61
+ componentWillUnmount: ->
62
+ RevelryContent.dispatcher.off 'pageChange', @onPageChange
63
+
64
+ onPageChange: (page)->
65
+ @setState page: page
66
+
67
+ RevelryContent.ImportTab = React.createClass
68
+ render: ->
69
+ <form action="import" method="POST" enctype="multipart/form-data" className="EditablePages">
70
+ <input type="hidden" name="authenticity_token" value={ RevelryContent.Utilities.getAuthenticityToken() } />
71
+ <h2>Import</h2>
72
+ <label>
73
+ <div>
74
+ <input type="file" name="import" />
75
+ </div>
76
+ </label>
77
+ <button className="Button">
78
+ Import
79
+ </button>
80
+ </form>
81
+
82
+ RevelryContent.AdminPage = React.createClass
83
+ render: ->
84
+ <div>
85
+ <RevelryContent.AdminTopBar />
86
+ <RevelryContent.AdminTabbedArea>
87
+ <RevelryContent.VersionHistory adminTabPage="history" />
88
+ <RevelryContent.ImportTab adminTabPage="import" />
89
+ </RevelryContent.AdminTabbedArea>
90
+ </div>
@@ -0,0 +1,16 @@
1
+ RevelryContent.Utilities.lazyComponentDefinition ->
2
+ RevelryContent.EditModeButton = React.createClass
3
+ render: ->
4
+ <button className="EditModeButton" onClick={ @toggleEdit }>
5
+ {
6
+ if RevelryContent.inEditMode
7
+ "Preview this page"
8
+ else
9
+ "Edit this page"
10
+ }
11
+ </button>
12
+
13
+ toggleEdit: ->
14
+ RevelryContent.inEditMode = !RevelryContent.inEditMode
15
+ RevelryContent.dispatcher.trigger 'didChangeEditMode'
16
+ @forceUpdate()
@@ -0,0 +1,10 @@
1
+ RevelryContent.Utilities.lazyComponentDefinition ->
2
+ RevelryContent.Loader = React.createClass
3
+ render: ->
4
+ <div className="RevelryContent-loader">
5
+ <div></div>
6
+ <div></div>
7
+ <div></div>
8
+ <div></div>
9
+ <div></div>
10
+ </div>
@@ -0,0 +1,15 @@
1
+ RevelryContent.Utilities.lazyComponentDefinition ->
2
+ RevelryContent.Timestamp = React.createClass
3
+ getDefaultProps: ->
4
+ props =
5
+ format: 'YYYY-MM-DD'
6
+
7
+ render: ->
8
+ datetime_moment = moment(@props.datetime)
9
+ <span {..._(@props).omit('datetime')} className="TimeAgo #{ @props.className or '' }">
10
+ { datetime_moment.format(@props.format) }
11
+ {
12
+ if @props.withTimeAgo? && @props.withTimeAgo
13
+ <span>&nbsp;({ datetime_moment.fromNow() })</span>
14
+ }
15
+ </span>
@@ -0,0 +1,20 @@
1
+ # @cjsx
2
+
3
+ RevelryContent.Utilities.lazyComponentDefinition ->
4
+ RevelryContent.TopBar = React.createClass
5
+ mixins: [RevelryContent.EditModeListener]
6
+
7
+ render: ->
8
+ if RevelryContent.inEditMode
9
+ <nav className="topBar">
10
+ <ul className="inline-list right">
11
+ <a href={ "#{RevelryContent.base_path}contents" }><li><span className="icon-loop2"></span>History</li></a>
12
+ </ul>
13
+ <div className="topBar-container">
14
+ <div className="topBar-items"><span className="icon-warning"></span>
15
+ You're in edit mode - Don't screw anything up!
16
+ </div>
17
+ </div>
18
+ </nav>
19
+ else
20
+ <span />
@@ -0,0 +1,295 @@
1
+ # @cjsx
2
+
3
+ RevelryContent.Utilities.lazyComponentDefinition ->
4
+ RevelryContent.EditableText = React.createClass
5
+ mixins: [RevelryContent.EditModeListener]
6
+
7
+ propTypes:
8
+ canEdit: React.PropTypes.bool
9
+ content: React.PropTypes.object
10
+ lookup: React.PropTypes.object
11
+ contentKey: React.PropTypes.string
12
+
13
+ getDefaultProps: ->
14
+ props =
15
+ canEdit: false
16
+
17
+ getInitialState: ->
18
+ state =
19
+ editing: false
20
+
21
+ render: ->
22
+ <div className={ @className() } {...@getHandlers()}>
23
+ <span dangerouslySetInnerHTML={{__html: @getContent().html_content }} />
24
+ {
25
+ if @state.editing && RevelryContent.inEditMode
26
+ <RevelryContent.TextEditor content={ @getContent() } onSave={ @onSave } onCancel={ @onCancel } />
27
+ }
28
+ </div>
29
+
30
+ getContent: ->
31
+ if @props.content? && @props.content
32
+ @props.content
33
+ else
34
+ (@props.lookup || RevelryContent.Contents)[@props.contentKey] || @defaultContent()
35
+
36
+ defaultContent: ->
37
+ { html_content: '', key: this.props.contentKey }
38
+
39
+ className: ->
40
+ classes =
41
+ EditableText: true
42
+ 'EditableText--editing': @state.editing
43
+ 'EditableText--inEditMode': RevelryContent.inEditMode
44
+ React.addons.classSet classes
45
+
46
+ getHandlers: ->
47
+ if RevelryContent.inEditMode
48
+ { onClick: @onClick }
49
+ else
50
+ { }
51
+
52
+ onClick: ->
53
+ @setState editing: true
54
+
55
+ onCancel: ->
56
+ @setState editing: false
57
+
58
+ onSave: (model)->
59
+ @props.content = model.attributes
60
+ @setState editing: false
61
+
62
+ RevelryContent.TextEditor = React.createClass
63
+ propTypes:
64
+ content: React.PropTypes.object.isRequired
65
+ onSave: React.PropTypes.func
66
+
67
+ mixins: [React.addons.LinkedStateMixin]
68
+
69
+ componentDidMount: ->
70
+ window.textEditor = @
71
+
72
+ componentWillUnmount: ->
73
+ window.textEditor = null
74
+
75
+ componentDidUpdate: (prevProps, prevState)->
76
+ if @state.newSelectionPosition
77
+ @setSelection @state.newSelectionPosition
78
+ @state.newSelectionPosition = null
79
+
80
+ getInitialState: ->
81
+ state =
82
+ contentString: @props.content.content
83
+ saving: false
84
+ error: false
85
+ linkURL: null
86
+
87
+ render: ->
88
+ <div className="EditorWrapper">
89
+ <div className={ @className() }>
90
+ <div className="ButtonBar">
91
+ <button className="EditorButton EditorButton--bold" onClick={ @onClickBold }>B</button>
92
+ <button className="EditorButton EditorButton--italic" onClick={ @onClickItalic }>I</button>
93
+ <button className="EditorButton EditorButton--underline" onClick={ @onClickUnderline }>u</button>
94
+ <button className="EditorButton EditorButton--link" onClick={ @openLinkFields }>Link</button>
95
+ </div>
96
+ {
97
+ if @state.linkFieldsVisible
98
+ <div>
99
+ <label>
100
+ Link:
101
+ <div>Anchor: { @getSelection().text }</div>
102
+ <input valueLink={ @linkState('linkURL') } />
103
+ <button onClick={ @onMakeLink }>Make Link</button>
104
+ </label>
105
+ </div>
106
+ }
107
+ <textarea valueLink={@linkState('contentString')} ref='textarea'>
108
+ { @state.contentString }
109
+ </textarea>
110
+ <div>
111
+ <button className="EditorButton" onClick={ @onCancel }>Cancel</button>
112
+ <button className="EditorButton" onClick={ @saveEdits }>Save</button>
113
+ </div>
114
+ </div>
115
+ </div>
116
+
117
+ openLinkFields: ->
118
+ @setState linkFieldsVisible: !@state.linkFieldsVisible
119
+
120
+ onMakeLink: ->
121
+ # [text that is a link](http://…)
122
+ left = '['
123
+ right = "](#{ @state.linkURL })"
124
+ @setState contentString: @wrappedSelection(left, right), linkFieldsVisible: false, newSelectionPosition: @getSelection().end + 1
125
+
126
+ onClickBold: (e)->
127
+ @setState contentString: @wrappedSelection('**'), newSelectionPosition: @getSelection().end + 1
128
+
129
+ onClickItalic: (e)->
130
+ @setState contentString: @wrappedSelection('*'), newSelectionPosition: @getSelection().end + 1
131
+
132
+ onClickUnderline: (e)->
133
+ @setState contentString: @wrappedSelection('_'), newSelectionPosition: @getSelection().end + 1
134
+
135
+ wrappedSelection: (left, right)->
136
+ right ||= left
137
+ selection = @getSelection()
138
+ beforeSelection = @state.contentString[0...selection.start]
139
+ selectedText = selection.text
140
+ afterSelection = @state.contentString[selection.end...]
141
+ "#{ beforeSelection }#{ left }#{ selectedText }#{ right }#{afterSelection}"
142
+
143
+ className: ->
144
+ classes =
145
+ TextEditor: true
146
+ 'TextEditor--saving': @state.editing
147
+ 'TextEditor--error': @state.error
148
+ React.addons.classSet classes
149
+
150
+ makeModel: ->
151
+ attributes =
152
+ authenticity_token: RevelryContent.Utilities.getAuthenticityToken()
153
+ content:
154
+ key: @props.content.key
155
+ content: @state.contentString
156
+ model = new RevelryContent.Models.Content attributes
157
+
158
+ saveEdits: ->
159
+ model = @makeModel()
160
+ @setState saving: true, error: false
161
+ model.once 'sync', @onSave
162
+ model.once 'error', @onSaveError
163
+ model.save()
164
+
165
+ onCancel: (e)->
166
+ e.stopPropagation()
167
+ @props.onCancel() if @props.onCancel
168
+
169
+ onSave: (model)->
170
+ @setState saving: false, error: false
171
+ @props.content.content = @state.contentString
172
+ @props.onSave(model) if @props.onSave
173
+
174
+ onSaveError: ->
175
+ @setState saving: false, error: true
176
+
177
+ setSelection: (position)->
178
+ node = @refs.textarea.getDOMNode()
179
+ node.focus()
180
+ node.setSelectionRange(position, position)
181
+
182
+ getSelection: ->
183
+ start = @refs.textarea.getDOMNode().selectionStart
184
+ end = @refs.textarea.getDOMNode().selectionEnd
185
+ selection =
186
+ start: start
187
+ end: end
188
+ text: @state.contentString[start...end]
189
+
190
+ RevelryContent.EditableImage = React.createClass
191
+ mixins: [RevelryContent.EditModeListener]
192
+
193
+ propTypes:
194
+ canEdit: React.PropTypes.bool
195
+ content: React.PropTypes.object
196
+ lookup: React.PropTypes.object
197
+ contentKey: React.PropTypes.string
198
+
199
+ getContent: ->
200
+ if @props.content?
201
+ @props.content
202
+ else
203
+ (@props.lookup || RevelryContent.Content)[@props.contentKey]
204
+
205
+ getDefaultProps: ->
206
+ props =
207
+ canEdit: false
208
+
209
+ getInitialState: ->
210
+ state =
211
+ editing: false
212
+
213
+ render: ->
214
+ <div className={ @className() } {...@getHandlers()}>
215
+ <img src={ @getContent().src } />
216
+ {
217
+ if @state.editing && RevelryContent.inEditMode
218
+ <RevelryContent.ImageEditor contentKey={ @getContent().key } content={ @getContent().src } onSave={ @onSave } onCancel={ @onCancel } />
219
+ }
220
+ </div>
221
+
222
+ className: ->
223
+ classes =
224
+ EditableImage: true
225
+ 'EditableImage--editing': @state.editing
226
+ 'EditableImage--inEditMode': RevelryContent.inEditMode
227
+ React.addons.classSet classes
228
+
229
+ getHandlers: ->
230
+ if RevelryContent.inEditMode
231
+ { onClick: @onClick }
232
+ else
233
+ { }
234
+
235
+ onClick: ->
236
+ @setState editing: true
237
+
238
+ onCancel: ->
239
+ @setState editing: false
240
+
241
+ onSave: (model)->
242
+ @getContent().src = model.get('src')
243
+ @setState editing: false
244
+
245
+ RevelryContent.ImageEditor = React.createClass
246
+ propTypes:
247
+ content: React.PropTypes.object.isRequired
248
+ onSave: React.PropTypes.func
249
+
250
+ componentDidMount: ->
251
+ window.imageEditor = @
252
+
253
+ componentWillUnmount: ->
254
+ window.imageEditor = null
255
+
256
+ getInitialState: ->
257
+ state =
258
+ image: @props.content
259
+ saving: false
260
+ error: false
261
+
262
+ render: ->
263
+ <div className="EditorWrapper">
264
+ <div className={ @className() }>
265
+ <input ref="fileField" type="file"></input>
266
+ <div>
267
+ <button className="EditorButton" type="button" onClick={ @onCancel }>Cancel</button>
268
+ <button className="EditorButton" type="button" onClick={ @saveEdits }>Save</button>
269
+ </div>
270
+ </div>
271
+ </div>
272
+
273
+ className: ->
274
+ classes =
275
+ ImageEditor: true
276
+ 'ImageEditor--saving': @state.editing
277
+ 'ImageEditor--error': @state.error
278
+ React.addons.classSet classes
279
+
280
+ saveEdits: (e) ->
281
+ @setState saving: true, error: false
282
+ fc = new RevelryContent.Models.FileContent({ key: @props.contentKey, src: @refs.fileField.getDOMNode().files[0] })
283
+ fc.once 'sync', (model)=> @onSave(model)
284
+ fc.save()
285
+
286
+ onCancel: (e)->
287
+ e.stopPropagation()
288
+ @props.onCancel() if @props.onCancel
289
+
290
+ onSave: (model)->
291
+ @setState saving: false, error: false
292
+ @props.onSave(model) if @props.onSave
293
+
294
+ onSaveError: ->
295
+ @setState saving: false, error: true