spontaneous 0.1.0.alpha1 → 0.2.0.alpha1

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 (413) hide show
  1. data/Gemfile +40 -35
  2. data/LICENSE +20 -0
  3. data/Rakefile +39 -42
  4. data/Readme.markdown +155 -0
  5. data/application/css/definitions.scss +3 -0
  6. data/application/css/editing.scss +9 -4
  7. data/application/css/min/565d4c25e82148acb01c45c8d675b37a08676d77.css +1 -0
  8. data/application/css/min/84dbe894ea96eafd321c30823d630817bfc4b03b.css +1 -0
  9. data/application/css/min/d1b54ff4847c613618267ca1c15658e2aee0a4e5.css +1 -0
  10. data/application/css/v2.scss +144 -50
  11. data/application/js/add_alias_dialogue.js +18 -8
  12. data/application/js/ajax.js +1 -1
  13. data/application/js/authentication.js +8 -1
  14. data/application/js/box.js +37 -7
  15. data/application/js/box_container.js +1 -1
  16. data/application/js/compatibility.js +7 -0
  17. data/application/js/content.js +7 -0
  18. data/application/js/content_area.js +4 -0
  19. data/application/js/edit_panel.js +44 -18
  20. data/application/js/editing.js +12 -0
  21. data/application/js/event_source.js +17 -0
  22. data/application/js/extensions.js +2 -0
  23. data/application/js/field_types/file_field.js +2 -1
  24. data/application/js/field_types/image_field.js +35 -48
  25. data/application/js/field_types/long_string_field.js +12 -0
  26. data/application/js/field_types/markdown_field.js +2 -5
  27. data/application/js/field_types/string_field.js +5 -1
  28. data/application/js/field_types/webvideo_field.js +15 -0
  29. data/application/js/init.js +1 -0
  30. data/application/js/location.js +30 -19
  31. data/application/js/login.js +1 -2
  32. data/application/js/min/2a0c2962537a3181fedfff5c92596ba6d3122dc9.js +3 -0
  33. data/application/js/min/4cf1c493d3379ecba5287758c61238034c0893f9.js +2 -0
  34. data/application/js/min/78ac6b99d96750bb6b9f9aad4cb9cd91cd03f391.js +3 -0
  35. data/application/js/min/c8efb9b9f7c3f6613fcebc6be60f605b6570a382.js +90 -0
  36. data/application/js/page.js +1 -0
  37. data/application/js/page_entry.js +6 -40
  38. data/application/js/preview.js +2 -3
  39. data/application/js/top_bar.js +76 -31
  40. data/application/js/upload.js +5 -2
  41. data/application/js/upload_manager.js +2 -81
  42. data/application/js/vendor/jquery-1.7.1.min.js +4 -0
  43. data/application/js/vendor/jquery-ui-1.8.16.custom.min.js +791 -0
  44. data/application/js/views.js +3 -3
  45. data/application/js/views/box_view.js +164 -83
  46. data/application/js/views/page_piece_view.js +2 -2
  47. data/application/js/views/page_view.js +46 -15
  48. data/application/js/views/piece_view.js +29 -8
  49. data/application/static/diagonal-texture.png +0 -0
  50. data/application/static/item-buttons-highlight.png +0 -0
  51. data/application/static/plus-box.png +0 -0
  52. data/application/static/plus_alt.svg +8 -0
  53. data/application/static/slot-up-arrow.png +0 -0
  54. data/application/views/{index.erubis → index.erb} +9 -5
  55. data/application/views/{login.erubis → login.erb} +14 -10
  56. data/application/views/schema_modification_error.html.erb +18 -6
  57. data/application/views/{unsupported.erubis → unsupported.erb} +0 -0
  58. data/bin/spot +15 -2
  59. data/db/migrations/20100610142136_init.rb +2 -2
  60. data/db/migrations/20101130104334_timestamps.rb +2 -2
  61. data/db/migrations/20110209152710_users_and_groups.rb +11 -11
  62. data/db/migrations/20120106171423_visibility_path.rb +19 -0
  63. data/db/migrations/20120107124541_owner_id.rb +19 -0
  64. data/docs/recipe-interface-screenshot.png +0 -0
  65. data/lib/cutaneous.rb +11 -10
  66. data/lib/cutaneous/context_helper.rb +119 -14
  67. data/lib/cutaneous/preview_context.rb +4 -3
  68. data/lib/cutaneous/preview_renderer.rb +1 -6
  69. data/lib/cutaneous/publish_context.rb +1 -0
  70. data/lib/cutaneous/{first_pass_renderer.rb → publish_renderer.rb} +2 -6
  71. data/lib/cutaneous/publish_template.rb +62 -0
  72. data/lib/cutaneous/publish_token_parser.rb +8 -0
  73. data/lib/cutaneous/renderer.rb +4 -2
  74. data/lib/cutaneous/request_context.rb +1 -0
  75. data/lib/cutaneous/{second_pass_renderer.rb → request_renderer.rb} +2 -5
  76. data/lib/cutaneous/request_template.rb +11 -0
  77. data/lib/cutaneous/request_token_parser.rb +9 -0
  78. data/lib/cutaneous/token_parser.rb +125 -0
  79. data/lib/sequel/plugins/content_table_inheritance.rb +19 -12
  80. data/lib/sequel/plugins/scoped_table_name.rb +45 -0
  81. data/lib/spontaneous.rb +123 -126
  82. data/lib/spontaneous/box.rb +127 -47
  83. data/lib/spontaneous/box_style.rb +39 -22
  84. data/lib/spontaneous/change.rb +2 -2
  85. data/lib/spontaneous/cli.rb +1 -0
  86. data/lib/spontaneous/cli/base.rb +12 -4
  87. data/lib/spontaneous/cli/console.rb +72 -0
  88. data/lib/spontaneous/cli/server.rb +36 -12
  89. data/lib/spontaneous/cli/site.rb +175 -1
  90. data/lib/spontaneous/collections/box_set.rb +19 -1
  91. data/lib/spontaneous/collections/entry_set.rb +70 -22
  92. data/lib/spontaneous/collections/field_set.rb +3 -3
  93. data/lib/spontaneous/collections/prototype_set.rb +28 -0
  94. data/lib/spontaneous/config.rb +14 -5
  95. data/lib/spontaneous/content.rb +23 -24
  96. data/lib/spontaneous/errors.rb +20 -4
  97. data/lib/spontaneous/extensions/array.rb +2 -2
  98. data/lib/spontaneous/extensions/json.rb +1 -1
  99. data/lib/spontaneous/extensions/nil.rb +13 -0
  100. data/lib/spontaneous/facet.rb +61 -7
  101. data/lib/spontaneous/field_types.rb +1 -3
  102. data/lib/spontaneous/field_types/date_field.rb +1 -0
  103. data/lib/spontaneous/field_types/field.rb +32 -15
  104. data/lib/spontaneous/field_types/image_field.rb +138 -69
  105. data/lib/spontaneous/field_types/location_field.rb +59 -0
  106. data/lib/spontaneous/field_types/long_string_field.rb +13 -0
  107. data/lib/spontaneous/field_types/markdown_field.rb +2 -1
  108. data/lib/spontaneous/field_types/string_field.rb +2 -2
  109. data/lib/spontaneous/field_types/webvideo_field.rb +255 -0
  110. data/lib/spontaneous/generators/page/inline.html.cut +1 -1
  111. data/lib/spontaneous/generators/page/page.html.cut.tt +5 -4
  112. data/lib/spontaneous/generators/page/page.rb.tt +1 -5
  113. data/lib/spontaneous/generators/site.rb +1 -0
  114. data/lib/spontaneous/generators/site/.gitignore +2 -0
  115. data/lib/spontaneous/generators/site/Gemfile.tt +3 -5
  116. data/lib/spontaneous/generators/site/config/environment.rb.tt +1 -0
  117. data/lib/spontaneous/generators/site/config/environments/development.rb.tt +3 -1
  118. data/lib/spontaneous/generators/site/config/environments/production.rb.tt +3 -1
  119. data/lib/spontaneous/generators/site/config/indexes.rb.tt +23 -0
  120. data/lib/spontaneous/generators/site/public/css/{site.css → site.scss} +0 -0
  121. data/lib/spontaneous/generators/site/schema/box.rb.tt +5 -0
  122. data/lib/spontaneous/generators/site/templates/layouts/standard.html.cut.tt +11 -5
  123. data/lib/spontaneous/image_size.rb +0 -1
  124. data/lib/spontaneous/loader.rb +335 -218
  125. data/lib/spontaneous/logger.rb +7 -2
  126. data/lib/spontaneous/media.rb +64 -59
  127. data/lib/spontaneous/media/file.rb +74 -0
  128. data/lib/spontaneous/page.rb +47 -18
  129. data/lib/spontaneous/page_piece.rb +29 -27
  130. data/lib/spontaneous/paths.rb +0 -1
  131. data/lib/spontaneous/permissions.rb +3 -21
  132. data/lib/spontaneous/permissions/user.rb +5 -1
  133. data/lib/spontaneous/permissions/user_level.rb +6 -7
  134. data/lib/spontaneous/piece.rb +12 -7
  135. data/lib/spontaneous/plugins/aliases.rb +76 -31
  136. data/lib/spontaneous/plugins/allowed_types.rb +36 -37
  137. data/lib/spontaneous/plugins/application/facets.rb +7 -10
  138. data/lib/spontaneous/plugins/application/features.rb +17 -0
  139. data/lib/spontaneous/plugins/application/paths.rb +25 -31
  140. data/lib/spontaneous/plugins/application/render.rb +1 -5
  141. data/lib/spontaneous/plugins/application/serialisation.rb +2 -0
  142. data/lib/spontaneous/plugins/application/state.rb +6 -9
  143. data/lib/spontaneous/plugins/boxes.rb +65 -40
  144. data/lib/spontaneous/plugins/controllers.rb +22 -22
  145. data/lib/spontaneous/plugins/entries.rb +149 -150
  146. data/lib/spontaneous/plugins/entry.rb +50 -35
  147. data/lib/spontaneous/plugins/field/editor_class.rb +13 -0
  148. data/lib/spontaneous/plugins/fields.rb +41 -33
  149. data/lib/spontaneous/plugins/instance_code.rb +9 -9
  150. data/lib/spontaneous/plugins/layouts.rb +31 -35
  151. data/lib/spontaneous/plugins/media.rb +31 -32
  152. data/lib/spontaneous/plugins/page/formats.rb +56 -31
  153. data/lib/spontaneous/plugins/page/request.rb +15 -9
  154. data/lib/spontaneous/plugins/page_search.rb +30 -31
  155. data/lib/spontaneous/plugins/page_tree.rb +59 -12
  156. data/lib/spontaneous/plugins/paths.rb +84 -79
  157. data/lib/spontaneous/plugins/permissions.rb +26 -28
  158. data/lib/spontaneous/plugins/prototypes.rb +42 -37
  159. data/lib/spontaneous/plugins/publishing.rb +50 -94
  160. data/lib/spontaneous/plugins/render.rb +8 -16
  161. data/lib/spontaneous/plugins/schema_hierarchy.rb +20 -21
  162. data/lib/spontaneous/plugins/schema_id.rb +33 -25
  163. data/lib/spontaneous/plugins/schema_title.rb +3 -4
  164. data/lib/spontaneous/plugins/serialisation.rb +32 -35
  165. data/lib/spontaneous/plugins/site/features.rb +32 -0
  166. data/lib/spontaneous/plugins/site/instance.rb +3 -2
  167. data/lib/spontaneous/plugins/site/level.rb +18 -0
  168. data/lib/spontaneous/plugins/site/map.rb +2 -1
  169. data/lib/spontaneous/plugins/site/publishing.rb +56 -59
  170. data/lib/spontaneous/plugins/site/revisions.rb +24 -19
  171. data/lib/spontaneous/plugins/site/schema.rb +33 -0
  172. data/lib/spontaneous/plugins/site/search.rb +43 -0
  173. data/lib/spontaneous/plugins/site/selectors.rb +35 -30
  174. data/lib/spontaneous/plugins/site/storage.rb +63 -0
  175. data/lib/spontaneous/plugins/site_map.rb +23 -25
  176. data/lib/spontaneous/plugins/styles.rb +35 -43
  177. data/lib/spontaneous/plugins/supertype.rb +3 -1
  178. data/lib/spontaneous/plugins/visibility.rb +90 -83
  179. data/lib/spontaneous/prototypes/box_prototype.rb +55 -25
  180. data/lib/spontaneous/prototypes/field_prototype.rb +66 -19
  181. data/lib/spontaneous/prototypes/style_prototype.rb +2 -2
  182. data/lib/spontaneous/publishing.rb +1 -1
  183. data/lib/spontaneous/publishing/immediate.rb +128 -49
  184. data/lib/spontaneous/publishing/simultaneous.rb +70 -0
  185. data/lib/spontaneous/rack.rb +38 -26
  186. data/lib/spontaneous/rack/around_back.rb +3 -23
  187. data/lib/spontaneous/rack/around_preview.rb +3 -8
  188. data/lib/spontaneous/rack/assets.rb +7 -6
  189. data/lib/spontaneous/rack/authentication.rb +21 -0
  190. data/lib/spontaneous/rack/back.rb +310 -331
  191. data/lib/spontaneous/rack/cacheable_file.rb +27 -0
  192. data/lib/spontaneous/rack/cookie_authentication.rb +38 -0
  193. data/lib/spontaneous/rack/css.rb +43 -0
  194. data/lib/spontaneous/rack/event_source.rb +31 -0
  195. data/lib/spontaneous/rack/front.rb +30 -8
  196. data/lib/spontaneous/rack/helpers.rb +31 -0
  197. data/lib/spontaneous/rack/media.rb +22 -21
  198. data/lib/spontaneous/rack/public.rb +2 -1
  199. data/lib/spontaneous/rack/query_authentication.rb +35 -0
  200. data/lib/spontaneous/rack/reloader.rb +6 -3
  201. data/lib/spontaneous/rack/user_helpers.rb +28 -0
  202. data/lib/spontaneous/render.rb +64 -23
  203. data/lib/spontaneous/render/context_base.rb +143 -0
  204. data/lib/spontaneous/render/format.rb +24 -19
  205. data/lib/spontaneous/render/helpers.rb +14 -0
  206. data/lib/spontaneous/render/helpers/html_helper.rb +69 -0
  207. data/lib/spontaneous/render/helpers/script_helper.rb +17 -0
  208. data/lib/spontaneous/render/helpers/stylesheet_helper.rb +16 -0
  209. data/lib/spontaneous/render/preview_context.rb +8 -0
  210. data/lib/spontaneous/render/preview_renderer.rb +6 -0
  211. data/lib/spontaneous/render/publish_context.rb +22 -0
  212. data/lib/spontaneous/render/published_renderer.rb +12 -13
  213. data/lib/spontaneous/render/publishing_renderer.rb +3 -0
  214. data/lib/spontaneous/render/render_cache.rb +26 -0
  215. data/lib/spontaneous/render/renderer.rb +5 -1
  216. data/lib/spontaneous/render/request_context.rb +8 -0
  217. data/lib/spontaneous/schema.rb +56 -24
  218. data/lib/spontaneous/schema/schema_modification.rb +2 -2
  219. data/lib/spontaneous/schema/uid.rb +22 -106
  220. data/lib/spontaneous/schema/uid_map.rb +120 -0
  221. data/lib/spontaneous/search.rb +11 -0
  222. data/lib/spontaneous/search/compound_indexer.rb +26 -0
  223. data/lib/spontaneous/search/database.rb +72 -0
  224. data/lib/spontaneous/search/field.rb +95 -0
  225. data/lib/spontaneous/search/index.rb +184 -0
  226. data/lib/spontaneous/search/results.rb +34 -0
  227. data/lib/spontaneous/server.rb +5 -1
  228. data/lib/spontaneous/site.rb +56 -16
  229. data/lib/spontaneous/storage.rb +22 -0
  230. data/lib/spontaneous/storage/backend.rb +10 -0
  231. data/lib/spontaneous/storage/cloud.rb +104 -0
  232. data/lib/spontaneous/storage/local.rb +52 -0
  233. data/lib/spontaneous/style.rb +27 -9
  234. data/lib/spontaneous/version.rb +1 -1
  235. data/spontaneous.gemspec +719 -0
  236. data/test/disabled/test_slots.rb +1 -1
  237. data/test/experimental/test_cutaneous.rb +309 -0
  238. data/test/experimental/test_features.rb +129 -0
  239. data/test/fixtures/application/views/{index.erubis → index.erb} +0 -0
  240. data/test/fixtures/back/public/css/sass_include.scss +5 -0
  241. data/test/fixtures/back/public/css/sass_template.scss +4 -0
  242. data/test/fixtures/example_application/templates/client_project.html.cut +4 -4
  243. data/test/fixtures/example_application/templates/client_project/images.html.cut +1 -1
  244. data/test/fixtures/example_application/templates/client_projects.html.cut +2 -2
  245. data/test/fixtures/example_application/templates/inline_image.html.cut +1 -1
  246. data/test/fixtures/example_application/templates/layouts/home.html.cut +7 -7
  247. data/test/fixtures/example_application/templates/layouts/info.html.cut +1 -1
  248. data/test/fixtures/example_application/templates/layouts/project.html.cut +4 -4
  249. data/test/fixtures/example_application/templates/layouts/projects.html.cut +2 -2
  250. data/test/fixtures/example_application/templates/project.html.cut +2 -2
  251. data/test/fixtures/example_application/templates/project/inline.html.cut +3 -3
  252. data/test/fixtures/example_application/templates/project_image.html.cut +1 -1
  253. data/test/fixtures/example_application/templates/text.html.cut +1 -1
  254. data/test/fixtures/fields/youtube_api_response.xml +102 -0
  255. data/test/fixtures/layouts/layouts/custom4.html.cut +0 -0
  256. data/test/fixtures/plugins/schema_plugin/public/css/plugin.css +1 -0
  257. data/test/fixtures/plugins/schema_plugin/public/js/plugin.js +1 -0
  258. data/test/fixtures/plugins/schema_plugin/public/static.html +1 -0
  259. data/test/fixtures/plugins/schema_plugin/public/subdir/image.gif +1 -0
  260. data/test/fixtures/plugins/schema_plugin/public/subdir/include1.scss +3 -0
  261. data/test/fixtures/plugins/schema_plugin/public/subdir/sass.scss +4 -0
  262. data/test/fixtures/plugins/schema_plugin/public/subdir/sass/include2.scss +4 -0
  263. data/test/fixtures/public/templates/layouts/default.html.cut +1 -1
  264. data/test/fixtures/public/templates/layouts/default.pdf.cut +1 -1
  265. data/test/fixtures/public/templates/layouts/default.rss.cut +1 -1
  266. data/test/fixtures/public/templates/layouts/dynamic.html.cut +1 -1
  267. data/test/fixtures/schema_modification/config/database.yml +0 -0
  268. data/test/fixtures/schema_modification/config/environment.rb +2 -0
  269. data/test/fixtures/schema_modification/schema/box.rb +1 -0
  270. data/test/fixtures/schema_modification/schema/custom_box.rb +1 -0
  271. data/test/fixtures/schema_modification/schema/page.rb +6 -0
  272. data/test/fixtures/schema_modification/schema/piece.rb +1 -0
  273. data/test/fixtures/search/config/database.yml +1 -0
  274. data/test/fixtures/search/config/indexes.rb +4 -0
  275. data/test/fixtures/serialisation/root_hash.yaml.erb +16 -20
  276. data/test/fixtures/storage/cloud/environment.rb +12 -0
  277. data/test/fixtures/storage/default/environment.rb +1 -0
  278. data/test/fixtures/templates/aliases/layouts/c_alias.html.cut +1 -1
  279. data/test/fixtures/templates/content/include.html.cut +1 -1
  280. data/test/fixtures/templates/content/include_dir.html.cut +1 -1
  281. data/test/fixtures/templates/content/included.epub.cut +1 -1
  282. data/test/fixtures/templates/content/included.html.cut +1 -1
  283. data/test/fixtures/templates/content/partial/included.html.cut +1 -1
  284. data/test/fixtures/templates/content/preprocess.html.cut +1 -1
  285. data/test/fixtures/templates/content/second.html.cut +1 -1
  286. data/test/fixtures/templates/content/template.epub.cut +1 -1
  287. data/test/fixtures/templates/content/template.html.cut +1 -1
  288. data/test/fixtures/templates/default_style_class.html.cut +1 -1
  289. data/test/fixtures/templates/engine/braces.html.cut +6 -0
  290. data/test/fixtures/templates/engine/multiline.html.cut +5 -0
  291. data/test/fixtures/templates/extended/grandparent.html.cut +7 -7
  292. data/test/fixtures/templates/extended/main.html.cut +5 -5
  293. data/test/fixtures/templates/extended/parent.html.cut +10 -8
  294. data/test/fixtures/templates/extended/partial.html.cut +1 -0
  295. data/test/fixtures/templates/extended/partial_with_locals.html.cut +1 -0
  296. data/test/fixtures/templates/extended/with_includes.html.cut +9 -0
  297. data/test/fixtures/templates/extended/with_includes_and_locals.html.cut +9 -0
  298. data/test/fixtures/templates/layouts/entries.html.cut +7 -7
  299. data/test/fixtures/templates/layouts/page_style.html.cut +1 -1
  300. data/test/fixtures/templates/layouts/params.html.cut +1 -1
  301. data/test/fixtures/templates/layouts/preview_render.html.cut +2 -2
  302. data/test/fixtures/templates/layouts/standard_page.html.cut +1 -1
  303. data/test/fixtures/templates/layouts/subdir_style.html.cut +1 -1
  304. data/test/fixtures/templates/layouts/template_params.html.cut +1 -1
  305. data/test/fixtures/templates/layouts/variables.html.cut +7 -0
  306. data/test/fixtures/templates/page_class/inline_style.html.cut +1 -1
  307. data/test/fixtures/templates/preview_render/variables.html.cut +1 -0
  308. data/test/fixtures/templates/publishing/templates/layouts/dynamic.html.cut +1 -0
  309. data/test/fixtures/templates/publishing/templates/layouts/dynamic.rtf.cut +1 -0
  310. data/test/fixtures/templates/publishing/templates/layouts/static.html.cut +1 -0
  311. data/test/fixtures/templates/template_class/anonymous_style.html.cut +2 -2
  312. data/test/fixtures/templates/template_class/complex_template.html.cut +4 -4
  313. data/test/fixtures/templates/template_class/complex_template.pdf.cut +4 -4
  314. data/test/fixtures/templates/template_class/default_template_style.html.cut +2 -2
  315. data/test/fixtures/templates/template_class/images_with_template.html.cut +3 -3
  316. data/test/fixtures/templates/template_class/slots_template.html.cut +3 -3
  317. data/test/fixtures/templates/template_class/slots_template.pdf.cut +3 -3
  318. data/test/fixtures/templates/template_class/this_template.epub.cut +1 -1
  319. data/test/fixtures/templates/template_class/this_template.html.cut +1 -1
  320. data/test/fixtures/templates/template_class/this_template.pdf.cut +1 -1
  321. data/test/fixtures/templates/with_default_style_class.html.cut +1 -1
  322. data/test/functional/test_application.rb +19 -15
  323. data/test/functional/test_back.rb +130 -98
  324. data/test/functional/test_front.rb +72 -28
  325. data/test/javascript/test_dom.rb +1 -1
  326. data/test/javascript/test_markdown.rb +1 -1
  327. data/test/slow/test_publishing.rb +94 -75
  328. data/test/slow/test_visibility.rb +47 -14
  329. data/test/test_helper.rb +30 -3
  330. data/test/ui/test_page_editing.rb +1 -1
  331. data/test/unit/test_alias.rb +200 -16
  332. data/test/unit/test_authentication.rb +26 -28
  333. data/test/unit/test_boxes.rb +146 -75
  334. data/test/unit/test_config.rb +42 -20
  335. data/test/unit/test_content.rb +156 -37
  336. data/test/unit/test_content_inheritance.rb +4 -2
  337. data/test/unit/test_extensions.rb +7 -1
  338. data/test/unit/test_fields.rb +558 -290
  339. data/test/{experimental → unit}/test_formats.rb +42 -3
  340. data/test/unit/test_generators.rb +3 -2
  341. data/test/unit/test_helpers.rb +54 -0
  342. data/test/unit/test_image_size.rb +1 -1
  343. data/test/unit/test_images.rb +51 -40
  344. data/test/unit/test_layouts.rb +21 -4
  345. data/test/unit/test_logger.rb +1 -1
  346. data/test/unit/test_media.rb +165 -7
  347. data/test/unit/test_page.rb +158 -27
  348. data/test/unit/test_permissions.rb +170 -187
  349. data/test/unit/test_piece.rb +27 -9
  350. data/test/unit/test_plugins.rb +153 -0
  351. data/test/unit/test_prototype_set.rb +60 -2
  352. data/test/unit/test_prototypes.rb +81 -20
  353. data/test/unit/test_render.rb +97 -9
  354. data/test/unit/test_schema.rb +167 -120
  355. data/test/unit/test_search.rb +588 -0
  356. data/test/unit/test_serialisation.rb +26 -10
  357. data/test/unit/test_site.rb +42 -25
  358. data/test/unit/test_storage.rb +88 -0
  359. data/test/unit/test_structure.rb +11 -5
  360. data/test/unit/test_styles.rb +64 -3
  361. data/test/unit/test_table_scoping.rb +76 -0
  362. data/test/unit/test_templates.rb +69 -31
  363. data/test/unit/test_type_hierarchy.rb +9 -1
  364. metadata +274 -208
  365. data/Gemfile.lock +0 -146
  366. data/application/css/min/54ee0ed3c7fac7632bd5c020d69e9a2503e0c88c.css +0 -1
  367. data/application/css/min/c256adc144e2bdd0b0539356b04eb62db01e1dc3.css +0 -1
  368. data/application/js/edit_dialogue.js +0 -137
  369. data/application/js/min/492a209de8ee955fa9c729a765377495001e11b1.js +0 -17
  370. data/application/js/min/80f684d77c940887a1d4a63e3a96102e993baa98.js +0 -88
  371. data/application/js/min/c7140ec9475e5bf868b901e0621338d7d162358b.js +0 -3
  372. data/application/js/min/f07f2bd6630ee31e1c2288ec223383d8f0658ba6.js +0 -2
  373. data/application/js/vendor/.DS_Store +0 -0
  374. data/application/js/vendor/JS.Class-2.1.5/src/command.js +0 -93
  375. data/application/js/vendor/JS.Class-2.1.5/src/comparable.js +0 -37
  376. data/application/js/vendor/JS.Class-2.1.5/src/constant_scope.js +0 -48
  377. data/application/js/vendor/JS.Class-2.1.5/src/core.js +0 -1060
  378. data/application/js/vendor/JS.Class-2.1.5/src/decorator.js +0 -50
  379. data/application/js/vendor/JS.Class-2.1.5/src/enumerable.js +0 -505
  380. data/application/js/vendor/JS.Class-2.1.5/src/forwardable.js +0 -22
  381. data/application/js/vendor/JS.Class-2.1.5/src/hash.js +0 -334
  382. data/application/js/vendor/JS.Class-2.1.5/src/linked_list.js +0 -114
  383. data/application/js/vendor/JS.Class-2.1.5/src/loader.js +0 -553
  384. data/application/js/vendor/JS.Class-2.1.5/src/method_chain.js +0 -172
  385. data/application/js/vendor/JS.Class-2.1.5/src/observable.js +0 -55
  386. data/application/js/vendor/JS.Class-2.1.5/src/package.js +0 -472
  387. data/application/js/vendor/JS.Class-2.1.5/src/proxy.js +0 -58
  388. data/application/js/vendor/JS.Class-2.1.5/src/ruby.js +0 -44
  389. data/application/js/vendor/JS.Class-2.1.5/src/set.js +0 -332
  390. data/application/js/vendor/JS.Class-2.1.5/src/stack_trace.js +0 -151
  391. data/application/js/vendor/JS.Class-2.1.5/src/state.js +0 -95
  392. data/application/js/vendor/JS.Class-2.1.5/src/stdlib.js +0 -2612
  393. data/application/js/vendor/jquery-1.4.2.min.js +0 -154
  394. data/application/js/vendor/jquery-1.4.3.min.js +0 -166
  395. data/application/js/vendor/jquery-1.5.1.min.js +0 -16
  396. data/application/js/vendor/jquery-1.5.1rc1.min.js +0 -24
  397. data/application/js/vendor/jquery-ui-1.8.6.custom.min.js +0 -265
  398. data/application/js/vendor/jquery-ui-1.8.custom.min.js +0 -106
  399. data/application/js/vendor/jquery.hotkeys-0.7.9.js +0 -248
  400. data/application/js/vendor/jquery.hotkeys-0.7.9.min.js +0 -19
  401. data/application/js/vendor/jsdiff.js +0 -169
  402. data/lib/cutaneous/first_pass_parser.rb +0 -23
  403. data/lib/cutaneous/parser_core.rb +0 -18
  404. data/lib/cutaneous/second_pass_parser.rb +0 -23
  405. data/lib/sequel/plugins/yajl_serialization.rb +0 -154
  406. data/lib/spontaneous/plugins.rb +0 -20
  407. data/lib/spontaneous/proxy_object.rb +0 -12
  408. data/lib/spontaneous/publishing/fire_and_forget.rb +0 -57
  409. data/lib/spontaneous/render/context.rb +0 -100
  410. data/spontaneous.gemspec.tmpl +0 -66
  411. data/test/experimental/test_plugins.rb +0 -64
  412. data/test/fixtures/templates/publishing/layouts/dynamic.html.cut +0 -1
  413. data/test/fixtures/templates/publishing/layouts/static.html.cut +0 -1
