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.
- checksums.yaml +4 -4
- data/README.md +177 -6
- data/Rakefile +34 -0
- data/app/assets/fonts/icomoon.eot +0 -0
- data/app/assets/fonts/icomoon.svg +20 -0
- data/app/assets/fonts/icomoon.ttf +0 -0
- data/app/assets/fonts/icomoon.woff +0 -0
- data/app/assets/javascripts/revelry_content.js.coffee +21 -0
- data/app/assets/javascripts/revelry_content/components/Admin.js.cjsx +90 -0
- data/app/assets/javascripts/revelry_content/components/EditModeButton.js.cjsx +16 -0
- data/app/assets/javascripts/revelry_content/components/Loader.js.cjsx +10 -0
- data/app/assets/javascripts/revelry_content/components/Time.js.cjsx +15 -0
- data/app/assets/javascripts/revelry_content/components/TopBar.js.cjsx +20 -0
- data/app/assets/javascripts/revelry_content/components/editor.js.coffee +295 -0
- data/app/assets/javascripts/revelry_content/components/versions.js.coffee +170 -0
- data/app/assets/javascripts/revelry_content/config.js.coffee.erb +2 -0
- data/app/assets/javascripts/revelry_content/mixins/EditModeListener.coffee +9 -0
- data/app/assets/javascripts/revelry_content/models/Content.js.coffee +16 -0
- data/app/assets/javascripts/revelry_content/models/Version.js.coffee +8 -0
- data/app/assets/javascripts/revelry_content/server_side.js.coffee +10 -0
- data/app/assets/javascripts/revelry_content/utilities.js +69 -0
- data/app/assets/javascripts/vendor/react_ujs.js +64 -0
- data/app/assets/stylesheets/revelry_content/application.scss +22 -0
- data/app/assets/stylesheets/revelry_content/components/EditableList.scss +42 -0
- data/app/assets/stylesheets/revelry_content/components/buttons.scss +137 -0
- data/app/assets/stylesheets/revelry_content/components/editors.scss +62 -0
- data/app/assets/stylesheets/revelry_content/components/loader.scss +53 -0
- data/app/assets/stylesheets/revelry_content/components/topBar.scss +42 -0
- data/app/assets/stylesheets/revelry_content/components/version.scss +72 -0
- data/app/assets/stylesheets/revelry_content/layout.scss +36 -0
- data/app/assets/stylesheets/revelry_content/modules/base.scss +3 -0
- data/app/assets/stylesheets/revelry_content/modules/colors.scss +14 -0
- data/app/assets/stylesheets/revelry_content/modules/mixins.scss +0 -0
- data/app/assets/stylesheets/revelry_content/modules/vars.scss +46 -0
- data/app/assets/stylesheets/revelry_content/partials/iconStyle.scss +91 -0
- data/app/assets/stylesheets/revelry_content/partials/utilities.scss +10 -0
- data/app/assets/stylesheets/revelry_content/reset.scss +21 -0
- data/app/controllers/revelry_content/application_controller.rb +4 -0
- data/app/controllers/revelry_content/contents_controller.rb +63 -0
- data/app/controllers/revelry_content/versions_controller.rb +36 -0
- data/app/helpers/revelry_content/application_helper.rb +4 -0
- data/app/helpers/revelry_content/contents_helper.rb +29 -0
- data/app/models/revelry_content/content.rb +167 -0
- data/app/models/revelry_content/content_version.rb +21 -0
- data/app/uploaders/src_uploader.rb +48 -0
- data/app/views/layouts/revelry_content/application.html.erb +14 -0
- data/app/views/revelry_content/contents/_menus.html.erb +2 -0
- data/app/views/revelry_content/contents/index.html.erb +1 -0
- data/config/routes.rb +14 -0
- data/lib/generators/revelry_content/install_generator.rb +25 -0
- data/lib/generators/revelry_content/templates/create_revelry_content_contents.rb +12 -0
- data/lib/generators/revelry_content/templates/create_versions.rb +14 -0
- data/lib/revelry_content.rb +38 -0
- data/lib/revelry_content/configuration.rb +69 -0
- data/lib/revelry_content/controller_concern.rb +11 -0
- data/lib/revelry_content/engine.rb +22 -0
- data/lib/revelry_content/js_exporter.rb +15 -0
- data/lib/revelry_content/model_concern.rb +11 -0
- data/lib/revelry_content/railtie.rb +7 -0
- data/lib/revelry_content/version.rb +3 -0
- data/lib/tasks/revelry_content_tasks.rake +6 -0
- data/test/controllers/revelry_content/contents_controller_test.rb +9 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +1 -0
- data/test/dummy/app/assets/javascripts/home.js +2 -0
- data/test/dummy/app/assets/stylesheets/application.scss +14 -0
- data/test/dummy/app/controllers/application_controller.rb +10 -0
- data/test/dummy/app/controllers/home_controller.rb +4 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/helpers/home_helper.rb +2 -0
- data/test/dummy/app/models/fake_user.rb +5 -0
- data/test/dummy/app/views/home/index.html.erb +16 -0
- data/test/dummy/app/views/layouts/application.html.erb +16 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +32 -0
- data/test/dummy/config/environments/production.rb +80 -0
- data/test/dummy/config/environments/test.rb +39 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/carrierwave.rb +5 -0
- data/test/dummy/config/initializers/content.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/revelry_content.rb +2 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/papertrail.rb +1 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20150427211438_create_revelry_content_contents.rb +12 -0
- data/test/dummy/db/migrate/20150427212126_create_versions.rb +14 -0
- data/test/dummy/db/schema.rb +38 -0
- data/test/dummy/log/development.log +1415 -0
- data/test/dummy/public/404.html +58 -0
- data/test/dummy/public/422.html +58 -0
- data/test/dummy/public/500.html +57 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/test/controllers/home_controller_test.rb +7 -0
- data/test/dummy/test/helpers/home_helper_test.rb +4 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/-I_fh6Ob3TV3ynXTvv2TsuKA8cQq62L1tKIrIuNXWjA.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/-YnOULGJdPpgh539S1Ms1ELd5--WkKXQZL4yYylOy-0.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/01i3BQNbZnC6BxmgguLy4xMYU2RnsNjDy_lEOEdzhxY.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/0CsApXQBjT34U567rgWiQGYOFwIpgM1ZcV3ZvrXPAXg.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/0LnMwfkPx0KckDudP0t_qfcIfrUx2JEt9_W28i5ota8.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/0Soh65Z50qGQ79OzRV5ywJzksbLPZ9Y7Xukmqyr6k5E.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/0XbuhYD4hx4ktBwomnPqrp-8ofGrK18w0XFrKr9A0TQ.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/1aGcEQlzCZqj47bR8b18bidGhSM2TCoUF8PH47DmsLU.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/1k4qrvfTSqyZpqJotrEJvryNYKwAYhcPYDr762tOceA.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/1qAjZK81hSd2VjC4whKNDW4X7SdJpLItpFtUW5R2vUU.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/1tgQBRMWbVAGLWkDo0fO1_ePFLz60fDuTdCKwp-LIJU.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/22e58P_cEp6-Pu5wgZqEMEpiJGooGJ2dI6gfNXacBaw.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/2ZbqEyDxBgh2_LtnR16sYKThwIziSqlASeCjQjkwL7Q.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/2t8ZjvFIs5Qg2owTTr20k8NqE0dCrbY5mHTjJGQd2To.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/4cBcXkgJSg0A9kNtcagSpP-C7RpYMO7GIYMiIdC0K48.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/4eWrs3PFkK1uDMlHgGflFhNtKLF63kY4nMqArSbZBpY.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/5-_j0ZY9kq3RzZvSq8dpYirIlmqsRJUSBNkE97ZcqWY.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/55ea_CKRYg4qGN5pyZy2H1oKxEnbQuJzgGyrVQ1ZE-k.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/5PZzqc1OeigG9XRqgCM3SCT9fLVn6wTm6awQx74XAD0.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/5WUZd0B2PMhhtp-V7XsX5zFLOPXl9z2WpIVdT8rW5AE.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/5cWdZIkyqWp1hyfiXzGiMnuqZ_4SlHG0DmWpUkQYuS8.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/5wFIFg4lQ-rd1ZWBhlRi9J56-EqjP61WWYq0jOA7bek.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/6COX4oqZCCZnmoes6ehqGZqIr2xtXv5HVYqJzRnccnU.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/6Ck5oeyDTZNctS2vkmtYRv6UU5SCv8DW_cqAumQHEW4.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/6W7Zp0ylWiCA_3Z-Hese0EPiWLITfAv2OViiC3GHvzU.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/6ajykKpm3QojPPBBJIx6vRImRgKpc_V_zX68dF-yV1Q.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/75Qu5KXpoOg--ZIa5yMWG0sQS_OoZiF0og8GEfCKodI.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/78FVepsCcIAm-tqmhFYO4eaDkF1BHiAwzZjoc1W6XrI.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/7OzH_p-6ZYmSIl-UNVwWQfD6PJHalPe5Y01jCP_MF1w.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/856F5ONTmAq3bpS5lqrZAzppRy4gwhAkugo9inM3EEU.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/8AVC27x21kixmECkHeOm4sR-mSbzhJO320NRwrW6B38.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/8KCGLeeBgsHpq-GGsxAKvONGThHONpkBhLmQv5x-5i8.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/8cyMCW5yogfK5gPFpci4rPtVb8pVIiZmF5DpOH8F07Y.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/9EThCCo9tuqXzBz-afDke-GvEyM_NG0dxw7dSdkzINw.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/9NoeClumq19p-VmRk5PPOHLvDXN_Jr6BCYnczJWWfv4.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/9YD7CWCBCkOdAYp-yB8nGhaNDiiUWsP7fzRWPmHbzKI.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/AY9mbclr0zMOzxzP4BYRTYyvBOlpLFHHQAimzs6dSDI.cache +38 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/AqkMYZH-ERTqi-15YvdhRVtysLKqim5CV7-GILZNras.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Au8GVVKkzmp8TySAWMgFJQObozIt4Mr-RW5BolO8J2k.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/BBPtOTznDSAhX5tIqbw_JRw9Cppz2SVtSFsJ1CpC37k.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/CC0dQuHqBjWqdKsRp2Ntw6nn3M1nC5lUY-dd8lMzJ6Y.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/CWYN7KxLVsU-N9FbSIrHgO979x5b6AeyckCfZ892Y7k.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/C_Sjupfz09XcSquDwczKxSTxWrEUrjaf49VmA5x68CQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/CcJCtip5hherUpH0eiHdJI5Stl08Txl1AU8NxDLKtro.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Clf7dMHxXwzeU3tZ2yxP8d3xr0HRWHFMdqjBuSceJZ0.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Cnkk4N8ysSWHH6ujQDBGzEiLuGa0dVNDL5Zq53tJq-M.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/D0USxWIEUAxLvX9bhYdtB_SXMXAJ9nQr9vewnyqrk5k.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Dy0AC2wVM0afv2MB-u7UGGLsb_2ExNZ8S6w7SGE-djg.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Ee1BFKugxHkzKUuAsIqQc60hV47E4VSUMZwBOThvSeY.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/EghXS1aAsnoopkxb4Fv0S21wqJGL59ryH5HV9-30KI8.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Eq8I8ukRZZ9BZ2SQxzSNc8mOoyKksxtzwtDh2FRZ1FE.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Eu26_D_tZu1dr7mVRA4F2--NUZ2UMM4QRXv9JcqO2TY.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/FEfkZdxv5MUSvLMUUWoC3lif13VZBbiaUYPNv8uizgM.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/FF9LKRGOPVZl03UeeMXbHRXBFwG4SkAdOfcDClwXXx8.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/F_NOlk6iL-Gonygn5tsU_AaDA69HBxeExwCiAa6Ezi4.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/FuMG_mCkNUt0OV_qrahX3ne-LN8Y3J-17T-I5BwYT_U.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/FzIl4k5FDcnN8SbzckzMXWXsj2DwBv_tGvZZky8_cvk.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/GBe9GA2qATaLqF7GTbxcZ8sWcPJ2zWeT8PFE8Cynb4U.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/GUcaNDg0KOqTIS7ltde6vWEZy4eTkdPuecVr52xaqY4.cache +4 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/GWveyzQul11IW7JP-MFTH1p2O-FAiSldGQCixPtBWZc.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/H8Py9_cLtmjiNd1zVjVpr-60bPm8OKt1NzBdYpuRoSg.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/HIOnKEwfKW9leZhYm8hw2zTPcTC7Lhr9QO3pGkpVUC0.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/IUOCPt0S05lp6-q_7CuqTJjuySoP7ZTTe1srP_Sgdag.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/IlxQ_nfFkpBhgHXJ9EL7TgHKTrQYX_1ockXtSOHH_1Q.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Intu4bn50Zl1tGpuw8N2VhNjvLeG367yEoPjIxYkYxA.cache +49 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/J3EzfF5t_RDdiaU-svpP2DBjb8gnlHHHCQjjpPvzvpk.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/J5rhZ_6c58sjOvHqDBBBBTvsLDbUGfHatkjiF1M-Fys.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/JP9pt25R98BIDqvwjp_DgmdNj4U1wLrVUhOnoDtekS8.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/K2yr6YhOBxRdaqrHViPlAYUKVTWMlI24INQctCW0rWQ.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/LT9baTsZAaEEgS5raUZGGsP2vTnlzW9LzvyCfQgqLLs.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/LW03HTHDvMz6l4ReQ29sJeZqRg3QLrcVdAutCg9ROyU.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/LcZdIStJUZnaKHh7vs-yLld_jzO3MSU4gCJaORFrjYk.cache +7 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/LruVN3C21yeFX4pfE6ZQw7z2CzkYXY5b8PXOTfz2o1E.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/M2tXWSvBjMhGoQLT8CaoVYULKWDVirToNVLYqstyW-g.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/MJxRV2KlWMJ5KrraeWvC4yp7N4-aMpktlzqBpoLhft8.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/NGgP2dkovkWF23p4ypqAUEO3kldLkAA7E9hERHoxJ_M.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/NX-xwAHuCC7QChZD4MSpX9fgCXgl532SBhXfSsIxG4k.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/OQdV6HhyTI5Otzo9cwR6IY-8eX0eip8x561B8hXKikY.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/OSmr2Sj9749HFHCMkGsJP2YGkQxIztofCliXs0urGE8.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/P73ImcSy1BYWt27ZGM-JKdkbzyIm2063NZr-dn-ygPE.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/PVxgcRUvLL0uRj6ScbeM7YyccWyjP2O2kvs2640MHck.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/PmcUgH3Y4bLndb9k4NAJlxdFPTXl3T8-jEskNYv7T9M.cache +15 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/PmrPSezdyM_8N-tzxdbn62XyY_l-YJPz7Tm7Qi1z2_M.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/QAr8mslUFMN0vPkEEQAZEbAUGes7lnpEtfFtKSK8lCc.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/QFioo2rOp-ljy1-PIoxzqOTmxmc6HFAft-qNbbQvfkQ.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/QPGkAA8L-cs-AO80ws0mqld73EIG2HCd8hzkga35Ydc.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/QaJhvzKs8vkSfWT534wn8jNcxfcnMDp4i8cDbwWESbs.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/RICRLw8IGgYZrEFYgyA-MY8-o_kXcmcY1gCavTvwW64.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/RgyohxMtV3OKNhuwrAaDjfXMV7SsjprKrEVgZ6NhwzE.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/RsbxexS-d0Msc_BIthGWINzE8v7aFHiWQVqTbifUHp4.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/SZlNp_5FFT99-2Qs5TFLbTZ4ZOG2UFO6sExA-aa-9Xc.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/T5Z3oNqbaal-reBCFzxyo8yxV-drGVwQjIC1O_pkHNI.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/T6Ft0zMwwCntps471lA0_0aXo1KaOp-ZFeptSt9SRks.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/TQ7i9C1sBaWIfDFYnQo4TqjBOMYbOVxm6f4Qhl0Uf6M.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/TR10mW2AT2rabnCmUhSF2tBx-ZpQJZfpoezdescBWxg.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/TSR9oCO5WIJZHL855zPdgj-pvzkWlz0vlnIPSMRudy4.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/V9W2dbEVRrR0tD27e8bft0flt50g1HHugzTd7lFVoMY.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/VHnCzqYhXqo4PNpfO5rhh1rxxllOWMQWrJ_1an8CxJ8.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Vs4mCFlsskLe0HvAg_ODhYRP8lNofUxZ45d6sOzUfC0.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/VsHDpo2bcpN87OPpULfpEIuC7ArNRDa4RgDTqYSgbbc.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/W1XNy0_UmGwk7xmb-0QiIdkD_gx_tjV351xE8X5LCPY.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/WEPPUYRJVm2CgPjW9cTdBuuFhadPuO7qPEqvqecfKjg.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/WIwRcAEBsLT7LSFw8071ukLJbJlwFoX_JaHD9w7fEAc.cache +16 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/WSR5PdIRaA9ix0LLhrUegJL8ztgPoIgZHdaq1d3Jm7k.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/WxVFbgL4Oty9vrd1AD37P2KqOGjwvcH5o_LSGrMI_do.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/XSXbBZ-YPcBvmUp0fzcIUcTwqNvYHvUU7xfLa38qYvg.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/YB9oCB5SEQMC6OwASUsvmD1GE90Ul31VfE2ZRo1Hd2k.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/Yf6ZOsV9gRVVFTsRNcQPGxKgCQ63L3JprFkpZMD0slI.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/YjXlZUeBr9ONZpMKis8Beab3ld-NdnlSKXm2oZOsysc.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/ZBbRPnK9QPeL_bLmZNttUrL0MMH6DtrYDpD4f1DbYtc.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/_7w_iwIfp6xsakWz0Ww-HrRNserrl5q6WzSq1iYZGaQ.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/_k6iDcm-RS6SK8ChV7hlp56ZM2bVtgzaDCrpSHIDFZ4.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/_tne4TjP6WhsfK-a0TBVts5lr-lr-sDxyQiKIugRPhM.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/_zOYmE_ymvMvcRhHFdH2JutNJimhiytkMAhh4Oq6mkk.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/aDjgtkQ97t1Rcjxv5nZUTSSYXea5orrfkCeCNrlNNao.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/aKAjc-eEaECxCE89czdDC52Kqkw11EBSF9vk7QorxPA.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/auLKIVQfT6ZcV9nSxkDD4xMrcIRtB_1-hO1qKXOcwxo.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/axJrczuMPd6m4cWaLl9wfSWgg5SWjyHvv1N0d8e7cas.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/cWuWB7O6uRomqwh3IemLWVclp4_ioPR7TBAF7yrPpV0.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/ciEBvpxWzLqer60DBJkr319p1iKyYHZxfCm3tIPMqcI.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/ct5UmPAxknsInqDq17r9u_NbuFw8F6w4ZLKNU05xZ_Q.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/cxW0sGi1l_Lc7eCBF8kxQo4kNtHw27K5H-Ngpiixm2A.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/d7lXJjCfvSvwTWSI3x4kn3TQzzYG0DGvqTOJL3avl6Y.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/dW3LJvt2E0gKdWoqZTSTWtntGqxhTENv8_-mbT_kfn0.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/dfT6vHCtyIBci9lpNUVgyqepSYt55BCo8MDzrPXxUEw.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/e7OkNhH6RmnQjEY0ZEO597J545crZH0qZdVDYz71KT4.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/ea-3NiBlut0EOdCVqVGn-RwNm0CiwA8YVBRqfRqhgLg.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/eqpR2RCSOj4T0wmrPGJDb_td3gtOdiyLwD02BpzuBkg.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/eqrwo9jjG9uZiNQCUMkdkvT40JGz2uvrufAv-l00X1k.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/fG1WmTPapxY9EMQ5D8HQw8E2MpudT32v--jD6VgazTU.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/fLosOyYOiUc-ZJIEAtgmz68UfDVlAVCVMAxtAlML-nQ.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/faEE1R7Sb00wgGFfL9FC9IqAGSkEHNY7rLPURjZVFv0.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/fgmBwPUcbsTKyMd7bxMbzh9YFF7GkD269KSZbCOpe54.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/g4m06tmSxrOnDxGpUyYkIEY8hi0ymUoUzYMAh06YkGc.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/gP9Pm0rpnz4IvvhguI8VxK8xhDKU8WisGwfm5ox97RY.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/gtka4cvnxw2bm_SnkE-5LxtRYKxD-MvM_T7lYxdLAug.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/hQFzaNvvDOyvg2U4FZcg-xUjctMTLEdb7tK-RYIziz8.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/hcS2HARtyE_tpJmmwUqYO-9e-Tshg3TF6W6XL29_cwM.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/hdMwJqicGzH0qHgBqMVfxHB8u3-zdirRgb1zpnRfb6w.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/hfIPOqDhaIk7vhQa4hLyWEIQasPwJSn3H-i2egLuFvQ.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/i3Mr4BCaCS865aFe9brU973ERtfoSONrUQhX5FW509w.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/jBOiy_uvOKOoBovFao2qEf6xVkGYRFmw-CR_I756N5g.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/jZZQUkAYSpxGGWp7Vb_vs2S3Clde8_XKFWwjwHaBmU0.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/jiUvf7zJxbsJ9a9IiZOy06PqL6dOOfprzyXci5p8vMM.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/kd10Jyu0ZXLelGbmQo03cFEKpR0qQRw-QyPPMlnY-FQ.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/ksZL57FCLWVpXdOSIHVytq_XIsGz78TdArP4aWt7uQA.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/l4Mb7Zqpi9HWWa67ftgd_ZkPTvGuhxm--tpHlgu4Eyc.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/m3gQ2mqyaWT0r9UVJriOzT0qkFiL4aZ5mhMgbbyLmyw.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/n6NcZJQK0j-WDDTq_7wksLUZBBYhGRPaW38Cua19t4E.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/nKs1V_XYWUW2uG9E7WQPaiVIvYx2I5ttwdMZ9bRsUVY.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/oB34rjWhV_SBgt62MMSw20hEYuiVTjLMILeSBjagbDo.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/oydOGeF22N2dttfBS68MA5PK4ofniHzd-LgBwVmJvI4.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/pA1evykc28UE2mszGRw015uHbbmBCU9gFZIcU8Hrwls.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/pBYZnqSsUmggXeAPQXcQrZSfrScDOEsZQdeXOIqfHaA.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/pENTpYJeZrQ-P80SXbbHVaXcEd7kaOm1bZRItPVK7OE.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/pYKIN2HEVMsGLDogjm8iDQ_4W8iGEq98NsJbOdA822o.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/pb5zODtFDJpqFTtbh09cOhwG1mZowQW1EZ-54eauNTc.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/pnDWkMT2Wf6v8kCepJzn9oEGWrxNOY-H9MlCq85zTlU.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/qJ6pwEWoy3oUs_aPayRv5D5d_F7oEyNIzxrJCaEpcpM.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/rJ88KtO5aBXvyE9sef5emc-MsAJaTna76vG5TNayYa4.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/rPyv5XauOpu-aOgB95w5ZSl6jCFUGvS8YE1h1eZZID0.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/rcp1tSuAgctt1BdAdUoGgD_UtZeD7w3rLuANXg8YU58.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/rfYNZtDWV3PCq5a57xTyj0-_iC1Psq1TaxWG86fXR2A.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/smmkAgu4NNfatz7vllczgMFH_tckzDUAmeV3WvmmsRE.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/szDR2M9t_osfhsE_agd1lcIjKrl5nwRmORMlyoWxTus.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/t4fruk986h623vtFPEW2sALWc3kl3ayPfBbgOzRm6Cs.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/tJDIhl16K_HokIK8UZx1y9hy-Ne6lk9ie2kMbsHVxdY.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/tSDhvZZY2gcpUHWppbAMQYQL0iNPOc3Vo2HHrnqKlDw.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/tYYAXLHGMIYQ1Ls-jw8thSBIzdixEpeQC2kg6irmEy0.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/tgFK--mLRPBU9bZUb6lc4kt6Qq9-Ux6AAfG7mDQBpu8.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/tpBLVkgP9PSqHqSHfPf9ZLar0vHGOTCOUl0FKOqGN54.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/u0B5U9yc20iANkRJi6-SiyL9U5RMrThVGmgnWSR2Rew.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/vtTvV-oGMOMD-l4YDTQRNHPiFRebBjqEfL9IoavTSGE.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/w3rjuVGSs9xUdab61H5KOFtoRsLH5abeNs9uloC2b94.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/w9RM9nORoFIx66Xb5PwygnSIR3922sjAkZkXvyeykgE.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/wK-n2sVphfsiv5g-IV404qJkdw6Skfo5wk55Yf8IHfs.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/wbSRRkjts6z6OP0o88ZwLIz6Za9iMMeF8F1FMAubBxc.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/xE9HS1AxUe2VZv8zzVYALc75Yhv53_LPpQNxurm0oSI.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/xX3QhVOxSxG9HjrdSvjeQoK1iBpYJX3Kw-yjea2vSuo.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/xa4ZU0nFS4WqDtDriIXMlwNURqkpUm_djZVqiz0ZynA.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/xzsnr6Bgr0MP4j4FZVUcYBADfkQCUHoShH_9hGp0ckk.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/y6xgU0dR6b-1_hjgAZAhFFq1T9zGZ8yjUQzOefGpcu8.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/yJ9qoQ6ZeEPmm4ttulT9hdYPemgTF4VUSdmFjmr9Vpw.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/yJuZz8Lopwyvmy-rto8ycJ0nOLWeWSobCY8z-421Bec.cache +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/yLZAaEFOlOcJfmo3pRpRpTiQMzBcqSRTrZYb_pJpTBs.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/yV9yGvP4CDMeEbb4ff4n_Hzu-GuBbM-S39cIE1WQy6Y.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/y_4IIBYH_ItxQoEeXjWm9Igwn6hAkl669CNtYfo0fyI.cache +1 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/zF_lfa7oUNjRgtepm9Ufi0DCzN_IXCJTDHRrH-JHu7Q.cache +2 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/v3.0/zeqXKQA7lKQnvEaJsDO404ZaYCV0dk57z-SXUkfmz24.cache +1 -0
- data/test/dummy/tmp/pids/server.pid +1 -0
- data/test/dummy/vendor/assets/javascripts/revelry_content/content.js +4 -0
- data/test/fixtures/rev_content/contents.yml +11 -0
- data/test/helpers/rev_content/contents_helper_test.rb +6 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/models/rev_content/content_test.rb +9 -0
- data/test/revelry_content_test.rb +7 -0
- data/test/test_helper.rb +15 -0
- metadata +605 -42
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 830867e74bccfaedb121caa8eb50834cdfe0ac3f
|
|
4
|
+
data.tar.gz: 6e72cba8c5a34636bf5c2749eb51511b968e0194
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b61dc71cfb12d9bada0ff92a6aed69f171d7f919a186e8c3b9c741045d492acfaafe60a56259d697a970b98909049e3fe1a8d09e3333e9d9f6175e64afd0ba6e
|
|
7
|
+
data.tar.gz: 01722e991c6198cde3568cc3f9e07507ca765be7f143d51e9e2f81c915880fb8605813382cbf24881f8cd5f1068b6cdf34a8d307f143abf97a65d3b81756635c
|
data/README.md
CHANGED
|
@@ -1,7 +1,178 @@
|
|
|
1
|
-
|
|
1
|
+
RevelryContent
|
|
2
|
+
===
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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=" " d="" horiz-adv-x="512" />
|
|
10
|
+
<glyph unicode="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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,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> ({ 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
|