spontaneous 0.2.0.alpha2 → 0.2.0.alpha3

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 (404) hide show
  1. data/Gemfile +3 -40
  2. data/Rakefile +29 -41
  3. data/Readme.markdown +21 -8
  4. data/application/css/add_alias_dialogue.css.scss +79 -0
  5. data/application/css/{v2.scss → core.css.scss} +537 -550
  6. data/application/css/{definitions.scss → definitions.css.scss} +121 -33
  7. data/application/css/dialogue.css.scss +409 -0
  8. data/application/css/{editing.scss → editing.css.scss} +25 -262
  9. data/application/css/font.css.scss +8 -0
  10. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  11. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  12. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_flat_10_000000_40x100.png +0 -0
  13. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  14. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  15. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  16. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  17. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  18. data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  19. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_222222_256x240.png +0 -0
  20. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_228ef1_256x240.png +0 -0
  21. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ef8c08_256x240.png +0 -0
  22. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ffd27a_256x240.png +0 -0
  23. data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ffffff_256x240.png +0 -0
  24. data/application/css/jquery-ui-1.8.21.custom/ui-lightness.css.scss +565 -0
  25. data/application/css/{login.scss → login.css.scss} +4 -4
  26. data/application/css/meta.css.scss +331 -0
  27. data/application/css/{popover.scss → popover.css.scss} +9 -8
  28. data/application/css/{schema_error.scss → schema_error.css.scss} +4 -4
  29. data/application/css/spontaneous.css +5 -0
  30. data/application/css/unsupported.css.scss +42 -0
  31. data/application/js/add_alias_dialogue.js +72 -10
  32. data/application/js/ajax.js +50 -16
  33. data/application/js/compatibility.js +19 -15
  34. data/application/js/content.js +39 -36
  35. data/application/js/content_area.js +53 -5
  36. data/application/js/dialogue.js +17 -0
  37. data/application/js/dom.js +1 -1
  38. data/application/js/edit_panel.js +23 -8
  39. data/application/js/extensions.js +7 -2
  40. data/application/js/field_preview.js +2 -1
  41. data/application/js/field_types/date_field.js +11 -8
  42. data/application/js/field_types/file_field.js +188 -9
  43. data/application/js/field_types/image_field.js +46 -29
  44. data/application/js/field_types/markdown_field.js +57 -14
  45. data/application/js/field_types/select_field.js +72 -0
  46. data/application/js/field_types/string_field.js +8 -0
  47. data/application/js/field_types/webvideo_field.js +8 -0
  48. data/application/js/init.js +1 -7
  49. data/application/js/location.js +41 -13
  50. data/application/js/login.js +3 -0
  51. data/application/js/meta_view/user_admin.js +543 -0
  52. data/application/js/meta_view.js +1 -0
  53. data/application/js/metadata.js +20 -0
  54. data/application/js/page.js +17 -3
  55. data/application/js/page_browser.js +40 -30
  56. data/application/js/page_entry.js +4 -0
  57. data/application/js/panel/root_menu.js +66 -0
  58. data/application/js/popover.js +2 -2
  59. data/application/js/preview.js +1 -1
  60. data/application/js/publish.js +138 -30
  61. data/application/js/services.js +43 -0
  62. data/application/js/sharded_upload.js +2 -2
  63. data/application/js/spontaneous.js +64 -5
  64. data/application/js/state.js +20 -9
  65. data/application/js/top_bar.js +273 -150
  66. data/application/js/types.js +20 -15
  67. data/application/js/upload.js +1 -2
  68. data/application/js/user.js +18 -4
  69. data/application/js/vendor/date.js +104 -0
  70. data/application/js/vendor/jquery-ui-1.8.18.custom.min.js +356 -0
  71. data/application/js/views/box_view.js +15 -8
  72. data/application/js/views/page_piece_view.js +11 -8
  73. data/application/js/views/page_view.js +21 -3
  74. data/application/js/views/piece_view.js +19 -10
  75. data/application/js/views.js +3 -0
  76. data/application/static/chromelogo-200x52-45c7cbc93be080bea342df5fcda2ef8b.png +0 -0
  77. data/application/static/dot-texture-9eea29e4ac7ad9a772285252078ec127.png +0 -0
  78. data/application/static/editing-textarea-resize-s-b5af62365eb7e19ea4beccf7242d508e.png +0 -0
  79. data/application/static/editing-texture-1-42b06a3439752490988f30f2a06d5e7c.png +0 -0
  80. data/application/static/font/fontawesome-webfont-5c5c21100a346972a82c34c5e96ffcfe.ttf +0 -0
  81. data/application/static/loop_alt1-white-7894b458528e92216196cae26b4c2c96.svg +12 -0
  82. data/application/static/spontaneous-states-e91ec89db525c62da0105b97cdd781ce.png +0 -0
  83. data/application/views/index.erb +2 -2
  84. data/application/views/login.erb +4 -8
  85. data/application/views/schema_modification_error.html.erb +1 -4
  86. data/application/views/unsupported.erb +9 -7
  87. data/bin/spot +1 -1
  88. data/db/migrations/20110209152710_users_and_groups.rb +10 -10
  89. data/db/migrations/20120305112647_site_modification_time.rb +11 -0
  90. data/db/migrations/20120418153903_add_ownership_of_content.rb +14 -0
  91. data/db/migrations/20120423175416_add_pending_modifications.rb +21 -0
  92. data/db/migrations/20120525164947_add_field_versions.rb +27 -0
  93. data/lib/sequel/plugins/scoped_table_name.rb +10 -1
  94. data/lib/spontaneous/asset/file.rb +25 -0
  95. data/lib/spontaneous/asset/source.rb +28 -0
  96. data/lib/spontaneous/asset.rb +75 -0
  97. data/lib/spontaneous/box.rb +6 -4
  98. data/lib/spontaneous/capistrano/deploy.rb +47 -0
  99. data/lib/spontaneous/capistrano/sync.rb +81 -0
  100. data/lib/spontaneous/capistrano.rb +13 -0
  101. data/lib/spontaneous/change.rb +60 -68
  102. data/lib/spontaneous/cli/assets.rb +29 -0
  103. data/lib/spontaneous/cli/base.rb +0 -48
  104. data/lib/spontaneous/cli/console.rb +1 -1
  105. data/lib/spontaneous/cli/server.rb +6 -4
  106. data/lib/spontaneous/cli/site.rb +28 -17
  107. data/lib/spontaneous/cli/user.rb +107 -0
  108. data/lib/spontaneous/cli.rb +100 -4
  109. data/lib/spontaneous/collections/entry_set.rb +2 -2
  110. data/lib/spontaneous/collections/field_set.rb +48 -22
  111. data/lib/spontaneous/collections/prototype_set.rb +20 -13
  112. data/lib/spontaneous/constants.rb +3 -0
  113. data/lib/spontaneous/content.rb +22 -5
  114. data/lib/spontaneous/errors.rb +3 -3
  115. data/lib/spontaneous/extensions/array.rb +12 -0
  116. data/lib/spontaneous/extensions/enumerable.rb +30 -0
  117. data/lib/spontaneous/extensions/nil.rb +3 -1
  118. data/lib/spontaneous/extensions/string.rb +16 -0
  119. data/lib/spontaneous/field_types/date_field.rb +45 -2
  120. data/lib/spontaneous/field_types/field.rb +42 -9
  121. data/lib/spontaneous/field_types/file_field.rb +68 -0
  122. data/lib/spontaneous/field_types/image_field.rb +63 -0
  123. data/lib/spontaneous/field_types/select_field.rb +109 -0
  124. data/lib/spontaneous/field_types/string_field.rb +6 -1
  125. data/lib/spontaneous/field_types/webvideo_field.rb +85 -27
  126. data/lib/spontaneous/field_types.rb +1 -1
  127. data/lib/spontaneous/field_version.rb +8 -0
  128. data/lib/spontaneous/generators/page.rb +1 -1
  129. data/lib/spontaneous/generators/site/Capfile.tt +1 -4
  130. data/lib/spontaneous/generators/site/Gemfile.tt +13 -6
  131. data/lib/spontaneous/generators/site/config/deploy.rb.tt +28 -0
  132. data/lib/spontaneous/generators/site/config/environments/production.rb.tt +7 -2
  133. data/lib/spontaneous/generators/site.rb +1 -0
  134. data/lib/spontaneous/json.rb +34 -11
  135. data/lib/spontaneous/layout.rb +22 -0
  136. data/lib/spontaneous/media/file.rb +4 -0
  137. data/lib/spontaneous/output/assets/compression.rb +58 -0
  138. data/lib/spontaneous/output/assets.rb +32 -0
  139. data/lib/spontaneous/output/context.rb +179 -0
  140. data/lib/spontaneous/output/format/html.rb +5 -0
  141. data/lib/spontaneous/output/format/plain.rb +5 -0
  142. data/lib/spontaneous/output/format.rb +180 -0
  143. data/lib/spontaneous/output/helpers/classes_helper.rb +18 -0
  144. data/lib/spontaneous/{render/helpers/html_helper.rb → output/helpers/conditional_comment_helper.rb} +3 -12
  145. data/lib/spontaneous/output/helpers/script_helper.rb +73 -0
  146. data/lib/spontaneous/output/helpers/stylesheet_helper.rb +61 -0
  147. data/lib/spontaneous/output/helpers.rb +28 -0
  148. data/lib/spontaneous/output/template/engine.rb +59 -0
  149. data/lib/spontaneous/output/template/renderer.rb +153 -0
  150. data/lib/spontaneous/output/template.rb +21 -0
  151. data/lib/spontaneous/output.rb +163 -0
  152. data/lib/spontaneous/page.rb +2 -1
  153. data/lib/spontaneous/paths.rb +6 -1
  154. data/lib/spontaneous/permissions/access_key.rb +5 -5
  155. data/lib/spontaneous/permissions/user.rb +81 -35
  156. data/lib/spontaneous/permissions/user_level.rb +26 -22
  157. data/lib/spontaneous/plugins/aliases.rb +76 -12
  158. data/lib/spontaneous/plugins/allowed_types.rb +60 -18
  159. data/lib/spontaneous/plugins/application/paths.rb +0 -28
  160. data/lib/spontaneous/plugins/application/system.rb +35 -0
  161. data/lib/spontaneous/plugins/boxes.rb +4 -0
  162. data/lib/spontaneous/plugins/content_groups.rb +16 -0
  163. data/lib/spontaneous/plugins/entries.rb +50 -30
  164. data/lib/spontaneous/plugins/fields.rb +15 -0
  165. data/lib/spontaneous/plugins/layouts.rb +8 -2
  166. data/lib/spontaneous/plugins/modifications.rb +228 -0
  167. data/lib/spontaneous/plugins/page/formats.rb +67 -42
  168. data/lib/spontaneous/plugins/page/request.rb +10 -0
  169. data/lib/spontaneous/plugins/page/site_timestamps.rb +28 -0
  170. data/lib/spontaneous/plugins/paths.rb +15 -3
  171. data/lib/spontaneous/plugins/publishing.rb +124 -45
  172. data/lib/spontaneous/plugins/render.rb +13 -8
  173. data/lib/spontaneous/plugins/schema_hierarchy.rb +18 -6
  174. data/lib/spontaneous/plugins/site/helpers.rb +53 -0
  175. data/lib/spontaneous/plugins/site/hooks.rb +50 -0
  176. data/lib/spontaneous/plugins/site/map.rb +1 -1
  177. data/lib/spontaneous/plugins/site/paths.rb +13 -0
  178. data/lib/spontaneous/plugins/site/publishing.rb +6 -2
  179. data/lib/spontaneous/plugins/site/{revisions.rb → state.rb} +5 -1
  180. data/lib/spontaneous/plugins/site/storage.rb +4 -0
  181. data/lib/spontaneous/plugins/site/url.rb +15 -0
  182. data/lib/spontaneous/plugins/site_map.rb +13 -3
  183. data/lib/spontaneous/plugins/styles.rb +5 -1
  184. data/lib/spontaneous/plugins/visibility.rb +39 -12
  185. data/lib/spontaneous/prototypes/box_prototype.rb +4 -0
  186. data/lib/spontaneous/prototypes/field_prototype.rb +15 -10
  187. data/lib/spontaneous/publishing/event_client.rb +46 -0
  188. data/lib/spontaneous/publishing/immediate.rb +81 -44
  189. data/lib/spontaneous/publishing/simultaneous.rb +23 -6
  190. data/lib/spontaneous/publishing.rb +4 -3
  191. data/lib/spontaneous/rack/around_back.rb +1 -5
  192. data/lib/spontaneous/rack/around_front.rb +4 -4
  193. data/lib/spontaneous/rack/around_preview.rb +4 -3
  194. data/lib/spontaneous/rack/assets.rb +81 -54
  195. data/lib/spontaneous/rack/authentication.rb +0 -1
  196. data/lib/spontaneous/rack/back.rb +160 -72
  197. data/lib/spontaneous/rack/cookie_authentication.rb +2 -2
  198. data/lib/spontaneous/rack/css.rb +18 -15
  199. data/lib/spontaneous/rack/event_source.rb +9 -21
  200. data/lib/spontaneous/rack/fiber_pool.rb +26 -0
  201. data/lib/spontaneous/rack/front.rb +12 -4
  202. data/lib/spontaneous/rack/helpers.rb +35 -13
  203. data/lib/spontaneous/rack/js.rb +41 -0
  204. data/lib/spontaneous/rack/public.rb +34 -44
  205. data/lib/spontaneous/rack/sse.rb +18 -0
  206. data/lib/spontaneous/rack/static.rb +3 -0
  207. data/lib/spontaneous/rack/user_admin.rb +100 -0
  208. data/lib/spontaneous/rack/user_helpers.rb +1 -1
  209. data/lib/spontaneous/rack.rb +6 -2
  210. data/lib/spontaneous/schema.rb +31 -4
  211. data/lib/spontaneous/search/index.rb +19 -3
  212. data/lib/spontaneous/search/results.rb +1 -1
  213. data/lib/spontaneous/sequel.rb +17 -0
  214. data/lib/spontaneous/site.rb +11 -4
  215. data/lib/spontaneous/state.rb +11 -0
  216. data/lib/spontaneous/storage/cloud.rb +4 -0
  217. data/lib/spontaneous/storage/local.rb +11 -0
  218. data/lib/spontaneous/style.rb +2 -2
  219. data/lib/spontaneous/tasks/database.rake +21 -22
  220. data/lib/spontaneous/utils/database/mysql_dumper.rb +4 -0
  221. data/lib/spontaneous/utils/database/postgres_dumper.rb +78 -0
  222. data/lib/spontaneous/utils/database.rb +6 -3
  223. data/lib/spontaneous/utils/smart_quotes.rb +499 -0
  224. data/lib/spontaneous/utils/smush_it.rb +66 -0
  225. data/lib/spontaneous/utils.rb +3 -1
  226. data/lib/spontaneous/version.rb +2 -2
  227. data/lib/spontaneous.rb +25 -29
  228. data/spontaneous.gemspec +186 -106
  229. data/test/experimental/test_features.rb +1 -1
  230. data/test/fixtures/asset_pipeline/application/css/basic.css.scss +4 -0
  231. data/test/fixtures/asset_pipeline/application/css/complex.css.scss.erb +6 -0
  232. data/test/fixtures/asset_pipeline/application/css/simple.css +3 -0
  233. data/test/fixtures/asset_pipeline/application/css/spontaneous.css +7 -0
  234. data/test/fixtures/asset_pipeline/application/css/subdir/complex.css.scss.erb +6 -0
  235. data/test/fixtures/asset_pipeline/application/css/subdir/library.css.scss +1 -0
  236. data/test/fixtures/asset_pipeline/application/css/subdir/simple.css +3 -0
  237. data/test/fixtures/asset_pipeline/application/js/basic.js.coffee +1 -0
  238. data/test/fixtures/asset_pipeline/application/js/complex.js.coffee.erb +1 -0
  239. data/test/fixtures/asset_pipeline/application/js/login.js +1 -0
  240. data/test/fixtures/asset_pipeline/application/js/require.js +1 -0
  241. data/test/fixtures/asset_pipeline/application/js/simple.js +1 -0
  242. data/test/fixtures/asset_pipeline/application/js/spontaneous.js +5 -0
  243. data/test/fixtures/asset_pipeline/application/js/subdir/complex.js.coffee.erb +1 -0
  244. data/test/fixtures/asset_pipeline/application/js/subdir/library.js.coffee +1 -0
  245. data/test/fixtures/asset_pipeline/application/js/subdir/simple.js +1 -0
  246. data/test/fixtures/asset_pipeline/application/js/vendor/jquery.js +1 -0
  247. data/test/fixtures/asset_pipeline/application/static/dot-texture.png +0 -0
  248. data/test/fixtures/asset_pipeline/application/static/subdir/px.gif +0 -0
  249. data/test/fixtures/assets/public1/css/a.scss +1 -0
  250. data/test/fixtures/assets/public1/js/a.js +1 -0
  251. data/test/fixtures/assets/public1/js/m.coffee +1 -0
  252. data/test/fixtures/assets/public2/css/b.scss +1 -0
  253. data/test/fixtures/assets/public2/css/c.css +1 -0
  254. data/test/fixtures/assets/public2/js/b.js +1 -0
  255. data/test/fixtures/assets/public2/js/c.js +1 -0
  256. data/test/fixtures/assets/public2/js/n.coffee +1 -0
  257. data/test/fixtures/back/config/user_levels.yml +3 -0
  258. data/test/fixtures/back/public/js/coffeescript.coffee +1 -0
  259. data/test/fixtures/back/templates/layouts/standard.css.cut +1 -0
  260. data/test/fixtures/back/templates/layouts/standard.js.cut +1 -0
  261. data/test/fixtures/example_application/config/database.yml +4 -4
  262. data/test/fixtures/helpers/templates/layouts/standard.html.cut +1 -0
  263. data/test/fixtures/helpers/templates/layouts/standard.mobile.cut +1 -0
  264. data/test/fixtures/images/vimlogo.pdf +0 -0
  265. data/test/fixtures/outputs/templates/layouts/standard.atom.cut +1 -0
  266. data/test/fixtures/permissions/config/user_levels.yml +6 -3
  267. data/test/fixtures/serialisation/class_hash.yaml.erb +1 -0
  268. data/test/fixtures/serialisation/root_hash.yaml.erb +2 -2
  269. data/test/fixtures/templates/extended/grandparent.html.cut +7 -7
  270. data/test/fixtures/templates/extended/main.html.cut +5 -5
  271. data/test/fixtures/templates/extended/parent.html.cut +8 -8
  272. data/test/fixtures/templates/extended/partial_with_locals.html.cut +1 -1
  273. data/test/fixtures/templates/extended/with_includes.html.cut +6 -6
  274. data/test/fixtures/templates/extended/with_includes_and_locals.html.cut +6 -7
  275. data/test/fixtures/templates/layouts/entries.html.cut +4 -4
  276. data/test/fixtures/templates/layouts/standard.html.cut +1 -0
  277. data/test/fixtures/templates/layouts/variables.html.cut +1 -1
  278. data/test/fixtures/templates/publishing/templates/layouts/static.html.cut +1 -1
  279. data/test/fixtures/templates/publishing/templates/layouts/static.rtf.cut +1 -0
  280. data/test/fixtures/templates/template_class/complex_template.html.cut +2 -2
  281. data/test/fixtures/templates/template_class/complex_template.pdf.cut +2 -2
  282. data/test/fixtures/templates/template_class/default_template_style.html.cut +1 -1
  283. data/test/fixtures/templates/template_class/images_with_template.html.cut +2 -2
  284. data/test/fixtures/templates/template_class/slots_template.html.cut +2 -2
  285. data/test/fixtures/templates/template_class/slots_template.pdf.cut +2 -2
  286. data/test/fixtures/user_manager/config/user_levels.yml +9 -0
  287. data/test/functional/test_application.rb +7 -7
  288. data/test/functional/test_back.rb +352 -97
  289. data/test/functional/test_front.rb +71 -20
  290. data/test/functional/test_user_manager.rb +284 -0
  291. data/test/javascript/env.js +13505 -0
  292. data/test/javascript/test_markdown.rb +43 -3
  293. data/test/support/custom_matchers.rb +3 -2
  294. data/test/test_helper.rb +50 -9
  295. data/test/test_javascript.rb +13 -13
  296. data/test/ui_helper.rb +1 -1
  297. data/test/unit/test_alias.rb +79 -8
  298. data/test/unit/test_asset_bundler.rb +220 -0
  299. data/test/unit/test_assets.rb +213 -0
  300. data/test/unit/test_async.rb +55 -0
  301. data/test/unit/test_authentication.rb +52 -39
  302. data/test/unit/test_boxes.rb +20 -15
  303. data/test/unit/test_changesets.rb +261 -0
  304. data/test/unit/test_content.rb +73 -33
  305. data/test/unit/test_content_inheritance.rb +18 -18
  306. data/test/unit/test_extensions.rb +26 -0
  307. data/test/unit/test_fields.rb +303 -16
  308. data/test/unit/test_formats.rb +267 -34
  309. data/test/unit/test_helpers.rb +79 -2
  310. data/test/unit/test_images.rb +10 -0
  311. data/test/unit/test_layouts.rb +21 -13
  312. data/test/unit/test_modifications.rb +648 -0
  313. data/test/unit/test_page.rb +6 -2
  314. data/test/unit/test_permissions.rb +101 -27
  315. data/test/unit/test_piece.rb +4 -4
  316. data/test/unit/test_plugins.rb +3 -2
  317. data/test/unit/test_publishing.rb +332 -0
  318. data/test/unit/test_render.rb +118 -67
  319. data/test/unit/test_revisions.rb +546 -0
  320. data/test/unit/test_schema.rb +83 -1
  321. data/test/unit/test_search.rb +59 -0
  322. data/test/unit/test_serialisation.rb +2 -47
  323. data/test/unit/test_site.rb +217 -108
  324. data/test/unit/test_storage.rb +26 -0
  325. data/test/unit/test_structure.rb +2 -2
  326. data/test/unit/test_styles.rb +90 -75
  327. data/test/unit/test_table_scoping.rb +21 -17
  328. data/test/unit/test_templates.rb +75 -69
  329. data/test/{slow → unit}/test_visibility.rb +78 -22
  330. metadata +528 -221
  331. data/application/css/add_alias_dialogue.scss +0 -27
  332. data/application/css/min/14c2a35812c443001b15d8b12a4780f88c678035.css +0 -1
  333. data/application/css/min/565d4c25e82148acb01c45c8d675b37a08676d77.css +0 -1
  334. data/application/css/min/84dbe894ea96eafd321c30823d630817bfc4b03b.css +0 -1
  335. data/application/css/spontaneous.scss +0 -111
  336. data/application/css/unsupported.scss +0 -16
  337. data/application/css/variables.scss +0 -80
  338. data/application/js/min/2a0c2962537a3181fedfff5c92596ba6d3122dc9.js +0 -3
  339. data/application/js/min/4cf1c493d3379ecba5287758c61238034c0893f9.js +0 -2
  340. data/application/js/min/78ac6b99d96750bb6b9f9aad4cb9cd91cd03f391.js +0 -3
  341. data/application/js/min/b8abf302a824c35385ff517b34111e1710ff3b37.js +0 -2
  342. data/application/js/min/c8efb9b9f7c3f6613fcebc6be60f605b6570a382.js +0 -90
  343. data/application/static/diagonal-texture.png +0 -0
  344. data/application/static/editing-0-noise.png +0 -0
  345. data/application/static/editing-1-noise.png +0 -0
  346. data/application/static/editing-texture-1.png +0 -0
  347. data/application/static/editing-texture.png +0 -0
  348. data/application/static/editing-toolbar-shadow-bottom.png +0 -0
  349. data/application/static/editing-toolbar-shadow-top.png +0 -0
  350. data/application/static/inner-glow.png +0 -0
  351. data/application/static/item-buttons-highlight.png +0 -0
  352. data/application/static/item-buttons.png +0 -0
  353. data/application/static/paper-texture-dark.png +0 -0
  354. data/application/static/plus_alt.svg +0 -8
  355. data/application/static/select-arrow-root.png +0 -0
  356. data/application/static/slot-up-arrow.png +0 -0
  357. data/application/static/spontaneous.png +0 -0
  358. data/lib/cutaneous/context_helper.rb +0 -187
  359. data/lib/cutaneous/preview_context.rb +0 -32
  360. data/lib/cutaneous/preview_renderer.rb +0 -10
  361. data/lib/cutaneous/publish_context.rb +0 -10
  362. data/lib/cutaneous/publish_renderer.rb +0 -14
  363. data/lib/cutaneous/publish_template.rb +0 -62
  364. data/lib/cutaneous/publish_token_parser.rb +0 -8
  365. data/lib/cutaneous/renderer.rb +0 -124
  366. data/lib/cutaneous/request_context.rb +0 -9
  367. data/lib/cutaneous/request_renderer.rb +0 -15
  368. data/lib/cutaneous/request_template.rb +0 -11
  369. data/lib/cutaneous/request_token_parser.rb +0 -9
  370. data/lib/cutaneous/token_parser.rb +0 -125
  371. data/lib/cutaneous.rb +0 -48
  372. data/lib/spontaneous/render/context_base.rb +0 -143
  373. data/lib/spontaneous/render/development_renderer.rb +0 -14
  374. data/lib/spontaneous/render/engine.rb +0 -19
  375. data/lib/spontaneous/render/format/html.rb +0 -5
  376. data/lib/spontaneous/render/format.rb +0 -75
  377. data/lib/spontaneous/render/helpers/script_helper.rb +0 -17
  378. data/lib/spontaneous/render/helpers/stylesheet_helper.rb +0 -16
  379. data/lib/spontaneous/render/helpers.rb +0 -14
  380. data/lib/spontaneous/render/preview_context.rb +0 -8
  381. data/lib/spontaneous/render/preview_renderer.rb +0 -24
  382. data/lib/spontaneous/render/publish_context.rb +0 -22
  383. data/lib/spontaneous/render/published_renderer.rb +0 -53
  384. data/lib/spontaneous/render/publishing_renderer.rb +0 -16
  385. data/lib/spontaneous/render/render_cache.rb +0 -26
  386. data/lib/spontaneous/render/renderer.rb +0 -50
  387. data/lib/spontaneous/render/request_context.rb +0 -8
  388. data/lib/spontaneous/render.rb +0 -214
  389. data/test/experimental/test_cutaneous.rb +0 -309
  390. data/test/fixtures/application/css/test.less +0 -5
  391. data/test/slow/test_publishing.rb +0 -1006
  392. /data/application/css/{developer.scss → developer.css.scss} +0 -0
  393. /data/application/js/vendor/{jquery-1.7.1.min.js → jquery.js} +0 -0
  394. /data/application/static/{location-arrow.png → location-arrow-c1c1d3ca472481c61a0a5f8cb289d743.png} +0 -0
  395. /data/application/static/{missing.png → missing-911ce6dbd9f4602e0f3fbcd7e78846a2.png} +0 -0
  396. /data/application/static/{orange-down-arrow.png → orange-down-arrow-395ae1929e8662b2ff0977daf12c35bb.png} +0 -0
  397. /data/application/static/{page-browser-next.png → page-browser-next-ce781a242c23b980b99b9db7abc20b05.png} +0 -0
  398. /data/application/static/{plus-box.png → plus-box-dcde74a1e496f68298c9b443caa1c5d5.png} +0 -0
  399. /data/application/static/{select-arrow.png → select-arrow-6e7dd3745b00e934b0d7a3250c46558b.png} +0 -0
  400. /data/application/static/{slot-down-arrow.png → slot-down-arrow-59ad5f5ee5b52a7ebd00bca4b3104194.png} +0 -0
  401. /data/application/static/{splash.png → splash-65b493a714df9b8b3ab170103401b53d.png} +0 -0
  402. /data/application/static/{spot.png → spot-71fab1d2f065034f5fc15e7bea2ad36c.png} +0 -0
  403. /data/application/static/{spot.svg → spot-8505041082d8d3bbe8d34c29dddb3b7d.svg} +0 -0
  404. /data/application/static/{texture.png → texture-03f7627e8264b1d607113ab32c593a58.png} +0 -0