@@ -0,0 +1,27 @@
1
+
2
+ module Spontaneous::Rack
3
+ class CacheableFile < ::Rack::File
4
+ include HTTP
5
+
6
+ TEN_YEARS = 10*365*24*3600
7
+ MAX_AGE = "max-age=#{TEN_YEARS}, public".freeze
8
+
9
+ def initialize(file_root)
10
+ super(file_root, 'public')
11
+ end
12
+
13
+ def call(env)
14
+ status, headers, body = super
15
+ [status, caching_headers(headers), body]
16
+ end
17
+
18
+ # Send a far future Expires header and make sure that
19
+ # the cache control is public
20
+ def caching_headers(headers)
21
+ headers.merge({
22
+ HTTP_CACHE_CONTROL => MAX_AGE,
23
+ HTTP_EXPIRES => (Time.now + TEN_YEARS).httpdate
24
+ })
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous
4
+ module Rack
5
+ class CookieAuthentication
6
+ def initialize(app)
7
+ @app = app
8
+ end
9
+
10
+ def access_key(env)
11
+ if login = Site.config.auto_login
12
+ user = Spontaneous::Permissions::User[:login => login]
13
+ if user.access_keys.empty?
14
+ user.generate_access_key
15
+ else
16
+ user.access_keys.first
17
+ end
18
+ else
19
+ request = ::Rack::Request.new(env)
20
+ api_key = request.cookies[Spontaneous::Rack::AUTH_COOKIE]
21
+ if api_key && key = Spontaneous::Permissions::AccessKey.authenticate(api_key)
22
+ key
23
+ else
24
+ nil
25
+ end
26
+ end
27
+ end
28
+
29
+ def call(env)
30
+ response = nil
31
+ key = env[S::Rack::ACTIVE_KEY] = access_key(env)
32
+ user = env[S::Rack::ACTIVE_USER] = key.user if key
33
+ response = @app.call(env)
34
+ response
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,43 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'sass'
4
+
5
+ module Spontaneous::Rack
6
+ class CSS
7
+ def initialize(app, options = {})
8
+ @options = options
9
+ @root = options.delete(:root)
10
+ @app = app
11
+ end
12
+
13
+ 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)
24
+ end
25
+ end
26
+
27
+ def render_sass_template(template)
28
+ load_paths = [Spontaneous.css_dir, File.dirname(template), File.join(File.dirname(template), "sass")]
29
+ engine = Sass::Engine.for_file(template, {
30
+ :load_paths => load_paths,
31
+ :filename => template,
32
+ :cache => false,
33
+ :style => :expanded
34
+ })
35
+ [200, {'Content-type' => 'text/css'}, [engine.render]]
36
+ end
37
+
38
+ def template_root_path(path)
39
+ basename = File.basename(path, '.css')
40
+ File.join(@root, File.dirname(path), basename)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous
4
+ module Rack
5
+ class EventSource < ::Simultaneous::Rack::EventSource
6
+ # def initialize
7
+ # @messenger = ::Simultaneous::Rack::EventSource.new
8
+ # @app = @messenger.app
9
+ # end
10
+
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
25
+
26
+ # def unauthorized!
27
+ # [401, {}, "Unauthorized"]
28
+ # end
29
+ end
30
+ end
31
+ end
@@ -10,12 +10,35 @@ module Spontaneous
10
10
  # use ::Rack::CommonLogger, STDERR #unless server.name =~ /CGI/
