spontaneous 0.1.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 (556) hide show
  1. data/Gemfile +49 -0
  2. data/Gemfile.lock +146 -0
  3. data/LICENSE +0 -0
  4. data/README +0 -0
  5. data/Rakefile +284 -0
  6. data/Readme.markdown +7 -0
  7. data/application/css/add_alias_dialogue.scss +27 -0
  8. data/application/css/definitions.scss +249 -0
  9. data/application/css/developer.scss +9 -0
  10. data/application/css/editing.scss +649 -0
  11. data/application/css/login.scss +91 -0
  12. data/application/css/min/54ee0ed3c7fac7632bd5c020d69e9a2503e0c88c.css +1 -0
  13. data/application/css/min/c256adc144e2bdd0b0539356b04eb62db01e1dc3.css +1 -0
  14. data/application/css/popover.scss +335 -0
  15. data/application/css/schema_error.scss +90 -0
  16. data/application/css/spontaneous.scss +111 -0
  17. data/application/css/unsupported.scss +16 -0
  18. data/application/css/v2.scss +1606 -0
  19. data/application/css/variables.scss +80 -0
  20. data/application/js/add_alias_dialogue.js +59 -0
  21. data/application/js/add_home_dialogue.js +59 -0
  22. data/application/js/ajax.js +99 -0
  23. data/application/js/authentication.js +22 -0
  24. data/application/js/box.js +104 -0
  25. data/application/js/box_container.js +82 -0
  26. data/application/js/compatibility.js +132 -0
  27. data/application/js/conflicted_field_dialogue.js +92 -0
  28. data/application/js/content.js +224 -0
  29. data/application/js/content_area.js +44 -0
  30. data/application/js/dialogue.js +196 -0
  31. data/application/js/dom.js +71 -0
  32. data/application/js/edit_dialogue.js +137 -0
  33. data/application/js/edit_panel.js +232 -0
  34. data/application/js/editing.js +42 -0
  35. data/application/js/entry.js +13 -0
  36. data/application/js/extensions.js +104 -0
  37. data/application/js/field.js +4 -0
  38. data/application/js/field_preview.js +55 -0
  39. data/application/js/field_types/date_field.js +16 -0
  40. data/application/js/field_types/file_field.js +71 -0
  41. data/application/js/field_types/image_field.js +358 -0
  42. data/application/js/field_types/markdown_field.js +656 -0
  43. data/application/js/field_types/string_field.js +185 -0
  44. data/application/js/image.js +72 -0
  45. data/application/js/init.js +34 -0
  46. data/application/js/load.js +4 -0
  47. data/application/js/location.js +157 -0
  48. data/application/js/login.js +53 -0
  49. data/application/js/min/492a209de8ee955fa9c729a765377495001e11b1.js +17 -0
  50. data/application/js/min/80f684d77c940887a1d4a63e3a96102e993baa98.js +88 -0
  51. data/application/js/min/b8abf302a824c35385ff517b34111e1710ff3b37.js +2 -0
  52. data/application/js/min/c7140ec9475e5bf868b901e0621338d7d162358b.js +3 -0
  53. data/application/js/min/f07f2bd6630ee31e1c2288ec223383d8f0658ba6.js +2 -0
  54. data/application/js/page.js +43 -0
  55. data/application/js/page_browser.js +147 -0
  56. data/application/js/page_entry.js +47 -0
  57. data/application/js/popover.js +99 -0
  58. data/application/js/popover_view.js +56 -0
  59. data/application/js/preview.js +64 -0
  60. data/application/js/progress.js +358 -0
  61. data/application/js/properties.js +90 -0
  62. data/application/js/publish.js +187 -0
  63. data/application/js/require.js +129 -0
  64. data/application/js/sharded_upload.js +206 -0
  65. data/application/js/side_bar.js +30 -0
  66. data/application/js/spontaneous.js +6 -0
  67. data/application/js/state.js +64 -0
  68. data/application/js/status_bar.js +47 -0
  69. data/application/js/top_bar.js +368 -0
  70. data/application/js/types.js +98 -0
  71. data/application/js/upload.js +88 -0
  72. data/application/js/upload_manager.js +319 -0
  73. data/application/js/user.js +37 -0
  74. data/application/js/vendor/.DS_Store +0 -0
  75. data/application/js/vendor/JS.Class-2.1.5/CHANGELOG +283 -0
  76. data/application/js/vendor/JS.Class-2.1.5/MIT-LICENSE +30 -0
  77. data/application/js/vendor/JS.Class-2.1.5/README +30 -0
  78. data/application/js/vendor/JS.Class-2.1.5/min/command.js +1 -0
  79. data/application/js/vendor/JS.Class-2.1.5/min/comparable.js +1 -0
  80. data/application/js/vendor/JS.Class-2.1.5/min/constant_scope.js +1 -0
  81. data/application/js/vendor/JS.Class-2.1.5/min/core.js +1 -0
  82. data/application/js/vendor/JS.Class-2.1.5/min/decorator.js +1 -0
  83. data/application/js/vendor/JS.Class-2.1.5/min/enumerable.js +1 -0
  84. data/application/js/vendor/JS.Class-2.1.5/min/forwardable.js +1 -0
  85. data/application/js/vendor/JS.Class-2.1.5/min/hash.js +1 -0
  86. data/application/js/vendor/JS.Class-2.1.5/min/linked_list.js +1 -0
  87. data/application/js/vendor/JS.Class-2.1.5/min/loader.js +1 -0
  88. data/application/js/vendor/JS.Class-2.1.5/min/method_chain.js +1 -0
  89. data/application/js/vendor/JS.Class-2.1.5/min/observable.js +1 -0
  90. data/application/js/vendor/JS.Class-2.1.5/min/package.js +1 -0
  91. data/application/js/vendor/JS.Class-2.1.5/min/proxy.js +1 -0
  92. data/application/js/vendor/JS.Class-2.1.5/min/ruby.js +1 -0
  93. data/application/js/vendor/JS.Class-2.1.5/min/set.js +1 -0
  94. data/application/js/vendor/JS.Class-2.1.5/min/stack_trace.js +1 -0
  95. data/application/js/vendor/JS.Class-2.1.5/min/state.js +1 -0
  96. data/application/js/vendor/JS.Class-2.1.5/min/stdlib.js +16 -0
  97. data/application/js/vendor/JS.Class-2.1.5/src/command.js +93 -0
  98. data/application/js/vendor/JS.Class-2.1.5/src/comparable.js +37 -0
  99. data/application/js/vendor/JS.Class-2.1.5/src/constant_scope.js +48 -0
  100. data/application/js/vendor/JS.Class-2.1.5/src/core.js +1060 -0
  101. data/application/js/vendor/JS.Class-2.1.5/src/decorator.js +50 -0
  102. data/application/js/vendor/JS.Class-2.1.5/src/enumerable.js +505 -0
  103. data/application/js/vendor/JS.Class-2.1.5/src/forwardable.js +22 -0
  104. data/application/js/vendor/JS.Class-2.1.5/src/hash.js +334 -0
  105. data/application/js/vendor/JS.Class-2.1.5/src/linked_list.js +114 -0
  106. data/application/js/vendor/JS.Class-2.1.5/src/loader.js +553 -0
  107. data/application/js/vendor/JS.Class-2.1.5/src/method_chain.js +172 -0
  108. data/application/js/vendor/JS.Class-2.1.5/src/observable.js +55 -0
  109. data/application/js/vendor/JS.Class-2.1.5/src/package.js +472 -0
  110. data/application/js/vendor/JS.Class-2.1.5/src/proxy.js +58 -0
  111. data/application/js/vendor/JS.Class-2.1.5/src/ruby.js +44 -0
  112. data/application/js/vendor/JS.Class-2.1.5/src/set.js +332 -0
  113. data/application/js/vendor/JS.Class-2.1.5/src/stack_trace.js +151 -0
  114. data/application/js/vendor/JS.Class-2.1.5/src/state.js +95 -0
  115. data/application/js/vendor/JS.Class-2.1.5/src/stdlib.js +2612 -0
  116. data/application/js/vendor/crypto-2.3.0-crypto.js +160 -0
  117. data/application/js/vendor/crypto-2.3.0-sha1.js +91 -0
  118. data/application/js/vendor/diff_match_patch.js +2153 -0
  119. data/application/js/vendor/jquery-1.4.2.min.js +154 -0
  120. data/application/js/vendor/jquery-1.4.3.min.js +166 -0
  121. data/application/js/vendor/jquery-1.5.1.min.js +16 -0
  122. data/application/js/vendor/jquery-1.5.1rc1.min.js +24 -0
  123. data/application/js/vendor/jquery-1.6.2.min.js +18 -0
  124. data/application/js/vendor/jquery-ui-1.8.6.custom.min.js +265 -0
  125. data/application/js/vendor/jquery-ui-1.8.9.custom.min.js +415 -0
  126. data/application/js/vendor/jquery-ui-1.8.custom.min.js +106 -0
  127. data/application/js/vendor/jquery.hotkeys-0.7.9.js +248 -0
  128. data/application/js/vendor/jquery.hotkeys-0.7.9.min.js +19 -0
  129. data/application/js/vendor/jsdiff.js +169 -0
  130. data/application/js/views/box_view.js +229 -0
  131. data/application/js/views/page_piece_view.js +45 -0
  132. data/application/js/views/page_view.js +238 -0
  133. data/application/js/views/piece_view.js +178 -0
  134. data/application/js/views.js +110 -0
  135. data/application/static/editing-0-noise.png +0 -0
  136. data/application/static/editing-1-noise.png +0 -0
  137. data/application/static/editing-texture-1.png +0 -0
  138. data/application/static/editing-texture.png +0 -0
  139. data/application/static/editing-toolbar-shadow-bottom.png +0 -0
  140. data/application/static/editing-toolbar-shadow-top.png +0 -0
  141. data/application/static/favicon.ico +0 -0
  142. data/application/static/inner-glow.png +0 -0
  143. data/application/static/item-buttons.png +0 -0
  144. data/application/static/location-arrow.png +0 -0
  145. data/application/static/logo-400px-transparent.png +0 -0
  146. data/application/static/missing.png +0 -0
  147. data/application/static/orange-down-arrow.png +0 -0
  148. data/application/static/page-browser-next.png +0 -0
  149. data/application/static/paper-texture-dark.png +0 -0
  150. data/application/static/px.gif +0 -0
  151. data/application/static/select-arrow-root.png +0 -0
  152. data/application/static/select-arrow.png +0 -0
  153. data/application/static/slot-down-arrow.png +0 -0
  154. data/application/static/splash.png +0 -0
  155. data/application/static/spontaneous.png +0 -0
  156. data/application/static/spot.png +0 -0
  157. data/application/static/spot.svg +40 -0
  158. data/application/static/texture.png +0 -0
  159. data/application/views/index.erubis +46 -0
  160. data/application/views/login.erubis +69 -0
  161. data/application/views/schema_modification_error.html.erb +61 -0
  162. data/application/views/unsupported.erubis +23 -0
  163. data/bin/limit-upload +5 -0
  164. data/bin/spot +10 -0
  165. data/bin/unlimit-upload +3 -0
  166. data/config/nginx.conf +60 -0
  167. data/db/migrations/20100610142136_init.rb +66 -0
  168. data/db/migrations/20101130104334_timestamps.rb +44 -0
  169. data/db/migrations/20101202113205_site_publishing_flags.rb +12 -0
  170. data/db/migrations/20101206124543_aliases.rb +16 -0
  171. data/db/migrations/20110201133550_visibility.rb +27 -0
  172. data/db/migrations/20110209152710_users_and_groups.rb +58 -0
  173. data/db/migrations/20110215133910_boxes.rb +25 -0
  174. data/db/migrations/20110521114145_remove_slots_and_entries.rb +21 -0
  175. data/db/migrations/20110604192145_rename_schema_id_columns.rb +22 -0
  176. data/db/migrations/20110805141925_rename_site_to_state.rb +11 -0
  177. data/lib/cutaneous/context_helper.rb +82 -0
  178. data/lib/cutaneous/first_pass_parser.rb +23 -0
  179. data/lib/cutaneous/first_pass_renderer.rb +18 -0
  180. data/lib/cutaneous/parser_core.rb +18 -0
  181. data/lib/cutaneous/preview_context.rb +31 -0
  182. data/lib/cutaneous/preview_renderer.rb +15 -0
  183. data/lib/cutaneous/publish_context.rb +9 -0
  184. data/lib/cutaneous/renderer.rb +122 -0
  185. data/lib/cutaneous/request_context.rb +8 -0
  186. data/lib/cutaneous/second_pass_parser.rb +23 -0
  187. data/lib/cutaneous/second_pass_renderer.rb +18 -0
  188. data/lib/cutaneous.rb +47 -0
  189. data/lib/sequel/plugins/content_table_inheritance.rb +196 -0
  190. data/lib/sequel/plugins/yajl_serialization.rb +154 -0
  191. data/lib/spontaneous/application/feature.rb +9 -0
  192. data/lib/spontaneous/application/plugin.rb +13 -0
  193. data/lib/spontaneous/application.rb +8 -0
  194. data/lib/spontaneous/box.rb +232 -0
  195. data/lib/spontaneous/box_style.rb +64 -0
  196. data/lib/spontaneous/change.rb +107 -0
  197. data/lib/spontaneous/cli/adapter.rb +13 -0
  198. data/lib/spontaneous/cli/base.rb +184 -0
  199. data/lib/spontaneous/cli/console.rb +0 -0
  200. data/lib/spontaneous/cli/media.rb +13 -0
  201. data/lib/spontaneous/cli/server.rb +50 -0
  202. data/lib/spontaneous/cli/site.rb +46 -0
  203. data/lib/spontaneous/cli/sync.rb +42 -0
  204. data/lib/spontaneous/cli/tasks.rb +9 -0
  205. data/lib/spontaneous/cli.rb +83 -0
  206. data/lib/spontaneous/collections/box_set.rb +56 -0
  207. data/lib/spontaneous/collections/change_set.rb +43 -0
  208. data/lib/spontaneous/collections/entry_set.rb +83 -0
  209. data/lib/spontaneous/collections/field_set.rb +53 -0
  210. data/lib/spontaneous/collections/prototype_set.rb +131 -0
  211. data/lib/spontaneous/collections/style_set.rb +13 -0
  212. data/lib/spontaneous/config.rb +156 -0
  213. data/lib/spontaneous/constants.rb +24 -0
  214. data/lib/spontaneous/content.rb +113 -0
  215. data/lib/spontaneous/content_query.rb +17 -0
  216. data/lib/spontaneous/errors.rb +48 -0
  217. data/lib/spontaneous/extensions/array.rb +18 -0
  218. data/lib/spontaneous/extensions/class.rb +17 -0
  219. data/lib/spontaneous/extensions/hash.rb +18 -0
  220. data/lib/spontaneous/extensions/json.rb +26 -0
  221. data/lib/spontaneous/extensions/kernel.rb +7 -0
  222. data/lib/spontaneous/extensions/object.rb +30 -0
  223. data/lib/spontaneous/extensions/object_space.rb +12 -0
  224. data/lib/spontaneous/extensions/string.rb +44 -0
  225. data/lib/spontaneous/facet.rb +47 -0
  226. data/lib/spontaneous/field_types/date_field.rb +12 -0
  227. data/lib/spontaneous/field_types/field.rb +252 -0
  228. data/lib/spontaneous/field_types/image_field.rb +329 -0
  229. data/lib/spontaneous/field_types/markdown_field.rb +37 -0
  230. data/lib/spontaneous/field_types/string_field.rb +14 -0
  231. data/lib/spontaneous/field_types.rb +40 -0
  232. data/lib/spontaneous/generators/page/inline.html.cut +1 -0
  233. data/lib/spontaneous/generators/page/page.html.cut.tt +4 -0
  234. data/lib/spontaneous/generators/page/page.rb.tt +9 -0
  235. data/lib/spontaneous/generators/page.rb +38 -0
  236. data/lib/spontaneous/generators/site/.gitignore +4 -0
  237. data/lib/spontaneous/generators/site/Gemfile.tt +31 -0
  238. data/lib/spontaneous/generators/site/Rakefile.tt +6 -0
  239. data/lib/spontaneous/generators/site/config/back.ru +7 -0
  240. data/lib/spontaneous/generators/site/config/boot.rb +19 -0
  241. data/lib/spontaneous/generators/site/config/database.yml.tt +21 -0
  242. data/lib/spontaneous/generators/site/config/deploy.rb.tt +0 -0
  243. data/lib/spontaneous/generators/site/config/environment.rb.tt +8 -0
  244. data/lib/spontaneous/generators/site/config/environments/development.rb.tt +15 -0
  245. data/lib/spontaneous/generators/site/config/environments/production.rb.tt +5 -0
  246. data/lib/spontaneous/generators/site/config/front.ru +8 -0
  247. data/lib/spontaneous/generators/site/config/user_levels.yml +22 -0
  248. data/lib/spontaneous/generators/site/lib/site.rb.tt +4 -0
  249. data/lib/spontaneous/generators/site/lib/tasks/site.rake.tt +8 -0
  250. data/lib/spontaneous/generators/site/public/css/site.css +0 -0
  251. data/lib/spontaneous/generators/site/public/favicon.ico +0 -0
  252. data/lib/spontaneous/generators/site/public/js/.empty_directory +0 -0
  253. data/lib/spontaneous/generators/site/public/js/site.js +0 -0
  254. data/lib/spontaneous/generators/site/public/robots.txt +0 -0
  255. data/lib/spontaneous/generators/site/schema/.map +1 -0
  256. data/lib/spontaneous/generators/site/schema/page.rb.tt +8 -0
  257. data/lib/spontaneous/generators/site/schema/piece.rb.tt +4 -0
  258. data/lib/spontaneous/generators/site/templates/layouts/standard.html.cut.tt +13 -0
  259. data/lib/spontaneous/generators/site.rb +77 -0
  260. data/lib/spontaneous/generators.rb +23 -0
  261. data/lib/spontaneous/image_size.rb +117 -0
  262. data/lib/spontaneous/json.rb +33 -0
  263. data/lib/spontaneous/layout.rb +15 -0
  264. data/lib/spontaneous/loader.rb +280 -0
  265. data/lib/spontaneous/logger.rb +369 -0
  266. data/lib/spontaneous/media.rb +84 -0
  267. data/lib/spontaneous/page.rb +92 -0
  268. data/lib/spontaneous/page_controller.rb +18 -0
  269. data/lib/spontaneous/page_piece.rb +77 -0
  270. data/lib/spontaneous/paths.rb +30 -0
  271. data/lib/spontaneous/permissions/access_group.rb +50 -0
  272. data/lib/spontaneous/permissions/access_key.rb +35 -0
  273. data/lib/spontaneous/permissions/user.rb +167 -0
  274. data/lib/spontaneous/permissions/user_level.rb +177 -0
  275. data/lib/spontaneous/permissions.rb +55 -0
  276. data/lib/spontaneous/piece.rb +30 -0
  277. data/lib/spontaneous/plugins/aliases.rb +128 -0
  278. data/lib/spontaneous/plugins/allowed_types.rb +173 -0
  279. data/lib/spontaneous/plugins/application/facets.rb +25 -0
  280. data/lib/spontaneous/plugins/application/paths.rb +137 -0
  281. data/lib/spontaneous/plugins/application/render.rb +29 -0
  282. data/lib/spontaneous/plugins/application/serialisation.rb +16 -0
  283. data/lib/spontaneous/plugins/application/state.rb +86 -0
  284. data/lib/spontaneous/plugins/boxes.rb +84 -0
  285. data/lib/spontaneous/plugins/controllers.rb +52 -0
  286. data/lib/spontaneous/plugins/entries.rb +193 -0
  287. data/lib/spontaneous/plugins/entry.rb +51 -0
  288. data/lib/spontaneous/plugins/fields.rb +103 -0
  289. data/lib/spontaneous/plugins/instance_code.rb +18 -0
  290. data/lib/spontaneous/plugins/layouts.rb +87 -0
  291. data/lib/spontaneous/plugins/media.rb +41 -0
  292. data/lib/spontaneous/plugins/page/formats.rb +67 -0
  293. data/lib/spontaneous/plugins/page/request.rb +89 -0
  294. data/lib/spontaneous/plugins/page_search.rb +64 -0
  295. data/lib/spontaneous/plugins/page_tree.rb +25 -0
  296. data/lib/spontaneous/plugins/paths.rb +125 -0
  297. data/lib/spontaneous/plugins/permissions.rb +63 -0
  298. data/lib/spontaneous/plugins/prototypes.rb +84 -0
  299. data/lib/spontaneous/plugins/publishing.rb +255 -0
  300. data/lib/spontaneous/plugins/render.rb +24 -0
  301. data/lib/spontaneous/plugins/schema_hierarchy.rb +76 -0
  302. data/lib/spontaneous/plugins/schema_id.rb +60 -0
  303. data/lib/spontaneous/plugins/schema_title.rb +33 -0
  304. data/lib/spontaneous/plugins/serialisation.rb +67 -0
  305. data/lib/spontaneous/plugins/site/instance.rb +22 -0
  306. data/lib/spontaneous/plugins/site/map.rb +19 -0
  307. data/lib/spontaneous/plugins/site/publishing.rb +74 -0
  308. data/lib/spontaneous/plugins/site/revisions.rb +28 -0
  309. data/lib/spontaneous/plugins/site/selectors.rb +41 -0
  310. data/lib/spontaneous/plugins/site_map.rb +34 -0
  311. data/lib/spontaneous/plugins/styles.rb +119 -0
  312. data/lib/spontaneous/plugins/supertype.rb +11 -0
  313. data/lib/spontaneous/plugins/visibility.rb +151 -0
  314. data/lib/spontaneous/plugins.rb +20 -0
  315. data/lib/spontaneous/prototypes/box_prototype.rb +168 -0
  316. data/lib/spontaneous/prototypes/field_prototype.rb +112 -0
  317. data/lib/spontaneous/prototypes/layout_prototype.rb +17 -0
  318. data/lib/spontaneous/prototypes/style_prototype.rb +42 -0
  319. data/lib/spontaneous/proxy_object.rb +12 -0
  320. data/lib/spontaneous/publishing/fire_and_forget.rb +57 -0
  321. data/lib/spontaneous/publishing/immediate.rb +197 -0
  322. data/lib/spontaneous/publishing/threaded.rb +25 -0
  323. data/lib/spontaneous/publishing.rb +10 -0
  324. data/lib/spontaneous/rack/around_back.rb +44 -0
  325. data/lib/spontaneous/rack/around_front.rb +29 -0
  326. data/lib/spontaneous/rack/around_preview.rb +26 -0
  327. data/lib/spontaneous/rack/assets.rb +98 -0
  328. data/lib/spontaneous/rack/back.rb +729 -0
  329. data/lib/spontaneous/rack/front.rb +41 -0
  330. data/lib/spontaneous/rack/http.rb +18 -0
  331. data/lib/spontaneous/rack/media.rb +29 -0
  332. data/lib/spontaneous/rack/public.rb +232 -0
  333. data/lib/spontaneous/rack/reloader.rb +42 -0
  334. data/lib/spontaneous/rack/static.rb +25 -0
  335. data/lib/spontaneous/rack.rb +55 -0
  336. data/lib/spontaneous/render/context.rb +100 -0
  337. data/lib/spontaneous/render/development_renderer.rb +14 -0
  338. data/lib/spontaneous/render/engine.rb +19 -0
  339. data/lib/spontaneous/render/format/html.rb +5 -0
  340. data/lib/spontaneous/render/format.rb +70 -0
  341. data/lib/spontaneous/render/preview_renderer.rb +18 -0
  342. data/lib/spontaneous/render/published_renderer.rb +54 -0
  343. data/lib/spontaneous/render/publishing_renderer.rb +13 -0
  344. data/lib/spontaneous/render/renderer.rb +46 -0
  345. data/lib/spontaneous/render.rb +173 -0
  346. data/lib/spontaneous/revision.rb +7 -0
  347. data/lib/spontaneous/schema/schema_modification.rb +260 -0
  348. data/lib/spontaneous/schema/uid.rb +221 -0
  349. data/lib/spontaneous/schema.rb +295 -0
  350. data/lib/spontaneous/server.rb +65 -0
  351. data/lib/spontaneous/site.rb +87 -0
  352. data/lib/spontaneous/state.rb +53 -0
  353. data/lib/spontaneous/style.rb +144 -0
  354. data/lib/spontaneous/tasks/database.rake +9 -0
  355. data/lib/spontaneous/tasks.rb +5 -0
  356. data/lib/spontaneous/version.rb +6 -0
  357. data/lib/spontaneous.rb +179 -0
  358. data/spontaneous.gemspec.tmpl +66 -0
  359. data/test/disabled/test_slots.rb +287 -0
  360. data/test/experimental/test_formats.rb +92 -0
  361. data/test/experimental/test_plugins.rb +64 -0
  362. data/test/fixtures/application/css/test.less +5 -0
  363. data/test/fixtures/application/js/test.js +1 -0
  364. data/test/fixtures/application/static/favicon.ico +1 -0
  365. data/test/fixtures/application/static/test.html +1 -0
  366. data/test/fixtures/application/views/index.erubis +1 -0
  367. data/test/fixtures/back/public/test.html +1 -0
  368. data/test/fixtures/back/templates/layouts/standard.html.cut +1 -0
  369. data/test/fixtures/config/config/environment.rb +4 -0
  370. data/test/fixtures/config/config/environments/development.rb +13 -0
  371. data/test/fixtures/config/config/environments/production.rb +22 -0
  372. data/test/fixtures/config/config/environments/staging.rb +2 -0
  373. data/test/fixtures/example_application/Gemfile +6 -0
  374. data/test/fixtures/example_application/Gemfile.lock +76 -0
  375. data/test/fixtures/example_application/Rakefile +6 -0
  376. data/test/fixtures/example_application/config/back.rb +15 -0
  377. data/test/fixtures/example_application/config/back.ru +8 -0
  378. data/test/fixtures/example_application/config/back.yml +8 -0
  379. data/test/fixtures/example_application/config/boot.rb +16 -0
  380. data/test/fixtures/example_application/config/database.yml +24 -0
  381. data/test/fixtures/example_application/config/environment.rb +4 -0
  382. data/test/fixtures/example_application/config/environments/development.rb +16 -0
  383. data/test/fixtures/example_application/config/environments/production.rb +21 -0
  384. data/test/fixtures/example_application/config/environments/staging.rb +1 -0
  385. data/test/fixtures/example_application/config/front.rb +8 -0
  386. data/test/fixtures/example_application/config/front.ru +8 -0
  387. data/test/fixtures/example_application/config/front.yml +8 -0
  388. data/test/fixtures/example_application/config/schema.yml +48 -0
  389. data/test/fixtures/example_application/config/unicorn.rb +1 -0
  390. data/test/fixtures/example_application/config/user_levels.yml +19 -0
  391. data/test/fixtures/example_application/public/css/test.css +0 -0
  392. data/test/fixtures/example_application/public/favicon.ico +1 -0
  393. data/test/fixtures/example_application/public/js/test.js +0 -0
  394. data/test/fixtures/example_application/public/test.html +1 -0
  395. data/test/fixtures/example_application/schema/client_project.rb +18 -0
  396. data/test/fixtures/example_application/schema/client_projects.rb +8 -0
  397. data/test/fixtures/example_application/schema/home_page.rb +22 -0
  398. data/test/fixtures/example_application/schema/info_page.rb +13 -0
  399. data/test/fixtures/example_application/schema/inline_image.rb +11 -0
  400. data/test/fixtures/example_application/schema/page.rb +4 -0
  401. data/test/fixtures/example_application/schema/piece.rb +3 -0
  402. data/test/fixtures/example_application/schema/project.rb +21 -0
  403. data/test/fixtures/example_application/schema/project_image.rb +18 -0
  404. data/test/fixtures/example_application/schema/projects_page.rb +12 -0
  405. data/test/fixtures/example_application/schema/text.rb +8 -0
  406. data/test/fixtures/example_application/templates/client_project/images.html.cut +1 -0
  407. data/test/fixtures/example_application/templates/client_project.html.cut +4 -0
  408. data/test/fixtures/example_application/templates/client_projects.html.cut +6 -0
  409. data/test/fixtures/example_application/templates/info_page/inline.html.cut +0 -0
  410. data/test/fixtures/example_application/templates/inline_image.html.cut +1 -0
  411. data/test/fixtures/example_application/templates/layouts/home.html.cut +15 -0
  412. data/test/fixtures/example_application/templates/layouts/info.html.cut +3 -0
  413. data/test/fixtures/example_application/templates/layouts/project.html.cut +13 -0
  414. data/test/fixtures/example_application/templates/layouts/projects.html.cut +11 -0
  415. data/test/fixtures/example_application/templates/layouts/standard.html.cut +0 -0
  416. data/test/fixtures/example_application/templates/project/inline.html.cut +5 -0
  417. data/test/fixtures/example_application/templates/project.html.cut +5 -0
  418. data/test/fixtures/example_application/templates/project_image.html.cut +1 -0
  419. data/test/fixtures/example_application/templates/text.html.cut +1 -0
  420. data/test/fixtures/images/rose.greyscale.jpg +0 -0
  421. data/test/fixtures/images/rose.jpg +0 -0
  422. data/test/fixtures/images/size.gif +0 -0
  423. data/test/fixtures/images/size.jpg +0 -0
  424. data/test/fixtures/images/size.png24 +0 -0
  425. data/test/fixtures/images/size.png8 +0 -0
  426. data/test/fixtures/layouts/layouts/custom1.html.cut +1 -0
  427. data/test/fixtures/layouts/layouts/custom1.pdf.cut +0 -0
  428. data/test/fixtures/layouts/layouts/custom1.xml.cut +0 -0
  429. data/test/fixtures/layouts/layouts/custom2.html.cut +1 -0
  430. data/test/fixtures/layouts/layouts/custom3.html.cut +0 -0
  431. data/test/fixtures/layouts/layouts/standard.html.cut +1 -0
  432. data/test/fixtures/media/101/003/rose.jpg +0 -0
  433. data/test/fixtures/permissions/config/user_levels.yml +9 -0
  434. data/test/fixtures/permissions/media/image.jpg +0 -0
  435. data/test/fixtures/plugins/schema_plugin/init.rb +1 -0
  436. data/test/fixtures/plugins/schema_plugin/schema/external.rb +5 -0
  437. data/test/fixtures/plugins/schema_plugin/templates/external.html.cut +1 -0
  438. data/test/fixtures/plugins/schema_plugin/templates/from_plugin.html.cut +0 -0
  439. data/test/fixtures/plugins/schema_plugin/templates/layouts/from_plugin.html.cut +0 -0
  440. data/test/fixtures/public/templates/layouts/default.html.cut +1 -0
  441. data/test/fixtures/public/templates/layouts/default.pdf.cut +1 -0
  442. data/test/fixtures/public/templates/layouts/default.rss.cut +1 -0
  443. data/test/fixtures/public/templates/layouts/dynamic.html.cut +1 -0
  444. data/test/fixtures/public/templates/layouts/standard.html.cut +0 -0
  445. data/test/fixtures/schema/before.yml +24 -0
  446. data/test/fixtures/schema/resolvable.yml +12 -0
  447. data/test/fixtures/schema/schema.yml +7 -0
  448. data/test/fixtures/serialisation/class_hash.yaml.erb +53 -0
  449. data/test/fixtures/serialisation/root_hash.yaml.erb +184 -0
  450. data/test/fixtures/sharding/rose.jpg +0 -0
  451. data/test/fixtures/sharding/xaa +0 -0
  452. data/test/fixtures/sharding/xab +0 -0
  453. data/test/fixtures/sharding/xac +0 -0
  454. data/test/fixtures/sharding/xad +0 -0
  455. data/test/fixtures/sharding/xae +0 -0
  456. data/test/fixtures/sharding/xaf +0 -0
  457. data/test/fixtures/sharding/xag +0 -0
  458. data/test/fixtures/styles/box_a/runny.html.cut +0 -0
  459. data/test/fixtures/styles/box_a.html.cut +1 -0
  460. data/test/fixtures/styles/named2.html.cut +1 -0
  461. data/test/fixtures/styles/orange/apple.html.cut +1 -0
  462. data/test/fixtures/styles/template_class/named1.html.cut +1 -0
  463. data/test/fixtures/styles/template_class/results.html.cut +1 -0
  464. data/test/fixtures/styles/template_class/walky.html.cut +0 -0
  465. data/test/fixtures/styles/template_class.epub.cut +0 -0
  466. data/test/fixtures/styles/template_class.html.cut +1 -0
  467. data/test/fixtures/styles/template_class.pdf.cut +0 -0
  468. data/test/fixtures/styles/template_sub_class1.html.cut +1 -0
  469. data/test/fixtures/templates/aliases/a/a_style.html.cut +0 -0
  470. data/test/fixtures/templates/aliases/a/page.html.cut +0 -0
  471. data/test/fixtures/templates/aliases/a_alias/a_alias_style.html.cut +0 -0
  472. data/test/fixtures/templates/aliases/layouts/b.html.cut +1 -0
  473. data/test/fixtures/templates/aliases/layouts/b_alias.html.cut +1 -0
  474. data/test/fixtures/templates/aliases/layouts/c_alias.html.cut +1 -0
  475. data/test/fixtures/templates/boxes/blank_content/things.html.cut +1 -0
  476. data/test/fixtures/templates/boxes/my_box_class/christy.html.cut +1 -0
  477. data/test/fixtures/templates/boxes/thangs.html.cut +1 -0
  478. data/test/fixtures/templates/boxes/with_template_box.html.cut +1 -0
  479. data/test/fixtures/templates/content/include.html.cut +1 -0
  480. data/test/fixtures/templates/content/include_dir.html.cut +1 -0
  481. data/test/fixtures/templates/content/included.epub.cut +1 -0
  482. data/test/fixtures/templates/content/included.html.cut +1 -0
  483. data/test/fixtures/templates/content/partial/included.html.cut +1 -0
  484. data/test/fixtures/templates/content/preprocess.html.cut +1 -0
  485. data/test/fixtures/templates/content/second.html.cut +1 -0
  486. data/test/fixtures/templates/content/template.epub.cut +1 -0
  487. data/test/fixtures/templates/content/template.html.cut +1 -0
  488. data/test/fixtures/templates/default_style_class.html.cut +1 -0
  489. data/test/fixtures/templates/direct.html.cut +1 -0
  490. data/test/fixtures/templates/extended/grandparent.html.cut +10 -0
  491. data/test/fixtures/templates/extended/main.html.cut +6 -0
  492. data/test/fixtures/templates/extended/parent.html.cut +10 -0
  493. data/test/fixtures/templates/layouts/entries.html.cut +7 -0
  494. data/test/fixtures/templates/layouts/page_style.html.cut +1 -0
  495. data/test/fixtures/templates/layouts/params.html.cut +1 -0
  496. data/test/fixtures/templates/layouts/preview_render.html.cut +2 -0
  497. data/test/fixtures/templates/layouts/standard_page.html.cut +1 -0
  498. data/test/fixtures/templates/layouts/subdir_style.html.cut +1 -0
  499. data/test/fixtures/templates/layouts/template_params.html.cut +1 -0
  500. data/test/fixtures/templates/page_class/inline_style.html.cut +1 -0
  501. data/test/fixtures/templates/preview_render/inline.html.cut +0 -0
  502. data/test/fixtures/templates/publishing/layouts/dynamic.html.cut +1 -0
  503. data/test/fixtures/templates/publishing/layouts/static.html.cut +1 -0
  504. data/test/fixtures/templates/template_class/anonymous_style.html.cut +4 -0
  505. data/test/fixtures/templates/template_class/another_template.html.cut +0 -0
  506. data/test/fixtures/templates/template_class/complex_template.html.cut +6 -0
  507. data/test/fixtures/templates/template_class/complex_template.pdf.cut +6 -0
  508. data/test/fixtures/templates/template_class/default_template_style.html.cut +4 -0
  509. data/test/fixtures/templates/template_class/images_with_template.html.cut +5 -0
  510. data/test/fixtures/templates/template_class/slots_template.html.cut +5 -0
  511. data/test/fixtures/templates/template_class/slots_template.pdf.cut +5 -0
  512. data/test/fixtures/templates/template_class/this_template.epub.cut +1 -0
  513. data/test/fixtures/templates/template_class/this_template.html.cut +1 -0
  514. data/test/fixtures/templates/template_class/this_template.pdf.cut +1 -0
  515. data/test/fixtures/templates/with_default_style_class.html.cut +1 -0
  516. data/test/functional/test_application.rb +176 -0
  517. data/test/functional/test_back.rb +902 -0
  518. data/test/functional/test_front.rb +571 -0
  519. data/test/javascript/test_dom.rb +94 -0
  520. data/test/javascript/test_markdown.rb +97 -0
  521. data/test/slow/test_publishing.rb +987 -0
  522. data/test/slow/test_visibility.rb +250 -0
  523. data/test/support/custom_matchers.rb +77 -0
  524. data/test/support/timing.rb +23 -0
  525. data/test/test_helper.rb +164 -0
  526. data/test/test_javascript.rb +34 -0
  527. data/test/ui/test_page_editing.rb +167 -0
  528. data/test/ui_helper.rb +114 -0
  529. data/test/unit/test_alias.rb +254 -0
  530. data/test/unit/test_authentication.rb +510 -0
  531. data/test/unit/test_boxes.rb +497 -0
  532. data/test/unit/test_config.rb +156 -0
  533. data/test/unit/test_content.rb +221 -0
  534. data/test/unit/test_content_inheritance.rb +103 -0
  535. data/test/unit/test_extensions.rb +14 -0
  536. data/test/unit/test_fields.rb +392 -0
  537. data/test/unit/test_generators.rb +97 -0
  538. data/test/unit/test_image_size.rb +25 -0
  539. data/test/unit/test_images.rb +265 -0
  540. data/test/unit/test_layouts.rb +111 -0
  541. data/test/unit/test_logger.rb +80 -0
  542. data/test/unit/test_media.rb +70 -0
  543. data/test/unit/test_page.rb +244 -0
  544. data/test/unit/test_permissions.rb +834 -0
  545. data/test/unit/test_piece.rb +80 -0
  546. data/test/unit/test_prototype_set.rb +192 -0
  547. data/test/unit/test_prototypes.rb +102 -0
  548. data/test/unit/test_render.rb +359 -0
  549. data/test/unit/test_schema.rb +1009 -0
  550. data/test/unit/test_serialisation.rb +215 -0
  551. data/test/unit/test_site.rb +145 -0
  552. data/test/unit/test_structure.rb +85 -0
  553. data/test/unit/test_styles.rb +417 -0
  554. data/test/unit/test_templates.rb +224 -0
  555. data/test/unit/test_type_hierarchy.rb +28 -0
  556. metadata +1017 -0