@@ -1,7 +1,8 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  require 'sass'
4
- require 'less'
4
+ require 'sinatra/streaming'
5
+ require 'sprockets'
5
6
 
6
7
  module Spontaneous
7
8
  module Rack
@@ -19,6 +20,54 @@ module Spontaneous
19
20
  @messenger
20
21
  end
21
22
 
23
+ class EventSource < ServerBase
24
+ helpers Sinatra::Streaming
25
+
26
+ get "/", :provides => "text/event-stream" do
27
+ headers "X-Accel-Buffering" => "no"
28
+ stream(:keep_open) do |out|
29
+ messenger = Spontaneous::Rack::Back.messenger
30
+ out.errback { messenger.delete(out) }
31
+ out.callback { messenger.delete(out) }
32
+ messenger << out
33
+ end
34
+ end
35
+ end
36
+
37
+ def self.editing_app
38
+ ::Rack::Builder.app do
39
+ use Spontaneous::Rack::FiberPool, :size => 15
40
+ use ::Rack::Lint
41
+ use Spontaneous::Rack::Static, :root => Spontaneous.application_dir, :urls => %W(/static)
42
+ use Spontaneous::Rack::Static, :root => Spontaneous.root / "public/@spontaneous", :urls => %W(/assets)
43
+ use AssetsHandler
44
+ use UnsupportedBrowserHandler
45
+ use SchemaModification
46
+ map "/users" do
47
+ run UserAdmin
48
+ end
49
+ run EditingInterface
50
+ end
51
+ end
52
+
53
+ def self.preview_app
54
+ ::Rack::Builder.app do
55
+ use ::Rack::Lint
56
+ use Spontaneous::Rack::Static, :root => Spontaneous.root / "public",
57
+ :urls => %w[/],
58
+ :try => ['.html', 'index.html', '/index.html']
59
+ use Spontaneous::Rack::CSS, :root => Spontaneous.instance.paths.expanded(:public)
60
+ use Spontaneous::Rack::JS, :root => Spontaneous.instance.paths.expanded(:public)
61
+ run Preview
62
+ end
63
+ end
64
+
65
+ def self.assets_app(dir)
66
+ ::Sprockets::Environment.new(Spontaneous.application_dir) do |environment|
67
+ environment.append_path("#{dir}")
68
+ end
69
+ end
70
+
22
71
  def self.application