11
11
  # use ::Rack::ShowExceptions
12
12
 
13
- use Spontaneous::Rack::Static, :root => Spontaneous.root / "public",
13
+
14
+ use Spontaneous::Rack::Static, :root => Spontaneous.revision_dir / "public",
14
15
  :urls => %w[/],
15
16
  :try => ['.html', 'index.html', '/index.html']
16
17
 
18
+
19
+
20
+ Spontaneous.instance.front_controllers.each do |namespace, controller_class|
21
+ map namespace do
22
+ run controller_class
23
+ end
24
+ end if Spontaneous.instance
25
+
26
+
27
+ # Make all the files available under plugin_name/public/**
28
+ # available under the URL /plugin_name/**
29
+ # Only used in preview mode
30
+ Spontaneous.instance.plugins.each do |plugin|
31
+ map "/#{plugin.name}" do
32
+ run ::Rack::File.new(plugin.paths.expanded(:public))
33
+ end
34
+ end if Spontaneous.instance
35
+
36
+ map "/rev" do
37
+ run Spontaneous::Rack::CacheableFile.new(Spontaneous.revision_dir / "rev")
38
+ end
39
+
17
40
  map "/media" do
18
- run Spontaneous::Rack::Media.new
41
+ run Spontaneous::Rack::CacheableFile.new(Spontaneous.media_dir)
19
42
  end
