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.
- data/Gemfile +49 -0
- data/Gemfile.lock +146 -0
- data/LICENSE +0 -0
- data/README +0 -0
- data/Rakefile +284 -0
- data/Readme.markdown +7 -0
- data/application/css/add_alias_dialogue.scss +27 -0
- data/application/css/definitions.scss +249 -0
- data/application/css/developer.scss +9 -0
- data/application/css/editing.scss +649 -0
- data/application/css/login.scss +91 -0
- data/application/css/min/54ee0ed3c7fac7632bd5c020d69e9a2503e0c88c.css +1 -0
- data/application/css/min/c256adc144e2bdd0b0539356b04eb62db01e1dc3.css +1 -0
- data/application/css/popover.scss +335 -0
- data/application/css/schema_error.scss +90 -0
- data/application/css/spontaneous.scss +111 -0
- data/application/css/unsupported.scss +16 -0
- data/application/css/v2.scss +1606 -0
- data/application/css/variables.scss +80 -0
- data/application/js/add_alias_dialogue.js +59 -0
- data/application/js/add_home_dialogue.js +59 -0
- data/application/js/ajax.js +99 -0
- data/application/js/authentication.js +22 -0
- data/application/js/box.js +104 -0
- data/application/js/box_container.js +82 -0
- data/application/js/compatibility.js +132 -0
- data/application/js/conflicted_field_dialogue.js +92 -0
- data/application/js/content.js +224 -0
- data/application/js/content_area.js +44 -0
- data/application/js/dialogue.js +196 -0
- data/application/js/dom.js +71 -0
- data/application/js/edit_dialogue.js +137 -0
- data/application/js/edit_panel.js +232 -0
- data/application/js/editing.js +42 -0
- data/application/js/entry.js +13 -0
- data/application/js/extensions.js +104 -0
- data/application/js/field.js +4 -0
- data/application/js/field_preview.js +55 -0
- data/application/js/field_types/date_field.js +16 -0
- data/application/js/field_types/file_field.js +71 -0
- data/application/js/field_types/image_field.js +358 -0
- data/application/js/field_types/markdown_field.js +656 -0
- data/application/js/field_types/string_field.js +185 -0
- data/application/js/image.js +72 -0
- data/application/js/init.js +34 -0
- data/application/js/load.js +4 -0
- data/application/js/location.js +157 -0
- data/application/js/login.js +53 -0
- data/application/js/min/492a209de8ee955fa9c729a765377495001e11b1.js +17 -0
- data/application/js/min/80f684d77c940887a1d4a63e3a96102e993baa98.js +88 -0
- data/application/js/min/b8abf302a824c35385ff517b34111e1710ff3b37.js +2 -0
- data/application/js/min/c7140ec9475e5bf868b901e0621338d7d162358b.js +3 -0
- data/application/js/min/f07f2bd6630ee31e1c2288ec223383d8f0658ba6.js +2 -0
- data/application/js/page.js +43 -0
- data/application/js/page_browser.js +147 -0
- data/application/js/page_entry.js +47 -0
- data/application/js/popover.js +99 -0
- data/application/js/popover_view.js +56 -0
- data/application/js/preview.js +64 -0
- data/application/js/progress.js +358 -0
- data/application/js/properties.js +90 -0
- data/application/js/publish.js +187 -0
- data/application/js/require.js +129 -0
- data/application/js/sharded_upload.js +206 -0
- data/application/js/side_bar.js +30 -0
- data/application/js/spontaneous.js +6 -0
- data/application/js/state.js +64 -0
- data/application/js/status_bar.js +47 -0
- data/application/js/top_bar.js +368 -0
- data/application/js/types.js +98 -0
- data/application/js/upload.js +88 -0
- data/application/js/upload_manager.js +319 -0
- data/application/js/user.js +37 -0
- data/application/js/vendor/.DS_Store +0 -0
- data/application/js/vendor/JS.Class-2.1.5/CHANGELOG +283 -0
- data/application/js/vendor/JS.Class-2.1.5/MIT-LICENSE +30 -0
- data/application/js/vendor/JS.Class-2.1.5/README +30 -0
- data/application/js/vendor/JS.Class-2.1.5/min/command.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/comparable.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/constant_scope.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/core.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/decorator.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/enumerable.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/forwardable.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/hash.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/linked_list.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/loader.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/method_chain.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/observable.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/package.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/proxy.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/ruby.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/set.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/stack_trace.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/state.js +1 -0
- data/application/js/vendor/JS.Class-2.1.5/min/stdlib.js +16 -0
- data/application/js/vendor/JS.Class-2.1.5/src/command.js +93 -0
- data/application/js/vendor/JS.Class-2.1.5/src/comparable.js +37 -0
- data/application/js/vendor/JS.Class-2.1.5/src/constant_scope.js +48 -0
- data/application/js/vendor/JS.Class-2.1.5/src/core.js +1060 -0
- data/application/js/vendor/JS.Class-2.1.5/src/decorator.js +50 -0
- data/application/js/vendor/JS.Class-2.1.5/src/enumerable.js +505 -0
- data/application/js/vendor/JS.Class-2.1.5/src/forwardable.js +22 -0
- data/application/js/vendor/JS.Class-2.1.5/src/hash.js +334 -0
- data/application/js/vendor/JS.Class-2.1.5/src/linked_list.js +114 -0
- data/application/js/vendor/JS.Class-2.1.5/src/loader.js +553 -0
- data/application/js/vendor/JS.Class-2.1.5/src/method_chain.js +172 -0
- data/application/js/vendor/JS.Class-2.1.5/src/observable.js +55 -0
- data/application/js/vendor/JS.Class-2.1.5/src/package.js +472 -0
- data/application/js/vendor/JS.Class-2.1.5/src/proxy.js +58 -0
- data/application/js/vendor/JS.Class-2.1.5/src/ruby.js +44 -0
- data/application/js/vendor/JS.Class-2.1.5/src/set.js +332 -0
- data/application/js/vendor/JS.Class-2.1.5/src/stack_trace.js +151 -0
- data/application/js/vendor/JS.Class-2.1.5/src/state.js +95 -0
- data/application/js/vendor/JS.Class-2.1.5/src/stdlib.js +2612 -0
- data/application/js/vendor/crypto-2.3.0-crypto.js +160 -0
- data/application/js/vendor/crypto-2.3.0-sha1.js +91 -0
- data/application/js/vendor/diff_match_patch.js +2153 -0
- data/application/js/vendor/jquery-1.4.2.min.js +154 -0
- data/application/js/vendor/jquery-1.4.3.min.js +166 -0
- data/application/js/vendor/jquery-1.5.1.min.js +16 -0
- data/application/js/vendor/jquery-1.5.1rc1.min.js +24 -0
- data/application/js/vendor/jquery-1.6.2.min.js +18 -0
- data/application/js/vendor/jquery-ui-1.8.6.custom.min.js +265 -0
- data/application/js/vendor/jquery-ui-1.8.9.custom.min.js +415 -0
- data/application/js/vendor/jquery-ui-1.8.custom.min.js +106 -0
- data/application/js/vendor/jquery.hotkeys-0.7.9.js +248 -0
- data/application/js/vendor/jquery.hotkeys-0.7.9.min.js +19 -0
- data/application/js/vendor/jsdiff.js +169 -0
- data/application/js/views/box_view.js +229 -0
- data/application/js/views/page_piece_view.js +45 -0
- data/application/js/views/page_view.js +238 -0
- data/application/js/views/piece_view.js +178 -0
- data/application/js/views.js +110 -0
- data/application/static/editing-0-noise.png +0 -0
- data/application/static/editing-1-noise.png +0 -0
- data/application/static/editing-texture-1.png +0 -0
- data/application/static/editing-texture.png +0 -0
- data/application/static/editing-toolbar-shadow-bottom.png +0 -0
- data/application/static/editing-toolbar-shadow-top.png +0 -0
- data/application/static/favicon.ico +0 -0
- data/application/static/inner-glow.png +0 -0
- data/application/static/item-buttons.png +0 -0
- data/application/static/location-arrow.png +0 -0
- data/application/static/logo-400px-transparent.png +0 -0
- data/application/static/missing.png +0 -0
- data/application/static/orange-down-arrow.png +0 -0
- data/application/static/page-browser-next.png +0 -0
- data/application/static/paper-texture-dark.png +0 -0
- data/application/static/px.gif +0 -0
- data/application/static/select-arrow-root.png +0 -0
- data/application/static/select-arrow.png +0 -0
- data/application/static/slot-down-arrow.png +0 -0
- data/application/static/splash.png +0 -0
- data/application/static/spontaneous.png +0 -0
- data/application/static/spot.png +0 -0
- data/application/static/spot.svg +40 -0
- data/application/static/texture.png +0 -0
- data/application/views/index.erubis +46 -0
- data/application/views/login.erubis +69 -0
- data/application/views/schema_modification_error.html.erb +61 -0
- data/application/views/unsupported.erubis +23 -0
- data/bin/limit-upload +5 -0
- data/bin/spot +10 -0
- data/bin/unlimit-upload +3 -0
- data/config/nginx.conf +60 -0
- data/db/migrations/20100610142136_init.rb +66 -0
- data/db/migrations/20101130104334_timestamps.rb +44 -0
- data/db/migrations/20101202113205_site_publishing_flags.rb +12 -0
- data/db/migrations/20101206124543_aliases.rb +16 -0
- data/db/migrations/20110201133550_visibility.rb +27 -0
- data/db/migrations/20110209152710_users_and_groups.rb +58 -0
- data/db/migrations/20110215133910_boxes.rb +25 -0
- data/db/migrations/20110521114145_remove_slots_and_entries.rb +21 -0
- data/db/migrations/20110604192145_rename_schema_id_columns.rb +22 -0
- data/db/migrations/20110805141925_rename_site_to_state.rb +11 -0
- data/lib/cutaneous/context_helper.rb +82 -0
- data/lib/cutaneous/first_pass_parser.rb +23 -0
- data/lib/cutaneous/first_pass_renderer.rb +18 -0
- data/lib/cutaneous/parser_core.rb +18 -0
- data/lib/cutaneous/preview_context.rb +31 -0
- data/lib/cutaneous/preview_renderer.rb +15 -0
- data/lib/cutaneous/publish_context.rb +9 -0
- data/lib/cutaneous/renderer.rb +122 -0
- data/lib/cutaneous/request_context.rb +8 -0
- data/lib/cutaneous/second_pass_parser.rb +23 -0
- data/lib/cutaneous/second_pass_renderer.rb +18 -0
- data/lib/cutaneous.rb +47 -0
- data/lib/sequel/plugins/content_table_inheritance.rb +196 -0
- data/lib/sequel/plugins/yajl_serialization.rb +154 -0
- data/lib/spontaneous/application/feature.rb +9 -0
- data/lib/spontaneous/application/plugin.rb +13 -0
- data/lib/spontaneous/application.rb +8 -0
- data/lib/spontaneous/box.rb +232 -0
- data/lib/spontaneous/box_style.rb +64 -0
- data/lib/spontaneous/change.rb +107 -0
- data/lib/spontaneous/cli/adapter.rb +13 -0
- data/lib/spontaneous/cli/base.rb +184 -0
- data/lib/spontaneous/cli/console.rb +0 -0
- data/lib/spontaneous/cli/media.rb +13 -0
- data/lib/spontaneous/cli/server.rb +50 -0
- data/lib/spontaneous/cli/site.rb +46 -0
- data/lib/spontaneous/cli/sync.rb +42 -0
- data/lib/spontaneous/cli/tasks.rb +9 -0
- data/lib/spontaneous/cli.rb +83 -0
- data/lib/spontaneous/collections/box_set.rb +56 -0
- data/lib/spontaneous/collections/change_set.rb +43 -0
- data/lib/spontaneous/collections/entry_set.rb +83 -0
- data/lib/spontaneous/collections/field_set.rb +53 -0
- data/lib/spontaneous/collections/prototype_set.rb +131 -0
- data/lib/spontaneous/collections/style_set.rb +13 -0
- data/lib/spontaneous/config.rb +156 -0
- data/lib/spontaneous/constants.rb +24 -0
- data/lib/spontaneous/content.rb +113 -0
- data/lib/spontaneous/content_query.rb +17 -0
- data/lib/spontaneous/errors.rb +48 -0
- data/lib/spontaneous/extensions/array.rb +18 -0
- data/lib/spontaneous/extensions/class.rb +17 -0
- data/lib/spontaneous/extensions/hash.rb +18 -0
- data/lib/spontaneous/extensions/json.rb +26 -0
- data/lib/spontaneous/extensions/kernel.rb +7 -0
- data/lib/spontaneous/extensions/object.rb +30 -0
- data/lib/spontaneous/extensions/object_space.rb +12 -0
- data/lib/spontaneous/extensions/string.rb +44 -0
- data/lib/spontaneous/facet.rb +47 -0
- data/lib/spontaneous/field_types/date_field.rb +12 -0
- data/lib/spontaneous/field_types/field.rb +252 -0
- data/lib/spontaneous/field_types/image_field.rb +329 -0
- data/lib/spontaneous/field_types/markdown_field.rb +37 -0
- data/lib/spontaneous/field_types/string_field.rb +14 -0
- data/lib/spontaneous/field_types.rb +40 -0
- data/lib/spontaneous/generators/page/inline.html.cut +1 -0
- data/lib/spontaneous/generators/page/page.html.cut.tt +4 -0
- data/lib/spontaneous/generators/page/page.rb.tt +9 -0
- data/lib/spontaneous/generators/page.rb +38 -0
- data/lib/spontaneous/generators/site/.gitignore +4 -0
- data/lib/spontaneous/generators/site/Gemfile.tt +31 -0
- data/lib/spontaneous/generators/site/Rakefile.tt +6 -0
- data/lib/spontaneous/generators/site/config/back.ru +7 -0
- data/lib/spontaneous/generators/site/config/boot.rb +19 -0
- data/lib/spontaneous/generators/site/config/database.yml.tt +21 -0
- data/lib/spontaneous/generators/site/config/deploy.rb.tt +0 -0
- data/lib/spontaneous/generators/site/config/environment.rb.tt +8 -0
- data/lib/spontaneous/generators/site/config/environments/development.rb.tt +15 -0
- data/lib/spontaneous/generators/site/config/environments/production.rb.tt +5 -0
- data/lib/spontaneous/generators/site/config/front.ru +8 -0
- data/lib/spontaneous/generators/site/config/user_levels.yml +22 -0
- data/lib/spontaneous/generators/site/lib/site.rb.tt +4 -0
- data/lib/spontaneous/generators/site/lib/tasks/site.rake.tt +8 -0
- data/lib/spontaneous/generators/site/public/css/site.css +0 -0
- data/lib/spontaneous/generators/site/public/favicon.ico +0 -0
- data/lib/spontaneous/generators/site/public/js/.empty_directory +0 -0
- data/lib/spontaneous/generators/site/public/js/site.js +0 -0
- data/lib/spontaneous/generators/site/public/robots.txt +0 -0
- data/lib/spontaneous/generators/site/schema/.map +1 -0
- data/lib/spontaneous/generators/site/schema/page.rb.tt +8 -0
- data/lib/spontaneous/generators/site/schema/piece.rb.tt +4 -0
- data/lib/spontaneous/generators/site/templates/layouts/standard.html.cut.tt +13 -0
- data/lib/spontaneous/generators/site.rb +77 -0
- data/lib/spontaneous/generators.rb +23 -0
- data/lib/spontaneous/image_size.rb +117 -0
- data/lib/spontaneous/json.rb +33 -0
- data/lib/spontaneous/layout.rb +15 -0
- data/lib/spontaneous/loader.rb +280 -0
- data/lib/spontaneous/logger.rb +369 -0
- data/lib/spontaneous/media.rb +84 -0
- data/lib/spontaneous/page.rb +92 -0
- data/lib/spontaneous/page_controller.rb +18 -0
- data/lib/spontaneous/page_piece.rb +77 -0
- data/lib/spontaneous/paths.rb +30 -0
- data/lib/spontaneous/permissions/access_group.rb +50 -0
- data/lib/spontaneous/permissions/access_key.rb +35 -0
- data/lib/spontaneous/permissions/user.rb +167 -0
- data/lib/spontaneous/permissions/user_level.rb +177 -0
- data/lib/spontaneous/permissions.rb +55 -0
- data/lib/spontaneous/piece.rb +30 -0
- data/lib/spontaneous/plugins/aliases.rb +128 -0
- data/lib/spontaneous/plugins/allowed_types.rb +173 -0
- data/lib/spontaneous/plugins/application/facets.rb +25 -0
- data/lib/spontaneous/plugins/application/paths.rb +137 -0
- data/lib/spontaneous/plugins/application/render.rb +29 -0
- data/lib/spontaneous/plugins/application/serialisation.rb +16 -0
- data/lib/spontaneous/plugins/application/state.rb +86 -0
- data/lib/spontaneous/plugins/boxes.rb +84 -0
- data/lib/spontaneous/plugins/controllers.rb +52 -0
- data/lib/spontaneous/plugins/entries.rb +193 -0
- data/lib/spontaneous/plugins/entry.rb +51 -0
- data/lib/spontaneous/plugins/fields.rb +103 -0
- data/lib/spontaneous/plugins/instance_code.rb +18 -0
- data/lib/spontaneous/plugins/layouts.rb +87 -0
- data/lib/spontaneous/plugins/media.rb +41 -0
- data/lib/spontaneous/plugins/page/formats.rb +67 -0
- data/lib/spontaneous/plugins/page/request.rb +89 -0
- data/lib/spontaneous/plugins/page_search.rb +64 -0
- data/lib/spontaneous/plugins/page_tree.rb +25 -0
- data/lib/spontaneous/plugins/paths.rb +125 -0
- data/lib/spontaneous/plugins/permissions.rb +63 -0
- data/lib/spontaneous/plugins/prototypes.rb +84 -0
- data/lib/spontaneous/plugins/publishing.rb +255 -0
- data/lib/spontaneous/plugins/render.rb +24 -0
- data/lib/spontaneous/plugins/schema_hierarchy.rb +76 -0
- data/lib/spontaneous/plugins/schema_id.rb +60 -0
- data/lib/spontaneous/plugins/schema_title.rb +33 -0
- data/lib/spontaneous/plugins/serialisation.rb +67 -0
- data/lib/spontaneous/plugins/site/instance.rb +22 -0
- data/lib/spontaneous/plugins/site/map.rb +19 -0
- data/lib/spontaneous/plugins/site/publishing.rb +74 -0
- data/lib/spontaneous/plugins/site/revisions.rb +28 -0
- data/lib/spontaneous/plugins/site/selectors.rb +41 -0
- data/lib/spontaneous/plugins/site_map.rb +34 -0
- data/lib/spontaneous/plugins/styles.rb +119 -0
- data/lib/spontaneous/plugins/supertype.rb +11 -0
- data/lib/spontaneous/plugins/visibility.rb +151 -0
- data/lib/spontaneous/plugins.rb +20 -0
- data/lib/spontaneous/prototypes/box_prototype.rb +168 -0
- data/lib/spontaneous/prototypes/field_prototype.rb +112 -0
- data/lib/spontaneous/prototypes/layout_prototype.rb +17 -0
- data/lib/spontaneous/prototypes/style_prototype.rb +42 -0
- data/lib/spontaneous/proxy_object.rb +12 -0
- data/lib/spontaneous/publishing/fire_and_forget.rb +57 -0
- data/lib/spontaneous/publishing/immediate.rb +197 -0
- data/lib/spontaneous/publishing/threaded.rb +25 -0
- data/lib/spontaneous/publishing.rb +10 -0
- data/lib/spontaneous/rack/around_back.rb +44 -0
- data/lib/spontaneous/rack/around_front.rb +29 -0
- data/lib/spontaneous/rack/around_preview.rb +26 -0
- data/lib/spontaneous/rack/assets.rb +98 -0
- data/lib/spontaneous/rack/back.rb +729 -0
- data/lib/spontaneous/rack/front.rb +41 -0
- data/lib/spontaneous/rack/http.rb +18 -0
- data/lib/spontaneous/rack/media.rb +29 -0
- data/lib/spontaneous/rack/public.rb +232 -0
- data/lib/spontaneous/rack/reloader.rb +42 -0
- data/lib/spontaneous/rack/static.rb +25 -0
- data/lib/spontaneous/rack.rb +55 -0
- data/lib/spontaneous/render/context.rb +100 -0
- data/lib/spontaneous/render/development_renderer.rb +14 -0
- data/lib/spontaneous/render/engine.rb +19 -0
- data/lib/spontaneous/render/format/html.rb +5 -0
- data/lib/spontaneous/render/format.rb +70 -0
- data/lib/spontaneous/render/preview_renderer.rb +18 -0
- data/lib/spontaneous/render/published_renderer.rb +54 -0
- data/lib/spontaneous/render/publishing_renderer.rb +13 -0
- data/lib/spontaneous/render/renderer.rb +46 -0
- data/lib/spontaneous/render.rb +173 -0
- data/lib/spontaneous/revision.rb +7 -0
- data/lib/spontaneous/schema/schema_modification.rb +260 -0
- data/lib/spontaneous/schema/uid.rb +221 -0
- data/lib/spontaneous/schema.rb +295 -0
- data/lib/spontaneous/server.rb +65 -0
- data/lib/spontaneous/site.rb +87 -0
- data/lib/spontaneous/state.rb +53 -0
- data/lib/spontaneous/style.rb +144 -0
- data/lib/spontaneous/tasks/database.rake +9 -0
- data/lib/spontaneous/tasks.rb +5 -0
- data/lib/spontaneous/version.rb +6 -0
- data/lib/spontaneous.rb +179 -0
- data/spontaneous.gemspec.tmpl +66 -0
- data/test/disabled/test_slots.rb +287 -0
- data/test/experimental/test_formats.rb +92 -0
- data/test/experimental/test_plugins.rb +64 -0
- data/test/fixtures/application/css/test.less +5 -0
- data/test/fixtures/application/js/test.js +1 -0
- data/test/fixtures/application/static/favicon.ico +1 -0
- data/test/fixtures/application/static/test.html +1 -0
- data/test/fixtures/application/views/index.erubis +1 -0
- data/test/fixtures/back/public/test.html +1 -0
- data/test/fixtures/back/templates/layouts/standard.html.cut +1 -0
- data/test/fixtures/config/config/environment.rb +4 -0
- data/test/fixtures/config/config/environments/development.rb +13 -0
- data/test/fixtures/config/config/environments/production.rb +22 -0
- data/test/fixtures/config/config/environments/staging.rb +2 -0
- data/test/fixtures/example_application/Gemfile +6 -0
- data/test/fixtures/example_application/Gemfile.lock +76 -0
- data/test/fixtures/example_application/Rakefile +6 -0
- data/test/fixtures/example_application/config/back.rb +15 -0
- data/test/fixtures/example_application/config/back.ru +8 -0
- data/test/fixtures/example_application/config/back.yml +8 -0
- data/test/fixtures/example_application/config/boot.rb +16 -0
- data/test/fixtures/example_application/config/database.yml +24 -0
- data/test/fixtures/example_application/config/environment.rb +4 -0
- data/test/fixtures/example_application/config/environments/development.rb +16 -0
- data/test/fixtures/example_application/config/environments/production.rb +21 -0
- data/test/fixtures/example_application/config/environments/staging.rb +1 -0
- data/test/fixtures/example_application/config/front.rb +8 -0
- data/test/fixtures/example_application/config/front.ru +8 -0
- data/test/fixtures/example_application/config/front.yml +8 -0
- data/test/fixtures/example_application/config/schema.yml +48 -0
- data/test/fixtures/example_application/config/unicorn.rb +1 -0
- data/test/fixtures/example_application/config/user_levels.yml +19 -0
- data/test/fixtures/example_application/public/css/test.css +0 -0
- data/test/fixtures/example_application/public/favicon.ico +1 -0
- data/test/fixtures/example_application/public/js/test.js +0 -0
- data/test/fixtures/example_application/public/test.html +1 -0
- data/test/fixtures/example_application/schema/client_project.rb +18 -0
- data/test/fixtures/example_application/schema/client_projects.rb +8 -0
- data/test/fixtures/example_application/schema/home_page.rb +22 -0
- data/test/fixtures/example_application/schema/info_page.rb +13 -0
- data/test/fixtures/example_application/schema/inline_image.rb +11 -0
- data/test/fixtures/example_application/schema/page.rb +4 -0
- data/test/fixtures/example_application/schema/piece.rb +3 -0
- data/test/fixtures/example_application/schema/project.rb +21 -0
- data/test/fixtures/example_application/schema/project_image.rb +18 -0
- data/test/fixtures/example_application/schema/projects_page.rb +12 -0
- data/test/fixtures/example_application/schema/text.rb +8 -0
- data/test/fixtures/example_application/templates/client_project/images.html.cut +1 -0
- data/test/fixtures/example_application/templates/client_project.html.cut +4 -0
- data/test/fixtures/example_application/templates/client_projects.html.cut +6 -0
- data/test/fixtures/example_application/templates/info_page/inline.html.cut +0 -0
- data/test/fixtures/example_application/templates/inline_image.html.cut +1 -0
- data/test/fixtures/example_application/templates/layouts/home.html.cut +15 -0
- data/test/fixtures/example_application/templates/layouts/info.html.cut +3 -0
- data/test/fixtures/example_application/templates/layouts/project.html.cut +13 -0
- data/test/fixtures/example_application/templates/layouts/projects.html.cut +11 -0
- data/test/fixtures/example_application/templates/layouts/standard.html.cut +0 -0
- data/test/fixtures/example_application/templates/project/inline.html.cut +5 -0
- data/test/fixtures/example_application/templates/project.html.cut +5 -0
- data/test/fixtures/example_application/templates/project_image.html.cut +1 -0
- data/test/fixtures/example_application/templates/text.html.cut +1 -0
- data/test/fixtures/images/rose.greyscale.jpg +0 -0
- data/test/fixtures/images/rose.jpg +0 -0
- data/test/fixtures/images/size.gif +0 -0
- data/test/fixtures/images/size.jpg +0 -0
- data/test/fixtures/images/size.png24 +0 -0
- data/test/fixtures/images/size.png8 +0 -0
- data/test/fixtures/layouts/layouts/custom1.html.cut +1 -0
- data/test/fixtures/layouts/layouts/custom1.pdf.cut +0 -0
- data/test/fixtures/layouts/layouts/custom1.xml.cut +0 -0
- data/test/fixtures/layouts/layouts/custom2.html.cut +1 -0
- data/test/fixtures/layouts/layouts/custom3.html.cut +0 -0
- data/test/fixtures/layouts/layouts/standard.html.cut +1 -0
- data/test/fixtures/media/101/003/rose.jpg +0 -0
- data/test/fixtures/permissions/config/user_levels.yml +9 -0
- data/test/fixtures/permissions/media/image.jpg +0 -0
- data/test/fixtures/plugins/schema_plugin/init.rb +1 -0
- data/test/fixtures/plugins/schema_plugin/schema/external.rb +5 -0
- data/test/fixtures/plugins/schema_plugin/templates/external.html.cut +1 -0
- data/test/fixtures/plugins/schema_plugin/templates/from_plugin.html.cut +0 -0
- data/test/fixtures/plugins/schema_plugin/templates/layouts/from_plugin.html.cut +0 -0
- data/test/fixtures/public/templates/layouts/default.html.cut +1 -0
- data/test/fixtures/public/templates/layouts/default.pdf.cut +1 -0
- data/test/fixtures/public/templates/layouts/default.rss.cut +1 -0
- data/test/fixtures/public/templates/layouts/dynamic.html.cut +1 -0
- data/test/fixtures/public/templates/layouts/standard.html.cut +0 -0
- data/test/fixtures/schema/before.yml +24 -0
- data/test/fixtures/schema/resolvable.yml +12 -0
- data/test/fixtures/schema/schema.yml +7 -0
- data/test/fixtures/serialisation/class_hash.yaml.erb +53 -0
- data/test/fixtures/serialisation/root_hash.yaml.erb +184 -0
- data/test/fixtures/sharding/rose.jpg +0 -0
- data/test/fixtures/sharding/xaa +0 -0
- data/test/fixtures/sharding/xab +0 -0
- data/test/fixtures/sharding/xac +0 -0
- data/test/fixtures/sharding/xad +0 -0
- data/test/fixtures/sharding/xae +0 -0
- data/test/fixtures/sharding/xaf +0 -0
- data/test/fixtures/sharding/xag +0 -0
- data/test/fixtures/styles/box_a/runny.html.cut +0 -0
- data/test/fixtures/styles/box_a.html.cut +1 -0
- data/test/fixtures/styles/named2.html.cut +1 -0
- data/test/fixtures/styles/orange/apple.html.cut +1 -0
- data/test/fixtures/styles/template_class/named1.html.cut +1 -0
- data/test/fixtures/styles/template_class/results.html.cut +1 -0
- data/test/fixtures/styles/template_class/walky.html.cut +0 -0
- data/test/fixtures/styles/template_class.epub.cut +0 -0
- data/test/fixtures/styles/template_class.html.cut +1 -0
- data/test/fixtures/styles/template_class.pdf.cut +0 -0
- data/test/fixtures/styles/template_sub_class1.html.cut +1 -0
- data/test/fixtures/templates/aliases/a/a_style.html.cut +0 -0
- data/test/fixtures/templates/aliases/a/page.html.cut +0 -0
- data/test/fixtures/templates/aliases/a_alias/a_alias_style.html.cut +0 -0
- data/test/fixtures/templates/aliases/layouts/b.html.cut +1 -0
- data/test/fixtures/templates/aliases/layouts/b_alias.html.cut +1 -0
- data/test/fixtures/templates/aliases/layouts/c_alias.html.cut +1 -0
- data/test/fixtures/templates/boxes/blank_content/things.html.cut +1 -0
- data/test/fixtures/templates/boxes/my_box_class/christy.html.cut +1 -0
- data/test/fixtures/templates/boxes/thangs.html.cut +1 -0
- data/test/fixtures/templates/boxes/with_template_box.html.cut +1 -0
- data/test/fixtures/templates/content/include.html.cut +1 -0
- data/test/fixtures/templates/content/include_dir.html.cut +1 -0
- data/test/fixtures/templates/content/included.epub.cut +1 -0
- data/test/fixtures/templates/content/included.html.cut +1 -0
- data/test/fixtures/templates/content/partial/included.html.cut +1 -0
- data/test/fixtures/templates/content/preprocess.html.cut +1 -0
- data/test/fixtures/templates/content/second.html.cut +1 -0
- data/test/fixtures/templates/content/template.epub.cut +1 -0
- data/test/fixtures/templates/content/template.html.cut +1 -0
- data/test/fixtures/templates/default_style_class.html.cut +1 -0
- data/test/fixtures/templates/direct.html.cut +1 -0
- data/test/fixtures/templates/extended/grandparent.html.cut +10 -0
- data/test/fixtures/templates/extended/main.html.cut +6 -0
- data/test/fixtures/templates/extended/parent.html.cut +10 -0
- data/test/fixtures/templates/layouts/entries.html.cut +7 -0
- data/test/fixtures/templates/layouts/page_style.html.cut +1 -0
- data/test/fixtures/templates/layouts/params.html.cut +1 -0
- data/test/fixtures/templates/layouts/preview_render.html.cut +2 -0
- data/test/fixtures/templates/layouts/standard_page.html.cut +1 -0
- data/test/fixtures/templates/layouts/subdir_style.html.cut +1 -0
- data/test/fixtures/templates/layouts/template_params.html.cut +1 -0
- data/test/fixtures/templates/page_class/inline_style.html.cut +1 -0
- data/test/fixtures/templates/preview_render/inline.html.cut +0 -0
- data/test/fixtures/templates/publishing/layouts/dynamic.html.cut +1 -0
- data/test/fixtures/templates/publishing/layouts/static.html.cut +1 -0
- data/test/fixtures/templates/template_class/anonymous_style.html.cut +4 -0
- data/test/fixtures/templates/template_class/another_template.html.cut +0 -0
- data/test/fixtures/templates/template_class/complex_template.html.cut +6 -0
- data/test/fixtures/templates/template_class/complex_template.pdf.cut +6 -0
- data/test/fixtures/templates/template_class/default_template_style.html.cut +4 -0
- data/test/fixtures/templates/template_class/images_with_template.html.cut +5 -0
- data/test/fixtures/templates/template_class/slots_template.html.cut +5 -0
- data/test/fixtures/templates/template_class/slots_template.pdf.cut +5 -0
- data/test/fixtures/templates/template_class/this_template.epub.cut +1 -0
- data/test/fixtures/templates/template_class/this_template.html.cut +1 -0
- data/test/fixtures/templates/template_class/this_template.pdf.cut +1 -0
- data/test/fixtures/templates/with_default_style_class.html.cut +1 -0
- data/test/functional/test_application.rb +176 -0
- data/test/functional/test_back.rb +902 -0
- data/test/functional/test_front.rb +571 -0
- data/test/javascript/test_dom.rb +94 -0
- data/test/javascript/test_markdown.rb +97 -0
- data/test/slow/test_publishing.rb +987 -0
- data/test/slow/test_visibility.rb +250 -0
- data/test/support/custom_matchers.rb +77 -0
- data/test/support/timing.rb +23 -0
- data/test/test_helper.rb +164 -0
- data/test/test_javascript.rb +34 -0
- data/test/ui/test_page_editing.rb +167 -0
- data/test/ui_helper.rb +114 -0
- data/test/unit/test_alias.rb +254 -0
- data/test/unit/test_authentication.rb +510 -0
- data/test/unit/test_boxes.rb +497 -0
- data/test/unit/test_config.rb +156 -0
- data/test/unit/test_content.rb +221 -0
- data/test/unit/test_content_inheritance.rb +103 -0
- data/test/unit/test_extensions.rb +14 -0
- data/test/unit/test_fields.rb +392 -0
- data/test/unit/test_generators.rb +97 -0
- data/test/unit/test_image_size.rb +25 -0
- data/test/unit/test_images.rb +265 -0
- data/test/unit/test_layouts.rb +111 -0
- data/test/unit/test_logger.rb +80 -0
- data/test/unit/test_media.rb +70 -0
- data/test/unit/test_page.rb +244 -0
- data/test/unit/test_permissions.rb +834 -0
- data/test/unit/test_piece.rb +80 -0
- data/test/unit/test_prototype_set.rb +192 -0
- data/test/unit/test_prototypes.rb +102 -0
- data/test/unit/test_render.rb +359 -0
- data/test/unit/test_schema.rb +1009 -0
- data/test/unit/test_serialisation.rb +215 -0
- data/test/unit/test_site.rb +145 -0
- data/test/unit/test_structure.rb +85 -0
- data/test/unit/test_styles.rb +417 -0
- data/test/unit/test_templates.rb +224 -0
- data/test/unit/test_type_hierarchy.rb +28 -0
- 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,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,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
|
+
|