23
72
  messenger = self.messenger
24
73
  app = ::Rack::Builder.new do
@@ -45,9 +94,6 @@ module Spontaneous
45
94
  # Needs testing...
46
95
  # ###################
47
96
 
48
- use Spontaneous::Rack::Static, :root => Spontaneous.root / "public",
49
- :urls => %w[/],
50
- :try => ['.html', 'index.html', '/index.html']
51
97
 
52
98
  ################### REMOVE THIS
53
99
  # map "#{NAMESPACE}/lock" do
@@ -84,16 +130,23 @@ module Spontaneous
84
130
  map "#{NAMESPACE}/events" do
85
131
  use CookieAuthentication
86
132
  use QueryAuthentication
87
- run messenger.app
133
+ run EventSource
134
+ end
135
+
136
+ map "#{NAMESPACE}/event" do
137
+ run EventListener
138
+ end
139
+
140
+ map "#{NAMESPACE}/css" do
141
+ run Spontaneous::Rack::Back.assets_app("css")
142
+ end
143
+
144
+ map "#{NAMESPACE}/js" do
145
+ run Spontaneous::Rack::Back.assets_app("js")
88
146
  end
89
147
 
90
148
  map NAMESPACE do
91
- use ::Rack::Lint
92
- use Spontaneous::Rack::Static, :root => Spontaneous.application_dir, :urls => %W(/static /js)
93
- use AssetsHandler
94
- use UnsupportedBrowserHandler
95
- use SchemaModification
96
- run EditingInterface
149
+ run Spontaneous::Rack::Back.editing_app
97
150
  end