20
43
 
21
44
  map "/" do
@@ -25,17 +48,16 @@ module Spontaneous
25
48
  end
26
49
  end
27
50
  end
28
- class Server# < Spontaneous::Rack::Public
51
+ class Server < Sinatra::Base
29
52
  include Spontaneous::Rack::Public
30
53
 
31
- def call(env)
32
- @response = ::Rack::Response.new
33
- @request = ::Rack::Request.new(env)
54
+ def call!(env)
55
+ @env = env
56
+ @response = ::Sinatra::Response.new
57
+ @request = ::Sinatra::Request.new(env)
34
58
  render_path(@request.path_info)
35
59
  end
36
60
  end
37
61
  end
38
62
  end
39
63
  end
40
-
41
-
@@ -0,0 +1,31 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous
4
+ module Rack
5
+ module Helpers
6
+
7
+ def style_url(style)
8
+ "#{NAMESPACE}/css/#{style}.css"
9
+ end
10
+
11
+ def script_url(script)
12
+ "#{NAMESPACE}/js/#{script}.js"
13
+ end
14
+
15
+ def script_list(scripts)
16
+ if Spontaneous.development?
17
+ scripts.map do |script|
18
+ src = "/js/#{script}.js"
19
+ path = Spontaneous.application_dir(src)
20
+ 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
27
+ end
28
+ end
29
+ end
30
+ end
31
+
@@ -1,29 +1,30 @@
1
+ # encoding: UTF-8
1
2
 
