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
@@ -3,9 +3,97 @@
3
3
 
4
4
  module Cutaneous
5
5
  module ContextHelper
6
- include Tenjin::ContextHelper
7
- include Spontaneous::Render::Context
8
- include Spontaneous
6
+ # include Spontaneous
7
+ attr_accessor :_buf, :_engine, :_layout
8
+
9
+ ## escape value. this method should be overrided in subclass.
10
+ def escape(val)
11
+ return val
12
+ end
13
+
14
+ ## include template. 'template_name' can be filename or short name.
15
+ def import(template_name, _append_to_buf=true)
16
+ _buf = self._buf
17
+ output = self._engine.render(template_name, context=self, layout=false)
18
+ _buf << output if _append_to_buf
19
+ return output
20
+ end
21
+
22
+ ## add value into _buf. this is equivarent to '#{value}'.
23
+ def echo(value)
24
+ self._buf << value
25
+ end
26
+
27
+ ##
28
+ ## start capturing.
29
+ ## returns captured string if block given, else return nil.
30
+ ## if block is not given, calling stop_capture() is required.
31
+ ##
32
+ ## ex. list.rbhtml
33
+ ## <html><body>
34
+ ## <h1><?rb start_capture(:title) do ?>Document Title<?rb end ?></h1>
35
+ ## <?rb start_capture(:content) ?>
36
+ ## <ul>
37
+ ## <?rb for item in list do ?>
38
+ ## <li>${item}</li>
39
+ ## <?rb end ?>
40
+ ## </ul>
41
+ ## <?rb stop_capture() ?>
42
+ ## </body></html>
43
+ ##
44
+ ## ex. layout.rbhtml
45
+ ## <?xml version="1.0" ?>
46
+ ## <html xml:lang="en">
47
+ ## <head>
48
+ ## <title>${@title}</title>
49
+ ## </head>
50
+ ## <body>
51
+ ## <h1>${@title}</h1>
52
+ ## <div id="content">
53
+ ## <?rb echo(@content) ?>
54
+ ## </div>
55
+ ## </body>
56
+ ## </html>
57
+ ##
58
+ def start_capture(varname=nil)
59
+ @_capture_varname = varname
60
+ @_start_position = self._buf.length
61
+ if block_given?
62
+ yield
63
+ output = stop_capture()
64
+ return output
65
+ else
66
+ return nil
67
+ end
68
+ end
69
+
70
+ ##
71
+ ## stop capturing.
72
+ ## returns captured string.
73
+ ## see start_capture()'s document.
74
+ ##
75
+ def stop_capture(store_to_context=true)
76
+ output = self._buf[@_start_position..-1]
77
+ self._buf[@_start_position..-1] = ''
78
+ @_start_position = nil
79
+ if @_capture_varname
80
+ self.instance_variable_set("@#{@_capture_varname}", output) if store_to_context
81
+ @_capture_varname = nil
82
+ end
83
+ return output
84
+ end
85
+
86
+ ##
87
+ ## if captured string is found then add it to _buf and return true,
88
+ ## else return false.
89
+ ## this is a helper method for layout template.
90
+ ##
91
+ def captured_as(name)
92
+ str = self.instance_variable_get("@#{name}")
93
+ return false unless str
94
+ @_buf << str
95
+ return true
96
+ end
9
97
 
10
98
 
11
99
  def extends(parent)
@@ -45,8 +133,10 @@ module Cutaneous
45
133
  position = super_calls.pop
46
134
  result = result[0...position] << output << (result[(position)..-1] || "")
47
135
  if _layout
48
- @_block_super_calls[block_name][-1] = @_block_super_calls[block_name].last + position
49
- @_block_content[block_name] = result
136
+ if (super_call_position = @_block_super_calls[block_name].last)
137
+ @_block_super_calls[block_name][-1] = super_call_position + position
138
+ @_block_content[block_name] = result
139
+ end
50
140
  end
51
141
  end
52
142
  @_buf << result
@@ -60,23 +150,38 @@ module Cutaneous
60
150
  output
61
151
  end