98
151
 
99
152
  map "/media" do
@@ -102,13 +155,19 @@ module Spontaneous
102
155
  end
103
156
 
104
157
  map "/" do
105
- use ::Rack::Lint
106
- use Spontaneous::Rack::CSS, :root => Spontaneous.instance.paths.expanded(:public)
107
- run Preview
158
+ run Spontaneous::Rack::Back.preview_app
108
159
  end
109
160
  end
110
161
  end
111
162
 
163
+ class EventListener < ServerBase
164
+ put "/" do
165
+ Back.messenger.deliver_event(SSE.new(params))
166
+ 200
167
+ end
168
+ end
169
+
170
+
112
171
  class EditingBase < ServerBase
113
172
  set :views, Proc.new { Spontaneous.application_dir + '/views' }
114
173
  set :environment, Proc.new { Spontaneous.env }
@@ -117,10 +176,6 @@ module Spontaneous
117
176
  helpers Spontaneous::Rack::UserHelpers
118
177
  helpers Spontaneous::Rack::Helpers
119
178
 
120
- def json(response)
121
- content_type 'application/json', :charset => 'utf-8'
122
- response.serialise_http(user)
123
- end
124
179
  end
125
180
 
126
181
  class UnsupportedBrowserHandler < EditingBase
@@ -199,6 +254,7 @@ module Spontaneous
199
254
  Content.db.transaction {
200
255
  dataset = lock ? Content.for_update : Content
201
256
  content = dataset.first(:id => params[:id])
257
+ content.current_editor = user
202
258
  halt 404 if content.nil?
203
259
  if box_id = Spontaneous.schema.uids[params[:box_id]]
204
260
  box = content.boxes.detect { |b| b.schema_id == box_id }
@@ -209,16 +265,30 @@ module Spontaneous
209
265
  }