@@ -0,0 +1,41 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'sinatra/base'
4
+
5
+ module Spontaneous
6
+ module Rack
7
+ module Front
8
+ def self.application
9
+ app = ::Rack::Builder.new do
10
+ # use ::Rack::CommonLogger, STDERR #unless server.name =~ /CGI/
11
+ # use ::Rack::ShowExceptions
12
+
13
+ use Spontaneous::Rack::Static, :root => Spontaneous.root / "public",
14
+ :urls => %w[/],
15
+ :try => ['.html', 'index.html', '/index.html']
16
+
17
+ map "/media" do
18
+ run Spontaneous::Rack::Media.new
19
+ end
20
+
21
+ map "/" do
22
+ use AroundFront
23
+ use Reloader if Site.config.reload_classes
24
+ run Server.new
25
+ end
26
+ end
27
+ end
28
+ class Server# < Spontaneous::Rack::Public
29
+ include Spontaneous::Rack::Public
30
+
31
+ def call(env)
32
+ @response = ::Rack::Response.new
33
+ @request = ::Rack::Request.new(env)
34
+ render_path(@request.path_info)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+
@@ -0,0 +1,18 @@
1
+ # encoding: UTF-8
2
+
3
+
4
+ module Spontaneous
5
+ module Rack
6
+ module HTTP
7
+ METHOD_GET = "GET".freeze
8
+ METHOD_POST = "POST".freeze
9
+ METHOD_HEAD = "HEAD".freeze
10
+ HTTP_CONTENT_LENGTH = "Content-Length".freeze
11
+ HTTP_EXPIRES = "Expires".freeze
12
+ HTTP_CACHE_CONTROL = "Cache-Control".freeze
13
+ HTTP_LAST_MODIFIED = "Last-Modified".freeze
14
+ HTTP_NO_CACHE = "max-age=0, must-revalidate, no-cache, no-store".freeze
15
+ end
16
+ end
17
+ end
18
+
@@ -0,0 +1,29 @@
1
+
2
+ module Spontaneous
3
+ module Rack
4
+ class Media < ::Rack::File
5
+ include HTTP
6
+
7
+ TEN_YEARS = 10*365*24*3600
8
+ MAX_AGE = "max-age=#{TEN_YEARS}, public".freeze
9
+
10
+ def initialize
11
+ super(Spontaneous.media_dir, 'public')
12
+ end
13
+
14
+ def call(env)
15
+ status, headers, body = super
16
+ [status, caching_headers(headers), body]
17
+ end
18
+
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
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,232 @@
1
+ # encoding: UTF-8
2
+
3
+
4
+ module Spontaneous
5
+ module Rack
6
+ module Public
7
+ include HTTP
8
+ include Sinatra::Helpers unless method_defined?(:redirect)
9
+
10
+
11
+ attr_reader :response, :request
12
+ attr_accessor :page
13
+
14
+ def render_path(path)
15
+ find_page!(path)
16
+
17
+ response = catch(:halt) do
18
+ if @page
19
+ case @request.request_method
20
+ when METHOD_GET
21
+ render_get
22
+ else
23
+ render_post
24
+ end
25
+ else
26
+ not_found!
27
+ end
28
+ end
29
+
30
+ parse_response(response)
31
+ status, header, body = @response.finish
32
+
33
+ # Never produce a body on HEAD requests. Do retain the Content-Length
34
+ # unless it's "0", in which case we assume it was calculated erroneously
35
+ # for a manual HEAD response and remove it entirely.
36
+ if request.request_method == METHOD_HEAD
37
+ body = []
38
+ header.delete(HTTP_CONTENT_LENGTH) if header[HTTP_CONTENT_LENGTH] == '0'
39
+ end
40
+
41
+ [status, header, body]
42
+ end
43
+
44
+ def halt(*response)
45
+ response = response.first if response.length == 1
46
+ throw :halt, response
47
+ end
48
+
49
+
50
+
51
+ # stolen from Sinatra
52
+ def parse_response(response)
53
+ case
54
+ when response.respond_to?(:spontaneous_content?)
55
+ @page = response
56
+ when response.respond_to?(:to_str)
57
+ @response.body = [response]
58
+ when response.respond_to?(:to_ary)
59
+ response = response.to_ary
60
+ if Fixnum === response.first
61
+ if response.length == 3
62
+ @response.status, headers, body = response
63
+ @response.body = body if body
64
+ headers.each { |k, v| @response.headers[k] = v } if headers
65
+ elsif response.length == 2
66
+ @response.status = response.first
67
+ @response.body = response.last
68
+ else
69
+ raise TypeError, "#{response.inspect} not supported"
70
+ end
71
+ else
72
+ @response.body = response
73
+ end
74
+ when response.respond_to?(:each)
75
+ @response.body = response
76
+ when (100..599) === response
77
+ @response.status = response
78
+ end
79
+ end
80
+
81
+ DOT = '.'.freeze
82
+ ACTION = "/#{S::Plugins::Controllers::ACTION_SEPARATOR}".freeze
83
+
84
+ def show(page, status=200)
85
+ page = Spontaneous::Site[page] if String === page
86
+ @page = page
87
+ status(status)
88
+ end
89
+
90
+ REDIRECTS = {
91
+ :permanent => 301,
92
+ :temporary => 302
93
+ }
94
+
95
+ def redirect(location, redirect_code=:temporary)
96
+ if String === location
97
+ destination = Site[location]
98
+ location = destination.path if destination and destination.respond_to?(:path)
99
+ else
100
+ location = location.path if location.respond_to?(:path)
101
+ end
102
+ redirect_code = REDIRECTS[redirect_code] if Symbol === redirect_code
103
+ redirect_code ||= REDIRECTS[:temporary]
104
+ # let Sinatra's helper method set up the proper Location headers for us
105
+ catch(:halt) { super(location) }
106
+ status(redirect_code)
107
+ # then re-throw the :halt
108
+ halt
109
+ end
110
+
111
+ def content_type(type, params={})
112
+ default = params.delete :default
113
+ mime_type = mime_type(type) || default
114
+ fail "Unknown media type: %p" % type if mime_type.nil?
115
+ mime_type = mime_type.dup
116
+ unless params.include? :charset
117
+ params[:charset] = params.delete('charset') || ::Spontaneous.config.default_charset || 'utf-8'
118
+ end
119
+ mime_type << ";#{params.map { |kv| kv.join('=') }.join(', ')}" unless params.empty?
120
+ response['Content-Type'] = mime_type
121
+ end
122
+
123
+ def find_page!(path)
124
+ @path, @format, @action = parse_path(path)
125
+ @page = Site[@path]
126
+ end
127
+
128
+ def format
129
+ @format
130
+ end
131
+
132
+ def action
133
+ @action
134
+ end
135
+
136
+ def render_get
137
+ # return not_found! unless @page
138
+
139
+ @format = (@format || @page.default_format).to_sym if @page
140
+
141
+ if @action
142
+ call_action!
143
+ else
144
+ block = page.request_block(request)
145
+ parse_response(instance_eval(&block)) if (block)
146
+
147
+ @format = (@format || @page.default_format).to_sym if @page
148
+ render_page_with_format(@page, @format)
149
+ end
150
+ end
151
+
152
+ # non-action urls shouldn't respond to post requests
153
+ def render_post
154
+ # return not_found! unless @page
155
+
156
+ block = page.request_block(request)
157
+ return not_found! unless (block or @action)
158
+
159
+ if @action
160
+ call_action!
161
+ else
162
+ parse_response(instance_eval(&block)) if (block)
163
+
164
+ @format = (@format || @page.default_format).to_sym if @page
165
+ render_page_with_format(@page, @format)
166
+ end
167
+ end
168
+
169
+ def call_action!
170
+ # get
171
+ status, headers, result = @page.process_action(action, request.env, format)
172
+ # our 404 page should come from the CMS
173
+ if status == 404
174
+ not_found!
175
+ else
176
+ if result.respond_to?(:spontaneous_content?)
177
+ render_page_with_format(result, format)
178
+ else
179
+ [status, headers, result]
180
+ end
181
+ end
182
+ end
183
+
184
+ def parse_path(path)
185
+ if path =~ %r(#{ACTION})
186
+ path, action = path.split(ACTION)
187
+ action, format = action.split(DOT)
188
+ else
189
+ path, format = path.split(DOT)
190
+ end
191
+ # format = (format || :html).to_sym
192
+ [path, format, action]
193
+ end
194
+
195
+ def render_page_with_format(page, format)
196
+ if page && page.provides_format?(format)
197
+ content_type(page.mime_type(format))
198
+ render_page(page, format)
199
+ else
200
+ # perhaps we should return the html version if the page exists but
201
+ # doesn't respond to the requested format?
202
+ # or even redirect to the html?
203
+ not_found!
204
+ end
205
+ end
206
+
207
+ def render_page(page, format = :html, local_params = {})
208
+ response.body = page.render(format, local_params.merge({
209
+ :params => request.params,
210
+ :request => request,
211
+ :session => request.session
212
+ }))
213
+ end
214
+
215
+ # def redirect?(page)
216
+ # redirection, redirect_code = page.request_redirect(request.params, request, request.session)
217
+ # if redirection
218
+ # redirection = redirection.path if redirection.respond_to?(:path)
219
+ # redirect_code = REDIRECTS[redirect_code] if Symbol === redirect_code
220
+ # redirect_code ||= REDIRECTS[:temporary]
221
+ # [redirection.to_s, redirect_code]
222
+ # else
223
+ # nil
224
+ # end
225
+ # end
226
+
227
+ def not_found!
228
+ 404
229
+ end
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'stringio'
4
+ require 'erubis'
5
+ require 'tilt'
6
+
7
+ module Spontaneous
8
+ module Rack
9
+ class Reloader
10
+ def initialize(app)
11
+ @app = app
12
+ @cooldown = 3
13
+ @last = (Time.now - @cooldown)
14
+ end
15
+
16
+
17
+ def call(env)
18
+ if @cooldown and Time.now > @last + @cooldown
19
+ if Thread.list.size > 1
20
+ Thread.exclusive{ reload! }
21
+ else
22
+ reload!
23
+ end
24
+
25
+ @last = Time.now
26
+ end
27
+
28
+ @app.call(env)
29
+ rescue Spontaneous::SchemaModificationError => error
30
+ template = Tilt::ErubisTemplate.new(File.expand_path('../../../../application/views/schema_modification_error.html.erb', __FILE__))
31
+ html = template.render(error.modification, :env => env)
32
+ [412, {'Content-type' => ::Rack::Mime.mime_type('.html')}, StringIO.new(html)].tap do |response|
33
+ end
34
+ end
35
+
36
+ def reload!
37
+ Spontaneous.reload!
38
+ end
39
+ end # Reloader
40
+ end # Rack
41
+ end # Spontaneous
42
+
@@ -0,0 +1,25 @@
1
+
2
+ module Spontaneous
3
+ module Rack
4
+ class Static
5
+ def initialize(app, options)
6
+ @app = app
7
+ @try = ['', *options.delete(:try)].compact
8
+ @static = ::Rack::Static.new(
9
+ lambda { |env| [404, {}, []] },
10
+ options)
11
+ end
12
+
13
+ def call(env)
14
+ orig_path = env['PATH_INFO']
15
+ found = nil
16
+ @try.each do |path|
17
+ resp = @static.call(env.merge!({'PATH_INFO' => orig_path + path}))
18
+ break if 404 != resp[0] && found = resp
19
+ end
20
+ found or @app.call(env.merge!('PATH_INFO' => orig_path))
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,55 @@
1
+ # encoding: UTF-8
2
+
3
+ require "rack"
4
+ # require "sinatra"
5
+ require 'sinatra/base'
6
+
7
+ module Spontaneous
8
+ module Rack
9
+ class << self
10
+ def application
11
+ case Spontaneous.mode
12
+ when :back
13
+ Back.application
14
+ when :front
15
+ Front.application
16
+ end
17
+ end
18
+
19
+ def port
20
+ Site.config.port
21
+ end
22
+ end
23
+
24
+ class ServerBase < ::Sinatra::Base
25
+ set :environment, Proc.new { Spontaneous.environment }
26
+
27
+ # serve static files from the app's public dir
28
+
29
+ ## removed these as sinatra now sets utf-8 by default
30
+ # mime_type :js, 'text/javascript; charset=utf-8'
31
+ # mime_type :css, 'text/css; charset=utf-8'
32
+
33
+ # before do
34
+ # ## globally setting this screws up auto content type setting by send_file
35
+ # # content_type 'text/html', :charset => 'utf-8'
36
+ # if Spontaneous.development?
37
+ # # Templates.clear_cache!
38
+ # end
39
+ # end
40
+ end
41
+
42
+ autoload :HTTP, 'spontaneous/rack/http'
43
+ autoload :Assets, 'spontaneous/rack/assets'
44
+ autoload :Back, 'spontaneous/rack/back'
45
+ autoload :Front, 'spontaneous/rack/front'
46
+ autoload :Public, 'spontaneous/rack/public'
47
+ autoload :Media, 'spontaneous/rack/media'
48
+ autoload :Static, 'spontaneous/rack/static'
49
+ autoload :AroundBack, 'spontaneous/rack/around_back'
50
+ autoload :AroundFront, 'spontaneous/rack/around_front'
51
+ autoload :AroundPreview, 'spontaneous/rack/around_preview'
52
+ autoload :Reloader, 'spontaneous/rack/reloader'
53
+ end
54
+ end
55
+
@@ -0,0 +1,100 @@
1
+ # encoding: UTF-8
2
+
3
+
4
+ module Spontaneous::Render
5
+ module Context
6
+
7
+ attr_reader :format, :target
8
+
9
+ def initialize(target, format, params={})
10
+ @target, @format, @params = target, format, params
11
+ _update(params) if params.is_a?(Hash)
12
+ end
13
+
14
+ def page
15
+ target.page
16
+ end
17
+
18
+ def template
19
+ target.template(format)
20
+ end
21
+
22
+ def each
23
+ content.each { |c| yield(c) } if block_given?
24
+ end
25
+
26
+ def each_with_index
27
+ content.each_with_index { |c, i| yield(c, i) } if block_given?
28
+ end
29
+
30
+ def map
31
+ content.map { |c| yield(c) } if block_given?
32
+ end
33
+
34
+ def content
35
+ target.iterable
36
+ end
37
+
38
+ def pieces
39
+ content
40
+ end
41
+
42
+ def first
43
+ content.first
44
+ end
45
+
46
+ def last
47
+ content.last
48
+ end
49
+
50
+ def first?
51
+ target.container.pieces.first == self
52
+ end
53
+
54
+ def last?
55
+ target.container.pieces.last == self
56
+ end
57
+
58
+ def render_content
59
+ target.map do |c|
60
+ c.render(format)
61
+ end.join("\n")
62
+ end
63
+
64
+ def render(format, *args)
65
+ target.render(format, *args)
66
+ end
67
+
68
+ def respond_to?(method)
69
+ super || target.respond_to?(method)
70
+ end
71
+
72
+ protected
73
+
74
+ def method_missing(method, *args)
75
+ if block_given?
76
+ target.__send__(method, *args, &Proc.new)
77
+ else
78
+ target.__send__(method, *args)
79
+ end
80
+ rescue => e
81
+ # TODO: sensible, configurable fallback for when template calls non-existant method
82
+ # - need line number and file that generated error
83
+ # - logging.warn when happens
84
+ # - an inline comment when in dev mode?
85
+ # - some placeholder text, perhaps the name of the missing method and line no.
86
+ logger.error(e)
87
+ # logger.error(target)
88
+ # logger.error(e.backtrace.join("\\n"))
89
+ nil
90
+ end
91
+
92
+ # make each key of the params hash into a method call for speed
93
+ def _update(params)
94
+ params.each do |key, val|
95
+ singleton_class.__send__(:define_method, key) { val }
96
+ end
97
+ end
98
+ end
99
+ end
100
+
@@ -0,0 +1,14 @@
1
+ # encoding: UTF-8
2
+
3
+
4
+ module Spontaneous
5
+ module Render
6
+ class DevelopmentRenderer < Renderer
7
+ def render_content(content, format=:html, params = {})
8
+ template = publishing_renderer.render_file(content.template(format), content, format, params)
9
+ result = request_renderer.render_string(template, content, format, params)
10
+ end
11
+ end # DevelopmentRenderer
12
+ end # Render
13
+ end # Spontaneous
14
+
@@ -0,0 +1,19 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous::Render
4
+ class Engine
5
+ attr_reader :template_root
6
+ attr_accessor :template_class
7
+ attr_accessor :context_class
8
+
9
+ def initialize(template_root)
10
+ @template_root = File.expand_path(template_root)
11
+ end
12
+
13
+ def render_content(content, format=:html)
14
+ context = context_class.new(content, format)
15
+ self.render(context)
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,5 @@
1
+ module Spontaneous::Render::Format
2
+ class Html < Spontaneous::Render::FormatBase
3
+ end
4
+ end
5
+
@@ -0,0 +1,70 @@
1
+
2
+ module Spontaneous::Render
3
+ module Format; end
4
+
5
+ class FormatBase
6
+ def self.format
7
+ @format ||= self.name.demodulize.downcase.to_sym
8
+ end
9
+
10
+
11
+ attr_reader :progress
12
+
13
+ def initialize(revision, pages, progress=nil)
14
+ @revision, @pages, @progress = revision, pages.find_all { |page| page.formats.include?(format) }, progress
15
+ end
16
+
17
+ def format
18
+ self.class.format
19
+ end
20
+
21
+ def render
22
+ before_render
23
+ delay = Spontaneous::Site.config.publishing_delay
24
+ @pages.each_with_index do |page, n|
25
+ render_page(page) if page.formats.include?(format)
26
+ after_page_rendered(page)
27
+ # sleep(delay) if delay
28
+ # sleep(3)
29
+ end
30
+ after_render
31
+ end
32
+
33
+ def after_page_rendered(page)
34
+ progress.page_rendered(page) if progress
35
+ end
36
+
37
+ def before_render; end
38
+ def after_render; end
39
+
40
+ def render_page(page)
41
+ output = page.render(format)
42
+ path = output_path(page, output)
43
+ File.open(path, 'w') do |f|
44
+ f.write(output)
45
+ end
46
+ end
47
+
48
+ def output_path(page, output)
49
+ ext = nil
50
+ ext = renderer.extension if Spontaneous.template_engine.is_dynamic?(output)
51
+ path = Spontaneous::Render.output_path(@revision, page, format, ext)
52
+
53
+ dir = File.dirname(path)
54
+ FileUtils.mkdir_p(dir) unless File.exist?(dir)
55
+ path
56
+ end
57
+
58
+ def revision_root
59
+ Spontaneous.revision_dir(@revision)
60
+ end
61
+
62
+ def renderer
63
+ Spontaneous::Render.renderer
64
+ end
65
+ end
66
+ end
67
+
68
+ Dir[File.join(File.dirname(__FILE__), 'format', '*.rb')].each do |format|
69
+ require format
70
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: UTF-8
2
+
3
+
4
+ module Spontaneous
5
+ module Render
6
+ class PreviewRenderer < Renderer
7
+ def render_content(content, format=:html, params = {})
8
+ # render content using first_pass_renderer
9
+ # then render this using second_pass_renderer
10
+ template = preview_renderer.render_file(content.template(format), content, format, params)
11
+ result = request_renderer.render_string(template, content, format, params)
12
+
13
+ result
14
+ end
15
+ end # PreviewRenderer
16
+ end # Render
17
+ end # Spontaneous
18
+