62
152
 
63
- def include(filename)
64
- import(filename)
153
+ def include(filename, locals = {})
154
+ import(filename, true, locals)
155
+ end
156
+
157
+ ## include template. 'template_name' can be filename or short name.
158
+ def import(template_name, _append_to_buf=true, locals={})
159
+ _buf = self._buf
160
+ context=self._dup_with_locals(locals)
161
+ output = self._engine.render(template_name, context, layout=false)
162
+ _buf << output if _append_to_buf
163
+ output
65
164
  end
66
165
 
67
166
  protected
68
167
 
69
- def _decode_params(param, *args)
168
+ def _dup_with_locals(locals = {})
169
+ self.dup.tap { |context| context._update(locals) }
170
+ end
171
+
172
+ def _decode_params(param)
70
173
  unless param.is_a?(String)
71
- @_render_method ||= "to_#{format}".to_sym
174
+ @_render_method ||= "to_#{_format}".to_sym
72
175
  if param.respond_to?(@_render_method)
73
- param = param.send(@_render_method, *args)
74
- end
75
- if param.respond_to?(:render)
76
- param = param.render(format, *args)
176
+ param = param.send(@_render_method)
177
+ else
178
+ if param.respond_to?(:render)
179
+ param = param.render(_format, self)
180
+ end
77
181
  end
78
182
  end
79
- super(param)
183
+ # super(param)
184
+ param.to_s
80
185
  end
81
186
  end
82
187
  end
@@ -3,10 +3,11 @@
3
3
  module Cutaneous
4
4
  class PreviewContext
5
5
  include ContextHelper
6
+ include Spontaneous::Render::PreviewContext
6
7
 
7
- def include(filename)
8
+ def include(filename, locals={})
8
9
  _comment(filename)
9
- import(filename)
10
+ import(filename, true, locals)
10
11
  end
11
12
 
12
13
  def _decode_params(param, *args)
@@ -18,7 +19,7 @@ module Cutaneous
18
19
  end
19
20
 
20
21
  def _comment(text)
21
- @_comment_method ||= "_comment_#{format}".to_sym
22
+ @_comment_method ||= "_comment_#{_format}".to_sym
22
23
  if (respond_to?(@_comment_method))
23
24
  self.send(@_comment_method, text)
24
25
  end
@@ -1,15 +1,10 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  module Cutaneous
4
- class PreviewRenderer < FirstPassRenderer
4
+ class PreviewRenderer < PublishRenderer
5
5
 
6
6
  def context_class
7
7
  Cutaneous::PreviewContext
8
8
  end
9
9
  end
10
10
  end
11
-
12
-
13
-
14
-
15
-
@@ -3,6 +3,7 @@
3
3
  module Cutaneous
4
4
  class PublishContext
5
5
  include ContextHelper
6
+ include Spontaneous::Render::PublishContext
6
7
  end
7
8
  end
8
9
 
@@ -1,10 +1,10 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  module Cutaneous
4
- class FirstPassRenderer < Renderer
4
+ class PublishRenderer < Renderer
5
5
 
6
6
  def template_class
7
- Cutaneous::FirstPassParser
7
+ Cutaneous::PublishTemplate
8
8
  end
9
9
 
10
10
  def context_class
@@ -12,7 +12,3 @@ module Cutaneous
12
12
  end
13
13
  end
14
14
  end