2
- module Spontaneous
3
- module Rack
4
- class Media < ::Rack::File
5
- include HTTP
3
+ require 'rack'
6
4
 
7
- TEN_YEARS = 10*365*24*3600
8
- MAX_AGE = "max-age=#{TEN_YEARS}, public".freeze
5
+ module Spontaneous::Rack
6
+ class XXX < ::Rack::File
7
+ include HTTP
9
8
 
10
- def initialize
11
- super(Spontaneous.media_dir, 'public')
12
- end
9
+ TEN_YEARS = 10*365*24*3600
10
+ MAX_AGE = "max-age=#{TEN_YEARS}, public".freeze
13
11
 
14
- def call(env)
15
- status, headers, body = super
16
- [status, caching_headers(headers), body]
17
- end
12
+ def initialize(file_root)
13
+ super(file_root, 'public')
14
+ end
15
+
16
+ def call(env)
17
+ status, headers, body = super
18
+ [status, caching_headers(headers), body]
19
+ end
18
20
 
19
- # media is never over-written so we can make sure clients
20
- # never make the same request twice
21
- def caching_headers(headers)
22
- headers.merge({
23
- HTTP_CACHE_CONTROL => MAX_AGE,
24
- HTTP_EXPIRES => (Time.now + TEN_YEARS).httpdate
25
- })
26
- end
21
+ # media is never over-written so we can make sure clients
22
+ # never make the same request twice
23
+ def caching_headers(headers)
24
+ headers.merge({
25
+ HTTP_CACHE_CONTROL => MAX_AGE,
26
+ HTTP_EXPIRES => (Time.now + TEN_YEARS).httpdate
27
+ })
27
28
  end