210
266
  end
211
267
 
268
+ def set_authentication_cookie(key)
269
+ response.set_cookie(AUTH_COOKIE, {
270
+ :value => key.key_id,
271
+ :path => '/',
272
+ :secure => request.ssl?,
273
+ :httponly => true
274
+ })
275
+ end
276
+
277
+ def unset_authentication_cookie
278
+ response.delete_cookie(AUTH_COOKIE, {
279
+ :path => '/',
280
+ :secure => request.ssl?,
281
+ :httponly => true
282
+ })
283
+ end
284
+
212
285
  post "/reauthenticate" do
286
+ origin = "#{NAMESPACE}#{(params[:origin] || "").gsub(%r[^#{NAMESPACE}], "")}"
213
287
  if key = Spot::Permissions::AccessKey.authenticate(params[:api_key])
214
- response.set_cookie(AUTH_COOKIE, {
215
- :value => key.key_id,
216
- :path => '/'
217
- })
218
- origin = "#{NAMESPACE}#{params[:origin]}"
288
+ set_authentication_cookie(key)
219
289
  redirect origin, 302
220
290
  else
221
- show_login_page( :invalid_key => true )
291
+ show_login_page( :invalid_key => true, :origin => origin )
222
292
  end
223
293
  end
224
294
 
@@ -226,11 +296,8 @@ module Spontaneous
226
296
  login = params[:user][:login]
