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,196 @@
1
+ # encoding: UTF-8
2
+
3
+ module Sequel
4
+ module Plugins
5
+ # The single_table_inheritance plugin allows storing all objects
6
+ # in the same class hierarchy in the same table. It makes it so
7
+ # subclasses of this model only load rows related to the subclass,
8
+ # and when you retrieve rows from the main class, you get instances
9
+ # of the subclasses (if the rows should use the subclasses's class).
10
+ #
11
+ # By default, the plugin assumes that the +sti_key+ column (the first
12
+ # argument to the plugin) holds the class name as a string. However,
13
+ # you can override this by using the <tt>:model_map</tt> option and/or
14
+ # the <tt>:key_map</tt> option.
15
+ #
16
+ # You should only load this plugin in the parent class, not in the subclasses.
17
+ #
18
+ # You shouldn't call set_dataset in the model after applying this
19
+ # plugin, otherwise subclasses might use the wrong dataset. You should
20
+ # make sure this plugin is loaded before the subclasses. Note that since you
21
+ # need to load the plugin before the subclasses are created, you can't use
22
+ # direct class references in the plugin class. You should specify subclasses
23
+ # in the plugin call using class name strings or symbols, see usage below.
24
+ #
25
+ # Usage:
26
+ #
27
+ # # Use the default of storing the class name in the sti_key
28
+ # # column (:kind in this case)
29
+ # Employee.plugin :single_table_inheritance, :kind
30
+ #
31
+ # # Using integers to store the class type, with a :model_map hash
32
+ # # and an sti_key of :type
33
+ # Employee.plugin :single_table_inheritance, :type,
34
+ # :model_map=>{1=>:Staff, 2=>:Manager}
35
+ #
36
+ # # Using non-class name strings
37
+ # Employee.plugin :single_table_inheritance, :type,
38
+ # :model_map=>{'line staff'=>:Staff, 'supervisor'=>:Manager}
39
+ #
40
+ # # Using custom procs, with :model_map taking column values
41
+ # # and yielding either a class, string, symbol, or nil,
42
+ # # and :key_map taking a class object and returning the column
43
+ # # value to use
44
+ # Employee.plugin :single_table_inheritance, :type,
45
+ # :model_map=>proc{|v| v.reverse},
46
+ # :key_map=>proc{|klass| klass.name.reverse}
47
+ #
48
+ # One minor issue to note is that if you specify the <tt>:key_map</tt>
49
+ # option as a hash, instead of having it inferred from the <tt>:model_map</tt>,
50
+ # you should only use class name strings as keys, you should not use symbols
51
+ # as keys.
52
+ module ContentTableInheritance
53
+ # Setup the necessary STI variables, see the module RDoc for SingleTableInheritance
54
+ def self.configure(model, key, opts={})
55
+ model.instance_eval do
56
+ # @sti_model_map = lambda{|v| v if v && v != ''}
57
+ # @sti_key_map = lambda{|klass| klass.name.to_s}
58
+ @sti_model_map = lambda { |id| Spontaneous::Schema[id] }
59
+ @sti_key_map = lambda { |klass| klass.schema_id.to_s }
60
+ @sti_key_array = nil
61
+ @sti_subclasses_array = [sti_key_map[model]]
62
+ @sti_key = key
63
+ @sti_dataset = dataset
64
+ @is_content_inheritance_root = false
65
+ @is_site_inheritance_root = false
66
+ dataset.row_proc = lambda{|r| model.sti_load(r)}
67
+ end
68
+ end
69
+
70
+ module ClassMethods
71
+ # The base dataset for STI, to which filters are added to get
72
+ # only the models for the specific STI subclass.
73
+ attr_reader :sti_dataset
74
+
75
+ # The column name holding the STI key for this model
76
+ attr_reader :sti_key
77
+
78
+ # Array holding keys for all subclasses of this class, used for the
79
+ # dataset filter in subclasses. Nil in the main class.
80
+ attr_reader :sti_key_array
81
+
82
+ # A hash/proc with class keys and column value values, mapping
83
+ # the the class to a particular value given to the sti_key column.
84
+ # Used to set the column value when creating objects, and for the
85
+ # filter when retrieving objects in subclasses.
86
+ attr_reader :sti_key_map
87
+
88
+ # A hash/proc with column value keys and class values, mapping
89
+ # the value of the sti_key column to the appropriate class to use.
90
+ attr_reader :sti_model_map
91
+
92
+ attr_reader :sti_subclasses_array
93
+
94
+ attr_reader :is_site_inheritance_root
95
+
96
+ # Copy the necessary attributes to the subclasses, and filter the
97
+ # subclass's dataset based on the sti_kep_map entry for the class.
98
+ def inherited(subclass)
99
+ super
100
+ sk = sti_key
101
+ sd = sti_dataset
102
+ skm = sti_key_map
103
+ smm = sti_model_map
104
+ key = skm[subclass]
105
+ ska = [key]
106
+ sti_subclass_added(key, subclass)
107
+ unless subclass.is_site_inheritance_root
108
+ subclass.set_dataset(sd.filter(SQL::QualifiedIdentifier.new(table_name, sk)=>ska), :inherited=>true)
109
+ end
110
+ subclass.instance_eval do
111
+ @sti_key = sk
112
+ @sti_key_array = ska
113
+ @sti_subclasses_array = [skm[subclass]]
114
+ @sti_dataset = sd
115
+ @sti_key_map = skm
116
+ @sti_model_map = smm
117
+ @simple_table = nil
118
+ end
119
+ end
120
+
121
+ # used by Page and Piece classes to control the subclasses used in searches
122
+ # see 'test_content_inheritance.rb'
123
+ def set_inheritance_root
124
+ @is_content_inheritance_root = true
125
+ dataset.row_proc = Spontaneous::Content.dataset.row_proc
126
+ end
127
+
128
+ def set_site_inheritance_root
129
+ @is_site_inheritance_root = true
130
+ dataset.row_proc = Spontaneous::Content.dataset.row_proc
131
+ end
132
+
133
+ def unset_site_inheritance_root
134
+ @is_site_inheritance_root = false
135
+ end
136
+
137
+ # Return an instance of the class specified by sti_key,
138
+ # used by the row_proc.
139
+ def sti_load(r)
140
+ sti_class(sti_model_map[r[sti_key]]).load(r)
141
+ end
142
+
143
+ # Make sure that all subclasses of the parent class correctly include
144
+ # keys for all of their descendant classes.
145
+ # Subclasses of Spontaneous::[Page, Piece] as well as ::Page & ::Piece are treated specially
146
+ # they only return instances of that one class as this is the intuitively correct result
147
+ # The top level Page & Piece classes return all sub-classes
148
+ def sti_subclass_added(key, subclass = nil)
149
+ if sti_key_array
150
+ if subclass && subclass.name
151
+ # alright, so this is a bit of a hack
152
+ # we want the site defined ::Page, ::Piece classes to work like Spot::[Page,Piece]
153
+ # but we don't want generic subclasses of Spot::[Page, Piece] to do so
154
+ if subclass.name.demodulize == self.name.demodulize && @is_content_inheritance_root
155
+ subclass.set_site_inheritance_root
156
+ end
157
+ end
158
+ if @is_site_inheritance_root or @is_content_inheritance_root
159
+ sti_key_array << key unless sti_key_array.include?(key)
160
+ end
161
+ sti_subclasses_array << key
162
+ superclass.sti_subclass_added(key)
163
+ end
164
+ end
165
+
166
+ private
167
+
168
+ # Return a class object. If a class is given, return it directly.
169
+ # Treat strings and symbols as class names. If nil is given or
170
+ # an invalid class name string or symbol is used, return self.
171
+ # Raise an error for other types.
172
+ def sti_class(v)
173
+ case v
174
+ when String, Symbol
175
+ constantize(v) rescue self
176
+ when nil
177
+ self
178
+ when Class
179
+ v
180
+ else
181
+ raise(Error, "Invalid class type used: #{v.inspect}")
182
+ end
183
+ end
184
+ end
185
+
186
+ module InstanceMethods
187
+ # Set the sti_key column based on the sti_key_map.
188
+ def before_create
189
+ send("#{model.sti_key}=", model.sti_key_map[model]) unless self[model.sti_key]
190
+ super
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end
196
+
@@ -0,0 +1,154 @@
1
+ # encoding: UTF-8
2
+
3
+ module Sequel
4
+ module Plugins
5
+ # Sequel's built in Serialization plugin allows you to keep serialized
6
+ # ruby objects in the database, while giving you deserialized objects
7
+ # when you call an accessor.
8
+ #
9
+ # This plugin works by keeping the serialized value in the values, and
10
+ # adding a @deserialized_values hash. The reader method for serialized columns
11
+ # will check the @deserialized_values for the value, return it if present,
12
+ # or deserialized the entry in @values and return it. The writer method will
13
+ # set the @deserialized_values entry. This plugin adds a before_save hook
14
+ # that serializes all @deserialized_values to @values.
15
+ #
16
+ # You can use either marshal, yaml, or json as the serialization format.
17
+ # If you use yaml or json, you should require them by yourself.
18
+ #
19
+ # Because of how this plugin works, it must be used inside each model class
20
+ # that needs serialization, after any set_dataset method calls in that class.
21
+ # Otherwise, it is possible that the default column accessors will take
22
+ # precedence.
23
+ #
24
+ # == Example
25
+ #
26
+ # require 'sequel'
27
+ # require 'yajl'
28
+ # class User < Sequel::Model
29
+ # plugin :yajl_serialization, :permissions
30
+ # # or
31
+ # plugin :yajl_serialization
32
+ # yajl_serialize_attributes :permissions, :attributes
33
+ # end
34
+ # user = User.create
35
+ # user.permissions = { :global => 'read-only' }
36
+ # user.save
37
+ module YajlSerialization
38
+
39
+ def self.parse(json)
40
+ parser.parse(json)
41
+ end
42
+
43
+ def self.parser
44
+ Yajl::Parser.new(:symbolize_keys => true)
45
+ end
46
+
47
+ def self.encode(obj)
48
+ encoder.encode(obj)
49
+ end
50
+
51
+ def self.encoder
52
+ Yajl::Encoder.new
53
+ end
54
+
55
+ # Set up the column readers to do deserialization and the column writers
56
+ # to save the value in deserialized_values.
57
+ def self.apply(model, *args)
58
+ model.instance_eval{@serialization_map = {}}
59
+ end
60
+
61
+ def self.configure(model, *columns)
62
+ model.yajl_serialize_attributes(*columns) unless columns.empty?
63
+ end
64
+
65
+ module ClassMethods
66
+ # A map of the serialized columns for this model. Keys are column
67
+ # symbols, values are serialization formats (:marshal, :yaml, or :json).
68
+ attr_reader :serialization_map
69
+
70
+ # Module to store the serialized column accessor methods, so they can
71
+ # call be overridden and call super to get the serialization behavior
72
+ attr_accessor :serialization_module
73
+
74
+ # Copy the serialization format and columns to serialize into the subclass.
75
+ def inherited(subclass)
76
+ super
77
+ sm = serialization_map.dup
78
+ subclass.instance_eval{@serialization_map = sm}
79
+ end
80
+
81
+ # Create instance level reader that deserializes column values on request,
82
+ # and instance level writer that stores new deserialized value in deserialized
83
+ # columns
84
+ def yajl_serialize_attributes(*columns)
85
+ raise(Error, "No columns given. The serialization plugin requires you specify which columns to serialize") if columns.empty?
86
+ define_serialized_attribute_accessor(*columns)
87
+ end
88
+
89
+
90
+ private
91
+
92
+ # Add serializated attribute acessor methods to the serialization_module
93
+ def define_serialized_attribute_accessor(*columns)
94
+ m = self
95
+ include(self.serialization_module ||= Module.new) unless serialization_module
96
+ serialization_module.class_eval do
97
+ columns.each do |column|
98
+ m.serialization_map[column] = :json
99
+ define_method(column) do
100
+ if deserialized_values.has_key?(column)
101
+ deserialized_values[column]
102
+ else
103
+ deserialized_values[column] = deserialize_value(column, super())
104
+ end
105
+ end
106
+ define_method("#{column}=") do |v|
107
+ changed_columns << column unless changed_columns.include?(column)
108
+ deserialized_values[column] = v
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+ module InstanceMethods
116
+ # Hash of deserialized values, used as a cache.
117
+ attr_reader :deserialized_values
118
+
119
+ # Set @deserialized_values to the empty hash
120
+ def initialize(*args)
121
+ @deserialized_values = {}
122
+ super
123
+ end
124
+
125
+ # Serialize all deserialized values
126
+ def before_save
127
+ deserialized_values.each{|k,v| @values[k] = serialize_value(k, v)}
128
+ super
129
+ end
130
+
131
+ # Empty the deserialized values when refreshing.
132
+ def refresh
133
+ @deserialized_values = {}
134
+ super
135
+ end
136
+
137
+ private
138
+
139
+ # Deserialize the column from JSON format
140
+ def deserialize_value(column, v)
141
+ return v if v.nil?
142
+ YajlSerialization.parse(v)
143
+ end
144
+
145
+ # Serialize the column to JSON format
146
+ def serialize_value(column, v)
147
+ return v if v.nil?
148
+ YajlSerialization.encode(v)
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
154
+
@@ -0,0 +1,9 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous
4
+ module Application
5
+ class Feature < Spontaneous::Facet
6
+ end # Feature
7
+ end # Application
8
+ end # Spontaneous
9
+
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous
4
+ module Application
5
+ class Plugin < Spontaneous::Facet
6
+ def init!
7
+ init_file = @root / "init.rb"
8
+ require(init_file) if File.exist?(init_file)
9
+ super
10
+ end
11
+ end # Plugin
12
+ end # Application
13
+ end # Spontaneous
@@ -0,0 +1,8 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous
4
+ module Application
5
+ autoload :Plugin, "spontaneous/application/plugin"
6
+ autoload :Feature, "spontaneous/application/feature"
7
+ end # Application
8
+ end # Spontaneous
@@ -0,0 +1,232 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous
4
+ class Box
5
+ extend Plugins
6
+ include Enumerable
7
+
8
+ plugin Plugins::SchemaHierarchy
9
+ plugin Plugins::Fields
10
+ plugin Plugins::Styles
11
+ plugin Plugins::Serialisation
12
+ plugin Plugins::Render
13
+ plugin Plugins::AllowedTypes
14
+ plugin Plugins::Permissions
15
+ plugin Plugins::Media
16
+
17
+ # use underscores to protect against field name conflicts
18
+ attr_reader :_name, :_prototype, :_owner
19
+
20
+
21
+ def initialize(name, prototype, owner)
22
+ @_name, @_prototype, @_owner = name.to_sym, prototype, owner
23
+ @field_initialization = false
24
+ end
25
+
26
+
27
+ def self.schema_id
28
+ Spontaneous::Schema.schema_id(self)
29
+ end
30
+
31
+ def self.schema_name
32
+ "type//#{self.name}"
33
+ end
34
+
35
+
36
+ def self.supertype
37
+ if self == Spontaneous::Box
38
+ nil
39
+ else
40
+ superclass
41
+ end
42
+ end
43
+
44
+ def self.supertype?
45
+ !supertype.nil? #&& supertype.respond_to?(:field_prototypes)
46
+ end
47
+
48
+ def schema_id
49
+ # Spontaneous::Schema.schema_id(_owner.class, :box, _name.to_s)
50
+ # _prototype.schema_id
51
+ self.class.schema_id
52
+ end
53
+
54
+ def schema_name
55
+ _name.to_s
56
+ end
57
+
58
+ def owner_sid
59
+ nil
60
+ end
61
+
62
+ def schema_owner
63
+ nil
64
+ end
65
+
66
+ def formats
67
+ _owner.formats
68
+ end
69
+
70
+ def media_id
71
+ "#{_owner.padded_id}/#{schema_id}"
72
+ end
73
+
74
+ def box_name
75
+ _name
76
+ end
77
+
78
+ def label
79
+ _name.to_s
80
+ end
81
+
82
+ # needed by Render::Context
83
+ def box?(box_name)
84
+ false
85
+ end
86
+
87
+ def field_store
88
+ _owner.box_field_store(self) || initialize_fields
89
+ end
90
+
91
+ # don't like this
92
+ def initialize_fields
93
+ field_store = nil
94
+ if default_values = _prototype.field_defaults
95
+ field_store = []
96
+ default_values.each do |field_name, value|
97
+ if self.field?(field_name)
98
+ field = self.class.field_prototypes[field_name].to_field
99
+ field.unprocessed_value = value
100
+ field_store << field.serialize_db
101
+ end
102
+ end
103
+ end
104
+ field_store
105
+ end
106
+
107
+ def field_modified!(modified_field)
108
+ @modified = true
109
+ _owner.box_modified!(self)
110
+ end
111
+
112
+ def serialize_db
113
+ {
114
+ :box_id => schema_id.to_s,
115
+ :fields => fields.serialize_db
116
+ }
117
+ end
118
+
119
+ def self.resolve_style(box)
120
+ Spontaneous::BoxStyle.new(box)
121
+ end
122
+
123
+ def self.style_class
124
+ Spontaneous::BoxStyle
125
+ end
126
+
127
+ def style
128
+ resolve_style(self)
129
+ end
130
+
131
+ def container
132
+ _owner
133
+ end
134
+
135
+ def page
136
+ container.page
137
+ end
138
+
139
+ def depth
140
+ container.content_depth
141
+ end
142
+
143
+ def push(content)
144
+ insert(-1, content)
145
+ end
146
+
147
+ alias_method :<<, :push
148
+
149
+ def insert(index, content)
150
+ @modified = true
151
+ _owner.insert(index, content, self)
152
+ end
153
+
154
+ def set_position(entry, new_position)
155
+ @modified = true
156
+ piece = pieces[new_position]
157
+ new_position = container.pieces.index(piece)
158
+ container.pieces.set_position(entry, new_position)
159
+ end
160
+
161
+ def modified?
162
+ @modified
163
+ end
164
+
165
+ def pieces
166
+ @pieces ||= _owner.pieces.for_box(self)
167
+ end
168
+
169
+
170
+ def each
171
+ pieces.each do |piece|
172
+ yield piece if block_given?
173
+ end
174
+ end
175
+
176
+ def last
177
+ pieces.last
178
+ end
179
+
180
+ def iterable
181
+ pieces
182
+ end
183
+
184
+ def export
185
+ shallow_export.merge({
186
+ :entries => pieces.map { |p| p.export }
187
+ })
188
+ end
189
+
190
+ def shallow_export
191
+ {
192
+ :name => _prototype.name.to_s,
193
+ :id => _prototype.schema_id.to_s,
194
+ :fields => self.class.readable_fields.map { |name| fields[name].export }
195
+ }
196
+ end
197
+
198
+ # only called directly after saving a boxes fields so
199
+ # we don't need to return the entries
200
+ def serialise_http
201
+ Spontaneous.serialise_http(shallow_export)
202
+ end
203
+
204
+ def writable?(content_type = nil)
205
+ return true if Spontaneous::Permissions.has_level?(Spontaneous::Permissions.root)
206
+ box_writable = self._owner.box_writable?(_name)
207
+ if content_type
208
+ allowed = self.allowed_type(content_type)
209
+ box_writable && allowed && allowed.addable?
210
+ else
211
+ box_writable
212
+ end
213
+ end
214
+
215
+ def readable?
216
+ self._owner.box_readable?(_name)
217
+ end
218
+
219
+ def start_inline_edit_marker
220
+ "spontaneous:previewedit:start:box id:#{schema_id}"
221
+ end
222
+
223
+ def end_inline_edit_marker
224
+ "spontaneous:previewedit:end:box id:#{schema_id}"
225
+ end
226
+
227
+ def save
228
+ _owner.save
229
+ end
230
+ end
231
+
232
+ end
@@ -0,0 +1,64 @@
1
+ # encoding: UTF-8
2
+
3
+
4
+ module Spontaneous
5
+ class BoxStyle < Style
6
+ attr_reader :box
7
+
8
+ def self.to_directory_name(klass)
9
+ return nil if klass == Spontaneous::Box
10
+ super
11
+ end
12
+
13
+ def initialize(box)
14
+ @box = box
15
+ @owner = box._owner.class
16
+ end
17
+
18
+ def inline_template(format)
19
+ nil
20
+ end
21
+
22
+ def supertype_template(format)
23
+ supertype = box.class.supertype
24
+ if supertype && supertype != Spontaneous::Box
25
+ self.class.new(supertype).template(format)
26
+ else
27
+ nil
28
+ end
29
+ end
30
+
31
+ def name
32
+ box._name.to_s
33
+ end
34
+
35
+ def try_paths
36
+ prototype = box._prototype
37
+ box_directory_name = self.class.to_directory_name(prototype.box_base_class)
38
+ paths = [ [owner_directory_name, box._name.to_s] ]
39
+
40
+ if box.styles.empty?
41
+ paths.push(box_directory_name)
42
+ else
43
+ if style_name = prototype.default_style
44
+ name = style_name.to_s
45
+ paths.push([owner_directory_name, name])
46
+ paths.push([box_directory_name, name])
47
+ else
48
+ box.styles.each do |style|
49
+ name = style.name.to_s
50
+ paths.push([owner_directory_name, name])
51
+ paths.push([box_directory_name, name])
52
+ end
53
+ end
54
+ end
55
+
56
+ paths
57
+ end
58
+
59
+ def anonymous_template
60
+ Proc.new { "{{ render_content }}" }
61
+ end
62
+ end
63
+ end
64
+