15
-
16
-
17
-
18
-
@@ -0,0 +1,62 @@
1
+ # encoding: UTF-8
2
+
3
+ module Cutaneous
4
+ class PublishTemplate
5
+ attr_reader :parser
6
+ attr_writer :script
7
+ attr_accessor :timestamp, :filename
8
+
9
+ def initialize(template_file = nil, format=:html)
10
+ @format = format
11
+ convert_file(template_file) if template_file
12
+ end
13
+
14
+ def convert_file(template_file)
15
+ convert(File.read(template_file), template_file)
16
+ end
17
+
18
+ def convert(template_string, filepath = nil)
19
+ @template_proc = @script = nil
20
+ @filename = filepath
21
+ @parser = create_parser(template_string)
22
+ script
23
+ end
24
+
25
+ def script
26
+ return nil unless @parser or @script
27
+ @script ||= @parser.script
28
+ end
29
+
30
+ # I'm not doing any type checking here as I know exactly where the calls are coming from
31
+ def render(context)
32
+ begin
33
+ context.instance_eval(&template_proc)
34
+ rescue => e
35
+ if context.show_errors?
36
+ raise e
37
+ else
38
+ logger.warn(e)
39
+ ""
40
+ end
41
+ end
42
+ end
43
+
44
+ protected
45
+
46
+ def template_proc
47
+ @template_proc ||= eval(template_proc_src.untaint, nil, @filename || '(cutaneous)')
48
+ end
49
+
50
+ def template_proc_src
51
+ "lambda { |context| self._buf = _buf = ''; #{script}; _buf.to_s }"
52
+ end
53
+
54
+ def create_parser(template_string)
55
+ parser_class.new(template_string)
56
+ end
57
+
58
+ def parser_class
59
+ Cutaneous::PublishTokenParser
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,8 @@
1
+ module Cutaneous
2
+ PublishTokenParser = Cutaneous::TokenParser.generate({
3
+ :comment => %w(!{ }),
4
+ :expression => %w(${ }),
5
+ :escaped_expression => %w($${ }),
6
+ :statement => %w(%{ })
7
+ })
8
+ end # Cutaneous
@@ -36,6 +36,7 @@ module Cutaneous
36
36
  context._buf = _buf
37
37
  unless context._layout.nil?
38
38
  layout = context._layout
39
+ # context._clean!
39
40
  context._layout = nil
40
41
  end
41
42
  break unless layout
@@ -63,16 +64,17 @@ module Cutaneous
63
64
  cache_path = filepath[0...(-Cutaneous.extension.length)] + 'rb'
64
65
  if test(?f, cache_path)
65
66
  # puts "Using cached template #{cache_path}"
67
+ template.filename = cache_path
66
68
  template.script = File.read(cache_path)
67
69
  else
68
- template.convert(File.read(filepath))
70
+ template.convert(File.read(filepath), filepath)
69
71
  File.open(cache_path, 'w') do |f|
70
72
  f.flock(File::LOCK_EX)
71
73
  f.write(template.script)
72
74
  end
73
75
  end
74
76
  else
75
- template.convert(File.read(filepath))
77
+ template.convert(File.read(filepath), filepath)
76
78
  end
77
79
  when Proc
78
80
  template = template_class.new(nil, format)
@@ -3,6 +3,7 @@
3
3
  module Cutaneous
4
4
  class RequestContext
5
5
  include ContextHelper
6
+ include Spontaneous::Render::RequestContext
6
7
  end
7
8
  end
8
9
 
@@ -1,10 +1,10 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  module Cutaneous
4
- class SecondPassRenderer < Renderer
4
+ class RequestRenderer < Renderer
5
5
 
6
6
  def template_class
7
- Cutaneous::SecondPassParser
7
+ Cutaneous::RequestTemplate
8
8
  end
9
9
 
10
10
  def context_class
@@ -13,6 +13,3 @@ module Cutaneous
13
13
 
14
14
  end
15
15
  end