227
297
  password = params[:user][:password]
228
298
  origin = "#{NAMESPACE}#{params[:origin]}"
229
- if key = Spontaneous::Permissions::User.authenticate(login, password)
230
- response.set_cookie(AUTH_COOKIE, {
231
- :value => key.key_id,
232
- :path => '/'
233
- })
299
+ if key = Spontaneous::Permissions::User.authenticate(login, password, env["REMOTE_ADDR"])
300
+ set_authentication_cookie(key)
234
301
  if request.xhr?
235
302
  json({
236
303
  :key => key.key_id,
@@ -244,6 +311,11 @@ module Spontaneous
244
311
  end
245
312
  end
246
313
 
314
+ post "/logout" do
315
+ unset_authentication_cookie
316
+ 401
317
+ end
318
+
247
319
  get '/?' do
248
320
  erb :index
249
321
  end
@@ -256,29 +328,20 @@ module Spontaneous
256
328
  json Site.root
257
329
  end
258
330
 
259
- get '/user' do
260
- json(user)
261
- end
262
- # TODO: check for perms on the particular bit of content
263
- # and pass user level into returned JSON
264
331
  get '/page/:id' do
265
332
  content_for_request { |content| json(content)}
266
333
  end
267
334
 
268
- get '/types' do
269
- json Site.schema
335
+ get '/metadata' do
336
+ json({
337
+ :types => Site.schema.export(user),
338
+ :user => user.export,
339
+ :services => (Site.config.services || [])
340
+ })
270
341
  end
271
342
 
272
- # get '/type/:type' do
273
- # klass = params[:type].gsub(/\\./, "::").constantize
274
- # json klass
275
- # end
276
-
277
- get '/map' do
278
- json Site.map
279
- end
280
-
281
- get '/map/:id' do
343
+ get '/map/?:id?' do
344
+ last_modified(Site.modified_at)
282
345
  map = Site.map(params[:id])
283
346
  if map
284
347
  json(map)
@@ -288,6 +351,7 @@ module Spontaneous
288
351
  end
289
352
 
290
353
  get '/location*' do
354
+ last_modified(Site.modified_at)
291
355
  if Page.count == 0
292
356
  406
293
357
  else
@@ -301,7 +365,6 @@ module Spontaneous
301
365
  if Site.root.nil?
302
366
  type = Spontaneous.schema[params[:type]]
303
367
  root = type.create(:title => "Home")
304
- Spontaneous::Change.push(root)
305
368
  json({:id => root.id})
306
369
  else
307
370
  403
@@ -314,6 +377,13 @@ module Spontaneous
314
377
  end
315
378
  end
316
379
 
380
+ get '/options/:field_sid/:id/?:box_id?' do
381
+ content_for_request do |content, box|
382
+ field = (box || content).fields.sid(params[:field_sid])
383
+ json(field.option_list)
384
+ end
385
+ end
386
+
317
387
  def generate_conflict_list(content)
318
388
  field_versions = params[:fields]
319
389
  conflicts = []
@@ -380,7 +450,7 @@ module Spontaneous
380
450
  if target.field_writable?(user, field.name)
381
451
  # version = params[:version].to_i
382
452
  # if version == field.version
383
- field.unprocessed_value = file
453
+ field.value = file
384
454
  content.save
385
455
  json(field.export(user))
386
456
  # else
@@ -404,7 +474,7 @@ module Spontaneous
404
474
  instance = type.new
405
475
  box.insert(position, instance)
406
476
  field = instance.field_for_mime_type(file[:type])
407
- field.unprocessed_value = file
477
+ field.value = file
408
478
  instance.save
409
479
  content.save
410
480
  json({
@@ -422,8 +492,9 @@ module Spontaneous
422
492
  content_for_request(true) do |content, box|
423
493
  position = (params[:position] || 0).to_i
424
494
  type = Spontaneous.schema[params[:type_name]]#.constantize
495
+
425
496
  if box.writable?(user, type)
426
- instance = type.new
497
+ instance = type.new(:created_by => user)
427
498
  box.insert(position, instance)
428
499
  content.save
429
500
  json({
@@ -469,6 +540,14 @@ module Spontaneous
469
540
  end
470
541
  end
471
542
 
543
+ post '/slug/:id/titlesync' do
544
+ content_for_request do |page|
545
+ page.slug = page.title.unprocessed_value
546
+ page.save
547
+ json({:path => page.path, :slug => page.slug })
548
+ end
549
+ end
550
+
472
551
  post '/uid/:id' do
473
552
  if user.developer?
474
553
  content_for_request(true) do |content|
@@ -485,14 +564,21 @@ module Spontaneous
485
564
  klass = Spontaneous.schema[params[:schema_id]]
486
565
  if klass.alias?
487
566
  content_for_request do |content, box|
488
- targets = klass.targets(content, box).map do |t|
489
- {
490
- :id => t.id,
567
+ options = {}
568
+ if (query = params[:query])
569
+ options[:search] = Regexp.new(query, Regexp::IGNORECASE)
570
+ end
571
+ targets = klass.targets(content, box, options).map do |t|
572
+ { :id => t.id,
491
573
  :title => t.alias_title,
492
- :icon => t.exported_alias_icon
493
- }
574
+ :icon => t.exported_alias_icon }
494
575
  end
495
- json(targets)
576
+ json({
577
+ :pages => 1,
578
+ :total => targets.length,
579
+ :page => 1,
580
+ :targets => targets
581
+ })
496
582
  end
497
583
  end
498
584
  end
@@ -502,9 +588,8 @@ module Spontaneous
502
588
  type = Spontaneous.schema[params[:alias_id]]
503
589
  position = (params[:position] || 0).to_i
504
590
  if box.writable?(user, type)
505
- target = Spontaneous::Content[params[:target_id]]
506
- if target
507
- instance = type.create(:target => target)
591
+ instance = type.for_target(params[:target_id])
592
+ if instance
508
593
  box.insert(position, instance)
509
594
  content.save
510
595
  json({
@@ -527,14 +612,14 @@ module Spontaneous
527
612
  end
528
613
 
529
614
  post '/publish/publish' do
530
- ids = params[:change_set_ids]
615
+ ids = params[:page_ids]
531
616
  ids = ids.blank? ? [] : ids
532
- change_sets = ids.map(&:to_i)
533
- if change_sets.empty?
617
+ pages = ids.map(&:to_i)
618
+ if pages.empty?
534
619
  400
535
620
  else
536
621
  if user.level.can_publish?
537
- Site.publish_changes(change_sets)
622
+ Site.publish_pages(pages)
538
623
  json({})
539
624
  else
540
625
  unauthorised!
@@ -579,7 +664,7 @@ module Spontaneous
579
664
  # version = params[:version].to_i
580
665
  # if version == field.version
581
666
  Spontaneous::Media.combine_shards(params[:shards]) do |combined|
582
- field.unprocessed_value = {
667
+ field.value = {
583
668
  :filename => params[:filename],
584
669
  :tempfile => combined
585
670
  }
@@ -606,7 +691,7 @@ module Spontaneous
606
691
  box.insert(position, instance)
607
692
  field = instance.field_for_mime_type(params[:mime_type])
608
693
  Spontaneous::Media.combine_shards(params[:shards]) do |combined|
609
- field.unprocessed_value = {
694
+ field.value = {
610
695
  :filename => params[:filename],
611
696
  :tempfile => combined
612
697
  }
@@ -657,11 +742,8 @@ module Spontaneous
657
742
  else
658
743
  content_type :css
659
744
  sass_template = Spontaneous.css_dir / File.basename(file, ".css") + ".scss"
660
- less_template = Spontaneous.css_dir / File.basename(file, ".css") + ".less"
661
745
  if File.exists?(sass_template)
662
746
  Sass::Engine.for_file(sass_template, :load_paths => [Spontaneous.css_dir], :filename => sass_template, :cache => false).render
663
- elsif File.exists?(less_template)
664
- Less::Engine.new(File.new(less_template)).to_css
665
747
  else
666
748
  raise Sinatra::NotFound
667
749
  end
@@ -673,12 +755,12 @@ module Spontaneous
673
755
  end
674
756
 
675
757
  class Preview < Sinatra::Base
758
+ use CookieAuthentication
759
+ use AroundPreview
676
760
  use Reloader if Site.config.reload_classes
677
761
  include Spontaneous::Rack::Public
678
762
  helpers Spontaneous::Rack::UserHelpers
679
763
 
680
- use CookieAuthentication
681
- use AroundPreview
682
764
 
683
765
  set :views, Proc.new { Spontaneous.application_dir + '/views' }
684
766
 
@@ -688,12 +770,17 @@ module Spontaneous
688
770
  }
689
771
 
690
772
 
773
+ # Forward all GETs to the page resolution method
691
774
  get '*' do
692
- path = params[:splat][0]
775
+ render_path(params[:splat][0])
776
+ end
693
777
 
694
- render_path(path)
778
+ # Forward all POSTs to the page resolution method
779
+ post '*' do
780
+ render_path(params[:splat][0])
695
781
  end
696
782
 
783
+ # Override the S::Rack::Public method to add in some cache-busting headers
697
784
  def render_page(page, format = :html, local_params = {})
698
785
  now = Time.now.to_formatted_s(:rfc822)
699
786
  response.headers[HTTP_EXPIRES] = now
@@ -706,3 +793,4 @@ module Spontaneous
706
793
  end
707
794
  end
708
795
  end
796
+
@@ -11,14 +11,14 @@ module Spontaneous
11
11
  if login = Site.config.auto_login
12
12
  user = Spontaneous::Permissions::User[:login => login]
13
13
  if user.access_keys.empty?
14
- user.generate_access_key
14
+ user.generate_access_key(env["REMOTE_ADDR"])
15
15
  else
16
16
  user.access_keys.first
17
17
  end
18
18
  else
19
19
  request = ::Rack::Request.new(env)
20
20
  api_key = request.cookies[Spontaneous::Rack::AUTH_COOKIE]
21
- if api_key && key = Spontaneous::Permissions::AccessKey.authenticate(api_key)
21
+ if api_key && key = Spontaneous::Permissions::AccessKey.authenticate(api_key, env["REMOTE_ADDR"])
22
22
  key
23
23
  else
24
24
  nil
@@ -4,24 +4,28 @@ require 'sass'
4
4
 
5
5
  module Spontaneous::Rack
6
6
  class CSS
7
+ CSS_EXTENSION = /\.css$/o
8
+
7
9
  def initialize(app, options = {})
8
- @options = options
9
- @root = options.delete(:root)
10
+ @roots = options[:root]
10
11
  @app = app
11
12
  end
12
13
 
13
14
  def call(env)
14
- path = env[S::PATH_INFO]
15
- if path =~ /\.css$/ and !File.exists?(File.join(@root, path))
16
- template = template_root_path(path) + ".scss"
17
- if File.exists?(template)
18
- render_sass_template(template)
19
- else
20
- raise Sinatra::NotFound
21
- end
22
- else
23
- @app.call(env)
15
+ try_sass(env[S::PATH_INFO]) or @app.call(env)
16
+ end
17
+
18
+ def try_sass(request_path)
19
+ return nil unless request_path =~ CSS_EXTENSION
20
+ try_paths = @roots.map { |root| File.join(root, request_path) }
21
+ # if the css file itself exists then we want to use that
22
+ return nil if try_paths.detect { |file| ::File.exists?(file) }
23
+
24
+ try_paths.each do |path|
25
+ template = template_path(path)
26
+ return render_sass_template(template) if File.exists?(template)
24
27
  end
28
+ nil
25
29
  end
26
30
 
27
31
  def render_sass_template(template)
@@ -35,9 +39,8 @@ module Spontaneous::Rack
35
39
  [200, {'Content-type' => 'text/css'}, [engine.render]]
36
40
  end
37
41
 
38
- def template_root_path(path)
39
- basename = File.basename(path, '.css')
40
- File.join(@root, File.dirname(path), basename)
42
+ def template_path(path)
43
+ path.gsub(CSS_EXTENSION, ".scss")
41
44
  end
42
45
  end
43
46
  end
@@ -1,31 +1,19 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require 'simultaneous'
4
+
3
5
  module Spontaneous
4
6
  module Rack
5
7
  class EventSource < ::Simultaneous::Rack::EventSource
6
- # def initialize
7
- # @messenger = ::Simultaneous::Rack::EventSource.new
8
- # @app = @messenger.app
9
- # end
8
+ def push(client)
9
+ @lock.synchronize { @clients << client }
10
+ end
10
11
 
11
- # def call(env)
12
- # user = env[S::Rack::ACTIVE_USER]
13
- # if user.nil?
14
- # unauthorized!
15
- # else
16
- # request = ::Rack::Request.new(env)
17
- # key = request[S::Rack::KEY_PARAM]
18
- # if ::S::Permissions::AccessKey.valid?(key, user)
19
- # @app.call(env)
20
- # else
21
- # unauthorized!
22
- # end
23
- # end
24
- # end
12
+ alias_method :<<, :push
25
13
 
26
- # def unauthorized!
27
- # [401, {}, "Unauthorized"]
28
- # end
14
+ def delete(client)
15
+ @lock.synchronize { removed = @clients.delete(client) }
16
+ end
29
17
  end
30
18
  end
31
19
  end
@@ -0,0 +1,26 @@
1
+ require 'rack/fiber_pool'
2
+
3
+ module Spontaneous::Rack
4
+ class FiberPool
5
+ def initialize(app, options = {})
6
+ @target_app = app
7
+ @options = options
8
+ end
9
+
10
+ def call(env)
11
+ app.call(env)
12
+ end
13
+
14
+ def app
15
+ @app ||= wrap_target_app
16
+ end
17
+
18
+ def wrap_target_app
19
+ if Spontaneous.async?
20
+ ::Rack::FiberPool.new(@target_app, @options)
21
+ else
22
+ @target_app
23
+ end
24
+ end
25
+ end
26
+ end
@@ -5,6 +5,13 @@ require 'sinatra/base'
5
5
  module Spontaneous
6
6
  module Rack
7
7
  module Front
8
+ def self.front_app
9
+ ::Rack::Builder.app do
10
+ use AroundFront
11
+ use Reloader if Site.config.reload_classes
12
+ run Server.new
13
+ end
14
+ end
8
15
  def self.application
9
16
  app = ::Rack::Builder.new do
10
17
  # use ::Rack::CommonLogger, STDERR #unless server.name =~ /CGI/
@@ -42,19 +49,20 @@ module Spontaneous
42
49
  end
43
50
 
44
51
  map "/" do
45
- use AroundFront
46
- use Reloader if Site.config.reload_classes
47
- run Server.new
52
+ run Spontaneous::Rack::Front.front_app
48
53
  end
49
54
  end
50
55
  end
56
+
51
57
  class Server < Sinatra::Base
52
58
  include Spontaneous::Rack::Public
53
59
 
54
60
  def call!(env)
55
61
  @env = env
56
62
  @response = ::Sinatra::Response.new
57
- @request = ::Sinatra::Request.new(env)
63
+ @request = ::Sinatra::Request.new(env)
64
+ @params = indifferent_params(@request.params)
65
+
58
66
  render_path(@request.path_info)
59
67
  end
60
68
  end
@@ -1,31 +1,53 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require 'sprockets'
4
+
3
5
  module Spontaneous
4
6
  module Rack
5
7
  module Helpers
8
+ def json(response)
9
+ content_type 'application/json', :charset => 'utf-8'
10
+ response.serialise_http(user)
11
+ end
12
+
13
+ def application_assets
14
+ @application_assets_compiler ||= Spontaneous::Asset::AppCompiler.new(Spontaneous.gem_dir, Spontaneous.root)
15
+ end
6
16
 
7
17
  def style_url(style)
8
- "#{NAMESPACE}/css/#{style}.css"
18
+ style = "#{style}.css" unless style =~ /\.css$/
19
+ if (compiled_asset = application_assets.manifest.assets[style])
20
+ return "#{NAMESPACE}/assets/#{compiled_asset}"
21
+ end
22
+ # TODO: use the sprockets environment to append a modification time to the non-compiled URL
23
+ "#{NAMESPACE}/css/#{style}"
9
24
  end
10
25
 
11
26
  def script_url(script)
12
- "#{NAMESPACE}/js/#{script}.js"
27
+ script = "#{script}.js" unless script =~ /\.js$/
28
+
29
+ if (compiled_asset = application_assets.manifest.assets[script])
30
+ return "#{NAMESPACE}/assets/#{compiled_asset}"
31
+ end
32
+ # TODO: use the sprockets environment to append a modification time to the non-compiled URL
33
+ "#{NAMESPACE}/js/#{script}"
13
34
  end
14
35
 
15
36
  def script_list(scripts)
16
- if Spontaneous.development?
17
- scripts.map do |script|
18
- src = "/js/#{script}.js"
19
- path = Spontaneous.application_dir(src)
37
+ scripts.map do |script|
38
+ script = "#{script}.js" unless script =~ /\.js$/
39
+ src = script_url(script)
40
+ size = 0
41
+ if (asset = application_assets.manifest.files[File.basename(src)])
42
+ size = asset["size"]
43
+ else
44
+ src = "#{NAMESPACE}/js/#{script}"
45
+ path = Spontaneous.application_dir("/js/#{script}")
20
46
  size = File.size(path)
21
- ["#{NAMESPACE}#{src}", size]
22
- # %(<script src="#{NAMESPACE}/js/#{script}.js" type="text/javascript"></script>)
23
- end.to_json
24
- else
25
- # script bundling + compression
26
- end
47
+ end
48
+ [src, size]
49
+ end.to_json
27
50
  end
28
51
  end
29
52
  end
30
53
  end
31
-