28
29
  end
29
30
  end
@@ -8,7 +8,8 @@ module Spontaneous
8
8
  include Sinatra::Helpers unless method_defined?(:redirect)
9
9
 
10
10
 
11
- attr_reader :response, :request
11
+
12
+ attr_reader :env, :response, :request
12
13
  attr_accessor :page
13
14
 
14
15
  def render_path(path)
@@ -0,0 +1,35 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous
4
+ module Rack
5
+ # Rack middleware that only allows access if the access key passed in the request query
6
+ # matches that used in the cookie
7
+ #
8
+ # Depends on CookieAuthentication being in the chain *before* this app to set up the current user in the env
9
+ class QueryAuthentication
10
+ def initialize(app)
11
+ @app = app
12
+ end
13
+
14
+ def call(env)
15
+ user = env[S::Rack::ACTIVE_USER]
16
+ if user.nil?
17
+ unauthorized!
18
+ else
19
+ request = ::Rack::Request.new(env)
20
+ key = request[S::Rack::KEY_PARAM]
21
+ if ::S::Permissions::AccessKey.valid?(key, user)
22
+ @app.call(env)
23
+ else
24
+ unauthorized!
25
+ end
26
+ end
27
+ end
28
+
29
+ def unauthorized!
30
+ [401, {}, "Unauthorized"]
31
+ end
32
+ end
33
+ end
34
+ end
35
+
@@ -7,9 +7,12 @@ require 'tilt'
7
7
  module Spontaneous
