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,144 @@
1
+ # encoding: UTF-8
2
+
3
+
4
+ module Spontaneous
5
+ class Style
6
+ def self.to_directory_name(klass)
7
+ return nil if klass.name.blank?
8
+ klass.name.demodulize.underscore
9
+ end
10
+
11
+ attr_reader :owner, :prototype
12
+
13
+ def initialize(owner, prototype = nil)
14
+ @owner, @prototype = owner, prototype
15
+ end
16
+
17
+ def schema_id
18
+ self.prototype.schema_id
19
+ end
20
+
21
+ def template(format = :html)
22
+ unless template = inline_template(format)
23
+ template = find_template(format)
24
+ end
25
+ template
26
+ end
27
+
28
+ def find_template(format = :html)
29
+ unless template = local_template(format)
30
+ template = supertype_template(format)
31
+ end
32
+ unless template
33
+ logger.warn("No template file found for style #{owner}/#{name}.#{format}")
34
+ template = anonymous_template
35
+ end
36
+ template
37
+ end
38
+
39
+ alias_method :path, :template
40
+
41
+ def local_template(format)
42
+ template_path = nil
43
+ Spontaneous.template_paths.each do |template_root|
44
+ template_path = try_template_paths.detect do |path|
45
+ Spontaneous::Render.exists?(template_root, path, format)
46
+ end
47
+ return (template_root / template_path) if template_path
48
+ end
49
+ nil
50
+ end
51
+
52
+ def supertype_template(format)
53
+ supertype = owner.supertype
54
+ if supertype && supertype != Spontaneous::Content
55
+ self.class.new(supertype, prototype).template(format)
56
+ else
57
+ nil
58
+ end
59
+ end
60
+
61
+ def inline_template(format)
62
+ if template_string = owner.inline_templates[format.to_sym]
63
+ Anonymous.new(template_string).template(format)
64
+ end
65
+ end
66
+
67
+ def anonymous_template
68
+ Proc.new { "" }
69
+ end
70
+
71
+ def name
72
+ prototype.name
73
+ end
74
+
75
+ def try_template_paths
76
+ try_paths.map { |path| Array === path ? File.join(path.compact) : path }.uniq
77
+ end
78
+
79
+ def try_paths
80
+ name = prototype.name.to_s
81
+ [[owner_directory_name, name], name]
82
+ end
83
+
84
+ def owner_directory_name
85
+ self.class.to_directory_name(owner)
86
+ end
87
+
88
+
89
+ def default?
90
+ @options[:default]
91
+ end
92
+
93
+ def formats
94
+ Spontaneous::Render.formats(self)
95
+ end
96
+
97
+ # def export
98
+ # {
99
+ # :name => name.to_s,
100
+ # :schema_id => schema_id.to_s
101
+ # }
102
+ # end
103
+
104
+ def ==(other)
105
+ other.class == self.class && other.prototype == self.prototype && other.owner == self.owner
106
+ end
107
+
108
+ class Default < Style
109
+ def name
110
+ "<default>"
111
+ end
112
+
113
+ def schema_id
114
+ nil
115
+ end
116
+
117
+ def try_paths
118
+ [owner_directory_name]
119
+ end
120
+ end
121
+
122
+ class Anonymous
123
+ def initialize(template_code = "")
124
+ @template_code = template_code
125
+ end
126
+
127
+ def template(format = :html)
128
+ Proc.new { @template_code }
129
+ end
130
+
131
+ def exists?(format = :html)
132
+ true
133
+ end
134
+
135
+ def name
136
+ nil
137
+ end
138
+
139
+ def schema_id
140
+ nil
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,9 @@
1
+
2
+ namespace :spot do
3
+ desc "Migrate the core Spontaneous database"
4
+ task :migrate do
5
+ Spontaneous.database.logger = Spontaneous.logger
6
+ Sequel.extension :migration
7
+ Sequel::Migrator.apply(Spontaneous.database, Spontaneous.gem_dir('db/migrations'))
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ Dir["#{File.dirname(__FILE__)}/tasks/**/*.rake"].each { |ext| load ext }
2
+
3
+ # Load the custom, site-specific tasks
4
+ Dir["#{Spontaneous.root}/lib/tasks/**/*.rake"].each { |ext| load ext }
5
+ # TODO: load the role tasks
@@ -0,0 +1,6 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous
4
+ VERSION = "0.1.0.alpha1"
5
+ GEM = true
6
+ end
@@ -0,0 +1,179 @@
1
+ # encoding: UTF-8
2
+
3
+
4
+ if RUBY_VERSION < '1.9'
5
+ $KCODE='u'
6
+ else
7
+ Encoding.default_external = Encoding::UTF_8
8
+ Encoding.default_internal = Encoding::UTF_8
9
+ end
10
+
11
+ require "home_run"
12
+ require "stringex"
13
+ require "sequel"
14
+ require "yajl"
15
+
16
+ require 'logger'
17
+ require 'fileutils'
18
+ require 'active_support/core_ext/date_time/conversions'
19
+ require 'active_support/core_ext/file'
20
+
21
+ Sequel.extension :inflector
22
+
23
+ Dir[File.join(File.dirname(__FILE__), 'spontaneous/extensions/*.rb')].each { |file|
24
+ require file
25
+ }
26
+
27
+ require 'spontaneous/logger'
28
+ require 'spontaneous/plugins'
29
+ require 'spontaneous/constants'
30
+ require 'spontaneous/errors'
31
+ require 'spontaneous/json'
32
+
33
+ Dir[File.expand_path('../spontaneous/plugins/application/*.rb', __FILE__)].each do |file|
34
+ require file
35
+ end
36
+
37
+ module Spontaneous
38
+ extend Plugins
39
+ include Constants
40
+
41
+ def self.gem_root
42
+ @gem_root ||= File.expand_path(File.dirname(__FILE__) / '..')
43
+ end
44
+
45
+ def self.reload!
46
+ Spontaneous::Schema.reload!
47
+ Spontaneous::Loader.reload!
48
+ Spontaneous::Schema.validate!
49
+ end
50
+
51
+ plugin Plugins::Application::State
52
+ plugin Plugins::Application::Paths
53
+ plugin Plugins::Application::Render
54
+ plugin Plugins::Application::Facets
55
+ plugin Plugins::Application::Serialisation
56
+
57
+ autoload :ProxyObject, "spontaneous/proxy_object"
58
+
59
+ autoload :Config, "spontaneous/config"
60
+ autoload :Paths, "spontaneous/paths"
61
+ autoload :Facet, "spontaneous/facet"
62
+
63
+ autoload :Content, "spontaneous/content"
64
+ autoload :Page, "spontaneous/page"
65
+ autoload :Piece, "spontaneous/piece"
66
+ autoload :Box, "spontaneous/box"
67
+
68
+ autoload :FieldTypes, "spontaneous/field_types"
69
+
70
+ autoload :PagePiece, "spontaneous/page_piece"
71
+
72
+
73
+ autoload :Style, "spontaneous/style"
74
+ autoload :BoxStyle, "spontaneous/box_style"
75
+ autoload :Layout, "spontaneous/layout"
76
+
77
+ autoload :Site, "spontaneous/site"
78
+ autoload :State, "spontaneous/state"
79
+ autoload :Schema, "spontaneous/schema"
80
+
81
+ autoload :ImageSize, "spontaneous/image_size"
82
+
83
+ autoload :Rack, "spontaneous/rack"
84
+
85
+ autoload :Render, "spontaneous/render"
86
+ autoload :Media, "spontaneous/media"
87
+
88
+ autoload :Change, "spontaneous/change"
89
+ autoload :Revision, "spontaneous/revision"
90
+ autoload :Publishing, "spontaneous/publishing"
91
+
92
+ autoload :Generators, "spontaneous/generators"
93
+
94
+ autoload :Server, "spontaneous/server"
95
+
96
+ autoload :Permissions, "spontaneous/permissions"
97
+ autoload :ContentQuery, "spontaneous/content_query"
98
+
99
+ autoload :PageController, "spontaneous/page_controller"
100
+
101
+ autoload :Application, "spontaneous/application"
102
+
103
+ module Prototypes
104
+ autoload :FieldPrototype, "spontaneous/prototypes/field_prototype"
105
+ autoload :BoxPrototype, "spontaneous/prototypes/box_prototype"
106
+ autoload :StylePrototype, "spontaneous/prototypes/style_prototype"
107
+ autoload :LayoutPrototype, "spontaneous/prototypes/layout_prototype"
108
+ end
109
+
110
+ module Collections
111
+ autoload :PrototypeSet, "spontaneous/collections/prototype_set"
112
+ autoload :ChangeSet, "spontaneous/collections/change_set"
113
+ autoload :EntrySet, "spontaneous/collections/entry_set"
114
+ autoload :FieldSet, "spontaneous/collections/field_set"
115
+ autoload :BoxSet, "spontaneous/collections/box_set"
116
+ autoload :StyleSet, "spontaneous/collections/style_set"
117
+ end
118
+
119
+ module Plugins
120
+ autoload :Supertype, "spontaneous/plugins/supertype"
121
+ autoload :Boxes, "spontaneous/plugins/boxes"
122
+ autoload :Fields, "spontaneous/plugins/fields"
123
+ autoload :Entries, "spontaneous/plugins/entries"
124
+ autoload :Entry, "spontaneous/plugins/entry"
125
+ autoload :Styles, "spontaneous/plugins/styles"
126
+ autoload :Layouts, "spontaneous/plugins/layouts"
127
+ autoload :SchemaTitle, "spontaneous/plugins/schema_title"
128
+ autoload :SchemaId, "spontaneous/plugins/schema_id"
129
+ autoload :Render, "spontaneous/plugins/render"
130
+ autoload :SchemaHierarchy, "spontaneous/plugins/schema_hierarchy"
131
+ autoload :InstanceCode, "spontaneous/plugins/instance_code"
132
+ autoload :Paths, "spontaneous/plugins/paths"
133
+ autoload :PageTree, "spontaneous/plugins/page_tree"
134
+ autoload :AllowedTypes, "spontaneous/plugins/allowed_types"
135
+ autoload :Serialisation, "spontaneous/plugins/serialisation"
136
+ autoload :SiteMap, "spontaneous/plugins/site_map"
137
+ autoload :PageSearch, "spontaneous/plugins/page_search"
138
+ autoload :Media, "spontaneous/plugins/media"
139
+ autoload :Publishing, "spontaneous/plugins/publishing"
140
+ autoload :Aliases, "spontaneous/plugins/aliases"
141
+ autoload :Visibility, "spontaneous/plugins/visibility"
142
+ autoload :Prototypes, "spontaneous/plugins/prototypes"
143
+ autoload :Permissions, "spontaneous/plugins/permissions"
144
+ autoload :Controllers, "spontaneous/plugins/controllers"
145
+
146
+
147
+ module Page
148
+ autoload :Formats, "spontaneous/plugins/page/formats"
149
+ autoload :Request, "spontaneous/plugins/page/request"
150
+ end
151
+
152
+ module Site
153
+ autoload :Publishing, "spontaneous/plugins/site/publishing"
154
+ autoload :Revisions, "spontaneous/plugins/site/revisions"
155
+ autoload :Selectors, "spontaneous/plugins/site/selectors"
156
+ autoload :Map, "spontaneous/plugins/site/map"
157
+ autoload :Instance, "spontaneous/plugins/site/instance"
158
+ end
159
+ end
160
+
161
+
162
+ class UnknownTypeException < Exception
163
+ def initialize(parent, type)
164
+ super("Unknown content type '#{type}' requested in class #{parent}")
165
+ end
166
+ end
167
+ class UnknownStyleException < Exception
168
+ def initialize(style_name, klass)
169
+ super("Unknown style '#{style_name}' for class #{klass}")
170
+ end
171
+ end
172
+
173
+ end
174
+
175
+ require 'spontaneous/loader'
176
+ require 'spontaneous/version'
177
+
178
+
179
+ Spot = S = Spontaneous unless defined?(Spot)
@@ -0,0 +1,66 @@
1
+ ## This is the rakegem gemspec template. Make sure you read and understand
2
+ ## all of the comments. Some sections require modification, and others can
3
+ ## be deleted if you don't need them. Once you understand the contents of
4
+ ## this file, feel free to delete any comments that begin with two hash marks.
5
+ ## You can find comprehensive Gem::Specification documentation, at
6
+ ## http://docs.rubygems.org/read/chapter/20
7
+ Gem::Specification.new do |s|
8
+ s.specification_version = 2 if s.respond_to? :specification_version=
9
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
10
+ s.rubygems_version = '1.3.5'
11
+
12
+ ## Leave these as is they will be modified for you by the rake gemspec task.
13
+ ## If your rubyforge_project name is different, then edit it and comment out
14
+ ## the sub! line in the Rakefile
15
+ s.name = 'NAME'
16
+ s.version = '0.0'
17
+ s.date = '2010-01-01'
18
+ s.rubyforge_project = 'NAME'
19
+
20
+ ## Make sure your summary is short. The description may be as long
21
+ ## as you like.
22
+ s.summary = "Spontaneous is a next-generation Ruby CMS"
23
+ s.description = "Spontaneous is a next-generation Ruby CMS"
24
+
25
+ ## List the primary authors. If there are a bunch of authors, it's probably
26
+ ## better to set the email to an email list or something. If you don't have
27
+ ## a custom homepage, consider using your GitHub URL or the like.
28
+ s.authors = ["Garry Hill"]
29
+ s.email = 'garry@magnetised.net'
30
+ s.homepage = 'http://spontaneouscms.org'
31
+
32
+ ## This gets added to the $LOAD_PATH so that 'lib/NAME.rb' can be required as
33
+ ## require 'NAME.rb' or'/lib/NAME/file.rb' can be as require 'NAME/file.rb'
34
+ s.require_paths = %%w[lib]
35
+
36
+ # ## This sections is only necessary if you have C extensions.
37
+ # s.require_paths << 'ext'
38
+ # s.extensions = %%w[ext/extconf.rb]
39
+
40
+ ## If your gem includes any executables, list them here.
41
+ s.executables = ["spot"]
42
+
43
+ ## Specify any RDoc options here. You'll want to add your README and
44
+ ## LICENSE files to the extra_rdoc_files list.
45
+ s.rdoc_options = ["--charset=UTF-8"]
46
+ s.extra_rdoc_files = %%w[README LICENSE]
47
+
48
+ ## List your runtime dependencies here. Runtime dependencies are those
49
+ ## that are needed for an end user to actually USE your code.
50
+ %s
51
+
52
+ ## List your development dependencies here. Development dependencies are
53
+ ## those that are only needed during development
54
+ %s
55
+
56
+ ## Leave this section as-is. It will be automatically generated from the
57
+ ## contents of your Git repository via the gemspec task. DO NOT REMOVE
58
+ ## THE MANIFEST COMMENTS, they are used as delimiters by the task.
59
+ # = MANIFEST =
60
+ s.files = %%w[]
61
+ # = MANIFEST =
62
+
63
+ ## Test files will be grabbed from the file list. Make sure the path glob
64
+ ## matches what you actually use.
65
+ s.test_files = s.files.select { |path| path =~ /^test\/test_.*\.rb/ }
66
+ end
@@ -0,0 +1,287 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'test_helper'
4
+
5
+
6
+ class SlotsTest < MiniTest::Spec
7
+ include Spontaneous
8
+
9
+ context "Slot containers" do
10
+ setup do
11
+ class ::SlotClass < Content; end
12
+ class ::ContentClass < Content; end
13
+ ContentClass.field :description
14
+ end
15
+
16
+ teardown do
17
+ Object.send(:remove_const, :SlotClass)
18
+ Object.send(:remove_const, :ContentClass)
19
+ end
20
+
21
+ should "start empty" do
22
+ SlotClass.slots.length.should == 0
23
+ end
24
+
25
+ should "have a flag showing there are no defined slots" do
26
+ SlotClass.has_slots?.should be_false
27
+ end
28
+
29
+ should "be definable with a name" do
30
+ SlotClass.slot :images0
31
+ SlotClass.slots.length.should == 1
32
+ SlotClass.slots.first.name.should == :images0
33
+ SlotClass.has_slots?.should be_true
34
+ end
35
+
36
+ should "accept a custom instance class" do
37
+ SlotClass.slot :images1, :type => SlotClass
38
+ SlotClass.slots.first.instance_class.superclass.should == SlotClass
39
+ end
40
+
41
+ should "accept a custom instance class as a string" do
42
+ SlotClass.slot :images2, :type => 'SlotClass'
43
+ SlotClass.slots.first.instance_class.superclass.should == SlotClass
44
+ end
45
+
46
+ should "accept a custom instance class as a symbol" do
47
+ SlotClass.slot :images3, :type => :SlotClass
48
+ SlotClass.slots.first.instance_class.superclass.should == SlotClass
49
+ end
50
+
51
+ should "have 'title' option" do
52
+ SlotClass.slot :images4, :title => "Custom Title"
53
+ @instance = SlotClass.new
54
+ @instance.pieces.first.slot_name.should == "Custom Title"
55
+ end
56
+
57
+ should "accept values for the slot's fields" do
58
+ SlotClass.slot :images4, :type => :ContentClass, :fields => { :description => "Neato" }
59
+
60
+ @instance = SlotClass.new
61
+ @instance.images4.fields.description.value.should == "Neato"
62
+ end
63
+
64
+ should "allow access to groups of slots" do
65
+ SlotClass.slot :images5, :tag => :main
66
+ SlotClass.slot :posts, :tag => :main
67
+ SlotClass.slot :comments
68
+ SlotClass.slot :last, :tag => :main
69
+ @instance = SlotClass.new
70
+ @instance.slots.tagged(:main).length.should == 3
71
+ @instance.slots.tagged('main').map {|e| e.label.to_sym }.should == [:images5, :posts, :last]
72
+ end
73
+
74
+ context "with superclasses" do
75
+ setup do
76
+ SlotClass.slot :images6, :tag => :main
77
+
78
+ @subclass1 = Class.new(SlotClass) do
79
+ slot :monkeys, :tag => :main
80
+ slot :apes
81
+ end
82
+ @subclass2 = Class.new(@subclass1) do
83
+ slot :peanuts
84
+ end
85
+ end
86
+ should "inherit slots from its superclass" do
87
+ @subclass2.slots.length.should == 4
88
+ @subclass2.slots.map { |s| s.name }.should == [:images6, :monkeys, :apes, :peanuts]
89
+ @subclass2.slots.tagged(:main).length.should == 2
90
+ instance = @subclass2.new
91
+ instance.slots.length.should == 4
92
+ end
93
+
94
+ should "allow customisation of the slot order" do
95
+ new_order = [:peanuts, :apes, :images6, :monkeys]
96
+ @subclass2.slot_order *new_order
97
+ @subclass2.slots.map { |s| s.name }.should == new_order
98
+ end
99
+
100
+ should "take order of instance slots from class defn" do
101
+ new_order = [:peanuts, :apes, :images6, :monkeys]
102
+ instance = @subclass2.create
103
+ @subclass2.slot_order *new_order
104
+ instance = @subclass2[instance.id]
105
+ instance.slots.map { |e| e.label.to_sym }.should == new_order
106
+ end
107
+ end
108
+
109
+ # should "default to the name of the slot for the style name" do
110
+ # SlotClass.slot :images
111
+ # instance = SlotClass.new
112
+ # instance.images.style.filename.should == "images.html.cut"
113
+ # end
114
+ should "default to a template-less style for slots without a style" do
115
+ SlotClass.slot :images7
116
+ instance = SlotClass.new
117
+ instance.images7.style.class.should == Spontaneous::Plugins::Styles::AnonymousStyle
118
+ end
119
+
120
+ should "accept a custom template name" do
121
+ SlotClass.slot :images8, :style => :anonymous_slot
122
+ instance = SlotClass.new
123
+ instance.images8.style.filename.should == "anonymous_slot.html.cut"
124
+ end
125
+
126
+ should "take template path from slot's parent for anonymous slots" do
127
+ SlotClass.slot :images9, :style => :anonymous_slot
128
+ SlotClass.slot :posts
129
+ instance = SlotClass.new
130
+ instance.images9.style.path.should == "slot_class/anonymous_slot"
131
+ # instance.posts.style.path.should #== "#{Spontaneous.template_root}/slot_class/posts.html.cut"
132
+ end
133
+
134
+ context "anonymous slots" do
135
+ setup do
136
+ class ::AllowedType < Content; end
137
+ SlotClass.slot :images10 do
138
+ allow AllowedType
139
+
140
+ def monkey
141
+ "magic"
142
+ end
143
+ end
144
+ end
145
+
146
+ teardown do
147
+ Object.send(:remove_const, :AllowedType)
148
+ end
149
+
150
+ should "allow configuration of allowed types for anonymous slots" do
151
+ SlotClass.slots.first.instance_class.allowed.length.should == 1
152
+ end
153
+
154
+ should "allow methods in slot definitions" do
155
+ instance = SlotClass.new
156
+ instance.images10.monkey.should == "magic"
157
+ end
158
+
159
+ should "correctly save pieces" do
160
+ instance = SlotClass.new
161
+ c1 = AllowedType.new
162
+ c2 = AllowedType.new
163
+ c3 = AllowedType.new
164
+ instance.images10 << c1
165
+ instance.images10 << c2
166
+ instance.images10 << c3
167
+
168
+ instance.save
169
+ instance.images10.save
170
+ c1.save
171
+ c2.save
172
+ c3.save
173
+
174
+ instance = SlotClass[instance.id]
175
+ instance.images10.pieces.length.should == 3
176
+ end
177
+ end
178
+
179
+ context "slots with definied classes" do
180
+ setup do
181
+ class ::AllowedType < Content; end
182
+ SlotClass.slot :images11, :type => AllowedType do
183
+ allow AllowedType
184
+
185
+ def monkey
186
+ "magic"
187
+ end
188
+ end
189
+ end
190
+
191
+ teardown do
192
+ Object.send(:remove_const, :AllowedType)
193
+ end
194
+
195
+ should "allow per-slot definitions" do
196
+ SlotClass.slots.first.instance_class.allowed.length.should == 1
197
+ instance = SlotClass.new
198
+ instance.images11.monkey.should == "magic"
199
+ instance = SlotClass[instance.id]
200
+ instance.images11.monkey.should == "magic"
201
+ end
202
+ end
203
+ context "" do
204
+ setup do
205
+ SlotClass.slot :images12
206
+ @instance = SlotClass.new
207
+ end
208
+
209
+ should "provide a test for existance of named slot" do
210
+ @instance.slot?(:images12).should be_true
211
+ @instance.slot?(:none).should be_false
212
+ end
213
+
214
+ should "instantiate a corresponding piece in new instances" do
215
+ @instance.pieces.length.should == 1
216
+ # @instance.pieces.first.class.should == Piece
217
+ @instance.pieces.first.label.should == :images12
218
+ @instance.pieces.first.slot_name.should == "Images12"
219
+ end
220
+
221
+ should "have a #slots method for accessing slots" do
222
+ @instance.slots.length.should == 1
223
+ @instance.slots.first.label.should == :images12
224
+ @instance.slots.first.slot_id.should == "images12"
225
+ @instance.slots[:images12].should == @instance.slots.first
226
+ end
227
+
228
+ should "have shortcut methods for accessing slots by name" do
229
+ @instance.slots.images12.should == @instance.slots.first
230
+ @instance.images12.should == @instance.slots.first
231
+ end
232
+
233
+ should "persist slots" do
234
+ @instance.save
235
+ @instance = SlotClass[@instance.id]
236
+ @instance.slots.length.should == 1
237
+ @instance.slots.first.label.should == :images12
238
+ @instance.slots[:images12].should == @instance.slots.first
239
+ @instance.slots.images12.should == @instance.slots.first
240
+ @instance.images12.should == @instance.slots.first
241
+ end
242
+
243
+ should "update list of slots on instance if slot added after creation" do
244
+ @instance.save
245
+ SlotClass.slot :posts
246
+ @instance = SlotClass[@instance.id]
247
+ @instance.slots.length.should == 2
248
+ @instance.slots.first.label.should == :images12
249
+ @instance.slots.last.label.should == :posts
250
+ @instance.slots[:images12].should == @instance.slots.first
251
+ @instance.slots[:posts].should == @instance.slots.last
252
+ @instance.slots.images12.should == @instance.slots.first
253
+ @instance.slots.posts.should == @instance.slots.last
254
+ @instance.images12.should == @instance.slots.first
255
+ @instance.posts.should == @instance.slots.last
256
+ end
257
+
258
+ ## waiting on entry deletion routines
259
+ should "update list of slots on instance if slot removed after creation"
260
+ # should "update list of slots on instance if slot removed after creation" do
261
+ # @instance.save
262
+ # SlotClass.slot :posts
263
+ # @instance = SlotClass[@instance.id]
264
+ # @instance.slots.length.should == 2
265
+ # SlotClass.slots.shift
266
+ # p SlotClass.slots
267
+ # @instance = SlotClass[@instance.id]
268
+ # @instance.slots.length.should == 1
269
+ # @instance.slots.first.label.should == "posts"
270
+ # @instance.slots[:posts].should == @instance.slots.first
271
+ # @instance.slots.posts.should == @instance.slots.first
272
+ # @instance.posts.should == @instance.slots.first
273
+ # end
274
+ end
275
+
276
+ context "addition of slots" do
277
+ should "be possible after creation" do
278
+ SlotClass.slot :posts
279
+ instance = SlotClass.new
280
+ instance.save
281
+ SlotClass.slot :images
282
+ instance = SlotClass[instance.id]
283
+ instance.images.should_not be_nil
284
+ end
285
+ end
286
+ end
287
+ end