16
-
17
-
18
-
@@ -0,0 +1,11 @@
1
+ # encoding: UTF-8
2
+
3
+ module Cutaneous
4
+ class RequestTemplate < PublishTemplate
5
+ protected
6
+
7
+ def parser_class
8
+ Cutaneous::RequestTokenParser
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module Cutaneous
2
+ RequestTokenParser = Cutaneous::TokenParser.generate({
3
+ :comment => %w(!{ }),
4
+ :expression => %w({{ }}),
5
+ :escaped_expression => %w({$ $}),
6
+ :statement => %w({% %})
7
+ })
8
+ end # Cutaneous
9
+
@@ -0,0 +1,125 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'strscan'
4
+
5
+ module Cutaneous
6
+ class TokenParser
7
+
8
+ class << self
9
+ attr_accessor :tags
10
+ end
11
+
12
+ module ClassMethods
13
+ def generate(tag_definitions)
14
+ parser_class = Class.new(Cutaneous::TokenParser)
15
+ parser_class.tags = tag_definitions
16
+ parser_class
17
+ end
18
+
19
+ def is_dynamic?(text)
20
+ !text.index(tag_start_pattern).nil?
21
+ end
22
+
23
+
24
+ def tag_start_pattern
25
+ @tag_start_pattern ||= compile_start_pattern
26
+ end
27
+
28
+ def compile_start_pattern
29
+ openings = self.tags.map { |type, tags| Regexp.escape(tags[0]) }
30
+ Regexp.new("#{ openings.join("|") }")
31
+ end
32
+
33
+ # map the set of tags into a hash used by the parse routine that converts an opening tag into a
34
+ # list of: tag type, the number of opening braces in the tag and the length of the closing tag
35
+ def token_map
36
+ @token_map ||= Hash[tags.map { |type, tags| [tags[0], [type, tags[0].count(?{), tags[1].length]] }]
37
+ end
38
+ end
39
+
40
+ extend ClassMethods
41
+
42
+ def initialize(template)
43
+ @template = template
44
+ end
45
+
46
+ def tokens
47
+ @tokens ||= parse
48
+ end
49
+
50
+ def script
51
+ @script ||= compile
52
+ end
53
+
54
+ protected
55
+
56
+ BRACES ||= /\{|\}/
57
+
58
+ def parse
59
+ tokens = []
60
+ scanner = StringScanner.new(@template)
61
+ tag_start = self.class.tag_start_pattern
62
+ tags = self.class.tags
63
+ token_map = self.class.token_map
64
+ previous = nil
65
+
66
+ while (text = scanner.scan_until(tag_start))
67
+ tag = scanner.matched
68
+ type, brace_count, endtag_length = token_map[tag]
69
+ text.slice!(text.length - tag.length, text.length)
70
+ expression = ""
71
+
72
+ begin
73
+ expression << scanner.scan_until(BRACES)
74
+ brace = scanner.matched
75
+ brace_count += ((123 - brace.ord)+1)
76
+ end while (brace_count > 0)
77
+
78
+ expression.slice!(expression.length - endtag_length, expression.length)
79
+
80
+ tokens << place_text_token(text, previous, type) if text.length > 0
81
+ tokens << create_token(type, expression)
82
+ previous = type
83
+ end
84
+ tokens << place_text_token(scanner.rest, previous, nil) unless scanner.eos?
85
+ tokens
86
+ end
87
+
88
+ def create_token(type, expression)
89
+ expression.strip! if type == :expression || type == :escaped_expression || type == :statement
90
+ [type, expression]
91
+ end
92
+
93
+ BEGINNING_WHITESPACE ||= /\A\s*?[\r\n]+/
94
+ ENDING_WHITESPACE ||= /(\r?\n)[ \t]*\z/
95
+ ESCAPE_STRING ||= /[`\\]/
96
+
97
+ def place_text_token(expression, preceeding_type, following_type)
98
+ if preceeding_type == :statement || preceeding_type == :comment
99
+ expression.gsub!(BEGINNING_WHITESPACE, '')
100
+ end
101
+ if following_type == :statement || following_type == :comment
102
+ expression.gsub!(ENDING_WHITESPACE, '\1')
103
+ end
104
+ expression.gsub!(ESCAPE_STRING, '\\\\\&')
105
+ [:text, expression]
106
+ end
107
+
108
+ def compile
109
+ script = ""
110
+ tokens.each do |type, expression|
111
+ case type
112
+ when :expression
113
+ script << %{_buf << _decode_params((} << expression << %{))\n}
114
+ when :text
115
+ script << %(_buf << %Q`) << expression << %(`\n)
116
+ when :statement
117
+ script << expression << "\n"
118
+ when :escaped_expression
119
+ script << %{_buf << escape(_decode_params((} << expression << %{)))\n}
120
+ end
121
+ end
122
+ script
123
+ end
124
+ end
125
+ end