8
8
  module Rack
9
9
  class Reloader
10
- def initialize(app)
10
+ include Spontaneous::Rack::Helpers
11
+
12
+ def initialize(app, *args)
11
13
  @app = app
12
- @cooldown = 3
14
+ config = args.first || {}
15
+ @cooldown = config[:cooldown] || 3
13
16
  @last = (Time.now - @cooldown)
14
17
  end
15
18
 
@@ -28,7 +31,7 @@ module Spontaneous
28
31
  @app.call(env)
29
32
  rescue Spontaneous::SchemaModificationError => error
30
33
  template = Tilt::ErubisTemplate.new(File.expand_path('../../../../application/views/schema_modification_error.html.erb', __FILE__))
31
- html = template.render(error.modification, :env => env)
34
+ html = template.render(self, :modification => error.modification, :env => env)
32
35
  [412, {'Content-type' => ::Rack::Mime.mime_type('.html')}, StringIO.new(html)].tap do |response|
33
36
  end
34
37
  end
@@ -0,0 +1,28 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous
4
+ module Rack
5
+ module UserHelpers
6
+
7
+ def unauthorised!
8
+ halt 401#, "You do not have the necessary permissions to update the '#{name}' field"
9
+ end
10
+
11
+ def api_key
12
+ request.cookies[AUTH_COOKIE]
13
+ end
14
+
15
+ def user
16
+ @user ||= load_user
17
+ end
18
+
19
+ def load_user
20
+ env[ACTIVE_USER]
21
+ end
22
+
23
+ def show_login_page(locals = {})
24
+ halt(401, erb(:login, :views => Spontaneous.application_dir('/views'), :locals => locals))
25
+ end
26
+ end
27
+ end
28
+ end
@@ -5,15 +5,15 @@ module Spontaneous
5
5
  module Render
