revelry_content 0.0.0 → 0.0.1

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 (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