card 1.17.4 → 1.18.0
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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/card.gemspec +24 -25
- data/config/initializers/01_init_ruby_extensions.rb +0 -4
- data/config/initializers/inflections.rb +1 -1
- data/config/initializers/notification.rb +2 -2
- data/db/migrate/20110511221913_require_earlier_migrations.rb +3 -3
- data/db/migrate/20120105203350_require_1_8_migrations.rb +3 -3
- data/db/migrate/20121111025347_require_1_10_migrations.rb +3 -3
- data/db/migrate/20130106052640_table_cleanup.rb +4 -4
- data/db/migrate/20130411210957_update_codenames.rb +2 -2
- data/db/migrate/20141001105348_move_revisions_to_actions.rb +4 -4
- data/db/migrate/20141121172918_rename_card_migration_table.rb +2 -2
- data/db/migrate/20141208132159_remove_present_from_reference_table.rb +2 -2
- data/db/migrate/20141216053032_better_index_names.rb +9 -9
- data/db/migrate_core_cards/20120611203506_rails_inflection_updates.rb +29 -32
- data/db/migrate_core_cards/20130411191151_renaming_for_menu.rb +3 -4
- data/db/migrate_core_cards/20130411211600_delete_old_related_tab_cards.rb +1 -1
- data/db/migrate_core_cards/20130419215612_import_help_text.rb +1 -2
- data/db/migrate_core_cards/20130823192433_add_style_cards.rb +3 -3
- data/db/migrate_core_cards/20130910183318_move_styles_to_content.rb +2 -3
- data/db/migrate_core_cards/20130920214038_jsonize_tinymce.rb +2 -2
- data/db/migrate_core_cards/20130920291703_update_stylesheets.rb +1 -2
- data/db/migrate_core_cards/20130927191728_account_events.rb +5 -6
- data/db/migrate_core_cards/20131016172445_common_css_patch.rb +2 -3
- data/db/migrate_core_cards/20140110193325_reset_account_request_type.rb +0 -1
- data/db/migrate_core_cards/20140307231621_user_data_to_cards.rb +23 -32
- data/db/migrate_core_cards/20140317035504_account_requests_to_signups.rb +1 -7
- data/db/migrate_core_cards/20140512155840_add_script_cards.rb +21 -24
- data/db/migrate_core_cards/20140629222005_add_email_cards.rb +17 -22
- data/db/migrate_core_cards/20140725180118_config_card_updates.rb +2 -2
- data/db/migrate_core_cards/20141111083921_delete_machine_output.rb +1 -3
- data/db/migrate_core_cards/20141115034214_config_descriptions_etc.rb +2 -2
- data/db/migrate_core_cards/20141119001955_make_symlinks_relative.rb +3 -3
- data/db/migrate_core_cards/20141120120605_fix_notification_html_message.rb +1 -1
- data/db/migrate_core_cards/20141204061304_watchers_to_following.rb +8 -12
- data/db/migrate_core_cards/20141208162106_add_ace_script.rb +2 -3
- data/db/migrate_core_cards/20141216155251_add_more_following_cards.rb +10 -10
- data/db/migrate_core_cards/20150202143810_import_bootstrap_layout.rb +10 -12
- data/db/migrate_core_cards/20150220134731_following_to_follow_rule.rb +4 -4
- data/db/migrate_core_cards/20150317162412_bootstrap_themes.rb +3 -3
- data/db/migrate_core_cards/20150326205655_bootswatch_themes.rb +7 -7
- data/db/migrate_core_cards/20150429090551_search_card_context.rb +18 -20
- data/db/migrate_core_cards/20150508212032_menu_compatibility.rb +3 -7
- data/db/migrate_core_cards/20150510031118_fix_skin_images.rb +2 -3
- data/db/migrate_core_cards/20150528084659_add_session_cardtype.rb +3 -3
- data/db/migrate_core_cards/20150601133433_add_recent_setting_session_card.rb +4 -4
- data/db/migrate_core_cards/20150610171702_add_debugger_session_card.rb +4 -4
- data/db/migrate_core_cards/20150610180019_add_recaptcha_key_and_admin_info_cards.rb +5 -11
- data/db/migrate_core_cards/20150724123438_update_file_and_image_cards.rb +29 -35
- data/db/migrate_core_cards/20150824135418_update_file_history.rb +10 -14
- data/db/migrate_core_cards/20150903130006_attachment_upload_cards.rb +1 -1
- data/db/schema.rb +92 -94
- data/db/seed/new/card_actions.yml +461 -469
- data/db/seed/new/card_acts.yml +154 -172
- data/db/seed/new/card_changes.yml +4076 -4031
- data/db/seed/new/card_references.yml +1584 -1927
- data/db/seed/new/cards.yml +2095 -2112
- data/db/seed/test/fixtures/card_actions.yml +1497 -1505
- data/db/seed/test/fixtures/card_acts.yml +454 -472
- data/db/seed/test/fixtures/card_changes.yml +7309 -7263
- data/db/seed/test/fixtures/card_references.yml +2263 -2613
- data/db/seed/test/fixtures/cards.yml +3298 -3316
- data/db/seed/test/seed.rb +3 -0
- data/lib/card.rb +17 -9
- data/lib/card/active_record_ext.rb +6 -8
- data/lib/card/active_record_helper.rb +42 -32
- data/lib/card/auth.rb +3 -3
- data/lib/card/cache.rb +4 -4
- data/lib/card/cache/persistent.rb +9 -5
- data/lib/card/cache/temporary.rb +5 -5
- data/lib/card/chunk.rb +1 -1
- data/lib/card/codename.rb +3 -2
- data/lib/card/content.rb +62 -57
- data/lib/card/core_ext.rb +20 -30
- data/lib/card/diff.rb +88 -76
- data/lib/card/director_register.rb +66 -0
- data/lib/card/env.rb +14 -17
- data/lib/card/exceptions.rb +7 -9
- data/lib/card/format.rb +18 -367
- data/lib/card/format/nest.rb +183 -0
- data/lib/card/format/permission.rb +63 -0
- data/lib/card/format/render.rb +140 -0
- data/lib/card/loader.rb +17 -26
- data/lib/card/location.rb +6 -6
- data/lib/card/mailer.rb +4 -7
- data/lib/card/migration.rb +1 -1
- data/lib/card/name.rb +3 -6
- data/lib/card/query.rb +8 -8
- data/lib/card/query/attributes.rb +6 -6
- data/lib/card/query/clause.rb +10 -10
- data/lib/card/query/join.rb +7 -9
- data/lib/card/query/reference.rb +17 -19
- data/lib/card/query/sql_statement.rb +2 -2
- data/lib/card/query/value.rb +15 -16
- data/lib/card/set.rb +106 -209
- data/lib/card/set/event.rb +126 -0
- data/lib/card/set_pattern.rb +42 -29
- data/lib/card/simplecov_helper.rb +19 -19
- data/lib/card/spec_helper.rb +40 -16
- data/lib/card/stage.rb +72 -0
- data/lib/card/stage_director.rb +231 -0
- data/lib/card/subcards.rb +56 -24
- data/lib/card/subdirector_array.rb +31 -0
- data/lib/card/success.rb +15 -18
- data/lib/card/version.rb +1 -2
- data/lib/card/view_cache.rb +4 -4
- data/lib/card/view_name.rb +10 -8
- data/lib/cardio.rb +1 -1
- data/lib/generators/card.rb +2 -4
- data/lib/generators/card/format/format_generator.rb +4 -4
- data/lib/generators/card/migration/migration_generator.rb +6 -6
- data/lib/generators/card/set/set_generator.rb +5 -6
- data/mod/01_core/chunk/include.rb +2 -1
- data/mod/01_core/chunk/link.rb +2 -2
- data/mod/01_core/chunk/literal.rb +6 -9
- data/mod/01_core/chunk/query_reference.rb +1 -1
- data/mod/01_core/chunk/reference.rb +2 -2
- data/mod/01_core/chunk/uri.rb +52 -63
- data/mod/01_core/format/html_format.rb +8 -12
- data/mod/01_core/format/text_format.rb +1 -1
- data/mod/01_core/set/all/actify.rb +96 -0
- data/mod/01_core/set/all/active_card.rb +7 -7
- data/mod/01_core/set/all/collection.rb +19 -20
- data/mod/01_core/set/all/content.rb +9 -7
- data/mod/01_core/set/all/erb.rb +5 -5
- data/mod/01_core/set/all/event.rb +60 -0
- data/mod/01_core/set/all/fetch.rb +13 -19
- data/mod/01_core/set/all/haml.rb +1 -1
- data/mod/01_core/set/all/initialize.rb +35 -41
- data/mod/01_core/set/all/location_history.rb +3 -5
- data/mod/01_core/set/all/name.rb +19 -68
- data/mod/01_core/set/all/name_validations.rb +56 -0
- data/mod/01_core/set/all/pattern.rb +2 -2
- data/mod/01_core/set/all/permissions.rb +14 -20
- data/mod/01_core/set/all/phases.rb +9 -200
- data/mod/01_core/set/all/references.rb +10 -10
- data/mod/01_core/set/all/rules.rb +3 -4
- data/mod/01_core/set/all/stages.rb +24 -0
- data/mod/01_core/set/all/states.rb +4 -4
- data/mod/01_core/set/all/subcards.rb +16 -26
- data/mod/01_core/set/all/templating.rb +1 -3
- data/mod/01_core/set/all/tracked_attributes.rb +47 -48
- data/mod/01_core/set/all/trash.rb +10 -10
- data/mod/01_core/set/all/type.rb +9 -8
- data/mod/01_core/set/all/utils.rb +10 -14
- data/mod/01_core/set/all/view_cache.rb +2 -2
- data/mod/01_core/set_pattern/01_all.rb +3 -3
- data/mod/01_core/set_pattern/02_all_plus.rb +3 -3
- data/mod/01_core/set_pattern/03_type.rb +2 -2
- data/mod/01_core/set_pattern/04_star.rb +3 -3
- data/mod/01_core/set_pattern/05_rstar.rb +3 -3
- data/mod/01_core/set_pattern/06_right.rb +2 -2
- data/mod/01_core/set_pattern/07_type_plus_right.rb +2 -2
- data/mod/01_core/set_pattern/08_self.rb +1 -1
- data/mod/01_core/spec/chunk/literal_spec.rb +7 -8
- data/mod/01_core/spec/chunk/uri_spec.rb +140 -142
- data/mod/01_core/spec/format/html_format_spec.rb +72 -57
- data/mod/01_core/spec/set/all/collection_spec.rb +63 -43
- data/mod/01_core/spec/set/all/content_spec.rb +4 -4
- data/mod/01_core/spec/set/all/fetch_spec.rb +12 -3
- data/mod/01_core/spec/set/all/name_spec.rb +3 -4
- data/mod/01_core/spec/set/all/pattern_spec.rb +32 -35
- data/mod/01_core/spec/set/all/permissions_spec.rb +17 -5
- data/mod/01_core/spec/set/all/phases_spec.rb +0 -1
- data/mod/01_core/spec/set/all/references_spec.rb +1 -1
- data/mod/01_core/spec/set/all/rules2_spec.rb +79 -91
- data/mod/01_core/spec/set/all/rules_spec.rb +63 -56
- data/mod/01_core/spec/set/all/templating_spec.rb +0 -1
- data/mod/01_core/spec/set/all/tracked_attributes_spec.rb +4 -5
- data/mod/01_core/spec/set/all/trash_spec.rb +23 -1
- data/mod/01_core/spec/set/all/type_spec.rb +2 -5
- data/mod/01_history/lib/card/action.rb +8 -10
- data/mod/01_history/set/all/actions.rb +2 -4
- data/mod/01_history/set/all/content_history.rb +38 -32
- data/mod/01_history/set/all/history.rb +20 -17
- data/mod/02_basic_types/format/rss_format.rb +0 -1
- data/mod/02_basic_types/set/all/all_css.rb +9 -13
- data/mod/02_basic_types/set/all/all_csv.rb +14 -17
- data/mod/02_basic_types/set/all/all_js.rb +3 -4
- data/mod/02_basic_types/set/all/base.rb +2 -2
- data/mod/02_basic_types/set/all/file.rb +2 -5
- data/mod/02_basic_types/set/all/json.rb +19 -18
- data/mod/02_basic_types/set/all/rss.rb +3 -3
- data/mod/02_basic_types/set/all/text.rb +1 -3
- data/mod/02_basic_types/set/type/html.rb +4 -8
- data/mod/02_basic_types/set/type/plain_text.rb +2 -3
- data/mod/02_basic_types/set/type/pointer.rb +82 -92
- data/mod/02_basic_types/spec/set/all/all_css_spec.rb +2 -2
- data/mod/02_basic_types/spec/set/all/all_csv_spec.rb +6 -4
- data/mod/02_basic_types/spec/set/all/base_spec.rb +6 -6
- data/mod/02_basic_types/spec/set/all/json_spec.rb +8 -8
- data/mod/02_basic_types/spec/set/type/plain_text_spec.rb +3 -3
- data/mod/02_basic_types/spec/set/type/pointer_spec.rb +29 -32
- data/mod/03_machines/lib/card/machine.rb +95 -81
- data/mod/03_machines/lib/card/machine_input.rb +35 -34
- data/mod/03_machines/set/right/machine_input.rb +1 -1
- data/mod/03_machines/set/self/script_ace.rb +2 -3
- data/mod/03_machines/set/self/script_card_menu.rb +2 -3
- data/mod/03_machines/set/self/script_jquery_helper.rb +2 -2
- data/mod/03_machines/set/self/script_slot.rb +2 -2
- data/mod/03_machines/set/self/style_bootstrap_compatible.rb +1 -1
- data/mod/03_machines/set/self/style_cards.rb +1 -1
- data/mod/03_machines/set/self/style_jquery_ui_smoothness.rb +0 -1
- data/mod/03_machines/set/type/coffee_script.rb +9 -13
- data/mod/03_machines/set/type/css.rb +12 -13
- data/mod/03_machines/set/type/java_script.rb +6 -8
- data/mod/03_machines/set/type/scss.rb +4 -5
- data/mod/03_machines/set/type/skin.rb +3 -6
- data/mod/03_machines/spec/lib/shared_machine_examples.rb +31 -38
- data/mod/03_machines/spec/lib/shared_machine_input_examples.rb +7 -8
- data/mod/03_machines/spec/set/type/coffeescript_spec.rb +19 -13
- data/mod/03_machines/spec/set/type/css_spec.rb +22 -16
- data/mod/03_machines/spec/set/type/scss_spec.rb +28 -21
- data/mod/03_machines/spec/set/type/skin_spec.rb +28 -30
- data/mod/04_settings/lib/card/setting.rb +4 -4
- data/mod/04_settings/set/abstract/permission.rb +30 -37
- data/mod/04_settings/set/right/add_help.rb +3 -3
- data/mod/04_settings/set/right/script.rb +4 -5
- data/mod/04_settings/set/right/structure.rb +3 -4
- data/mod/04_settings/set/right/style.rb +3 -3
- data/mod/04_settings/set/self/add_help.rb +1 -1
- data/mod/04_settings/set/self/input.rb +1 -1
- data/mod/04_settings/set/self/on_create.rb +1 -1
- data/mod/04_settings/set/self/options.rb +1 -1
- data/mod/04_settings/set/self/options_label.rb +1 -1
- data/mod/04_settings/set/type/setting.rb +29 -44
- data/mod/04_settings/spec/set/right/comment_spec.rb +9 -12
- data/mod/04_settings/spec/set/right/script_spec.rb +7 -7
- data/mod/04_settings/spec/set/right/structure_spec.rb +13 -12
- data/mod/04_settings/spec/set/right/style_spec.rb +13 -13
- data/mod/04_settings/spec/set/type/setting_spec.rb +1 -1
- data/mod/05_email/format/email_html_format.rb +1 -1
- data/mod/05_email/format/email_text_format.rb +2 -2
- data/mod/05_email/lib/card/follow_option.rb +12 -15
- data/mod/05_email/set/all/email_html.rb +2 -3
- data/mod/05_email/set/all/email_text.rb +3 -3
- data/mod/05_email/set/all/follow.rb +14 -22
- data/mod/05_email/set/all/notify.rb +11 -11
- data/mod/05_email/set/all/observer.rb +7 -8
- data/mod/05_email/set/right/bcc.rb +4 -9
- data/mod/05_email/set/right/follow.rb +26 -39
- data/mod/05_email/set/right/follow_fields.rb +2 -2
- data/mod/05_email/set/right/followers.rb +3 -1
- data/mod/05_email/set/right/following.rb +13 -16
- data/mod/05_email/set/self/always.rb +1 -2
- data/mod/05_email/set/self/created.rb +4 -6
- data/mod/05_email/set/self/edited.rb +3 -7
- data/mod/05_email/set/self/follow_defaults.rb +11 -12
- data/mod/05_email/set/self/never.rb +2 -4
- data/mod/05_email/set/type/email_template.rb +40 -27
- data/mod/05_email/set/type_plus_right/user/follow.rb +159 -157
- data/mod/05_email/spec/set/all/follow_spec.rb +28 -37
- data/mod/05_email/spec/set/all/notify_spec.rb +21 -26
- data/mod/05_email/spec/set/all/observer_spec.rb +58 -37
- data/mod/05_email/spec/set/right/followers_spec.rb +9 -14
- data/mod/05_email/spec/set/right/following_spec.rb +1 -1
- data/mod/05_email/spec/set/self/follow_defaults_spec.rb +1 -1
- data/mod/05_standard/lib/carrier_wave/cardmount.rb +9 -9
- data/mod/05_standard/lib/file_uploader.rb +8 -13
- data/mod/05_standard/lib/image_uploader.rb +8 -9
- data/mod/05_standard/set/abstract/attachment.rb +26 -43
- data/mod/05_standard/set/all/account.rb +2 -2
- data/mod/05_standard/set/all/comment.rb +11 -13
- data/mod/05_standard/set/all/error.rb +18 -18
- data/mod/05_standard/set/all/event_viz.rb +16 -29
- data/mod/05_standard/set/all/links.rb +35 -34
- data/mod/05_standard/set/all/list_changes.rb +10 -12
- data/mod/05_standard/set/all/rich_html/content.rb +13 -13
- data/mod/05_standard/set/all/rich_html/editing.rb +5 -5
- data/mod/05_standard/set/all/rich_html/form.rb +22 -26
- data/mod/05_standard/set/all/rich_html/header.rb +18 -25
- data/mod/05_standard/set/all/rich_html/menu.rb +20 -22
- data/mod/05_standard/set/all/rich_html/modal.rb +3 -3
- data/mod/05_standard/set/all/rich_html/toolbar.rb +49 -58
- data/mod/05_standard/set/all/rich_html/wrapper.rb +40 -41
- data/mod/05_standard/set/right/account.rb +26 -14
- data/mod/05_standard/set/right/email.rb +2 -2
- data/mod/05_standard/set/right/password.rb +6 -5
- data/mod/05_standard/set/right/salt.rb +2 -2
- data/mod/05_standard/set/right/stats.rb +17 -20
- data/mod/05_standard/set/right/token.rb +1 -1
- data/mod/05_standard/set/right/when_created.rb +1 -1
- data/mod/05_standard/set/right/when_last_edited.rb +1 -1
- data/mod/05_standard/set/rstar/rules.rb +3 -3
- data/mod/05_standard/set/rstar/rules_editor.rb +39 -39
- data/mod/05_standard/set/self/account_links.rb +21 -22
- data/mod/05_standard/set/self/admin_info.rb +5 -5
- data/mod/05_standard/set/self/alerts.rb +1 -1
- data/mod/05_standard/set/self/all.rb +1 -1
- data/mod/05_standard/set/self/foot.rb +1 -1
- data/mod/05_standard/set/self/head.rb +19 -22
- data/mod/05_standard/set/self/navbox.rb +3 -7
- data/mod/05_standard/set/self/now.rb +1 -1
- data/mod/05_standard/set/self/recent.rb +19 -25
- data/mod/05_standard/set/self/search.rb +2 -4
- data/mod/05_standard/set/self/signin.rb +6 -6
- data/mod/05_standard/set/self/stats.rb +31 -38
- data/mod/05_standard/set/self/version.rb +1 -2
- data/mod/05_standard/set/type/basic.rb +15 -17
- data/mod/05_standard/set/type/cardtype.rb +3 -3
- data/mod/05_standard/set/type/date.rb +1 -2
- data/mod/05_standard/set/type/file.rb +22 -33
- data/mod/05_standard/set/type/image.rb +30 -23
- data/mod/05_standard/set/type/layout_type.rb +4 -4
- data/mod/05_standard/set/type/list.rb +32 -38
- data/mod/05_standard/set/type/listed_by.rb +11 -13
- data/mod/05_standard/set/type/number.rb +5 -6
- data/mod/05_standard/set/type/phrase.rb +1 -1
- data/mod/05_standard/set/type/search_type.rb +25 -23
- data/mod/05_standard/set/type/session.rb +2 -3
- data/mod/05_standard/set/type/set.rb +46 -51
- data/mod/05_standard/set/type/signup.rb +18 -19
- data/mod/05_standard/set/type/toggle.rb +5 -5
- data/mod/05_standard/set/type/user.rb +6 -6
- data/mod/05_standard/spec/chunk/include_spec.rb +115 -98
- data/mod/05_standard/spec/chunk/link_spec.rb +58 -31
- data/mod/05_standard/spec/chunk/query_reference_spec.rb +12 -14
- data/mod/05_standard/spec/set/all/email_html_spec.rb +3 -3
- data/mod/05_standard/spec/set/all/error_spec.rb +3 -3
- data/mod/05_standard/spec/set/all/history_spec.rb +52 -38
- data/mod/05_standard/spec/set/all/links_spec.rb +2 -2
- data/mod/05_standard/spec/set/all/rich_html/editing_spec.rb +0 -1
- data/mod/05_standard/spec/set/all/rich_html/form_spec.rb +11 -11
- data/mod/05_standard/spec/set/all/rich_html/wrapper_spec.rb +4 -4
- data/mod/05_standard/spec/set/right/email_spec.rb +1 -4
- data/mod/05_standard/spec/set/right/password_spec.rb +4 -7
- data/mod/05_standard/spec/set/right/stats_spec.rb +2 -3
- data/mod/05_standard/spec/set/right/when_created_spec.rb +1 -1
- data/mod/05_standard/spec/set/right/when_last_edited_spec.rb +1 -1
- data/mod/05_standard/spec/set/rstar/rules_spec.rb +6 -6
- data/mod/05_standard/spec/set/self/all_spec.rb +11 -13
- data/mod/05_standard/spec/set/self/head_spec.rb +1 -3
- data/mod/05_standard/spec/set/self/navbox_spec.rb +1 -1
- data/mod/05_standard/spec/set/self/now_spec.rb +2 -2
- data/mod/05_standard/spec/set/self/signin_spec.rb +1 -1
- data/mod/05_standard/spec/set/self/stats_spec.rb +1 -1
- data/mod/05_standard/spec/set/self/version_spec.rb +2 -2
- data/mod/05_standard/spec/set/type/cardtype_spec.rb +3 -4
- data/mod/05_standard/spec/set/type/date_spec.rb +1 -1
- data/mod/05_standard/spec/set/type/email_template_spec.rb +5 -5
- data/mod/05_standard/spec/set/type/file_spec.rb +50 -28
- data/mod/05_standard/spec/set/type/html_spec.rb +12 -7
- data/mod/05_standard/spec/set/type/image_spec.rb +55 -45
- data/mod/05_standard/spec/set/type/layout_type_spec.rb +2 -2
- data/mod/05_standard/spec/set/type/listed_by_spec.rb +2 -2
- data/mod/05_standard/spec/set/type/number_spec.rb +1 -1
- data/mod/05_standard/spec/set/type/phrase_spec.rb +1 -1
- data/mod/05_standard/spec/set/type/search_type_spec.rb +15 -16
- data/mod/05_standard/spec/set/type/set_spec.rb +16 -17
- data/mod/05_standard/spec/set/type/signup_spec.rb +7 -5
- data/mod/05_standard/spec/set/type/toggle_spec.rb +4 -4
- data/mod/05_standard/spec/set/type/uri_spec.rb +11 -11
- data/mod/05_standard/spec/set/type/user_spec.rb +0 -1
- data/mod/06_bootstrap/set/all/bootstrap/form.rb +9 -10
- data/mod/06_bootstrap/set/all/bootstrap/helper.rb +22 -27
- data/mod/06_bootstrap/set/all/bootstrap/wrapper.rb +1 -2
- data/mod/06_bootstrap/set/all/rich_bootstrap.rb +1 -3
- data/mod/06_bootstrap/set/self/bootstrap_cards.rb +2 -2
- data/mod/06_bootstrap/set/self/bootstrap_js.rb +2 -2
- data/mod/06_bootstrap/set/self/bootswatch_shared.rb +19 -19
- data/mod/06_bootstrap/set/self/smartmenu_css.rb +2 -2
- data/mod/06_bootstrap/set/self/smartmenu_js.rb +3 -3
- data/mod/06_bootstrap/spec/set/all/bootstrap/form_spec.rb +5 -5
- data/spec/lib/card/action_spec.rb +4 -4
- data/spec/lib/card/cache_spec.rb +3 -5
- data/spec/lib/card/chunk_spec.rb +6 -8
- data/spec/lib/card/codename_spec.rb +4 -6
- data/spec/lib/card/content_spec.rb +12 -17
- data/spec/lib/card/diff_spec.rb +59 -61
- data/spec/lib/card/format_spec.rb +55 -34
- data/spec/lib/card/loader_spec.rb +35 -37
- data/spec/lib/card/name_spec.rb +159 -145
- data/spec/lib/card/query_spec.rb +4 -4
- data/spec/lib/card/reference_spec.rb +24 -24
- data/spec/lib/card/set_pattern_spec.rb +3 -3
- data/spec/lib/card/stage_director_spec.rb +218 -0
- data/spec/lib/card/subcards_spec.rb +12 -16
- data/spec/lib/card/success_spec.rb +16 -18
- data/spec/lib/card/view_cache_spec.rb +1 -1
- data/spec/mailers/mailer_spec.rb +3 -5
- data/spec/models/card/cardtype_spec.rb +40 -51
- data/spec/models/card/create_spec.rb +58 -39
- data/spec/models/card/trash_spec.rb +23 -32
- data/spec/models/card/type_transition_spec.rb +41 -32
- data/spec/models/card/validation_spec.rb +13 -15
- data/spec/models/card_spec.rb +48 -59
- data/spec/spec_helper.rb +26 -31
- metadata +16 -2
data/lib/card/stage.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
class Card
|
2
|
+
# The process of writing a card change to the database is divided into
|
3
|
+
# 8 stages that are grouped in 3 phases.
|
4
|
+
#
|
5
|
+
# 'validation phase'
|
6
|
+
# * initialize stage
|
7
|
+
# * prepare_to_validate stage
|
8
|
+
# * validate stage
|
9
|
+
#
|
10
|
+
# 'storage phase'
|
11
|
+
# * prepare_to_store stage
|
12
|
+
# * store stage
|
13
|
+
# * finalize stage
|
14
|
+
#
|
15
|
+
# 'integration phase'
|
16
|
+
# * integrate stage
|
17
|
+
# * integrate_with_delay stage
|
18
|
+
#
|
19
|
+
#
|
20
|
+
module Stage
|
21
|
+
STAGES = [:initialize, :prepare_to_validate, :validate, :prepare_to_store,
|
22
|
+
:store, :finalize, :integrate, :integrate_with_delay].freeze
|
23
|
+
STAGE_INDEX = {}
|
24
|
+
STAGES.each_with_index do |stage, i|
|
25
|
+
STAGE_INDEX[stage] = i
|
26
|
+
end
|
27
|
+
STAGE_INDEX.freeze
|
28
|
+
|
29
|
+
def stage_symbol index
|
30
|
+
case index
|
31
|
+
when Symbol
|
32
|
+
return index if STAGE_INDEX[index]
|
33
|
+
when Integer
|
34
|
+
return STAGES[index] if index < STAGES.size
|
35
|
+
end
|
36
|
+
raise Card::Error, "not a valid stage index: #{index}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def stage_index stage
|
40
|
+
case stage
|
41
|
+
when Symbol then
|
42
|
+
return STAGE_INDEX[stage]
|
43
|
+
when Integer then
|
44
|
+
return stage
|
45
|
+
else
|
46
|
+
raise Card::Error, "not a valid stage: #{stage}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def stage_ok? opts
|
51
|
+
stage && (
|
52
|
+
(opts[:during] && in?(opts[:during])) ||
|
53
|
+
(opts[:before] && before?(opts[:before])) ||
|
54
|
+
(opts[:after] && after?(opts[:after])) ||
|
55
|
+
true # no phase restriction in opts
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
def before? allowed_phase
|
60
|
+
STAGE_INDEX[allowed_phase] > STAGE_INDEX[stage]
|
61
|
+
end
|
62
|
+
|
63
|
+
def after? allowed_phase
|
64
|
+
STAGE_INDEX[allowed_phase] < STAGE_INDEX[stage]
|
65
|
+
end
|
66
|
+
|
67
|
+
def in? allowed_phase
|
68
|
+
(allowed_phase.is_a?(Array) && allowed_phase.include?(stage)) ||
|
69
|
+
allowed_phase == stage
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,231 @@
|
|
1
|
+
|
2
|
+
class Card
|
3
|
+
# A 'StageDirector' executes the stages of a card when the card gets created,
|
4
|
+
# updated or deleted.
|
5
|
+
# For subcards, i.e. other cards that are changed in the same act, a
|
6
|
+
# StageDirector has StageSubdirectors that take care of the stages for
|
7
|
+
# those cards
|
8
|
+
#
|
9
|
+
# In general a stage is executed for all involved cards before the
|
10
|
+
# StageDirector proceeds with the next stage.
|
11
|
+
# Only exception is the finalize stage.
|
12
|
+
# The finalize stage of a subcard is executed immediately after its store
|
13
|
+
# stage. When all subcards are finalized the supercard's finalize stage is
|
14
|
+
# executed.
|
15
|
+
#
|
16
|
+
# If a subcard is added in a stage then it catches up at the end of the stage
|
17
|
+
# to the current stage.
|
18
|
+
# For example if you add a subcard in a card's :prepare_to_store stage then
|
19
|
+
# after that stage the stages :initialize, :prepare_to_validate,
|
20
|
+
# :validate and :prepare_to_store are executed for the subcard.
|
21
|
+
#
|
22
|
+
# Stages are executed with pre-order depth-first search.
|
23
|
+
# That means if A has subcards AA and AB; AAA is subcard of AA and ABA
|
24
|
+
# subcard of AB then the order of execution is
|
25
|
+
# A -> AA -> AAA -> AB -> ABA
|
26
|
+
#
|
27
|
+
# A special case can happen in the store phase.
|
28
|
+
# If the id of a subcard is needed for a supercard
|
29
|
+
# (for example as left_id or as type_id) and the subcard doesn't
|
30
|
+
# have an id yet (because it gets created in the same act)
|
31
|
+
# then the subcard's store stage is executed before the supercard's store
|
32
|
+
# stage
|
33
|
+
class StageDirector
|
34
|
+
include Stage
|
35
|
+
|
36
|
+
attr_accessor :prior_store, :act, :card, :stage, :parent, :main,
|
37
|
+
:subdirectors
|
38
|
+
attr_reader :running
|
39
|
+
alias running? running
|
40
|
+
alias main? main
|
41
|
+
|
42
|
+
def initialize card, opts={}, main=true
|
43
|
+
@card = card
|
44
|
+
@card.director = self
|
45
|
+
@card.prepare_for_phases
|
46
|
+
@stage = nil
|
47
|
+
@running = false
|
48
|
+
@parent = opts[:parent]
|
49
|
+
# has card to be stored before the supercard?
|
50
|
+
@prior_store = opts[:priority]
|
51
|
+
@main = main
|
52
|
+
@subdirectors = SubdirectorArray.initialize_with_subcards(self)
|
53
|
+
register
|
54
|
+
end
|
55
|
+
|
56
|
+
def register
|
57
|
+
Card::DirectorRegister.add self
|
58
|
+
end
|
59
|
+
|
60
|
+
def unregister
|
61
|
+
@card.director = nil
|
62
|
+
@subdirectors = nil
|
63
|
+
@stage = nil
|
64
|
+
@action = nil
|
65
|
+
Card::DirectorRegister.delete self
|
66
|
+
end
|
67
|
+
|
68
|
+
def validation_phase
|
69
|
+
@running = true
|
70
|
+
run_single_stage :initialize
|
71
|
+
run_single_stage :prepare_to_validate
|
72
|
+
run_single_stage :validate
|
73
|
+
@card.expire_pieces if @card.errors.any?
|
74
|
+
@card.errors.empty?
|
75
|
+
end
|
76
|
+
|
77
|
+
# everything in here can use dirty marks
|
78
|
+
def storage_phase &block
|
79
|
+
# for a subcard :prepare_to_store was already executed
|
80
|
+
# don't execute it twice
|
81
|
+
catch_up_to_stage :prepare_to_store
|
82
|
+
run_single_stage :store, &block
|
83
|
+
run_single_stage :finalize
|
84
|
+
ensure
|
85
|
+
@from_trash = nil
|
86
|
+
end
|
87
|
+
|
88
|
+
# dirty marks are gone in this phase
|
89
|
+
def integration_phase
|
90
|
+
run_single_stage :integrate
|
91
|
+
run_single_stage :integrate_with_delay
|
92
|
+
rescue => e # don't rollback
|
93
|
+
Card::Error.current = e
|
94
|
+
@card.notable_exception_raised
|
95
|
+
return false
|
96
|
+
end
|
97
|
+
|
98
|
+
def catch_up_to_stage next_stage
|
99
|
+
@stage ||= -1
|
100
|
+
(@stage + 1).upto(stage_index(next_stage)) do |i|
|
101
|
+
run_single_stage stage_symbol(i)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def call_after_store &block
|
106
|
+
@call_after_store ||= []
|
107
|
+
@call_after_store << block
|
108
|
+
end
|
109
|
+
|
110
|
+
def need_act
|
111
|
+
act_director = main_director
|
112
|
+
unless act_director
|
113
|
+
raise Card::Error, 'act requested without a main stage director'
|
114
|
+
end
|
115
|
+
act_director.act ||= Card::Act.create(ip_address: Env.ip)
|
116
|
+
@card.current_act = @act = act_director.act
|
117
|
+
end
|
118
|
+
|
119
|
+
def main_director
|
120
|
+
if main?
|
121
|
+
self
|
122
|
+
else
|
123
|
+
DirectorRegister.act_director || (@parent && @parent.main_director)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
def run_single_stage stage, &block
|
130
|
+
# puts "#{@card.name}: #{stage} stage".red
|
131
|
+
@stage = stage_index stage
|
132
|
+
return if @card.errors.any? && @stage <= stage_index(:validate)
|
133
|
+
|
134
|
+
# in the store stage it can be necessary that
|
135
|
+
# other subcards must be saved before we save this card
|
136
|
+
if stage == :store
|
137
|
+
store(&block)
|
138
|
+
else
|
139
|
+
run_stage_callbacks stage
|
140
|
+
run_subdirector_stages stage unless stage == :finalize
|
141
|
+
end
|
142
|
+
rescue => e
|
143
|
+
@card.rescue_event e
|
144
|
+
end
|
145
|
+
|
146
|
+
def run_stage_callbacks stage
|
147
|
+
# we use abort :success in the :store stage for :save_draft
|
148
|
+
if stage_index(stage) <= stage_index(:store) && !main?
|
149
|
+
@card.abortable do
|
150
|
+
@card.run_callbacks :"#{stage}_stage"
|
151
|
+
end
|
152
|
+
else
|
153
|
+
@card.run_callbacks :"#{stage}_stage"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def run_subdirector_stages stage
|
158
|
+
@subdirectors.each do |subdir|
|
159
|
+
subdir.catch_up_to_stage stage
|
160
|
+
end
|
161
|
+
ensure
|
162
|
+
@card.handle_subcard_errors
|
163
|
+
end
|
164
|
+
|
165
|
+
# handle the store stage
|
166
|
+
# The tricky part here is to preserve the dirty marks on the subcards'
|
167
|
+
# attributes for the finalize stage.
|
168
|
+
# To achieve this we can't just call the :store and :finlaize callbacks on
|
169
|
+
# the subcards as we do in the other phases.
|
170
|
+
# Instead we have to call `save` on the subcards
|
171
|
+
# and use the ActiveRecord :around_save callback to run the :store and
|
172
|
+
# :finalize stages
|
173
|
+
def store &save_block
|
174
|
+
if main? && !block_given?
|
175
|
+
raise Card::Error, 'need block to store main card'
|
176
|
+
end
|
177
|
+
# the block is the ActiveRecord block from the around save callback that
|
178
|
+
# saves the card
|
179
|
+
if block_given?
|
180
|
+
run_stage_callbacks :store
|
181
|
+
store_with_subcards(&save_block)
|
182
|
+
else
|
183
|
+
store_and_finalize_as_subcard
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def store_with_subcards
|
188
|
+
store_prior_subcards
|
189
|
+
yield
|
190
|
+
if @call_after_store
|
191
|
+
@call_after_store.each do |handle_id|
|
192
|
+
handle_id.call(@card.id)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
store_subcards
|
196
|
+
@virtual = false # TODO: find a better place for this
|
197
|
+
ensure
|
198
|
+
@card.handle_subcard_errors
|
199
|
+
end
|
200
|
+
|
201
|
+
# store subcards whose ids we need for this card
|
202
|
+
def store_prior_subcards
|
203
|
+
@subdirectors.each do |subdir|
|
204
|
+
next unless subdir.prior_store
|
205
|
+
subdir.catch_up_to_stage :store
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def store_subcards
|
210
|
+
@subdirectors.each do |subdir|
|
211
|
+
next if subdir.prior_store
|
212
|
+
subdir.catch_up_to_stage :store
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# trigger the storage_phase, skip the other phases
|
217
|
+
# At this point the :prepare_to_store stage was already executed
|
218
|
+
# by the parent director. So the storage phase will only run
|
219
|
+
# the :store stage and the :finalize stage
|
220
|
+
def store_and_finalize_as_subcard
|
221
|
+
@card.skip_phases = true
|
222
|
+
@card.save! validate: false
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
class StageSubdirector < StageDirector
|
227
|
+
def initialize card, opts={}
|
228
|
+
super card, opts, false
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
data/lib/card/subcards.rb
CHANGED
@@ -11,29 +11,13 @@
|
|
11
11
|
class Card
|
12
12
|
def subcards
|
13
13
|
@subcards ||= Subcards.new(self)
|
14
|
-
|
15
|
-
|
16
|
-
def preserve_subcards
|
17
|
-
return unless subcards.present?
|
18
|
-
Card.cache.soft.write subcards_cache_key, @subcards
|
19
|
-
end
|
20
|
-
|
21
|
-
def restore_subcards
|
22
|
-
cached_subcards = Card.cache.soft.read(subcards_cache_key)
|
23
|
-
return unless cached_subcards
|
24
|
-
@subcards = cached_subcards
|
25
|
-
@subcards.context_card = self
|
14
|
+
# @subcards ||= (director && director.subcards)
|
26
15
|
end
|
27
16
|
|
28
17
|
def expire_subcards
|
29
|
-
Card.cache.soft.delete subcards_cache_key
|
30
18
|
subcards.clear
|
31
19
|
end
|
32
20
|
|
33
|
-
def subcards_cache_key
|
34
|
-
"#{key}#SUBCARDS#"
|
35
|
-
end
|
36
|
-
|
37
21
|
class Subcards
|
38
22
|
attr_accessor :context_card, :keys
|
39
23
|
def initialize context_card
|
@@ -48,6 +32,15 @@ class Card
|
|
48
32
|
@keys = ::Set.new
|
49
33
|
end
|
50
34
|
|
35
|
+
def deep_clear cleared=::Set.new
|
36
|
+
each_card do |card|
|
37
|
+
next if cleared.include? card.id
|
38
|
+
cleared << card.id
|
39
|
+
card.subcards.deep_clear cleared
|
40
|
+
end
|
41
|
+
clear
|
42
|
+
end
|
43
|
+
|
51
44
|
def remove name_or_card
|
52
45
|
key = case name_or_card
|
53
46
|
when Card
|
@@ -96,8 +89,15 @@ class Card
|
|
96
89
|
end
|
97
90
|
end
|
98
91
|
|
99
|
-
def
|
92
|
+
def catch_up_to_stage stage_index
|
93
|
+
each_card do |subcard|
|
94
|
+
subcard.catch_up_to_stage stage_index
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def rename old_name, _new_name
|
100
99
|
return unless @keys.include? old_name.to_name.key
|
100
|
+
# FIXME: something should happen here
|
101
101
|
end
|
102
102
|
|
103
103
|
def << value
|
@@ -122,7 +122,7 @@ class Card
|
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
125
|
-
|
125
|
+
alias each each_card
|
126
126
|
|
127
127
|
def each_with_key
|
128
128
|
@keys.each do |key|
|
@@ -146,9 +146,7 @@ class Card
|
|
146
146
|
|
147
147
|
def field name
|
148
148
|
key = field_name_to_key name
|
149
|
-
if @keys.include? key
|
150
|
-
fetch_subcard key
|
151
|
-
end
|
149
|
+
fetch_subcard key if @keys.include? key
|
152
150
|
end
|
153
151
|
|
154
152
|
def card name
|
@@ -173,8 +171,8 @@ class Card
|
|
173
171
|
end
|
174
172
|
end
|
175
173
|
|
176
|
-
|
177
|
-
|
174
|
+
alias add_field add_child
|
175
|
+
alias remove_field remove_child
|
178
176
|
|
179
177
|
def present?
|
180
178
|
@keys.present?
|
@@ -240,7 +238,41 @@ class Card
|
|
240
238
|
end
|
241
239
|
@keys << card.key
|
242
240
|
Card.write_to_soft_cache card
|
241
|
+
card.director = @context_card.director.subdirectors.add(card)
|
243
242
|
card
|
244
243
|
end
|
245
244
|
end
|
245
|
+
|
246
|
+
def right_id= card_or_id
|
247
|
+
write_card_or_id :right_id, card_or_id
|
248
|
+
end
|
249
|
+
|
250
|
+
def left_id= card_or_id
|
251
|
+
write_card_or_id :left_id, card_or_id
|
252
|
+
end
|
253
|
+
|
254
|
+
def type_id= card_or_id
|
255
|
+
write_card_or_id :type_id, card_or_id
|
256
|
+
end
|
257
|
+
|
258
|
+
def write_card_or_id attribute, card_or_id
|
259
|
+
if card_or_id.is_a? Card
|
260
|
+
card = card_or_id
|
261
|
+
if card.id
|
262
|
+
write_attribute attribute, card.id
|
263
|
+
else
|
264
|
+
add_subcard card
|
265
|
+
card.director.prior_store = true
|
266
|
+
with_id_when_exists(card) do |id|
|
267
|
+
write_attribute attribute, id
|
268
|
+
end
|
269
|
+
end
|
270
|
+
else
|
271
|
+
write_attribute attribute, card_or_id
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
def with_id_when_exists card, &block
|
276
|
+
card.director.call_after_store(&block)
|
277
|
+
end
|
246
278
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class Card
|
2
|
+
class SubdirectorArray < Array
|
3
|
+
def self.initialize_with_subcards parent
|
4
|
+
dir_array = new(parent)
|
5
|
+
parent.card.subcards.each_card do |subcard|
|
6
|
+
dir_array.add subcard
|
7
|
+
end
|
8
|
+
dir_array
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize parent
|
12
|
+
@parent = parent
|
13
|
+
super()
|
14
|
+
end
|
15
|
+
|
16
|
+
def add card
|
17
|
+
each do |dir|
|
18
|
+
return dir if dir.card == card
|
19
|
+
end
|
20
|
+
dir = Card::DirectorRegister.fetch card, parent: @parent
|
21
|
+
dir.main = false
|
22
|
+
dir.parent = @parent
|
23
|
+
self << dir
|
24
|
+
dir
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete card
|
28
|
+
delete_if { |dir| dir.card == card }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|