6
6
 
7
7
  class << self
8
- def output_path(revision, page, format, extension = nil)
9
- output_path_with_root(revision_root(revision), revision, page, format, extension)
8
+ def output_path(revision, page, format, extension = nil, template_dynamic = false)
9
+ output_path_with_root(revision_root(revision), revision, page, format, extension, template_dynamic)
10
10
  end
11
11
 
12
- def output_path_with_root(root, revision, page, format, extension = nil)
12
+ def output_path_with_root(root, revision, page, format, extension = nil, template_dynamic = false)
13
13
  ext = ".#{format}"
14
- ext += ".#{extension}" if extension
15
-
16
- dir = root / format / page.path
14
+ ext += ".#{extension}" if extension && template_dynamic
15
+ segment = template_dynamic ? "dynamic" : (page.dynamic? ? "protected" : "static")
16
+ dir = root / segment / page.path
17
17
  path = dir / "/index#{ext}"
18
18
  path
19
19
  end
@@ -58,12 +58,15 @@ module Spontaneous
58
58
  @renderer ||= renderer_class.new(template_root)
59
59
  end
60
60
 
61
+
61
62
  def with_preview_renderer(&block)
62
63
  with_renderer(PreviewRenderer, &block)
63
64
  end
64
65
 
65
66
  def with_publishing_renderer(&block)
66
- with_renderer(PublishingRenderer, &block)
67
+ with_render_cache {
68
+ with_renderer(PublishingRenderer, &block)
69
+ }
67
70
  end
68
71
 
69
72
  def with_published_renderer(&block)
@@ -97,6 +100,36 @@ module Spontaneous
97
100
  end
98
101
 
99
102
 
103
+ def with_render_cache
104
+ Thread.current[:_render_cache] = {}
105
+ yield if block_given?
106
+ ensure
107
+ Thread.current[:_render_cache] = nil
108
+ end
109
+
110
+ def render_cache
111
+ Thread.current[:_render_cache]
112
+ end
113
+
114
+ def render_cache_active?
115
+ !render_cache.nil?
116
+ end
117
+
118
+ def render_cache_key?(key)
119
+ return false unless render_cache_active?
120
+ render_cache.key?(key)
121
+ end
122
+
123
+ def render_cache_value(key)
124
+ return nil unless render_cache_active?
125
+ render_cache[key]
126
+ end
127
+
128
+ def render_cache_set_value(key, value)
129
+ return value unless render_cache_active?
130
+ render_cache[key] = value
131
+ end
132
+
100
133
  def template_root
101
134
  @template_root ||= Spontaneous.root / "templates"
102
135
  end
@@ -105,10 +138,10 @@ module Spontaneous
105
138
  ::File.join(template_root, *path)
106
139
  end
107
140
 
108
- def template_root=(root)
109
- @template_root = root
110
- @renderer = nil
111
- end
141
+ # def template_root=(root)
142
+ # @template_root = root
143
+ # @renderer = nil
144
+ # end
112
145
 
113
146
  def extension
114
147
  Spontaneous.template_ext
@@ -152,22 +185,30 @@ module Spontaneous
152
185
  end
153
186
  end
154
187
 
155
- def render(content, format=:html, params={})
188
+ def render(content, format=:html, params={}, *args)
156
189
  Content.with_visible do
157
- renderer.render_content(content, format || :html, params)
190
+ renderer.render_content(content, format || :html, params, *args)
191
+ end
192
+ end
193
+ def render_string(template_string, content, format=:html, params={}, *args)
194
+ Content.with_visible do
195
+ renderer.render_string(template_string, content, format || :html, params, *args)
158
196
  end
159
197
  end
160
198
  end
161
- autoload :Engine, "spontaneous/render/engine"
162
-
163
- autoload :Context, "spontaneous/render/context"
164
-
165
- autoload :Renderer, "spontaneous/render/renderer"
166
- autoload :PreviewRenderer, "spontaneous/render/preview_renderer"
167
- autoload :PublishingRenderer, "spontaneous/render/publishing_renderer"
168
- autoload :PublishedRenderer, "spontaneous/render/published_renderer"
169
- autoload :DevelopmentRenderer, "spontaneous/render/development_renderer"
170
199
 
171
- autoload :Format, "spontaneous/render/format"
200
+ autoload :Engine, "spontaneous/render/engine"
201
+ autoload :ContextBase, "spontaneous/render/context_base"
202
+ autoload :PreviewContext, "spontaneous/render/preview_context"
203
+ autoload :PublishContext, "spontaneous/render/publish_context"
204
+ autoload :RequestContext, "spontaneous/render/request_context"
205
+ autoload :RenderCache, "spontaneous/render/render_cache"
206
+ autoload :Renderer, "spontaneous/render/renderer"
207
+ autoload :PreviewRenderer, "spontaneous/render/preview_renderer"
208
+ autoload :PublishingRenderer, "spontaneous/render/publishing_renderer"
209
+ autoload :PublishedRenderer, "spontaneous/render/published_renderer"
210
+ autoload :DevelopmentRenderer, "spontaneous/render/development_renderer"
211
+ autoload :Format, "spontaneous/render/format"
212
+ autoload :Helpers, "spontaneous/render/helpers"
172
213
  end
173
214
  end